]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial
authorLinus Torvalds <torvalds@g5.osdl.org>
Tue, 3 Oct 2006 16:13:29 +0000 (09:13 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 3 Oct 2006 16:13:29 +0000 (09:13 -0700)
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial: (21 commits)
  [SERIAL] add PNP IDs for FPI based touchscreens
  [SERIAL] Magic SysRq SAK does nothing on serial consoles
  [SERIAL] tickle NMI watchdog on serial output.
  [SERIAL] Fix oops when removing suspended serial port
  [SERIAL] Fix resume handling bug
  [SERIAL] Remove wrong asm/serial.h inclusions
  [SERIAL] CONFIG_PM=n slim: drivers/serial/8250_pci.c
  [SERIAL] OMAP1510 serial fix for 115200 baud
  [SERIAL] returning proper error from serial core driver
  [SERIAL] Make uart_line_info() correctly tell MMIO from I/O port
  [SERIAL] suspend/resume handlers don't have level arg anymore
  [SERIAL] 8250 resourse management fixes
  [SERIAL] serial_cs: Add quirk for brainboxes 2-port RS232 card
  [SERIAL] serial_cs: handle Nokia multi->single port bodge via config quirk
  [SERIAL] serial_cs: add configuration quirk
  [SERIAL] serial_cs: Convert Oxford 950 / Possio GCC wakeup quirk
  [SERIAL] serial_cs: convert IBM post-init handling to a quirk
  [SERIAL] serial_cs: allow wildcarded quirks
  [SERIAL] serial_cs: convert multi-port table to quirk table
  [SERIAL] serial_cs: Use clean up multiport card detection
  ...

1633 files changed:
CREDITS
Documentation/DocBook/kernel-api.tmpl
Documentation/HOWTO
Documentation/IPMI.txt
Documentation/SubmitChecklist
Documentation/accounting/getdelays.c
Documentation/accounting/taskstats-struct.txt [new file with mode: 0644]
Documentation/fb/intel810.txt
Documentation/fb/intelfb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
Documentation/ia64/serial.txt
Documentation/input/ff.txt
Documentation/kbuild/modules.txt
Documentation/kprobes.txt
Documentation/lockdep-design.txt
Documentation/md.txt
Documentation/rt-mutex-design.txt
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/bttv/Insmod-options
Documentation/video4linux/cx2341x/README.hm12 [new file with mode: 0644]
Documentation/video4linux/cx2341x/README.vbi [new file with mode: 0644]
Documentation/x86_64/boot-options.txt
MAINTAINERS
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/proto.h
arch/alpha/kernel/srmcons.c
arch/alpha/kernel/time.c
arch/alpha/mm/Makefile
arch/alpha/mm/remap.c [deleted file]
arch/arm/kernel/ecard.c
arch/arm/kernel/setup.c
arch/arm/kernel/smp.c
arch/arm/kernel/sys_arm.c
arch/arm/kernel/time.c
arch/arm/mach-pnx4008/clock.c
arch/arm/vfp/vfpsingle.c
arch/arm26/kernel/setup.c
arch/arm26/kernel/sys_arm.c
arch/arm26/kernel/time.c
arch/avr32/kernel/sys_avr32.c
arch/avr32/mm/ioremap.c
arch/cris/arch-v32/kernel/smp.c
arch/cris/kernel/setup.c
arch/cris/kernel/time.c
arch/cris/mm/ioremap.c
arch/frv/Kconfig
arch/frv/kernel/Makefile
arch/frv/kernel/kernel_execve.S [new file with mode: 0644]
arch/h8300/kernel/sys_h8300.c
arch/i386/Kconfig
arch/i386/boot/video.S
arch/i386/defconfig
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/crash.c
arch/i386/kernel/i8237.c
arch/i386/kernel/kprobes.c
arch/i386/kernel/nmi.c
arch/i386/kernel/process.c
arch/i386/kernel/setup.c
arch/i386/kernel/smp.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/sys_i386.c
arch/i386/kernel/time.c
arch/i386/kernel/traps.c
arch/i386/lib/delay.c
arch/i386/mach-voyager/voyager_smp.c
arch/i386/mm/highmem.c
arch/i386/mm/init.c
arch/i386/mm/ioremap.c
arch/i386/pci/mmconfig.c
arch/ia64/Kconfig
arch/ia64/hp/sim/simserial.c
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/kprobes.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/numa.c
arch/ia64/kernel/process.c
arch/ia64/kernel/time.c
arch/ia64/mm/numa.c
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/ia64/sn/pci/pcibr/pcibr_ate.c
arch/ia64/sn/pci/pcibr/pcibr_dma.c
arch/m32r/kernel/sys_m32r.c
arch/m32r/kernel/time.c
arch/m32r/mm/ioremap.c
arch/m68k/kernel/sys_m68k.c
arch/m68k/kernel/time.c
arch/m68knommu/kernel/sys_m68k.c
arch/m68knommu/kernel/time.c
arch/mips/Kconfig
arch/mips/basler/excite/excite_flashtest.c [deleted file]
arch/mips/configs/atlas_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/ddb5477_defconfig
arch/mips/configs/decstation_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/emma2rh_defconfig
arch/mips/configs/ev64120_defconfig
arch/mips/configs/excite_defconfig
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/it8172_defconfig
arch/mips/configs/ivr_defconfig
arch/mips/configs/jaguar-atx_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat200_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/ocelot_3_defconfig
arch/mips/configs/ocelot_c_defconfig
arch/mips/configs/ocelot_defconfig
arch/mips/configs/ocelot_g_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-v2pci_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/configs/rbhma4500_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/sead_defconfig
arch/mips/configs/tb0226_defconfig
arch/mips/configs/tb0229_defconfig
arch/mips/configs/tb0287_defconfig
arch/mips/configs/workpad_defconfig
arch/mips/configs/wrppmc_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/defconfig
arch/mips/kernel/Makefile
arch/mips/kernel/genex.S
arch/mips/kernel/i8259.c
arch/mips/kernel/linux32.c
arch/mips/kernel/process.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/stacktrace.c [new file with mode: 0644]
arch/mips/kernel/syscall.c
arch/mips/kernel/sysirix.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/c-sb1.c
arch/mips/mm/c-tx39.c
arch/mips/mm/cache.c
arch/mips/mm/tlbex-fault.S
arch/mips/sgi-ip22/ip22-reset.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sgi-ip32/ip32-reset.c
arch/parisc/hpux/fs.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/firmware.c
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/time.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/mpc8560ads.dts [new file with mode: 0644]
arch/powerpc/boot/wrapper [new file with mode: 0755]
arch/powerpc/boot/zImage.coff.lds [deleted file]
arch/powerpc/boot/zImage.coff.lds.S [new file with mode: 0644]
arch/powerpc/boot/zImage.lds [deleted file]
arch/powerpc/boot/zImage.lds.S [new file with mode: 0644]
arch/powerpc/configs/chrp32_defconfig
arch/powerpc/configs/g5_defconfig
arch/powerpc/configs/iseries_defconfig
arch/powerpc/configs/mpc7448_hpc2_defconfig
arch/powerpc/configs/mpc834x_itx_defconfig
arch/powerpc/configs/mpc8560_ads_defconfig [new file with mode: 0644]
arch/powerpc/configs/pmac32_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/syscalls.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/time.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/rheap.c
arch/powerpc/math-emu/Makefile
arch/powerpc/oprofile/backtrace.c
arch/powerpc/platforms/83xx/mpc834x_itx.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_ads.h [new file with mode: 0644]
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/hw_ops.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/maple/pci.c
arch/powerpc/platforms/powermac/cpufreq_64.c
arch/powerpc/platforms/powermac/nvram.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/cpm2_common.c [new file with mode: 0644]
arch/powerpc/sysdev/cpm2_pic.c [new file with mode: 0644]
arch/powerpc/sysdev/cpm2_pic.h [new file with mode: 0644]
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/fsl_soc.h
arch/ppc/4xx_io/serial_sicc.c
arch/ppc/boot/utils/mkbugboot.c
arch/ppc/boot/utils/mkprep.c
arch/ppc/kernel/misc.S
arch/ppc/kernel/setup.c
arch/ppc/kernel/time.c
arch/ppc/platforms/mpc8272ads_setup.c
arch/ppc/platforms/mpc866ads_setup.c
arch/ppc/platforms/mpc885ads_setup.c
arch/s390/hypfs/inode.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/head31.S
arch/s390/kernel/head64.S
arch/s390/kernel/kprobes.c
arch/s390/kernel/sys_s390.c
arch/s390/kernel/time.c
arch/s390/lib/spinlock.c
arch/sh/Kconfig
arch/sh/boards/hp6xx/hp6xx_apm.c
arch/sh/boards/hp6xx/pm.c
arch/sh/boards/landisk/irq.c
arch/sh/boards/landisk/landisk_pwb.c
arch/sh/boards/landisk/rtc.c
arch/sh/boards/landisk/setup.c
arch/sh/boards/renesas/r7780rp/irq.c
arch/sh/boards/renesas/r7780rp/led.c
arch/sh/boards/renesas/systemh/setup.c
arch/sh/boards/se/7343/io.c
arch/sh/boards/se/7343/irq.c
arch/sh/boards/se/7343/led.c
arch/sh/boards/se/7343/setup.c
arch/sh/boards/se/770x/setup.c
arch/sh/boards/se/7751/setup.c
arch/sh/boards/sh03/setup.c
arch/sh/boot/.gitignore [new file with mode: 0644]
arch/sh/configs/adx_defconfig [deleted file]
arch/sh/configs/cqreek_defconfig [deleted file]
arch/sh/configs/dreamcast_defconfig
arch/sh/configs/hp6xx_defconfig
arch/sh/configs/hs7751rvoip_defconfig [new file with mode: 0644]
arch/sh/configs/landisk_defconfig
arch/sh/configs/microdev_defconfig
arch/sh/configs/r7780rp_defconfig
arch/sh/configs/rts7751r2d_defconfig
arch/sh/configs/se7300_defconfig
arch/sh/configs/se73180_defconfig
arch/sh/configs/se7343_defconfig
arch/sh/configs/se7705_defconfig
arch/sh/configs/se7750_defconfig
arch/sh/configs/se7751_defconfig
arch/sh/configs/sh03_defconfig
arch/sh/configs/sh7710voipgw_defconfig
arch/sh/configs/shmin_defconfig
arch/sh/configs/snapgear_defconfig
arch/sh/configs/systemh_defconfig
arch/sh/configs/titan_defconfig
arch/sh/drivers/dma/dma-sysfs.c
arch/sh/drivers/pci/ops-landisk.c
arch/sh/drivers/pci/ops-r7780rp.c
arch/sh/drivers/pci/ops-sh03.c
arch/sh/drivers/pci/ops-titan.c
arch/sh/drivers/pci/pci-sh7780.c
arch/sh/kernel/apm.c
arch/sh/kernel/entry.S
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms.c
arch/sh/kernel/smp.c
arch/sh/kernel/sys_sh.c
arch/sh/kernel/time.c
arch/sh/kernel/vsyscall/.gitignore [new file with mode: 0644]
arch/sh/math-emu/math.c
arch/sh/mm/cache-debugfs.c
arch/sh/tools/gen-mach-types
arch/sh64/configs/cayman_defconfig
arch/sh64/kernel/process.c
arch/sh64/kernel/sys_sh64.c
arch/sh64/kernel/time.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sunos.c
arch/sparc/kernel/time.c
arch/sparc64/Kconfig
arch/sparc64/defconfig
arch/sparc64/kernel/power.c
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/time.c
arch/sparc64/solaris/fs.c
arch/sparc64/solaris/misc.c
arch/um/drivers/line.c
arch/um/drivers/mconsole_kern.c
arch/um/drivers/ubd_kern.c
arch/um/include/line.h
arch/um/kernel/syscall.c
arch/um/kernel/um_arch.c
arch/um/os-Linux/process.c
arch/um/os-Linux/sys-i386/tls.c
arch/um/os-Linux/tls.c
arch/um/sys-i386/unmap.c
arch/um/sys-x86_64/syscalls.c
arch/um/sys-x86_64/sysrq.c
arch/um/sys-x86_64/unmap.c
arch/v850/kernel/memcons.c
arch/v850/kernel/rte_cb_leds.c
arch/v850/kernel/rte_mb_a_pci.c
arch/v850/kernel/simcons.c
arch/v850/kernel/syscalls.c
arch/x86_64/Kconfig
arch/x86_64/defconfig
arch/x86_64/ia32/sys_ia32.c
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/sys_x86_64.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/vsyscall.c
arch/x86_64/mm/init.c
arch/x86_64/mm/ioremap.c
arch/x86_64/mm/srat.c
arch/xtensa/kernel/syscalls.c
arch/xtensa/kernel/time.c
arch/xtensa/platform-iss/console.c
block/Kconfig
block/Kconfig.iosched
block/Makefile
block/as-iosched.c
block/blktrace.c
block/cfq-iosched.c
block/deadline-iosched.c
block/elevator.c
block/ioctl.c
block/ll_rw_blk.c
block/noop-iosched.c
block/scsi_ioctl.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/processor_idle.c
drivers/ata/pata_hpt366.c
drivers/base/Makefile
drivers/block/DAC960.c
drivers/block/DAC960.h
drivers/block/Kconfig
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/cciss_cmd.h
drivers/block/cciss_scsi.c
drivers/block/cpqarray.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/paride/pd.c
drivers/block/pktcdvd.c
drivers/block/swim3.c
drivers/block/swim_iop.c
drivers/block/umem.c
drivers/block/xd.c
drivers/cdrom/Kconfig
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/char/Kconfig
drivers/char/agp/amd64-agp.c
drivers/char/agp/generic.c
drivers/char/amiserial.c
drivers/char/cyclades.c
drivers/char/drm/Kconfig
drivers/char/drm/Makefile
drivers/char/drm/drmP.h
drivers/char/drm/drm_auth.c
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_fops.c
drivers/char/drm/drm_hashtab.c [new file with mode: 0644]
drivers/char/drm/drm_hashtab.h [new file with mode: 0644]
drivers/char/drm/drm_ioc32.c
drivers/char/drm/drm_ioctl.c
drivers/char/drm/drm_irq.c
drivers/char/drm/drm_mm.c [new file with mode: 0644]
drivers/char/drm/drm_pciids.h
drivers/char/drm/drm_proc.c
drivers/char/drm/drm_sman.c [new file with mode: 0644]
drivers/char/drm/drm_sman.h [new file with mode: 0644]
drivers/char/drm/drm_stub.c
drivers/char/drm/drm_vm.c
drivers/char/drm/i810_dma.c
drivers/char/drm/i830_dma.c
drivers/char/drm/i915_dma.c
drivers/char/drm/i915_drm.h
drivers/char/drm/i915_drv.h
drivers/char/drm/i915_irq.c
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_drv.c
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_state.c
drivers/char/drm/sis_drv.c
drivers/char/drm/sis_drv.h
drivers/char/drm/sis_ds.c [deleted file]
drivers/char/drm/sis_ds.h [deleted file]
drivers/char/drm/sis_mm.c
drivers/char/drm/via_dmablit.c
drivers/char/drm/via_drm.h
drivers/char/drm/via_drv.c
drivers/char/drm/via_drv.h
drivers/char/drm/via_ds.c [deleted file]
drivers/char/drm/via_ds.h [deleted file]
drivers/char/drm/via_map.c
drivers/char/drm/via_mm.c
drivers/char/ds1286.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/hvc_console.c
drivers/char/hvc_iseries.c
drivers/char/hvcs.c
drivers/char/hvsi.c
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/keyboard.c
drivers/char/mbcs.c
drivers/char/moxa.c
drivers/char/mwave/mwavedd.c
drivers/char/mxser.c
drivers/char/nwbutton.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/pty.c
drivers/char/random.c
drivers/char/raw.c
drivers/char/rio/rio_linux.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/ser_a2232.c
drivers/char/serial167.c
drivers/char/snsc_event.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/sysrq.c
drivers/char/tipar.c
drivers/char/tty_io.c
drivers/char/viocons.c
drivers/char/vme_scc.c
drivers/char/vt.c
drivers/char/vt_ioctl.c
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Makefile
drivers/char/watchdog/acquirewdt.c
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/alim1535_wdt.c
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/at91_wdt.c
drivers/char/watchdog/booke_wdt.c
drivers/char/watchdog/cpu5wdt.c
drivers/char/watchdog/ep93xx_wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/i6300esb.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/ibmasr.c
drivers/char/watchdog/indydog.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ixp4xx_wdt.c
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/mpc83xx_wdt.c
drivers/char/watchdog/mpc8xx_wdt.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/mv64x60_wdt.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/pnx4008_wdt.c [new file with mode: 0644]
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/sa1100_wdt.c
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/scx200_wdt.c
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/w83627hf_wdt.c
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/w83977f_wdt.c
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wdrtas.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt285.c
drivers/char/watchdog/wdt977.c
drivers/char/watchdog/wdt_pci.c
drivers/cpufreq/cpufreq.c
drivers/fc4/fc.c
drivers/firmware/dell_rbu.c
drivers/hwmon/hdaps.c
drivers/i2c/busses/i2c-ite.c
drivers/i2c/i2c-core.c
drivers/ide/Kconfig
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-lib.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/hd.c
drivers/ide/legacy/ide-cs.c
drivers/ide/pci/Makefile
drivers/ide/pci/cs5530.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/generic.c
drivers/ide/pci/jmicron.c [new file with mode: 0644]
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/serverworks.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/via82cxxx.c
drivers/ide/setup-pci.c
drivers/ieee1394/Kconfig
drivers/ieee1394/csr.c
drivers/ieee1394/csr.h
drivers/ieee1394/dma.c
drivers/ieee1394/dma.h
drivers/ieee1394/dv1394-private.h
drivers/ieee1394/dv1394.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/highlevel.h
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.h
drivers/ieee1394/ieee1394-ioctl.h
drivers/ieee1394/ieee1394.h
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.h
drivers/ieee1394/ieee1394_hotplug.h
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.h
drivers/ieee1394/ieee1394_types.h
drivers/ieee1394/iso.c
drivers/ieee1394/iso.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/ohci1394.c
drivers/ieee1394/raw1394-private.h
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.h
drivers/ieee1394/video1394.c
drivers/infiniband/core/cma.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_tools.h
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/evbug.c
drivers/input/evdev.c
drivers/input/ff-core.c [new file with mode: 0644]
drivers/input/ff-memless.c [new file with mode: 0644]
drivers/input/fixp-arith.h [new file with mode: 0644]
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/iforce/iforce-ff.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce.h
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/stowaway.c [new file with mode: 0644]
drivers/input/misc/uinput.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/lifebook.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/sermouse.c
drivers/input/mouse/synaptics.c
drivers/input/mousedev.c
drivers/input/power.c
drivers/input/serio/i8042-io.h
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/i8042.h
drivers/input/serio/libps2.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/penmount.c [new file with mode: 0644]
drivers/input/touchscreen/touchright.c [new file with mode: 0644]
drivers/input/touchscreen/touchwin.c [new file with mode: 0644]
drivers/input/tsdev.c
drivers/isdn/capi/capi.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/proc.c
drivers/isdn/hardware/eicon/dsp_defs.h
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hisax/st5481_b.c
drivers/isdn/hisax/st5481_d.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/sc/command.c
drivers/isdn/sc/event.c
drivers/isdn/sc/interrupt.c
drivers/isdn/sc/timer.c
drivers/leds/led-triggers.c
drivers/macintosh/smu.c
drivers/macintosh/via-pmu.c
drivers/macintosh/via-pmu68k.c
drivers/macintosh/windfarm_smu_controls.c
drivers/macintosh/windfarm_smu_sensors.c
drivers/md/Kconfig
drivers/md/bitmap.c
drivers/md/dm-crypt.c
drivers/md/dm-emc.c
drivers/md/dm-exception-store.c
drivers/md/dm-linear.c
drivers/md/dm-mpath.c
drivers/md/dm-raid1.c
drivers/md/dm-snap.c
drivers/md/dm-snap.h
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/common/Kconfig
drivers/media/common/ir-keymaps.c
drivers/media/common/saa7146_fops.c
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
drivers/media/dvb/bt8xx/Kconfig
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/bt8xx/dst_common.h
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/dvb-core/Kconfig
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-core/dvb_ringbuffer.c
drivers/media/dvb/dvb-core/dvbdev.h
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/a800.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/dibusb-mb.c
drivers/media/dvb/dvb-usb/dibusb-mc.c
drivers/media/dvb/dvb-usb/dibusb.h
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/media/dvb/dvb-usb/nova-t-usb2.c
drivers/media/dvb/dvb-usb/umt-010.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/bcm3510.h
drivers/media/dvb/frontends/cx22700.h
drivers/media/dvb/frontends/cx22702.c
drivers/media/dvb/frontends/cx22702.h
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/cx24110.h
drivers/media/dvb/frontends/cx24123.c
drivers/media/dvb/frontends/cx24123.h
drivers/media/dvb/frontends/dib3000-common.c [deleted file]
drivers/media/dvb/frontends/dib3000-common.h [deleted file]
drivers/media/dvb/frontends/dib3000.h
drivers/media/dvb/frontends/dib3000mb.c
drivers/media/dvb/frontends/dib3000mb_priv.h
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dib3000mc.h [new file with mode: 0644]
drivers/media/dvb/frontends/dib3000mc_priv.h [deleted file]
drivers/media/dvb/frontends/dibx000_common.c [new file with mode: 0644]
drivers/media/dvb/frontends/dibx000_common.h [new file with mode: 0644]
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/isl6421.c
drivers/media/dvb/frontends/isl6421.h
drivers/media/dvb/frontends/l64781.h
drivers/media/dvb/frontends/lgdt330x.h
drivers/media/dvb/frontends/lnbp21.c
drivers/media/dvb/frontends/lnbp21.h
drivers/media/dvb/frontends/mt2060.c [new file with mode: 0644]
drivers/media/dvb/frontends/mt2060.h [new file with mode: 0644]
drivers/media/dvb/frontends/mt2060_priv.h [new file with mode: 0644]
drivers/media/dvb/frontends/mt312.h
drivers/media/dvb/frontends/mt352.c
drivers/media/dvb/frontends/mt352.h
drivers/media/dvb/frontends/nxt200x.h
drivers/media/dvb/frontends/nxt6000.h
drivers/media/dvb/frontends/or51132.h
drivers/media/dvb/frontends/or51211.h
drivers/media/dvb/frontends/s5h1420.h
drivers/media/dvb/frontends/sp8870.h
drivers/media/dvb/frontends/sp887x.h
drivers/media/dvb/frontends/stv0297.h
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/stv0299.h
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/tda10021.h
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda1004x.h
drivers/media/dvb/frontends/tda10086.c [new file with mode: 0644]
drivers/media/dvb/frontends/tda10086.h [new file with mode: 0644]
drivers/media/dvb/frontends/tda8083.h
drivers/media/dvb/frontends/tda826x.c [new file with mode: 0644]
drivers/media/dvb/frontends/tda826x.h [new file with mode: 0644]
drivers/media/dvb/frontends/tua6100.c [new file with mode: 0644]
drivers/media/dvb/frontends/tua6100.h [new file with mode: 0644]
drivers/media/dvb/frontends/ves1820.h
drivers/media/dvb/frontends/ves1x93.h
drivers/media/dvb/frontends/zl10353.c
drivers/media/dvb/frontends/zl10353.h
drivers/media/dvb/ttpci/Kconfig
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110_av.c
drivers/media/dvb/ttpci/av7110_ca.c
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/dvb/ttpci/av7110_v4l.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-patch.c
drivers/media/dvb/ttpci/budget.c
drivers/media/dvb/ttusb-budget/Kconfig
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/radio/Kconfig
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/radio/radio-gemtek.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-rtrack2.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-terratec.c
drivers/media/radio/radio-trust.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/bt866.c
drivers/media/video/bt8xx/Kconfig
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bt8xx/bttv-i2c.c
drivers/media/video/compat_ioctl32.c
drivers/media/video/cpia2/cpia2.h
drivers/media/video/cx2341x.c
drivers/media/video/cx25840/Kconfig
drivers/media/video/cx25840/cx25840-vbi.c
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-i2c.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-tvaudio.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h
drivers/media/video/em28xx/Kconfig
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/ks0127.c
drivers/media/video/pvrusb2/Kconfig
drivers/media/video/pvrusb2/Makefile
drivers/media/video/pvrusb2/pvrusb2-ctrl.c
drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
drivers/media/video/pvrusb2/pvrusb2-encoder.c
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/pvrusb2/pvrusb2-main.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7115.c
drivers/media/video/saa711x_regs.h [new file with mode: 0644]
drivers/media/video/saa7134/Kconfig
drivers/media/video/saa7134/Makefile
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda9887.c
drivers/media/video/tuner-simple.c
drivers/media/video/tuner-types.c
drivers/media/video/tvaudio.c
drivers/media/video/tveeprom.c
drivers/media/video/tvp5150.c
drivers/media/video/usbvideo/konicawc.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-common.c
drivers/media/video/video-buf-dvb.c
drivers/media/video/videodev.c
drivers/media/video/vino.c
drivers/media/video/vivi.c
drivers/media/video/vpx3220.c
drivers/media/video/zoran_card.c
drivers/media/video/zoran_driver.c
drivers/media/video/zr36120.c
drivers/message/i2o/Kconfig
drivers/message/i2o/i2o_block.c
drivers/message/i2o/pci.c
drivers/misc/Makefile
drivers/misc/lkdtm.c [new file with mode: 0644]
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/mmc_queue.c
drivers/mmc/sdhci.c
drivers/mmc/sdhci.h
drivers/mmc/wbsd.c
drivers/mmc/wbsd.h
drivers/mtd/Kconfig
drivers/mtd/devices/Kconfig
drivers/mtd/maps/arctic-mtd.c
drivers/mtd/maps/beech-mtd.c
drivers/mtd/maps/cstm_mips_ixx.c
drivers/mtd/maps/nettel.c
drivers/mtd/maps/redwood.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/nand/edb7312.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nftlcore.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/onenand_base.c
drivers/net/Space.c
drivers/net/dgrs.c
drivers/net/e100.c
drivers/net/e1000/LICENSE [deleted file]
drivers/net/e1000/Makefile
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_osdep.h
drivers/net/e1000/e1000_param.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/hp100.c
drivers/net/ifb.c
drivers/net/ixgb/Makefile
drivers/net/ixgb/ixgb.h
drivers/net/ixgb/ixgb_ee.c
drivers/net/ixgb/ixgb_ee.h
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_hw.c
drivers/net/ixgb/ixgb_hw.h
drivers/net/ixgb/ixgb_ids.h
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/ixgb/ixgb_param.c
drivers/net/phy/fixed.c
drivers/net/phy/phy_device.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/spider_net.c
drivers/net/tun.c
drivers/net/wireless/airo.c
drivers/net/wireless/ipw2100.c
drivers/parisc/led.c
drivers/parisc/power.c
drivers/pci/quirks.c
drivers/pcmcia/cardbus.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/socket_sysfs.c
drivers/pnp/isapnp/core.c
drivers/pnp/pnpbios/core.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/class.c
drivers/rtc/rtc-at91.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-ep93xx.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-lib.c
drivers/rtc/rtc-m48t86.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pcf8583.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-proc.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-test.c
drivers/rtc/rtc-v3020.c
drivers/rtc/rtc-vr41xx.c
drivers/rtc/rtc-x1205.c
drivers/s390/block/Kconfig
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_fba.c
drivers/s390/char/con3215.c
drivers/s390/char/fs3270.c
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tty3270.c
drivers/s390/s390mach.c
drivers/s390/scsi/zfcp_scsi.c
drivers/sbus/char/aurora.c
drivers/sbus/char/bbc_envctrl.c
drivers/sbus/char/envctrl.c
drivers/scsi/53c700.c
drivers/scsi/BusLogic.h
drivers/scsi/Kconfig
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/gdth.c
drivers/scsi/ide-scsi.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/pluto.c
drivers/scsi/qla1280.c
drivers/scsi/scsi.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3_scsi.c
drivers/scsi/sun3_scsi_vme.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/8250_acorn.c
drivers/serial/8250_gsc.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/cpm_uart/cpm_uart_cpm2.h
drivers/serial/crisv10.c
drivers/serial/ioc4_serial.c
drivers/serial/ip22zilog.c
drivers/serial/mcfserial.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/mux.c
drivers/serial/serial_core.c
drivers/serial/sunsu.c
drivers/tc/zs.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/devio.c
drivers/usb/core/hcd.c
drivers/usb/core/inode.c
drivers/usb/core/usb.h
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/serial.c
drivers/usb/gadget/zero.c
drivers/usb/input/Kconfig
drivers/usb/input/Makefile
drivers/usb/input/fixp-arith.h [deleted file]
drivers/usb/input/hid-core.c
drivers/usb/input/hid-ff.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid-lgff.c
drivers/usb/input/hid-pidff.c [new file with mode: 0644]
drivers/usb/input/hid-tmff.c
drivers/usb/input/hid-zpff.c [new file with mode: 0644]
drivers/usb/input/hid.h
drivers/usb/input/pid.c [deleted file]
drivers/usb/input/pid.h [deleted file]
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/aty/atyfb.h
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_ct.c
drivers/video/aty/radeon_i2c.c
drivers/video/aty/radeon_pm.c
drivers/video/au1100fb.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_cw.c
drivers/video/console/fbcon_ud.c
drivers/video/console/softcursor.c
drivers/video/fb_ddc.c [new file with mode: 0644]
drivers/video/fbmem.c
drivers/video/fbsysfs.c
drivers/video/i810/i810-i2c.c
drivers/video/i810/i810_main.c
drivers/video/intelfb/Makefile
drivers/video/intelfb/intelfb.h
drivers/video/intelfb/intelfb_i2c.c [new file with mode: 0644]
drivers/video/intelfb/intelfbdrv.c
drivers/video/intelfb/intelfbhw.c
drivers/video/intelfb/intelfbhw.h
drivers/video/matrox/matroxfb_base.c
drivers/video/mbx/mbxfb.c
drivers/video/nvidia/nv_i2c.c
drivers/video/nvidia/nvidia.c
drivers/video/riva/fbdev.c
drivers/video/riva/rivafb-i2c.c
drivers/video/savage/savagefb-i2c.c
drivers/video/sis/init.h
drivers/video/sis/init301.h
drivers/video/sis/initextlfb.c
drivers/video/sis/osdef.h
drivers/video/sis/sis_accel.c
drivers/video/sis/sis_accel.h
drivers/video/sis/sis_main.c
drivers/video/sis/sis_main.h
drivers/video/sis/vgatypes.h
drivers/video/sstfb.c
fs/9p/vfs_inode.c
fs/Kconfig
fs/Makefile
fs/adfs/file.c
fs/affs/file.c
fs/afs/dir.c
fs/afs/file.c
fs/aio.c
fs/autofs/root.c
fs/autofs4/root.c
fs/bad_inode.c
fs/bfs/dir.c
fs/bfs/file.c
fs/binfmt_elf.c
fs/bio.c
fs/block_dev.c
fs/buffer.c
fs/char_dev.c
fs/cifs/cifsfs.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/ioctl.c
fs/cifs/sess.c
fs/coda/dir.c
fs/compat.c
fs/compat_ioctl.c
fs/configfs/dir.c
fs/configfs/file.c
fs/configfs/mount.c
fs/dcache.c
fs/debugfs/inode.c
fs/dnotify.c
fs/eventpoll.c
fs/exec.c
fs/exportfs/expfs.c
fs/ext2/dir.c
fs/ext2/ext2.h
fs/ext2/file.c
fs/ext2/ioctl.c
fs/ext2/namei.c
fs/ext3/dir.c
fs/ext3/file.c
fs/ext3/inode.c
fs/ext3/ioctl.c
fs/ext3/namei.c
fs/fat/dir.c
fs/fat/file.c
fs/fcntl.c
fs/file_table.c
fs/fs-writeback.c
fs/fuse/control.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/hfs/dir.c
fs/hfs/inode.c
fs/hfsplus/dir.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/hfsplus/ioctl.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/hpfs/namei.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/internal.h [new file with mode: 0644]
fs/ioprio.c
fs/jffs/inode-v23.c
fs/jffs2/dir.c
fs/jffs2/file.c
fs/jffs2/fs.c
fs/jfs/acl.c
fs/jfs/endian24.h
fs/jfs/file.c
fs/jfs/inode.c
fs/jfs/ioctl.c
fs/jfs/jfs_acl.h
fs/jfs/jfs_btree.h
fs/jfs/jfs_debug.c
fs/jfs/jfs_dinode.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.h
fs/jfs/jfs_extent.c
fs/jfs/jfs_extent.h
fs/jfs/jfs_filsys.h
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.h
fs/jfs/jfs_incore.h
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_lock.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.h
fs/jfs/jfs_mount.c
fs/jfs/jfs_superblock.h
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.h
fs/jfs/jfs_types.h
fs/jfs/jfs_umount.c
fs/jfs/jfs_unicode.c
fs/jfs/jfs_unicode.h
fs/jfs/jfs_uniupr.c
fs/jfs/jfs_xattr.h
fs/jfs/jfs_xtree.c
fs/jfs/jfs_xtree.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/super.c
fs/jfs/symlink.c
fs/jfs/xattr.c
fs/libfs.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/mon.c
fs/lockd/svc.c
fs/lockd/svclock.c
fs/lockd/xdr.c
fs/locks.c
fs/minix/file.c
fs/minix/namei.c
fs/mpage.c
fs/msdos/namei.c
fs/namei.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/ioctl.c
fs/nfs/callback.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/file.c
fs/nfs/nfsroot.c
fs/nfs/write.c
fs/nfsd/export.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/nfsd/vfs.c
fs/nls/nls_base.c
fs/no-block.c [new file with mode: 0644]
fs/ntfs/aops.c
fs/ntfs/aops.h
fs/ntfs/attrib.c
fs/ntfs/attrib.h
fs/ntfs/bitmap.c
fs/ntfs/bitmap.h
fs/ntfs/collate.h
fs/ntfs/compress.c
fs/ntfs/file.c
fs/ntfs/index.c
fs/ntfs/index.h
fs/ntfs/inode.c
fs/ntfs/layout.h
fs/ntfs/lcnalloc.c
fs/ntfs/lcnalloc.h
fs/ntfs/logfile.c
fs/ntfs/logfile.h
fs/ntfs/mft.c
fs/ntfs/mft.h
fs/ntfs/ntfs.h
fs/ntfs/quota.c
fs/ntfs/quota.h
fs/ntfs/runlist.c
fs/ntfs/super.c
fs/ntfs/types.h
fs/ntfs/unistr.c
fs/ntfs/usnjrnl.c
fs/ntfs/usnjrnl.h
fs/ocfs2/dlm/dlmfs.c
fs/ocfs2/file.c
fs/ocfs2/namei.c
fs/open.c
fs/partitions/Makefile
fs/partitions/ldm.c
fs/pipe.c
fs/posix_acl.c
fs/proc/array.c
fs/proc/base.c
fs/proc/proc_misc.c
fs/proc/root.c
fs/qnx4/file.c
fs/qnx4/namei.c
fs/quota.c
fs/ramfs/file-mmu.c
fs/ramfs/file-nommu.c
fs/ramfs/inode.c
fs/read_write.c
fs/read_write.h [new file with mode: 0644]
fs/readdir.c
fs/reiserfs/bitmap.c
fs/reiserfs/dir.c
fs/reiserfs/file.c
fs/reiserfs/ioctl.c
fs/reiserfs/namei.c
fs/reiserfs/resize.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/smbfs/file.c
fs/splice.c
fs/stat.c
fs/super.c
fs/sync.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/mount.c
fs/sysv/file.c
fs/sysv/namei.c
fs/udf/file.c
fs/udf/inode.c
fs/udf/namei.c
fs/ufs/file.c
fs/ufs/namei.c
fs/utimes.c [new file with mode: 0644]
fs/vfat/namei.c
fs/xfs/Kconfig
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_lrw.c
include/asm-alpha/spinlock.h
include/asm-alpha/unistd.h
include/asm-arm/arch-pnx4008/clock.h
include/asm-arm/spinlock.h
include/asm-arm/unistd.h
include/asm-arm26/unistd.h
include/asm-avr32/unistd.h
include/asm-cris/arch-v32/spinlock.h
include/asm-cris/unistd.h
include/asm-frv/pgtable.h
include/asm-frv/timex.h
include/asm-frv/unistd.h
include/asm-generic/pgtable.h
include/asm-h8300/keyboard.h
include/asm-h8300/unistd.h
include/asm-i386/bugs.h
include/asm-i386/elf.h
include/asm-i386/mca_dma.h
include/asm-i386/nmi.h
include/asm-i386/pgtable-2level.h
include/asm-i386/pgtable-3level.h
include/asm-i386/pgtable.h
include/asm-i386/ptrace.h
include/asm-i386/smp.h
include/asm-i386/spinlock.h
include/asm-i386/topology.h
include/asm-i386/unistd.h
include/asm-ia64/ptrace.h
include/asm-ia64/spinlock.h
include/asm-ia64/topology.h
include/asm-ia64/unistd.h
include/asm-m32r/pgtable-2level.h
include/asm-m32r/spinlock.h
include/asm-m32r/timex.h
include/asm-m32r/unistd.h
include/asm-m68k/unistd.h
include/asm-m68knommu/unistd.h
include/asm-mips/cacheflush.h
include/asm-mips/galileo-boards/ev96100.h [deleted file]
include/asm-mips/galileo-boards/ev96100int.h [deleted file]
include/asm-mips/irqflags.h
include/asm-mips/mach-ev64120/mach-gt64120.h
include/asm-mips/mach-ip27/topology.h
include/asm-mips/serial.h
include/asm-mips/spinlock.h
include/asm-mips/stacktrace.h [new file with mode: 0644]
include/asm-mips/unistd.h
include/asm-parisc/spinlock.h
include/asm-parisc/unistd.h
include/asm-powerpc/fs_pd.h [new file with mode: 0644]
include/asm-powerpc/io.h
include/asm-powerpc/kprobes.h
include/asm-powerpc/mpc85xx.h [new file with mode: 0644]
include/asm-powerpc/ptrace.h
include/asm-powerpc/spinlock.h
include/asm-powerpc/time.h
include/asm-powerpc/topology.h
include/asm-powerpc/unistd.h
include/asm-ppc/cpm2.h
include/asm-ppc/fs_pd.h [new file with mode: 0644]
include/asm-ppc/rheap.h
include/asm-ppc/spinlock.h
include/asm-s390/ptrace.h
include/asm-s390/setup.h
include/asm-s390/spinlock.h
include/asm-s390/spinlock_types.h
include/asm-s390/unistd.h
include/asm-sh/.gitignore [new file with mode: 0644]
include/asm-sh/bugs.h
include/asm-sh/cpu-sh3/rtc.h [deleted file]
include/asm-sh/cpu-sh4/rtc.h [deleted file]
include/asm-sh/ec3104/keyboard.h
include/asm-sh/elf.h
include/asm-sh/hs7751rvoip/io.h [deleted file]
include/asm-sh/mpc1211/keyboard.h
include/asm-sh/rts7751r2d/io.h [deleted file]
include/asm-sh/rts7751r2d/rts7751r2d.h
include/asm-sh/sfp-machine.h
include/asm-sh/spinlock.h
include/asm-sh/string.h
include/asm-sh/unistd.h
include/asm-sh64/keyboard.h
include/asm-sh64/timex.h
include/asm-sh64/unistd.h
include/asm-sparc/spinlock.h
include/asm-sparc/unistd.h
include/asm-sparc64/compat_signal.h [new file with mode: 0644]
include/asm-sparc64/signal.h
include/asm-sparc64/spinlock.h
include/asm-sparc64/unistd.h
include/asm-um/unistd.h
include/asm-v850/unistd.h
include/asm-x86_64/nmi.h
include/asm-x86_64/ptrace.h
include/asm-x86_64/semaphore.h
include/asm-x86_64/spinlock.h
include/asm-x86_64/topology.h
include/asm-x86_64/uaccess.h
include/asm-x86_64/unistd.h
include/asm-x86_64/vsyscall.h
include/asm-xtensa/timex.h
include/asm-xtensa/unistd.h
include/linux/acct.h
include/linux/aio.h
include/linux/aio_abi.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/blktrace_api.h
include/linux/buffer_head.h
include/linux/compat.h
include/linux/compat_ioctl.h
include/linux/compiler.h
include/linux/console.h
include/linux/console_struct.h
include/linux/consolemap.h
include/linux/device-mapper.h
include/linux/dm-ioctl.h
include/linux/elevator.h
include/linux/ext2_fs.h
include/linux/ext3_fs.h
include/linux/fb.h
include/linux/fs.h
include/linux/fs_enet_pd.h
include/linux/fs_uart_pd.h
include/linux/genalloc.h
include/linux/genhd.h
include/linux/getcpu.h
include/linux/i2c-id.h
include/linux/ide.h
include/linux/init_task.h
include/linux/input.h
include/linux/io.h
include/linux/ipc.h
include/linux/ipmi.h
include/linux/kallsyms.h
include/linux/kernel.h
include/linux/kmod.h
include/linux/kprobes.h
include/linux/latency.h [new file with mode: 0644]
include/linux/libps2.h
include/linux/lockd/bind.h
include/linux/lockd/lockd.h
include/linux/memory.h
include/linux/memory_hotplug.h
include/linux/mm.h
include/linux/module.h
include/linux/mpage.h
include/linux/mtd/nand.h
include/linux/mtd/onenand.h
include/linux/mtd/onenand_regs.h
include/linux/namei.h
include/linux/namespace.h
include/linux/ncp_fs.h
include/linux/nfs_fs.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/nfsfh.h
include/linux/nfsd/syscall.h
include/linux/nodemask.h
include/linux/nsproxy.h [new file with mode: 0644]
include/linux/pci.h
include/linux/pid.h
include/linux/proc_fs.h
include/linux/pspace.h [new file with mode: 0644]
include/linux/raid/bitmap.h
include/linux/raid/md.h
include/linux/raid/md_k.h
include/linux/raid/md_u.h
include/linux/raid/raid1.h
include/linux/raid/raid10.h
include/linux/raid/raid5.h
include/linux/ramfs.h
include/linux/rbtree.h
include/linux/reiserfs_fs.h
include/linux/reiserfs_fs_sb.h
include/linux/rtc.h
include/linux/sched.h
include/linux/serio.h
include/linux/stat.h
include/linux/stddef.h
include/linux/string.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcsock.h
include/linux/synclink.h
include/linux/syscalls.h
include/linux/sysrq.h
include/linux/taskstats.h
include/linux/timex.h
include/linux/topology.h
include/linux/tsacct_kern.h [new file with mode: 0644]
include/linux/tty.h
include/linux/tty_driver.h
include/linux/types.h
include/linux/uinput.h
include/linux/unistd.h
include/linux/unwind.h
include/linux/utime.h
include/linux/utsname.h
include/linux/videodev2.h
include/linux/vt_kern.h
include/linux/writeback.h
include/media/ir-common.h
include/media/tuner-types.h
include/media/tuner.h
include/media/v4l2-common.h
include/media/v4l2-dev.h
include/mtd/Kbuild
include/mtd/mtd-abi.h
include/net/genetlink.h
include/net/sock.h
include/scsi/scsi_device.h
include/scsi/scsi_tcq.h
include/sound/pcm.h
include/video/sstfb.h
init/Kconfig
init/do_mounts.c
init/do_mounts_initrd.c
init/do_mounts_md.c
init/main.c
init/version.c
ipc/mqueue.c
ipc/msg.c
ipc/sem.c
ipc/shm.c
ipc/util.c
ipc/util.h
kernel/Makefile
kernel/acct.c
kernel/cpuset.c
kernel/dma.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/kallsyms.c
kernel/kmod.c
kernel/kprobes.c
kernel/latency.c [new file with mode: 0644]
kernel/lockdep.c
kernel/module.c
kernel/nsproxy.c [new file with mode: 0644]
kernel/panic.c
kernel/pid.c
kernel/power/snapshot.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/spinlock.c
kernel/sys.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/taskstats.c
kernel/time.c
kernel/time/Makefile
kernel/time/ntp.c [new file with mode: 0644]
kernel/timer.c
kernel/tsacct.c [new file with mode: 0644]
kernel/utsname.c [new file with mode: 0644]
lib/Kconfig.debug
lib/Makefile
lib/cpumask.c
lib/errno.c [deleted file]
lib/genalloc.c
lib/ioremap.c [new file with mode: 0644]
lib/list_debug.c
lib/rbtree.c
lib/sort.c
mm/Kconfig
mm/Makefile
mm/bounce.c [new file with mode: 0644]
mm/filemap.c
mm/fremap.c
mm/highmem.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/migrate.c
mm/mprotect.c
mm/mremap.c
mm/nommu.c
mm/page-writeback.c
mm/shmem.c
mm/truncate.c
mm/util.c
net/bluetooth/rfcomm/tty.c
net/ipv4/ipconfig.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/tcp_probe.c
net/irda/ircomm/ircomm_tty.c
net/rxrpc/transport.c
net/socket.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
net/sunrpc/sunrpc_syms.c
net/sunrpc/svc.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
scripts/.gitignore
scripts/Makefile
scripts/Makefile.modpost
scripts/kconfig/Makefile
scripts/kconfig/confdata.c
scripts/kconfig/lxdialog/Makefile [deleted file]
scripts/kconfig/lxdialog/checklist.c
scripts/kconfig/lxdialog/colors.h [deleted file]
scripts/kconfig/lxdialog/dialog.h
scripts/kconfig/lxdialog/inputbox.c
scripts/kconfig/lxdialog/lxdialog.c [deleted file]
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/lxdialog/msgbox.c [deleted file]
scripts/kconfig/lxdialog/textbox.c
scripts/kconfig/lxdialog/util.c
scripts/kconfig/lxdialog/yesno.c
scripts/kconfig/mconf.c
security/inode.c
security/selinux/selinuxfs.c
sound/core/info_oss.c
sound/core/pcm.c
sound/core/pcm_native.c
sound/oss/cs46xx.c
sound/oss/swarm_cs4297a.c
sound/oss/trident.c
sound/oss/via82cxxx_audio.c
sound/pci/echoaudio/layla24_dsp.c
sound/usb/usbaudio.c
sound/usb/usbmidi.c

diff --git a/CREDITS b/CREDITS
index 66e82466dde8af73c814354d8e4df82398e78e5c..6c06ded9882b39300e76f2cea4d57f78ff47f752 100644 (file)
--- 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
index 6d4b1ef5b6f11a24a1705e1c0e73b17220feb35c..49c745720f47360edba2a19b0f441233acf317a2 100644 (file)
@@ -325,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>
index 1d6560413cc593e001080759ce867c070956aeb7..d6f3dd1a3464f0cd6950e1c6dcecc4f7bcb6c84f 100644 (file)
@@ -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
 -------------
 
index 0256805b548f8c43906c07b4e05ab1f76ae1f972..9f08d73d90bf12251770e0d22bd8cd1a2c18a70e 100644 (file)
@@ -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.
 
index a6cb6ffd293377bef9a19cd077299626fcb5bf47..7ac61f60037af81905aad58a39d70152f333eb82 100644 (file)
@@ -64,3 +64,5 @@ kernel patches.
 
 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'.
index 795ca3911cc58f7fd043a6e51b95df8e9bff449f..b11792abd6b616d56754edcc9b940a519f7a36fb 100644 (file)
@@ -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 (file)
index 0000000..661c797
--- /dev/null
@@ -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 */
+
+}
index 4f0d6bc789ef0fadf101eaa362fa3d829dc8a588..be3e7836abef235c5140cf7810eee84f27b8d835 100644 (file)
@@ -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
index c12d39a23c3d1b43827f2fe37a1b1776036db2d1..da5ee74219e8c55016dda1f8d1a6fb4820e5e717 100644 (file)
@@ -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
index 436697cb93882e174199d7f00efc1d243954ac75..b98f01fc14bf8e8e2f1f8b1fe2e07139f0ed32a9 100644 (file)
@@ -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>
+
+---------------------------
index 247d7f619aa2c8cc86e7777004c198428798ff9c..eb1a6cad21e6a8cadc993111b1f4c7099d794ad2 100644 (file)
@@ -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,
index 1cb7e8be927ad55acdd739bd31439096d9c55d5d..cd07c21b84005cb4e2cd3980f1c103ec94824662 100644 (file)
@@ -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);
index f51eb4bc2ff1e1635c0ca1b14c9db9e90de2fb56..040b9773209fe173e61f4c79d23db74ecf6c0118 100644 (file)
@@ -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
index c7e10eaff203c595e3ba99bd77540e7b86889723..c53b1c11aa40959f082579c490a3ffe994811d08 100644 (file)
@@ -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.
+
index 2e7702e94a786c0942c91134da25fef40ecc07b4..769ee05ee4d1f6da279386c2325ff5f80e322570 100644 (file)
@@ -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
index 2c3b1eae42801ae38fe9fe4eb2174f15b44c89f3..ba26201d50234ba3c78e2c0c9084b1d6d25d7110 100644 (file)
@@ -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)
index 00d93605bfd3093f377ea2325719e9b0140577da..55a7e4fa8cc2b5d37635188475d15e6e9268073e 100644 (file)
@@ -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:
 ------------------------
 
index 0668f9dc9d29635393e5876b15b1a3bce9abaa13..9ae9e40789858c36895c976c8cc606de5332c14e 100644 (file)
@@ -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
index c472ffacc2f6f6cfa517e70df96211919b2767e8..4b736d24da7a95ef0b292c542bedccf9122448f1 100644 (file)
@@ -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.
 
index 00d9a1f2a54c05dc01d1ab0b16b3b90f7aad6bf1..669a09aa5bb463934d96c25a76dc0346b8611fe8 100644 (file)
@@ -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]
index 9068b669f5ee5d34af6dac4ff91a834df623b2f1..94cf695b1378ce8f79dd763448d3303909b76d19 100644 (file)
@@ -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]
index fc94ff235ffac51f1f0079bbe673f47c3a460632..bb7c2cac7917e97bd206442747eb6b0e77356c42 100644 (file)
@@ -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 (file)
index 0000000..0e213ed
--- /dev/null
@@ -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 (file)
index 0000000..5807cf1
--- /dev/null
@@ -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>
index 4303e0c12476d1afb4af9c7998e46cb2ed4b7494..74b77f9e91bc5cc5692eee19fc0b4b6be3a49302 100644 (file)
@@ -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]
 
index 2c752d18e24b677f865a1a9d5a81f7aa38972045..28cd70cf3e9912077da3f5e21ba14fb3e250dd43 100644 (file)
@@ -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
@@ -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
@@ -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
@@ -2842,17 +2817,13 @@ P:      Paul Mundt
 M:     lethal@linux-sh.org
 L:     linuxsh-dev@lists.sourceforge.net (subscribers-only)
 W:     http://www.linux-sh.org
-W:     http://www.m17n.org/linux-sh/
 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
@@ -2993,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
index f042cc42b00fc531f7c8e6528aae05002a72b172..dbe327d32b6f03327fdab830d405c11a7bcf87f4 100644 (file)
@@ -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);
 
index 01ecd09d4a64c42be3a6872d6f068e0492db03d9..c95e95e1ab0423b2664e8359a32ff2da0d13372d 100644 (file)
@@ -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
 
 \f
 /*
index 73c7622b529755d2d42def44da80ee335c631df7..ad61736519950e72debd8fa691a9c59181a361a8 100644 (file)
@@ -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 */
index 2a6e3da8144f01440733135289cb8760c872804c..21f71287b6f5f11b511a939d54222d4f4b5e7087 100644 (file)
@@ -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 */
 
index 9d7dff27f81562e986064ff55d68d045cd8ca5fb..75692320386080c25a730f1e78779b1851f75926 100644 (file)
@@ -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,
index 7c1e44420a78ce8ffa5e63ac6ec1930e2d0c80f9..581ddcc22fc58e13eca80f75446e04c4c866ef09 100644 (file)
@@ -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);
@@ -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
index 6edd9a09ea4fdcd3c267c16a9cf9a2deffb11b6d..09399c5386cbaf058fce1e0906d4028cfeaad28c 100644 (file)
@@ -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/remap.c b/arch/alpha/mm/remap.c
deleted file mode 100644 (file)
index a78356c..0000000
+++ /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;
-}
-
index eca248d9eba44823986f1e6c30a1ffa7b8d1f77f..3e14b1348c0b715d77c77390bdd12e95668c5e0a 100644 (file)
@@ -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;
 
index 0a722e77c1438af559c9068399a3ec251862c2d8..6bbd93dd186a74f43ca3bbae43cac88e90c63f4c 100644 (file)
@@ -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
index 68e9634d260a74c8a1d21d93db7a2421fa376859..421329f5e18e6ea0a8e336b4a32543622f1c0895 100644 (file)
@@ -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
index 8170af4714393ed39946682302a16ef229dfb838..00c18d35913cb2c9a6da852fba86d67efa9fd5a4 100644 (file)
@@ -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
index f7d5165796ef2e337ea6a8473c4db562535efb1c..b030320b17c7eef06e1a66ddd084b67867aa235f 100644 (file)
@@ -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);
index f582ed2ec43c615cbbc10c8812b3b423ef7f2096..daa8d3d98eff13b7d33927d7a8218bdc021d4bc7 100644 (file)
@@ -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)
index ab5e9503bae5423132a8a2388bd2ce89ebfd2a47..0221ba3bc799bcef222032a5545013bb91a286fe 100644 (file)
@@ -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);
        }
 
index e7eb070f794fbb7d7d30fbf9f6900468998fafd8..466ddb54b44ffb01bd0c1211ddaf2f6ba80fc971 100644 (file)
@@ -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;
 
index 85457897b8a9cb756fe983dd4ab44588c8ef4499..dc05aba58baf29f46df49c4eb1be9e6f887e102b 100644 (file)
@@ -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);
index 80adbd005fc51812a8a0bc1701e37513c424f5b0..1206469b2b86249574f0dd111a83d457b960c7a8 100644 (file)
@@ -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;
index 6ec5693da4488ce938d5c507848d4b81793caa3f..8deb6003ee626afb44c14f785c25eea3b239c9f2 100644 (file)
@@ -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;
+}
index 536021877df60cced06d2d841818790f2f6d9b54..8cfec65e37f76f72ac101aaacc1315affe1da913 100644 (file)
  */
 #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;
        }
 
index 464ecaec3bc08d8ef21878fac55bbbdf05cc6d74..2d0023f2d49bc01ade50767f8b2f9d9584034691 100644 (file)
@@ -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);
 
index 7af3d5d43e43b73466212ded824b131c46ba4886..ca8b45a0fe2ed4dc8fc48cb9c0cdfdd20a5af7db 100644 (file)
@@ -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)
index 66ba8898db07ba0facf5a1edb86b31bb48a4f874..0f9213cbd48e24f9068c62125b7b9814d09ce617 100644 (file)
@@ -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);
index 1780df3ed9e590997529aadcbd9d3a1c7f134abd..8b0b9348b574c17bb91c2cc0703a99c4f0dbe026 100644 (file)
  */
 
 #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;
        }
index f7b171b92ea2bad7ae134ea0cc5b04cc71f5d1a0..cf1c446e003ac6cad36c4a354872d0b41b2a2925 100644 (file)
@@ -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
index 32db3499c4611f2f79f2ea250e48c59a1084480f..e8f73ed28b529b248d306c47f42b9b51a3394be5 100644 (file)
@@ -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 (file)
index 0000000..9b074a1
--- /dev/null
@@ -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
index 0f61b7ad69abdea6661f411c1696cb3af7388424..302a2dfe634aa8df11b3bfe47669003116cd8a86 100644 (file)
@@ -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;
+}
+
+
index 3fd2f256f2be3402cea23aa3a93a21c0c161197a..af219e51734fce97abd64b534746aff04cd30dbc 100644 (file)
@@ -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
index 8c2a6faeeae51b128e27b43e4669a7ac75dcf792..2c5b5cc55f795339a30036691d0f0d45b6a48e1a 100644 (file)
@@ -11,8 +11,6 @@
  *
  */
 
-#include <linux/config.h> /* for CONFIG_VIDEO_* */
-
 /* Enable autodetection of SVGA adapters and modes. */
 #undef CONFIG_VIDEO_SVGA
 
index 1a29bfa26d0cbf4ddf54a5d7e98661f5ecf91e74..ee2d79bd8af7933dcd4250756c719496dca5502c 100644 (file)
@@ -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
index ea19d091fd41e278c2e58122ccb372721b959849..57c880bf0bd69f4af7e0c2026f5ac12e2b9e2aa5 100644 (file)
@@ -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);
 }
 
 
index f5cc9f5c9bab3dae9d0cf050507ac774b945037b..7233abe5d695533a5ca701bb615681c1a156d487 100644 (file)
@@ -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;
 }
 
index 7a9325349e949e8e5be8f7bb3c25e3578fd6d613..e8993baf3d1422ca7fbb1ccdf045a3676349d176 100644 (file)
@@ -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;
index 67d297dc1003cd0d1fec64ade9fba9fd4218a33f..144b432889655aa77a6d8196ac724e383ae402ec 100644 (file)
@@ -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)
index c36d1c006c2fba75b3549514d2f78549b0c0cab0..6f508e8d7c57433085feec900a851b9a312747d2 100644 (file)
@@ -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>
index afe6505ca0b3a78af53db084d60574540ea7361d..d98e44b16fe20fa1edbda6d0246bc95b3a49cede 100644 (file)
@@ -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;
 }
 
index dbda706fdd14e9e704ee1ab846b3ba361ddeaaf3..3e8e3adb04896243323922cc0dadf3b94429c0c1 100644 (file)
@@ -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
index 8c190ca7ae4494b980b01c8a4c88eee291a3fd45..dad02a960e03572046c2e9ced98186c64e7ca5a5 100644 (file)
@@ -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);
        }
 
index 814cdebf73773ed73b2a7228179067f5f7c972dc..000cf03751fe9fd88280ea6938837c3f49126cac 100644 (file)
@@ -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;
 }
index 465188e2d701779878b7363fd8cf46e24ae6f4e0..1b080ab8a49fad87d600b397d12748393d46ed6e 100644 (file)
@@ -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;
+}
index 82b26d5ce476554bd3eb6158cda3d664a6974224..9d93ecf6d999d82944c017778a40a9cff5cda92c 100644 (file)
@@ -612,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);
@@ -1061,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;
index 8fdb1fb17a5f0ca457cdf0bdaa8e3d998fcd0ccf..4048397f1740bdbdce7d613e244ad3e9b3094dc0 100644 (file)
@@ -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;
+}
index 86944acfb647228186544f2c8ce3375b9c5d6efe..58a2d5582419d2051f3e8c7db7082ecaea496f40 100644 (file)
@@ -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;
index a13037fe0ee383dc0088893af946ab5eb42bfd0e..00489b706d2719c2083172342569381b60f5ce7e 100644 (file)
@@ -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);
index 3c0714c4b6691aaa7e256cce82262603cc82276c..f6edb11364dfe5edef9ffac33341b24307a85434 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 
index 6c86575ffdcb250a7168d3922d4b977a61bbed32..856c73fcb7e76b0fcc27aa7956ce1ed0258384df 100644 (file)
@@ -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)
index ba44000b9069f5376d64304fafdf43ddcd4987f7..f9f647cdbc7ba3550e83d82c0c9e6996b3ae8878 100644 (file)
@@ -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;
 }
index 4a5a914b34321bcc69b714ca17223b08bc898edb..90089c14c23d8612673fed024e1a59ae23c98090 100644 (file)
@@ -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;
index 247fde76aaeddaf0c81215917a015bda7ea648ae..fff08ae7b5ed57c61767615decca493e3e9c7686 100644 (file)
@@ -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>
 #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;
        }
index 05be8db58a8cee783bde63b5f207d7e8137fd7fc..d0c3da3aa2aa9978eef4774c4a61ec97955e2df3 100644 (file)
@@ -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) {
index 0b7f701d5cf7e38253465e82c1261c92dc854a15..70f7eb9fed3562aaa9e072376fb3efd759d7b28e 100644 (file)
@@ -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
index 0daacc20ed36e26c8600176b5332a5ce4a65b10f..246eb3d3757adc85db23f8892ed49beb5c0d5a11 100644 (file)
@@ -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,
index bddbd22706ed1ad76a791635b621784a80cde5a9..9d6a3f210148f3e1b9a775b8615a88841803e479 100644 (file)
@@ -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)
index 12701cf32d9944de96a3fa609788d50fc79b8518..e5b1be51b197a5c97588df38eeb98df0b7fa1827 100644 (file)
@@ -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
index 169ec3a7156ce4dc349769e90ead997bed4f4329..51217d63285ea35122d9373647e2dd40c5cd0346 100644 (file)
@@ -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;
 }
index bfbd8986153b96101d00ba27b1ccbb2ac8d25f17..663230183254c7bf9c34d85518f48e0b98995088 100644 (file)
@@ -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);
 
index 20340631179f669fd7d9216d85f210c2a4cf381e..a78b45f5fe2f9d3aef7c9c8aa8012987b0558a0e 100644 (file)
@@ -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)
 {
index ea914cc6812a0a327cd73802f4b0e2b6beacd42b..51922b98086afb1919a174772206263ab9519a39 100644 (file)
@@ -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>
index 16262687a103a1be82d04f8b6acba09d2f7a2bd0..62e07f906e05dd4debed3688c151a661c60b64db 100644 (file)
@@ -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
index 64e4c21f311cdc7f328165b18ae189e07476f885..7807fc5c04224fcad33d98a83d96a48a1df25423 100644 (file)
@@ -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
index b632b9c1e3b3e1785ffdc6b678e495c59b805dba..462ea178f49abadfed37375141629013fda98e62 100644 (file)
@@ -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);
index 1f0253bfe0a0473f1a8b83046a4ca317204d0bf4..5eb1e1e078b4a1ab511cda2d87271da5a26e6c77 100644 (file)
@@ -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 */
index a86c7b9459625973a06c8e0adc2a32c3af8d8549..1ee977fb6ebb8ab3d33fdf7cd184994b41856522 100644 (file)
@@ -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;
index a9cea32eb8246286924667bbef46291547297696..b567351f3c5236d41e0b108a2ba516a86fc170fd 100644 (file)
@@ -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;
+}
index 7a896893cd284b80dbd4d2793dca650ec6032848..d8af155db9846eff93a3bb1aa3ba1776d9eec403 100644 (file)
@@ -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);
index a151849a605edc794593587a5d1c6b90911fc689..5152c4e6ac80dfec69bde07efe6754edf657df37 100644 (file)
 #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;
        }
index 143c552d38f36a6ca799bee01e8a2e418934cdb8..90238a8c9e14996cf48daca92b083390c703e6a4 100644 (file)
@@ -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;
+}
index 1072e4946a4acab38173ba2246773c363782164c..6cfc984380d96619dc821d840a35825701cca28d 100644 (file)
@@ -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);
index d87e1e0a1336d8aed5f6dffeeb61e75616d03870..c3494b8447d155f890a319097b97fdf352eb4319 100644 (file)
@@ -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;
+}
index db1e1ce0a34960392e44999cfc1e793e6e93532e..c5667bdddd5ef263551ef7e6c7633d75bc64a14b 100644 (file)
@@ -26,8 +26,6 @@
 
 #define        TICK_SIZE (tick_nsec / 1000)
 
-extern unsigned long wall_jiffies;
-
 
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
@@ -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));
index 30750c54bdf5169564855012899f6e2acb42299d..87cee341eb54d1318fa2c117be81f07d50edb50d 100644 (file)
@@ -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/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c
deleted file mode 100644 (file)
index f0024a8..0000000
+++ /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");
index d3705284de39bf45d5c09dd34a1b7c7140168113..35931bedc3df2449452d3e74222065120f56d704 100644 (file)
@@ -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
index e12a475dcbf43cf85ef65bc5842837cda761ab2c..c6a015940b410d2929d1af85d6278f413bed8486 100644 (file)
@@ -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
index bfade9abb767f7bf1c987806959f3240831113c1..e5358121d2da0ff928e2e89ca3487f91f3d2d36c 100644 (file)
@@ -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
index 4baf2ff1128a0ba8b24c3d854b113969402dceb0..adf1e8c98c654de024b5acfd580b1e1a45e7dc1d 100644 (file)
@@ -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
index 93cca1585bc342c08fb2ea2913c1698205379deb..4fd29ffdfb8dafd22e9fbf43ded53215e7807124 100644 (file)
@@ -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
index ffd99252a8376c9b83bd1cbc1797bf750ca5aa41..025b960ba990fb0e95cb78a1680f1aca76edbebf 100644 (file)
@@ -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
index 63eac5e89b9cdd63ae4208f8a261d4264a0d342d..80c9dd98f897fc1e088c176517861fb6aed9619a 100644 (file)
@@ -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
index 25a095f7dc4ef56dcab70debf6a207ce333c1111..6caa90b0e1766fd3991fc1c1ea285147746574f1 100644 (file)
@@ -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
index dda469c842b35dedff228dd521e1229d5daa2f0e..c6cae86c6ab7c5f73a08d493807b644e9d5b4cc0 100644 (file)
@@ -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
index fcd3dd19bc744e252440c318cdcc58edabfd9c3d..72f24001c99e88a24061d7b47303d4a84ed66269 100644 (file)
@@ -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
index 8683e0df12e07615aaff8425a1490aa070fa5c41..be901df7fefae8f7619cdbb50ee053f262a486f5 100644 (file)
@@ -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
index 4ace61c95778992ad929c2d11a45b9b206655569..6133c28beb8c757db6f17b52ef4c1e2dd38234f3 100644 (file)
@@ -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"
 
 #
index 5847c916c130a90bf79b9e7f84f28be32ce809f7..a484b7d396fc8a9ab4c0830b21b2f47c3506b80f 100644 (file)
@@ -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
index bc4c4f125c480087235a66bf41f2084b4ab11be2..21bfcdebf8f53664cc0207f778ad57f78b62ec26 100644 (file)
@@ -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
index eb87cbbfd03729923e9753d635268b28595a8057..1a5b06cfb4d6b9d63685801055bb4247e222a017 100644 (file)
@@ -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
index cc9b24eda9e89480f17b0ddfb09d506d86febdae..21d53e0c9ee84c5126881129026a9224eddcdd20 100644 (file)
@@ -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
index 50092ba8aa7135e381403a2459dbf74f88ee96c0..e3e94c7e5ee1b6ff81bcd089658dff3dba2782f4 100644 (file)
@@ -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
index dec2ba6ba03f428a2b72c0780d28ac9149e2255b..b4ab2bea972331c9f0d84544b9cbe9cd9899e3bb 100644 (file)
@@ -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
index 37f9dd7187b1073d12ba0a0ffda7597cfc6372ea..18d20fb7d5f0cd8499cb1199b9afa670ea9fb82b 100644 (file)
@@ -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
index 18874a4c24fec8978ea5539c29e36d81265026f6..99831d0bf76bc9c8913bf6444dfef715ff37267d 100644 (file)
@@ -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
index 9f1e3048d62347417d464d32ec7cc9ef5fb8bea0..9d4d17ace123b50eacc4192b5c11fafba99e35a8 100644 (file)
@@ -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
index fded3f73815feaf13cfda7e025d6056a5949b803..d03746667a96c6e390de1d7cef39585517e29ffa 100644 (file)
@@ -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
index 320b8cdd6e589e9bfbac7127c53bdff629693a2a..1db8249b4c0fa1aaafb33355137ee42c846e8b85 100644 (file)
@@ -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
index 0ba1ef5048fb0a88a5cbf0c96619fb11cb0cab3d..aeefe2873e38fde99f986f266f93d6249eba533d 100644 (file)
@@ -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
index adbeeadddb8f3da2bb16bd1270b4973793ef1cde..a3cbd23bf217d72ba338faf2cec97c3e1edd456a 100644 (file)
@@ -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
index 79fd544fcb2a186b3ca0abcb5e8d4b319137a1cb..6570b47426cef5e326fa10d6dd22201da934b228 100644 (file)
@@ -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"
 
 #
index 4d87da2b99fde8ee93cd2c14deff41256ce935bb..440d65f93a949bb6fbee4239b10caf9a57c7985a 100644 (file)
@@ -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
index a7ac2b0a8273a87ad46222717021bb316e96a331..c2c7ae77da3e68fc03562dab396f9e4499f46c6e 100644 (file)
@@ -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
index 853e7bba5122e3294498a9224795b641c669370e..67efe270e0cc4cf6d3ee14db47ee357db8f54d02 100644 (file)
@@ -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
index 8524efa23a490b7983c04d7149a6106728ca1109..a10f34de5f7ef5cc929dac8d5f33d726c70fe275 100644 (file)
@@ -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
index 1a16e92900cbd9140f555f77a4f3d85eb791abb9..741f8258075c96ab27e2a284a0bb258f1654e089 100644 (file)
@@ -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
index 9ea8edea6f2934c03b553038e824a9d856ff5a0c..8576340714da703f2f81216d33f1a29e782cfa92 100644 (file)
@@ -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
index c4a158976f8f97209cc524b4ed14e23a322d249c..3db7427d1b5578d94c426226b66f530e474d5d1e 100644 (file)
@@ -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
index 1cbf270c301ce416b8d84300db216980cb04e302..26b0b9883496d8af2246a01f3b2f7c9ec8bc4e74 100644 (file)
@@ -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
index bec30b15b9bdc448225cdee4ca981ca87da62362..e93266b37dd918a9e752aba99dbcc1c503d52d90 100644 (file)
@@ -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
index f5f799e9370728d57f0f95dfc42c2f511e8c8b7b..9b0dab822bd0d3d63572c96889324214612e4b85 100644 (file)
@@ -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
index 2f5650227ba36aefbd454184f95f0f09699e2c9c..dd0296036026d3ed0f0fe5e194c7e65bdd783b3b 100644 (file)
@@ -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
index 4fee90b2b100920580610e49900c19f4a1ecb774..d8a498d64d625575812bdba03502cca0e03b3dc8 100644 (file)
@@ -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
index 9041f095f96fb892f7c0c04937040227c9e118b1..805a4fe450f5ea07329343687e8231d05163e6cf 100644 (file)
@@ -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
index 02abb2f1bfaf017b63f4379ffd52c02a9ca2ce00..6fcb656d8d87e69cada3001ffad816cc65cb787e 100644 (file)
@@ -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
index ca3d0c4ba15b5861b4147bc08cd7af91b84cd291..dc312f19ada7ea36c8c87302bb5658312e9345f3 100644 (file)
@@ -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
index 4e2009ace278d7ce076074a089400caae5e99600..85615d99b01aeb63e552242ee3e3e9d9ab2c0631 100644 (file)
@@ -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
index 535a813d01a932ba20936f3a71fdb6ceeb96111d..ad7271b3f2666dee49c35463b85ebf800cd23ac2 100644 (file)
@@ -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
index 3a3ef20b21cc0afbe9c13d6b6b1c70282dfd9eb3..863f6a7cadfd7b35008d59dae3cf0606990340b9 100644 (file)
@@ -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"
 
 #
index e6b1dea5584245b12be1b1d688667ea8e0bc22bf..c10267d61cc90e36655c39e41953156b2c9dd030 100644 (file)
@@ -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
index 06a072b77b1c963a75a620da8fc6563c4eb6e1d8..4d3c1329f3cf8e4b0b66f8797d6f67e29c199c2a 100644 (file)
@@ -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
index cc9b24eda9e89480f17b0ddfb09d506d86febdae..21d53e0c9ee84c5126881129026a9224eddcdd20 100644 (file)
@@ -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
index 881c467c698241d2902454b603de9b4e4dae4ae7..cd9cec9e39e931c85c3f8af50e562615e281bf93 100644 (file)
@@ -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
index 37fda3dcdfc5b84bdbd57c785187ec3086b50ade..af6ef2fd8300338f26e45e3acf7073027b8a6df6 100644 (file)
@@ -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
 
index ea36c8e8852c1b9f1b0c2c5e789e5d6e4e40ee29..48e3418c217b8445509fa6326daf2fefbfc2a220 100644 (file)
@@ -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
 };
 
 /*
index 43b1162d714f281db07a3bad5b53bcf0576f8423..53f4171fc188a9695eb094b6a4ddda7977af349c 100644 (file)
@@ -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);
 
index 2613a0dd4b823bde6959cd575d194cb8cb5677b8..045d987bc683b3da05fe6f5a700c413154d9e5f8 100644 (file)
@@ -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:
index e7178510220635c5da2be58e59c3b839a36a0bfa..61362e6fa9eccfbfb79b8abfde01d57b431f6e08 100644 (file)
 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
 
index 4c22d0b4825dc70bcdfb5d239dc458d60d6c185c..6c7b5ed0ea6e0ccec04ebfff052e0e9fd2fc780e 100644 (file)
@@ -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
index f25c2a2f10387b10128bd92251cc9ee8df45559f..6d9f18727ac51e5baf3232f4624f733c8789732b 100644 (file)
@@ -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
index 288ee4ac4dbb8cce221c6b530b3da04bdae4eea1..2e6d0673163e1896cc2ac05d3299755f77f43aac 100644 (file)
@@ -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 (file)
index 0000000..4aabe52
--- /dev/null
@@ -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);
+}
index 9951240cc3fd23fde7c356542534de4c79a904af..26e1a7e78d13dac0acac8277572c88c74c9a106a 100644 (file)
@@ -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;
+}
index 1137dd6ea7aa914bd91c3ec10722c843ef531ebe..93c74fefff766e9c3cc035a57011a3e62d992a1a 100644 (file)
@@ -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;
index 6ab8d975a974213a3e7fe3c16014ebe4279d9c50..845c7e55505d39f3335e66f031e723b2729d6406 100644 (file)
@@ -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);
index e51d8fd9a15234ec4d3e5fabcafb22b24010f6ed..b7292a56d4cd80b65d4bf2ef6f6ff016d371c857 100644 (file)
@@ -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);
 }
index e1f35ef81145445c5530ccbdca83b4715a040c2d..d1af42c2a52e1b24c4342ab1a2990ededac007e6 100644 (file)
@@ -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;
index 0b2da53750bd4220a30d1e97d7016d436a41ce6e..cc895dad71d2297094243bd5d23d8d411d4893c0 100644 (file)
@@ -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;
index 16bad7c0a63f876ec0555c247607512bae82dc8a..5537558f19f795d467e327a5225e662ff03dd7b6 100644 (file)
@@ -306,66 +306,6 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end)
        __attribute__((alias("local_sb1_flush_icache_range")));
 #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.
  */
@@ -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 */
index 932a09d7ef84810bdb4d43c591d63badbff3892c..f32ebde30ccf1cee1dbe06b29a623b00ea07a744 100644 (file)
@@ -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;
index 40c8b0235183859bfc087b72a509db11fdcd4490..caf807ded51415aea2f6d9ba63a7458970f4f3dc 100644 (file)
@@ -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);
index 9e7f4175b4933504c2f8b2fc9586b7b073b19f68..e99eaa1fbedcc7e7cf54e3ba045382b95c708ad4 100644 (file)
@@ -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
 
index 8134220ed600211a41801d1962ab71d1f9db9dfe..7a941ecff3bbd505066013f125118b55c9c0d39f 100644 (file)
@@ -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();
        }
index c62a3a9ef867fa6e3af03ecb773b8418e3ebed37..257ce118e380fd2dd7d4e104c4eb02c87a4ec20f 100644 (file)
@@ -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)
 {
index 79ddb460565955a60864472b818ef2d00808fef7..fd0932b2d5218ef58a08a79056c5f2af68c23d61 100644 (file)
@@ -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();
        }
index d7c80edf44899323f7401c59fd8e1c64be5648f6..6e79dbf3f6bdf7e205ccccc5e6e2674c9e8c6b54 100644 (file)
@@ -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);
index cb69727027aecf66889bad82a29e947bf87cb994..2e2dc4f2c853edee44818110eee1d44e5d85d1b9 100644 (file)
@@ -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:
index 4398d2a95789b247c2676ae4f798631e45f77af0..c2531ae032cf74895e4d6ef518607b856ba810c3 100644 (file)
@@ -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;
index 0b485ef4be89e8b1c9d655e19fa59aca1f29c41a..2f9f9dfa66f7ba557d2a9158ffae6cfbe13a29dd 100644 (file)
@@ -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;
index b74869803081900be006855604f941664a46d157..e3b30bc36453a0d05b830c3d9967de27112ab0c3 100644 (file)
@@ -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);
index 700df10924dd8d671b9ae1d6f62b8763ad3f1c0a..ab641d67f5516fc6fb494799edce9db1f13f08d0 100644 (file)
@@ -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;
 
@@ -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
index a0dd1b0ee4838fc1b6f6b870354d67886c171fbe..032e6ab5d3c4f314a68bcefe8b4ca3417e8cd138 100644 (file)
@@ -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
index 01667d1d571dbdee4636760d924b98604404b8e0..a00fe7236555676aa1abdabafc4f355456e335d3 100644 (file)
@@ -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)
 
index e73774136b5586dd547a9e048c79eddb8d70ad23..c383d56bbe184b4ca549443b58a6c96dfd4d8720 100644 (file)
 #      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 (file)
index 0000000..2b16848
--- /dev/null
@@ -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 (executable)
index 0000000..eab7318
--- /dev/null
@@ -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
deleted file mode 100644 (file)
index 6016251..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-OUTPUT_ARCH(powerpc:common)
-ENTRY(_start)
-SECTIONS
-{
-  . = (5*1024*1024);
-  _start = .;
-  .text      :
-  {
-    *(.text)
-    *(.fixup)
-  }
-  _etext = .;
-  . = ALIGN(4096);
-  .data    :
-  {
-    *(.rodata*)
-    *(.data*)
-    *(.sdata*)
-    __got2_start = .;
-    *(.got2)
-    __got2_end = .;
-
-    _vmlinux_start =  .;
-    *(.kernel:vmlinux.strip)
-    _vmlinux_end =  .;
-
-    _initrd_start =  .;
-    *(.kernel:initrd)
-    _initrd_end =  .;
-  }
-
-  . = ALIGN(4096);
-  _edata  =  .;
-  __bss_start = .;
-  .bss       :
-  {
-   *(.sbss)
-   *(.bss)
-  }
-  _end = . ;
-
-  /DISCARD/ :
-  {
-    *(.comment)
-  }
-}
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
new file mode 100644 (file)
index 0000000..6016251
--- /dev/null
@@ -0,0 +1,46 @@
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_start)
+SECTIONS
+{
+  . = (5*1024*1024);
+  _start = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+
+    _vmlinux_start =  .;
+    *(.kernel:vmlinux.strip)
+    _vmlinux_end =  .;
+
+    _initrd_start =  .;
+    *(.kernel:initrd)
+    _initrd_end =  .;
+  }
+
+  . = ALIGN(4096);
+  _edata  =  .;
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+  _end = . ;
+
+  /DISCARD/ :
+  {
+    *(.comment)
+  }
+}
diff --git a/arch/powerpc/boot/zImage.lds b/arch/powerpc/boot/zImage.lds
deleted file mode 100644 (file)
index 4b6bb3f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-OUTPUT_ARCH(powerpc:common)
-ENTRY(_zimage_start)
-SECTIONS
-{
-  . = (4*1024*1024);
-  _start = .;
-  .text      :
-  {
-    *(.text)
-    *(.fixup)
-  }
-  _etext = .;
-  . = ALIGN(4096);
-  .data    :
-  {
-    *(.rodata*)
-    *(.data*)
-    *(.sdata*)
-    __got2_start = .;
-    *(.got2)
-    __got2_end = .;
-  }
-
-  . = ALIGN(4096);
-  _vmlinux_start =  .;
-  .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
-  _vmlinux_end =  .;
-
-  . = ALIGN(4096);
-  _initrd_start =  .;
-  .kernel:initrd : { *(.kernel:initrd) }
-  _initrd_end =  .;
-
-  . = ALIGN(4096);
-  _edata  =  .;
-
-  . = ALIGN(4096);
-  __bss_start = .;
-  .bss       :
-  {
-   *(.sbss)
-   *(.bss)
-  }
-  . = ALIGN(4096);
-  _end = . ;
-}
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
new file mode 100644 (file)
index 0000000..4b6bb3f
--- /dev/null
@@ -0,0 +1,46 @@
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_zimage_start)
+SECTIONS
+{
+  . = (4*1024*1024);
+  _start = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+  }
+
+  . = ALIGN(4096);
+  _vmlinux_start =  .;
+  .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
+  _vmlinux_end =  .;
+
+  . = ALIGN(4096);
+  _initrd_start =  .;
+  .kernel:initrd : { *(.kernel:initrd) }
+  _initrd_end =  .;
+
+  . = ALIGN(4096);
+  _edata  =  .;
+
+  . = ALIGN(4096);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+  . = ALIGN(4096);
+  _end = . ;
+}
index bbf2b5f8a8cbe739a2f465b2c18ea97ecddd7aec..fee72f8a2fb76858fc3323228966bed3fbf94031 100644 (file)
@@ -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
index 4b9c2ed925f505b5b70ca001ac91547c6fda2703..92d0a9dd0b8f67a4655745b18ef58097f83b5556 100644 (file)
@@ -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
index eb0885ea073178ac09b9cea142803099ce471865..d58f82f836f82553e9c5b98bd0dce39f55afda38 100644 (file)
@@ -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
index 719fba4eb42100833c2103f4a0dbc8e0ed084c66..d1811e754518d01930eafd188391d502e4c5bd8c 100644 (file)
@@ -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
index 8da6a47f03390b2765c17ca020244a37972379b8..cd3535e1a09558d323b351fd52b87c7c2831c692 100644 (file)
@@ -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 (file)
index 0000000..ddc2a7b
--- /dev/null
@@ -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
+#
index 6861dde7d77bc54a3951defd0de5cb28c63a85ea..765c8bb90ddd12078bd92b725c7d3d4081a71e2b 100644 (file)
@@ -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
index 7517d0c5303fc1803a73dee77157628e61abdc29..be11df7c11aa4ea455022791b7e8847449f371ee 100644 (file)
@@ -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
index a8cdf312e1b0fbc4a8d79101913fc1f31f27b2f7..44175fb7adecc7822dab452201833373eaffddcf 100644 (file)
@@ -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
index b4432332341fc6a695b87e0cf4f6b3de1ac520ba..c3f58f2f9f525d15fcb12466c6d7321218b2fc80 100644 (file)
@@ -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);
index cd65c367b8b6d5c9abcc23fe7cbf595931814a5d..7b8d12b9026c48487fbad3a4b83ca682108db260 100644 (file)
@@ -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;
 }
 
 /*
index 58758d8833619f011e10801e0647a2c08b1e8ff1..88fd73fdf048aea647974a694f033653e93cd4f8 100644 (file)
@@ -843,7 +843,7 @@ _GLOBAL(kernel_thread)
        addi    r1,r1,16
        blr
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
        li      r0,__NR_execve
        sc
        bnslr
index e3ed21cd3d945e6d3e5afbfb64108dc5602517f6..9c54eccad9933fc71903cda34fe9090617f3d4f8 100644 (file)
@@ -556,7 +556,7 @@ _GLOBAL(giveup_altivec)
 
 #endif /* CONFIG_ALTIVEC */
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
        li      r0,__NR_execve
        sc
        bnslr
index a127a1e3c0976aea0134de07ce2c6d3d1f4d0ba6..7b2f6452ba7252caa11c377553392446d44c02e0 100644 (file)
@@ -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);
index dea75d73f9831eb8c5d0a539374212dfb2b6472f..975102a020d96e9d95bc5f747da348fa1fdc5ebd 100644 (file)
@@ -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
index e0df2ba1ab9f936f397aa547e44e3a3af2a02cc5..79a17795d17bd5bfba19c61da9bf2a61bddef2d1 100644 (file)
@@ -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
index 00d6b8addd78896ebe5d2578549f9d445446a459..cda2dbe70a7656ce520d593ef57b5c3a9bf167f4 100644 (file)
@@ -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);
index 5e391fc253407fcfa8b712363d74d46bb99ee7c5..d15c33e95959998dde17fdbd053244f0ecfa80f7 100644 (file)
@@ -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);
index 9b69d99a910381237791d5e7d0dd9d7c5219aadc..d358866b880f25012aadf35a5e6340dd233ae801 100644 (file)
@@ -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);
index 406f308ddeaddf2dda54c6f75ae656f2b9e159cf..d45a168bdacaaff0dc7092e50772102046566eb1 100644 (file)
@@ -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)
index 71f71da98e7deb6288a9acdeb6a0449e493787b6..85b9244a098c79d76373e4d75eef1cbe54a8a395 100644 (file)
@@ -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;
 
@@ -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
index 336dd191f768c1a8e4949cf9f928ed3f6d21fcae..a0360ae10d0ccd5db00a1a0ff77b6bde74bd1629 100644 (file)
@@ -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
index 31e511856dc58bc2b819e80c32a35840db5bd9ca..57bf991ccd6e11751cf4b37c5f4548ac83e55aba 100644 (file)
@@ -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)
index 754143e8936bd4c528ae6bfccaba166a761ee8b0..29bc9126241b1d9893acf6d51024a6f6797efa19 100644 (file)
@@ -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
index 75f57bc96b404416480d410a537eccfcdbcfe4b6..b4278cfd1f80cccb5596f29b6c5068961aad06c2 100644 (file)
@@ -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;
 
index 969fbb6d8c46730b7e2da3b6912e44aa68c386ec..8c676d763bb0aecc1a47ab4ef8badba262a12707 100644 (file)
@@ -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,
index c3268d9877e47ab968d14d0b9718fab6307bbf41..0584f3c7e8844559d2ad15622c571fe8cf2cfb68 100644 (file)
@@ -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
index 7615aa59c78bacf6d911f2ea7e194e927f4e1b79..282f5d0d01520a4a83b78b378283e352803d7e5d 100644 (file)
@@ -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
index cae6b73357d5b8ed95f5ec2e182c1ddbea02f0fc..28070e7ae5074fc36ee52929358b831ddcc8affd 100644 (file)
 #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 (file)
index 0000000..effcbf7
--- /dev/null
@@ -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 */
index 3bd36d46ab4ae4f6b24dbe14c0dd1c18b2b57cdd..0f5c8ebc7fc3378ff93ee4a270871884007d7762 100644 (file)
@@ -538,7 +538,7 @@ static void __iomem * __init map_spe_prop(struct spu *spu,
 
        const void *p;
        int proplen;
-       voidret = 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 */
index 58e794f9da1b6a5b920f95ba6fe57f0f054d1cb7..51fd197ab5dd1f98ac9f1bfbab25ef7b6f839ad4 100644 (file)
@@ -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, },
index c8670f519734aab795e40d4fc8b10e247b9dccbb..efc452e71ab0f03b93b4d3178d28cc05ef1200c1 100644 (file)
@@ -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);
index 1a2c2a50f9221c912e3c5a465f97a495d03fac9c..1983b640bac117593c84cd42e197fbb9c9771ce3 100644 (file)
@@ -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), "
index c3aa46b8e2b9db064351ab75585d01b63f1913d0..1b827618e05f9f59f412896df8b0f61f5be06191 100644 (file)
@@ -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;
index d30466d741942c621db357a0fc1aa18c3be21a2e..9d22361a26d6012a93393bfb664803aa6f73785a 100644 (file)
@@ -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);
index 6a36ea9bf67339d8f5e066419db811feed612dc7..692945c149194e77914318f71a9f8240567664d8 100644 (file)
@@ -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,
index 84bc8f7e17ef77481269204890e2b576e1c2810f..3c2d63ebf787fae9e60e3c98713c36d3e1590d8f 100644 (file)
@@ -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);
 }
 
index a6398fbe530dc55ad8a79cb6baad66e586df429e..43dbf737698ce458efccc8c4dd03e868ff8e7bfc 100644 (file)
@@ -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();
index e5e999ea891ad43f1e3442118724d256fc35e6ce..f15f4d78aee9b8b3b12e1057e345782ac11bb6e0 100644 (file)
@@ -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 (file)
index 0000000..ec26599
--- /dev/null
@@ -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 (file)
index 0000000..5175299
--- /dev/null
@@ -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 (file)
index 0000000..d63e45d
--- /dev/null
@@ -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 */
index 92ba378b7990a44fa4ca24f004d10cca7a30218a..022ed275ea6890c2084ee34c8d21d82c5163d06a 100644 (file)
@@ -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
 #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 */
index 5a3dd480d2fd8eff791e62ae40e12de8a553b22a..04e145b5fc324066ebb52d2f895d8538270c3506 100644 (file)
@@ -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
index b81a367dc2780bb15e49545e1d8ac92fe73a4d24..87fe9a89dba710f1afd9d5c9f5b5ecb1a5a173f3 100644 (file)
@@ -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,
index 29115e01f60adc8956b8cdec751916ed558b615b..1640c4199ca623294813f2dbee0d06d6b33590e6 100644 (file)
 #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;
 }
index f6d5a2f2fcf658e8a6e5d20d83a3d8d47f15ead3..192bb397126fac25f5eae2901316252dc19803e6 100644 (file)
  * 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);
 }
index 50b4bbd06804b123a443ab0420e824a1ebaf2bc8..5f6684012ded76d4d02c9b0f55c37b8e2cb6548f 100644 (file)
@@ -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)
index 5458ac5da7c3f9f535f01c3c2b42934beee13acc..75fe13815be27c23e817ac7527c00079476f1c0b 100644 (file)
@@ -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
index 1e1f315547671503d0370a2e36bb31eb071b7167..187388625a768ed45a15d3bb68c0c93dc491e8af 100644 (file)
@@ -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;
 
@@ -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);
 
index 2a35fe2b9b9652784d80e9a1a0d8ddd629725e04..d5d36c372c8e27c0b017bfcf020f3eb9d04e636d 100644 (file)
@@ -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));
 
index e12cece4c9fd056e1a2586d2feabc996d986ef7d..5f130dca377009cbe3d13d8294f9ce9ee62b025b 100644 (file)
@@ -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;
index 5dfa4e6c2af038e6c7d45578b68f07f44435f02f..bf388ed04d468ecdbc5e7131d49222ae39ce8beb 100644 (file)
@@ -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;
index 813fc21358f9764cc2ae6a34a17d5edcd60c265c..cd702ae45d6ddda9d52df2a5632278fcd34a5414 100644 (file)
@@ -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;
index c46e3d48e4104d827abc7c17c40bed215fe70461..e15e1489aef56b5c89b54f52822234ba84a64935 100644 (file)
@@ -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);
index 1fa9fa1ca740a477e8c1d30d382815340a0af8bd..1b952a3664e2dc38c0e3684427ea8dc0337b54ca 100644 (file)
@@ -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
index 48998d50b00abd7bdbc48640354ca15e56b03fe9..b30e5897cdf75af602fb380785a72a52d2dcc09c 100644 (file)
@@ -250,6 +250,17 @@ startup_continue:
        oi      7(%r12),0x80            # set IDTE flag
 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
 #
index ca28fb0b3790f7c966e338f546bed0b18ac192fc..4d9ff5ce4cbdb41c04a78261ad8d98e579bb8891 100644 (file)
@@ -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
index e351780bb660cab9ef1dbc503799969edb175eb1..584ed95f3380b07b61c151e9616efecf2a218e3c 100644 (file)
@@ -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;
+}
index abab42e9f5f8718cfcda91702803e8d797f70544..4bf66cc4a267ee9d8fed39992e52a84c74b4dbd6 100644 (file)
@@ -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;
 }
 
index b9b7958a226a75a5787129404b1eb525c95832b4..8d76403fcf89b5900f02f6084312049791b8dc4e 100644 (file)
@@ -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;
 
index 1cc5c9b27bfdeae32671c58e61263d929c92f6e2..f6a0c44361682de8e34fdc1eec8c57a2d7977f7e 100644 (file)
@@ -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
index ad0e712c29f6955681dff88ac49ad9bf8596062b..75f91aaae0777ab373cd476da69bd9e6bf5620bf 100644 (file)
@@ -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>
index 0e501bcbd7a964a8dfe9da141cd9742a13eceb83..83d3272120645d149c16965e46d0f90b2f5c1183 100644 (file)
@@ -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>
index a006d6443225fca54abf6f57b0dd29513d709d88..8f2e1c68b90fb7c61f9f25f6321f272e54ea5c46 100644 (file)
@@ -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);
 }
 
index e75cb578a28becfc1ec87c7c160dda9b10f7d3b5..0b7bee1a9ca5af99c0c3bdeb33aa0a8370f39174 100644 (file)
@@ -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>
index 35ba726a097962718206fa62c53134c0fb035715..0a9a2a2ad05b7916e318258b9508e96fe2cd8586 100644 (file)
@@ -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>
index 127b9e020e0087e2b65cb87f488f7801a7769ce1..122d6996263763dc43a785ddae91b0f36a6fa808 100644 (file)
@@ -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>
index 61d5e5d3c2949575d10e8d358f0e10df17877fe3..2d960e9a3143b5bae8c2061b0c0bd4e4dfd4915e 100644 (file)
@@ -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);
 }
 
index 9f02766b6f531b1f1fc625bb7e7b34a5610f4d1c..6a00a257afd26e153373c2f2d7225f93311edd0e 100644 (file)
@@ -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>
index a8467bf90c2515d00df03feb1926931e9e7321f3..bab7d3cdc87b6f57dc1d1223843116c2c44bfb5c 100644 (file)
@@ -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)
index 646661a146ad38ad6c55a14c8258fe07552dbc1e..3a6d114249385ba390a20de148594f096027d26b 100644 (file)
@@ -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>
index b41e3d4ea37c41af4a5f03e74f11522d5e5a8f83..288b62f59419990c8e50ab42a261308831278d24 100644 (file)
@@ -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);
 }
 
index 6a439cf83e46334880b7ca27fef255c1d54fc1f4..6b39e191c4209ee8ac50b51d463625e2ec9cf321 100644 (file)
@@ -2,8 +2,6 @@
  * arch/sh/boards/se/7343/led.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <asm/mach/se7343.h>
 
index 787322291fb34d4f77e4b66ff23cba8d990cdc37..c7d17fe7764ed2cbabd145726ea31b75912df125 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/machvec.h>
index f3f82b7c821740b22849caadb665d82330fdca0c..a1d51d5fa925cbb56512a98cf913c2d40d27312b 100644 (file)
@@ -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);
index 73e826310ba8748379395871c663681cbfa99939..f7e1dd39c8364c30db40874a04e391144f249b17 100644 (file)
@@ -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);
index 6c310587ddfe72ecc15848d34297e1e52ec7f2b0..137e2ba9243e82a85f222e455f852f357df3a5d9 100644 (file)
@@ -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 (file)
index 0000000..b6718de
--- /dev/null
@@ -0,0 +1 @@
+zImage
diff --git a/arch/sh/configs/adx_defconfig b/arch/sh/configs/adx_defconfig
deleted file mode 100644 (file)
index 353bfdc..0000000
+++ /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 (file)
index 614662a..0000000
+++ /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
index 776c1909bee31c394afcb8f976a7c34a7c7bcd43..8b6b5a779de8496b709241cfe79ee00ee31cd228 100644 (file)
@@ -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,24 +243,41 @@ 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
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -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
@@ -348,6 +476,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -456,19 +600,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # 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 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
 #
@@ -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
@@ -546,15 +691,36 @@ CONFIG_SH_WDT=y
 # 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
@@ -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'
 #
 
 #
@@ -652,30 +829,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 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
@@ -781,14 +988,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
index b36f102cec81685a3178be6775653ef4c7a036b2..b931d9b2d5798158206b4011efaa1dd11eeed9f9 100644 (file)
@@ -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
 
 #
@@ -256,6 +276,15 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # 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
 #
@@ -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,18 +392,11 @@ 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
@@ -470,30 +518,35 @@ 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
 
 #
 # Misc devices
 #
 
-#
-# 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'
@@ -579,13 +635,43 @@ 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
 
@@ -730,10 +822,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
@@ -741,3 +829,4 @@ CONFIG_LOG_BUF_SHIFT=14
 # 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 (file)
index 0000000..e1a886d
--- /dev/null
@@ -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
index 6b43316d03cfa18b6c9d5056af876ca835700e0f..238c0f109907533b8e6ccfef7b124048aeddac4e 100644 (file)
@@ -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
@@ -247,6 +295,11 @@ 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
 #
@@ -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
@@ -615,6 +625,11 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_PCMCIA_QLOGIC is not set
 # CONFIG_PCMCIA_SYM53C500 is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
 #
@@ -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,57 +881,84 @@ 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
 #
 # 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
 #
 
-#
-# 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
@@ -1071,20 +1114,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_MDC800 is not set
 # 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
 #
@@ -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
@@ -1166,13 +1204,44 @@ 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
@@ -1360,10 +1438,6 @@ CONFIG_SH_STANDARD_BIOS=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
@@ -1371,3 +1445,6 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
index ab3db76d1e51b5d4d6c92bf87c1ab8337889f003..e89d951c3c16b6ad327eb4b72a6c0c1279a1c2c4 100644 (file)
@@ -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
 
 #
@@ -247,6 +269,11 @@ 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
 #
@@ -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,27 +594,26 @@ 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
 
 #
 # Misc devices
 #
 
-#
-# 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'
@@ -604,16 +653,43 @@ 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
index d597fc57154977008dba6dbac5d3ac9dd693bc4c..2470364948e75aa007d53597204194bbe6900171 100644 (file)
@@ -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
 
 #
@@ -265,6 +291,11 @@ 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
 #
@@ -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,33 +544,34 @@ 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
 # 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)
 #
@@ -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
@@ -785,30 +847,35 @@ 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
 
 #
 # Misc devices
 #
 
-#
-# 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
 
 #
@@ -862,13 +934,44 @@ 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
index e43cf57326bdaca812fd9a12f15ae44d6a9acee9..099e98f14729429566128e0be141b5f6bcb872f6 100644 (file)
 #
 # 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,27 +230,43 @@ 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
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -176,6 +282,95 @@ 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 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
@@ -356,6 +495,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -528,15 +678,36 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -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'
 #
 
 #
@@ -677,31 +847,67 @@ 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
@@ -835,13 +1049,11 @@ 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
index 4b71cd692fa5fffb70c25c720d765d06b9f1db2c..8a217908b81f2b4172049c575327af74fd845c34 100644 (file)
 #
 # 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
 #
 # 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,25 +298,15 @@ 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
 #
@@ -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
@@ -232,13 +342,6 @@ CONFIG_IOSCHED_NOOP=y
 # I2O device support
 #
 
-#
-# 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
@@ -265,18 +369,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # 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 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
 #
@@ -286,6 +378,16 @@ CONFIG_SERIO=y
 # 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_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -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'
 #
 
 #
@@ -392,31 +519,65 @@ 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
@@ -519,13 +687,10 @@ 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
index fe19feb95ca9a4a918761a23459d284db9c809c6..1a766153cbb01d6c6fedd52122b2b2241f8489d0 100644 (file)
 #
 # 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,26 +305,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=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
 #
@@ -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
@@ -239,13 +350,6 @@ CONFIG_IOSCHED_NOOP=y
 # I2O device support
 #
 
-#
-# 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'
 #
 
 #
@@ -377,31 +495,65 @@ 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,20 +633,16 @@ CONFIG_SH_STANDARD_BIOS=y
 # 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_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
index 948e507b52beeb596b0d7c0b743d8db34d09769e..84c0075e2ad47c6492f0d5d7ba081097565e8fbd 100644 (file)
@@ -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,11 +160,15 @@ 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
 #
@@ -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
@@ -788,12 +801,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 
-#
-# SuperH devices
-#
-CONFIG_SH7343_SIU=m
-CONFIG_AK4537_CODEC=y
-
 #
 # Open Sound System
 #
@@ -846,6 +853,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
 #
@@ -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
@@ -982,10 +1007,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index e4a14602b169a7fb4e4a7de32abacf760ff68547..06ebd6ec0cdb87bf560368451568e939ae57ae8f 100644 (file)
 #
 # 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
 
 #
@@ -255,6 +448,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
 #
@@ -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,76 +512,19 @@ 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
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -451,18 +595,6 @@ CONFIG_INPUT=y
 # 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 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
 #
@@ -472,6 +604,16 @@ CONFIG_SERIO=y
 # 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_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -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'
 #
 
 #
@@ -567,31 +733,65 @@ 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,22 +899,19 @@ CONFIG_DEBUG_PREEMPT=y
 # 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=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
index 6dc31584752a7a20f9de830ae629ddcd8c572bc4..5d357d68b234e866d26a2efb4e27297e11d4b350 100644 (file)
 #
 # 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
 #
 
 #
@@ -168,6 +272,98 @@ 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 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
 
 #
@@ -255,6 +454,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
 #
@@ -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,77 +515,19 @@ 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
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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'
 #
 
 #
@@ -556,30 +718,64 @@ 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
@@ -699,15 +905,13 @@ 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
index 1ce02894745951e16b78f9fd84d423aa6877c4eb..a9095593f8f362d3c2be237c84014f3aafd6f3f9 100644 (file)
 #
 # 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
 
 #
@@ -261,6 +468,11 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -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'
 #
 
 #
@@ -637,31 +726,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 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
@@ -763,15 +895,13 @@ 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
index 078f78c7fe53bf756ac9d48f554aef0a93c53a7e..9fd5ea7304e5aef2fc99ed4216cd8fd77dcea730 100644 (file)
@@ -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,24 +231,42 @@ 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
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -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,39 +500,34 @@ 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)
 #
@@ -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
@@ -441,6 +565,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -546,14 +686,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # 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 is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -563,28 +695,39 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING 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
@@ -624,15 +767,36 @@ CONFIG_SH03_RTC=y
 # 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
@@ -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'
 #
 
 #
@@ -685,11 +852,46 @@ 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
 #
@@ -697,6 +899,7 @@ 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
index ec9a3034daa5e2936f1884d61c40c49b614a9063..9380c321169a747d19a993bc52a51776591a1f84 100644 (file)
@@ -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,10 +157,15 @@ 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
 #
@@ -161,6 +173,7 @@ 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
@@ -777,6 +805,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
 #
@@ -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
@@ -898,10 +944,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index 382b3bd3963bc171a7b0286bc3f8ece6dffef330..8800fefcbaf028075a913dc82559f9864285a24a 100644 (file)
@@ -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,10 +149,15 @@ 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
 #
@@ -161,6 +165,7 @@ 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
 
 #
@@ -690,6 +713,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
 #
@@ -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
@@ -813,10 +852,6 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index 69cf02a24761f16ef4f759e7512e12447c6a9a3a..98503f16f3f5da1749c0632d4e0ce70f7d02fdc2 100644 (file)
 #
 # 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
 #
 # 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
@@ -326,6 +454,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -434,18 +578,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # 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_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -455,12 +587,24 @@ CONFIG_SERIO_SERPORT=y
 # 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_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
@@ -497,15 +642,36 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -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'
 #
 
 #
@@ -558,31 +727,67 @@ 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
@@ -686,14 +899,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_PLIST=y
index 431c9c9da165348338741f9e4b0a0cbbb0c1ff56..c16350dac01bf8ebc854566d9e937ff888201126 100644 (file)
@@ -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,30 +304,15 @@ 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
 #
@@ -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'
 #
 
 #
@@ -388,30 +488,63 @@ 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
@@ -496,14 +632,12 @@ 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
index 1db2904de9e5ab80a1af9e01db3aebada96bbc97..5e817546113893289a6ccfdf3d1da879690ed8e6 100644 (file)
@@ -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
@@ -237,6 +279,11 @@ 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
 #
@@ -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,33 +764,34 @@ 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
 # 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)
 #
@@ -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,12 +1095,19 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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
 #
@@ -902,35 +1118,38 @@ 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
 
 #
 # Misc devices
 #
 
-#
-# 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
@@ -1016,15 +1243,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_MDC800 is not set
 # 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
 #
@@ -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
@@ -1105,40 +1332,72 @@ 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
index 70a5d82eb2f8c8b6a10340e152e77357304ce162..29b8ef9873d19128f27c150275e8705b2d7357c5 100644 (file)
@@ -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);
 }
-
index ada301c21fe7d3b489757fbe8d9a016487e6a4a4..d06030815a96acca6a01d5a54d3d41d86ef60b31 100644 (file)
@@ -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>
index 554d5ed2c5865466878eae422e08ad3855125257..6e3ba9c65b40534de3d65f3c9a358d52d3476853 100644 (file)
@@ -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>
index e58d556e5f94b0cde1523815f6dacbdff9fdf7d6..ebb58e605d9d27ddd47fecc45ce30d3a1e11a5db 100644 (file)
@@ -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 },
 };
 
index c6097bcd97fd4a5b1799024c7ee881534bd93bad..cd56d53375e7dc806c32c31cd2851058a622985b 100644 (file)
@@ -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>
index bd3064a820878062904c1c9c6c20ccd2824cfb0d..d6e635296534201965be4c9ce72a806a154b3597 100644 (file)
  *  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>
index 871e7d640002fa73c075457c8a39062fab155d38..4f66f91b1006671dd617c77c755b946aa727557a 100644 (file)
@@ -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>
index fe8221855b282648f25472cd64286814728f7843..97c571fbcdf13a5e2922867c143bf55dcb432292 100644 (file)
@@ -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>
  *     syscall #
  *
  */
-
-ENOSYS = 38
-EINVAL = 22
-
 #if defined(CONFIG_KGDB_NMI)
 NMI_VEC = 0x1c0                        ! Must catch early for debounce
 #endif
index 5f587332234a3e977cf1203477831dddfb446f50..36d86f9ac38a78b2834c6ba6551c1a6053ac76ef 100644 (file)
@@ -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);
index d3cbfa2ad4a785b13d9e6b130ee5c435b9cbf948..9daad70bc3050bf45a86e83b25018295a164be11 100644 (file)
@@ -72,6 +72,7 @@ DECLARE_EXPORT(__ashrdi3);
 DECLARE_EXPORT(__ashldi3);
 DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
+DECLARE_EXPORT(__movstrSI16);
 
 EXPORT_SYMBOL(strcpy);
 
index 6c0fb7c4af1190f40f1fcca3f93b2e15a82fedc9..dbebaddcfe394974686c833a39f837d562720fa5 100644 (file)
@@ -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. */
index b68ff705f0673c56c1a6845d97569689df136932..8fde95001c346873744057040b85c6f3cdbb094d 100644 (file)
@@ -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;
+}
index f664a196c4f58dd635cd6ec960fd7808a8e8532f..450c68f1df052f5ccba2eaef9d0149a1bc2390bf 100644 (file)
@@ -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);
diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore
new file mode 100644 (file)
index 0000000..40836ad
--- /dev/null
@@ -0,0 +1 @@
+vsyscall.lds
index 26b6046814fdf082ca0425923177b148a69c0da6..1efbac15ff4e4d370ab3c9fa651a7ae093c09163 100644 (file)
@@ -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>
index a22d914e4d15a1f52a8a9fba5c32894f2c81e596..e0122bd33ddb6373771e0d10bc648063ff2d990d 100644 (file)
@@ -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 = {
index bb2b82234e83a0610baa4b641e817773a15d9e27..65161e368353609fe58081a4fb6034aa3168a6de 100644 (file)
@@ -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");
index 48f27407d5e4b2c0ee10f2023e9bf27a9e092489..d81df574a7f70840ffd0121778065368ad210965 100644 (file)
@@ -1,55 +1,89 @@
 #
 # 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
 #
 # 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
 #
@@ -103,25 +137,29 @@ 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
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -134,6 +172,92 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # 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,39 +360,38 @@ 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)
 #
@@ -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
@@ -363,6 +429,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -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
@@ -475,19 +559,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # 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_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -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
@@ -505,12 +577,24 @@ CONFIG_MOUSE_PS2=y
 # 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_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
@@ -563,15 +649,36 @@ CONFIG_WATCHDOG=y
 # 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
@@ -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'
 #
 
 #
@@ -668,16 +786,52 @@ 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
@@ -823,15 +1001,13 @@ 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
index db475b7833fb86c97b77d70d8c45f9200905dfdf..525d0ec19b7822d597bcd9b6e4efd017295c6249 100644 (file)
 /*
  * 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);
 }
 
 /*
index 58ff7d522d81e0181950954f98608d6594bb3bd3..ad0fa4e003e79c082cfed7c0b5bf00d6a4726a36 100644 (file)
@@ -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;
+}
index 3b61e06f9d7258622d9aaa6123d433b66dd0f7d9..9c4a38a8698c608e353a04831fc1761fcd99e526 100644 (file)
 
 #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);
index e19b1bad9bc56e0c1710c4c1d006b6867fdc5984..edb6cc665f561652a7c3ef487166ad034c31f0df 100644 (file)
@@ -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--;
index 896863fb208a1a3e61f83f60b6f45860c4076115..a954a0c000002410e518e05f9ba905e8f53ff31a 100644 (file)
@@ -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;
+}
index aa0fb2efb6154241032343e30a748cea59dc5739..6f3ac548ee66dbe908eb157308962e9db489576b 100644 (file)
@@ -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;
index 6f84fa1b58e5e54b94c8ce42b05ee82c484c837b..e10dc831944d45c27f129038b1103306c15b567d 100644 (file)
@@ -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);
@@ -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);
index 8d8ca716f7a76de2073286e34ac03fc12fa52b3b..b627f8dbcaad5da32b4b5ffe1cad244d820bc898 100644 (file)
@@ -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
index 0fbdaa5daa8cfbdd6f761481a93d3b1f7b95ff06..f54ab375464b97ff4d1f8a515d597c5ad29121d4 100644 (file)
@@ -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
index e55466c77b61efaf0a8c13172e0dc100bcf3a2a1..0b9c70627ce4e7537d96422d62ff2ac5feb1ba1f 100644 (file)
@@ -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;
index 708ba9b42cda123a4522326495e2f9118053e166..c45f21b881d5faffd15afed4cd14a81acfca5e3d 100644 (file)
@@ -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)))
 
index c608c947e6c3dfb125ee6bb75358a7c0049f0ba0..a53d4abb4b49de1193b6a21d1d7e10a96c8eba51 100644 (file)
@@ -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;
+}
index 69444f266e2d5b88526b7019f3a0529de80edd9d..e27cb71bd8e2c09a20bfe7d50b379c80b39abe0a 100644 (file)
@@ -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);
index 87ebdf858a3a478c1140185e784f5f03964cfe16..7da72d3b322ae854853ed5f4724219ad8bcb3363 100644 (file)
@@ -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);
index ca1193482f07d2df1cd292bd6cce62531bad3426..00f6fc4aaaffc4182c0dec5af21f127d7e353493 100644 (file)
@@ -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;
 
index 0f0eb6aa1c401523c9af9fe00057884c00ff3e6f..12a940cc791f3cc0f96c6c39f99d199d514e3048 100644 (file)
@@ -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)               ||
index 9c581328e76a191e3b4aa4903840276db2c3aab2..9ed997982f8dbe245e2f3a15fab1257ee9c10c56 100644 (file)
@@ -249,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);
@@ -273,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);
@@ -305,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;
index 563ce7690a1eb66ccf38376da5c68c591666a7ea..24747a413785abc575dfd16cb74f60f159ce2339 100644 (file)
@@ -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);
index 773a134e7fdb806fd6b63c80ceb3576ede57a370..a67dcbd78de4765c7f7f54d7f907cfd01449c2c3 100644 (file)
@@ -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);
 }
 
index 5fa4c8e258a4e4d76d9406b5e002589e6c042374..fda4a3940698c26a8be776ce5141e5fa3e03189f 100644 (file)
@@ -981,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",
index 642c9a0320f9a111af988a8dead98a08ef107efb..7be24811bb3094b127667941f06c7297c085f2e9 100644 (file)
@@ -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);
 
index 48cf88dd02d4daaf94c0aca862065eb9abeb8388..f5ed8624648b88f0b0022a5994f202361fea19fb 100644 (file)
@@ -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;
+}
index 55005710dcbbc8254fc3bbea46f3f3b6ad065ad1..97d88e7902f7dbb71f19b62facbf652fe854575f 100644 (file)
@@ -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];
index ff203625a4bd9afb44ddc1c918a79df2dbc3d608..51f0893640a6ff39f7c42519506d7dae9ec6c3de 100644 (file)
@@ -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)
index 120abbe4e3ce2916d7d20eb7680dcdfd2a8c0baa..6e945ab4584324b6b6df71a7c32688c7cde95538 100644 (file)
@@ -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;
index 9cb09a45546b8828bd105729897ad431f6c509c1..a2de2580b8af4716593832ef880d1c930042c21b 100644 (file)
@@ -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;
        }
index 1b0ad0e4adcd26d29f0b605266dfea0cfb1f19d2..8e55cd5d3d07230bb5d98d5a5113fd6b707cec8a 100644 (file)
@@ -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);
index 6fce9f45dfdc0257aafafaf543afffcfc42127e3..73ce4463f70c6f96b2cd94f000b69df5a0da95ff 100644 (file)
@@ -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);
index d0a25af19a5bd216dc2995807fb0ed410238b44e..ce3e07fcf283747bdb72216bcf2f7968d2abe0af 100644 (file)
@@ -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),
index f4a4bffd8a18bc5fb4f6aadce49fb466453d11bd..57c9286a701bcdc71df35740973674b8c603684e 100644 (file)
@@ -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);
index 491614c435cd5f8de9a2d54a445156f94448a5d6..92f514fdcc79fa608e98093e1d003d506ef0eaf1 100644 (file)
@@ -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,
index f654088b27600098d89cab8afe0714f5a10aa645..996bd4f33ecb11a84de31911cb44fa531d53a429 100644 (file)
@@ -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];                    \
                                                                        \
index f36b778f14320e96e6dca7f748b2ed7cf98ae76c..35213fa9f7d829544c36e1223a6805df9cc4f004 100644 (file)
@@ -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);
 
index 3975aa02cef83df866a58085bb384715c87a3423..9973596ae3044e7dffc937bf8fc074f06ae451c5 100644 (file)
@@ -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,
index 2ec0700fc46bc75cc0ab9c312c0be75cdba674b9..d2b1fb19d24313d22896da6d72c710113ddaf9ef 100644 (file)
@@ -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;
+}
index 32ae1378f35c7ea6dbcb639d5a73b215fa71c93f..0a5d8e659aa4af3a03ec080368f7ff77f68860c1 100644 (file)
@@ -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
index 647610ecb5802b39e5e3e09b9e649381acb6a36d..4844b543bed0b8c4d697f64910ec7c550c922a11 100644 (file)
@@ -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
index f280d3665f4bed8fa07513078f39113369814354..c9bac3af29d6a746be28d38a241667e78593df3f 100644 (file)
@@ -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);
index 135ff25e6b449ad613671756ff3ba0c0b37ae018..6472e321cad7d0d6d682cf8e846a7f48ea761086 100644 (file)
@@ -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++;
-                       }
                }
        }
 }
index 2802524104f32da51e268cdc6b540efccccb93e1..b8285cf1a9c3b2780bdd53c499047856d378195d 100644 (file)
@@ -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
index ffc73ac72485f666befc9e7b13c730930fd6681b..ac241567e682eb45c4a7918b805082cddd52f5cb 100644 (file)
@@ -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;
 }
 
 /*
index 20e88f4b564b6d8c31604c8c5c50f71da6a7ac0e..b8d53dfa9931730a39409e2bb7c8048d6c6070cd 100644 (file)
@@ -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++;
 
index 4d6fb047952e8abec336175d3bc5abe12dc76e76..7af9cb3e2d99a8e71e54d89c170245580b2d470e 100644 (file)
 #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
index 4dcb671bd19fa760f81dc7d22f05a3eecf7c36a4..f8d857453f8afaf5fc839060cf1ad07dc69d13dc 100644 (file)
@@ -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);
 
index 458006ae19f3837c240477611cdcb6c1e3df503f..de10cb8a2c97b8cde91e730bcb1486442fc4f82e 100644 (file)
@@ -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,
index 0b00bb2ea5766fde600c537f4bc2778d33b9b1e0..fc944b5e8f4a6050612a0c9220c713e2f47d3a51 100644 (file)
@@ -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]);
        }
 
index 6449ea8fe756475b7316bdaa51ddd16e3c2c6dd9..76bf7c241fe410fdd676b17c6bce41143293a883 100644 (file)
@@ -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);                 
index 7ea3bf2a858c6299c1c686fc0530b1da14bbef63..557e92af7beabdf84b58d265ecda54bb5dbf4f58 100644 (file)
@@ -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);
@@ -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;
index d0564f1bcb0b9aa62a42919bcbeb24f8c2725397..b9df2ab6529fc8286b00f41d2081d393bbb2b444 100644 (file)
@@ -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 */
index ac48c3857ddb2164b34f857e6fe659b5b154b9b3..a98b460af6a1f600ebc2153490ecd4706700d08e 100644 (file)
@@ -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;
index 3e16fe08150ec6f3bb7a94e7bc6ec12a2e5193a7..19c72520a86876a616becaf31ab3d72f73e8bb3f 100644 (file)
@@ -462,19 +462,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;
index 45d7d823c3b85c91dab6740e30278fd0caa628ae..c6e5e8d401a490ab4fe25cf0a850f8cbc84d76a2 100644 (file)
 #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;
        }
index f8c04d6935c922725d64ddf97178826f1b3e27cd..3cc0544e25f5a8569af1a727c3f819b252fe3635 100644 (file)
 
 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);
+
index 4688ba2db84d5c46c8ae060bec50fe891454bf4b..d9285d4d5565bfbfa21ae1043697a2cdd5ba0f15 100644 (file)
@@ -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;
+}
index 241db201f40e59300bb97691bdcc4b2608c80c23..37347e36998723aaaf7803a3185cf9543cd9f805 100644 (file)
@@ -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)
                ;
 
@@ -179,8 +173,7 @@ again:
 
                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;
index 22d3c571a7bc70c8927b19cd17ec19990185a3e3..5c947cae75207d91825ead1b34cf59fdc516bcf7 100644 (file)
@@ -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,
index b6f5f0a79655a3de0125af945682f91bf92bc726..83766a6bdee264f3c3a8da74bfa95ada55097062 100644 (file)
@@ -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
index 48d090e266fc5745be94af97ff8deb32c2726995..903f0d3b68520a94a5a76222b31c6860ba57de20 100644 (file)
@@ -1,3 +1,4 @@
+if BLOCK
 
 menu "IO Schedulers"
 
@@ -67,3 +68,5 @@ config DEFAULT_IOSCHED
        default "noop" if DEFAULT_NOOP
 
 endmenu
+
+endif
index c05de0e0037fe6f14f9e6f508bece1271568bb36..4b84d0d5947bc22cf8a94f91fb7c556b29ff571c 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the kernel block layer
 #
 
-obj- := 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
index 5da56d48fbd36473ba92fb346a91d06dbea148a1..50b95e4c1425b8ae3950451c146c020da4b0b146 100644 (file)
@@ -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);
index 8ff33441d8a214259bd2c718ddb4735874dd2fc5..135593c8e45bdee40f97c3e690d47c34e769370a 100644 (file)
@@ -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)))
@@ -473,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;
@@ -490,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)
@@ -532,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;
index 3a3aee08ec5f4850f0a1877b3bdf86d9b03d9625..d3d76136f53adea6293244f7cd9a9aa07f24b4d0 100644 (file)
@@ -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)
@@ -102,29 +81,14 @@ struct cfq_data {
        struct list_head idle_rr;
        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
         */
@@ -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,69 +195,13 @@ 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();
index c7ca9f0b64989cdda8a16a56593fd52f2a251470..b7c5b34cb7b43b4688b3f4bbda5951726bbb008a 100644 (file)
@@ -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
@@ -301,28 +121,15 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
        struct request *__rq;
        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);
 }
 
index 9b72dc7c8a5c98dcde87dc0d7e42d9a56f447776..487dd3da8853971d9bcb77cf6ecf51eb39faedf3 100644 (file)
@@ -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:
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/blktrace_api.h>
+#include <linux/hash.h>
 
 #include <asm/uaccess.h>
 
 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?
  */
@@ -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);
index 309760b7e37f0c9a7d08ddcf047196dc1eb70875..58aab630dfc1a55eaf06975d5a48600b5f14e49e 100644 (file)
@@ -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)
index 51dc0edf76e0281f52e53da15576e4ffa62b0eab..83425fb3c8dba6e2b62122aaa6a02a25d2436ab4 100644 (file)
@@ -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;
@@ -2029,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);
 
@@ -2044,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;
@@ -2141,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".
@@ -2189,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
@@ -2225,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:
@@ -2268,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);
@@ -2299,6 +2271,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
@@ -2351,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;
 
@@ -2365,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);
 }
 
@@ -2558,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);
@@ -2598,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;
@@ -2710,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))
@@ -2719,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);
@@ -2764,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);
 
        /*
@@ -2829,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;
 
        /*
@@ -2890,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;
@@ -2914,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;
@@ -2924,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
@@ -2943,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;
@@ -2972,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:
@@ -2992,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. */
@@ -3012,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
@@ -3306,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);
@@ -3569,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);
@@ -3658,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);
 }
 
@@ -3688,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;
@@ -3697,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;
@@ -3721,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;
@@ -3837,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);
 
index 56a7c620574f86c0338a431354344d149314ce0f..79af431794213867e5ac1c457103d62b0d74cb43 100644 (file)
@@ -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);
index b33eda26e2053e84f85473a13cd657cf920e3fe0..2dc326421a24af9c745e9f4eb34f7a80f1a41d0a 100644 (file)
@@ -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;
index 1dda370f402b69d4d69dd433c6dcfab2e58cd5d5..98099de59b45bcfec5ee8636650c5eb29ee5fbd0 100644 (file)
@@ -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;
index 71066066d626b82f8b0bc656e253bb925761ee8c..0a395fca843b46686b748ffe1583515cc863e9af 100644 (file)
@@ -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;
index cf656ecbe5073359b3c02b5faaeee9313f476740..8c757438f350329e47e045b88a930587e9267520 100644 (file)
@@ -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;
index b539e5e75b5690116f868c9ea06283c758f6f7a7..7bbb9eeda235efb5dd307eb1d5e89dfa552f550a 100644 (file)
@@ -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
 
index a360215dbce79cc1ff85f4b03651000ae17436b0..b3f639fbf220038a8b04fad8de15178741ab9e16 100644 (file)
@@ -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;
index a82f37f749a5c2e265dd96c4d2abb88e84a7d329..f9217c34bc2bb2cbf200f2d4a3f3eb486de11cf0 100644 (file)
@@ -71,7 +71,7 @@
   Define a Boolean data type.
 */
 
-typedef enum { false, true } __attribute__ ((packed)) boolean;
+typedef bool boolean;
 
 
 /*
index b5382cedf0c09cad0376df575c32b194d5ba7c0d..422e31d5f8e5c4627c15c88ecc38ff8627276069 100644 (file)
@@ -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
index 2cd3391ff8783dcb8497600d833f4cedf4a24eb4..99f87efe0f588b2d4327516b7a7dac0304fcc39b 100644 (file)
@@ -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);
 }
 
index 868e0d862b0d274980857ee8593a385006ae2432..562235c1445a123b9a5f36293b6f28bf887c2ff0 100644 (file)
@@ -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];
index 53fea549ba8b23a6714cfd8a33fc55705893986e..4af7c4c0c7afb4610863d36142ed1e9ad19d994f 100644 (file)
@@ -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
index 05f79d7393f72960a1f8af8006ba025f939e4a43..bb15051ffbe0d316182cbb9ef11d9dba9b8f64c0 100644 (file)
@@ -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;
index 78082edc14b4f6fdaec8652f12b45e3a921c3223..4abc193314ee6c34f7a6e93f5e5faaaca8c3761f 100644 (file)
@@ -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;
index ad1d7065a1b20ef10028c8723bf63fab817ade4a..629c5769d994e3a45aa9063cfd5cf08532f2c494 100644 (file)
@@ -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)) {
index 68b0471ad5a64e52a2b53135ab58523507fb700d..d6bb8da955a213c0c192dd3272ea435393a0a180 100644 (file)
@@ -66,6 +66,7 @@
 #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() */
@@ -1165,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;
@@ -1192,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
 };
 
 /*
index bdbade9a5cf50a99e3b2e3fa3f860d71f36bfe82..9d1035e8d9d8c713148aa589abbf2c738022c197 100644 (file)
@@ -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
index 2403721f9db107509cc4ff8b628795a70290597e..40a11e567970f30675f8b84590591146947d4e95 100644 (file)
@@ -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);
index 451b996bba91e53bc934cc54048951015acc9868..a6b2aa67c9b264869b71720971b4566b171ec71f 100644 (file)
@@ -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);
index cc42e762396f28fccff473f32b9cc1c73ef862fb..f2305ee792a142b32d700473222ffe530742f31b 100644 (file)
@@ -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) {
index 89e3c2f8b77681bacd376ba480732d4e84b97b9d..dfda796eba563df8fbfa53b476f7abc0f48d9372 100644 (file)
@@ -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) {
index 5d8925bd90454c68d33d00d3263e93dac09b91df..cbb9d0f21acc7d8f52dbdbacb499465172b36982 100644 (file)
@@ -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);
index e828e4cbd3e1122a0ca3abb48e7ed2de51a6bf81..ebf3025721d148866aeb0f5be68fbd4e6fdfb7ea 100644 (file)
@@ -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;
                }
index ff5652d40619e018a83a29b7bed703531e37e85f..4b12e9031fb3cecbf6259c457aa77c8a394a3674 100644 (file)
@@ -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"
index d239cf8b20bd1e769a84612959e55eccfe8e1510..b38c84a7a8e3e30e7d8080fafa209562d7e7f673 100644 (file)
@@ -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;
 
index 37bdb0163f0d1b47acf2df88392b318de984480a..ccd91c1a84bd10d2e0c2ca42a7cbd161f93146af 100644 (file)
@@ -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;
index 4cc619edf42466e02f08079f186338a7eb7a5959..bde1c665d9f4b1cf6e70cfa9ba32ec7bd765d3cc 100644 (file)
@@ -1006,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. 
index 8cd52984cda5230b8ecbf93561801cfc72b8977d..00b17ae39736cbbb4132f85d91c0b1c80f415bd1 100644 (file)
@@ -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;
 }
 
index 0dcdb363923fed70e4fa9f964c563a53bcf4f67c..c39200161688eef6ed3b45b6a1de451f4cd67dc9 100644 (file)
@@ -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;
                        }
index 9d6713a93ed74ddb74adaf18aa85fd22e0ee6508..d0e92ed0a367292d271d625b1b80069fed195fd6 100644 (file)
@@ -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,
index c1c67281750da61ef1750706bb8351e780cb3e43..f85b4eb166181ba5d1777af825454601abd301aa 100644 (file)
@@ -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,
index 5278c388d3e747dbc40251c70985e25ef5d4eceb..ef833a1c27eb1c60a49eca9566f8d987add2d262 100644 (file)
@@ -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
 
index 9d180c42816cb592c4c83b7331d2977116cf263d..3ad0f648c6b22340e79f0f12068f5661808a3c43 100644 (file)
@@ -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
index d2a56182bc35786a08c681abb273fea450e3abdd..7690a59ace0426b0249127831b3d668bab2bb444 100644 (file)
@@ -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 */
 #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
 #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
 
 /*@}*/
 
 /*@{*/
 
 #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)
index 2a37586a7ee8d4e7ca856723f27be808e6649005..c7b19d35bcd6fc059c4c41d6925221f0bc78eb0a 100644 (file)
 
 #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.
  *
@@ -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;
 }
 
 /**
index 006b06d29727069b30ff304f5ad58084804a689d..029baea33b628772bb0f238acb3d59392117fa9c 100644 (file)
@@ -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)) {
index 3c0b882a8e72843a2074b2b495ffa2f2ebf266ab..b366c5b1bd16713345c56a09e389db70b026e727 100644 (file)
@@ -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);
index b7f7951c458721d8b3517c49dd5b4531bfa6f3be..898f47dafec0b2fc6234e0c7f42ad3a4656e70ef 100644 (file)
@@ -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 (file)
index 0000000..a0b2d68
--- /dev/null
@@ -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 (file)
index 0000000..40afec0
--- /dev/null
@@ -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
+
index e9e2db18952dc91e2b88c8283efb6d385ff84dd9..d4f874520082844776eff9f912cb70323f25003f 100644 (file)
@@ -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];
index 555f323b8a32c350578b4f75ea04b5a345472c80..565895547d75b2c254db4eafaab91c344d14780e 100644 (file)
@@ -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);
index ebdb7182c4fd7e2c973d27a5aaa602861058c960..4553a3a1e496c463b82b6a93e7cda756aec350a0 100644 (file)
@@ -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 (file)
index 0000000..617526b
--- /dev/null
@@ -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);
index b1bb3c7b568deaac4be5e259930d7daecc00699c..09398d5fbd3f0644ca528e740f3bbb8f53c65431 100644 (file)
@@ -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}, \
        {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}, \
        {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}, \
        {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 \
        {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}
 
        {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 \
        {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}
 
index 362a270af0f10c53387069b2b7124ce788f23e96..62d5fe15f0468971b9017c1b932c3c1fcd5be819 100644 (file)
@@ -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 (file)
index 0000000..425c823
--- /dev/null
@@ -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 (file)
index 0000000..ddc732a
--- /dev/null
@@ -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
index 9a842a36bb2754cfef213344754e0ff951e4c44c..7b1d4e8659baa41e71560f8c02d5592baa66ea4a 100644 (file)
@@ -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;
index ffd0800ed601b286863f5a3a80c2538042340af1..b40ae438f5315343248930f32df8f53f10b38845 100644 (file)
@@ -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))
index c658dde3633b4307b4e38d79eafdf079ab56af0d..fa2de70f7401aded1c300fec6ba4799075348562 100644 (file)
@@ -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;
                }
 
index b0f815d8cea8592028cee0540f6b23ffe3dac9c8..4f0e5746ab3382f30ff16e393aabca4f973e025d 100644 (file)
@@ -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;
index a94233bdbc0e4575748e90ed54b461521016dda6..fb7913ff5286b58e6fd8b5a574590f8e1d8f8948 100644 (file)
 #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);
index 5aa3e0e3bb457693f45174962bcf5039973a1deb..6af83e613f277537af402c7358f3288ef715d8d6 100644 (file)
@@ -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
index 2d565031c0020c541e07bdeaa97d9b172cd21243..fdc2bf1927143febdac052799b72c68747ff11ae 100644 (file)
@@ -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)
index cd96cfa430db2615d5276c60990a022b139f0913..0d4a162aa38514a4aea1f27898cb47b05e829264 100644 (file)
@@ -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)
index 5ad43ba7b5aa16fa526a8428d507a212073688ae..5ed965688293a04b6c6a11641be19ce0adf5ba6c 100644 (file)
@@ -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;
 }
 
index eb985c2a31e96b3a81ac2ae3ef37357834cb2fb7..2eb652ec674578c97f24cf1ca6c40b0d58a4454e 100644 (file)
@@ -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" :
index e5a256f5429c81c504d1ec15086caea2489c67cb..f45cd7f147a5ad97eaffd2aec313ed1d0fb4fe05 100644 (file)
@@ -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 {                                     \
index 39a7f685e3fd7d5f0e3c4e98f58510258303069a..feac5f005d47be1d56d52819ff8074651ec87e7a 100644 (file)
@@ -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);
        }
 
index 5e9dc86f2956f5ed93683ca618f375b9917e03b2..3d5b3218b6ff02fa5da3e377276be76174692151 100644 (file)
@@ -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,
index e218e5269503b80ff65d6127b249ba88baf79bab..2b8d6f6ed7c013adfb3affb0850a0c39e4276473 100644 (file)
 /* 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 (file)
index 2e485d4..0000000
+++ /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 (file)
index 94f2b47..0000000
+++ /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__ */
index 5e9936bc307fc21d7a321fae5e1ce2377182aee6..d26f5dbb78538ea4532c7f79965fdd91aefd3fd1 100644 (file)
-/* 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);
index 78a81a4a99c5c60fda46b05497351e211d94df1f..60c1695db3000e3611af463374ee0fd388439b07 100644 (file)
@@ -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().
  */
index 47f0b5b26379522d1881ea95158c74283572c96b..e4ee97d7156ff2b322bcc0ecda06ad1eebbf8b49 100644 (file)
@@ -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;
index b3d364d793d748bf06eeb9833fbada3b38dff0b0..bb9dde8b1911138445caf8cbf665f479dfc1fe42 100644 (file)
@@ -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,
index 52bcc7b1ba4560065be1a85eb981b15e5a46aea8..d21b5b75da0fa944153fe1a7134670dd44f6606b 100644 (file)
 #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 (file)
index 9429736..0000000
+++ /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 (file)
index d2bb9f3..0000000
+++ /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
index c6a08e96285bf55c62a96480c7989ea0632a7419..782011e0a58d49efb209593d0896dacd030cdde9 100644 (file)
@@ -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;
index 33e0cb12e4c30dd448365847421b9266f8ac71c5..2fcf0577a7aa9e5b4b52d37cf7e897b3238e2315 100644 (file)
@@ -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"),
  * 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;
 }
index 21c8229f544388cfb2d75f68218abaac215b4c17..6d58b037080234431b49f6cacde669998ab749a7 100644 (file)
@@ -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
index 86d290e9f307044041fed353cf6bca3ed0cc44cc..3baa2ab8cbd49421818ed995bf38a4935af1da34 100644 (file)
@@ -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,
index afcd83d9984be5b00937c7959d3bc7476ec2041c..05788c75d7fc83dffc807c5e654cae160a469959 100644 (file)
@@ -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,
index a76d2c40dd5e7e5e375a9a39054333c3752fdafa..4053d1cd393f520101857047d52fc63b70efe7d7 100644 (file)
@@ -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,
index 4747729459c7a5a0c0aa29f9ec8a7023d73fc66a..8b6f197e5f8cbce32a307bec1be4d66846b43103 100644 (file)
@@ -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);
 
index 4589ff302b076a123396bd5d218aa6007a08d294..0b89bcde8c52e80c6550e96d42ed9503c91f1a99 100644 (file)
@@ -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,
index a89a95fb5e40fb76b766c8b50483bd435ac2bd5e..c07dc58d5c1d7261eb6a4b75f9f935d3bf61ce72 100644 (file)
@@ -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,
index 7907ae88c2f4df48cdecccd87d0c20f6e7f2b8e2..62ef511d143bf92888beffddf3441d2fc9460677 100644 (file)
@@ -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:
index 68d7c61a864e7ecc4f696e3b36f4ceb92201472f..81fcf0ce21d1c91cf95f478a960a20d2459a6772 100644 (file)
@@ -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;
        }
 
index 843d34c8627c38d3a72889557f216513bc9fe638..2455e8d478ace521bd7ef8f85c3ffac7e6a5388e 100644 (file)
@@ -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);
index abca98beac14507471537abfc50403e06d10abdf..b106c45abfc927f359ae463ad8659cd2f2cdf7e7 100644 (file)
@@ -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);
index 913be23e0a2427e16b07ae6e422ba9e8632bf7ea..ea2bbf80ad33839b381bb526ab957dd540e55b8a 100644 (file)
@@ -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;
 
index 6b4d82a4565fbf9ec533891f8043b6aa3d5ca707..d6e031542c6bdbd68932b3a46c7fa3ccaf1d2925 100644 (file)
@@ -4636,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,
index 3e90aac3751032b74178a85fd31f5778f3bb7d29..e2011669c7bb4bc187a3e216e21a37b1711b9f4e 100644 (file)
@@ -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);
index 0385650f6077892843b966f3c68018c254a46492..636354722658eb4b6cc035f7f0a22196fc91e141 100644 (file)
@@ -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;
 
index a369dd6877d8afdf5f57f66def984f207b3ea581..b401383808c26ac4c16ce38f15fc129b4dafd56a 100644 (file)
@@ -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);
index 39a2e661ff550e1ba50848539940c3a0e1e439b6..8d14823b0514ef3b58a4e775aa33cfa72009a4e8 100644 (file)
@@ -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:"
index 556abd3e0d0735e93ce55415fdf3c14834f69ba6..8253fca8efd527c3a1d763a2805bffc4c20cb77a 100644 (file)
@@ -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);
        }
 
index 7c57ebfa8640a578d2840ba00a38cef5388eb761..ea1aa7764f8e1a0b756b8be75172488bdc7bf714 100644 (file)
@@ -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);
index 539efe7826185fe8c4fc72709b8a35ffa8be22b9..d1ecb2c6de98719803479876d3e9ea0d7f185c03 100644 (file)
@@ -3009,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,
index 34dd4c38110e060f6bdfd866d0aa2bdb41994d08..80d3eedd7f96f32997a69fa24f2134b38c8d1f1f 100644 (file)
@@ -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,
index 4c3a5ca9d8f7a98f882cdbeed12f0949af940a55..07f47a0208a7200b4e0ba1f32bd747d82ae1db6b 100644 (file)
@@ -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)
index c596a08c07b3591da8025955a236fd8fb908303b..89b718e326e5a0873ca0002cc76441a3c5469238 100644 (file)
@@ -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,
 };
 
index 3fa80aaf452751b24397192406ee944f7f3e04bc..202a3b0945b78749dbf0c4cc97356e217753f07b 100644 (file)
@@ -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,
index f1c94f771af5e803426fd2f0a707cd7154e66897..214d850112fde66bcbff652fc2561926fcd16923 100644 (file)
@@ -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,
index 0ac131881322c96920b049c45e8aa64d5fbdb635..bac80056f7e0c7e45893c7f7a46f9b2c196222af 100644 (file)
@@ -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,
index 510bd3e0e88b432744ab8064bcaa9edaea95287d..65c751d0d64350b2b6c25df7d777504da53c6c21 100644 (file)
@@ -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,
index 21a710cb4bbaed1df2ebfc6a6044bcf5abeb67c4..b4ea1266b66300980288141975bc0392345955ee 100644 (file)
@@ -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,
index d12d4f629cec80ca1137fc4e0fc8ad0351f8bfa2..864854c58866ad12076e970acbea1181872e4a79 100644 (file)
@@ -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);
index c0ef0f0e5800dcd74a90e38cc483bc2e37ac60f0..902c48dca3bc98e86938fb23a0affbd052d921ea 100644 (file)
@@ -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,
@@ -1674,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;
        }
@@ -2364,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,
@@ -2398,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;
@@ -2417,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();
@@ -2443,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();
index 3beb2203d24be21375175daf23021bbdd8e6daae..bd711537ec4e851791699c377e2540218aaa7ff6 100644 (file)
@@ -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,
index e1cd2bc4b1e4222e5806dab4389169ffa774900b..57e31e5eaedb7aa998dff3373fc96f180cb45e79 100644 (file)
@@ -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,
index c53f4579a59fa6e8e8beb8634e071f29940fd0ca..38d94987de8343988faa9ef3ffe0049a61d5be60 100644 (file)
@@ -4359,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,
index 2f07b085536b8879b67ece97348a1126074e2a6d..bdc7cb248b8f1818db19b0bbb09ae46904f8cd06 100644 (file)
@@ -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.
  *
  * 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);
 
index 66f3754fbbdf443e891b21cdfcf88c799144e6b9..6eb75dcd79613b2f8c454be4331f496004156000 100644 (file)
@@ -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,
index 0ad6cb081db4d1b3681a7b069d9439454e3bd9fc..6b4d4d1e343da3332f413b8d47c65b00e9ff4a0b 100644 (file)
@@ -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();
 }
index d30dc09dbbc9df2ffbb5c09e8f3cb32e334a49e2..9df0ca1be0e31a4e25310e58b370c10da4227c78 100644 (file)
@@ -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;
                }
index 333741770f1e079f2fbe0df98b69699a4194f924..e90ea39c7c4b1112fd7d7db878b96d8531a0f162 100644 (file)
@@ -3680,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;
index f3efeaf2826e901a65fced866aa86b0c9b21bead..a362ee9c92ddb68305cf0d2b6ba2ef2c89932301 100644 (file)
@@ -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,
index bfe5ea948f6a51a4acb6687efe4f45ab05d441ff..c2ca31eb850ba034b9c7e9f27f06c9e15086d422 100644 (file)
@@ -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,
index fb75da940b59c971472812795b3094966b5c8b73..8e4413f6fbaf6145352ffb5e7c9af0530240cc79 100644 (file)
 #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;
@@ -138,14 +139,6 @@ const struct consw *conswitchp;
 extern void vcs_make_sysfs(struct tty_struct *tty);
 extern void vcs_remove_sysfs(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
-
 struct vc vc_cons [MAX_NR_CONSOLES];
 
 #ifndef VT_SINGLE_DRIVER
@@ -903,6 +896,7 @@ void vc_deallocate(unsigned int currcons)
        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);
@@ -2674,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,
@@ -3069,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;
+       }
+
+       if (error) {
+               while (--i >= 0)
+                       class_device_remove_file(con->class_dev,
                                         &class_device_attrs[i]);
+               con->flag &= ~CON_DRIVER_FLAG_ATTR;
+       }
 
-       return 0;
+       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;
+       }
 }
 
 /**
@@ -3183,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);
index a53e382cc10747b2e73a9386c67a78f73700582f..ac5d60edbafaadda7d58dd13601fb70e9ac70a82 100644 (file)
@@ -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();
@@ -1060,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);
@@ -1111,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
@@ -1171,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
index 77ab7e020da0a8ee2672a379d79f93aed3235899..06f3fa2fe877dd335fd59bd0a8b1b35cd6331046 100644 (file)
@@ -172,6 +172,17 @@ config OMAP_WATCHDOG
          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
index 5099f8be8cc51efab2bc38d98dfd2df495833daf..6ffca7cb56ab65756a70e22025004c5f691ef07e 100644 (file)
@@ -33,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
index c77fe3cf2852a198ff51133c0d79be03918a2960..154d67e591e5c928b6cd59b97a746e994c46b8d8 100644 (file)
@@ -183,7 +183,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
 }
 
index 8069be445edc3683f358e644ec7e883d7d4ad40c..9d732769ba0144bd36a720d4362185dc0bb651d1 100644 (file)
@@ -176,7 +176,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index c5c94e4c94950ba93035e01e4053c9d1cc916a58..01b0d132ee41b3890b58cb3a983b87742bf69dff 100644 (file)
@@ -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);
index ffd7684f999b3220572dbcf45cbe7a92b4a9b677..5948863b592b7434d57117dadc381a7584c113be 100644 (file)
@@ -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;
 }
 
index cc266715ea320b029496d0b5ad1d3ece4dc0d77e..4e7a1145e78fd472a70f9442e3a0c7bec461741d 100644 (file)
@@ -168,7 +168,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file,
                        return 0;
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
index e3cefc538b40476b341aeed5e4f61a874b64baa4..488902231cc237ec24cd76568af57c186bc6d12d 100644 (file)
@@ -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;
index 04c7e49918db0b5d491521f63a2415d318f0443a..00bdabb90f27b958a76ab7b8d39c4b505892411e 100644 (file)
@@ -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;
 }
index 77c8a955ae9e1f10f2e548b6b395bffe420d1f48..01cf123b1616db2eebda898dafbd167e994d8099 100644 (file)
@@ -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:
index 62dbccb2f6df979b23e0129871b6884df40b0c76..4f4269754c462fb21aa2573a23a1028323af98db 100644 (file)
@@ -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;
index 870539eabbf3a93100693f19f966b1e404104ce5..fb64df4d7c8720107f16e360047c93ef2deac0b4 100644 (file)
@@ -315,7 +315,7 @@ static int esb_ioctl (struct inode *inode, struct file *file,
                         return put_user(heartbeat, p);
 
                 default:
-                        return -ENOIOCTLCMD;
+                        return -ENOTTY;
         }
 }
 
index 8385dd36eefe0fd7074306d7eacec6b4d4b25826..e0627d79707b27f6b91d8ccb47506a29f1fad451 100644 (file)
@@ -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);
index fd95f7327798692c8612da2caacd1939ba0b7280..c1ed209a138ca3176313abcf3fa4bdcc2de33b9f 100644 (file)
@@ -199,7 +199,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          break;
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index 26ceee7a4df0922bd370560a4023d1bfa1892267..dd6760f1a23ba43ecc40342cc9c1d9da3ef13e9c 100644 (file)
@@ -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)
index dacc1c20a310747aa322f9661047d82d47e1c7ab..0bc239308989d53dbf7adf8ad537ada06e086b12 100644 (file)
@@ -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)))
index 692908819e26651cda0aa04ad555a78a651b6a52..c91d9a660ec00c5644a6d5a0a386582209d5aecc 100644 (file)
@@ -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) {
index 9db5cf2c38c37064334875b42c35c93dbce15126..db477f7123883c143cdabef88b456a8c6c400850 100644 (file)
@@ -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) {
index 23734e07fb22503d5395550e49bae577595a1295..276577d08fba2f0f2791c1c1a03de69ad8feb5c2 100644 (file)
@@ -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;
        }
index ae943324d2511e2b5ab174b59d864fc055ca60a3..c2dac0aa1d6254906468a35dcbaea932197b416f 100644 (file)
@@ -185,7 +185,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
                        mixcomwd_ping();
                        break;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
        return 0;
 }
index a480903ee1a59cbf4e17e0bcd150cc0e4aef47c6..18ca752e2f904f7425208c0fd2453ef0c55ebd99 100644 (file)
@@ -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;
        }
 }
 
index 35dd9e6e114023e5b9d65a801b23e8a728be1263..8aaed10dd4999e66928168cdb781df1fda97fad2 100644 (file)
@@ -126,7 +126,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        return 0;
index 54b3c56ead0df8abdde728fe425a54ac9fc7661f..02d336ace50477bdb85609329cebb44f6422efdb 100644 (file)
@@ -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) {
index 5c8fab345b403668a6159cc9b8a35392a0cc3b36..b887cdb0133428c07d4f08613b355527dad55b82 100644 (file)
@@ -160,7 +160,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        return 0;
index cd7d1b6a5d9fb2dd97aeae7783327f74163d8830..6f8515db5b076028cb620de63e01e8d3692be6f8 100644 (file)
@@ -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)))
index c7cfd6dbfe1b299b7bcf8db0189645cb3a5fe78d..2de6e497c1402e9fa434c1f7afd12708f1820427 100644 (file)
@@ -541,7 +541,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                }
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
index b7ae73dcdd0823602e1c75983fdb7455f9a7a824..77662cb0ac46e3962beb4f7d660ecaf16fc9bb4c 100644 (file)
@@ -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 (file)
index 0000000..e7f0450
--- /dev/null
@@ -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);
index be978e8ed754941fa215bc5864e72e8e3bb258ea..b36a04ae9ab8e96306a35ce07680aed56bae40d2 100644 (file)
@@ -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,
index 1fc16d995788792794e7cbf3cb673c62314464d0..33c1137f17d6d3e8be5cbbc3abb2bf3099721cc1 100644 (file)
@@ -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;
index 4663c2fd53cd6fbe57f41c6acad6c2577cbc452b..c7b2045bc76b5196f6aa04c732c2dd95a4912704 100644 (file)
@@ -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:
index bfc475dabe6d76406dd44b968479227c31678619..8882b427d24f44d988bd2682fee1559a305eecec 100644 (file)
@@ -141,7 +141,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
 
                return retval;
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index 7c3cf293a5afc3684111c95bce7ad52653a4cb74..d8d0f28e0acf9ab30b54c9abfd57f12416313e7d 100644 (file)
@@ -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))
index 2c7c9db71be81e9eb5318cebe94d7fd215ecd8c3..caec37ba750a6810e7ea54abb6f73a6e72ef8e69 100644 (file)
@@ -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:
index c561299a5537b483ab242399114bb9580c499930..fc0e0347f9d24b665711e21ca8d315567ea20e98 100644 (file)
@@ -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;
index e5b8c64f1d65acf4ac67dfb8f77d5376d2ac974e..dc403629aeb3d79a4e112798fe4ababfd2751070 100644 (file)
@@ -360,7 +360,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
 
                        return retval;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 
        return 0;
index ef8da517545add27cabc43338cbf17d851170625..4067e1f8a36878c7fa6665175051231b2710542f 100644 (file)
@@ -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;
index 13f16d41c2fd33a1db8d68cd6b74b41038c2a103..b4adc527e687e8c7e43f047be489b0fbc13f0ddf 100644 (file)
@@ -223,7 +223,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index ccf6c0915945d8f517f124cbf989016f6c1b1ddf..b0e5f84d6bafdc24fb9c21742f35b3b0bcdcc965 100644 (file)
@@ -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:
index 98f4e17db70a478441bfa9d68e2d1d1a704df12a..2c8d5d8bd4e85303750274d1e9b2907b66c0bdad 100644 (file)
@@ -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;
index 2bb6a9d6ad2805dba0bb60093a31acf6d5fd7e1c..163e028ef9ed6cee052ee4aa643d8659e17e5bc8 100644 (file)
@@ -174,7 +174,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        }
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
        return 0;
 }
index 5c38cdf41731201b7f37506e79cbadf6cfcd3438..1d64e277567dc487a3ab1f098afe0b38c227d5d4 100644 (file)
@@ -385,7 +385,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
                return put_user(wdrtas_interval, argp);
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index 70be81e39a61b3284cd86775ebcdc6fa0d9f54c3..13f23f4a223347393173a86d7c4eb17648f5097a 100644 (file)
@@ -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;
 
index 6555fb844f2342113a91ca7cec265403e25f628a..89a249e23fdee2b0377d3e5a04ade645ee7979bf 100644 (file)
@@ -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:
index a0935bc775f8eb847d39ab4f32eacb8a7914ae47..6253041b235bb2ae0c1260e772f86b659bd799cb 100644 (file)
@@ -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,
index 5918ca2c9c35b6c5bbc9bbb2d4012ebab122b80a..74d8cf836e13aa91fb11885dbb5e769ac5f2f49b 100644 (file)
@@ -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;
 
index d35a9f06ab7b6fe25420c53dd657e849fc00cbed..2caaf71d80c85566bd24d235419f6e09fa097d12 100644 (file)
@@ -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;
index 1a159e8843ca47dd27778937d350df400448c48f..22d17474755f73ac86660c499e486750132f3c60 100644 (file)
@@ -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;
 
index 23b086685453d295c6b119c3ce83253cd57e95d7..fc17599c905e001f055cec284d52bd3e1f86a25f 100644 (file)
@@ -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;
        }
 
index 8e7b5607f5a116c1b5ef73af39c42fa67e356e2e..26be4ea8a38ac7c2150d250fdabcc3395f5cbb71 100644 (file)
@@ -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"),
index d82e6dae84070951f625622229154cb32d3f2333..559a62b04ee9aa0269c69ae6104725b53aabe783 100644 (file)
@@ -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
index 01233f0f7771687951a5dda8e6e2482a0bbaeca5..7ca81f42d14bfd7c1ab5834b2a6cb853587259a9 100644 (file)
@@ -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;
 }
 
 
index b6fb167e20f681980a54c9baa7ef14a0de4fea83..abcabb2955925f09583d6da02a5ce8c7b7cace0b 100644 (file)
@@ -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
index 654d4cd09847cebdcad66b77fc5c9f0167f78149..69bbb6206a00ef5673638c0ccfb4a59bfa272b1d 100644 (file)
@@ -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;
index 7cf3eb02352140d8f8558533aee4107c8fd1a445..0a05a377d66ac54a77056fd67cf484cf5bdf8fec 100644 (file)
@@ -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);
index 7c3a13e1cf647a4cbca6ee39c327c36f9de8d422..56efed6742d4d32945a1072203fea57b833d1df5 100644 (file)
@@ -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;
 }
 
index adbe9f76a50533c64355078e77bf1ce564de746e..8ccee9c769f8ad54ee80f539a16eaa3a15615684 100644 (file)
@@ -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);
index fb6795236e76c677c9bf990a48dc62ec675da8da..ba6039b55b41ebb348223db10dc4f9a9ea9cfd0e 100644 (file)
@@ -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;
 
index 77703acaec1731164c433d7ce35d2eda0ba15293..badde6331775a12208c375fb68139b0e156d9606 100644 (file)
@@ -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.
index 1feff23487d44f515574809e153744a615c7ad26..8237d89eec6e2c3ddd735369ddef750c1ea4fad3 100644 (file)
@@ -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;
index 9cadf0106c6c781d45a2add269b0b2961a1691aa..dad9c47ebb69bb0aa667689f701301a34118c115 100644 (file)
@@ -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;
index 41b74b13a00c477f2f0f498442d207ac4fefa5c3..aa049dab3d95c17609f3a1d54621f18a01896749 100644 (file)
@@ -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;
 }
 
index 7067ab997927d5515f32f2b09c8a48af1cc34cdf..e2f4bb5490638de5c1326dc863c322417c99002b 100644 (file)
@@ -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);
index 97a9244312fc0492fc813e2effa99cbbe2542b55..1d0470c1f9579d262f0e93c2fcebab6dd89ad399 100644 (file)
@@ -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);
 }
index 9c8468de1a7521aa62c179cd6bf952fa461a2a4c..287a66201150a0bd32432817a4357705b767329c 100644 (file)
@@ -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();
 
index aebecd8f51ccd7be2119164ff3bf3d58a9525b46..4ab93114567389122323e22a413280216c5729d1 100644 (file)
@@ -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);
index 602797a4420877f6fc74e659a05b4c50be8d54d6..bef4759f70e505e7e5e401751fa3e0e990b416b1 100644 (file)
@@ -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),
index f35d684edc250a662d76825714fa603ebf943ceb..640a54b09b5a2f094e8d66fdf5ab623cfd67b03f 100644 (file)
@@ -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
index 380bb28c7c54aad4a6d99eefa5931e47f1459786..ae405fa32236691a4bf10f5813317d6bd72e7513 100644 (file)
@@ -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;
 }
 
index 120929fbe7a37c652b0e6aa0d8189ffa1cc21990..64330c459bd47e44e78117bb28478ee1875629fb 100644 (file)
@@ -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;
 }
index 78810ba982e9efb17b6713c1a12d480ec4e77491..0cb7b9b520ea198e2ca487686788620ab5ca5006 100644 (file)
 
 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 (file)
index 0000000..68c74bb
--- /dev/null
@@ -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");
index b46022a11bef82a2576d0e684282780ba814e0d6..184cdacddeb6b7ff8acf0f8967cbdd2656e75e9a 100644 (file)
@@ -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;
 
index 50332ddd5ddb9d3a2efd3617760cfb9191ae0f8a..cdc3aab9ebcbc46676c76f6e5569f13eb214505a 100644 (file)
@@ -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 */
index fc2b5496b6d251a611bd3200baf733d8263e1f23..ff80937d94ddd307c6c2974f058980ee71273285 100644 (file)
@@ -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)
index f063d954236c02baf9e04f04f5bb7e0d4b651dbb..057548d072056dfe70e63667d21d483d402be317 100644 (file)
@@ -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.
index d8a0d87df734bb22f383b540b5291991ffef99fa..f3fe287fbd89ba6b5d65deb92b42ba1ca9f875e2 100644 (file)
@@ -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);
 
index 20b392948f366ac9a5767f2226eb5f2d44f7be52..697f566fb90ae02b87c44d47a62b3ac6dc8f0d48 100644 (file)
@@ -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;
 }
 
index f03196c5db37a49c2290b46f0be030de7108fb47..92edf76bd7adb1880b677558a56bc7d1528c47b2 100644 (file)
@@ -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]);
index 9b7589e8e93e52e13316aea9a501e21082100618..2af634d7acf4a86de888b7077e037c5e5a4a0fe7 100644 (file)
@@ -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;
 }
 
index eb0945284accec16b4c0ff0075c504da59f34a35..0719b6484824cd6075923ef0b322a417a1713f47 100644 (file)
@@ -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 */
@@ -794,24 +794,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
index 186737539cf5f4fe32fac373fe982724bd5ac7ec..2769e505f051530cb676cf60df41b59a34161ceb 100644 (file)
@@ -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"
index 149573db91c5a1dc35d727694de54263f0dc96f3..ab0c80f61b9d184152d6ed2005cfae5f360e7835 100644 (file)
  *
  */
 
-#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);
 }
index ea9aa4f53ab688dd3703d5f4ddc400eee047c0b7..f11546550d84efa01bfdf03f127d50e467dc2820 100644 (file)
@@ -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 */
index ca5167de707d645de7f3305bdfc61ef2434c678b..c68f328e1a29c9c8e7db039610831ae9a0a7900b 100644 (file)
@@ -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 */
index 061550a6fb9941669655e5eb68463b01c089ac5d..a1682aba71c7caa5aa4259825817a2498e3bcf07 100644 (file)
 #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 */
index 80b5ac7fe38341d547d0dd3f912af21dc7594c32..7d1d2845b42065a64c696b5fb19f8e0a3770275b 100644 (file)
@@ -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;
index 87532dd43374f9625d9f06693503a63c07a2758f..6c72f04b2b5db0399f5be66ecbe5653101819892 100644 (file)
@@ -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>
 #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:
 #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;
 
index 2d5b57be98c3b024d1f40c7cad7d6a841aee3db1..8a7b8fab62383670a600abfda49f6d718b971a5c 100644 (file)
 #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)
index e119fb87e5b594c82fae757242f8802bbac3ec20..50f2dd2c7e20afecc2dde1b95c78eeac070730da 100644 (file)
@@ -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 */
index 4feead4a35c5b7b404b2aacee5e2282f1dd4cd52..d90a3a1898c0d4276bd6a1c7c0688f62a184a46b 100644 (file)
@@ -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);
index 9ad4b2463077656ff166a752b6fd89e462b59163..bc6dbfadb8914a751764a2704c9db751f63987f0 100644 (file)
@@ -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.
index 156703986348cddade654814eaa4de4ce465bcdb..8f207508ed1dae62dc4ba417df8a5cb14089d62a 100644 (file)
@@ -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 */
index 936d776de00a883bdcd0301f7bde5742e64f1384..40492074c013c9d42af0eda8f4363506ab32e1da 100644 (file)
@@ -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 */
index f43739c5cab2ed11176c8493d4cf90de2e9a5f49..5fccf9f7a1d2e2a72eabffa78404156824156950 100644 (file)
@@ -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 */
index 0ecbf335c64f5591e476b0c327abd1e7efdaeb31..af4a78a8ef3b124f61e9a9b667cc8b9f5383ee7f 100644 (file)
@@ -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 */
-
index 5be70d31b007151492e306a3e621812d3ce07e7d..dd5500ed83221ef3c856310ba07c63a69be6b8df 100644 (file)
@@ -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 */
index a114b91d606db640ce5ffa46acc13abef2ebe6a2..0833fc9f50c4ad1914513620bbaae219889a1b42 100644 (file)
@@ -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) \
         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,
index 45ba784fe6da044b4114cfa40f1a26f96bb0fdc2..c1369c41469b5464cb66b4a3bad22ee2d996846b 100644 (file)
@@ -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 */
index 3165609ec1ec3019a03f19fa8e0ff7775466bc7d..9803aaa15be04431994e8a8a764fd887bd42456c 100644 (file)
@@ -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 */
index f26680ebef7cdcd5387627a98c79120d48dc77bb..08bd15d2a7b6cea63a675664ea333e9e0837b376 100644 (file)
@@ -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)
index 3efc60b33a88734f40baca223b3654e78fff94f0..1210a97e8685624f7a5ccf669e892111d619d462 100644 (file)
 #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);
index d541b508a159b8103c128a0cc4f3d76d9bdd6d6a..3e7974c5744326464e4f26eda25a4eef69e4468e 100644 (file)
 #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 = {
index 0b26616e16c3f715daeaf57333d41449647e2ffc..0e1e7d930783e7320a78a7f993fc10f756cadc6f 100644 (file)
 #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;
 
index 448df27733778d61d31781e475993c53555cf8f1..8fd0030475ba70db16de13164e5af5aa293c0ed2 100644 (file)
 #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);
index c93587be9cab411d5232d174046dca67b5e38821..c7731d1bcd89da69559e342be57f2fe6aa1fae3d 100644 (file)
@@ -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;
 
index 571ea68c0cf2fe446d0508768a6460d7ca5036b6..5ec4f5eb6b19834b56fe7a53827321470c24ae20 100644 (file)
 #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 */
index b08755e2e68f31115ff11920f598835001ea0bd3..6986ac188281745eda188c9b1c26110a9fe7f62f 100644 (file)
  *       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>
 #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;
 }
 
 /*
@@ -2077,11 +2088,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
        sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb),
                             "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
         */
@@ -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;
index b22ce1aa8fe4e5a716f2313920120c65c943e8eb..abbe48e646c3a7397d8a355de0e8f0757b426647 100644 (file)
@@ -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,
index c6e3f02bc6d74a731fd36ed3e6616e9d839c72bd..9bc65059cc6901eba8eb4f3cb09e46ca312f5da0 100644 (file)
 #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
index 1178bd434d1b1f12cd41f32bbbb0c5aaa3a50929..9ae4f3a67c704639bfee110773d22c58d536ea2c 100644 (file)
@@ -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);
 
index 2380994418a5f193db4cafc769fe2d2945ade8c5..024d511c4b58f3c64140d8d5d1a4b236cff6ddca 100644 (file)
@@ -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);
index 9f56bb846d93bab73b190ab09e4b3bc691d3e91d..809da3ef706bd72959a26bd2fed842fcbcb239f3 100644 (file)
@@ -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])); \
index a507d0b5be6c9c8bf31e2b4a3b22ed27a1e705c1..d9ff283f725e75dc900e436ebde42dee65e5fa53 100644 (file)
@@ -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;
index a504cf67f27274b2f8cd622884a09e519f7e410e..ce6038743c5c258bd7b06bbaf62d77a7d6ab4bbe 100644 (file)
@@ -241,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) {
@@ -368,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
@@ -690,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;
@@ -731,8 +730,6 @@ 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:
@@ -765,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).
@@ -777,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
@@ -807,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) ||
@@ -825,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)) {
@@ -1055,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:
@@ -1091,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 */
index 42eaed88c281b2a194641c6231abc80bafa45893..a5456108dbadcae24bbfd1b753cdf77eb07a694b 100644 (file)
@@ -1601,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)
index 58223b5d842a00059c9d6b0ee30a45417fd0961a..96232313b1b97fc277aeb4c67ebff59d205eb6aa 100644 (file)
@@ -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
index 1a6ff4982f302e124b67ad71b844131f0dabef93..a005b1df5f1a57ddc32be556f8c503d8f4f7a4fa 100644 (file)
@@ -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
index 07358fb51b82aacf8e7cb1b9fbe9f2cc943eb455..5a9653c3128a0d90308e632683f2a2c9a6e077ec 100644 (file)
@@ -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)
index 4bf48188cc9114cdce3a6a97de55351db1bf9ec3..6439f378f6cc9562f23ec5f8ee331f57bd898f45 100644 (file)
@@ -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 (file)
index 0000000..35656ca
--- /dev/null
@@ -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 (file)
index 0000000..cd8b729
--- /dev/null
@@ -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/input/fixp-arith.h b/drivers/input/fixp-arith.h
new file mode 100644 (file)
index 0000000..ed3d2da
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef _FIXP_ARITH_H
+#define _FIXP_ARITH_H
+
+/*
+ * Simplistic fixed-point arithmetics.
+ * Hmm, I'm probably duplicating some code :(
+ *
+ * Copyright (c) 2002 Johann Deneux
+ */
+
+/*
+ * 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 <deneux@ifrance.com>
+ */
+
+#include <linux/types.h>
+
+/* The type representing fixed-point values */
+typedef s16 fixp_t;
+
+#define FRAC_N 8
+#define FRAC_MASK ((1<<FRAC_N)-1)
+
+/* Not to be used directly. Use fixp_{cos,sin} */
+static const fixp_t cos_table[46] = {
+       0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
+       0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
+       0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
+       0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078,
+       0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035,
+       0x002C, 0x0023, 0x001A, 0x0011, 0x0008, 0x0000
+};
+
+
+/* a: 123 -> 123.0 */
+static inline fixp_t fixp_new(s16 a)
+{
+       return a<<FRAC_N;
+}
+
+/* a: 0xFFFF -> -1.0
+      0x8000 -> 1.0
+      0x0000 -> 0.0
+*/
+static inline fixp_t fixp_new16(s16 a)
+{
+       return ((s32)a)>>(16-FRAC_N);
+}
+
+static inline fixp_t fixp_cos(unsigned int degrees)
+{
+       int quadrant = (degrees / 90) & 3;
+       unsigned int i = degrees % 90;
+
+       if (quadrant == 1 || quadrant == 3)
+               i = 90 - i;
+
+       i >>= 1;
+
+       return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
+}
+
+static inline fixp_t fixp_sin(unsigned int degrees)
+{
+       return -fixp_cos(degrees + 90);
+}
+
+static inline fixp_t fixp_mult(fixp_t a, fixp_t b)
+{
+       return ((s32)(a*b))>>FRAC_N;
+}
+
+#endif
index 9cb4b9a54f01ffa38dd0f803785f190dae1f8adb..1c8c8a5bc4a91c0076c9af4539ef3a768102afed 100644 (file)
@@ -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);
 
index d67157513bf7dc286024e182400b545bf895d0c6..9f3529ad3fdab5b149cf7c835fc32e413e6c5109 100644 (file)
@@ -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)
index 50c90765aee15274eefc8b8fd05367af14e00462..8fb0c19cc60e27b459f084e59075aea46735ca02 100644 (file)
@@ -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,
index b4914e7231f863a3073da1c7e8e320e3e93c9c87..24c684bc63375917e44a06b3eae67947a501497d 100644 (file)
@@ -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.
  */
index 76cb1f88f4e83d4177b8cb8c281861aef50325df..8632d47a7fbe588eed1a10cfa7f14b59845cef58 100644 (file)
@@ -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;
        }
index e9924d6f01b33991b975de0272588f6f0691ea7e..947df273984399384fd0e8aece218ac388cadb43 100644 (file)
 #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
 #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;
index 83eac3a66bc801d11f11d6f1535f3894b9950f18..c62e00c79dec81a80135b6a9702dd65e3d0e987a 100644 (file)
@@ -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
index b265391f1f10a226e6054d3496cb296f3deeafc7..4c79e7bc9d06df25bfd98a71a1acd480ab98201e 100644 (file)
@@ -11,6 +11,7 @@ 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
index a86afd0a5ef13c95c869613c5fd4e67b7c414825..40244d4ce0f1696e6dc3179c7ab13e260884851a 100644 (file)
@@ -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/stowaway.c b/drivers/input/keyboard/stowaway.c
new file mode 100644 (file)
index 0000000..04c54c5
--- /dev/null
@@ -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);
index d723e9ad7c41a103ce092db1b45068b98b8acd9b..9516439b7c78837ed83ede2d6559c194b4aeb50e 100644 (file)
@@ -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);
index de0f46dd96922020abda38f24bf0975f59bb7e46..4639537336fc116c9eeb62dcbb5741027e342e7b 100644 (file)
@@ -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 = {
index 070d75330afd335de4dcf1691477aeb1bc8593e9..450b68a619fd4ab375db67d0b85567a1ef5455de 100644 (file)
@@ -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;
index e428f8d5d12ece57db9e20818d11088de71e1a12..69db7325a4944a79dc2aef6a925cdb329a262a24 100644 (file)
@@ -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 */
 };
 
index c14395ba798005d31a14b7c3c0e135548ed4c03d..5e9d25067513850920d4589c029f4056f4fd3625 100644 (file)
@@ -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)
index 54b696cfe1e33be4bf94b599ab8f5cc71e4562c7..7972eecbcfe4184863bdb84e0a3dda6eff31f854 100644 (file)
@@ -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;
index 343afa38f4c2d2b1c38ae809097ea343d44a670a..9fb7eb6b0f71f3bb9f5d7972e99627146a463fa7 100644 (file)
@@ -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;
index 0023501a5b634fd086837d3e1e9dc49f116414d4..680b323538847cbc53dfa7a99f9d5ae9b97d97ce 100644 (file)
@@ -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"};
 
index ad5d0a85e960157b335915e693a87872e4a9bf96..392108c436baca504abd345b4013ae90799e41e5 100644 (file)
@@ -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;
index 1f851acab30db2f692ab74886256701409432110..a22a74a2a3dcc6e781b79609360830b95208c026 100644 (file)
@@ -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");
index 51a519e24b6d07bd146206d47cd1293719dedb48..ee82464a2fa73c5bfd2b203fdfe68a8cd6ccfb61 100644 (file)
@@ -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)
index cc21914fbc72360967c117138fe75eab3db907fe..3b4e13b9ce1b9ac7317335c49f7b5bed8f854524 100644 (file)
@@ -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
 }
index f606e96bc2f4b5e4f5e04f22f0440c94c3453607..8738edda661001236e0db92c0607ec98fa0496b7 100644 (file)
@@ -159,6 +159,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
                },
        },
+       {
+               .ident = "Toshiba Equium A110",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+               },
+       },
        {
                .ident = "Alienware Sentia",
                .matches = {
@@ -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"),
+               },
+       },
        { }
 };
 
index 06a3f25657dd29062455027e076cbab0c99165b5..1bb0c76a9259b182c2153a86472965712b134c6d 100644 (file)
@@ -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);
        }
@@ -286,100 +275,6 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
        return retval;
 }
 
-/*
- * 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
@@ -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" : "");
 
@@ -493,6 +386,58 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_RETVAL(ret);
 }
 
+/*
+ * 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;
@@ -737,26 +699,13 @@ 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;
index af526ab9ec04205239f5d580aec7ce30323dc9e2..b3eb7a72d96114653799339dce4d9040391f4abd 100644 (file)
 
 #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.
  */
index ed202f2f251aa76eeb3b680186a7baa7ddefaa7a..dcb16b5cbec084716050232f88c16fc53942b19f 100644 (file)
@@ -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
@@ -138,6 +132,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
                        break;
 
                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);
index b1b14f8d4dd6ecf8b6b5e1675cc7c67c7d7b4e6c..9418bbe4707298bc1d605fca696c7e03790b8f5d 100644 (file)
@@ -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
index 5e5557c43121a128243412074d689c8340a5f2fd..1abb8f10d608809f5ecb57d4b0b1563cb3744bec 100644 (file)
@@ -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
index c86a2eb310fd93703f30246a7094d18a5529b64f..ab565335ee44131a69830fc9ac47b1213f58ce14 100644 (file)
@@ -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 eloelo, 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 eloelo, 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 eloelo, 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 eloelo = 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 eloelo = 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 (file)
index 0000000..f737010
--- /dev/null
@@ -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 (file)
index 0000000..1c89fa5
--- /dev/null
@@ -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 (file)
index 0000000..a7b4c75
--- /dev/null
@@ -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);
index 00e3929c62888a906852558cf7935cf9b6c36022..a730c461227f78608d8c461195f33b80f11210fb 100644 (file)
@@ -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)
index 669f76393b5a5128de344b0cc7b7b1cda40179e2..11844bbfe9339d3db64fc401347149edae459a69 100644 (file)
@@ -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,
index bd2e4267528e58aadbcb4f770f75b4cccbc72ba0..596f3aebe2f7748c553aa50c860866aa8e37b205 100644 (file)
@@ -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,
index 9ae3a7f3e7b3724982ce68bc75a37ae215766a6a..9ad840e95dbe8247928b6191fcedcac8fe2ab63b 100644 (file)
@@ -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");
 }
index b44950e06f3289772c431112834a6f5c7dddf5ff..fec1e381a6880791e7b1ba306c9acda4781d9790 100644 (file)
@@ -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,
index e10350360f2ff27c5158fbebe732fa0991bf44bd..e4823ab2b12702b6085a48cec68ac1ad077c9dbc 100644 (file)
@@ -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:
index 3a5ca8a68fc42fb512d64542aa707c819b5c997b..0ca5e66d2f5ab482fd78370ae29843cc4ce68d51 100644 (file)
@@ -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;
index f27c1608a3a706ba482d4163b0f67c2393e9dedd..b7e8e23be3371b7aa8f61d6dfd975cae26628379 100644 (file)
@@ -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 */
index b5e571a526943847f3bd1e0d0240d27c1041c989..6b88ecb5047dbf459de4de0a6f21f33cc640dd07 100644 (file)
@@ -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);
index 75920aa0a3c57711514ec795a3084f003c46a527..2f9d5118ceaf8b1d545264a3dbab8d24415aa6d8 100644 (file)
@@ -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);
index 1d7cf3bd6aa336bbf1884869de15436efedcf57d..881a4165cfb47d8855b7a03d5d7af821a1f02602 100644 (file)
@@ -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)
index 22fd5db18d48c613ab92245ec469408256a8120d..aca2a3954b1454dfd65a28036f0e06a3ff33879e 100644 (file)
@@ -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;
index 493dc94992e568cc9f96627ebd3dd20a86931fa5..98adec4405906cffca26bf479927a69d40a7d440 100644 (file)
@@ -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);
 }
index 9ab66e8960d5ddc1082f5d23c5c86642c8c528c5..2b91bb07fc7f2ab087b80d501f772deca3f426ca 100644 (file)
@@ -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,
index b4b24335f7165b0e5de378a637ca98ab7697d702..04b8a58f03b55441420a1c16082293a740521742 100644 (file)
@@ -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;
index 5b8c7c1a7663ffdc5418e8194a9a44430dd76279..57367325ef04513f9ef4fa30c81244c58cc41df6 100644 (file)
@@ -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);
index 8631d338d69ab550084ad4e3d0eaaebacd206b6c..ae6263125ac2ef04dbcf8c4ff04c9af340a80ab9 100644 (file)
@@ -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);
index aced19aac5a2e5011d81cb4f03ef6805836e5d62..f43282be0adafd0e1b474ccea84cccb24ba9bc7f 100644 (file)
@@ -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);
index 47f0ff196328d2808268a17701444b08faafee1a..454fb0901f8211dc31ec6b86e6edac5bec774286 100644 (file)
@@ -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);
index 090e40fc501335115e51c5c3138354b0dbccedd7..c0f9d82e46625593773f77733cfbe4fe3f979700 100644 (file)
@@ -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;
index dda03985dcf5b804cdf7c6724561012523660942..4f04fd0956a006a5bb9097cc558912b2df77f4df 100644 (file)
@@ -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]);
index 35b70323e7e3069e13382e4e44e18c944bd9881a..9f4eff1d1a0f672f0b3714b2ec2460ea177be3d1 100644 (file)
@@ -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);
index bff1f372f1885ebe5082048d48e580c8e008a8a8..31b750d61206acd13091d39a68218d0e251284e8 100644 (file)
@@ -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 */
index defe9922ebd1b0ba287312c294d9de2fbfa122d5..01b4c50143ddc77010b0ef72bc57f85f11861a5d 100644 (file)
@@ -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,
index bf869ed03eed33c9b61c7c4c46d78e621b0e1b0e..c92c1521546dfaa7c412f96ff9e021d5369b34ef 100644 (file)
@@ -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
index ecc56765d949ebc977ebbe5326b0dcc39197566e..8e67634e79a0d1f16d033e9e7ecdf3bcdd416f56 100644 (file)
@@ -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) /
index bdbd34993a80c055796804c1c0c8792ca99831bd..655d816760e591f0d007a6721fd557265004a791 100644 (file)
@@ -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.
  */
 #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)
index 2a374ccb30ddc0dcb165c7736c5d3abe6eab1fb0..2b2d45d7baaaaf55f9cfb45ff9b755587fc83d61 100644 (file)
@@ -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;
 }
index d12379b5cdb5137da258453bf6729cc1f44d49af..99cdffa7fbfe0a4522330099dd80ca810f3dc796 100644 (file)
@@ -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)
index 47b3c62bbdb8839086466a60439a0651758acd52..00234909b3db02b8b55e146b09fe27f57a20cdcc 100644 (file)
@@ -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)
index 93f701ea87bc3438bf5ab2426b74e5f43085827a..d754e0bc6e90c09f8ea73311e509e3d0a88f707d 100644 (file)
@@ -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)
index c54de989eb005e74738800557f37f1ce0459753f..659224cb7c533d6a7dba75e84cf03ab2ced13a0c 100644 (file)
@@ -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);
        }
 
index 1d0fafda0f761abb3630bd180f628dd7dfbbbc4d..5281e0094072b28fd5714ca8227d54c616422352 100644 (file)
@@ -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);
index fdec1e2dc87183926cac41e1d62fc961e9aab851..15fa2ae6cdc2971f590a814578d06536b75b8484 100644 (file)
@@ -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.
index 75fe9493e6af47059dbe79819b16683455304be8..05befa91807a332b87676bef2cc47de92417e1eb 100644 (file)
@@ -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);
index c99bf9f017599a1002a15f608ea356639239dedd..b5764a86c8b56f3f44b8ca2ebc38d30af8389a44 100644 (file)
@@ -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
 };
index 3c03c0ecab7e4b9e9e31b0c00ff0661ce668a53b..a48ec5e3c1f478ea9523424f87b0db21fc8ab06d 100644 (file)
 #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);
index b99c19c7eb2237e6f6583530c849bcfcaa2887c2..c625ddb8833d8b2de3f3d937b899e67b42cb48ae 100644 (file)
@@ -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;
 }
 
index 8dbab2ef38857f1f0cff938701869e3b067d7b44..38a0a5741d526cc4491a2c76dbdfe786ac58f0d5 100644 (file)
@@ -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 {
@@ -2519,6 +2527,36 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
 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)
 {
@@ -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");
index 1cc9de44ce86c2cce64c58fb72d8b3f33245a83f..171ff41b52b053e7acdc2f6c78e0ef34ed2bd695 100644 (file)
@@ -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;
 
index cb8c6317e4e5fc367c7098a87e310b5ed059f724..dfe32149ad3ae1b0caf77fc39003d82cb640f3f7 100644 (file)
@@ -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;
index 3b4d69c0562301b18039657ac0d47261a4eed6af..dc9d2def0270df7460a4eb0e20c4cf494ae94319 100644 (file)
@@ -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;
 
index 016ddb831c9b393dfb44c52076dbcbc4f4750b96..1250f0eab4afaf7b2c946a3c3767c25efc062bfc 100644 (file)
@@ -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....
index 450066007160ca04d1a8956abe870bc1b363210a..37e4ff661b6cce263148fe7f28d1a6be719b0244 100644 (file)
@@ -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);
index 1a04db4552da9dc2521867eaff7fd4c5666c7d89..f33e5d973413c2a1c064c66111c7f111383024dd 100644 (file)
@@ -4,7 +4,6 @@ config VIDEO_SAA7146
 
 config VIDEO_SAA7146_VV
        tristate
-       select VIDEO_V4L2
        select VIDEO_BUF
        select VIDEO_VIDEOBUF
        select VIDEO_SAA7146
index ca98d94789476f7c7454dc3a034f2b752e68b990..db753443587acf5a2cf7deddbeafebcb4974f18d 100644 (file)
@@ -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);
index 0027acc5b8e988b2a271ae79d1a90a96acbbd5d8..d867a6a9e43065335894bf93da8f00bc74a46c67 100644 (file)
@@ -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,
 };
index 49a06fc54c51add4cb30df21303b0419db633171..a0dcd59da76e5833502814abf62d66eda780ae79 100644 (file)
@@ -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.
index 3be87c72e37b7f6bf13053f3db75a0fd9a4229af..b8ba8786345783e107aa6e7a31babc4ff0cd6bd4 100644 (file)
@@ -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;
 }
index 7d0ee1ab2903c4bb06b5c16c7146f21f14f2ce9a..ae2ff5dc238d958d03f92fe9bf2a2c4d3926e93d 100644 (file)
@@ -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
index 06ac899a9a26931f3bc23b87cf9a1ae7a351a1a4..9f72b7000c080281e6149318a730b814348a9baf 100644 (file)
@@ -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);
 }
 
index fa923b9b346ea99440dceeac23e695c4c4b3a193..240ad084fa787ae4f5dc07b0acf47f25d2554b5c 100644 (file)
@@ -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);
index 0677b047b3a78be3381046c3ef0eb88e576cf5c3..3bf084f2e5226b883aeca002b39e75b54de04801 100644 (file)
@@ -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);
index b715b972d2fcfbfdbd495d5a1cc2ed558c60e632..fb6c4cc8477db818d04fb061f0893584b428690e 100644 (file)
@@ -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);
index 12ee912a5705176af05f73be9e61ffa2e140687d..e46eae3b9be2624690746413bbb2c74601e2af54 100644 (file)
@@ -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.
index 57b34cda99f5a6f598b9786d42af22d58a19f70d..3dd5dbafb330634c400e57d58b198eb21ef5c9a0 100644 (file)
@@ -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);
index 2887e2b862a4436d1002a5dcee6ffafb1b5aba1f..e5d5028b3694fc68663da122664e6172095c596f 100644 (file)
@@ -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);
index c972fe014c58283bdbca41f584cb76be583b0b61..9878183ba3f0d8cc751cfbd968b3c7c9aa5d5d3b 100644 (file)
@@ -26,7 +26,6 @@
 
 
 
-#define __KERNEL_SYSCALLS__
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 7a7f75fd168c30f19bf622a349322994914ca336..620e7887b3d3b11c155d65cbbddc12dfdd284555 100644 (file)
@@ -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_ */
index 75824b77198ab2a2524f5d123c719455a1fdadfb..0a3c35399bea7480ef9bdcc84bc510e43704ade2 100644 (file)
@@ -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.
 
index ce44aa6bbb838da936e9c41466819a9d226d64cf..df0c384bd4ca8a0d677afcd2507e04685d068648 100644 (file)
@@ -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,
index ae23bdde42a82505271051024dd2d0509ec994cb..c710c0176e0737e9174d3529b88e3e5db69d3dc8 100644 (file)
@@ -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;
index abd75b4a350dab46c2d054d176edb991668f44bf..124e25ac53b3ce625660ed6819a2d92833fe1ab8 100644 (file)
@@ -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);
 
index f4c45f386ebc693992cb7a165bb76896c1c60086..effd34cc4b02d23601086904734a3b0ce78db57c 100644 (file)
@@ -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,
index 55802fba3c29ee71bc320cf056b6fa1a0c665eb7..eca4082a61ae4920b0e49b045b4d55ab21f6e837 100644 (file)
@@ -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 },
        }
 };
 
index 2d99d05c7eab3c9f7dde14fa17db918d5e56233e..a43f87480cf608810a20c9c320a5f764770780e4 100644 (file)
@@ -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;
index c14d9efb48fdb7162a809ba16b3cd5b207acebc0..015854487308b7b7f9c452dd429eb002d1350a3f 100644 (file)
@@ -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;
index 70afcfd141ca02437eda63f7976eb8aaf85e9a05..27af4e43647936fe72a6db60704fcb5eaa804068 100644 (file)
@@ -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");
index ec631708c39480cf7d390267b452c109d2da2088..fe6208ada9037c916ffdb62c594bbe1a9f3b7dd6 100644 (file)
@@ -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;
 }
index 95698918bc116878da6ae4ac96f2b77661cf127d..57a10de1d3dd113c986fd858d7b07d7707e72713 100644 (file)
 #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
 #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
 #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
index e5c6d9835e06d24cac72b3ae3f342cab98b055da..380b2a45ee4c2accc59d0b8af0da13e6dc980dc5 100644 (file)
@@ -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);
index 412039d8dbae728a730fac25742701a7fe288ad2..79f0a02ce98719742b3ad83791145c0041e2228d 100644 (file)
@@ -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),
 
index 97d74da0dad88676457b01081a6d8eaa406d0371..418a0b707151c9071f9833d6e52f49027bd1e20f 100644 (file)
@@ -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;
 }
index db978555b1eb34d2c5819cf2b5380f6e52450c8d..080fa257a0bc25aca04bd84e77c044dfe3f9043f 100644 (file)
@@ -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
index 0e4880b6db14699c8204295884b3a9b0e0454cfc..dce9cf0c75c0880acc234ad7a58d5441b3b6286c 100644 (file)
@@ -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
index 80f5d0953d02635797ffdf9fc97ec242ebe01b1f..6dfa839a70224612c4fe72344c78fa080fca18e8 100644 (file)
@@ -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
index dcd8979c1a15e2668b5a5a8a8c276b59366edbb2..10286cc29fb40e8245ea76aae8086499d6c71858 100644 (file)
@@ -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
index 4106d46c957fa2e081c637790dace69827c791c1..335219ebce2d5a5568dc6d815ffe8aaf3ac185c6 100644 (file)
@@ -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;
 }
index 7f2f241e5d4485985cfe0c0c23ddafd489e8add5..bc217ddf02c09f427c70822b6a4dd74106fa75db 100644 (file)
@@ -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
index ce3c7398bac9ffa74168145b9b67d4eccf519c02..ae96395217a2e475c2c79a9b2b21ca62b2ac18bf 100644 (file)
@@ -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);
index b354a64e0e74970f728d4b5f905a24b5abb3ff75..c9d5ae250ebb46296e43ea20fc728dd5b24af86a 100644 (file)
@@ -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
index 274a87b7a5d5fe8e54acf887aaeaa155bd82def1..62d69a6ea699269e2a937c1a764fd28e1cc3976c 100644 (file)
@@ -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);
index 9606f825935c8341f53b760e9c91f06e4146e9a8..57a1dae1dc40a5bc1c61434f614401f638f84b69 100644 (file)
@@ -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 (file)
index 1a4f1f7..0000000
+++ /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 (file)
index be1c0d3..0000000
+++ /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
index ec927628d2734cac2eee5ef633e5eb55de4d680e..0caac3f0f279f3b1ed461f5d7658f3900fa18a12 100644 (file)
@@ -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
index 5302e11883a24738153dfd75f1f4c6ed3c53b354..adbabfdb04a95c0fe50f23251af39e2140139d2a 100644 (file)
 #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);
 
index 999b19047816dfc4402781557b9aea7a6f611de5..1a12747fdc914108bf6ee5f4d4bc26342b7c3392 100644 (file)
 #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 */
index 98673474a14021dd551ea887f9867e7b40ad4c79..cc28417fa33ac7fb6bc1eef2e496cd0ec682ec6e 100644 (file)
 /*
- * 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 (file)
index 0000000..fd0b2e7
--- /dev/null
@@ -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 (file)
index 2930aac..0000000
+++ /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 (file)
index 0000000..a18c8f4
--- /dev/null
@@ -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 (file)
index 0000000..bb0c65f
--- /dev/null
@@ -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
index 2be33f27c69fbfb7944140220eb34df815f15034..b7e7108ee5b3cadd0e82c562a1264575a9e9a093 100644 (file)
@@ -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);
 
index 66361cd188078c6361d84d255febce35d0685aa2..ed5ac5a361ae12da3c65a850f33bbe67f48f3f63 100644 (file)
@@ -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
index 58c34db31071e948d42049022150cc14a7e72fac..ef319369ec262e2fd9016e0fa9d4b1674b433424 100644 (file)
@@ -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);
 
index 675f80a19b9917ad694121856d4851daaa6878f6..1916e3eb2df39c30d07b5bc889e80e0c08cc7d70 100644 (file)
 #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
index 83b8bc21027404563875208b3e559d2037ef287a..21ba4a2307601067348e4a0d50d774927357c6cb 100644 (file)
@@ -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
index bad903c6f0f8261111a6b1d2b7dfe3bdbabb9325..3f96b485584c663ce68deac95b0e32970aa83689 100644 (file)
@@ -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 */
 
index e933edc8dd292499b78ef7746bde7202f94da2a0..2d2f58c26226527dd7ddadd5fd4e9ba634d388a4 100644 (file)
@@ -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);
 
index 047a4ab68c01be0a0cc0c6579eff5f0c3ec149ad..1fe1dd1793123985b813fda65b992c332e4162cb 100644 (file)
 
 #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 (file)
index 0000000..508ec1b
--- /dev/null
@@ -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 (file)
index 0000000..c58b03e
--- /dev/null
@@ -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 (file)
index 0000000..5eaccde
--- /dev/null
@@ -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
index 666a1bd1c244ff0752c9b79a64d5abb08c5f7d07..7112fb4d58acb3a59db6c8313b9b83f309b71750 100644 (file)
@@ -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
index 5de7376c94ce13e9501b1cda912c17a09be738e6..87e31ca7e1084e9d7916468eb9038e0dae6d71a5 100644 (file)
@@ -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);
index 9e7ff4b8fe5f30156dabb28c4f46408328fe1169..0035c2e2d7c275ee8eb937304535ce643f2e8454 100644 (file)
@@ -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
index 34d61735845be8199d3d75e3c89614250b8f57aa..2eb220e9806257e09352b3349509a520456cccf0 100644 (file)
@@ -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 */
 
index 117031d117082009c1fab69377059f29110f7a5a..9397393a6bd10ab63426d058af78b7eaa8cd1463 100644 (file)
@@ -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
index 89658883abf5eb65a241b9b8f14bd024f8a9738d..9718be4fb8358ba33e436a7ea8d2edc9da2606b5 100644 (file)
@@ -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
 
index 13a5a3afbf8b1e8fe8f184a3448ec82f370420f7..10a5419f9e0041c3e3cbc74a94ce66153579696c 100644 (file)
@@ -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
 
index 4e39015fa67e38c17bf519e8f6b143ff81a2fb3f..efc54d7f3c5569681c68af061e95771cbcefbf0b 100644 (file)
@@ -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
index 93afbb969d6b57f7b54cc104fe575fc5ce4641f4..4cf27d3b10f2ef8d520d717b0a24236e9a7201a5 100644 (file)
@@ -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
index c44b0ebdf1e220e32dd2c10a469e106ba1401c9f..cab7ea644dfa485b4da728554379383cfd44cf4c 100644 (file)
@@ -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
index 1da5384fb985454b06f6aa8b027dba583853338d..760b80db43a57080ea66a92caf5c1cefccadd6c2 100644 (file)
@@ -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
index 96648a75440dc9f7972bb27a1f113faec024d7b3..93483769eca842bfabfcbd83c029fd7b1c3f4599 100644 (file)
@@ -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);
index 1504828e423246faf41c4c5f09a9b864344af627..7ef25207081d2ee46b2b2f128ef3ea99c33b0fb1 100644 (file)
@@ -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
index 9cbd164aa281dead63829e13503bbef9fd39ebe8..dca89171be1fe232239cd5a143b8b4c855054fa6 100644 (file)
@@ -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,
index b1df4259bee9f4d7c16a0030d34f04e062517dcf..d68ae20c84129c92a6b17b6b37b58612cd420d17 100644 (file)
@@ -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
index 59a2ed614fca4046d4bd2474851f5f2552ac55c3..11e0dca9a2d7307de9e1a6648eedd4311844f9f1 100644 (file)
@@ -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);
index b877b23ed734e07398f2ac9d2ee5d2ef58508fc0..e28fca05734c30f9001549dce908e249442140fb 100644 (file)
@@ -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 (file)
index 0000000..7456b0b
--- /dev/null
@@ -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 (file)
index 0000000..e8061db
--- /dev/null
@@ -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
index e7a48f61ea2c6382e2e272f7f1b37f5e3c58d813..aae15bdce6ebafcc3d900c45117e473077344f50 100644 (file)
@@ -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 (file)
index 0000000..eeab26b
--- /dev/null
@@ -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 (file)
index 0000000..3307607
--- /dev/null
@@ -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 (file)
index 0000000..8855439
--- /dev/null
@@ -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 (file)
index 0000000..8f98033
--- /dev/null
@@ -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
index 520f09522fbbd0bc7604738ea61c366801aef75c..f0c9dded39d77fea63914ebb82a329ee1d976e87 100644 (file)
@@ -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
index ba88ae0855c994025b4a13c5e07ae65ab919bca7..395fed39b2865527aea538c434fa953c247a4e09 100644 (file)
@@ -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
index 2b95e8b6cd3973dd8613f3edbe47e97c5b4871f4..0e9b59af271edcb96a3ffdd89f5efe92897d8b62 100644 (file)
@@ -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);
index 9770cb840cfccbfc4ae96657201a69fbcb112455..79a947215c4d4d6a0d447dcbc39b85ba9caf6eee 100644 (file)
@@ -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 */
index 5fb097595cfbdab39188b56005cca785de0a6c70..95531a624991644337b3f98dde9c98d8114e6f96 100644 (file)
@@ -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
index 4506165c5de259ac9a9a2785866b3cf7048624c4..bba23bcd1b11d813326464f80fe72cfd1ff16896 100644 (file)
@@ -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,
index 0f3a044aeb17e82e4ee245ef1097ed41c0537b33..8c577cf30fb379359dc52841642bf2dd24d844ae 100644 (file)
@@ -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>
 
index 6079e8865d5b99d3f3ca4185e20b44014227df9f..dd9aee314e0a389b72f2347c347c5e45ad8df3ee 100644 (file)
@@ -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"
index 75736f2fe83864bb6bf48e7204a28c6a9930e806..37de2e88a273b9616a8af19129f7cf880682d766 100644 (file)
@@ -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>
 
index 6ffe53fdcf570bced668dd68cce10233eef437ab..10cfe3131e72aad0ecdeec292d926b5fcab126eb 100644 (file)
@@ -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],
index 2d21fec23b4d9ea4f04694ab1678bbff747a797d..2235ff8b8a1d06b35f9273fe7dd832d8591c6b3a 100644 (file)
@@ -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),
index ffbbb3e34be482cf3071e1dabbb7d76882404e0f..2a2e9b400613ed6674c8ee69c349ec64f484be79 100644 (file)
@@ -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,
index 57227441891e54bea5d0236417042e6f12ede756..fc1267b8c892f43627b9a8c2e1749fad25ad64fe 100644 (file)
@@ -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,
index 863dffb4ed8e5058b42fb31be828297945adc1f8..e58f0391e9d1ac0386a707bfaf9373dcab261dfa 100644 (file)
@@ -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,
index 46a6a60d2ab9b9751ff2b9262bbe045866b0baa5..e78ea9227b0ea0c39ee22a4f45ad0961f7577fa7 100644 (file)
@@ -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'.
index 04cef3023457c34ccc7584cec6e83002844ff143..234199875f53f77c094251969c1713eb91dcb34d 100644 (file)
@@ -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);
 
index c9d663549dff849cff3666ed72a1c4af2e790dbf..de077a757192de57915dda6aecb3297e123e6cf7 100644 (file)
@@ -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);
 }
 
index 220076b1b956df5d20434a5c5d8b2d9b9c1e7583..7015517e2c1b68aa78f84dede0289807accaace2 100644 (file)
@@ -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
index f7e33f9ee8e921fddbe569e0898fece377e5b97b..db865a0667e5ae8caed0fd9d8f75c879120ce2d0 100644 (file)
 
  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
 
 */
 
-
 #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>
 /*
  * 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;
index df22a582e7a2fae4762b07801313eec005bbc66d..3368a89bfadbe356d0b4a7ed46ee3389ea3a3bef 100644 (file)
@@ -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>
  *
 #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,
 };
 
index 95e6322133ee43289c1077af080cf50a57825db8..3ba5fa8cf7e611f1a8f616a63a63b734827e744c 100644 (file)
@@ -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:
  *
 #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,
 };
 
index 8641aec7baf87093e8faf1ea90331d913abe0ca9..69d4b7919c5aa8b8f3f73783d7fc06d9b14c16ac 100644 (file)
  *
  * 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,
 };
 
index 4c82956390c1de098a28c290baba01b698fd0c5c..cfab57d6bc4a7b9d8dfcf3a86c1252affa7167da 100644 (file)
@@ -34,6 +34,8 @@
  *
  *     TODO: multiple device support and portability were not tested
  *
+ *     Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
  ***************************************************************************
  */
 
 #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,
 };
 
index 162f37d8bf9623f52d9e46dc120089c53879b628..730fe16126cb9598610e5821d020ce2f8f78f485 100644 (file)
@@ -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                      */
 #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,
 };
 
index fcfa6c9fe2256df1b949014831ad0b3e000819e5..e8ce5f75cf1200630b20cf5981a192c0a39ba4e3 100644 (file)
@@ -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>
 #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);
index f93d7afe7304c97d1159967f20e5ee130c41f608..c2eeae7a10d02eb37e65f1b430ca3deb959edb38 100644 (file)
  *   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>
  */
 
 
 #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);
+
        }
 }
 
index 5b68ac4c7322e710c112bb787a996ef621f48e04..b9e98483e58d18e9a81c7cb56cd7c9250cd0a1e8 100644 (file)
@@ -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                      */
 #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,
 };
 
index efee6e339d15b0b7d7110160640e2c2ca35536e1..ecc854b4ba386d4c241e1195c810f64a7a5d3b49 100644 (file)
  *  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);
index 3483b2c7bc9d70488c26cb99b9a2f696192c03e2..4444dce864a932ddeaad7ec8790ca42354d5c9bd 100644 (file)
@@ -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                      */
 #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);
index dfba4ae596cd342abb3e737234274d4488ae4e23..f539491a0d76f31e7cdfa874a075c8e24e71a043 100644 (file)
@@ -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                      */
 #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,
 };
 
index 8da4badc22b47f399ae8c3ce3f9e80e60a3f127c..bb03ad5a2033bdb117671ef50d30ba6b72fa8692 100644 (file)
@@ -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>
 #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,
 };
 
index edd0122886693183f89245d799131869be0c0475..4a72b4d4e62a70b7c174e6cdac0252f96d84e33a 100644 (file)
@@ -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                        */
 #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,
 };
 
index 59b86a6b4b0e745a008276ede9a2a1d50e30e260..671fe1b1e5bcec6a028c71804699db75dfb976d4 100644 (file)
@@ -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                        */
 #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,
 };
 
index 94d078b77bab4a7373f5dc278e4921a2a2c10700..d1183c9392217666abaa9f638c071d153097058b 100644 (file)
@@ -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"
index e82e511f2a72782e343c6d19258d84f7aeeca6af..af57abce8a6ecc9ccdcefd0e9724775704581d1f 100644 (file)
@@ -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
-
index 05e42bbcfc3d5c26a5e034f20445f3f9803c914f..772fd52d551aaf35a5a43cb363831e1f51be9bc8 100644 (file)
@@ -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;
index cdcf556507141559be9f3284a9a8425c1069a9ce..58eae887a62992c4a542193a219a81c4f4061f8d 100644 (file)
@@ -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
index de14818d5cc462815ff503e206c4da1047391abe..d23a42b1504f907e16d7736a6771e99982a554ac 100644 (file)
@@ -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;
index 20dff7c316eb595e2c8e9385f90ba0ad22723de9..50dde82844ec6f431dcc2079339e97b0711204e5 100644 (file)
@@ -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)
index 0dfbcc85ebb9d901ba36c53d509da2f794157673..70de6c96e201c9dba69a010d1b40d9d8294bc64a 100644 (file)
@@ -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,
index b69ee1194815cf84155b109d0d8f801de4e3ff58..d82a488f12a6a5214ff15bdea70a6b4fdde51102 100644 (file)
@@ -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:
index c5ecb2be5f9313d692f0c9826e6202f2b64c357b..8d2dfc128821ab57703689fbb7ed1671e04bd432 100644 (file)
 /***
  * Image defines
  ***/
-#ifndef true
-#define true 1
-#define false 0
-#endif
 
 /*  Misc constants */
 #define ALLOW_CORRUPT 0                /* Causes collater to discard checksum */
index 65f00fc08fa961d5671ccfe5a3cf92aa38efb4ab..657e0b9691459c532803fec0b8a2d9cfc1a76494 100644 (file)
@@ -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",
index 854264e42ec03e4b02af9809f000ce241b7ee4ef..7cf29a03ed63a9d3da53f9d3823627e86e23b47c 100644 (file)
@@ -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.
index 6cc8bf215e851c548beedecd46d254d626dc052f..48014a254e15fdcf10b31c2ac255d5543083643d 100644 (file)
@@ -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;
index 7a94e6a11927bdf877b7f8440fc5b499adff002c..51d68f32aa068f9e7fa2c39d21ac31c56b7ae463 100644 (file)
@@ -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.
index 352b919f30c4a41a4ab896f3d1f686d393211879..639c3b659d0ecf098c4805d70ced3038fc5bc270 100644 (file)
@@ -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)
index b60177f173c3c1162726ca3da7eaa105781c8043..a7921f9d45d844d77e1a5019fe1d2f477863cfa7 100644 (file)
@@ -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)
index 14bd4863d157514d526bc61735743cebe214a8e2..6214eb823b29afffc94b0da20d628846ed72c41c 100644 (file)
@@ -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);
index 973d3f39b2d540133c5398abd4e028956dee212b..f379ede3049a5cfce78002b62f83346b9e72e52c 100644 (file)
@@ -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);
index afde3789d702e2f295cc66a4d953b2c028c9ddce..c87041dee21e7d677b835fdc6683da01e1a110ef 100644 (file)
 #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)
index 7bea34714861b6e3090f9319bcccfc5d4558c5d1..27b5dbb2ca1a12d5ddb33a6249987f6f4947ea7a 100644 (file)
@@ -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,
index c255646489933f19170ec466badc8d1c896693cf..83ebf7a3c054a9bfa44d384175bdba3d72acae48 100644 (file)
@@ -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)
index 5785c3481579d1dda8b77d4cfb8af9300ed14b82..741e7c5e69ec7085d2d68cb53f05dddef74ad9e1 100644 (file)
@@ -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 */
index 94c92bacc342be219f78035e855c78d43ce1a763..fbc79e9842aa70299c2d4b98147805eaffdc2996 100644 (file)
@@ -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)
index e7810955dd4f845c803e954de86644eab40f4d73..89f12e273b7f83a5ac7f47e241028e321f9dd839 100644 (file)
@@ -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                                              */
index dfb15bfb83dcad2f03b47a521a10d26174ccdd22..9285a58e47aae9a166723809b1df65c57f1525a4 100644 (file)
@@ -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.
 
index 2a461dde480c89c0dcf339920861764a709c89f9..20df657b70c8f1c63bbef43fbdb2c1ee3c4855e6 100644 (file)
@@ -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);
 
index 3bf7ac4f52882ff40193c7d9811d4c0e38cf0d3e..c1a377f797d9b21679bf6c23d4fe23bb51c2ac6e 100644 (file)
@@ -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)
index 7e727fe14b322876914ee9445dd495db04a73d70..a52171ef6134ca6bf77c1c82f3f972e65209e9e5 100644 (file)
@@ -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.
index 02e414210dac4ab61be1baa43558c5fc32610bd8..69b3e43cd0ebb8175cd3b5f465186947a7092955 100644 (file)
@@ -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
index fb6198f1df98629dbb04d14eeb643838300c8041..c77de859cc8e109989b6ebc0ec55d45c496747f8 100644 (file)
@@ -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);
index c80c26be6e4d31dd048964525184d676cc96bf0d..df8feac16aee78a7ba4a744bf0d12ecf580adfd7 100644 (file)
@@ -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);
 }
 
index 18a7073501c6037fd845dfdf414d70cee51aefbc..c94f97b7939246ff0dd61e6ad417f438861a621d 100644 (file)
@@ -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;
        }
 
index 0d6dc33ca32046db2e34cd6aef0f7502af2af968..34b08fbcc6eaf8ca0beb49417408a8c17f66cfad 100644 (file)
@@ -33,7 +33,6 @@
 
 */
 
-#include <linux/config.h>
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #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
index be1e5cc780812b1820ef21e94fea7e9058787888..88604365777c32c936bec578935ce3337ceb2dd5 100644 (file)
@@ -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) {
index fbe6039aeb6a8a5c588c3c7f1a81b389c54f5ae0..ed3e8105292a23b807c5267e1216ab851d524821 100644 (file)
 #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;
index 8a9933dec9123213ed092a04991f9e8b76b3e387..05ea17afe9037817567c710b4c06e3dae94ddc6b 100644 (file)
@@ -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);
 }
index 7fca47982277a2ea68a013030a53cf0f584b3dcc..3b9012f8e380671a8595b9bf9847bcc6f2c58242 100644 (file)
@@ -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));
index 8f1a5afdd34e25104466a6dff2b76a952f8c22f4..e976c484c058db621d52a6e90d0ac738c590382b 100644 (file)
@@ -20,7 +20,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
index d1dda5caf4063dd4b14063e25496c4c86ab8a4a2..c294f46db9b9f421c0a7648ec3cdc9e567098fe1 100644 (file)
@@ -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;
index 0caf70b8c0de94ca873e760a56c8224085f5ed74..3608c2f81df912fa91a6bc33a7db57691d452cd9 100644 (file)
@@ -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:
index 59a187272c831007de3dba1745759abeb0c04653..77bb940a1a4f4159c3a6ceafd41cd839188e5367 100644 (file)
@@ -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,
index 19a8d65699f84892be0149e1cacedb48e18a0fdb..bb3fb4387f6500ff04dbadf0e003336798c41dd2 100644 (file)
@@ -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,
 };
 
index b59c1171727351a52beb6b77286fb977f5c27903..974179d4d3895b2dd3135b245d1e5158c4a8e213 100644 (file)
@@ -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 (file)
index 0000000..4e5f2eb
--- /dev/null
@@ -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
index f5543166d1930fce988fc0c32f39abe5e57b4d08..59da79ce2efda40cf7b45758dd8928a7eb82915d 100644 (file)
@@ -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.
index be7b9ee697d6ceb1aa41358f7887b35e32e5c2cb..89a1565b4256e11398ef54152314ab95ca18f57a 100644 (file)
@@ -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)
index d73cff1970ae22391ae77a6e1f1289f23119403f..a39e0136ce3ba4614b422d05e8febc1fd319c736 100644 (file)
@@ -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;
 
index 927413aded10c120cedbfbddcf57970d48dceca4..aa1db509f3d477ec895a42c33a90b21ebe976787 100644 (file)
@@ -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,
@@ -3421,6 +3495,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x16be,
                .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,
@@ -3445,6 +3531,36 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x5168,
                .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,
@@ -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
                 */
index be3a81fc90a2498769cb95ca2b4f306c4d71cfc8..09aa62f61af7bab0ce172f4452750fa4dc4b7944 100644 (file)
@@ -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);
index 279828b8f299bf45598b92af8d6e4b3f2b9d775d..b6881541e704ab0192834af210a33d2594009d2e 100644 (file)
 #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;
index 7c595492c56b1719cc3059e03030f60573366723..f7ea857d5d73e540eda9913bab293de9450b5d7a 100644 (file)
@@ -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;
index 0db53d192b2a2b1d40f975b63256066982ba1e3e..d31220d204958f16ad7d4cdb9eea829b0369706f 100644 (file)
@@ -1046,6 +1046,7 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
 }
 
 EXPORT_SYMBOL(saa_dsp_writel);
+EXPORT_SYMBOL(saa7134_tvaudio_setmute);
 
 /* ----------------------------------------------------------- */
 /*
index c04ce6152fd5373a0e2ea1410621b17ba923f8b8..7db7b970595388865d3374918b2c3d7ae0a17a34 100644 (file)
@@ -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
index 8dab481d384aa58b292de4dd26fd6155c8fda1ac..87ffb0e84a7a063cd34589d8705e00d1a9b1b28b 100644 (file)
@@ -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;
 }
 
index abe37cf632c6845eabab734962e631e78dda5342..63db4e97ae6ce57a6003d55b0b0c6a187cc46e6e 100644 (file)
@@ -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];
index 8b542599ed471c0f84c9e4247d627178d87a4fd9..8fff642fad56fa8e2579c2741d96818ea6850d94 100644 (file)
@@ -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,
        },
 };
 
index 936e3f746fba59ca3f4f0cbf892408022ac80a23..fcaef4bf82896da5e5c20d463fca436835cc75b1 100644 (file)
@@ -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);
index d95529e8e51376dbadeea8e89f94ab770769cf6d..cd1502ac956056f5e0e461b3b7fcdeac076d25f4 100644 (file)
@@ -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;
index b167ffab25202106da0bc956b8304430a48634e8..bc0a4fc27b24452a828e971d906e1918aeff2a27 100644 (file)
@@ -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);
 };
index 6f31ecc88843d16c7de882a8ee7e9dd28f538375..4eee8be88314104524eafcafce16a263e5400b9b 100644 (file)
@@ -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)
index 90d48e8510ba308fae6402e866b22bf14b95dbd2..08f9559a6bfa475e414f7f3b94a52039b32da74d 100644 (file)
@@ -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 */
 };
 
index d7c3fcbc80f7b5585d2a9463ece0f31695b566ee..1d899e2db394e62eff8f3398b005e1d37e78be3c 100644 (file)
@@ -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;
index 8d972ffdaf98782b3070713900faa245d308eec5..78d28b03ec93df4e2b4eb0096aebd8589adf7fab 100644 (file)
@@ -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;
 
index 7ee8a53cd336f1702a35b2532071b1955d9af3f2..f53edf1923b7de3fa558c2adf4c42980f97ad608 100644 (file)
@@ -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);
 }
 
index edd7b83c3464b4a2367c6391b30fcee2f9abcbe7..479a0675cf60bf8ddfc7b6a372077be03063b35a 100644 (file)
@@ -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;
        }
index 268e69fdefc6f3194fdcdc3cc2902fffbd642c3b..d1e04f7c530bbf9ee66f1e80072fb0263b1b5dab 100644 (file)
@@ -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,
 };
index 841884af0cc03b56a992aa1084740dfa1937c3b6..e7c01d560b6460f1dd6de8ab19a87ed651556782 100644 (file)
@@ -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;
index 1eca7e65d235e570fcb36ce5dcf7312b759c56ea..8ef31ed7d3f1133edfe514ba0b34445d3aaed3a6 100644 (file)
@@ -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");
index 29f59c36f0014425ac85efbce2579316ebfff161..9f21d0ba0f0f721df3d44cad9d8b8566288964cd 100644 (file)
@@ -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
index 5f90db27892b9386a5b7c56f3a81e2bf6d7954ce..862a984c2155c6d8a739f54f4007f90b1a20f13b 100644 (file)
@@ -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;
index 50437383ed6297476380cc1f4ed49014a2778c9a..9240638a01342bca3ad81d7b463dc906b30764cd 100644 (file)
@@ -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 */
index fef677103880b5e94a80c84bf52dcb692fbc4340..6443392bffff17402d59b2ff39f3700a7229e7fe 100644 (file)
@@ -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
index 1ddc2fb429d5668a2f653c2c3e5d7561e5a4a92d..eaba81bf2ecad7a023d6e1ae22563ed9900bfcab 100644 (file)
@@ -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;
 };
index 1b58444d5aafa4d2bea4e96a18c9229357a5269d..dec41cc8993786f111ee216af84849c1fbc728b0 100644 (file)
@@ -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;
index 19c2b85249c3029556e532117394f65d611ce0f8..c1bf1fb04c5c5cf2007c93f8a3239de35a29659a 100644 (file)
@@ -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 (file)
index 0000000..e689ee9
--- /dev/null
@@ -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");
index 45bcf098e762c500e3777facb3a85c8f841ab385..f540bd88dc5a23aa12216079cf7ad675b2eff092 100644 (file)
@@ -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.
index d2957e35cc6f2d40c6a9031c98a2a88aad3ba0ef..b1f6e03e7aa9cd216a6a12ccc9518956f0cb2fbb 100644 (file)
@@ -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
index 74f8cdeeff0f8501f379d01037144ecd404c6ff4..4ccdd82b680f8f22ed78e27a89a7d9c418df859a 100644 (file)
@@ -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;
 }
index fdfc3838dd796ee1d37ed9d50039e4cc05ccf331..4dab5ec392eabf450e23d351a0b39c36f63afb68 100644 (file)
@@ -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>
index f2453343f783bd3b7dc75ce3e8946c7c277a9eec..72a67937afe0edc83fe8289116c1e61304367b3f 100644 (file)
@@ -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.
  */
 
 /*
index 6435a6822ad34106abc05a0d47996b4af1170e1d..88c6f0b129f5eea6c6ca4f99ac4932a594b46894 100644 (file)
@@ -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!
index 249baa701cb0be7f5930e6282c944f499365119a..6072993f01e3f9debc30c0933856fea23a55190e 100644 (file)
@@ -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
index a03e862851db65bdd9783685b55e2cf4ec37ce2c..a304b34c2632f32c1713a9d337c02a4e27453bdd 100644 (file)
@@ -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
index 16c02b5ccf7ec30c994a7fb5a938e4fcb2d8278b..440f6851da6997ac296be09773ada5d54a00bb4c 100644 (file)
@@ -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:
index 642d96bc89198488ec3e136f515f7f6058c98fbf..2cc9024362759f2a4bbb0963c53090b19892ea94 100644 (file)
@@ -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;
index a64b1a5ab3161d57c47f639433280c8f0f51bdb7..d76d5981b8639f965aa15d189874163f28449c29 100644 (file)
@@ -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;
index d6bef100d69a2b2f3be47aa71f537bd4c8ed44ee..df2c38ef105ad476769c0d30004f6a3ea61e9549 100644 (file)
@@ -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;
index 198e840ff6db9060230b0675f79d698c26bac273..f9e8e5bcbc3354d659520e7e68c4b219c15dfa35 100644 (file)
@@ -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:
index 2257d2b500c00dd092907951c2a55a36132c2edf..4d858b3d5f826f368872d5317ecc4e9388c91a7c 100644 (file)
@@ -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);
index 458d3c8ae1eee3904fa34cbd414d44e6a28633b3..178b53b56be91380cbbf3e1f2d46c01bd60470c1 100644 (file)
@@ -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;
        }
 }
index 12017f3c6bd68ea026f794d85badd1cbf99aa348..1daf8231aaefc079885be293a7f598e88bb87401 100644 (file)
@@ -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);
index 975b2ef611215061de098d5027cd72b63cb47463..baece61169f4933af73704779143ddbaf21c08f7 100644 (file)
@@ -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)
index a612c4ea8194d86750c39d0aac18784cbfe20606..9402653eb09b4982ac7d924beda88cb203442741 100644 (file)
@@ -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);
 }
 
 /**
index dd5cea8b4a7a2dc31b1429ce6a7ebe07c143ec7b..b5a5f8da4722e78ecd8d00efc50cca97724c34f3 100644 (file)
@@ -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
index 5930a03736d7557ab9bdfc9137bb604a863560d1..465961b8bcd14319e02be8c0adf8d8db41862288 100644 (file)
@@ -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
index 84ec40d254386f366a3d4e2f92ad54cda2663eb9..8ed68b28afe37651d85500889676f7a48a93e9b0 100644 (file)
@@ -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 */
@@ -1563,13 +1637,44 @@ 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);
 }
index 9953201c670dcaab69b88a8bad8a3b5e19b8a729..a67f5efc983f29be5ec116bf09bd6113277f3534 100644 (file)
@@ -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
index e9361cb5f4cd44297ab0ed0fbe99f050333d9360..d0842527b3694782ebdcbde85e21e5ad95f55193 100644 (file)
@@ -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"
index dc5e38aefca6adc706ae9feb27ea2d9d87162d93..26073c3452130b01aaaa3ce83d20b10f2919c382 100644 (file)
@@ -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
 
 *******************************************************************************/
 
 #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 (file)
index 5f297e5..0000000
+++ /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.
index 5dea2b7dea4d6b9118f4ad9426ea7093058779e7..4a6ab1522451ca77dbd83b2186125cee0c86a803 100644 (file)
@@ -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>
index 98afa9c2057e7a163f961b32cc346dfff0dbbbe1..7ecce438d2586ba483f16ef19dc2837ba3590487 100644 (file)
@@ -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_ */
index e39aa1fc4d1e2592fcbcc69bbe8ee12dbb7d01a1..778ede3c02163a1c4655c092e52196bb903316e3 100644 (file)
@@ -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>
 
 #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);
 }
index 10b8c8c25325acd63eef44ac369c4ee94e4fa891..65077f39da69970e7e51b6854febb8998f8f527e 100644 (file)
@@ -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>
 
 #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 */
@@ -721,6 +709,123 @@ e1000_reset_hw(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
+/******************************************************************************
+ *
+ * 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.
  *
@@ -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;
@@ -5639,99 +5751,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
  *
@@ -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)
 {
index 4020acb5500580d6e4a356f788ddbcdb40243b11..112447fd8bf2d558f66a6de96559e2b9cac15db3 100644 (file)
@@ -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
index 3f6a752700a101a93ee18fef71518492a1e233ed..7dca38fba6a1809605340915aa7c9d65abeaa206 100644 (file)
@@ -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)
index 46bc49df15e78e896a532666aa3aa6604c6a84d2..a464cb290621537737074c8393d5eea38d1e9a23 100644 (file)
@@ -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>
index 2128427389724c4bca3c4ca6181bca2d86a9b41e..9c3c1acefccc3c92eefcc19667bf445eeb11a889 100644 (file)
@@ -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 }}
                };
index 34412bc7c4b638a1c5458c3edb220780adeb053c..d01870619a4aefc7ca9d278b58250da77fa3f809 100644 (file)
@@ -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)
index 03b3df33d81b1c6c325613a881d9aad1d0d486ce..ae8ad4f763bff9fa1e5634c7422d6aef1fd87ae3 100644 (file)
@@ -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)
index 6469130c1413f532633e0a87df31c821a1ae36c2..c26a4b8e552a52274832b551a45c2d47ca357da7 100644 (file)
@@ -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;
 }
index a8a2d3d03567fc9f082a64533df578e1c077d09c..838a5084fa00c93f1f46e3ec890e9ef2cc6fba07 100644 (file)
@@ -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
index a51604b3651f0063ed3c9362803d688305b1e855..50ffe90488ff4584c033618cb86e2e14859867fc 100644 (file)
@@ -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)))
index 8357c5590bfb8a4887250958cbb422c1241798dc..f15aebde7b9026bea724f90785e08847889c84f0 100644 (file)
@@ -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
 
 *******************************************************************************/
index bf6fa220f38e64eabe3c0ae0ce0dce14f54d45d3..ef236b935c15559edb5cd9c69889fd73bef9eb70 100644 (file)
@@ -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
 
 *******************************************************************************/
index 64a383e4e892a83eb5bc6091bcbb02030b4afd16..cd22523fb03521535b2fd71c074e9984599d9278 100644 (file)
@@ -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
 
 *******************************************************************************/
index acc6df7a6b38c55c0f168079902d4f290332700d..02089b64e42c55f6672cd178790c7ba6a9bb63f2 100644 (file)
@@ -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
 
 *******************************************************************************/
index cb4568915ada7a363b3e6d435bc809f15f176aae..40ef5ca88717d4f4d3f9bfa0e5606f3003d06803 100644 (file)
@@ -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
 
 *******************************************************************************/
index 9fd61189b4b29c73ad71343802fbbce0a4adbecc..4376e7e8fbef275c4b2efe407fcfce9feaf08d17 100644 (file)
@@ -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
 
 *******************************************************************************/
index 2e0f4b950a902cf9df22d2fcc8acac47b91c6f11..cfde7c2569bb80314d979191fa7afad39f143122 100644 (file)
@@ -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);
 
index 19cb1d586dec6d67659b57a4e5517d9ee210a05a..8434d752fd81873b726e47207544a8dd9647235b 100644 (file)
@@ -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
 
 *******************************************************************************/
index 39fbed29a3dfd9fc7018db044fa204546b3cb751..b27442a121f2fba05b388d0691c118c4170a0b78 100644 (file)
@@ -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
 
 *******************************************************************************/
index 19f7ee63276fb56a6ad4f64e0adf3200bf049a59..94b47c8d0ab402c681bb73057adb71952ede69c1 100644 (file)
@@ -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:
index ecd3da151e2d2a17eca4dabf378a3cef41a341df..3bbd5e70c209100cdf274408200c5ab1b957f9b9 100644 (file)
@@ -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) {
index 7eeefa2d6c89c8fd1691add25fbbbfde5ea7c2cd..396e7df3c61b8573017d829fe298b7f7b1ba1f9d 100644 (file)
 #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);
index 4c13c371bc217518be652ef9e868ecedf0d72525..f66109a96d95b0b2f13dfeba2c02f13241507a8d 100644 (file)
@@ -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;
index cc240adb72690304c58b129abcf1fbef0af4b128..1397fc55cf688c345899ea19a4f12271d0662287 100644 (file)
@@ -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);
index de8da6dee1b0598d6d22e8bd106356d39184d0a7..151a2e10e4f3dc980720dcbd277dd240ea84174a 100644 (file)
@@ -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,
index ba737c6cebec643a6316a058a0ebc2e0f1ac7d72..39d09345027cbbc0680d95e7c863d09b7ed02b32 100644 (file)
@@ -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
index 6c5add701a6fc9508bdcc34d2b44587c17e882b4..599e2fe76188534cedd9973f7ebfd0fb1fb03e6a 100644 (file)
@@ -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);
index bf00fa2537bbb6f8774611eb55481751bede4965..8dac2ba82bb95ee748d6b69d5f56e02f4b30e329 100644 (file)
@@ -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) {
index fad5a33bf0fa3ecac80bc57358cbd2327c2dbd68..4a9f025a6b58026ba208d4a3a695b9d7b9ffa608 100644 (file)
@@ -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();
        }
index 08cd86a6dd6696585dc5937d1b056a55e898d6a0..23b599d6a9d540db8b2727533f74ffcd7e72f06d 100644 (file)
@@ -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");
        }
 }
index 3f6d51d11374063b0f3e0c86de1d75e23c1f3b34..2d7effe7990d9c67136a44617e31bed2290a7026 100644 (file)
@@ -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;
 
index 420e10aec0ae451c52961cceb9c2e3ca4f5de306..01be47e72730b5fa847ac9e8245fa2e9d9cda23d 100644 (file)
@@ -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)
index c5d7476da4712fca78e185be6a6dff74a7b948c2..933cd864a5c95c296844493b65d868b7cf7548aa 100644 (file)
@@ -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;
 }
 
 
index f2e0179962e2f85f6aae48db8bacc42c6ac9f700..3ac5b123215a09f17551531d106324e1e8ac9554 100644 (file)
@@ -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);
index 551f58e298106060b5708cb288d04c8c7da39043..81a6c83d89a644bb9400aef1ee2470f0a536784d 100644 (file)
@@ -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
index 62c804af9fbe473a5f20816d8f5fbaad3a1ff785..fc766a7a611ee0a88327561f93f2996431c9bdb4 100644 (file)
@@ -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
index e72d467ab2143b771711c688933efda888306629..3ba5ff6e68004700162f2e05c75fe02e438ff0b9 100644 (file)
@@ -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
index 1cb61a761cb284cc6dd590e6ebd8062f6271d246..7a0d8ee2de9c9aa95f973b86dec3d5955d348798 100644 (file)
@@ -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");
index dfd0ce86f6a0d82e445752653e667899959d22cd..c0714da44920287fc1be7ad76d2cacccc0bd927c 100644 (file)
@@ -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);
index 61a58259c93fe04ed5a502435763a921f3d57cc5..583789c66cdb9d2404157f0cda029c9e8dfc7c60 100644 (file)
@@ -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>");
index e8afb9384786a605a0881d153474f4ca0554c2ac..cc5032b6f42ac45c9aba4f0ff896b17585a6c813 100644 (file)
@@ -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,
 };
index 209001495474f9f88b74cbee8bb410fd7b868523..9647188fee2c66c4c172bce9923b919a2a17eef5 100644 (file)
@@ -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)
index 9be81fd4737c20c11cbcc4c2e466a41331c01434..9c68ec99afa5776ad23d039efd693b02ef2d4890 100644 (file)
@@ -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,
index 8e47e5a06d2a48c336cd4cd44e6b4e86a16670fe..6273a3d240a2afd2f4a57179d38219f6259797a1 100644 (file)
@@ -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)
index e1a1169e46649f4be8c8917f5a1a9b6cc7230615..ef4f147f3c0c30b0a16b46908f545f3ac6001eb1 100644 (file)
@@ -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,
index f324d0a635d4743c9268e4f914fcd51a8069af17..1c743641b73b294c0e365b4ca27a93ff14015bbd 100644 (file)
@@ -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,
index 9812120f3a7c825c783a7c15635279740ced383d..ba795a4db1e97289829c3c69dbee613fa2720a25 100644 (file)
@@ -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;
index 8c0d1a6739adb23012a1c92bf9a102898b9a94cf..8ff4a1221f59a4a1aaa549451b659cab8f7d4c6a 100644 (file)
@@ -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,
index 2c9739562b5c284a740d2e004ab776abeaf0039a..9eeef964663ac84597f7d1ab1d754e1df302063c 100644 (file)
@@ -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,
 };
index ba9a583b7b6817ff073b4c70a5a93910fdc89fe0..a760cf69af90de24bb80782fbdbf3a393d08777c 100644 (file)
@@ -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,
 };
index b235a30cb6610b67c12f82447ecdb534d5b91e51..5875ebb8c79d9c3070c025860a8a5b1cf428fbec 100644 (file)
@@ -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,
 };
index d6d1c5726b0ee87347e9532a1da267c6cb1c79e3..739d1a6e14eb9054d717bda6eef4f8266d3213fd 100644 (file)
@@ -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,
index cef5f5a3bbf9298233e25a2da7ba9dcc464133b2..d51d8f20e634e020428b834febb6852731303310 100644 (file)
@@ -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>");
index 25589061f9310d6555d729205b09490982c19132..f50f3fc353cd64be4845c8dcc90bfd6eeb7cc877 100644 (file)
@@ -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,
 };
index 7553d797603fd86d78a266d578765e439ea5aced..bbdad099471d43b65d33ec05161f1f88e01b0dac 100644 (file)
@@ -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,
index 2c7de79c83b9baa352769e7626bc06b27c8abb60..625dad2eeb4f4fa2b8f787ce805bf44c67eccf56 100644 (file)
@@ -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,
index ee4b61ee67b03de09faa6296137dd0c3f925d495..439c41aea31c9d091bcfe66f326d2ba3afdd2679 100644 (file)
@@ -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,
index 7c1f3d2e53c4d3eeff9354dcbf168aacd874380f..625637b84d33424be18af05530db5293b11fd3ea 100644 (file)
@@ -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>");
index e1fa5fe7901f900167b448997cb4f4373a85e892..bc4bd24508a2d4beb23458c3b6ee3a86b7e41e26 100644 (file)
@@ -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,
index a40f400acff6b814401228ba550f54e92aeddfda..09b714f1cdc39f9dedb4cad38b5b036677a0d9dd 100644 (file)
@@ -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;
index 596764fd29f5a320cfeb89a4fb0823cac3972720..58e5ed0aa12702fc9798f03eb915f262d7f92a8c 100644 (file)
@@ -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,
index 788b6d1f8f2fd282cac69e6b8a5c0e9a3698c9f2..522c69753bbfb3843b6dccf1c4f922b43e45a666 100644 (file)
@@ -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,
index 929d6fff6152a642b929d8854e515d3f8152bc1d..b250c53545033cba2a019ee4e5973bf1bac04551 100644 (file)
@@ -1,4 +1,4 @@
-if S390
+if S390 && BLOCK
 
 comment "S/390 block device drivers"
        depends on S390
index 9d051e5687ea433cb6852f1748f5ed216ff22b6c..222a8a71a5e8b439dd11df7e31ee389270a1dab9 100644 (file)
@@ -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;
index b7a7fac3f7c3a05ae3448e5d172db199578a4dc6..5ecea3e4fdefd3a5bdaa8ef0cebc0711dc91028f 100644 (file)
@@ -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 */
index e85015be109bb918366a62c83fec616512a6bb30..80926c5482281293644f52e06888060e804a9f2a 100644 (file)
@@ -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 */
index 2fa566fa6da4e287488fda979f2d3b72fe552f38..d7de175d53f08b0794170e08170edf5d2ea406d5 100644 (file)
@@ -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,
index b4557fa30858038103825a70ae43402062dce96d..78f8bda81daee67e38fc651c6988b66b940890a8 100644 (file)
@@ -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);
index f6cf9023039e352bed29b71ca0da273ecd8b6d24..6f43e04dbefdce1e57eee86bfd94960a7488d89d 100644 (file)
@@ -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,
index 54fba6f171883fda8384ab794adb77f761759991..723bf4191bfe2adb009c55d59797dfd98891f882 100644 (file)
@@ -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,
index 06e2eeec8473dca2e3ff3c79ae5fab78014eac0c..4717c3611601f308094f588238a5b6c8c039cbd9 100644 (file)
@@ -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,
index 479364d0332a062c2424fbf16728464fb3c29b7a..e088b5e287111b7268e322ad62dc838663d4815c 100644 (file)
@@ -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
 
index 7cafa34e4c7f5b17a0aa1e8cfe19b4c97057af2e..4d2bc7981324b4fc5abe939fbcca0f26895e0c91 100644 (file)
@@ -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;
index 4fdb2c932210a80772d74c69636061734af334cf..a305d4091547f9180a367a26bc67d410d1e926cc 100644 (file)
@@ -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,
index 1cc706e111193c9fb7f066416e7f8edd9f3b4a7b..d27e4f6d7045a3a5f21e38d6bab32455d83c3d8a 100644 (file)
@@ -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");
 }
 
index 063e676a3ac046e5de17809cce433ca281b21dd5..728a133d0fc5b7c306443280e63d296e047cc5dc 100644 (file)
@@ -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 */
        }
index 657a3ab75399426b23f7028a925b37d2860fdd97..15ce40a7053a6dfae5ccfcc20fc69b507483106b 100644 (file)
@@ -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];
 
index 9792e5af5252c4a6378490667fe64f5318c64dac..d6d1d5613c8aa9e6a207204cdd0127112a548761 100644 (file)
@@ -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.
index c4dfcc91dddaa07ea474037fd60f9245ae962d98..dab082002e6fe572f10e9e46f4cafecba2f3dbc7 100644 (file)
@@ -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
index c7eeaced324afe4954a1fa79b06716dce5bf5d70..1faa008b5b817047d16c0f976523ba746105ab9a 100644 (file)
@@ -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);
index 64c8b88a429fa1d11228138babe693518db30edb..339b85cb61cdbefb4a5bb9af77da7caf9f03b4ed 100644 (file)
@@ -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);
index 5dcef48d414faeaf9ce636c093e924a719d9eea0..10353379a0741e5f4f4f784ad230c4cba6249192 100644 (file)
@@ -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)
        {
index 43afd476e606adad053fb3a1ff8d94dccb5b1cb8..0f3eb22b979a1b8345dcf75e6d3bd83c09580c6e 100644 (file)
@@ -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)
index 94d1de55607f2dc00a05605259b0d8e864937062..1427a41e844104149a7e71c4a3e639f01711718b 100644 (file)
@@ -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;
index 7f9e89bcac7eacc4feae3b9a9bc6df846244a1c6..e46e79355b776ec98a407962694a8e3756414571 100644 (file)
@@ -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;
index ae4106458991890086cb81be16bbd91dbddfeabd..1b53afb1cb5768c4946e889987cd58ab1691be39 100644 (file)
@@ -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);
index 0bd9c60e6455b879b831c4b7a64854422213ee8c..aa60a5f1fbc3b5b639cf0123900b0ba862a36518 100644 (file)
@@ -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), 
index 8953991462d78f3d9600ea6445ed08820e133ec4..332151e2a0189eb57a529eb4461afc218811a492 100644 (file)
@@ -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");
index 7a054f9d1ee38230a7b59344e3e791d217f46d79..da95bce907dd3a23257637510bb12e3613bc6a6c 100644 (file)
@@ -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");
index d6743b959a72b151f1d6ade6d70b6d3b70c44d92..71084728eb42322462af7a6f0980d627af54e725 100644 (file)
@@ -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);
index 638cff41d436777fa85afc31dfd6213f227b2637..10bc99c911faf55744dc226f04b4fe84fc210800 100644 (file)
@@ -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;
index 2f8073b73bf30d1d5924498ec899c8984c0549ff..7f9bcef6adfa941cfa07cc3301a57b62177cd7ca 100644 (file)
@@ -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;
index 837173415d4c8442ae7bb036be84452b7c1d615e..44a99aeb818046355a17a4fbb9b94b34506878f7 100644 (file)
@@ -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;
index 008a82ab8521e9142bc4845e0f03298a7645ca75..f5742b84b27aa28bf4b6ed0e16f23a4c20cc1745 100644 (file)
@@ -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;
index 993a702422ec6e2e22175ea67e6c9bacb55ab093..bac853c5abb565dfeb11cc32ed910191f956a9c9 100644 (file)
@@ -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,
index e80e70e9b12620487236f4ec56b3cb416104fc53..1b299e8c57cdf7071b5d155aa556d4ef05d51b29 100644 (file)
@@ -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,
index 0ede0ee64243fa24271b13224aa445fc4b7c8152..cc2a205d42300af96e6f0ecfda63172c5e151425 100644 (file)
@@ -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);
 
index 32af3650e8b44bace902d939d58f4e57403c1e2b..ef8cc8a70c6092e018a7e34b98a7c66426140bec 100644 (file)
@@ -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);
 }
 
index 913c71cc056939b0295a78c1a6f3a644fb9aa2b3..1ebe6b585d2d57d3c44b4d52bcceebb3b5fdfd78 100644 (file)
@@ -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;
        }
         
index 90ff96e3339bce5c8817f833e66d5d9580661a50..a0d6136deb9b0d47a8af0e970dd0b891876e7a5b 100644 (file)
@@ -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);
 
index ef3bb476c4326ab5c46b98cc43530a48c3312b93..b691d3e14754fa94a40ff0eac22889b2e2afda33 100644 (file)
@@ -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
 
index 4793fecf8ecef8667c1d89c03d69b83681b91861..a663300d3476b4222d441e8d648ef63b6f86b017 100644 (file)
@@ -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
index cabd048c8636060138b497b294bd9b4f6e9e1382..9851d9eff022a6e655db1011fa1f93cbd8cd03b4 100644 (file)
@@ -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,
index 576ca1eaa2b68119acedf4fc4ea33ee2a3209a3f..5ec4716c99bf30e5bd16bb271e45aa1f38207343 100644 (file)
@@ -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:
 
index 5ff269fb604c051212449d18a1270e2da174c855..dbf13c03a1bbceac17df1de52d1608f8812ceac0 100644 (file)
@@ -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);
 }
 
index 832abd3c4706ddabe8a3a6c07d9caf0e2b8e139f..00d7859c167ec7c246c885cc918e2932cd1df69e 100644 (file)
@@ -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,
index 7708e5dd3656967882ae990d1984e33b361301b3..dbad0e31e005864cb02c72b9f293ecbc11e906d5 100644 (file)
@@ -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
index 63d2a66e563bac3823fbb699b11ecabce44cdbb3..704243c9f78a44c2d58f560d1cd4301aaafeb138 100644 (file)
@@ -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;
        }
 
index 4a1c9983f38f8e38a78e47f761b996da129c6969..aa819d3f8ee51344d58b2939c39f396d4698a058 100644 (file)
@@ -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);
index 397147a7054f39fa0d4cb11dfd4d7e31f2954df3..c67b05e9a45144c3410c23ed0050f4f70ec26c9a 100644 (file)
@@ -2117,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,
index d3a5aeee73a34b33bb4736b751a2aacab8ec5e8a..9b3b9aaa6b909efd4a7bc61e111a01cd8b6a373b 100644 (file)
@@ -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;
index 5e8a27620f6f339045981b5994b4138c69be073a..622881f26761263dafef90ed1dec8c611950a696 100644 (file)
@@ -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,
index ca90326f2f5c6983ad6a6cd44f6980251ea11ca9..71288295df2f7f5113c30a25fc1d054c019319aa 100644 (file)
@@ -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,
index a94c63bef632c5151e985073f2cf6457f30a0ad4..3f509beb88e4771906f4badd0237e8ff45b59b24 100644 (file)
@@ -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);
index 37f9f5e7425d1b5e1a518302fa36cad686989c25..e658089f7b504d9a6ba90d42bdff3abc57b150f3 100644 (file)
@@ -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
index df3d152f0493dbb5dfcd3e76195f370791a78876..b5d6a79af0be3473b94e23dd73c6340e7db650ee 100644 (file)
@@ -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);
                }
        }
 }
index f69df137ec0ec91aac813342ee3a3e0e564a6fae..13322e33f9127652afd6179a5fda7d09d8dcd03e 100644 (file)
@@ -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;
index 366dc0a9e52c291e8057970eca7b3de8644e53ce..1c17d26d03b807d24db3d05da49b2b3431ba5a9b 100644 (file)
@@ -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
index c83d3b6c68f2121dd574ff92fd3c30a4b9670791..8b975d15538ddff6fb93e2757e7d1888be538881 100644 (file)
@@ -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
index b68cecd57411b1c13b1bd5cb44037299ff75ab64..83601d4009e36dd66a82e026b2c9c482877f612a 100644 (file)
@@ -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) {
index 4655522a08d95b10dfa227e267d3d144d3b9b694..86924f9cdd7e0c5e57845e4f4a41d63a188414b2 100644 (file)
@@ -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);
 }
 
 /*----------------------------------------------------------------------*/
index 0a64504c2545467409a2ebcae606c2e151f9a95f..8c18df86983330a8e29118546a680d208a90d74d 100644 (file)
@@ -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;
index b893e3118e1be480e9b4d8bbd739152efd718141..208e55a667ac0d2124ece6bb49c17dbe1cf59d27 100644 (file)
@@ -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));
index b7018ee487ea51fbe60ed42455410a4cb40feeaf..0f809dd684921662a0aa41a4dc99d54f90f3e2f7 100644 (file)
@@ -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;
index a102a58fe3612c89589817dadcdd9b6c566d5cf4..21cd22640080fbce6d032354409f59dc61de32a3 100644 (file)
@@ -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
index 48551be324ac61fb102a530fcd34ad0205fbed57..295f459d1079ffa4c3afe69bb38d61474f503162 100644 (file)
@@ -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/fixp-arith.h b/drivers/usb/input/fixp-arith.h
deleted file mode 100644 (file)
index ed3d2da..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef _FIXP_ARITH_H
-#define _FIXP_ARITH_H
-
-/*
- * Simplistic fixed-point arithmetics.
- * Hmm, I'm probably duplicating some code :(
- *
- * Copyright (c) 2002 Johann Deneux
- */
-
-/*
- * 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 <deneux@ifrance.com>
- */
-
-#include <linux/types.h>
-
-/* The type representing fixed-point values */
-typedef s16 fixp_t;
-
-#define FRAC_N 8
-#define FRAC_MASK ((1<<FRAC_N)-1)
-
-/* Not to be used directly. Use fixp_{cos,sin} */
-static const fixp_t cos_table[46] = {
-       0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
-       0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
-       0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
-       0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078,
-       0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035,
-       0x002C, 0x0023, 0x001A, 0x0011, 0x0008, 0x0000
-};
-
-
-/* a: 123 -> 123.0 */
-static inline fixp_t fixp_new(s16 a)
-{
-       return a<<FRAC_N;
-}
-
-/* a: 0xFFFF -> -1.0
-      0x8000 -> 1.0
-      0x0000 -> 0.0
-*/
-static inline fixp_t fixp_new16(s16 a)
-{
-       return ((s32)a)>>(16-FRAC_N);
-}
-
-static inline fixp_t fixp_cos(unsigned int degrees)
-{
-       int quadrant = (degrees / 90) & 3;
-       unsigned int i = degrees % 90;
-
-       if (quadrant == 1 || quadrant == 3)
-               i = 90 - i;
-
-       i >>= 1;
-
-       return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
-}
-
-static inline fixp_t fixp_sin(unsigned int degrees)
-{
-       return -fixp_cos(degrees + 90);
-}
-
-static inline fixp_t fixp_mult(fixp_t a, fixp_t b)
-{
-       return ((s32)(a*b))>>FRAC_N;
-}
-
-#endif
index 81b1ea01a172e40e32790a64d6602f653b0e9171..e0fd11605b430939fc10dbfc52111f9de3745d92 100644 (file)
@@ -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)
 {
index d5c91ee67991cf9e4331ad451cca18ca8e67a2c4..a8fc46c721c50cf0a1a8485d50da96c800b3f5fe 100644 (file)
@@ -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);
 }
index 7208839f2dbf24d50c15516b7d99971980f8160d..4c62afbeb430a31620ff3681d6ac303b613af187 100644 (file)
@@ -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;
index f07d44357ff12fbb01eb18271d0832acbbabe672..93da222b6da8ffce8ab4d11762ab562e2d4fc2d1 100644 (file)
@@ -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>
  */
 
 /*
  */
 
 #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 (file)
index 0000000..5420c13
--- /dev/null
@@ -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;
+}
index 534425c69c0a502b1a7f86be0811446147c0afd7..2d5be4c318ac2a566e99e89865391a2140a7b2eb 100644 (file)
  */
 
 #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 (file)
index 0000000..d2ce321
--- /dev/null
@@ -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;
+}
index 778e575de35230831bebbfaa983a555f3754b40b..b03fd9b075df7cf836112f06531d199ef140c40b 100644 (file)
@@ -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 (file)
index d9d9f65..0000000
+++ /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 (file)
index a2cb962..0000000
+++ /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
index 0222d92842b8ba79e89404d58ebcd06c729e8a2a..8006e51c34bb108e28d40b5956f8d29f47a146ef 100644 (file)
@@ -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,
index 86e48c42d6af3cf955c2cb4320bb33eeda29f77e..422a4b288e346f589687aada8950d294dfbf469a 100644 (file)
@@ -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.
 
index 702eb933cf88bc9414ccbcb85e74de2dcfc18b08..a1c8923b0bf5ae95b52fe3e28b8c261e6db5609c 100644 (file)
@@ -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
index 481c6c9695f821da3bd133017bc4a9c3823046be..a6980e9a2481beb4e15bf06baa87f143b6068726 100644 (file)
@@ -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
index 55fb8b04489b77ea3caf04ad01a1983b6054fa76..b04f49fb976ac3fe72d1f6d9bb955afccda1b012 100644 (file)
@@ -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);
+
index 19a71f045784008c3a278be54f1f42f19cfda6c9..b45c9fd1b3307af0c712edd78fe32011f9e3d485 100644 (file)
@@ -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)
index e7056934c6a831c06620fd6ea1a45d1b689c3ead..5080816be653de4802a523d364ef720d394d0808 100644 (file)
@@ -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);
index 9aaca58c074ac6c4926d55608ae98bae7aab0c9f..676754520099ca8e1ad53f52940b0ba0895c23b2 100644 (file)
@@ -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;
index 365de5dcc888edf9c37766276f091ae689da648e..9a2b0d69b0ae7ebdb8bc0dac91a686e986c27f11 100644 (file)
@@ -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 }
 };
 
index f25d5d648333cb6665529154aeaec90184da02b5..ef5c16f7f5a64852b1505fbab982f8f63f6b899e 100644 (file)
@@ -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);
-               }
+                       }
                }
        }
 
index 1b4f75d1f8a949bb3321733d0aa5e61fe7bdf04f..8c041daa3a15b264b5825141a5382f92a526fa4c 100644 (file)
@@ -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)
index f244ad066d688852af1826a8f3b0aabc550c0b6a..b9386d168c0499a260a99b9b9c3d76fec8828d27 100644 (file)
@@ -80,6 +80,8 @@ struct fbcon_ops {
        char  *cursor_data;
        u8    *fontbuffer;
        u8    *fontdata;
+       u8    *cursor_src;
+       u32    cursor_size;
        u32    fd_size;
 };
     /*
index 4481c80b8b2a12b533b206cda6e19775ea6bbe1b..825e6d6972a72cbecb51a1194fcdaf16f0cf0a7e 100644 (file)
@@ -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;
index 7f92c06afea7a7b749e9ce8e7dba20b691f8ac43..c637e6318803796e6b735b2f860227543cd0107d 100644 (file)
@@ -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);
index ab91005e64dc67d07688dc24a175b2fa68d45f83..1473506df5d0654cba5d2bf6e5281ccc6b186870 100644 (file)
@@ -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;
index 557c563e4aed2033a9ce33ea850a85b87ff35d04..7d07d838356904e0b14462a9f50911abaaa92257 100644 (file)
 
 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 (file)
index 0000000..3aa6ebf
--- /dev/null
@@ -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");
index 17961e3ecaa07ed1b9572868e5af8055f1b91760..93ffcdd95f5026fd467116553b5c1335f872d89d 100644 (file)
@@ -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,
index c151dcf68786a1c5ca1987f209e83351db5159d7..d3a50417ed9a6ab09d16841e435597bf8f6da312 100644 (file)
@@ -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
index 7d06b38e80a00f7e4f5d7ead2062a46da7e5730d..b38d805db3134673723716083703efa571c84c4a 100644 (file)
@@ -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);
 
index d42edaccb84c732bab17286ef9b5fc90687ca419..b55a12d95eb22ebe641add5c6c9e9602803b2793 100644 (file)
@@ -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;
 }
index 722d21d6e5cd3a7d00f60bafebb9c04ae9a18852..6c782d3ae1bede62c0bc8a7c93526c144d102600 100644 (file)
@@ -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
index e290d7460e1bee1840487b5cc84194e9fa1db51e..80b94c19a9fac5ea30f373654fb8a78b0d83740b 100644 (file)
@@ -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"
 /* 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 (file)
index 0000000..c1113d6
--- /dev/null
@@ -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;
+               }
+       }
+}
index 06af89d44a0ddc90e06ab7db005de0843d96014a..6f9de04193d216d62f62511f7bbb0cd821d3c0df 100644 (file)
 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;
 
@@ -1187,6 +1210,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
  *                       fbdev interface                       *
  ***************************************************************/
 
+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)
 {
@@ -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;
 }
index 2a9322f9cfdc3f220c35afac745f648b8f8c764f..f887f1efd3fef1676201321665651c147668fda7 100644 (file)
@@ -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;
+}
index 10acda098b71e5c5685c739d105f2c12d90598c4..8c54ba8fbdda2e0bd240f00e87d289d17430cbb9 100644 (file)
 #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)
 
 #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
 
 /* 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 */
index 4a57dabb77d4a1cf028d47b5f84f8643fb00f663..7acf01c181eeb6d622efa8d2f1615240089e4272 100644 (file)
@@ -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);
index 6849ab75d4034f12e5b70a69cf896a61b9b224a3..a32d1af79e07c4b349e2e88e65d8d9d4cf6bf4ab 100644 (file)
@@ -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)
index 19eef3a090232854860ad993365993dc7e5f68f6..e48de3c9fd13ff0ee1f35df67a85281a719e26fd 100644 (file)
@@ -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 */
index f8cd4c519aebf1125ba9e6a347be3cdc67f80418..eb24107bcc81f539a4a7e92b87fb5efb0523f9d1 100644 (file)
@@ -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;
 }
index 4acde4f7dbf8925a159fce3a9594be4bd4727e4a..b120896c8ab455eb0e99d9454199a9847567e20f 100644 (file)
@@ -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();
 }
 
index 9751c37c0bfd57de13b4c182090c2adcc0422dd7..c15b259af64401f770b83cdcda69db5a30bab20a 100644 (file)
@@ -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)
index d7d810dbf0bdb6b1db553b35529eb99a651a2a25..3f94223b7f0ca86c4b76a01553c6b89240c388e9 100644 (file)
@@ -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 */
index 7ecab87cef027cece07ad55c987bd96a280f4a39..59d12844b4dd9f2cffcabeb0b3ac126b08ff3b6c 100644 (file)
 #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};
index bc321dc57e92ebc1ceb4b70eadd1c2934c72fcf8..4f3a28699d3753ca7c48be541861ee6c1ca3950d 100644 (file)
 #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] = {
   {
index 09f5d758b6c02b79d3aab802698664c949f9de0d..c3884a29f4c5a15fd41679cb34363abfaf04b05c 100644 (file)
 #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,
index f59568020eb220d7a720a10c73c87b3b5dadb66e..d048bd39961b173312be5fc0aac46d24c92185df 100644 (file)
 #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
index 3b7ce032e2ed6af47599e9336c01d37bdc864e8c..7addf91d2feab2068b65b627b52994ef3d42c3ac 100644 (file)
 #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 */
-
-
index 046e2c4a8e09cac082a317bf548826fe85b70b3e..30e03cdf6b85a18ba1ff43685995ee3edab9748d 100644 (file)
        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
index 895ebda7d9e3547443785aa6e465589acd2457cf..baaf495a0a6dff7513fd1c054ec8551d59d09910 100644 (file)
@@ -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>
 #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;
 
@@ -6770,16 +6619,13 @@ SISINITSTATIC int __init sisfb_init(void)
                return -ENODEV;
 
        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,
index 70b6df371b8e7f72231c91c9bbc32efb9c1fdb28..88e4f1e414706cb444568c6adc390f4f5131cdd5 100644 (file)
@@ -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);
index 831b9f42264bb8590d1cebf3c978ac8b4114a5f0..05d08b7889a1aca636b516b032341cbade9582a6 100644 (file)
@@ -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)
index dad54e73147b4d68420fb5c189889c94213f34bd..711cb11d6eb34e6223d2eb67463de2073492d909 100644 (file)
  *     (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)");
-
index 7a7ec2d1d2f4a8f60bb79c2f82bc0f110f9509b9..5241c600ce28be2f00f0eb454b41db882beab1a8 100644 (file)
@@ -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
index 4fd9efac29abad9fc5d1f3f75f862f8283f6a59c..1453d2d164f7c2d5a94e5da75d41dbba9d94a66e 100644 (file)
@@ -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"
 
@@ -939,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
@@ -967,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
@@ -989,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
@@ -1002,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
@@ -1015,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
@@ -1042,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
@@ -1064,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
@@ -1079,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
@@ -1264,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
@@ -1283,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
@@ -1300,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
@@ -1316,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).
@@ -1343,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
@@ -1381,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
@@ -1959,11 +1974,13 @@ config GENERIC_ACL
 
 endmenu
 
+if BLOCK
 menu "Partition Types"
 
 source "fs/partitions/Kconfig"
 
 endmenu
+endif
 
 source "fs/nls/Kconfig"
 
index 46b8cfe497b2206e66fd986617e5b554116174a9..819b2a93bebe55cb4cc137514872892f90fa83da 100644 (file)
@@ -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
index 1014b9f2117b2bd2e6bc00086f8bcc9d84475d0e..6101ea679cb1bf7772ba5da5342d7fb6def023ee 100644 (file)
 
 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,
 };
 
index 3de8590e4f6a56a35d13e09be2e8a3012df2fb54..05b5e22de759e10513301ac7b441bc4127c3b492 100644 (file)
@@ -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,
index 2fc99877cb0d1b55c74329a40cd23f2eaae91e13..cf8a2cb2850563d9c9d19741dd2c3b12d367b01a 100644 (file)
@@ -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;
 
index 67d6634101fdcc81e75787c87d8084f5c13256c9..2e8c42639eaa54803887b441758d6e176b4cb58b 100644 (file)
@@ -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,
index 950630187acc72a781de4cc6ef936045be5bd0be..94766599db00d3ca530eb37da388e1e63b900d35 100644 (file)
--- 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;
index 9cac08d6a873111086c8ab75529976589e12dfce..368a1c33a3c824effc61b722bdcebc0f35e62f3d 100644 (file)
@@ -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();
 
index 563ef9d7da9ffa858ad754217861f4e2292b30ea..c1493524da4d614da928caec7abbfc845c417c0c 100644 (file)
@@ -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;
index 80599ae339669d3a3a962d64d974f62fb30a58d6..34e6d7b220c322b9399c32a701fe4910c256946f 100644 (file)
@@ -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,
index dcf04cb132831c116cac8fe0de090a7106527a47..a650f1d0b85ea815860ef528d0177ceefa51655e 100644 (file)
@@ -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;
index 3d5aca28a0a0980922c83c0b197d1cf52cb27593..a9164a87f8deebfee1ceefd1f722bb0baac75491 100644 (file)
 
 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,
 };
index 6eb48e1446ecb4fd7c239f2cdca17e7faef89c28..06435f3665f472f7a1e7ff4879627bff3064c740 100644 (file)
@@ -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
@@ -1152,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;
 }
 
@@ -1204,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))) \
@@ -1427,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;
@@ -1570,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 */
@@ -1595,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
@@ -1603,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 */
@@ -1612,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;
@@ -1632,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,
@@ -1659,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);
 
index 6a0b9ad8f8c9d031d4c32fb32e1c53e0677d1ef2..8f93e939f21375abe2c205fd2783c319098cc87f 100644 (file)
--- 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);
index 4346468139e80247e6db85d389a072cedf0d52a0..bc8f27cc448314b2eaf99cc93628671d51d5adc1 100644 (file)
 #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;
@@ -1152,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);
@@ -1187,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,
@@ -1313,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);
index 3b6d701073e7f09a311f10297a58d8c06e715df5..16cfbcd254f15fa05eb452eb512297c439605035 100644 (file)
@@ -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
@@ -259,118 +234,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,
@@ -1550,35 +1413,6 @@ static void discard_buffer(struct buffer_head * bh)
        unlock_buffer(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
  *
@@ -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
index 1f3285affa39c9d06da9fb3af7bee91094d894f9..a885f46ca001f117a9b8bc3bd4ac0e140b5c9e3e 100644 (file)
@@ -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
index 22bcf4d7e7aed4e700bb75e846df73a8480316d4..c00c654f2e11c0ce9cdbb3d597bb1afe9e673ddb 100644 (file)
@@ -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,
index 0e9ba0b9d71eb008138eab55841bffe5d73be196..c78762051da4e5b15da45fa06b46b66d85e55d82 100644 (file)
@@ -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 */
index ddb012a68023fe0818d50670f2fb81a990dbab56..976a691c5a680561a97b1aede8840e292b23ce73 100644 (file)
@@ -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>
index b88147c1dc27f0df435b6251376a73b7dfc531cb..6b90ef98e4cfe9cdfcd224bdb0a2df202b66612f 100644 (file)
@@ -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);
index b0ea6687ab55e8116a4790a52682e24c71146c34..e34c7db00f6feccaba099b9604352e7745322a03 100644 (file)
@@ -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;
index d1705ab8136e1fc53768240d6dbca66bfcb56132..22b4c35dcfe3e4bfbc067b56880f5fb958df50ae 100644 (file)
@@ -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;
index 8651ea6a23b727c1c27b24b0d9a3b9d03c062fa0..0102b28a15fb5f8230eea9904d04f481d3e4068c 100644 (file)
@@ -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();
 
index ce982f6e8c80270be3fd23f8f9553c486626986e..4d3fbcb2ddb1a32353dcf6001c9a4f53e42e94d4 100644 (file)
@@ -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);
index 4063a939697768d990faa971a4488efe21f80dcb..27ca1aa305625fbc19b0122b7875d75f06125c53 100644 (file)
 #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>
 #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>
 #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>
 #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)
index 816e8ef645605a5cdd505b7bdd6be8e8bf38345a..8a3b6a1a6ad139aa50ba1da2e10bdf6cd0de2980 100644 (file)
@@ -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;
index 85105e50f7db668702b36ea78a32feaa6ef12593..e6d5754a715ecde980dd50225495d3628c49e2d8 100644 (file)
@@ -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);
index 3e5fe843e1df7588564dad9f3d5140318c6b84b6..68bd5c93ca524a089d1881bbcb9b5da4ef563b74 100644 (file)
@@ -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;
index 17b392a2049ebfb9b39103ecedbd9fe6ec884828..fc2faa44f8d185b6be9b8600a4ffb9991d5b980f 100644 (file)
@@ -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();
index 269e649e6dc6b6e1f891bc2aaf4f11aa03b58dec..ecf3da9edf21ab65a1a291a5edf8836dcdcaa520 100644 (file)
@@ -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;
 }
 
index f932591df5a43d00af7b2a6c72db3a1de1fdcb3b..2b0442db67e05cb7b0a275dafd0f7c762d86e050 100644 (file)
@@ -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;
 
index 8d544334bcd22d216b057620900834e73b756698..557d5b614fae6ba694703b86d950471cc2eeedc5 100644 (file)
@@ -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();
index a8efe35176b025626e4e49732ec49a1843862250..d993ea1a81aee7b60cdc11ffc9ee18dd09a8658d 100644 (file)
--- 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);
@@ -1318,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;
@@ -1463,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)
@@ -1504,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);
index 4c39009350f3e59529363108800c003de2e2d2d0..93e77c3d24906af5156254b29ee1cd3e39ba1ac3 100644 (file)
@@ -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;
index 92ea8265d7d5248e046954369da84b86bb858753..3e7a84a1e509a4aad71656e7bfeb8432d8a61460 100644 (file)
@@ -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,
 };
index e65a019fc7a58b87f80c64fcaa7944b06bd30242..c19ac153f56b72c38d564de76a4616a4f599d9e6 100644 (file)
@@ -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);
index 23e2c7ccec1d15794c2679c4215a917b8f0edb25..2dba473c524ad33282402305b6b1afe837caf5d3 100644 (file)
@@ -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,
index 3ca9afdf713d579d92f2037cc5ee4f69db9ab3da..1dfba77eab10dc348e0ac3c4fa4e23d2448ac281 100644 (file)
@@ -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
index 4ca8249853219cbee8529031e8602052cda46db2..e1af5b4cf80c100c26ce08a559bbdab12de8753b 100644 (file)
@@ -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) {
index 429acbb4e064bd21352f8019e133a781523169fb..d0b54f30b914e5304f367252e5f6a3bd96ac8d38 100644 (file)
@@ -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,
index 994efd189f4e3c7bd667e866d359670189f7ea65..e96c388047e09a0a89e1595b01ddc079745e9a0f 100644 (file)
@@ -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,
index dcf4f1dd108b21acd60c4ea3c88b0d8780b319c3..03ba5bcab18633725372096cd94c9e52b6aa83cc 100644 (file)
@@ -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",
index 3a6b012d120cedae637169ee747ec43b36b25e47..12daa68695721ffaf4a06bfa087d2018fceeb845 100644 (file)
 #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
index 85d132c37ee0f1a8a8c840432d7839f4d9b97af6..906731a20f1ae37c4f7be8999d72d7986cbabadd 100644 (file)
@@ -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);
                }
index 698b85bb1dd45855a709635eb6239a4c9bbef0d6..69c439f443877be9bf72e28760d939581b5a00d5 100644 (file)
@@ -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,
 };
 
index d50fc47169c1aba4b4388677dfabfd4f53b11933..f4b8f8b3fbdd25ed95df235862171dcf2a905a2a 100644 (file)
@@ -127,8 +127,6 @@ 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,
index d35cbc6bc11206b528a47672678d4337c933ecec..e4f26165f12a22567526a74d2f463aa6d6798547 100644 (file)
@@ -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);
index bc35a40417d7ada53223f5c93ed26875af97a646..24f25a057d9c131f94f1f2eb2400739958d09a95 100644 (file)
@@ -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;
index 892643dc9af10a1a6fbf7c858fd430ab209a5724..c403b66ec83c6525532c25decbe923c32356649b 100644 (file)
@@ -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 */
index 79ec1f23d4d2d65718d465f375c3926d9bd8613a..16b39c053d470c3d3cc71c3881c0f5c8c834864b 100644 (file)
@@ -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,
index 4fc557c40cc0c0bf8f158a7793d508f9ccb23111..66571eafbb1eb88afd8acc0e3625bdc0342207df 100644 (file)
@@ -680,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;
@@ -761,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)
 {
@@ -814,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;
 
@@ -898,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;
@@ -1041,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,
index f85b2a282f130e2f0d4a5dc4d4bcfc61ed99b2f7..8605155db171359398c952d8319c551a95fb305b 100644 (file)
@@ -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)
index 5c4fcd1dbf5908d29401aa3f83d1aac23a1d8244..183626868eea602d4658e5395ec31f46130c0afe 100644 (file)
@@ -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,
index 7cd8cc03aea7790159aa7ce5263e73655dabfd8d..37d681b4f2162da24cdaacd9b93e07108e041173 100644 (file)
@@ -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);
index d05641c35fc902e1f385a076977bc704f1cc05bf..02f5573e03491b597a7d68b40fb45f72f87e4a07 100644 (file)
@@ -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,
index 1f9ece0de326227af5a15c238aca2f7b78a61aa0..7e309751645f1618feec1547b502a5cbf5f03032 100644 (file)
@@ -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);
index 8a1ca5ef7ada1f26468d031ee0882d61e350ca36..3915635b4470bcaa29ce094acb10b9620bf8d2c9 100644 (file)
@@ -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
 
 
 /*
index 0eb1a60926682bec544dcbd697c293cec407973d..9e36752496336fa86ea19a7fbb3bdf6e73e8d2fd 100644 (file)
@@ -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,
index 13cf848ac8330ef03ebfbce82e3ce3ba07d5bc2c..79fd10402ea3479d3aaad8b7f6b780fa6a362216 100644 (file)
@@ -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;
index 322e876c35edd8105d3a49150ced12b0c9efd618..b6bd33ca3731edafe9866ce0a7a725a2bc3287c3 100644 (file)
@@ -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,
index d9eb19b7b8aecef05ef1d49d0a12feca4b184755..8b94d24855f00b7ece487dc2b1cd5b5a741af0db 100644 (file)
@@ -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,
index 59e7dc182a0c760ff78631cf162313ff6b2f97d4..2507e7393f3c6733ebda781bfea8be1d8459e927 100644 (file)
@@ -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;
index f5b8f329aca6d3e3c3b102cc50b1ee55c2663362..5e03b2f67b932dcb37d61ed3dbbffb6576141cff 100644 (file)
@@ -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;
 }
 
index abf77471e6c4a68701421dc6df6994de6e7000eb..bf6bec4e54ff648b4696c04909dcf2a5000c8748 100644 (file)
@@ -362,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)
 {
@@ -678,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;
 
@@ -1024,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);
 
@@ -1231,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 (file)
index 0000000..ea00126
--- /dev/null
@@ -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 *);
index 78b1deae3fa2e1a9aaa4142fa83050b434840b90..6dc6721d9e822d159fbb7e68cfc047aafe6c4e34 100644 (file)
@@ -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;
 }
 
index f5cf9c93e24380ef1c5347749f4d1f3d5c7d38cb..3f7899ea4cba9389742e6cb85d441ce9ff8c2535 100644 (file)
@@ -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,
index edd8371fc6a5b0f6f3c4dc1e220fe245642c5871..9def6adf4a5dee6a0a0162e31ebdf475842d9305 100644 (file)
@@ -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);
 
index 3ed6e3e120b602fb814051606dc7fc7f89edc430..242875f77cb38261fec2c2da5e35e3db08b15773 100644 (file)
@@ -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,
index 72d9909d95ff360e095b34a3b80320082c4ec1f2..7bc1a4201c0c233437dd5e60d45159620b39e57c 100644 (file)
@@ -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;
index e2281300979c7b2c5e09287e28364bb25733c648..4d84bdc882999150a1e9bd7ae829f1aff24b33f2 100644 (file)
@@ -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;
 
index ab7cd0567c958715e01b7f5ec7853a0c6e47ce7b..79494c4f2b10c2601c20044085d10815661d34a9 100644 (file)
@@ -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
index 1c9745be5adab3db43fd2218b69b4e92884100f6..34181b8f5a0ac6cbbbea4cee5fee75d5ab9e3175 100644 (file)
@@ -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,
index a223cf4faa9b59e61f14e2ffc57712b9469017be..f5719117edfe94e664e2dd46af752d7de8d9a142 100644 (file)
@@ -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;
 
index 67b3774820eb663086675ef4a057066e56e93e94..37db524882628dd3b4a4eed92b7a3243d6e61b60 100644 (file)
@@ -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},
 };
 
index a76293767c73649048fb904698771b8d0da15845..455fa4292045559ea52202da59ae920dfe8d64ed 100644 (file)
@@ -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
index 7f3e9ac454fff1f34678e002740d65ecb9754415..79c61805bd3358baba69387cc511a943c85be502 100644 (file)
@@ -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
index 81f0e514c4900c8fa679b429a3709ceb6decc318..9c5d59632aac98730aea6df4f5a50cac665e7a2c 100644 (file)
@@ -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
  */
 
index 9f2572aea5611b00279a771c760c6bbcf2126f7d..40b20111383c5f2c07419ab41cb5103fbed57a41 100644 (file)
@@ -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
index c161c98954e08b17afb7e849ef57c7b47bbd1b6f..23546c8fd48bd433c67f4233879c494f1c5457e9 100644 (file)
@@ -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
  */
 
  *
  *     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;
index 8b14cc8e0228346d703e6bb45509214d0b116be9..45ea454c74bd03f615fac463793ace154d9a7b1f 100644 (file)
@@ -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 {
index 6c3f083198468a686af3ed7c4dcc6bcbaf782dd8..ecb2216d881ccf5fb76bbd46151cc14763866018 100644 (file)
@@ -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 */
index 13e4fdf07724daefbc6a659f0f682dcd0d4fdde5..af8513f78648336f8bda39c8e5c271b943a43535 100644 (file)
@@ -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 */
index 4c74f0944f7ea20ccad8343b02d1edcd85af95dc..a35bdca6a805b81b2fe2bf4b379a27d55c02dd5f 100644 (file)
@@ -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));
index e80fc7ced87d96ddfa2ae5484130dcb34cbb7d29..b567e12c52d30af3d4fe9c2eb83723468cca2698 100644 (file)
@@ -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
 #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 */
index 72a5588faecac5040a241448796d0cfb1e7a5b3f..9901928668cfe62395da77cceba9626dcac9249b 100644 (file)
@@ -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:
                                         */
 
                                         * 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)
  */
 #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 */
 
index 369d7f39c040a94d0720c884d5dbc6c4ceaa54bc..489a3d63002db2db9d5dec4a3c3f1899a154a4e7 100644 (file)
@@ -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;
                }
index 6e24465f0f98d12cba1eb35bbe9b37ae0c8bcbee..4f9c346ed49868eaa6f9546a3be6299bdac0c294 100644 (file)
@@ -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
 /* 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);
index 54d73716ca8c4dfbed653ae6e0c0df29dcb6da96..94005584445a403f00996cd3d3bc50cec9d0679f 100644 (file)
@@ -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
 
index bffaca9ae3a20ef31e737485230b0836d666887a..4c67ed97682b74711ce67fcd37681e5b4e26fb20 100644 (file)
@@ -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;
index 1fc48df670c834f334f9620c4bd44c0a586145c7..0d06ccfaff0e7cf69935e556643f6176c99d4c4b 100644 (file)
@@ -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
index 70ac9f7d1e00c22064dcc43ff3d923820ce1048c..7d78e83d7c40eaee39c0b9e67b6210b5ea40504c 100644 (file)
@@ -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
index 3315f0b1fbc0ad5106e28dd65369ac7e443739e1..b89c9aba046635b90ec977a9415ddb8ef79a2f8f 100644 (file)
@@ -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;
                }
-               
+
        }
 
        /*
index 8c6909b80014b6948c0f044cb19062e72fafe25d..a53fb17ea219eeb8bc6e0bd903954b0fa0e724f6 100644 (file)
@@ -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
 /*
  *     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 */
 };
index f5afc129d6b12d2c9483574441f7b7296fb15cac..0cccd1c39d750e199185c4b1d7f7004f52246142 100644 (file)
@@ -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);
                }
index d17a3290f5aab901253c0f2d43b136a237dc893d..d94f8d9e87d79daf92e639c791a3b81742eadb57 100644 (file)
@@ -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 *);
index 032d111bc3309b65f4f3a8c80e5556c1a3435afb..4dd479834897be20d7e8ee4d5b7b66eccf1d0137 100644 (file)
@@ -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
  */
 
  *
  * 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)
index 682cf1a68a185ae3a7f22c954a86de1b35c2d339..884fc21ab8ee6182bb0d8ea3f58450b78895a277 100644 (file)
@@ -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
 /*
  * 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
index 3856efc399c11d7f28a58e24b21f7e9db05a0909..81f6f04af192ae45c64d3022591522b527342a38 100644 (file)
@@ -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);
index 0e4dc4514c47a4953420fa1cb1f9201b19ca6da1..7863cf21afcac82ef586c97541697f14d2640eaa 100644 (file)
@@ -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: */
index 5bfad39a20787ef5b8721f1aa723f1c8a1e7b526..09b2529586874159c550978ea46410285738035a 100644 (file)
@@ -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)
  */
index 21eaf7ac0fcb6c46ebfc784bc9a9a24a32e18339..a386f48c73fcb5270bfcf90ac067d172792280f6 100644 (file)
@@ -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.
         */
index f327decfb1556c5abb146e999bf1bd1cb94b4a6b..c7de6f5bbefc1da43b269ffe54ddec707ba7b0a1 100644 (file)
@@ -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);
index 69e25ebe87ac94cb222955b272cc5430ddc13a0f..3fbb3a22559077e0fbfd21ae4a44cb91ebd7605e 100644 (file)
@@ -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
index 4ab185d26308b9f081e360ee32697d3c3d1c0516..cfe50666d31220893c4b35a8fe2b111e2be5bb94 100644 (file)
@@ -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
  */
 
index 25e9990bccd1be1926a21847d4135544a7dd4e42..88b6cc535bf246cee2dc33487993fcd488b48dc2 100644 (file)
@@ -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
index e72f4ebb6e9cd8058f0be8a656cb04d584feb238..e98eb03e53105083b3fb33b0c35b11a3c5b3f8f3 100644 (file)
@@ -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;
index af668a80b40f8b989d278f7fdc0068b73bc41ef6..164f6f2b10191055bdb10522e9d1ff17603f3df5 100644 (file)
@@ -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
index 295268ad231b5ec1f26c78cb43489d434122c907..a6a8c16c872c886ba68f3e89c7d2682a1e9d429f 100644 (file)
@@ -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);
index 45180361871c9a98e04db73506a973e0c0dce0c1..79d625f3f7336f555acb604ca30966819b97e5d0 100644 (file)
@@ -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
 */
 
index 143bcd1d5eaa42f0529596676c85c16304a3e995..9c1c6e0e633d365dca62a9726037c5cfefcbaa2c 100644 (file)
@@ -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)
index 16477b3835e1d62235ff939bcab6f32b6be454bb..cee43f36f51d526843271398356dfb3bef030ce0 100644 (file)
@@ -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
  */
 
index 9bc5b7c055ce12ad015dc90df3d87fd72f42a7e7..4c7985ebca92505ae584d43024a8bf1c4f1cc258 100644 (file)
@@ -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;
                }
index 3793aaa145776971a19fbbbb9b61934634f80731..bd08e0e64a8caa8731c9ee5ccbd37962eb658298 100644 (file)
@@ -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 =
index f95cc3f3c42db4ff709cd2a4f203d78a619323b6..87e1d03e82673cdf14b435025556f608f07b68ec 100644 (file)
@@ -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. */
index 271e2165fff6ebf8577f4f5ab590a911ec9bedfe..0116729cec5f717ed246715e813108e7b12cb6b7 100644 (file)
@@ -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;
index 5954dcb497e4e43b241ba48d6cab7f6b1453e307..a816b920d431fcfd60fc806b10bd4e0cc25c02f7 100644 (file)
@@ -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);
index 9a991b52c647d7614cb014100c73b1124751b517..3cc369e5693f2d9af1c34e605c1ba2c615a21eae 100644 (file)
@@ -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;
 }
index c9d419703cf30b35daa6fcf17609b948f465b4a0..93c00ee7189d739f07f60ddf119cc719a4ce4146 100644 (file)
@@ -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 */
index 033ea4ac2c30be2590f36103d9f2f1fe4dd7023a..61c46facf257413f21ca462a9466e402265df906 100644 (file)
@@ -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)
index d7c53392cac12cf5b907d0122e1e504ca7a26f0e..e0b6a80649a01ff79c26206c039ece3d4faebd0c 100644 (file)
@@ -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;
index 420b32882a10ce6f55c8cd6d396d5045f334d5d6..40eac2e60d25deb803bebfbd4712e5caae5a65b6 100644 (file)
@@ -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,
index 5b6a4540a05b61cf496d2f5b3bcbd2c3e9958fa0..299bb66e3bde55a880435c5dee0c315cfbdced0d 100644 (file)
@@ -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) {
index 1e4598247d0b962f02eca7f390bf6683c9df3e4e..692a3e578fc8f1102823548dbc5d49a1a1850953 100644 (file)
@@ -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,
index d220165d49180fc53c6b66401e439ac2b9d36113..b0f01b3b0536de2dbe775a2d2d2988d255f7fba5 100644 (file)
@@ -343,9 +343,9 @@ 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:
@@ -389,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);
@@ -430,7 +430,7 @@ 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:
@@ -549,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 */
@@ -566,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:
index 2892e68d3a8647981e5aa7caf3c53e708584d4bf..28d49b301d5516bbdfb5bf7651f3c51b8f370f31 100644 (file)
@@ -1595,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()
  *
@@ -1676,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;
        }
 
        /*
@@ -1934,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;
 }
 
@@ -2056,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);
@@ -2199,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;
 }
@@ -2308,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);
index 6ede3a539ed82acb0eca0781ce78ba2fd86db1df..55442a6cf22133d2c9687636b3e3ca788eacac53 100644 (file)
 #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);
 
@@ -134,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)
@@ -831,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);
@@ -1442,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;
@@ -1509,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;
 
@@ -1532,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);
@@ -1755,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);
@@ -1781,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))
@@ -1797,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);
index b4ee89250e952047c20ec8f8d33919089bae46ab..458b3b785194e815a0081ed3dcd3cf2e116a6172 100644 (file)
@@ -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 =
index e6b7c67cf057765f86921cf2220fee385eaaee38..df37524b85db0a69f823935bdf666cda214f48e8 100644 (file)
@@ -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,
index 42039fe0653c0c3afc546748e060b005ca882fd8..a89ac84a8241a53d4e260deda2ad7d7f8c675255 100644 (file)
@@ -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
index a3ee11364db02044e07cd6dce7a5546aa4016650..7933e2e99dbc2a4d448591aa87d17f937d816619 100644 (file)
@@ -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;
index ec1938d4b814f3d3b9e031aa076499c7ca6102bd..8106f3b29e4aa9747fd786280b132d7c41332154 100644 (file)
@@ -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
index 7432f1a43f3d6bc66c3aee43366a3111a46b8ad8..481f8892a919489cb5705269834b0145b0d5c8f1 100644 (file)
@@ -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:
        /*
index 377839bed1725895cc837aa0aedbea8ba9821c61..9f7f8b9ea1e253b2e9614a658a7186720a5a80b1 100644 (file)
@@ -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;
index be997d649127376d515193ec5460ab61ee46e4d8..cc93865cea932a4e9c78ea95e1c0165e575630d1 100644 (file)
@@ -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;
 
index c0a754ecdee66447464a9bb67c900071896909a3..1d656a64519977189d7741e944dd11832e6e51ae 100644 (file)
@@ -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;
index b674462793d3375cf2adab2d642a8526e956fa0d..f6675d2c386c29127a9e6bad4223f47a1dbd3e12 100644 (file)
@@ -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>
index 01bc68c628ad16b92f84ce183e9cf908e09511c3..cfe141e5d7592630a58edd15447b1e023b99b04a 100644 (file)
@@ -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;
index 8583d99ee7407a894def12584afde6a5c5f9a992..f6ca9fb3fc63fb7b78870bd387d8844c648e5b57 100644 (file)
@@ -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; \
        } \
index ee4eff27aedc80d9faac58a7dc208929551d36ef..15ded7a30a72dcf4426b0e45c13c6a45395f6505 100644 (file)
@@ -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;
                }
        }
index e35d7e52fdebd4f37f477fa15c8de69b821d54a4..1cbd2e4ee12252bb30c8a5c37a5aa50486584252 100644 (file)
@@ -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;
index 7046ac9cf97fa14e50743ed1cc4655d4b4ec26f7..5c6a477c20ec30693267f0425a4117e1f93caef5 100644 (file)
 #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},
index ec1decf29babd194b8ea8f2ae94912f252d770ec..19443056ec301a94df4db864d617fac80a0f0fa5 100644 (file)
@@ -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:
index c9e3b5a8fe07d6ce8a790f668da75898cb0474f7..443ebc52e38240062e4f3c4d726c8ac4fce740a9 100644 (file)
@@ -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;
 
index 9de6b495f1128c09dd7c7d87767473e0431122cd..b1317ad5ca1851f0ba4954d7bb47bba1bd239213 100644 (file)
@@ -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 (file)
index 0000000..d269a93
--- /dev/null
@@ -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,
+};
index bc579bfdfbd8ff0c09c701a849b8b61c362b0fa0..7b2c8f4f6a6f7aba6e5012f37e5e8836d0e04f0f 100644 (file)
@@ -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.
index 325ce261a107d3773040d463038ade0b34032256..9393f4b1e298faa9d84d2f6dcb3b771a8be7d4b0 100644 (file)
@@ -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,
index 6708e1d68a9ed818902a40dec5a59cd002a56173..9f08e851cfb69ed9373344b7865b42b747451d0f 100644 (file)
@@ -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),
index 9074886b44ba194d1c6cffed6f8bb838f2263f97..3c8b74c99b808f3bed9d48104b2c770c13edd4ec 100644 (file)
  * 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);
index 7a190cdc60e2f4d403d157e2b5c912f182e4bf46..0809cf876098965fcd33d472201491bb7796403c 100644 (file)
  * @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) {
index bb50d6bc9212f88d611b5bfdf42102f6a2f439cf..72c9ad8be70d0b1d80b5e03d41737e9db10f20a9 100644 (file)
@@ -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);
 }
 
 /**
index e027f36fcc2f8f5b01193a194abdf44a124906e3..aba83347e5fe4fb0da406f76e3597e496d8ad1cb 100644 (file)
@@ -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,
index 68a607ff9fd36d2f7e62b76546392029ff1111a7..d98daf59e0b64ac91bf3c950594ba6685e6ca737 100644 (file)
@@ -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.
index 2e42c2dcae12310d123c13642809219c5cb51126..ae2fe0016d2c7be63adf1029f878b798fa1af7b6 100644 (file)
@@ -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
index 9f5427c2d1057d1652a60b1a0e3e317d48415518..e32cde486362bb21976d271fb02892effbeb2460 100644 (file)
@@ -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;
index 846a489e8692b23a93fcfcb47402f735a32b1857..8745469c3989d626b2ccf7aeddff01d5036ce8f2 100644 (file)
  * @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.
  *
  * 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;
index 933dbd89c2a433275c2cdd354ef42296c54be8c8..2d3de9c89818033a0c96f1a9f43afeb84132a285 100644 (file)
@@ -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
index d34b93cb8b48adc878fdddf1bc86892b42b274e7..1e383328eceb769c778b2694dbed5a86f200e150 100644 (file)
@@ -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)))
 
index 29cabf93d2d24ed66ffd0aff3a5478163e93f210..1711b710b641f40a0c8c5690a94c9681f2b5fa92 100644 (file)
@@ -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 "
index 72cbca7003b2de3ee54ffe4a358efac9e767f090..2adb04316941017109ba85b893d504d06b230be0 100644 (file)
@@ -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,
index 4af2ad1193ec374288f0f803ce7bf3b05ee9da62..acfed325f4ec17481099f505dc3dcb2a37751dd6 100644 (file)
  * @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 */
index a51f3dd0e9eb56c106f3935b14c4d2d7ed76cbc7..9468e1c45ae305dae0a5a626d38de952da914d7b 100644 (file)
@@ -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 */
 
index 584260fd68489a2ec49a412f0824939660872fb8..2ad5c8b104b934c9177e162d2c20c6da211ed0d9 100644 (file)
@@ -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)) {
index 639cd1bab08b7919c3307964faaf75f525717950..b52bf87b99de90ecf1a40adcd2c602ac87fbae7e 100644 (file)
@@ -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);
 
index ddd3d503097c081e42176abb5fd494864fcf56c4..a12847ae467d3a595dc020d646b7912b5f2cbc4e 100644 (file)
@@ -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);
index d0ef4182147be0a02550335baca0ed5751ffaeb9..d80e3315cab0ec73cfdd9b668594d588f559273e 100644 (file)
  * 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 */
index 40e4763aa2221d1f6f15afcddbddee9ac9070994..4cbe5594c0b077f8fe795a39ff217cb0c6ac8ef0 100644 (file)
@@ -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 */
 
index eb52b801512bc8027d2def23cd2359cd9f96a1ca..9afd72c7ad0db7c81f4487302971c2340cabecf0 100644 (file)
@@ -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;
index 6b2712f10dd288d07469e6fcbbce1d8abdf1657f..03a391ac71457a282aeb1703c5585877d93533f9 100644 (file)
@@ -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;
 }
 
 /**
index 6e4a7e3343f22d268c80dccbf2a2ee9d3857f852..8c8053b66984222fd3c4c744cc63c81e40124b7f 100644 (file)
@@ -61,11 +61,6 @@ typedef sle64 leLSN;
 typedef s64 USN;
 typedef sle64 leUSN;
 
-typedef enum {
-       FALSE = 0,
-       TRUE = 1
-} BOOL;
-
 typedef enum {
        CASE_SENSITIVE = 0,
        IGNORE_CASE = 1,
index a1b572196fe4a14f86aaaeb6f0656b79d386ebf1..6a495f7369f9e7fbd170d0802014f4d750d6c6ae 100644 (file)
@@ -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);
index 77773240d13980a403ccf7ee3f4cecb2a3550e6b..b2bc0d55b0365b854173b1c2802ce2f78e99bc7a 100644 (file)
  * @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 */
index ff988b0deb45d46aea455a55e338ce2d49ba7bfe..3a8af75351e8662235eff32b67f9810f1c717248 100644 (file)
@@ -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 */
 
index 0368c64021822c56f809d84cd84cdcace2ea81d4..16b8d1ba706662c15ee99db4fc20f07f20b10e1f 100644 (file)
@@ -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 */
 
index 2bbfa17090cfd3f5071ad9a17fc86b6af4280ea3..d9ba0a931a03b89aa5c9a894b040470db459e05b 100644 (file)
@@ -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");
 
index 849c3b4bb94a12d1e856df92e3c47d8e08dd3b43..259155f0eb2e97ce20a39b7d990ee497b59a5725 100644 (file)
@@ -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);
                }
        }
index 304c1c7814cbacfec0695e8714c5557ea8ee0e9b..89e0c237a636987d5b131e5816e8d9d9f238f210 100644 (file)
--- 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;
@@ -737,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;
 }
 
@@ -756,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;
 }
@@ -770,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;
 }
 
@@ -782,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;
 }
 
index d713ce6b3e12935891bda7e21d301ec3d53038f8..67e665fdb7fccbde923238532d49f192931d43f9 100644 (file)
@@ -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
index 7ab1c11dca4efb9f06a63827cb43c6a806c59f96..1a60926a4ccd5908587555e84235fa0ba8e90e36 100644 (file)
 #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);
index f3b6f71e9d0bdd5680cca1d889305bd339a1d67d..b1626f269a3445e38f34c1bc338734e0893bbd32 100644 (file)
--- 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;
@@ -509,15 +503,6 @@ out:
        return ret;
 }
 
-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)
 {
@@ -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;
 }
 
 /*
index 6c8dcf7613fd89bf903a95b311af8a1eee2bf8ce..aec931e09973716240bf55441622dccf95cf3c74 100644 (file)
@@ -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;
 }
index c0e554971df01dbac80e057bde18b94e6648faa9..25e917fb47399bf22761fb8ed47b190776ee6cff 100644 (file)
@@ -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;
@@ -349,15 +347,33 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        cutime = cstime = utime = stime = cputime_zero;
 
        mutex_lock(&tty_mutex);
-       read_lock(&tasklist_lock);
-       if (task->sighand) {
-               spin_lock_irq(&task->sighand->siglock);
-               num_threads = atomic_read(&task->signal->count);
+       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;
@@ -365,31 +381,20 @@ 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)
index 89c20d9d50bfbf09c77aca8ca921885bb7eb0084..82da55b5cffef804f4528bf1bed4d94645f7df2d 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/cpuset.h>
 #include <linux/audit.h>
 #include <linux/poll.h>
+#include <linux/nsproxy.h>
 #include "internal.h"
 
 /* NOTE:
  *     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);
@@ -1137,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 */
 
@@ -1293,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;
@@ -1307,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;
 
@@ -1333,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 */
 
 /*
@@ -1372,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);
-
-       rcu_read_lock();
-       stat->uid = 0;
-       stat->gid = 0;
-       task = pid_task(proc_pid(inode), PIDTYPE_PID);
+       /* 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);
+
        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)
@@ -1428,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;
 
        /*
@@ -1506,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;
@@ -1520,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..
  */
@@ -1556,36 +1355,162 @@ 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,
-};
-
-#ifdef CONFIG_SECURITY
-static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
-                                 size_t count, loff_t *ppos)
+static struct dentry *proc_pident_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, void *ptr)
 {
-       struct inode * inode = file->f_dentry->d_inode;
-       unsigned long page;
-       ssize_t length;
-       struct task_struct *task = get_proc_task(inode);
-
-       length = -ESRCH;
-       if (!task)
-               goto out_no_task;
+       struct pid_entry *p = ptr;
+       struct inode *inode;
+       struct proc_inode *ei;
+       struct dentry *error = ERR_PTR(-EINVAL);
 
-       if (count > PAGE_SIZE)
-               count = PAGE_SIZE;
-       length = -ENOMEM;
-       if (!(page = __get_free_page(GFP_KERNEL)))
+       inode = proc_pid_make_inode(dir->i_sb, task);
+       if (!inode)
                goto out;
 
-       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);
+       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,
+                                 size_t count, loff_t *ppos)
+{
+       struct inode * inode = file->f_dentry->d_inode;
+       unsigned long 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;
+       length = -ENOMEM;
+       if (!(page = __get_free_page(GFP_KERNEL)))
+               goto out;
+
+       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);
        free_page(page);
 out:
        put_task_struct(task);
@@ -1595,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;
@@ -1613,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);
@@ -1630,329 +1555,262 @@ 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,
-                            void * dirent, filldir_t filldir)
-{
-       return proc_pident_readdir(filp,dirent,filldir,
-                                  tid_attr_stuff,ARRAY_SIZE(tid_attr_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 = {
-       .read           = generic_read_dir,
-       .readdir        = proc_tid_attr_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 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,
-       .getattr        = pid_getattr,
-       .setattr        = proc_setattr,
-};
-#endif
-
-/*
- * /proc/self:
- */
-static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
-                             int buflen)
+static int proc_tgid_base_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
 {
-       char tmp[PROC_NUMBUF];
-       sprintf(tmp, "%d", current->tgid);
-       return vfs_readlink(dentry,buffer,buflen,tmp);
+       return proc_pident_readdir(filp,dirent,filldir,
+                                  tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
 }
 
-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 file_operations proc_tgid_base_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_tgid_base_readdir,
+};
 
-static struct inode_operations proc_self_inode_operations = {
-       .readlink       = proc_self_readlink,
-       .follow_link    = proc_self_follow_link,
+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_base_inode_operations = {
+       .lookup         = proc_tgid_base_lookup,
+       .getattr        = pid_getattr,
+       .setattr        = proc_setattr,
 };
 
 /**
@@ -2022,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;
@@ -2077,178 +1904,250 @@ 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.
  *
@@ -2318,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);
@@ -2358,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;
@@ -2392,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,
+};
index 5bbd60896050545759f4aa603e12cfee9cd63295..8d88e58ed5cca648a75a514766f41a80f883d5d7 100644 (file)
@@ -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
index 8901c65caca83be55d575ea70d51411435d5410e..ffe66c38488b6d6925614e00147d213dfc271e0f 100644 (file)
@@ -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);
 }
 
index 62af4b1348bda336cfcc90420a6f1b208f7f807f..467e5ac7280e739eb65a3ee63267ef5e46fbef20 100644 (file)
 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
 };
index c3d83f67154a61c2fe39421d7809a04d4769577b..733cdf01d645365a204f57fbd83ddcdee292e608 100644 (file)
@@ -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:
index d6a2be826e29880abd0f6873caa2344f88f2c5f8..b9dae76a0b6e2212083efa9ca0281e31661c0375 100644 (file)
@@ -337,6 +337,34 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
        return 0;
 }
 
+/*
+ * 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
@@ -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);
index 86f14cacf64120569f2fd0ad8e6ee573de98eb4e..0947fb57dcf3425bb4952eb947dd9d3af05bfe2e 100644 (file)
@@ -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,
index 677139b48e000d0d98100122c851eff5572aa14a..bfe5dbf1002e597a5b0b5ca25cfb9ea411b1c36e 100644 (file)
@@ -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,
index bc0e51662424070cc1d5a38f8dcee23034a42d45..2faf4cdf61b0d126713eb7b7eddb692517730504 100644 (file)
@@ -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;
 }
 
index d4cb3183c99cb9c89ccb5b1bc2f98c4e976087d8..f792000a28e63179ce88fea9bbeba93f48b9dc94 100644 (file)
 #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 (file)
index 0000000..d07b954
--- /dev/null
@@ -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);
index b6109329b60739197685270d833b0699d11c020d..bff3ee58e2f86ecd8e599e104b46e7faa04752f5 100644 (file)
@@ -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;
index 4a7dbdee1b6d73f1d1ae8fb44becb0410c6e58d1..1bfae42117ca714d1951a179d26d037f12226767 100644 (file)
@@ -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;
+       }
+}
index 9aabcc0ccd2d002401e7611a93f5f6b8458136c0..657050ad7430e68777a326c18fad5a4d8a04cefb 100644 (file)
@@ -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,
index 1cfbe857ba27216c03243c6eea5b07ab9d72b1f4..41f24369e47a0945e67fd52a10fa3bcabc357943 100644 (file)
@@ -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>
@@ -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,
index a986b5e1e288c8dd47eca5ea525c9cfe2fc26b77..9c57578cb831a2f869c7e277896b04b06a369c80 100644 (file)
@@ -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.
index c61710e49c6244e9559cb0f1b0fb92e24442d59f..16e9cff8f15de9e2884079adb426a3f476445be8 100644 (file)
@@ -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;
index 39cc7f47f5dc57686469302c9ba75e3289d1360f..315684793d1d8d0ff6b61ec08c4e9a5e4dc75d22 100644 (file)
@@ -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);
index 80fc3b32802f827d6fe1bf8e9e919321d3f9e6d0..c89aa2338191af86e6299496e18882756ccb78d2 100644 (file)
@@ -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));
 
@@ -1243,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;
@@ -1456,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))) {
@@ -1465,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;
-
 }
 
 /////////////////////////////////////////////////////
@@ -1659,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;
@@ -1736,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;
@@ -1818,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));
 
@@ -1903,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);
index d935fb9394e360866cfa650ca6704bdd229c044d..7bdb0ed443e1155bdd7b40b8e26a417f2d96be1c 100644 (file)
@@ -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;
index dae67048baba345fcbd6358e4a84fd890f834633..50784d13c87b55a542d9db3dce156ede054b5a1a 100644 (file)
@@ -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,
index 684bca3d3a107c021715f8394a1f1d23a1913aaa..13e92dd19fbb1b9165f6cd05e02128c2a0a39cd8 100644 (file)
@@ -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>
  *
index 60a31d5e5966a03ba0a3e009ae521bf02ade2adb..bca07eb2003c395b8e40d33cfe3ce548065d9ff7 100644 (file)
--- 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
index 6987824d0dce0ec94713d3f394e8d2c8535c04aa..aec99ddbe53f726a526d4cd0b02abb9f55179e0b 100644 (file)
@@ -220,6 +220,37 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
        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,
index 955aef04da289fecb80f51981ae98f538e6bcdc2..1de747b5ddb9dcaf12ac0dc164f9a614db7b6d13 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
 #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
index 5f3d725d11251487481c57599bc0f0ddedcfe904..3aa3434621ca89296b3c0b0598a663807977f1eb 100644 (file)
@@ -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);
                        }
index cf3786625bfade2ec42b0bcebcd6b0c72771ff21..146f1dedec844ced95a9055e31e701365b4b241e 100644 (file)
@@ -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);
index 40190c4892715502b286c3e491c114af1c0b97bd..20551a1b8a56494ffb7ea2b0a10c01f8f7f99a78 100644 (file)
@@ -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;
index a59e303135fa02feca937e45706c87b14f8d0c5b..47a4b728f15b49bfdf84d7b30d17568e08a13b1c 100644 (file)
  */
 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,
index b8a73f716fbe35c5a0683017db96fc3c2d1136cd..f7c08db8e34c80225000cd10b7722e5d8ef82eb6 100644 (file)
@@ -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) {
index a59e5f33daf6f7ed5225d8f85c349acbf29f05ab..7aedd552cba12c205706fb921dd0bde45ec68e11 100644 (file)
@@ -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,
index b223b32db991c4a1d3b4dbb225e0217733ec4dcd..ae21a0e59e9569b09234f57fd1a910baf9928059 100644 (file)
@@ -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:
index ab9a7629d23e82c094e8b7db9606a57af007e294..73163325e5ec36ba628209cc146cf808d3f94abc 100644 (file)
@@ -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);
                }
        }
index a9c6e5f04faea080ddc271602cab79f829295548..1e096323bad47f240bdbc30191922d46638a5612 100644 (file)
@@ -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,
index d344b411e2617eca708d104a7b8dc5266e26ab7b..e84c0ecf07304f0f8222e3c438f4e1b8bb5bed34 100644 (file)
@@ -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 (file)
index 0000000..1bcd852
--- /dev/null
@@ -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);
+}
index 9a8f48bae95626b739b34867713fc2d7d367f649..edb711ff7b05781b624b310dcf7b360f2c683745 100644 (file)
@@ -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:
index 26b364c9d62c67226de54101ae6f7faa31f33251..35115bca036e01d5363c6103100a875c232784e0 100644 (file)
@@ -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
index 41cfcba7ce49bed9c85e94785c163922e44a57c8..d93d8dd1958d3fcb5cc597d44fdda345ac522fac 100644 (file)
@@ -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,
index 55992b40353cad97de4dd7b20dd9a009bd3d5b63..fa842f1c9fa27b3511c86725a1cad2f3334f4b9c 100644 (file)
@@ -279,7 +279,9 @@ xfs_read(
 
        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)
index 0c294c9b0c558a8a45f080b8e0b825fadbdf859f..aeeb125f68513df03fe1d625de0cf1883b46c869 100644 (file)
@@ -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 */
index bc6e6a9259dceae583af27b0c5bda3b33f21d323..2cabbd465c0c4d1b3437dafea1bf7030b080c217 100644 (file)
@@ -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")))
index 91ae0030fdf28e4a8e808e67047da8d1d3060963..ce155e1612690dbf7671f9c0d95a20aa9ef0ac51 100644 (file)
@@ -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)
index 01b7c26a30386951905de5ae46d3bc31fdde30cd..861092fbaa53283953bd41c9dbb6e840bb42ff02 100644 (file)
@@ -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 */
index 2ab4078334bf1ee57afba6e6ffa7639903dd6889..14a87eec5a2dd28662173173316bf1a9ffa29ac6 100644 (file)
@@ -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
  *
index c6d2436c9d349ca322790a81fe95181988641da0..25a5eead85beaa4a26530f9d331519edc6270ffe 100644 (file)
@@ -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
  *
index 1f528f92690d48fba210eecfeff3c0436211cc77..a50e5004550c5d506d23b33db1a5bea490d50e84 100644 (file)
 #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
 #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 */
index 52df72a622329659d27524f57fc1d2f95556bc13..5f43df0a5fb42df32847984e49e6a2d8db070f2c 100644 (file)
@@ -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 */
index 7372efae05163d166ab1ebec5b94cb7c5b1e0134..7c90fa970c3842f468b88b163943770425db6dbe 100644 (file)
 #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
  *
index 2fb3c6f05e034b30c2c3a419b4958106cbe7b45c..ba1b37df69d50d6147a2150b052c5e8cc89dd9de 100644 (file)
@@ -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;
index 2aa562fa067bf4e371a79b9ea3e80edf15e4504c..a89bddefdacf9194373a201c6c6c4cf8c4ac87c0 100644 (file)
@@ -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)
index d104d1b91d399bb4f34f627b478f8740ebbee662..725e854928cf3cf60f79863fd2db64011ad0747c 100644 (file)
@@ -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
index 349260cd86ededc1487131a77518f6dc6187da8e..9d774d07d95b4a3a53d5fb75fac15b076d892a02 100644 (file)
  * 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)
@@ -165,6 +162,26 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 #define move_pte(pte, prot, old_addr, new_addr)        (pte)
 #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
index fbad65e8a5c0ab8cf70d702b30abadf0a8366ee0..90efbd65539076b2afd06d1f9cafb714f8e1a7fb 100644 (file)
 #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 */
 
 
index a2dd90462d80f172b17760b1501dfd6c91e3030d..747788d629ae1dc192d87356bb15a986dca95e75 100644 (file)
@@ -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
  */
index 2a9e4ee5904d50b91d3b6310ed2e78451ce2630c..592ffeeda45e7745c4554201ce8a78da1a80df38 100644 (file)
@@ -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(); 
 }
index db4344d9f73f52fe716076b7f3704a0455f747ae..3a05436f31c0e8252e01389f251d7d5225711583 100644 (file)
@@ -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)
 
index 4b3b526c5a3f64503aceeea46e4eb4e8c7277362..fbb1f3b71279d5da826870b3186e53bd3e463a65 100644 (file)
@@ -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)
index 303bcd4592bbe332337c10726dce6a0b3bd4c94a..269d315719ca422d478e7d18cd441cf71c44438d 100644 (file)
@@ -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 */
index 201c86a6711e87f91f688ab15b2c10ddf3b8ad64..8d8d3b9ecdb02d0437b0e0393fc8e753cd439178 100644 (file)
@@ -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)
index 0d899173232e1f54bf6e80e924391a8fa0b30cc2..c2d701ea35beb0650ecd0cd8360f857a1e90ca31 100644 (file)
@@ -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) \
index 541b3e23433571d590f8e79291bb2c21fded9306..7d398f493ddeedfc2d5e826d595028767ae64b76 100644 (file)
@@ -246,6 +246,23 @@ static inline pte_t pte_mkhuge(pte_t pte)  { (pte).pte_low |= _PAGE_PSE; return p
 # include <asm/pgtable-2level.h>
 #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
@@ -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.
index a4a0e5207db58627c4ef02eb1a22eceb54c20a86..d505f501077a67bc77b01729a724b61eb6e26b7a 100644 (file)
@@ -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__ */
 
index 915c26a31b79a6f0a855ae06920810761978abe8..6aa1206f6e2a9b17ffd120f94625db0552916f71 100644 (file)
@@ -84,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;
@@ -92,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 */
index b0b3043f05e154742738f5ff03b7c409d265f2f4..c18b71fae6b38f6ec0a524509deb4a229de002ad 100644 (file)
@@ -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 */
index 6adbd9b1ae881121e9f377a121ec0c4e9355361c..978d09596130d2625d2eee9be4e8b850e8cbf4c5 100644 (file)
@@ -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,                   \
index bd9987087adc6adb90d95daabf67c4eba7be8392..3ca7ab963d7d6ad2f152bd927314e15639223d29 100644 (file)
@@ -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
  *
index 1414316efd405028d84a357a198a7fd3684e8f2a..f4ef87a3623674db5c8510374aeb0b3ecea8d333 100644 (file)
@@ -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.
  */
index 9e83210dc31257adc4c5356b64f37b24e83bf1e4..ff857e31738a00dfbed4534ee1832528e231fb33 100644 (file)
@@ -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 */
index 937c212575239f3ec9ee9526e2c989289669f967..a6e38565ab4c068e6adc16738c7418c7b247b3c9 100644 (file)
@@ -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)), \
index bb0eb727dcd086fb15d43135ca7e0e20ebb4cdf8..53c5c0ee122c96291655807f05dc8a60d121773f 100644 (file)
 
 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,
index 6a674e3d37a20cdc30a5efd4d8765d106ec87c87..84152760e0b56e90847b9eb49c3772459afbdc09 100644 (file)
@@ -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.)
index f9f90727a4a1f9c88485150e380db6113d461218..f5cfba81ee10c1f59b007dcf34fd9db508a9bff5 100644 (file)
@@ -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 */
index e89bfd17db519bd0e78718f2db2342547060c21a..019441c1d7a0ef4feaff5523a6435d58283057ab 100644 (file)
@@ -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__
 /*
index 5c6a9ac6cf1aea11eefcca4969dae98057e6c724..95aa34298d8211d85252976da8931d49f9ef5665 100644 (file)
@@ -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
  *
index 751632b904dbca90a4e8a1967ff24a28815d9532..3ab716f0fc18a7870df7a1359fea9df74b16119e 100644 (file)
@@ -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
  *
index 21fdc37c5c2c60c8c4e69d0a6829efa297042dc9..daafb5d43ef196c6fbc829d78ad0cdf508562c6e 100644 (file)
@@ -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
  *
index 36416fdfcf6893030e4f0325e8407023857babc0..9ab59e2bb23368530fa67c95af0d6ab2c4f7fe8f 100644 (file)
@@ -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 (file)
index 070dfd8..0000000
+++ /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 (file)
index c58b16d..0000000
+++ /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) */
index 43ca09a3a3d0ca2735b6f0b364c0190cee2569c4..46bf5de5ac720f1691b75bce5ea022eb7cf7d874 100644 (file)
@@ -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
 
index 13b1443a7a650b654bf367c28fb7219d7a073ce2..7e272ce57ea3a44ff42aa78270919516e2c39fa8 100644 (file)
@@ -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,
index 59d26b52ba321af8775bfee6edcb9de3191f1252..a13b715fd9caf5d028af465941d3f6c1f08ff193 100644 (file)
@@ -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,                   \
index 035637c67e7c0ab2c29b62f5d16dc7ce85b42c62..c882e04e1497ea71e86fd90af1950c3f7ac192be 100644 (file)
  * 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
 
 #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                           \
index 4c1a1b53aeaf1c3db24c8f01fab27147600e0020..c8d5587467bbf6181ba2950fa66bf63c8dcc3858 100644 (file)
@@ -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 (file)
index 0000000..07f8733
--- /dev/null
@@ -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 */
index c39142920fe6e61bd2610345fd8849a051c54676..685c91467e6347527567f5aa78198226ea236514 100644 (file)
@@ -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__ */
 
 /*
index a93960e232cffabb43de39d78a97dc9d7542f154..e1825530365d3d1724b925fabb54a125429cd564 100644 (file)
@@ -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 */
index 27bcfad1c3e337cf3642245c3430dba14202ccb4..53b0f5d290e457d405d2950cb8982693658514df 100644 (file)
@@ -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/fs_pd.h b/include/asm-powerpc/fs_pd.h
new file mode 100644 (file)
index 0000000..3d0e819
--- /dev/null
@@ -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
index 46bae1cf385b9e26c2d05b9463bd09f2a7f2119b..cbbd8c648df1341120e825b29c9d33a9763d234b 100644 (file)
@@ -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>
index 34e1f89a5fa02eda188e2654e47dda3555066686..2dafa376a63f60f89b3697a2034c943583a1de87 100644 (file)
@@ -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 (file)
index 0000000..ccdb8a2
--- /dev/null
@@ -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__ */
index 4435efe85d0edb37cd2d3de5b0307140cb8375b1..4ad77a13f8652ebdf69aa2225ceea03346916212 100644 (file)
@@ -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
index c31e4382a7759dba58f18f7925e675538a951e5f..cc4cfceac67c16af4dc5326720ec0dda77fd6227 100644 (file)
@@ -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 */
index 5785ac4737b5ee7575837b2d8e8d9c05b752f8cd..b051d4c88c3b46a19b40ba11d2e951010be502d6 100644 (file)
@@ -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 */
index bbc3844b086fcadd9f529c69f5b12b6556530667..8f7ee16781a4d6497c7fb0b8b79993768f67efc2 100644 (file)
@@ -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,                   \
index eb66eae6616fb3026dbf38f966afff686664601c..464a48cce7f51c561f799eb67f95a7e50473c3a2 100644 (file)
@@ -478,13 +478,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #endif
 
-/*
- * System call prototypes.
- */
-#ifdef __KERNEL_SYSCALLS__
-extern int execve(const char *file, char **argv, char **envp);
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
index f6a7ff04ffe5030a46092538ce31c99ac9478c3e..220cc2debe089ee92c5daa70caa3590e5494b5ea 100644 (file)
@@ -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 (file)
index 0000000..8691327
--- /dev/null
@@ -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
index e6ca1f67cedc0e526ad36d9dba1c784d88db7ad2..65b93225a7786016845e2a4db544571c743445af 100644 (file)
@@ -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);
 
index 5c64b75f0295bb0eec7697dd79a6b4f171269a2a..fccaf5531e579444b83d46192ef4280245a1a8ae 100644 (file)
@@ -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 */
index 8d2bf65b0b6487a4c64df4444f3740d16c0428cb..7b768c5c68a8226b43cffbfb44ce7f9ed9aa4615 100644 (file)
@@ -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
index f1959732b6fdeb731608eea88da206c97ade05c1..5d72eda8a11b7b4a813b97d25c2734c192618ed0 100644 (file)
@@ -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)
index ce3edf6d63b3bdf4bac03a982d00151577843d4c..6b78af16999be895b31a08f3386ddd3c532d64ae 100644 (file)
@@ -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 */
index f79a2216204f523bac490f3d0009dd01a33b307f..b7ac13f7aa373e0c2c21412579d9e0f5f3215103 100644 (file)
@@ -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
index 0361ac5dcde38333183b8e1e89676b61d28c37bf..0cccfd83c45758e7b9d367442efcb6094567ba7a 100644 (file)
@@ -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 (file)
index 0000000..9218ef8
--- /dev/null
@@ -0,0 +1,3 @@
+cpu
+mach
+machtypes.h
index b4000c8bf31b8b76161b93c227a9bfa24c8ad0a3..beeea40f549ec391248d0a0673851f478c3dad17 100644 (file)
@@ -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 (file)
index 2d92667..0000000
+++ /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 (file)
index e091e32..0000000
+++ /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 */
-
index 0dee7b05b49d9b069bd820e4d5e9a7977553e4e8..c1253a6831974c7bc4e60435af44cf3f02ad6789 100644 (file)
@@ -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
index 3a07ab40ac4d0a66eab64eb094f538e08fef68bb..fc050fd7645e0e11c29fcf63cf7e1554dca148e7 100644 (file)
@@ -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 (file)
index 513c851..0000000
+++ /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 */
index 71ef4cf4242dd5770e416e62eef01a48e2939a4f..9020feee7b4c472327cb758555ba7f0c8db51c88 100644 (file)
@@ -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 (file)
index 2410940..0000000
+++ /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 */
index b112ae221fd1f4ca0b6ac87cb50909df83037544..796b8fcb81a8984ce5d887e49840d3c0f5fd74d3 100644 (file)
@@ -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 */
index 8a6399a8cfe0c4ac71548ed591aa67c55abbb0fa..d3c548443f2a6e7774e7f1f2fd6789e2d129d9c0 100644 (file)
@@ -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
index 846322d4c35d489daf86e337518dbee79f5c738f..2586eef07d57214ec977f50b818d61c1c0fff9ed 100644 (file)
@@ -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 */
index 3e0cff04caec8c32adb8c4bcda7a9f209243377d..95bc7db006b0761db05829e730323533e2553970 100644 (file)
@@ -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 */
index 5d5e9f94def587192e726bb59c5079585580629f..f1a0cbc966be0c8667a5acf7afe54982c043a9bc 100644 (file)
@@ -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
  *
index 1fab96d792bff9452cd2335db32f7abdddc11ce3..0b01c3beb2f8625cf1da858c4b61c246b5944b8a 100644 (file)
@@ -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()
index af0b792696615058268ce878567f7f23f6ae31dc..163e2b62fe278be34955a30468073af09334913f 100644 (file)
@@ -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;
 
index c113566bef3320b348f337a684688323b3e723f6..ee7828b27ad19334f694a440330cfb03ee56298a 100644 (file)
@@ -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
  *
index 1c75474ba1df706b1abb5e9c96b50f8fc18dfc5b..557d08959d2f319ce90b491672c9d4ba518ec471 100644 (file)
@@ -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)
 
index 2553762465ca78f1d31cdaf10d57f6d8279bf4c0..c7a495afc82ece5359e811c4e05a670a7b99a35e 100644 (file)
@@ -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 (file)
index 0000000..7aefa30
--- /dev/null
@@ -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) */
index 9968871103bcf79cf2b802b4c6ea9516cfdf0da8..fa6f467389db2735daf794361b481a08b40ec942 100644 (file)
@@ -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;
index bd5ffc76bc7e6774274b596ca8b43154c894ed08..0006fe9f8c7a03cab556cec5119ad5c016608e74 100644 (file)
@@ -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) */
index badc73fdcb97c261a1011db687a45a4ac88b59a5..124cf076717f25d8c3edfc1a54caae609cf6147d 100644 (file)
@@ -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
index afccfcaa9ea9228d0c744d371815266d7afe0233..732c83f04c3d29d71071b80a1061542db3023d22 100644 (file)
@@ -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_*/
index 552b7c873a5702790d913ed85a4270baa4b3455e..737401e7d3ad33a5c398577bfb465354d6e6b7dc 100644 (file)
@@ -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
  */
index cbf2669bca71505013227528f9f779c87c81492a..f367d4014b423b5298df04dfc556ff4d5aeaf3fb 100644 (file)
@@ -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 */
index ab827dc381d7f3c0afe18b37811d817b7b6e7d73..5ea84dbb1e9ce5f07278cb678f00291fbc64e0a5 100644 (file)
@@ -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);
 
index 107bd90429e86e14e47185895d9ab222be3b0652..1194888536b93736f3d2616c6cb4eddfd2803e56 100644 (file)
@@ -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;
index 3daf5b0059054994c04ba2bce41a8dfa81f701fc..05ef097ba55b26dccd45d997417228ad79a110ba 100644 (file)
@@ -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 */
index 6e7a2e976b04fc8bc8a98213522fabf5c623af02..5c8f49280dbcc273d718bfd1d9895403910a3ca5 100644 (file)
@@ -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,                   \
index e856570c068952045b73bd25a2cf45d22ed7aeb2..19f99178fe83735cc17bff14516f529c17e479c3 100644 (file)
@@ -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 */
index 6137146516d3905ef58c931f56fc7951a26ad194..777288eb7e75ecc5272599a3995874162ab4c1b2 100644 (file)
@@ -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_ */
index 2281e9399b9677ddf64211164f06d221604c542a..fd452fc2c037d7b08765905161ede0df52ccdef9 100644 (file)
@@ -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;
index d14a3755a12b96a739f88b5b99303c6b92d700f5..c7b705e66655746a2efce6fdeefbd76f128d0acd 100644 (file)
@@ -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;
index 5e1b99dc4ab3bfd93b3657182e9d43a960b19e11..411f810a55c604e0e5e5e77eede58f69dab8ddd8 100644 (file)
@@ -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
  *
index e86bae7324d2f7eac86826f6686c69f66b532977..0496d1f0995212b4c8ae873ac5e7159fcab318cb 100644 (file)
@@ -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
 
 /*
index 00c8efa95cc3ade224b9e7b61033c414f3dfb464..0d71c0041f137e09eb48c06017af91fafb84c22d 100644 (file)
@@ -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)
index 30fdcc89d14213fecec5ff69c8dfa98f7e4fa5f2..3466b1d0ffd29ca6bbd8cbed53bac00e861cc94f 100644 (file)
@@ -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. */
index 76bdaeab6f622240fe8f898a9caf0815770f7c38..711c321a70119f07b6bc1d6192caec4f64aa017c 100644 (file)
@@ -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
index cfde8b3ee9199293b17c883bd7a2292ecbad44c2..1d79b8d4ca6dcc21f2e9f80775883350eb389547 100644 (file)
@@ -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>
 
 #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
@@ -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,
@@ -678,21 +712,6 @@ static inline void blkdev_dequeue_request(struct request *req)
        elv_dequeue_request(req->q, 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
  */
@@ -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
index 7520cc1ff9e2b9d3947f3cb1ace868b329394555..b99a714fcac67adf74e85650abcfa7ecaf6ef7ab 100644 (file)
@@ -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;
index 737e407d0cd11e7479e6d38d3cf48562eec4f596..131ffd37e716fb7ac4a386eaea9ff58c26bf639d 100644 (file)
@@ -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 */
index 9760753e662b4f735583034b17a1e0ed5c24dc07..ef5cd192784c23bc326531660184c2098f930736 100644 (file)
@@ -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 */
index bea0255196c435c5c1ba986c7c9361034f36ad86..4e1663d7691e4a44c676a446d2c94374963656b3 100644 (file)
@@ -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)
index 0780de440220e43211f6f9a00cd3dc29ba77b290..538423d4a865de29981ff7a2208fb1afc77ccd43 100644 (file)
 # 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 __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 *);
index 76a1807726eb0fb24b668995eb3bd5388c3e1013..7d0420274de00d26b86d6d986631860bb158d5d3 100644 (file)
@@ -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)
index 25423f79bf9f95fbedc359de9aced4d4c99d1c23..ed6c0fee1ac76fa5af1e0ed27c26a6b6fbc86395 100644 (file)
@@ -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 */
index 65842efc1b70fba98fdeaec9b3db88491dfe161f..82c9a1f11020b2ecfd1f3947d42ac6218b50a841 100644 (file)
@@ -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);
index e3d1c33d155883797f41d33b0096e06329d8de82..03ef41c1eaac346b441a00a54048818b7f35c60f 100644 (file)
@@ -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,8 +66,17 @@ 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.
@@ -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 {
index 9623bb6250901d37e8cedfea42304b770cddc534..8853fc4d1c5ebcd3b4f56749208057935955a208 100644 (file)
@@ -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 */
index 1713ace808bfb4d581ccfff53aa4b0c42ebfa9ef..b3370ef5164d0589d3300e91162c0b5599045de1 100644 (file)
@@ -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 *);
 
 /*
@@ -124,6 +130,19 @@ extern int elevator_init(request_queue_t *, char *);
 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
  */
@@ -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
index 33a1aa10732916e222347728888b979b69c98b07..153d755376a42344d046482e7c7606dcea4bb373 100644 (file)
@@ -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
index cc08f56750da7cf7ed68c1349db063fd01a6be68..11cca1bdc0c79840ab69c12b2a538d2a9770fb65 100644 (file)
@@ -216,20 +216,37 @@ 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
 #define EXT3_IOC_GETRSVSZ              _IOR('f', 5, long)
 #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
  */
@@ -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 *);
index 2f335e966011510df9944119d33daae9850580aa..3e69241e6a81484a993a19566197abc8f19de0e8 100644 (file)
@@ -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
index 6eafbe309483a56c91ec3ae4176dc9525321d457..f53bf4ff195592bfa315677b45dc073a02d63b56 100644 (file)
@@ -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
@@ -645,7 +684,8 @@ 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 */
        int signum;             /* posix.1b rt signal to be delivered on IO */
 };
@@ -841,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);
 
 /*
@@ -1007,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 *);
@@ -1058,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);
@@ -1074,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);
@@ -1113,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 *,
@@ -1177,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);
 }
 
@@ -1443,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);
@@ -1451,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 *);
@@ -1471,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
@@ -1484,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);
 
@@ -1505,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
  */
@@ -1516,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);
@@ -1546,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,
@@ -1568,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);
@@ -1633,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);
@@ -1644,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 *,
@@ -1677,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);
@@ -1716,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,
@@ -1753,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;
 
index 74ed35a00a94db84cefdc6ddcf62715582d6006a..543cd3cd9e779eb3694bbb74ecbd585c0e14e921 100644 (file)
@@ -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
index f5975126b712261fc12e62c101630fe4856d1dde..809bb9ffc78846fbc2f8b5747ef42b225d8c4940 100644 (file)
@@ -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
index 690c42803d2e7d310e7bd59cbac2abebaa263098..9869ef3674acbfe0f1a8fbad4fd20286c092c3be 100644 (file)
@@ -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);
index e4af57e87c178ab0bff22b97b2e710e72a870428..41f276fdd185f6b16b4edb280041a23fa642440c 100644 (file)
@@ -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
index 031ed3780e45bf779a7dc3cd681c76e7b3d72f84..c7372d7a97be34a22874f38c388284640ae29512 100644 (file)
@@ -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
index 9418519a55d16e936cf593e472e953d294f68ea7..0a8f750cbede9e9c963515ca09e60f121081c05e 100644 (file)
 #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 */
index 99620451d958730a7754cf80acf572a770d75e40..07d8d725541fa5c9b26d312671fcd8b974329190 100644 (file)
@@ -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);
 
index 60aac2cea0cf63764b26d09f1f05cbc88b53e7ee..33c5daacc74338dd0d479f976892659ab308eab8 100644 (file)
@@ -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 \
 {                                                      \
        .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}}},                                       \
index b3253ab72ff7da2914e225550d1a0c3db42b6d8d..5770105471dd359eb2e2b46c70f510e4c2eac35b 100644 (file)
@@ -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
index 420e2fdf26f654a4d89b7853340783dad432fffe..aa3f5af670b579bc9de78a9d1a4075daa6c039c2 100644 (file)
 #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 */
index b291189737e747178b664d1d312e8b737442d790..d9e2b3f36c35906ee1606a8a6aebce565c30214e 100644 (file)
@@ -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 */
index d09fbeabf1dc976539384f1889299bfc2e69383e..796ca009fd468a8716cd8d6b31570bcc83ca4faf 100644 (file)
@@ -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
index 849043ce4ed6ad811d77decf3463238a1c9a6f82..1cebcbc28b474d9f7af1d4061f0e30ba60347aa8 100644 (file)
 /* 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,
index 4d00988dad039ebc5f871d6323b2b7d1676da9dc..80f39cab470a2800abd64994341f2daca6c66678 100644 (file)
@@ -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...) \
index 0db22a1ab474d94edfa5e4f79f95e3f286d7c51e..10f505c8431dc320f46d77a88095df20cb475cb8 100644 (file)
@@ -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__ */
index 8bf6702da2a0348e1ac3538ffba7f1954ceffc5b..ac4c0559f7510e16c8b2c6113964284f762fcc9d 100644 (file)
@@ -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 (file)
index 0000000..c08b52b
--- /dev/null
@@ -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
index 08a450a9dbf7dc77bd6788824e82a38f8d09e6e2..f6f301e2b0f58a5f229c62c826f810c8e1177431 100644 (file)
@@ -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 */
index b054debef2e0599f8b681690f2831589daa79bc5..81e3a185f9515ada07ef16bef6b94a619e9196f6 100644 (file)
@@ -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 */
index 0d92c468d55aeeb1f4b83e5847ef3bc5c529b2b7..47b7dbd647a63efa5e6c84b872231dc194d2c211 100644 (file)
@@ -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 */
index 8f04143ca36357e3330ae2cc23c9c9595f890c8e..654ef55448780905fbdfb31d7eda298afb805b97 100644 (file)
@@ -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 =              \
index 218501cfaeb9255ed62ca9fbf2a197cbb6993f53..7b54666cea8e9d3ea1b5c66682f2ea7a36e0fc72 100644 (file)
@@ -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 */
index 7b703b6d43582dd918a1c8c397a2a3932accf72c..b7966ab8cb6ac42ebd864c62542e01427d5b99eb 100644 (file)
@@ -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);
index 2c599175c583c36a0bbd71528640489fceb6c149..4b2d8091a4104a0cd603d64a9240d6dbdf9b5396 100644 (file)
@@ -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];
index 3ca880463c47426029bad70eb02f30ad3ab41015..cc5fb75af78a25e22c55ba868e4612e09331fbe1 100644 (file)
@@ -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
index 0b4cd2fa64aa6cf5a1b6da709b761ab8f2234fc8..70420bbae82b3b219847d0ed5f230728412a1de6 100644 (file)
 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;
index 1f4972155249887c1c70e3a2a25f42520ac2f871..6f045b586e768b16d2d9949828a6d6f2d99f5985 100644 (file)
@@ -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)
 
 /*
index 4a72818d25453205f64d7e538913885ebd1c2657..9e409fe6ded6ab76ed7d52507f47870a1bc11bfb 100644 (file)
@@ -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)
 #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)
index c6470ba006680a3d97191f7baf62c73bd3b0c96b..f5f19606effbd0c84f74007aaf25c145e76d9eef 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_NAMEI_H
 #define _LINUX_NAMEI_H
 
+#include <linux/dcache.h>
 #include <linux/linkage.h>
 
 struct vfsmount;
index 3abc8e3b4879a5eac2dd54374f0fb9b37ca9f3a7..d137009f0b2be0feb70efcffba537f899195865d 100644 (file)
@@ -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);
        }
 }
index 02e352be717e93f650743c4ca41dfe271a9027bb..0ea7f89e613c1c6f95ac5fcbb71cdbcfa5f6b9d9 100644 (file)
@@ -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,
index 98c9b9f667a5690f34072e89fbf5508c1678db6e..76ff54846ada1e07cab6ca2fa8e0de019a906e85 100644 (file)
@@ -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
index 2dcad295fecef2685ffb4121d4ea977cc6b8c279..e1dbc86c270b874e00ede638eeb8f64155d22872 100644 (file)
@@ -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
index 31a3cb617ce0b02c1129bcba8d58ff1c4bac000a..069257ea99a0fe4c92de7ccc4a993d88b35774ea 100644 (file)
@@ -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
  */
index dae0faea28070a594c49d886458e1ebc4934a477..8bcddccb6c427e81a7a7b960d1f25afaa1bb9b6f 100644 (file)
 #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 */
index 1a9ef3e627d1b6e04984688c071ed6e27fa964fd..5dce5c21822ca12bc6b3c6423352b50fcbe75b44 100644 (file)
@@ -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 (file)
index 0000000..f6baecd
--- /dev/null
@@ -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
index 5c3a4176eb64a732546e5ef6c75c61e06a7e1212..4431ce4e1e6f9fa8d27801cb88a7f9c51049d572 100644 (file)
@@ -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 */
index 93da7e2d9f30bdda2268d8163e3c9f29d73a4a4a..2c0007d172189390911779471f54db752e3dd50d 100644 (file)
@@ -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 */
index 57f70bc8b24bba1bf3f9e9336a1a10b01945778c..87dec8fe6de900da1c495175144e21f99a1bf6b1 100644 (file)
@@ -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 (file)
index 0000000..91d48b8
--- /dev/null
@@ -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 */
index 63df898fe2e95dcf092a3ac5dedeb76b431f8122..84d88775185556e4d2a8a6b0560bcfc9c202038a 100644 (file)
@@ -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);
index eb3e547c8fee37798521949cc4f341df352a6d6d..866a1e2b0ce049fd991f3e85d52bdeea3b82d520 100644 (file)
@@ -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 
 
index d28890295852ce4f9be9f6bf0c6529f7b81041e6..8245c282168b4a436884653c61eda6a1490d83eb 100644 (file)
@@ -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)
 #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
 
index 81da20ccec4dadeab0dd13da2ac94b7e7f48243e..7192035fc4b0680094f3c4f0c2780a79c20dfd1b 100644 (file)
@@ -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)
index 3009c813d83d33d2748804d4db1081bce811cb5f..0a9ba7c3302e2393e881244983a3397807e29dfb 100644 (file)
@@ -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;
index c41e56a7c090801f401f97e116986204a5fb728d..e9091cfeb286c2a9b0d30dc57e6748933bb3a9ee 100644 (file)
@@ -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 */
index 20ed4c997636fac9b92aa003a982c5c641d1a45d..f13299a15591ed6170bb440495b69edd6262104a 100644 (file)
@@ -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 */
index 00b340ba66127131b5f4a3790d649b1bc33c5256..b160fb18e8d6ce6f724827fe19fd31dfe748ddb8 100644 (file)
@@ -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
index 8d5382e62c08e8503f5e43e2e62b7215df2dd26b..344bc3495ddbd12548c32ebaf57cd3c6ee7e8be9 100644 (file)
@@ -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 *);
index 28493ffaafe7b26e1dfec49fab09333658702d3e..7bc6bfb86253899c9ad088ffa39e9f4c81c71147 100644 (file)
@@ -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
index 31b4c0bd4fa000e94a32f5b8b5f99c9211f68f4e..73e0becec0866d39664b79cae596b712e811b2fe 100644 (file)
@@ -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 */
index 5371e4e745958f37e67cba09db7eaa9e49a2ada0..b89f09357054ff13414eade0f14dc0748e98f925 100644 (file)
@@ -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);
index a06fc89cf6e5b8778c93ca53ebbb733948448948..331f4502e92bb6540f407d2c1d735c693a28edd9 100644 (file)
@@ -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);
@@ -239,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
@@ -624,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 {
@@ -643,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 */
@@ -710,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
@@ -755,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,
@@ -898,8 +908,8 @@ struct task_struct {
        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;
@@ -982,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;
@@ -1021,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.
@@ -1044,6 +1074,8 @@ 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)
 
@@ -1248,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 *);
@@ -1266,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)
@@ -1359,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),
index 6348e8330897c3393a88e937ef7ae167c767faca..c9069310b6acc531242a64210743b471639fea77 100644 (file)
@@ -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
index 8669291352dba326e952d0f2a02e5e2a552101b8..679ef0d70b6b1bae44fb4d9a60af100b1ec2d8fb 100644 (file)
@@ -57,7 +57,7 @@
 #include <linux/time.h>
 
 struct kstat {
-       unsigned long   ino;
+       u64             ino;
        dev_t           dev;
        umode_t         mode;
        unsigned int    nlink;
index ea65dfb60cd80e19d2a5a1ce9a5f00194017e4c0..6a40c76bdcf1a7732d71675d888e722aa0dc578c 100644 (file)
 #endif
 
 #ifdef __KERNEL__
+
+enum {
+       false   = 0,
+       true    = 1
+};
+
 #undef offsetof
 #ifdef __compiler_offsetof
 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
index e4c7558603167bfffd23cc6966c0d88cb7b45b04..4f69ef9e6eb5098ddafc6ccee368c08af2efd98f 100644 (file)
@@ -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
 }
index 73140ee5c638ab631916ecf6fb697da58384693d..4ebcdf91f3b3dcc078e7fadf6313dd23dc4175fa 100644 (file)
 #include <linux/wait.h>
 #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.
  *
@@ -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,10 +62,35 @@ 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
@@ -127,11 +174,13 @@ static inline void svc_putu32(struct kvec *iov, __be32 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 */
@@ -180,6 +229,7 @@ struct svc_rqst {
                                                 * to prevent encrypting page
                                                 * cache pages */
        wait_queue_head_t       rq_wait;        /* synchronization */
+       struct task_struct      *rq_task;       /* service thread */
 };
 
 /*
@@ -320,21 +370,22 @@ struct svc_procedure {
        unsigned int            pc_xdrressize;  /* maximum size of XDR reply */
 };
 
-/*
- * 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 */
index b4acb3d37c3f2556e2b5f01efe587c94c6b8cced..4c296152cbfa71ecdb52efb98e2586454a9b1e30 100644 (file)
@@ -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 */
index 0577f5284cbc9c4f73beb031d9c53834456f354c..c8b042667af1fb70e1326bbec1c0b7b8474017f5 100644 (file)
@@ -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
  *
 
 #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
index 2d1c3d5c83acc150d9838c881d4d22d79509fc4b..3efcfc7e9c6c705a7e9c42f93c1ed0369fddb3cf 100644 (file)
@@ -599,4 +599,6 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
                                    size_t len);
 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
index 4812ff60561cb44cf66625691059dee49fce6347..e657e523b9bf62b7a6f0d51850e3b9d3292c64fc 100644 (file)
@@ -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 */
index f1cb6cddd19d70959c966e0faaca16de4dcac457..45248806ae9c5916a416102d9bd1a8c9b54a03a2 100644 (file)
@@ -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
  *     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 */
 };
 
 
index d543d3871e3867d91ff7b5b93497927a00071332..049dfe4a11f2a520399314b50bf3664044b01c46 100644 (file)
  * 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 */
index ec1eca85290ade96c5f42da4d74acac2a8ae2407..da508d1998e413714ee788a4602d2a6478dba96d 100644 (file)
@@ -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,                    \
 #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,                    \
                                | 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,                    \
 #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(), \
        .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/tsacct_kern.h b/include/linux/tsacct_kern.h
new file mode 100644 (file)
index 0000000..7e50ac7
--- /dev/null
@@ -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
+
+
index ea4c2605f8da8836128fd2e2f4fe7e712d536ee5..44091c0db0b46b473234172a91d983319648e7ce 100644 (file)
@@ -307,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 */
index 58c961c9e1707027fe8989bfa821c78121fdb183..5c8473bb6882e7cc4f7dfe03a33072e94f6bceb2 100644 (file)
@@ -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
index 3f235660a3cd6a76c4fa0480e649deaa5a4077d3..406d4ae57631709542ad5097b1aba9216fa2a4c3 100644 (file)
@@ -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;
index 7168302f98441ea9da3c42c931ea40a23bfec5b1..1fd61eeed664c6958e4595aa455f4c3228807712 100644 (file)
  * 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
index c18c60f3254ec998d33222aa1bd226c1f6314441..aa8d5b5e2e3e0b35b94df5824115640f972ce1d8 100644 (file)
@@ -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>
 
index ce48e2cd37a28d52c1e15e8497e4b3c74da769ab..73e1751d03dd18e2806d4a018c05f9cf05eaf942 100644 (file)
@@ -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
index c6bf27b7897e79e279446fb2ef9aa887f4b34488..640be6a1959e8074ad79bce56ef71ecbeb779053 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _LINUX_UTIME_H
 #define _LINUX_UTIME_H
 
+#include <linux/types.h>
+
 struct utimbuf {
        time_t actime;
        time_t modtime;
index 13e1da0c538d209871bb1099169004aa24d52072..02e4b69720645e5a15a04b8f74d0a78b69638b00 100644 (file)
@@ -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
index e3715d7741977715a34326940033a674fd0b8b15..44c59da26ed2673c10c62fc54e50712cd6f3cff5 100644 (file)
@@ -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 _IO ('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)
index 1009d3fe1fc214e8eb920e207483ebdd7d35f1b3..37a1a41f5b65cbd06a0e71ccb17c3304160a9594 100644 (file)
@@ -84,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 */
index 9d4074ecd0cdc95248fb42dd4dde5b421f152518..4f4d98addb448afb61cd3d49b4a2a8cc3a00cbea 100644 (file)
@@ -111,6 +111,8 @@ 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);
index 7bab09b0ed451ae2f1f1569ceeaeb3ce2b8ab52a..8f58406533c64c6b1ae0fb6ebd0343783963dcd8 100644 (file)
@@ -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
 
index 3c43b95f4c0dd5062b07b5d3864027b0ca0aff89..37dad07a8439434c26127c2c766ceb8b2c03354f 100644 (file)
@@ -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;
index 2f7b00b08e8817224c5827ab09e7f13bd376d883..3116e750132f2e7575e07d2caced3b21bdf34bdb 100644 (file)
@@ -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__
 
index 5564db13c0d5f1d1897dadb20309c1d06219480a..aecc946980a3a7da00ce0f7b90fbaf70248bf7a1 100644 (file)
@@ -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
index bb495b7f4680b112b96d82bad4a8320a29e91b11..6a11d772700ff649e9a1d81b47db9f8622af3594 100644 (file)
@@ -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 */
index 13e7a3c6d79476274c3eb993da753f94ba08b864..e0fe92b03a4e1141c297d6d741c26fa7d59f001d 100644 (file)
@@ -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
index b0a67b7ffdcd2697b1b281c4b3ff1c1733214216..f913c30d7b8976754e4c0008eb5c2db8eca44e08 100644 (file)
@@ -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;
index 4a38d85e4e25d13534b2840809f62a8e62822bef..b619314218a6368ea50dbad83a1208b21cc23312 100644 (file)
@@ -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 */
index edd4d73ce7f5cb4371430942bc542c4c72df84a1..40bb90ebb2d1b24e11134b08c21ab47f59f68e75 100644 (file)
@@ -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;
 };
 
index 895d212864cd99bafaaa0240e17b915133beaad1..b401c82036be216edf1dadf0f1ce01c0b1301891 100644 (file)
@@ -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)
index d04d05adfa9b68ca1ccd08e231a81996a316c714..c247a28259bc77fa453994b3492a457f8b99bb7c 100644 (file)
@@ -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 */
index 60d40b34efc0fb79241b08ffaf25a876a563c4ba..afaf3e88e086c8712c7cdf8b4d743e1e3674bd97 100644 (file)
@@ -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;
index 3570f9c9b1112be92a4e5b409abf5d6a5582d038..5dbf5e7e50a8c1c659261b796f7985150e6e9637 100644 (file)
 #  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))
 
index 4381006dd666aaba6f9d1e29913d65fe5c3e5a8c..10382931eead561940c023bd1b376863b9b11dab 100644 (file)
@@ -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
index b290aadb1d3f2a0b1448a06df90bb05f75aed42f..dc1ec0803ef9b93b76c27b9db3a9d3e741f98280 100644 (file)
@@ -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
 }
 
 /*
index a06f037fa000a932d9de7b6f8dee909e5ce01720..919a80cb322e6f57dfa2be0a3bb727251bcd7e0e 100644 (file)
@@ -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)
index 2429e1bf8c60a1277edaed473760cfad8e486a1f..753dc54a664972ff0ae441ab8945c1345d563c2a 100644 (file)
@@ -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;
        }
index 0766e69712b2a86efa74caf3c5bd487bbbcd3753..ee123243fb530b4d4e589f731c5bfa4652148dc8 100644 (file)
@@ -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();
index e290802c6bd2c4920245d82cbe7b549a78cd1593..8f28344d9c70fda49300ac1455e98e086913b481 100644 (file)
 #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 "@"
index 840f8a6fb85ff1e98ee37774df42ea748465eff6..c45ae86cec31efba043d21d531c6e64f4bce5fc5 100644 (file)
@@ -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);
index 2b4fccf8ea55a9a2babc5f92b36fcdf6a1dd5a7d..5b213d952545e82684dc1d3f212f311ad3348790 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
  *
  * 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>
 #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 (;;) {
index 6013c751156fe81bee30536bef27bab7792eb1bb..0dafcc455f920888fe13a474b926ad0bd6825a11 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
  *
  * 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>
 #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) {
index 940b0c9b13aab7c33159760bba2a3a53756779dd..bfbd317ec11c0be1a73bc85b82d37ee3bbf33dd3 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
  *
  * 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>
 
 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;
index 67b6d178db6e17d95b54e84b75361aec9a0544cc..42479e4eec5935b808a198acd34285dae69f2618 100644 (file)
@@ -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>
 
 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)
index 0181553d31d85d4c3c9c85e712e3db1d17d63e1a..c8fd6b9d77b5e0bfddcae8b2bbf5f40d6ae4ea03 100644 (file)
@@ -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);
index d62ec66c1af28246946d9a21a52f5fc6df706701..d948ca12acf0e5b3ad113ec77680067f42923ada 100644 (file)
@@ -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
index f4330acead468a8cd228d0249918dbd748e7fbf2..0aad5ca36a8125e205e85978aa32e8712ddc957a 100644 (file)
@@ -602,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;
-}
index 8c3c400cce91f4a679e0d034380ca16065b296a5..9d850ae13b1b61e763d09fc8231c33d1d6e43139 100644 (file)
@@ -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;
        }
@@ -1565,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;
@@ -1598,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);
@@ -2033,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;
index aef0a45b7893db2c7a5a2c94f67da7618e181bc9..2020644c938a48d0f34670765e788b32fed8900d 100644 (file)
@@ -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) {
index 2e4c13cba95ae7af79bc373a859ecac42a340225..f250a5e3e28151d293741a6604938d49c9336feb 100644 (file)
 #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>
@@ -395,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);
@@ -915,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);
@@ -930,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;
index 1c999f3e0b47f02a4fd805daf90f9b914c44282b..7dc6140baac69325f1ce2fa08fa9bd858aa57258 100644 (file)
@@ -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>
@@ -1115,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;
        /*
@@ -1211,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) {
@@ -1259,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:
@@ -1513,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;
 
@@ -1588,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_*
@@ -1605,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)))
@@ -1628,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;
@@ -1640,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;
                }
 
@@ -1666,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);
index 4b6770e9806d0c080ef5f9bd542ddb778ddbcff2..4aaf91951a43959be9d448b66fe7538d46f7d244 100644 (file)
@@ -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;
                }
index ab16a5a4cfe9ba4c1e3009f136e4c6d11a8cffa7..eeac3e313b2bfa41f26a4ccd9235232593fb947c 100644 (file)
@@ -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;
        }
 
index 842f8015d7fd2e6c7bc07f86b9b6766b13864539..bb4e29d924e4ff29567a962e7b643e0c1c875896 100644 (file)
@@ -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;
@@ -268,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");
index 3f57dfdc8f92ba2d60e0b49af23ce6823d0598f1..610c837ad9e0aa8923f48541aaa7ea903c6b2fd2 100644 (file)
@@ -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>
 #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 (file)
index 0000000..258f255
--- /dev/null
@@ -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);
index e596525669ed4fa5018ee452c7bc429b945f8d00..4c0553461000360e4f4cb459bde0d289f9f89b97 100644 (file)
@@ -518,9 +518,9 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
 
 static void print_kernel_version(void)
 {
-       printk("%s %.*s\n", system_utsname.release,
-               (int)strcspn(system_utsname.version, " "),
-               system_utsname.version);
+       printk("%s %.*s\n", init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
 }
 
 /*
index 05625d5dc7583ac5567d3deec22ebd95c57b72bc..7f60e782de1e49fdfbcc96374e39898920cea94a 100644 (file)
@@ -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;
 }
@@ -1339,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;
        }
 }
 
@@ -1618,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)) {
@@ -1711,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);
@@ -1760,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
 
@@ -2032,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);
                }
        }
@@ -2226,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 (file)
index 0000000..6ebdb82
--- /dev/null
@@ -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);
+}
index 6ceb664fb52aec50c9c2d922c5c8cf17ad5979b2..525e365f72390bb3fb4601c0be4c4bd81214eceb 100644 (file)
@@ -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;
index 8387e8c681938a968ae005f52c58fcdf11ab17c3..b914392085f9a171f08a3e202dc14145e1563929 100644 (file)
@@ -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;
@@ -302,6 +335,26 @@ struct pid *find_get_pid(pid_t nr)
        return pid;
 }
 
+/*
+ * 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
@@ -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),
index 1b84313cbab5ad973d69dda99006d8439316af7d..99f9b7d177d6a843f5bcb3ade50e67379e169013 100644 (file)
@@ -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);
index 9db38a1a75208cb36bb8c68cd51f6ba7b293ce5f..6de60c12143e63f539701c3bc1687f3f21d0df9d 100644 (file)
@@ -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);
 
 /*
index 74f169ac0773cd2ac3eeac0bfbb3c3a631d70c65..53608a59d6e3c0fd3d0b18dbf919beb9b0125397 100644 (file)
@@ -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) {
@@ -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;
 
@@ -4384,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)
@@ -4814,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;
@@ -5389,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;
        }
@@ -5423,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;
@@ -5445,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);
 
@@ -5458,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)
@@ -5486,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;
 
@@ -5505,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);
@@ -5972,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)
@@ -6081,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;
 }
@@ -6092,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
@@ -6134,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);
 }
@@ -6166,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
@@ -6208,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);
 }
 
 /*
@@ -6230,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;
@@ -6265,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");
@@ -6279,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
@@ -6289,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
        }
@@ -6356,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
 
@@ -6368,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
 
@@ -6382,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 */
@@ -6461,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
@@ -6534,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);
@@ -6560,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.
@@ -6744,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)
index fb5da6d19f14eef721f28750307c9654f17a8bfa..7ed8d5304bec2d2c9e51099f5c66ff304d40946a 100644 (file)
@@ -1055,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)
 {
@@ -1089,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;
@@ -1101,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);
@@ -1111,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;
@@ -1122,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;
@@ -1146,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).
@@ -1264,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)
 {
index d48143eafbfde6388717e67c1c3b74011ea8a747..476c3741511b31af1717f90e052880e0e6c9b585 100644 (file)
@@ -215,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;                                         \
 }                                                                      \
@@ -237,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;                                                   \
index 8647061c084a6d67b6a484b5287656306f52049b..2314867ae34f138a80daf20e6ed930ef731d8f6e 100644 (file)
@@ -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,11 +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);
-       }
        machine_restart(cmd);
 }
 EXPORT_SYMBOL_GPL(kernel_restart);
@@ -627,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();
@@ -775,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)
@@ -823,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();
        }
@@ -857,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();
                }
@@ -900,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();
        }
@@ -957,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();
        }
@@ -1008,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();
        }
@@ -1054,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();
                }
@@ -1105,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();
                }
@@ -1151,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();
                }
@@ -1182,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();
                }
@@ -1321,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;
 
@@ -1353,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;
 
@@ -1363,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;
@@ -1431,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);
@@ -1489,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;
 
@@ -1647,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;
 }
 
@@ -1658,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;
 }
 
@@ -1675,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;
@@ -1693,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);
@@ -1710,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;
@@ -1739,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);
@@ -1775,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;
 }
@@ -2083,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;
 }
index 6991bece67e8e7609e5d18920183246e0e007143..7a3b2e75f0402122ced8b15d5488a6b9de49ee8e 100644 (file)
@@ -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);
index 9535a38399307130b0a1f5728fbfece8333d3d93..8020fb273c4f1d0ddce105037bc7803b3c98331a 100644 (file)
 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
@@ -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)
 {
index 2ed4040d0dc56423fa73ec0105c226357528f18e..5d6a8c54ee85f56f9a3640480d5560ed35f2b4e5 100644 (file)
@@ -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);
index 5bd489747643c9e9dced9316cd372bba8f81a9e1..0e017bff4c19e77daeb657669618c757399dde03 100644 (file)
@@ -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 */
index e1dfd8e86cce145131de4021a226df60d3acd61f..61a3907d16fb5caa0ef0391b3e52b70a08a6844e 100644 (file)
@@ -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 (file)
index 0000000..47195fa
--- /dev/null
@@ -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);
+}
index 4f55622b0d38462ad59b28322d31ebeee8a0c40c..c1c7fbcffec1615e84a380c2994659cde6216947 100644 (file)
 #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);
@@ -568,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 
@@ -587,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>
@@ -966,10 +751,13 @@ 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);
 }
 
@@ -980,7 +768,7 @@ static int timekeeping_suspended;
  * @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)
@@ -1149,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();
@@ -1230,9 +1016,6 @@ static inline void calc_load(unsigned long ticks)
        }
 }
 
-/* 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.
@@ -1270,7 +1053,6 @@ void run_local_timers(void)
  */
 static inline void update_times(unsigned long ticks)
 {
-       wall_jiffies += ticks;
        update_wall_time();
        calc_load(ticks);
 }
@@ -1775,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 (file)
index 0000000..db44322
--- /dev/null
@@ -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/utsname.c b/kernel/utsname.c
new file mode 100644 (file)
index 0000000..c859164
--- /dev/null
@@ -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);
+}
index f9ae75cc014566b95609983b803e0ef6282723f8..756a908c441d28710e773e15b7b619191f9efdcd 100644 (file)
@@ -384,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
index 402762fead70f6b8e8384b84d85f89d70e7d63f1..b0361756e22e2ff0801a12e4291b7d51a22305a8 100644 (file)
@@ -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
index 3a67dc5ada7d5b2655ae461890519e995d50d7c9..7a2a73f88d594dc73282c24e3d0304a602a10a25 100644 (file)
@@ -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 (file)
index 41cb9d7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- *  linux/lib/errno.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-int errno;
index 71338b48e88919ab2a668ecf2ff9f1e25a91b0fa..75ae68ce03e10be0596a1a86956360bf9fc012bb 100644 (file)
 #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 (file)
index 0000000..99fa277
--- /dev/null
@@ -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;
+}
index e80d27c9789820d867139428650d6cbd88812165..7ba9d823d388665cdef6cb647a13cc0bd41ddb75 100644 (file)
@@ -59,9 +59,6 @@ EXPORT_SYMBOL(list_add);
  */
 void list_del(struct list_head *entry)
 {
-       BUG_ON(entry->prev->next != entry);
-       BUG_ON(entry->next->prev != 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);
index 1e55ba1c2edfac510c41c87e47e7849f99a5f3b3..48499c2d88ccf16d65c8891e3fc5a23e8cdf283a 100644 (file)
@@ -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) {
index 5f3b51ffa1dc2a6897b09b42cee81ef2870b9ec8..488788b341cb01960b92163b9326ec85c2a33445 100644 (file)
@@ -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)
index 8f5b45615f7bf1b43c35253b8f28f1ef4871818e..5d88489ef2de39e43245aa5483daa8af4a8a9452 100644 (file)
@@ -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.
index 6200c6d6afd20812acd95af4409b2467dd3a1f6f..12b3a4eee88d56a3b4d4fe6c4255fa4a1ca81352 100644 (file)
@@ -12,6 +12,9 @@ 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
diff --git a/mm/bounce.c b/mm/bounce.c
new file mode 100644 (file)
index 0000000..e4b62d2
--- /dev/null
@@ -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);
index 3277f3b2352441eb6d0a5e4d8caf8437bab16460..ec469235985d6e2cd89d39bf8bd40405f133e142 100644 (file)
@@ -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;
@@ -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);
index aa30618ec6b2cd356c57896a2099a3e4b2a5e39c..7a9d0f5d246da922c132738f2476a688812fc1ac 100644 (file)
@@ -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;
 }
index ee5519b176ee9a2fc704e9af51f4f26836b53df1..0206e7e5018c8998c87349706fe1fcfb5644933c 100644 (file)
 #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
index 160f5b503eaddeb5880cc0c4ac63c08821074e5c..9cf3f341a28a6cf4c53af58f01959a9cf7c23eb1 100644 (file)
@@ -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;
 }
index 2053bb165a21a81d4d32fce38a1cd528981d197d..fd678a662eae1a015ef6393c2b6f23e586592105 100644 (file)
 
 #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;
@@ -47,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;
@@ -196,6 +223,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
        writeback_set_ratelimit();
        return 0;
 }
+#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
 static pg_data_t *hotadd_new_pgdat(int nid, u64 start)
 {
@@ -225,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)
 {
index cf18f0942553554ae4977958dc06109335eb8abd..25788b1b7fcff4b6d116dffab3abe6e1ecc17d08 100644 (file)
@@ -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;
 }
index 20a8c2687b1efea5b7bb1ab23d6b9195a2e97453..ba2453f9483dfe4b03b3df1c089607da36ebb60c 100644 (file)
@@ -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;
 
index 955f9d0e38aa3f5f35d09eb2473ce3f565196292..3b8f3c0c63f3b948cda9edca535d7aaa65b4a38b 100644 (file)
@@ -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);
 }
 
index 7c15cf3373ad0d0e94ba6f5b74145339da0052d3..9c769fa29f32aff451ef6ff86ce836c1fc0bf856 100644 (file)
@@ -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);
index 564540662192290b67f4a000c969407c404e86ad..365019599df8556c23d493f007a07dbf201add00 100644 (file)
@@ -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;
index 488b7088557c549840b7cf6cf9daba1efc38bd44..c0d4ce144dec41130e552723c5b3ecd4dca1876a 100644 (file)
@@ -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
@@ -550,6 +552,139 @@ void __init page_writeback_init(void)
        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;
@@ -672,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))
index b96de69f236b22225c4dcb9221d807808a7c8945..bb8ca7ef70940de154adfcbb7f30debd3f3c3737 100644 (file)
@@ -1379,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;
@@ -1715,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;
 }
 
@@ -1750,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);
@@ -1772,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;
 }
@@ -1782,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);
 }
 
@@ -1804,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;
index a654928323dcc4459cf33b59f67be5868d5b105d..f4edbc179d14423e1f3acf9555b96bc9795b37bc 100644 (file)
                                   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;
index 7368479220b3b4c3d8c12a9306bb18221d9a99b9..e14fa84ef39a2df08b2087259c110851bfcf1bcc 100644 (file)
--- 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
  *
index 26f322737db0c83702267b25190dca8fa925c324..1958ad1b8541e57be7f32bb70b2b19a242884dce 100644 (file)
@@ -1011,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,
index 1fbb38415b193e66f487a5eb8aef1738df866661..f8ce8475915966c7d10abbec1542f71b1ac10d0d 100644 (file)
@@ -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:
index 6ab57d72b615b32ff875a52c0b5ad7a58db3c2d4..91a075edd68e379fc8fcad685ac1ecd53c4801b7 100644 (file)
@@ -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) ||
index dab37d2f65fcf09a820bce52300d7f335ab5066c..4be336f17883ca21e129fd93a146d6e73c338fb1 100644 (file)
@@ -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),
 };
 
 
index 3bcdb467efc5658dd525d924acfd3faffd2adccb..d50a02030ad72dbf1598a87d24812203241a36a4 100644 (file)
@@ -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,
index 465efc86fccf1f253cf93a4e5705017e6e1dd83d..94b2e2fe6fdb97ec548956f1d247d5da8ad4c70b 100644 (file)
@@ -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 */
index 1bc4167e0da8da20c2364c14ea48b73a0cca28df..6c9b9b326d764991f4687b9a2799f6c245448834 100644 (file)
 #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:
index 124ff0ceb55b2ee20ce47d6f3358a966de37ddb5..78696f2dc7d6d402ef200f140f897388ce383db1 100644 (file)
@@ -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:
index 700c6e061a044fc77eee9a17db6151f58bdd2c9b..9a0b41a97f90764f84636811137a76cdfff5ac3b 100644 (file)
@@ -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:
index 26c0531d7e253739d5e0a7b9f38225ac0e311da6..192dff5dabcbc76258a378179d7132f5e3845bf8 100644 (file)
@@ -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);
index 44b8d9d4c18a7d09e5929688e45eab41cdc60ef8..a99e67b164c1a2dec4b8cf1ded5dacd97d634ae8 100644 (file)
@@ -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>
 #define RPCDBG_FACILITY        RPCDBG_SVCDSP
 #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,13 +684,14 @@ 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;
        __be32                  *statp;
        u32                     dir, prog, vers, proc;
index 1020d54b01d074a7fd8c1d25976a7d9fe800935c..40d41a2831d75bb1dc4d710212e742bb62fa3033 100644 (file)
@@ -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)
index 5b0fe1b66a23d5fbed578179268bedc15eae52c2..cba85d195222e9603be9c29c68628b113fd5582a 100644 (file)
@@ -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>
 
 /* 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);
 }
 
 /*
@@ -428,6 +452,51 @@ out:
        return len;
 }
 
+/*
+ * 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
  */
@@ -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.
@@ -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);
-               rqstp->rq_sock = svsk;
-               svsk->sk_inuse++;
-       } else if ((svsk = svc_sock_dequeue(serv)) != NULL) {
+       spin_lock_bh(&pool->sp_lock);
+       if ((svsk = svc_sock_dequeue(pool)) != 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;
@@ -1300,6 +1358,58 @@ svc_send(struct svc_rqst *rqstp)
        return len;
 }
 
+/*
+ * 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.
  */
@@ -1434,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);
@@ -1473,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) {
@@ -1484,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);
@@ -1518,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;
@@ -1548,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,
@@ -1561,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;
 }
index a234e524a4901ad05c11a818575ed23e82c1e265..a1f52cb47200990d9da983c204319954ff4e0a18 100644 (file)
@@ -5,3 +5,4 @@ conmakehash
 kallsyms
 pnmtologo
 bin2c
+unifdef
index ea41de8fb7f57c09d6ff2297a5ee985077fd695f..1c73c5aea66b06bcecff315356abcecc2a79522f 100644 (file)
@@ -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
index 4b2721ca97da3af2e51e58392acdb8c6fe674b84..6c5469b1473bee648984676165942cebed2b5971 100644 (file)
 # 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
index a90d3cc76bfaf7839eef3e480b0558a5431251ab..7e7e147875bf0d01b453a65f2b037dcae20ef345 100644 (file)
@@ -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 \
index 69f96b398c22848d39d31907adb43505884a361a..66b15ef029313468b3918a3dcf89ae1dd65c9aa2 100644 (file)
@@ -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 (file)
index a8b0263..0000000
+++ /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
index 79886413b6d52736689e29f8b5a5cd8e4a9c7532..cf697080ddddd4bf47df0057f860ef681255ea29 100644 (file)
@@ -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 (file)
index db071df..0000000
+++ /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];
index af3cf716e2156ca4c9dbada932497af069d230a6..8dea47f9d3e49a36803ed4c90223d9858a83d3de 100644 (file)
@@ -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)
 #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);
index 779503726b0a77b9eb08ab3f3b9d7abc921415a7..05e72066b35987dfe7037f6abd2fe29a03cb016a 100644 (file)
@@ -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 (file)
index 79f6c5f..0000000
+++ /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);
-}
index bf8052f4fd4ab73c80cfd2040ed69d4562e456e0..0d83159d90127a1dad38be99edff1a0973353a33 100644 (file)
@@ -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 (file)
index 7323f54..0000000
+++ /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;
-}
index 77848bb8e07f8795fbffeebee7980a0ee1adc269..fabfc1ad789d674f5f91637cba70cbfc335431d0 100644 (file)
@@ -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);
 }
index f82cebb9ff06d718f758f24f5674a671c17a36e1..ebc781b493d7c8a86ca7d95bae7f943bbb5430a9 100644 (file)
 
 #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,39 +268,21 @@ 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.
  */
@@ -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);
+}
index cb2568aae3ed7609a68dd04a81750e3e7c52ab2c..ee0a04e3e012ecd4ba119cd153d96a08ded7b2a2 100644 (file)
@@ -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 */
 }
index 7f973195e79a05b5eaac232030b9fdcc12993b52..08a4c7af93ea0ffd9d19b9efcbf02572d7fb94ac 100644 (file)
@@ -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"
index 49ee5152939674349e4174025b78ed2769be731a..9b16e14f3a80e8faa6ad2bc5efe53d100e3d29a0 100644 (file)
@@ -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;
 }
 
index bab7b386cb8dee7cd21a1fe21f9741960d34f59c..cd244419c980b2ef7cfd2df7ce4e4bdae252ccb2 100644 (file)
@@ -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;
 }
index 3ebc34919c76fc746a12643135b73d9c0f5b2435..a444bfe2cf7417245014562a20b06791006dbaab 100644 (file)
@@ -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");
index bf8f412988b8ead58fe147d102c006fda12b78fb..fbbbcd20c4cc7d6001163631dbfa15b55900e56d 100644 (file)
@@ -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;
index 0224c70414f516a9666966f38c4b83aa0d5e44e4..37b4b10850ae0358cdbbf654fffd6754aa5a11d4 100644 (file)
@@ -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,
index 3f81b79afbaaa23145d429ce482b39a09ffbed94..43193581f836f3d923cfb2cae57e799e1351e01f 100644 (file)
@@ -2982,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 */
 
@@ -3008,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);
 }
 
        
index eb5ea32fd1b0ffde2b44b75413664323eaf7f04a..3edf8d4ac9987d3909de91a5a48db4d2818656af 100644 (file)
@@ -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) {
index d4844de0c3b7200aa74cb3cab286c083c80e8d63..147c816a1f2293914ba3b902dd987180ecb40cae 100644 (file)
@@ -1862,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);
 
@@ -1978,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);
 
@@ -3269,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);
@@ -3284,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));
@@ -3490,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;
 
@@ -3507,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;
 }
 
@@ -3517,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));
@@ -4103,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;
 
@@ -4114,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)
@@ -4393,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;
@@ -4547,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;
@@ -4597,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");
index 08d8c94d01b21d42073bb84728bd46866f395115..2fec42fc348284bd6a4c20d2ba1aadbf781e51c6 100644 (file)
@@ -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");
index 7ec5b63d0dcec008b0a7200ca5d57cef4ae42438..97e42e1151476cdafbb40ac83a6d09b2798bd704 100644 (file)
@@ -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);
 
index 49248fa7aef47adaa9884aada5ebf593f8838d72..a42acf6d7b68962b22b17061eebf1090abcc88e3 100644 (file)
@@ -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;
index abe29dadd979365e01d1458ac00531dd292d1984..0dcf78adb99a879365b5949e9c9092076d120508 100644 (file)
@@ -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);