Merge branch 'master' into upstream
authorJeff Garzik <jeff@garzik.org>
Sun, 1 Oct 2006 03:55:03 +0000 (23:55 -0400)
committerJeff Garzik <jeff@garzik.org>
Sun, 1 Oct 2006 03:55:03 +0000 (23:55 -0400)
1500 files changed:
CREDITS
Documentation/CodingStyle
Documentation/DocBook/kernel-api.tmpl
Documentation/SubmitChecklist
Documentation/SubmittingDrivers
Documentation/SubmittingPatches
Documentation/cpusets.txt
Documentation/fb/intelfb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/proc.txt
Documentation/hwmon/it87
Documentation/hwmon/k8temp [new file with mode: 0644]
Documentation/hwmon/vt1211 [new file with mode: 0644]
Documentation/hwmon/w83627ehf [new file with mode: 0644]
Documentation/hwmon/w83791d
Documentation/kernel-parameters.txt
Documentation/networking/pktgen.txt
Documentation/seclvl.txt [deleted file]
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/time.c
arch/alpha/mm/fault.c
arch/arm/Kconfig
arch/arm/Kconfig-nommu
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/common/icst307.c
arch/arm/common/icst525.c
arch/arm/common/locomo.c
arch/arm/common/sharpsl_pm.c
arch/arm/configs/ep93xx_defconfig
arch/arm/configs/iop32x_defconfig [moved from arch/arm/configs/ep80219_defconfig with 66% similarity]
arch/arm/configs/iop33x_defconfig [moved from arch/arm/configs/iq80331_defconfig with 74% similarity]
arch/arm/configs/iq31244_defconfig [deleted file]
arch/arm/configs/iq80321_defconfig [deleted file]
arch/arm/configs/iq80332_defconfig [deleted file]
arch/arm/configs/s3c2410_defconfig
arch/arm/kernel/apm.c
arch/arm/kernel/debug.S
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head-nommu.S
arch/arm/kernel/module.c
arch/arm/kernel/process.c
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/mach-at91rm9200/at91rm9200.c
arch/arm/mach-at91rm9200/board-1arm.c
arch/arm/mach-at91rm9200/board-carmeva.c
arch/arm/mach-at91rm9200/board-csb337.c
arch/arm/mach-at91rm9200/board-csb637.c
arch/arm/mach-at91rm9200/board-dk.c
arch/arm/mach-at91rm9200/board-eb9200.c
arch/arm/mach-at91rm9200/board-ek.c
arch/arm/mach-at91rm9200/board-kafa.c
arch/arm/mach-at91rm9200/board-kb9202.c
arch/arm/mach-at91rm9200/clock.c
arch/arm/mach-at91rm9200/clock.h [new file with mode: 0644]
arch/arm/mach-at91rm9200/devices.c
arch/arm/mach-at91rm9200/generic.h
arch/arm/mach-at91rm9200/gpio.c
arch/arm/mach-at91rm9200/irq.c
arch/arm/mach-at91rm9200/pm.c
arch/arm/mach-ep93xx/Kconfig
arch/arm/mach-ep93xx/Makefile
arch/arm/mach-ep93xx/edb9312.c [new file with mode: 0644]
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-iop32x/Kconfig [new file with mode: 0644]
arch/arm/mach-iop32x/Makefile [new file with mode: 0644]
arch/arm/mach-iop32x/Makefile.boot [new file with mode: 0644]
arch/arm/mach-iop32x/glantank.c [new file with mode: 0644]
arch/arm/mach-iop32x/iq31244.c [new file with mode: 0644]
arch/arm/mach-iop32x/iq80321.c [new file with mode: 0644]
arch/arm/mach-iop32x/irq.c [new file with mode: 0644]
arch/arm/mach-iop32x/n2100.c [new file with mode: 0644]
arch/arm/mach-iop33x/Kconfig [new file with mode: 0644]
arch/arm/mach-iop33x/Makefile [new file with mode: 0644]
arch/arm/mach-iop33x/Makefile.boot [new file with mode: 0644]
arch/arm/mach-iop33x/iq80331.c [new file with mode: 0644]
arch/arm/mach-iop33x/iq80332.c [new file with mode: 0644]
arch/arm/mach-iop33x/irq.c [new file with mode: 0644]
arch/arm/mach-iop33x/uart.c [new file with mode: 0644]
arch/arm/mach-iop3xx/Kconfig [deleted file]
arch/arm/mach-iop3xx/Makefile [deleted file]
arch/arm/mach-iop3xx/Makefile.boot [deleted file]
arch/arm/mach-iop3xx/common.c [deleted file]
arch/arm/mach-iop3xx/iop321-irq.c [deleted file]
arch/arm/mach-iop3xx/iop321-pci.c [deleted file]
arch/arm/mach-iop3xx/iop321-setup.c [deleted file]
arch/arm/mach-iop3xx/iop321-time.c [deleted file]
arch/arm/mach-iop3xx/iop331-irq.c [deleted file]
arch/arm/mach-iop3xx/iop331-pci.c [deleted file]
arch/arm/mach-iop3xx/iop331-setup.c [deleted file]
arch/arm/mach-iop3xx/iop331-time.c [deleted file]
arch/arm/mach-iop3xx/iq31244-mm.c [deleted file]
arch/arm/mach-iop3xx/iq31244-pci.c [deleted file]
arch/arm/mach-iop3xx/iq80321-mm.c [deleted file]
arch/arm/mach-iop3xx/iq80321-pci.c [deleted file]
arch/arm/mach-iop3xx/iq80331-mm.c [deleted file]
arch/arm/mach-iop3xx/iq80331-pci.c [deleted file]
arch/arm/mach-iop3xx/iq80332-mm.c [deleted file]
arch/arm/mach-iop3xx/iq80332-pci.c [deleted file]
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/clock.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/mux.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/prcm.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/bast-irq.c
arch/arm/mach-s3c2410/cpu.c
arch/arm/mach-s3c2410/devs.h
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/dma.h [new file with mode: 0644]
arch/arm/mach-s3c2410/gpio.c
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/mach-amlm5900.c [new file with mode: 0644]
arch/arm/mach-s3c2410/mach-anubis.c
arch/arm/mach-s3c2410/mach-smdk2440.c
arch/arm/mach-s3c2410/mach-vstms.c [new file with mode: 0644]
arch/arm/mach-s3c2410/pm-simtec.c
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2410/pm.h
arch/arm/mach-s3c2410/s3c2410-dma.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2410-irq.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2410-pm.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2410-sleep.S [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2410/s3c2412-dma.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2412-irq.c
arch/arm/mach-s3c2410/s3c2412-pm.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2412.c
arch/arm/mach-s3c2410/s3c2440-dma.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2440-dsc.c
arch/arm/mach-s3c2410/s3c2440-irq.c
arch/arm/mach-s3c2410/s3c244x-irq.c
arch/arm/mach-s3c2410/sleep.S
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/mach-sa1100/collie.c
arch/arm/mach-versatile/pci.c
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/abort-lv4t.S
arch/arm/mm/abort-nommu.S [new file with mode: 0644]
arch/arm/mm/alignment.c
arch/arm/mm/cache-v4.S
arch/arm/mm/context.c [new file with mode: 0644]
arch/arm/mm/copypage-v4mc.c
arch/arm/mm/copypage-v6.c
arch/arm/mm/copypage-xscale.c
arch/arm/mm/fault.c
arch/arm/mm/fault.h
arch/arm/mm/flush.c
arch/arm/mm/init.c
arch/arm/mm/mm-armv.c [deleted file]
arch/arm/mm/mm.h [new file with mode: 0644]
arch/arm/mm/mmap.c
arch/arm/mm/mmu.c
arch/arm/mm/nommu.c
arch/arm/mm/pgd.c [new file with mode: 0644]
arch/arm/mm/proc-arm740.S [new file with mode: 0644]
arch/arm/mm/proc-arm7tdmi.S [new file with mode: 0644]
arch/arm/mm/proc-arm940.S [new file with mode: 0644]
arch/arm/mm/proc-arm946.S [new file with mode: 0644]
arch/arm/mm/proc-arm9tdmi.S [new file with mode: 0644]
arch/arm/mm/proc-xscale.S
arch/arm/oprofile/op_model_xscale.c
arch/arm/plat-iop/Makefile [new file with mode: 0644]
arch/arm/plat-iop/gpio.c [new file with mode: 0644]
arch/arm/plat-iop/i2c.c [new file with mode: 0644]
arch/arm/plat-iop/pci.c [new file with mode: 0644]
arch/arm/plat-iop/setup.c [new file with mode: 0644]
arch/arm/plat-iop/time.c [new file with mode: 0644]
arch/arm/plat-omap/clock.c
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/pm.c [deleted file]
arch/arm/plat-omap/sram.c
arch/arm/plat-omap/timer32k.c
arch/arm/tools/mach-types
arch/arm/vfp/vfp.h
arch/arm/vfp/vfpdouble.c
arch/arm/vfp/vfpinstr.h
arch/arm/vfp/vfpmodule.c
arch/arm/vfp/vfpsingle.c
arch/arm26/kernel/time.c
arch/arm26/mm/fault.c
arch/avr32/kernel/time.c
arch/cris/arch-v10/kernel/time.c
arch/cris/arch-v32/kernel/time.c
arch/frv/kernel/time.c
arch/h8300/kernel/time.c
arch/i386/defconfig
arch/i386/kernel/apm.c
arch/i386/kernel/efi.c
arch/i386/kernel/nmi.c
arch/i386/kernel/setup.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/srat.c
arch/i386/kernel/traps.c
arch/i386/lib/usercopy.c
arch/i386/mm/fault.c
arch/i386/oprofile/op_model_ppro.c
arch/ia64/hp/sim/simeth.c
arch/ia64/kernel/time.c
arch/ia64/mm/fault.c
arch/m32r/kernel/time.c
arch/m32r/mm/fault.c
arch/m68k/kernel/time.c
arch/m68k/mm/fault.c
arch/m68k/sun3/sun3ints.c
arch/m68knommu/kernel/time.c
arch/mips/au1000/common/time.c
arch/mips/gt64120/common/time.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/time.c
arch/mips/mm/fault.c
arch/mips/momentum/ocelot_g/gt-irq.c
arch/mips/sgi-ip27/ip27-timer.c
arch/parisc/kernel/module.c
arch/parisc/kernel/time.c
arch/powerpc/kernel/time.c
arch/powerpc/mm/fault.c
arch/powerpc/platforms/pseries/ras.c
arch/ppc/kernel/time.c
arch/ppc/kernel/traps.c
arch/ppc/mm/fault.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/appldata/appldata_base.c
arch/s390/crypto/crypt_s390.h
arch/s390/hypfs/hypfs_diag.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/cpcmd.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head64.S
arch/s390/kernel/ipl.c
arch/s390/kernel/process.c
arch/s390/kernel/reipl.S
arch/s390/kernel/reipl64.S
arch/s390/kernel/relocate_kernel.S
arch/s390/kernel/relocate_kernel64.S
arch/s390/kernel/semaphore.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/traps.c
arch/s390/lib/Makefile
arch/s390/lib/delay.c
arch/s390/lib/div64.c [new file with mode: 0644]
arch/s390/lib/uaccess_mvcos.c
arch/s390/lib/uaccess_std.c
arch/s390/math-emu/math.c
arch/s390/math-emu/sfp-util.h
arch/s390/mm/extmem.c
arch/s390/mm/fault.c
arch/s390/mm/init.c
arch/sh/kernel/time.c
arch/sh/mm/fault.c
arch/sh64/kernel/time.c
arch/sh64/mm/fault.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/time.c
arch/sparc/lib/copy_user.S
arch/sparc64/kernel/time.c
arch/sparc64/solaris/misc.c
arch/um/drivers/mconsole_kern.c
arch/um/drivers/mconsole_user.c
arch/um/drivers/net_kern.c
arch/um/drivers/net_user.c
arch/um/drivers/null.c
arch/um/drivers/random.c
arch/um/drivers/stderr_console.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd_kern.c
arch/um/include/net_kern.h
arch/um/include/net_user.h
arch/um/kernel/exitcode.c
arch/um/kernel/skas/mmu.c
arch/um/kernel/skas/process_kern.c [deleted file]
arch/um/kernel/time.c
arch/um/kernel/trap.c
arch/um/os-Linux/mem.c
arch/v850/kernel/time.c
arch/x86_64/defconfig
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/pci-swiotlb.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/vsyscall.c
arch/x86_64/mm/fault.c
arch/xtensa/kernel/time.c
arch/xtensa/mm/fault.c
arch/xtensa/platform-iss/network.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/genhd.c
block/ll_rw_blk.c
block/noop-iosched.c
block/scsi_ioctl.c
drivers/base/class.c
drivers/base/firmware_class.c
drivers/block/DAC960.c
drivers/block/Kconfig
drivers/block/cciss.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/xd.c
drivers/bluetooth/bfusb.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_vhci.c
drivers/cdrom/Kconfig
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/char/Kconfig
drivers/char/Makefile
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/generic_serial.c
drivers/char/hw_random/intel-rng.c
drivers/char/istallion.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/pc8736x_gpio.c
drivers/char/random.c
drivers/char/raw.c
drivers/char/rtc.c
drivers/char/s3c2410-rtc.c [deleted file]
drivers/char/scx200_gpio.c
drivers/char/selection.c
drivers/char/specialix.c
drivers/char/sysrq.c
drivers/char/tty_io.c
drivers/char/tty_ioctl.c
drivers/char/vc_screen.c
drivers/char/vt.c
drivers/char/vt_ioctl.c
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Makefile
drivers/char/watchdog/omap_wdt.c [new file with mode: 0644]
drivers/char/watchdog/omap_wdt.h [new file with mode: 0644]
drivers/fc4/fc.c
drivers/firmware/dmi_scan.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/abituguru.c
drivers/hwmon/adm1021.c
drivers/hwmon/adm1025.c
drivers/hwmon/adm1026.c
drivers/hwmon/adm1031.c
drivers/hwmon/adm9240.c
drivers/hwmon/asb100.c
drivers/hwmon/atxp1.c
drivers/hwmon/ds1621.c
drivers/hwmon/f71805f.c
drivers/hwmon/fscher.c
drivers/hwmon/fscpos.c
drivers/hwmon/gl518sm.c
drivers/hwmon/gl520sm.c
drivers/hwmon/hdaps.c
drivers/hwmon/it87.c
drivers/hwmon/k8temp.c [new file with mode: 0644]
drivers/hwmon/lm63.c
drivers/hwmon/lm75.c
drivers/hwmon/lm77.c
drivers/hwmon/lm78.c
drivers/hwmon/lm80.c
drivers/hwmon/lm83.c
drivers/hwmon/lm85.c
drivers/hwmon/lm87.c
drivers/hwmon/lm90.c
drivers/hwmon/lm92.c
drivers/hwmon/max1619.c
drivers/hwmon/pc87360.c
drivers/hwmon/sis5595.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/smsc47m1.c
drivers/hwmon/smsc47m192.c
drivers/hwmon/via686a.c
drivers/hwmon/vt1211.c [new file with mode: 0644]
drivers/hwmon/vt8231.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83627hf.c
drivers/hwmon/w83781d.c
drivers/hwmon/w83791d.c
drivers/hwmon/w83792d.c
drivers/hwmon/w83l785ts.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-sibyte.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-lib.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/hd.c
drivers/ide/pci/atiixp.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/addr.c
drivers/infiniband/hw/amso1100/c2_ae.c
drivers/infiniband/hw/amso1100/c2_alloc.c
drivers/infiniband/hw/amso1100/c2_cm.c
drivers/infiniband/hw/amso1100/c2_provider.c
drivers/infiniband/hw/amso1100/c2_rnic.c
drivers/infiniband/hw/ipath/ipath_common.h
drivers/infiniband/hw/ipath/ipath_cq.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_eeprom.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_iba6110.c
drivers/infiniband/hw/ipath/ipath_iba6120.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_keys.c
drivers/infiniband/hw/ipath/ipath_mad.c
drivers/infiniband/hw/ipath/ipath_mr.c
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_registers.h
drivers/infiniband/hw/ipath/ipath_ruc.c
drivers/infiniband/hw/ipath/ipath_srq.c
drivers/infiniband/hw/ipath/ipath_sysfs.c
drivers/infiniband/hw/ipath/ipath_uc.c
drivers/infiniband/hw/ipath/ipath_ud.c
drivers/infiniband/hw/ipath/ipath_user_pages.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/ipath/ipath_verbs.h
drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
drivers/infiniband/ulp/iser/Kconfig
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/omap-keypad.c [new file with mode: 0644]
drivers/isdn/i4l/isdn_net.c
drivers/leds/leds-net48xx.c
drivers/macintosh/via-pmu-backlight.c
drivers/macintosh/windfarm_smu_sat.c
drivers/md/Kconfig
drivers/md/dm-emc.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/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/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/mfd/ucb1x00-ts.c
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/at91_mci.c
drivers/mmc/imxmmc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_block.c
drivers/mmc/mmc_queue.c
drivers/mmc/mmci.c
drivers/mmc/omap.c
drivers/mmc/sdhci.c
drivers/mmc/wbsd.c
drivers/mtd/Kconfig
drivers/mtd/devices/Kconfig
drivers/mtd/mtd_blkdevs.c
drivers/net/8390.c
drivers/net/Kconfig
drivers/net/appletalk/ipddp.c
drivers/net/arm/at91_ether.c
drivers/net/bnx2.c
drivers/net/bonding/bond_main.c
drivers/net/fec_8xx/fec_main.c
drivers/net/fs_enet/fs_enet.h
drivers/net/irda/Kconfig
drivers/net/irda/nsc-ircc.c
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/stir4200.c
drivers/net/irda/via-ircc.c
drivers/net/loopback.c
drivers/net/pppoe.c
drivers/net/smc91x.h
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/wan/hdlc_cisco.c
drivers/net/wan/syncppp.c
drivers/net/wireless/strip.c
drivers/parport/parport_serial.c
drivers/rtc/Kconfig
drivers/rtc/rtc-rs5c348.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/block/xpram.c
drivers/s390/char/fs3270.c
drivers/s390/char/sclp.c
drivers/s390/char/tty3270.c
drivers/s390/char/vmwatchdog.c
drivers/s390/cio/device_id.c
drivers/s390/cio/ioasm.h
drivers/s390/cio/qdio.h
drivers/s390/net/iucv.c
drivers/s390/net/qeth_main.c
drivers/s390/s390mach.c
drivers/scsi/Kconfig
drivers/scsi/aic7xxx_old.c
drivers/scsi/ide-scsi.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/pluto.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/Kconfig
drivers/serial/at91_serial.c
drivers/serial/sunzilog.c
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/file_storage.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci.h
drivers/usb/image/microtek.c
drivers/usb/image/microtek.h
drivers/usb/input/hid-core.c
drivers/usb/misc/phidgetkit.c
drivers/usb/net/asix.c
drivers/usb/net/kaweth.c
drivers/usb/net/pegasus.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/generic.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/omninet.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/safe_serial.c
drivers/usb/storage/Kconfig
drivers/usb/storage/unusual_devs.h
drivers/video/Kconfig
drivers/video/backlight/locomolcd.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
fs/9p/v9fs.c
fs/Kconfig
fs/Makefile
fs/afs/file.c
fs/afs/proc.c
fs/autofs4/root.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_misc.c
fs/bio.c
fs/block_dev.c
fs/buffer.c
fs/char_dev.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/ioctl.c
fs/compat.c
fs/compat_ioctl.c
fs/cramfs/inode.c
fs/cramfs/uncompress.c
fs/dcache.c
fs/dquot.c
fs/exec.c
fs/ext2/dir.c
fs/ext2/ext2.h
fs/ext2/file.c
fs/ext2/ioctl.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/fat/inode.c
fs/file.c
fs/filesystems.c
fs/freevxfs/vxfs_super.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/inode.c
fs/generic_acl.c [new file with mode: 0644]
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/ioctl.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/internal.h [new file with mode: 0644]
fs/ioprio.c
fs/isofs/inode.c
fs/jbd/journal.c
fs/jbd/recovery.c
fs/jfs/ioctl.c
fs/libfs.c
fs/mbcache.c
fs/mpage.c
fs/msdos/namei.c
fs/namei.c
fs/namespace.c
fs/nfs/write.c
fs/no-block.c [new file with mode: 0644]
fs/open.c
fs/partitions/Makefile
fs/partitions/msdos.c
fs/proc/array.c
fs/proc/base.c
fs/proc/kcore.c
fs/proc/proc_misc.c
fs/quota.c
fs/reiserfs/Makefile
fs/reiserfs/dir.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/ioctl.c
fs/reiserfs/journal.c
fs/reiserfs/super.c
fs/select.c
fs/splice.c
fs/super.c
fs/sync.c
fs/udf/super.c
fs/xfs/Kconfig
fs/xfs/Makefile-linux-2.6
fs/xfs/linux-2.6/kmem.c
fs/xfs/linux-2.6/kmem.h
fs/xfs/linux-2.6/sema.h
fs/xfs/linux-2.6/sv.h
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_buf.h
fs/xfs/linux-2.6/xfs_globals.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_linux.h
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_vfs.h
fs/xfs/linux-2.6/xfs_vnode.h
fs/xfs/quota/xfs_dquot_item.c
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm.h
fs/xfs/quota/xfs_quota_priv.h
fs/xfs/support/ktrace.c
fs/xfs/xfs_ag.h
fs/xfs/xfs_alloc.c
fs/xfs/xfs_alloc_btree.c
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr.h
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_attr_leaf.h
fs/xfs/xfs_behavior.c
fs/xfs/xfs_behavior.h
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap_btree.c
fs/xfs/xfs_bmap_btree.h
fs/xfs/xfs_btree.c
fs/xfs/xfs_btree.h
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_error.h
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_extfree_item.h
fs/xfs/xfs_fs.h
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc_btree.c
fs/xfs/xfs_ialloc_btree.h
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_iomap.c
fs/xfs/xfs_itable.c
fs/xfs/xfs_itable.h
fs/xfs/xfs_log.c
fs/xfs/xfs_log.h
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_mount.h
fs/xfs/xfs_quota.h
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_sb.h
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_ail.c
fs/xfs/xfs_trans_priv.h
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c
include/asm-arm/arch-at91rm9200/at91rm9200.h
include/asm-arm/arch-at91rm9200/at91rm9200_sys.h
include/asm-arm/arch-at91rm9200/at91rm9200_twi.h [new file with mode: 0644]
include/asm-arm/arch-at91rm9200/gpio.h
include/asm-arm/arch-at91rm9200/hardware.h
include/asm-arm/arch-at91rm9200/irqs.h
include/asm-arm/arch-clps711x/time.h
include/asm-arm/arch-iop32x/debug-macro.S [new file with mode: 0644]
include/asm-arm/arch-iop32x/dma.h [moved from include/asm-arm/arch-iop3xx/dma.h with 71% similarity]
include/asm-arm/arch-iop32x/entry-macro.S [new file with mode: 0644]
include/asm-arm/arch-iop32x/glantank.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/hardware.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/io.h [moved from include/asm-arm/arch-iop3xx/io.h with 62% similarity]
include/asm-arm/arch-iop32x/iop32x.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/iq31244.h [moved from include/asm-arm/arch-iop3xx/iq31244.h with 55% similarity]
include/asm-arm/arch-iop32x/iq80321.h [moved from include/asm-arm/arch-iop3xx/iq80321.h with 55% similarity]
include/asm-arm/arch-iop32x/irqs.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/memory.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/n2100.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/system.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/timex.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/uncompress.h [new file with mode: 0644]
include/asm-arm/arch-iop32x/vmalloc.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/debug-macro.S [new file with mode: 0644]
include/asm-arm/arch-iop33x/dma.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/entry-macro.S [new file with mode: 0644]
include/asm-arm/arch-iop33x/hardware.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/io.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/iop33x.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/iq80331.h [moved from include/asm-arm/arch-iop3xx/iq80331.h with 51% similarity]
include/asm-arm/arch-iop33x/iq80332.h [moved from include/asm-arm/arch-iop3xx/iq80332.h with 51% similarity]
include/asm-arm/arch-iop33x/irqs.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/memory.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/system.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/timex.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/uncompress.h [new file with mode: 0644]
include/asm-arm/arch-iop33x/vmalloc.h [new file with mode: 0644]
include/asm-arm/arch-iop3xx/debug-macro.S [deleted file]
include/asm-arm/arch-iop3xx/entry-macro.S [deleted file]
include/asm-arm/arch-iop3xx/hardware.h [deleted file]
include/asm-arm/arch-iop3xx/iop321-irqs.h [deleted file]
include/asm-arm/arch-iop3xx/iop321.h [deleted file]
include/asm-arm/arch-iop3xx/iop331-irqs.h [deleted file]
include/asm-arm/arch-iop3xx/iop331.h [deleted file]
include/asm-arm/arch-iop3xx/irqs.h [deleted file]
include/asm-arm/arch-iop3xx/memory.h [deleted file]
include/asm-arm/arch-iop3xx/system.h [deleted file]
include/asm-arm/arch-iop3xx/timex.h [deleted file]
include/asm-arm/arch-iop3xx/uncompress.h [deleted file]
include/asm-arm/arch-iop3xx/vmalloc.h [deleted file]
include/asm-arm/arch-ixp4xx/platform.h
include/asm-arm/arch-l7200/io.h
include/asm-arm/arch-l7200/time.h
include/asm-arm/arch-omap/board-ams-delta.h
include/asm-arm/arch-omap/clock.h
include/asm-arm/arch-omap/dma.h
include/asm-arm/arch-omap/dmtimer.h
include/asm-arm/arch-omap/gpmc.h
include/asm-arm/arch-omap/irqs.h
include/asm-arm/arch-omap/keypad.h
include/asm-arm/arch-omap/mux.h
include/asm-arm/arch-s3c2410/dma.h
include/asm-arm/arch-s3c2410/map.h
include/asm-arm/arch-s3c2410/osiris-map.h
include/asm-arm/arch-s3c2410/regs-ac97.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/regs-lcd.h
include/asm-arm/atomic.h
include/asm-arm/bitops.h
include/asm-arm/cacheflush.h
include/asm-arm/flat.h [new file with mode: 0644]
include/asm-arm/hardware/iop3xx.h [new file with mode: 0644]
include/asm-arm/hardware/locomo.h
include/asm-arm/hardware/sharpsl_pm.h
include/asm-arm/io.h
include/asm-arm/irqflags.h [new file with mode: 0644]
include/asm-arm/mach/pci.h
include/asm-arm/mach/time.h
include/asm-arm/page.h
include/asm-arm/pgtable.h
include/asm-arm/proc-fns.h
include/asm-arm/setup.h
include/asm-arm/system.h
include/asm-arm/timeofday.h [new file with mode: 0644]
include/asm-arm/tlbflush.h
include/asm-arm/unaligned.h
include/asm-generic/bug.h
include/asm-i386/dma-mapping.h
include/asm-i386/mach-default/do_timer.h
include/asm-i386/mach-summit/mach_apic.h
include/asm-i386/mach-visws/do_timer.h
include/asm-i386/mach-voyager/do_timer.h
include/asm-i386/nmi.h
include/asm-i386/smp.h
include/asm-powerpc/bug.h
include/asm-s390/appldata.h
include/asm-s390/atomic.h
include/asm-s390/bitops.h
include/asm-s390/byteorder.h
include/asm-s390/checksum.h
include/asm-s390/div64.h
include/asm-s390/ebcdic.h
include/asm-s390/io.h
include/asm-s390/irq.h
include/asm-s390/irqflags.h
include/asm-s390/lowcore.h
include/asm-s390/page.h
include/asm-s390/pgtable.h
include/asm-s390/processor.h
include/asm-s390/ptrace.h
include/asm-s390/rwsem.h
include/asm-s390/semaphore.h
include/asm-s390/sfp-machine.h
include/asm-s390/sigp.h
include/asm-s390/smp.h
include/asm-s390/spinlock.h
include/asm-s390/string.h
include/asm-s390/system.h
include/asm-s390/timex.h
include/asm-s390/tlbflush.h
include/asm-s390/uaccess.h
include/asm-s390/unistd.h
include/asm-um/pgtable.h
include/asm-x86_64/dma-mapping.h
include/asm-x86_64/nmi.h
include/asm-x86_64/semaphore.h
include/asm-x86_64/uaccess.h
include/linux/Kbuild
include/linux/atalk.h
include/linux/atmlec.h
include/linux/audit.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/blktrace_api.h
include/linux/buffer_head.h
include/linux/compat_ioctl.h
include/linux/compiler.h
include/linux/cpuset.h
include/linux/cramfs_fs.h
include/linux/dma-mapping.h
include/linux/dmi.h
include/linux/elevator.h
include/linux/errqueue.h
include/linux/ext2_fs.h
include/linux/ext3_fs.h
include/linux/file.h
include/linux/fs.h
include/linux/generic_acl.h [new file with mode: 0644]
include/linux/genhd.h
include/linux/getcpu.h
include/linux/hrtimer.h
include/linux/i2c-id.h
include/linux/icmp.h
include/linux/if.h
include/linux/if_arp.h
include/linux/if_link.h [new file with mode: 0644]
include/linux/igmp.h
include/linux/in.h
include/linux/in6.h
include/linux/inet_diag.h
include/linux/inetdevice.h
include/linux/interrupt.h
include/linux/ip.h
include/linux/ipv6.h
include/linux/jbd.h
include/linux/leds.h
include/linux/list.h
include/linux/lockdep.h
include/linux/loop.h
include/linux/mm.h
include/linux/mmc/host.h
include/linux/mmc/mmc.h
include/linux/module.h
include/linux/mpage.h
include/linux/mroute.h
include/linux/msdos_fs.h
include/linux/namei.h
include/linux/netdevice.h
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/netfilter_ipv4/ip_conntrack_h323.h
include/linux/netfilter_ipv4/ip_conntrack_tuple.h
include/linux/netfilter_ipv4/ip_nat.h
include/linux/netfilter_ipv4/ip_queue.h
include/linux/netfilter_ipv4/ipt_iprange.h
include/linux/nmi.h
include/linux/page-flags.h
include/linux/pci_ids.h
include/linux/percpu.h
include/linux/posix-timers.h
include/linux/ptrace.h
include/linux/raid/md.h
include/linux/raid/md_k.h
include/linux/ramfs.h
include/linux/rbtree.h
include/linux/reiserfs_acl.h
include/linux/reiserfs_fs.h
include/linux/reiserfs_fs_i.h
include/linux/reiserfs_xattr.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/scx200_gpio.h
include/linux/security.h
include/linux/shmem_fs.h
include/linux/spinlock.h
include/linux/spinlock_api_smp.h
include/linux/sunrpc/auth.h
include/linux/sunrpc/msg_prot.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcauth.h
include/linux/sunrpc/xdr.h
include/linux/sunrpc/xprt.h
include/linux/syscalls.h
include/linux/tcp.h
include/linux/trdevice.h
include/linux/tty.h
include/linux/udp.h
include/linux/usb.h
include/linux/videodev2.h
include/linux/vmstat.h
include/linux/vt_kern.h
include/linux/writeback.h
include/linux/xfrm.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/net/arp.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/cipso_ipv4.h
include/net/dst.h
include/net/flow.h
include/net/icmp.h
include/net/inet_connection_sock.h
include/net/inet_hashtables.h
include/net/inet_sock.h
include/net/inet_timewait_sock.h
include/net/inetpeer.h
include/net/ip.h
include/net/ip_fib.h
include/net/ip_mp_alg.h
include/net/ip_vs.h
include/net/ipv6.h
include/net/irda/irlan_common.h
include/net/irda/irlap_frame.h
include/net/irda/irlmp.h
include/net/netlabel.h
include/net/netlink.h
include/net/route.h
include/net/xfrm.h
include/scsi/scsi_device.h
include/scsi/scsi_tcq.h
init/Kconfig
init/do_mounts.c
kernel/acct.c
kernel/auditsc.c
kernel/capability.c
kernel/compat.c
kernel/cpuset.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/hrtimer.c
kernel/irq/chip.c
kernel/kexec.c
kernel/kfifo.c
kernel/kmod.c
kernel/lockdep.c
kernel/module.c
kernel/panic.c
kernel/params.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/ptrace.c
kernel/rcutorture.c
kernel/relay.c
kernel/rtmutex.c
kernel/sched.c
kernel/signal.c
kernel/softirq.c
kernel/softlockup.c
kernel/spinlock.c
kernel/stop_machine.c
kernel/sys.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/timer.c
kernel/unwind.c
lib/Kconfig.debug
lib/Makefile
lib/list_debug.c [new file with mode: 0644]
lib/rbtree.c
lib/rwsem.c
lib/spinlock_debug.c
lib/ts_fsm.c
mm/Makefile
mm/bounce.c [new file with mode: 0644]
mm/filemap.c
mm/highmem.c
mm/memory.c
mm/memory_hotplug.c
mm/migrate.c
mm/oom_kill.c
mm/page-writeback.c
mm/shmem.c
mm/shmem_acl.c [new file with mode: 0644]
mm/slab.c
mm/swapfile.c
mm/truncate.c
net/802/tr.c
net/Kconfig
net/appletalk/ddp.c
net/atm/lec.c
net/atm/lec.h
net/atm/lec_arpc.h
net/atm/mpc.c
net/atm/mpoa_caches.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/tty.c
net/bridge/netfilter/ebt_arpreply.c
net/core/dev.c
net/core/ethtool.c
net/core/neighbour.c
net/core/pktgen.c
net/core/rtnetlink.c
net/core/utils.c
net/dccp/ipv4.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/cipso_ipv4.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/inetpeer.c
net/ipv4/ip_fragment.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipcomp.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_dh.c
net/ipv4/ipvs/ip_vs_ftp.c
net/ipv4/ipvs/ip_vs_lblc.c
net/ipv4/ipvs/ip_vs_lblcr.c
net/ipv4/ipvs/ip_vs_proto.c
net/ipv4/ipvs/ip_vs_proto_tcp.c
net/ipv4/ipvs/ip_vs_proto_udp.c
net/ipv4/ipvs/ip_vs_sh.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/multipath_wrandom.c
net/ipv4/netfilter.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_helper_h323.c
net/ipv4/netfilter/ip_conntrack_helper_pptp.c
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_netbios_ns.c
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_conntrack_sip.c
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_nat_core.c
net/ipv4/netfilter/ip_nat_ftp.c
net/ipv4/netfilter/ip_nat_helper.c
net/ipv4/netfilter/ip_nat_helper_h323.c
net/ipv4/netfilter/ip_nat_helper_pptp.c
net/ipv4/netfilter/ip_nat_proto_icmp.c
net/ipv4/netfilter/ip_nat_proto_tcp.c
net/ipv4/netfilter/ip_nat_proto_udp.c
net/ipv4/netfilter/ip_nat_rule.c
net/ipv4/netfilter/ip_nat_sip.c
net/ipv4/netfilter/ip_nat_snmp_basic.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_NETMAP.c
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_SAME.c
net/ipv4/netfilter/ipt_TCPMSS.c
net/ipv4/netfilter/ipt_TOS.c
net/ipv4/netfilter/ipt_TTL.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/ipt_hashlimit.c
net/ipv4/netfilter/ipt_recent.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_lp.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_state.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/inet6_hashtables.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_state.c
net/ipv6/xfrm6_tunnel.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_lmp.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_provider.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irttp.c
net/key/af_key.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_domainhash.c
net/netlabel/netlabel_domainhash.h
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlabel/netlabel_user.c
net/netlabel/netlabel_user.h
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sched/sch_htb.c
net/sctp/input.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/sm_make_chunk.c
net/sctp/socket.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_krb5_seal.c
net/sunrpc/auth_gss/gss_krb5_wrap.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/auth_null.c
net/sunrpc/auth_unix.c
net/sunrpc/clnt.c
net/sunrpc/pmap_clnt.c
net/sunrpc/svc.c
net/sunrpc/svcauth.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xdr.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c
net/xfrm/xfrm_hash.h
net/xfrm/xfrm_input.c
net/xfrm/xfrm_state.c
scripts/basic/docproc.c
security/Kconfig
security/Makefile
security/commoncap.c
security/seclvl.c [deleted file]
security/selinux/hooks.c
sound/Makefile
sound/mips/au1x00.c
sound/oss/COPYING [deleted file]
sound/oss/cs46xx.c
sound/oss/cs46xxpm-24.h [deleted file]
sound/oss/trident.c
sound/sound_core.c
sound/sound_firmware.c
sound/sparc/dbri.c

diff --git a/CREDITS b/CREDITS
index cc3453a55fb948f5173ff82715c304d18dc1212d..66e82466dde8af73c814354d8e4df82398e78e5c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1620,7 +1620,8 @@ D: fbdev hacking
 
 N: Jesper Juhl
 E: jesper.juhl@gmail.com
-D: Various fixes, cleanups and minor features.
+D: Various fixes, cleanups and minor features all over the tree.
+D: Wrote initial version of the hdaps driver (since passed on to others).
 S: Lemnosvej 1, 3.tv
 S: 2300 Copenhagen S.
 S: Denmark
@@ -2477,7 +2478,8 @@ S: Derbyshire DE4 3RL
 S: United Kingdom
 
 N: Ian S. Nelson
-E: ian.nelson@echostar.com
+E: nelsonis@earthlink.net
+P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6  9E97 576F 1B97 00D3 D983
 D: Minor mmap and ide hacks
 S: 1370 Atlantis Ave.
 S: Lafayette CO, 80026
index 6d2412ec91edb21ebab0c13e581951bbe352b610..29c18966b0502c3489e1058bd361db50a6c07686 100644 (file)
@@ -532,6 +532,40 @@ appears outweighs the potential value of the hint that tells gcc to do
 something it would have done anyway.
 
 
+               Chapter 16: Function return values and names
+
+Functions can return values of many different kinds, and one of the
+most common is a value indicating whether the function succeeded or
+failed.  Such a value can be represented as an error-code integer
+(-Exxx = failure, 0 = success) or a "succeeded" boolean (0 = failure,
+non-zero = success).
+
+Mixing up these two sorts of representations is a fertile source of
+difficult-to-find bugs.  If the C language included a strong distinction
+between integers and booleans then the compiler would find these mistakes
+for us... but it doesn't.  To help prevent such bugs, always follow this
+convention:
+
+       If the name of a function is an action or an imperative command,
+       the function should return an error-code integer.  If the name
+       is a predicate, the function should return a "succeeded" boolean.
+
+For example, "add work" is a command, and the add_work() function returns 0
+for success or -EBUSY for failure.  In the same way, "PCI device present" is
+a predicate, and the pci_dev_present() function returns 1 if it succeeds in
+finding a matching device or 0 if it doesn't.
+
+All EXPORTed functions must respect this convention, and so should all
+public functions.  Private (static) functions need not, but it is
+recommended that they do.
+
+Functions whose return value is the actual result of a computation, rather
+than an indication of whether the computation succeeded, are not subject to
+this rule.  Generally they indicate failure by returning some out-of-range
+result.  Typical examples would be functions that return pointers; they use
+NULL or the ERR_PTR mechanism to report failure.
+
+
 
                Appendix I: References
 
index f8fe882e33dccfc50f6e5add6ca89a53389d649f..6d4b1ef5b6f11a24a1705e1c0e73b17220feb35c 100644 (file)
@@ -181,27 +181,6 @@ X!Ilib/string.c
      </sect1>
   </chapter>
 
-  <chapter id="proc">
-     <title>The proc filesystem</title>
-     <sect1><title>sysctl interface</title>
-!Ekernel/sysctl.c
-     </sect1>
-
-     <sect1><title>proc filesystem interface</title>
-!Ifs/proc/base.c
-     </sect1>
-  </chapter>
-
-  <chapter id="debugfs">
-     <title>The debugfs filesystem</title>
-     <sect1><title>debugfs interface</title>
-!Efs/debugfs/inode.c
-!Efs/debugfs/file.c
-     </sect1>
-  </chapter>
-
   <chapter id="vfs">
      <title>The Linux VFS</title>
      <sect1><title>The Filesystem types</title>
@@ -234,6 +213,50 @@ X!Ilib/string.c
      </sect1>
   </chapter>
 
+  <chapter id="proc">
+     <title>The proc filesystem</title>
+     <sect1><title>sysctl interface</title>
+!Ekernel/sysctl.c
+     </sect1>
+
+     <sect1><title>proc filesystem interface</title>
+!Ifs/proc/base.c
+     </sect1>
+  </chapter>
+
+  <chapter id="sysfs">
+     <title>The Filesystem for Exporting Kernel Objects</title>
+!Efs/sysfs/file.c
+!Efs/sysfs/symlink.c
+!Efs/sysfs/bin.c
+  </chapter>
+
+  <chapter id="debugfs">
+     <title>The debugfs filesystem</title>
+     <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+     </sect1>
+  </chapter>
+
+  <chapter id="relayfs">
+     <title>relay interface support</title>
+
+     <para>
+       Relay interface support
+       is designed to provide an efficient mechanism for tools and
+       facilities to relay large amounts of data from kernel space to
+       user space.
+     </para>
+
+     <sect1><title>relay interface</title>
+!Ekernel/relay.c
+!Ikernel/relay.c
+     </sect1>
+  </chapter>
+
   <chapter id="netcore">
      <title>Linux Networking</title>
      <sect1><title>Networking Base Types</title>
@@ -349,13 +372,6 @@ X!Earch/i386/kernel/mca.c
      </sect1>
   </chapter>
 
-  <chapter id="sysfs">
-     <title>The Filesystem for Exporting Kernel Objects</title>
-!Efs/sysfs/file.c
-!Efs/sysfs/symlink.c
-!Efs/sysfs/bin.c
-  </chapter>
-
   <chapter id="security">
      <title>Security Framework</title>
 !Esecurity/security.c
@@ -386,6 +402,7 @@ X!Iinclude/linux/device.h
 -->
 !Edrivers/base/driver.c
 !Edrivers/base/core.c
+!Edrivers/base/class.c
 !Edrivers/base/firmware_class.c
 !Edrivers/base/transport_class.c
 !Edrivers/base/dmapool.c
@@ -437,6 +454,11 @@ X!Edrivers/pnp/system.c
 !Eblock/ll_rw_blk.c
   </chapter>
 
+  <chapter id="chrdev">
+       <title>Char devices</title>
+!Efs/char_dev.c
+  </chapter>
+
   <chapter id="miscdev">
      <title>Miscellaneous Devices</title>
 !Edrivers/char/misc.c
index a10bfb6ecd9fa4e55c9beecd2e588c9a0359ec71..a6cb6ffd293377bef9a19cd077299626fcb5bf47 100644 (file)
@@ -61,3 +61,6 @@ kernel patches.
     Documentation/kernel-parameters.txt.
 
 18: All new module parameters are documented with MODULE_PARM_DESC()
+
+19: All new userspace interfaces are documented in Documentation/ABI/.
+    See Documentation/ABI/README for more information.
index 6bd30fdd0786b9a7c64aa4c34f5a732b4c7096e0..58bead05eabb057fb777bdd5fe7a56b44f35b0e0 100644 (file)
@@ -59,11 +59,11 @@ Copyright:  The copyright owner must agree to use of GPL.
                are the same person/entity. If not, the name of
                the person/entity authorizing use of GPL should be
                listed in case it's necessary to verify the will of
-               the copright owner.
+               the copyright owner.
 
 Interfaces:    If your driver uses existing interfaces and behaves like
                other drivers in the same class it will be much more likely
-               to be accepted than if it invents gratuitous new ones. 
+               to be accepted than if it invents gratuitous new ones.
                If you need to implement a common API over Linux and NT
                drivers do it in userspace.
 
@@ -88,7 +88,7 @@ Clarity:      It helps if anyone can see how to fix the driver. It helps
                it will go in the bitbucket.
 
 Control:       In general if there is active maintainance of a driver by
-               the author then patches will be redirected to them unless 
+               the author then patches will be redirected to them unless
                they are totally obvious and without need of checking.
                If you want to be the contact and update point for the
                driver it is a good idea to state this in the comments,
@@ -100,7 +100,7 @@ What Criteria Do Not Determine Acceptance
 Vendor:                Being the hardware vendor and maintaining the driver is
                often a good thing. If there is a stable working driver from
                other people already in the tree don't expect 'we are the
-               vendor' to get your driver chosen. Ideally work with the 
+               vendor' to get your driver chosen. Ideally work with the
                existing driver author to build a single perfect driver.
 
 Author:                It doesn't matter if a large Linux company wrote the driver,
@@ -116,17 +116,13 @@ Linux kernel master tree:
        ftp.??.kernel.org:/pub/linux/kernel/...
        ?? == your country code, such as "us", "uk", "fr", etc.
 
-Linux kernel mailing list:             
+Linux kernel mailing list:
        linux-kernel@vger.kernel.org
        [mail majordomo@vger.kernel.org to subscribe]
 
 Linux Device Drivers, Third Edition (covers 2.6.10):
        http://lwn.net/Kernel/LDD3/  (free version)
 
-Kernel traffic:
-       Weekly summary of kernel list activity (much easier to read)
-       http://www.kerneltraffic.org/kernel-traffic/
-
 LWN.net:
        Weekly summary of kernel development activity - http://lwn.net/
        2.6 API changes:
@@ -145,11 +141,8 @@ KernelNewbies:
 Linux USB project:
        http://www.linux-usb.org/
 
-How to NOT write kernel driver by arjanv@redhat.com
-       http://people.redhat.com/arjanv/olspaper.pdf
+How to NOT write kernel driver by Arjan van de Ven:
+       http://www.fenrus.org/how-to-not-write-a-device-driver-paper.pdf
 
 Kernel Janitor:
        http://janitor.kernelnewbies.org/
-
---
-Last updated on 17 Nov 2005.
index d42ab4c9e893b787d0918cc9f5a540a785a11aee..302d148c2e18f0e0fe565bc9c9c1a2f4b232d346 100644 (file)
@@ -173,15 +173,15 @@ For small patches you may want to CC the Trivial Patch Monkey
 trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
 patches. Trivial patches must qualify for one of the following rules:
  Spelling fixes in documentation
- Spelling fixes which could break grep(1).
+ Spelling fixes which could break grep(1)
  Warning fixes (cluttering with useless warnings is bad)
  Compilation fixes (only if they are actually correct)
  Runtime fixes (only if they actually fix things)
- Removing use of deprecated functions/macros (eg. check_region).
+ Removing use of deprecated functions/macros (eg. check_region)
  Contact detail and documentation fixes
  Non-portable code replaced by portable code (even in arch-specific,
  since people copy, as long as it's trivial)
- Any fix by the author/maintainer of the file. (ie. patch monkey
+ Any fix by the author/maintainer of the file (ie. patch monkey
  in re-transmission mode)
 URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
 
@@ -209,6 +209,19 @@ Exception:  If your mailer is mangling patches then someone may ask
 you to re-send them using MIME.
 
 
+WARNING: Some mailers like Mozilla send your messages with
+---- message header ----
+Content-Type: text/plain; charset=us-ascii; format=flowed
+---- message header ----
+The problem is that "format=flowed" makes some of the mailers
+on receiving side to replace TABs with spaces and do similar
+changes. Thus the patches from you can look corrupted.
+
+To fix this just make your mozilla defaults/pref/mailnews.js file to look like:
+pref("mailnews.send_plaintext_flowed", false); // RFC 2646=======
+pref("mailnews.display.disable_format_flowed_support", true);
+
+
 
 7) E-mail size.
 
@@ -245,13 +258,13 @@ updated change.
 It is quite common for Linus to "drop" your patch without comment.
 That's the nature of the system.  If he drops your patch, it could be
 due to
-* Your patch did not apply cleanly to the latest kernel version
+* Your patch did not apply cleanly to the latest kernel version.
 * Your patch was not sufficiently discussed on linux-kernel.
-* A style issue (see section 2),
-* An e-mail formatting issue (re-read this section)
-* A technical problem with your change
-* He gets tons of e-mail, and yours got lost in the shuffle
-* You are being annoying (See Figure 1)
+* A style issue (see section 2).
+* An e-mail formatting issue (re-read this section).
+* A technical problem with your change.
+* He gets tons of e-mail, and yours got lost in the shuffle.
+* You are being annoying.
 
 When in doubt, solicit comments on linux-kernel mailing list.
 
@@ -476,10 +489,10 @@ SECTION 3 - REFERENCES
 Andrew Morton, "The perfect patch" (tpp).
   <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
 
-Jeff Garzik, "Linux kernel patch submission format."
+Jeff Garzik, "Linux kernel patch submission format".
   <http://linux.yyz.us/patch-format.html>
 
-Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer".
+Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
   <http://www.kroah.com/log/2005/03/31/>
   <http://www.kroah.com/log/2005/07/08/>
   <http://www.kroah.com/log/2005/10/19/>
@@ -488,9 +501,9 @@ Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer".
 NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!
   <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
 
-Kernel Documentation/CodingStyle
+Kernel Documentation/CodingStyle:
   <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
 
-Linus Torvald's mail on the canonical patch format:
+Linus Torvalds's mail on the canonical patch format:
   <http://lkml.org/lkml/2005/4/7/183>
 --
index 76b44290c1546c50a4e15527c18a19e626249f35..842f0d1ab2165781420fdd53b3875a16ba91adb6 100644 (file)
@@ -217,11 +217,11 @@ exclusive cpuset.  Also, the use of a Linux virtual file system (vfs)
 to represent the cpuset hierarchy provides for a familiar permission
 and name space for cpusets, with a minimum of additional kernel code.
 
-The cpus file in the root (top_cpuset) cpuset is read-only.
-It automatically tracks the value of cpu_online_map, using a CPU
-hotplug notifier.  If and when memory nodes can be hotplugged,
-we expect to make the mems file in the root cpuset read-only
-as well, and have it track the value of node_online_map.
+The cpus and mems files in the root (top_cpuset) cpuset are
+read-only.  The cpus file automatically tracks the value of
+cpu_online_map using a CPU hotplug notifier, and the mems file
+automatically tracks the value of node_online_map using the
+cpuset_track_online_nodes() hook.
 
 
 1.4 What are exclusive cpusets ?
index c12d39a23c3d1b43827f2fe37a1b1776036db2d1..aa0d322db171d1175bee86f2e85448a94ceff8d7 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,7 +81,7 @@ 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
 ------------
index 436697cb93882e174199d7f00efc1d243954ac75..9364f47c711690e4a262ed0c93c1072ff1be181e 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
index 7db71d6fba824bc92f08785578d7dc8fefb4c5aa..7240ee7515decf7b8d5205a18e43b891ddba2f9a 100644 (file)
@@ -39,6 +39,8 @@ Table of Contents
   2.9  Appletalk
   2.10 IPX
   2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
+  2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+  2.13 /proc/<pid>/oom_score - Display current oom-killer score
 
 ------------------------------------------------------------------------------
 Preface
@@ -1962,6 +1964,22 @@ a queue must be less or equal then msg_max.
 maximum  message size value (it is every  message queue's attribute set during
 its creation).
 
+2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+------------------------------------------------------
+
+This file can be used to adjust the score used to select which processes
+should be killed in an  out-of-memory  situation.  Giving it a high score will
+increase the likelihood of this process being killed by the oom-killer.  Valid
+values are in the range -16 to +15, plus the special value -17, which disables
+oom-killing altogether for this process.
+
+2.13 /proc/<pid>/oom_score - Display current oom-killer score
+-------------------------------------------------------------
+
+------------------------------------------------------------------------------
+This file can be used to check the current score used by the oom-killer is for
+any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
+process should be killed in an out-of-memory situation.
 
 ------------------------------------------------------------------------------
 Summary
index 9555be1ed99947b88a776fa2b9e6b49e143fde2e..e783fd62e3085a5abb7a965d83fa3b462d990e8d 100644 (file)
@@ -13,12 +13,25 @@ Supported chips:
                        from Super I/O config space (8 I/O ports)
     Datasheet: Publicly available at the ITE website
                http://www.ite.com.tw/
+  * IT8716F
+    Prefix: 'it8716'
+    Addresses scanned: from Super I/O config space (8 I/O ports)
+    Datasheet: Publicly available at the ITE website
+               http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP
+  * IT8718F
+    Prefix: 'it8718'
+    Addresses scanned: from Super I/O config space (8 I/O ports)
+    Datasheet: Publicly available at the ITE website
+               http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
+               http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
   * SiS950   [clone of IT8705F]
     Prefix: 'it87'
     Addresses scanned: from Super I/O config space (8 I/O ports)
     Datasheet: No longer be available
 
-Author: Christophe Gauthron <chrisg@0-in.com>
+Authors:
+    Christophe Gauthron <chrisg@0-in.com>
+    Jean Delvare <khali@linux-fr.org>
 
 
 Module Parameters
@@ -43,26 +56,46 @@ Module Parameters
 Description
 -----------
 
-This driver implements support for the IT8705F, IT8712F and SiS950 chips.
-
-This driver also supports IT8712F, which adds SMBus access, and a VID
-input, used to report the Vcore voltage of the Pentium processor.
-The IT8712F additionally features VID inputs.
+This driver implements support for the IT8705F, IT8712F, IT8716F,
+IT8718F and SiS950 chips.
 
 These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
 joysticks and other miscellaneous stuff. For hardware monitoring, they
 include an 'environment controller' with 3 temperature sensors, 3 fan
 rotation speed sensors, 8 voltage sensors, and associated alarms.
 
+The IT8712F and IT8716F additionally feature VID inputs, used to report
+the Vcore voltage of the processor. The early IT8712F have 5 VID pins,
+the IT8716F and late IT8712F have 6. They are shared with other functions
+though, so the functionality may not be available on a given system.
+The driver dumbly assume it is there.
+
+The IT8718F also features VID inputs (up to 8 pins) but the value is
+stored in the Super-I/O configuration space. Due to technical limitations,
+this value can currently only be read once at initialization time, so
+the driver won't notice and report changes in the VID value. The two
+upper VID bits share their pins with voltage inputs (in5 and in6) so you
+can't have both on a given board.
+
+The IT8716F, IT8718F and later IT8712F revisions have support for
+2 additional fans. They are not yet supported by the driver.
+
+The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
+16-bit tachometer counters for fans 1 to 3. This is better (no more fan
+clock divider mess) but not compatible with the older chips and
+revisions. For now, the driver only uses the 16-bit mode on the
+IT8716F and IT8718F.
+
 Temperatures are measured in degrees Celsius. An alarm is triggered once
 when the Overtemperature Shutdown limit is crossed.
 
 Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
-triggered if the rotation speed has dropped below a programmable limit. Fan
-readings can be divided by a programmable divider (1, 2, 4 or 8) to give the
-readings more range or accuracy. Not all RPM values can accurately be
-represented, so some rounding is done. With a divider of 2, the lowest
-representable value is around 2600 RPM.
+triggered if the rotation speed has dropped below a programmable limit. When
+16-bit tachometer counters aren't used, fan readings can be divided by
+a programmable divider (1, 2, 4 or 8) to give the readings more range or
+accuracy. With a divider of 2, the lowest representable value is around
+2600 RPM. Not all RPM values can accurately be represented, so some rounding
+is done.
 
 Voltage sensors (also known as IN sensors) report their values in volts. An
 alarm is triggered if the voltage has crossed a programmable minimum or
@@ -71,9 +104,9 @@ zero'; this is important for negative voltage measurements. All voltage
 inputs can measure voltages between 0 and 4.08 volts, with a resolution of
 0.016 volt. The battery voltage in8 does not have limit registers.
 
-The VID lines (IT8712F only) encode the core voltage value: the voltage
-level your processor should work with. This is hardcoded by the mainboard
-and/or processor itself. It is a value in volts.
+The VID lines (IT8712F/IT8716F/IT8718F) encode the core voltage value:
+the voltage level your processor should work with. This is hardcoded by
+the mainboard and/or processor itself. It is a value in volts.
 
 If an alarm triggers, it will remain triggered until the hardware register
 is read at least once. This means that the cause for the alarm may already
diff --git a/Documentation/hwmon/k8temp b/Documentation/hwmon/k8temp
new file mode 100644 (file)
index 0000000..bab445a
--- /dev/null
@@ -0,0 +1,52 @@
+Kernel driver k8temp
+====================
+
+Supported chips:
+  * AMD K8 CPU
+    Prefix: 'k8temp'
+    Addresses scanned: PCI space
+    Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
+
+Author: Rudolf Marek
+Contact: Rudolf Marek <r.marek@sh.cvut.cz>
+
+Description
+-----------
+
+This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs.
+Official documentation says that it works from revision F of K8 core, but
+in fact it seems to be implemented for all revisions of K8 except the first
+two revisions (SH-B0 and SH-B3).
+
+There can be up to four temperature sensors inside single CPU. The driver
+will auto-detect the sensors and will display only temperatures from
+implemented sensors.
+
+Mapping of /sys files is as follows:
+
+temp1_input - temperature of Core 0 and "place" 0
+temp2_input - temperature of Core 0 and "place" 1
+temp3_input - temperature of Core 1 and "place" 0
+temp4_input - temperature of Core 1 and "place" 1
+
+Temperatures are measured in degrees Celsius and measurement resolution is
+1 degree C. It is expected that future CPU will have better resolution. The
+temperature is updated once a second. Valid temperatures are from -49 to
+206 degrees C.
+
+Temperature known as TCaseMax was specified for processors up to revision E.
+This temperature is defined as temperature between heat-spreader and CPU
+case, so the internal CPU temperature supplied by this driver can be higher.
+There is no easy way how to measure the temperature which will correlate
+with TCaseMax temperature.
+
+For newer revisions of CPU (rev F, socket AM2) there is a mathematically
+computed temperature called TControl, which must be lower than TControlMax.
+
+The relationship is following:
+
+temp1_input - TjOffset*2 < TControlMax,
+
+TjOffset is not yet exported by the driver, TControlMax is usually
+70 degrees C. The rule of the thumb -> CPU temperature should not cross
+60 degrees C too much.
diff --git a/Documentation/hwmon/vt1211 b/Documentation/hwmon/vt1211
new file mode 100644 (file)
index 0000000..77fa633
--- /dev/null
@@ -0,0 +1,206 @@
+Kernel driver vt1211
+====================
+
+Supported chips:
+  * VIA VT1211
+    Prefix: 'vt1211'
+    Addresses scanned: none, address read from Super-I/O config space
+    Datasheet: Provided by VIA upon request and under NDA
+
+Authors: Juerg Haefliger <juergh@gmail.com>
+
+This driver is based on the driver for kernel 2.4 by Mark D. Studebaker and
+its port to kernel 2.6 by Lars Ekman.
+
+Thanks to Joseph Chan and Fiona Gatt from VIA for providing documentation and
+technical support.
+
+
+Module Parameters
+-----------------
+
+* uch_config: int      Override the BIOS default universal channel (UCH)
+                       configuration for channels 1-5.
+                       Legal values are in the range of 0-31. Bit 0 maps to
+                       UCH1, bit 1 maps to UCH2 and so on. Setting a bit to 1
+                       enables the thermal input of that particular UCH and
+                       setting a bit to 0 enables the voltage input.
+
+* int_mode: int                Override the BIOS default temperature interrupt mode.
+                       The only possible value is 0 which forces interrupt
+                       mode 0. In this mode, any pending interrupt is cleared
+                       when the status register is read but is regenerated as
+                       long as the temperature stays above the hysteresis
+                       limit.
+
+Be aware that overriding BIOS defaults might cause some unwanted side effects!
+
+
+Description
+-----------
+
+The VIA VT1211 Super-I/O chip includes complete hardware monitoring
+capabilities. It monitors 2 dedicated temperature sensor inputs (temp1 and
+temp2), 1 dedicated voltage (in5) and 2 fans. Additionally, the chip
+implements 5 universal input channels (UCH1-5) that can be individually
+programmed to either monitor a voltage or a temperature.
+
+This chip also provides manual and automatic control of fan speeds (according
+to the datasheet). The driver only supports automatic control since the manual
+mode doesn't seem to work as advertised in the datasheet. In fact I couldn't
+get manual mode to work at all! Be aware that automatic mode hasn't been
+tested very well (due to the fact that my EPIA M10000 doesn't have the fans
+connected to the PWM outputs of the VT1211 :-().
+
+The following table shows the relationship between the vt1211 inputs and the
+sysfs nodes.
+
+Sensor          Voltage Mode   Temp Mode   Default Use (from the datasheet)
+------          ------------   ---------   --------------------------------
+Reading 1                      temp1       Intel thermal diode
+Reading 3                      temp2       Internal thermal diode
+UCH1/Reading2   in0            temp3       NTC type thermistor
+UCH2            in1            temp4       +2.5V
+UCH3            in2            temp5       VccP (processor core)
+UCH4            in3            temp6       +5V
+UCH5            in4            temp7       +12V
++3.3V           in5                        Internal VCC (+3.3V)
+
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by an 8-bit ADC with a LSB of ~10mV. The supported input
+range is thus from 0 to 2.60V. Voltage values outside of this range need
+external scaling resistors. This external scaling needs to be compensated for
+via compute lines in sensors.conf, like:
+
+compute inx @*(1+R1/R2), @/(1+R1/R2)
+
+The board level scaling resistors according to VIA's recommendation are as
+follows. And this is of course totally dependent on the actual board
+implementation :-) You will have to find documentation for your own
+motherboard and edit sensors.conf accordingly.
+
+                                      Expected
+Voltage       R1     R2     Divider   Raw Value
+-----------------------------------------------
++2.5V         2K     10K    1.2       2083 mV
+VccP          ---    ---    1.0       1400 mV (1)
++5V           14K    10K    2.4       2083 mV
++12V          47K    10K    5.7       2105 mV
++3.3V (int)   2K     3.4K   1.588     3300 mV (2)
++3.3V (ext)   6.8K   10K    1.68      1964 mV
+
+(1) Depending on the CPU (1.4V is for a VIA C3 Nehemiah).
+(2) R1 and R2 for 3.3V (int) are internal to the VT1211 chip and the driver
+    performs the scaling and returns the properly scaled voltage value.
+
+Each measured voltage has an associated low and high limit which triggers an
+alarm when crossed.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are reported in millidegree Celsius. Each measured temperature
+has a high limit which triggers an alarm if crossed. There is an associated
+hysteresis value with each temperature below which the temperature has to drop
+before the alarm is cleared (this is only true for interrupt mode 0). The
+interrupt mode can be forced to 0 in case the BIOS doesn't do it
+automatically. See the 'Module Parameters' section for details.
+
+All temperature channels except temp2 are external. Temp2 is the VT1211
+internal thermal diode and the driver does all the scaling for temp2 and
+returns the temperature in millidegree Celsius. For the external channels
+temp1 and temp3-temp7, scaling depends on the board implementation and needs
+to be performed in userspace via sensors.conf.
+
+Temp1 is an Intel-type thermal diode which requires the following formula to
+convert between sysfs readings and real temperatures:
+
+compute temp1 (@-Offset)/Gain, (@*Gain)+Offset
+
+According to the VIA VT1211 BIOS porting guide, the following gain and offset
+values should be used:
+
+Diode Type      Offset   Gain
+----------      ------   ----
+Intel CPU       88.638   0.9528
+                65.000   0.9686   *)
+VIA C3 Ezra     83.869   0.9528
+VIA C3 Ezra-T   73.869   0.9528
+
+*) This is the formula from the lm_sensors 2.10.0 sensors.conf file. I don't
+know where it comes from or how it was derived, it's just listed here for
+completeness.
+
+Temp3-temp7 support NTC thermistors. For these channels, the driver returns
+the voltages as seen at the individual pins of UCH1-UCH5. The voltage at the
+pin (Vpin) is formed by a voltage divider made of the thermistor (Rth) and a
+scaling resistor (Rs):
+
+Vpin = 2200 * Rth / (Rs + Rth)   (2200 is the ADC max limit of 2200 mV)
+
+The equation for the thermistor is as follows (google it if you want to know
+more about it):
+
+Rth = Ro * exp(B * (1 / T - 1 / To))   (To is 298.15K (25C) and Ro is the
+                                        nominal resistance at 25C)
+
+Mingling the above two equations and assuming Rs = Ro and B = 3435 yields the
+following formula for sensors.conf:
+
+compute tempx 1 / (1 / 298.15 - (` (2200 / @ - 1)) / 3435) - 273.15,
+              2200 / (1 + (^ (3435 / 298.15 - 3435 / (273.15 + @))))
+
+
+Fan Speed Control
+-----------------
+
+The VT1211 provides 2 programmable PWM outputs to control the speeds of 2
+fans. Writing a 2 to any of the two pwm[1-2]_enable sysfs nodes will put the
+PWM controller in automatic mode. There is only a single controller that
+controls both PWM outputs but each PWM output can be individually enabled and
+disabled.
+
+Each PWM has 4 associated distinct output duty-cycles: full, high, low and
+off. Full and off are internally hard-wired to 255 (100%) and 0 (0%),
+respectively. High and low can be programmed via
+pwm[1-2]_auto_point[2-3]_pwm. Each PWM output can be associated with a
+different thermal input but - and here's the weird part - only one set of
+thermal thresholds exist that controls both PWMs output duty-cycles. The
+thermal thresholds are accessible via pwm[1-2]_auto_point[1-4]_temp. Note
+that even though there are 2 sets of 4 auto points each, they map to the same
+registers in the VT1211 and programming one set is sufficient (actually only
+the first set pwm1_auto_point[1-4]_temp is writable, the second set is
+read-only).
+
+PWM Auto Point             PWM Output Duty-Cycle
+------------------------------------------------
+pwm[1-2]_auto_point4_pwm   full speed duty-cycle (hard-wired to 255)
+pwm[1-2]_auto_point3_pwm   high speed duty-cycle
+pwm[1-2]_auto_point2_pwm   low speed duty-cycle
+pwm[1-2]_auto_point1_pwm   off duty-cycle (hard-wired to 0)
+
+Temp Auto Point             Thermal Threshold
+---------------------------------------------
+pwm[1-2]_auto_point4_temp   full speed temp
+pwm[1-2]_auto_point3_temp   high speed temp
+pwm[1-2]_auto_point2_temp   low speed temp
+pwm[1-2]_auto_point1_temp   off temp
+
+Long story short, the controller implements the following algorithm to set the
+PWM output duty-cycle based on the input temperature:
+
+Thermal Threshold             Output Duty-Cycle
+                    (Rising Temp)           (Falling Temp)
+----------------------------------------------------------
+                    full speed duty-cycle   full speed duty-cycle
+full speed temp
+                    high speed duty-cycle   full speed duty-cycle
+high speed temp
+                    low speed duty-cycle    high speed duty-cycle
+low speed temp
+                    off duty-cycle          low speed duty-cycle
+off temp
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
new file mode 100644 (file)
index 0000000..fae3b78
--- /dev/null
@@ -0,0 +1,85 @@
+Kernel driver w83627ehf
+=======================
+
+Supported chips:
+  * Winbond W83627EHF/EHG (ISA access ONLY)
+    Prefix: 'w83627ehf'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
+
+Authors:
+        Jean Delvare <khali@linux-fr.org>
+        Yuan Mu (Winbond)
+        Rudolf Marek <r.marek@sh.cvut.cz>
+
+Description
+-----------
+
+This driver implements support for the Winbond W83627EHF and W83627EHG
+super I/O chips. We will refer to them collectively as Winbond chips.
+
+The chips implement three temperature sensors, five fan rotation
+speed sensors, ten analog voltage sensors, alarms with beep warnings (control
+unimplemented), and some automatic fan regulation strategies (plus manual
+fan control mode).
+
+Temperatures are measured in degrees Celsius and measurement resolution is 1
+degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
+the temperature gets higher than high limit; it stays on until the temperature
+falls below the Hysteresis value.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 or
+128) to give the readings more range or accuracy. The driver sets the most
+suitable fan divisor itself. Some fans might not be present because they
+share pins with other functions.
+
+Voltage sensors (also known as IN sensors) report their values in millivolts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit.
+
+The driver supports automatic fan control mode known as Thermal Cruise.
+In this mode, the chip attempts to keep the measured temperature in a
+predefined temperature range. If the temperature goes out of range, fan
+is driven slower/faster to reach the predefined range again.
+
+The mode works for fan1-fan4. Mapping of temperatures to pwm outputs is as
+follows:
+
+temp1 -> pwm1
+temp2 -> pwm2
+temp3 -> pwm3
+prog  -> pwm4 (the programmable setting is not supported by the driver)
+
+/sys files
+----------
+
+pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
+          0 (stop) to 255 (full)
+
+pwm[1-4]_enable - this file controls mode of fan/temperature control:
+       * 1 Manual Mode, write to pwm file any value 0-255 (full speed)
+       * 2 Thermal Cruise
+
+Thermal Cruise mode
+-------------------
+
+If the temperature is in the range defined by:
+
+pwm[1-4]_target    - set target temperature, unit millidegree Celcius
+                    (range 0 - 127000)
+pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000)
+
+there are no changes to fan speed. Once the temperature leaves the interval,
+fan speed increases (temp is higher) or decreases if lower than desired.
+There are defined steps and times, but not exported by the driver yet.
+
+pwm[1-4]_min_output - minimum fan speed (range 1 - 255), when the temperature
+                      is below defined range.
+pwm[1-4]_stop_time  - how many milliseconds [ms] must elapse to switch
+                      corresponding fan off. (when the temperature was below
+                      defined range).
+
+Note: last two functions are influenced by other control bits, not yet exported
+      by the driver, so a change might not have any effect.
index 83a3836289c2e0db91f9148258d70effd860eb4c..19b2ed739fa1325e09ab91cb629ce69b3331a2af 100644 (file)
@@ -5,7 +5,7 @@ Supported chips:
   * Winbond W83791D
     Prefix: 'w83791d'
     Addresses scanned: I2C 0x2c - 0x2f
-    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf
+    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791D_W83791Gb.pdf
 
 Author: Charles Spirakis <bezaur@gmail.com>
 
@@ -20,6 +20,9 @@ Credits:
     Chunhao Huang <DZShen@Winbond.com.tw>,
     Rudolf Marek <r.marek@sh.cvut.cz>
 
+Additional contributors:
+    Sven Anders <anders@anduras.de>
+
 Module Parameters
 -----------------
 
@@ -46,7 +49,8 @@ Module Parameters
 Description
 -----------
 
-This driver implements support for the Winbond W83791D chip.
+This driver implements support for the Winbond W83791D chip. The W83791G
+chip appears to be the same as the W83791D but is lead free.
 
 Detection of the chip can sometimes be foiled because it can be in an
 internal state that allows no clean access (Bank with ID register is not
@@ -71,34 +75,36 @@ Voltage sensors (also known as IN sensors) report their values in millivolts.
 An alarm is triggered if the voltage has crossed a programmable minimum
 or maximum limit.
 
-Alarms are provided as output from a "realtime status register". The
-following bits are defined:
-
-bit - alarm on:
-0  - Vcore
-1  - VINR0
-2  - +3.3VIN
-3  - 5VDD
-4  - temp1
-5  - temp2
-6  - fan1
-7  - fan2
-8  - +12VIN
-9  - -12VIN
-10 - -5VIN
-11 - fan3
-12 - chassis
-13 - temp3
-14 - VINR1
-15 - reserved
-16 - tart1
-17 - tart2
-18 - tart3
-19 - VSB
-20 - VBAT
-21 - fan4
-22 - fan5
-23 - reserved
+The bit ordering for the alarm "realtime status register" and the
+"beep enable registers" are different.
+
+in0 (VCORE)  :  alarms: 0x000001 beep_enable: 0x000001
+in1 (VINR0)  :  alarms: 0x000002 beep_enable: 0x002000 <== mismatch
+in2 (+3.3VIN):  alarms: 0x000004 beep_enable: 0x000004
+in3 (5VDD)   :  alarms: 0x000008 beep_enable: 0x000008
+in4 (+12VIN) :  alarms: 0x000100 beep_enable: 0x000100
+in5 (-12VIN) :  alarms: 0x000200 beep_enable: 0x000200
+in6 (-5VIN)  :  alarms: 0x000400 beep_enable: 0x000400
+in7 (VSB)    :  alarms: 0x080000 beep_enable: 0x010000 <== mismatch
+in8 (VBAT)   :  alarms: 0x100000 beep_enable: 0x020000 <== mismatch
+in9 (VINR1)  :  alarms: 0x004000 beep_enable: 0x004000
+temp1        :  alarms: 0x000010 beep_enable: 0x000010
+temp2        :  alarms: 0x000020 beep_enable: 0x000020
+temp3        :  alarms: 0x002000 beep_enable: 0x000002 <== mismatch
+fan1         :  alarms: 0x000040 beep_enable: 0x000040
+fan2         :  alarms: 0x000080 beep_enable: 0x000080
+fan3         :  alarms: 0x000800 beep_enable: 0x000800
+fan4         :  alarms: 0x200000 beep_enable: 0x200000
+fan5         :  alarms: 0x400000 beep_enable: 0x400000
+tart1        :  alarms: 0x010000 beep_enable: 0x040000 <== mismatch
+tart2        :  alarms: 0x020000 beep_enable: 0x080000 <== mismatch
+tart3        :  alarms: 0x040000 beep_enable: 0x100000 <== mismatch
+case_open    :  alarms: 0x001000 beep_enable: 0x001000
+user_enable  :  alarms: -------- beep_enable: 0x800000
+
+*** NOTE: It is the responsibility of user-space code to handle the fact
+that the beep enable and alarm bits are in different positions when using that
+feature of the chip.
 
 When an alarm goes off, you can be warned by a beeping signal through your
 computer speaker. It is possible to enable all beeping globally, or only
@@ -109,5 +115,6 @@ often will do no harm, but will return 'old' values.
 
 W83791D TODO:
 ---------------
-Provide a patch for per-file alarms as discussed on the mailing list
+Provide a patch for per-file alarms and beep enables as defined in the hwmon
+       documentation (Documentation/hwmon/sysfs-interface)
 Provide a patch for smart-fan control (still need appropriate motherboard/fans)
index 54983246930d1aeb922c3691ac0b5a96028d97ef..137e993f4329aa9c6cc83a7835dcc9380312dbd6 100644 (file)
@@ -110,6 +110,13 @@ be entered as an environment variable, whereas its absence indicates that
 it will appear as a kernel argument readable via /proc/cmdline by programs
 running once the system is up.
 
+The number of kernel parameters is not limited, but the length of the
+complete command line (parameters including spaces etc.) is limited to
+a fixed number of characters. This limit depends on the architecture
+and is between 256 and 4096 characters. It is defined in the file
+./include/asm/setup.h as COMMAND_LINE_SIZE.
+
+
        53c7xx=         [HW,SCSI] Amiga SCSI controllers
                        See header of drivers/scsi/53c7xx.c.
                        See also Documentation/scsi/ncr53c7xx.txt.
@@ -1324,7 +1331,7 @@ running once the system is up.
        pt.             [PARIDE]
                        See Documentation/paride.txt.
 
-       quiet=          [KNL] Disable log messages
+       quiet           [KNL] Disable most log messages
 
        r128=           [HW,DRM]
 
index 44f2f769e8659dd2565c82a9ece8771150091a5f..18d385c068fc85b8a87deaef82caadd27e4204e6 100644 (file)
@@ -100,6 +100,7 @@ Examples:
                          are: IPSRC_RND #IP Source is random (between min/max),
                               IPDST_RND, UDPSRC_RND,
                               UDPDST_RND, MACSRC_RND, MACDST_RND 
+                              MPLS_RND, VID_RND, SVID_RND
 
  pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
                          cycle through the port range.
@@ -125,6 +126,21 @@ Examples:
 
  pgset "mpls 0"                  turn off mpls (or any invalid argument works too!)
 
+ pgset "vlan_id 77"       set VLAN ID 0-4095
+ pgset "vlan_p 3"         set priority bit 0-7 (default 0)
+ pgset "vlan_cfi 0"       set canonical format identifier 0-1 (default 0)
+
+ pgset "svlan_id 22"      set SVLAN ID 0-4095
+ pgset "svlan_p 3"        set priority bit 0-7 (default 0)
+ pgset "svlan_cfi 0"      set canonical format identifier 0-1 (default 0)
+
+ pgset "vlan_id 9999"     > 4095 remove vlan and svlan tags
+ pgset "svlan 9999"       > 4095 remove svlan tag
+
+
+ pgset "tos XX"           set former IPv4 TOS field (e.g. "tos 28" for AF11 no ECN, default 00)
+ pgset "traffic_class XX" set former IPv6 TRAFFIC CLASS (e.g. "traffic_class B8" for EF no ECN, default 00)
+
  pgset stop                      aborts injection. Also, ^C aborts generator.
 
 
diff --git a/Documentation/seclvl.txt b/Documentation/seclvl.txt
deleted file mode 100644 (file)
index 97274d1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-BSD Secure Levels Linux Security Module
-Michael A. Halcrow <mike@halcrow.us>
-
-
-Introduction
-
-Under the BSD Secure Levels security model, sets of policies are
-associated with levels. Levels range from -1 to 2, with -1 being the
-weakest and 2 being the strongest. These security policies are
-enforced at the kernel level, so not even the superuser is able to
-disable or circumvent them. This hardens the machine against attackers
-who gain root access to the system.
-
-
-Levels and Policies
-
-Level -1 (Permanently Insecure):
- - Cannot increase the secure level
-
-Level 0 (Insecure):
- - Cannot ptrace the init process
-
-Level 1 (Default):
- - /dev/mem and /dev/kmem are read-only
- - IMMUTABLE and APPEND extended attributes, if set, may not be unset
- - Cannot load or unload kernel modules
- - Cannot write directly to a mounted block device
- - Cannot perform raw I/O operations
- - Cannot perform network administrative tasks
- - Cannot setuid any file
-
-Level 2 (Secure):
- - Cannot decrement the system time
- - Cannot write to any block device, whether mounted or not
- - Cannot unmount any mounted filesystems
-
-
-Compilation
-
-To compile the BSD Secure Levels LSM, seclvl.ko, enable the
-SECURITY_SECLVL configuration option.  This is found under Security
-options -> BSD Secure Levels in the kernel configuration menu.
-
-
-Basic Usage
-
-Once the machine is in a running state, with all the necessary modules
-loaded and all the filesystems mounted, you can load the seclvl.ko
-module:
-
-# insmod seclvl.ko
-
-The module defaults to secure level 1, except when compiled directly
-into the kernel, in which case it defaults to secure level 0. To raise
-the secure level to 2, the administrator writes ``2'' to the
-seclvl/seclvl file under the sysfs mount point (assumed to be /sys in
-these examples):
-
-# echo -n "2" > /sys/seclvl/seclvl
-
-Alternatively, you can initialize the module at secure level 2 with
-the initlvl module parameter:
-
-# insmod seclvl.ko initlvl=2
-
-At this point, it is impossible to remove the module or reduce the
-secure level.  If the administrator wishes to have the option of doing
-so, he must provide a module parameter, sha1_passwd, that specifies
-the SHA1 hash of the password that can be used to reduce the secure
-level to 0.
-
-To generate this SHA1 hash, the administrator can use OpenSSL:
-
-# echo -n "boogabooga" | openssl sha1
-abeda4e0f33defa51741217592bf595efb8d289c
-
-In order to use password-instigated secure level reduction, the SHA1
-crypto module must be loaded or compiled into the kernel:
-
-# insmod sha1.ko
-
-The administrator can then insmod the seclvl module, including the
-SHA1 hash of the password:
-
-# insmod seclvl.ko
-         sha1_passwd=abeda4e0f33defa51741217592bf595efb8d289c
-
-To reduce the secure level, write the password to seclvl/passwd under
-your sysfs mount point:
-
-# echo -n "boogabooga" > /sys/seclvl/passwd
-
-The September 2004 edition of Sys Admin Magazine has an article about
-the BSD Secure Levels LSM.  I encourage you to refer to that article
-for a more in-depth treatment of this security module:
-
-http://www.samag.com/documents/s=9304/sam0409a/0409a.htm
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 63673e6513b717994de75ffb552f546f3c140ab8..f0cd5a3f6de69188f57e1aafb10406b58a2fe288 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
@@ -851,7 +851,7 @@ P:  Doug Warzecha
 M:     Douglas_Warzecha@dell.com
 S:     Maintained
 
-DEVICE-MAPPER
+DEVICE-MAPPER  (LVM)
 P:     Alasdair Kergon
 L:     dm-devel@redhat.com
 W:     http://sources.redhat.com/dm
@@ -1380,7 +1380,7 @@ S:        Maintained
 
 IDE/ATAPI CDROM DRIVER
 P:     Jens Axboe
-M:     axboe@suse.de
+M:     axboe@kernel.dk
 L:     linux-kernel@vger.kernel.org
 W:     http://www.kernel.dk
 S:     Maintained
@@ -1398,36 +1398,29 @@ M:      Gadi Oxman <gadio@netvision.net.il>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-IEEE 1394 ETHERNET (eth1394)
-L:     linux1394-devel@lists.sourceforge.net
-W:     http://www.linux1394.org/
-S:     Orphan
-
 IEEE 1394 SUBSYSTEM
 P:     Ben Collins
 M:     bcollins@debian.org
-P:     Jody McIntyre
-M:     scjody@modernduck.com
+P:     Stefan Richter
+M:     stefanr@s5r6.in-berlin.de
 L:     linux1394-devel@lists.sourceforge.net
 W:     http://www.linux1394.org/
-T:     git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
 S:     Maintained
 
-IEEE 1394 OHCI DRIVER
-P:     Ben Collins
-M:     bcollins@debian.org
-P:     Jody McIntyre
-M:     scjody@modernduck.com
+IEEE 1394 IPV4 DRIVER (eth1394)
+P:     Stefan Richter
+M:     stefanr@s5r6.in-berlin.de
 L:     linux1394-devel@lists.sourceforge.net
-W:     http://www.linux1394.org/
-S:     Maintained
+S:     Odd Fixes
 
 IEEE 1394 PCILYNX DRIVER
 P:     Jody McIntyre
 M:     scjody@modernduck.com
+P:     Stefan Richter
+M:     stefanr@s5r6.in-berlin.de
 L:     linux1394-devel@lists.sourceforge.net
-W:     http://www.linux1394.org/
-S:     Maintained
+S:     Odd Fixes
 
 IEEE 1394 RAW I/O DRIVER
 P:     Ben Collins
@@ -1435,16 +1428,6 @@ M:       bcollins@debian.org
 P:     Dan Dennedy
 M:     dan@dennedy.org
 L:     linux1394-devel@lists.sourceforge.net
-W:     http://www.linux1394.org/
-S:     Maintained
-
-IEEE 1394 SBP2
-P:     Ben Collins
-M:     bcollins@debian.org
-P:     Stefan Richter
-M:     stefanr@s5r6.in-berlin.de
-L:     linux1394-devel@lists.sourceforge.net
-W:     http://www.linux1394.org/
 S:     Maintained
 
 IMS TWINTURBO FRAMEBUFFER DRIVER
@@ -2062,7 +2045,7 @@ L:        linux-hams@vger.kernel.org
 W:     http://www.linux-ax25.org/
 S:     Maintained
 
-NETWORK BLOCK DEVICE
+NETWORK BLOCK DEVICE (NBD)
 P:     Paul Clements
 M:     Paul.Clements@steeleye.com
 S:     Maintained
@@ -2548,7 +2531,7 @@ S:        Maintained
 
 SCSI CDROM DRIVER
 P:     Jens Axboe
-M:     axboe@suse.de
+M:     axboe@kernel.dk
 L:     linux-scsi@vger.kernel.org
 W:     http://www.kernel.dk
 S:     Maintained
@@ -2810,6 +2793,12 @@ M:       R.E.Wolff@BitWizard.nl
 L:     linux-kernel@vger.kernel.org ?
 S:     Supported
 
+SPIDERNET NETWORK DRIVER for CELL
+P:     Jim Lewis
+M:     jim@jklewis.com
+L:     netdev@vger.kernel.org
+S:     Supported
+
 SRM (Alpha) environment access
 P:     Jan-Benedict Glaw
 M:     jbglaw@lug-owl.de
@@ -2834,12 +2823,9 @@ S:       Maintained
 SUPERH (sh)
 P:     Paul Mundt
 M:     lethal@linux-sh.org
-P:     Kazumoto Kojima
-M:     kkojima@rr.iij4u.or.jp
-L:     linuxsh-dev@lists.sourceforge.net
+L:     linuxsh-dev@lists.sourceforge.net (subscribers-only)
 W:     http://www.linux-sh.org
 W:     http://www.m17n.org/linux-sh/
-W:     http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
 S:     Maintained
 
 SUPERH64 (sh64)
@@ -2990,7 +2976,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
@@ -3309,6 +3295,12 @@ W:       http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
 
+VT1211 HARDWARE MONITOR DRIVER
+P:     Juerg Haefliger
+M:     juergh@gmail.com
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
 VT8231 HARDWARE MONITOR DRIVER
 P:     Roger Lucas
 M:     roger@planbit.co.uk
index b191cc75973751d5bdfe6137596a051a1c821b13..7c1e44420a78ce8ffa5e63ac6ec1930e2d0c80f9 100644 (file)
@@ -132,7 +132,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
        nticks = delta >> FIX_SHIFT;
 
        while (nticks > 0) {
-               do_timer(regs);
+               do_timer(1);
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
index 622dabd846800b14fb13c623eff5c61da0ac9cf7..8871529a34e2026e4f2bd4eda531df7ec59808a4 100644 (file)
@@ -193,7 +193,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
        /* We ran out of memory, or some other thing happened to us that
           made us unable to handle the page fault gracefully.  */
  out_of_memory:
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index f81a62380addefde7db4f0cde3902cb872c1c061..f9362ee9955f2411e932dbdca13a9dab5bf2c364 100644 (file)
@@ -17,6 +17,10 @@ config ARM
          Europe.  There is an ARM Linux project with a web page at
          <http://www.arm.linux.org.uk/>.
 
+config GENERIC_TIME
+       bool
+       default n
+
 config MMU
        bool
        default y
@@ -51,6 +55,10 @@ config GENERIC_HARDIRQS
        bool
        default y
 
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default y
+
 config HARDIRQS_SW_RESEND
        bool
        default y
@@ -91,7 +99,7 @@ config ARCH_MTD_XIP
 
 config VECTORS_BASE
        hex
-       default 0xffff0000 if MMU
+       default 0xffff0000 if MMU || CPU_HIGH_VECTOR
        default DRAM_BASE if REMAP_VECTORS_TO_RAM
        default 0x00000000
        help
@@ -198,16 +206,27 @@ config ARCH_IMX
        help
          Support for Motorola's i.MX family of processors (MX1, MXL).
 
-config ARCH_IOP3XX
-       bool "IOP3xx-based"
+config ARCH_IOP32X
+       bool "IOP32x-based"
+       depends on MMU
+       select PLAT_IOP
+       select PCI
+       help
+         Support for Intel's 80219 and IOP32X (XScale) family of
+         processors.
+
+config ARCH_IOP33X
+       bool "IOP33x-based"
        depends on MMU
+       select PLAT_IOP
        select PCI
        help
-         Support for Intel's IOP3XX (XScale) family of processors.
+         Support for Intel's IOP33X (XScale) family of processors.
 
 config ARCH_IXP4XX
        bool "IXP4xx-based"
        depends on MMU
+       select GENERIC_TIME
        help
          Support for Intel's IXP4XX (XScale) family of processors.
 
@@ -308,7 +327,9 @@ source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
 
-source "arch/arm/mach-iop3xx/Kconfig"
+source "arch/arm/mach-iop32x/Kconfig"
+
+source "arch/arm/mach-iop33x/Kconfig"
 
 source "arch/arm/mach-ixp4xx/Kconfig"
 
@@ -348,6 +369,9 @@ source "arch/arm/mach-netx/Kconfig"
 config ARCH_ACORN
        bool
 
+config PLAT_IOP
+       bool
+
 source arch/arm/mm/Kconfig
 
 #  bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
@@ -602,6 +626,7 @@ config LEDS_CPU
 
 config ALIGNMENT_TRAP
        bool
+       depends on CPU_CP15_MMU
        default y if !ARCH_EBSA110
        help
          ARM processors can not fetch/store information which is not
@@ -633,11 +658,12 @@ config ZBOOT_ROM_BSS
        hex "Compressed ROM boot loader BSS address"
        default "0"
        help
-         The base address of 64KiB of read/write memory in the target
-         for the ROM-able zImage, which must be available while the
-         decompressor is running.  Platforms which normally make use of
-         ROM-able zImage formats normally set this to a suitable
-         value in their defconfig file.
+         The base address of an area of read/write memory in the target
+         for the ROM-able zImage which must be available while the
+         decompressor is running. It must be large enough to hold the
+         entire decompressed kernel plus an additional 128 KiB.
+         Platforms which normally make use of ROM-able zImage formats
+         normally set this to a suitable value in their defconfig file.
 
          If ZBOOT_ROM is not enabled, this has no effect.
 
@@ -832,7 +858,7 @@ source "drivers/base/Kconfig"
 
 source "drivers/connector/Kconfig"
 
-if ALIGNMENT_TRAP
+if ALIGNMENT_TRAP || !CPU_CP15_MMU
 source "drivers/mtd/Kconfig"
 endif
 
@@ -844,7 +870,7 @@ source "drivers/block/Kconfig"
 
 source "drivers/acorn/block/Kconfig"
 
-if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
+if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
        || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
        || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
        || ARCH_IXP23XX
index e1574be2ded614e05633c715381df9086d69f776..f087376748d12253bb9f0414c6c742dfd6eb0b89 100644 (file)
@@ -25,6 +25,14 @@ config FLASH_SIZE
        hex 'FLASH Size' if SET_MEM_PARAM
        default 0x00400000
 
+config PROCESSOR_ID
+       hex
+       default 0x00007700
+       depends on !CPU_CP15
+       help
+         If processor has no CP15 register, this processor ID is
+         used instead of the auto-probing which utilizes the register.
+
 config REMAP_VECTORS_TO_RAM
        bool 'Install vectors to the begining of RAM' if DRAM_BASE
        depends on DRAM_BASE
index 92873cdee31f50d259bda86d3c8a3241f9aa149c..2a0b2c8a1fe00df55a7dd87092d4ce3661399cfe 100644 (file)
@@ -55,7 +55,12 @@ arch-$(CONFIG_CPU_32v3)              :=-D__LINUX_ARM_ARCH__=3 -march=armv3
 # This selects how we optimise for the processor.
 tune-$(CONFIG_CPU_ARM610)      :=-mtune=arm610
 tune-$(CONFIG_CPU_ARM710)      :=-mtune=arm710
+tune-$(CONFIG_CPU_ARM7TDMI)    :=-mtune=arm7tdmi
 tune-$(CONFIG_CPU_ARM720T)     :=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM740T)     :=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM9TDMI)    :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM940T)     :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM946T)     :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
 tune-$(CONFIG_CPU_ARM920T)     :=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_ARM922T)     :=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_ARM925T)     :=-mtune=arm9tdmi
@@ -101,7 +106,8 @@ endif
  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
- machine-$(CONFIG_ARCH_IOP3XX)    := iop3xx
+ machine-$(CONFIG_ARCH_IOP32X)    := iop32x
+ machine-$(CONFIG_ARCH_IOP33X)    := iop33x
  machine-$(CONFIG_ARCH_IXP4XX)    := ixp4xx
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
  machine-$(CONFIG_ARCH_IXP23XX)    := ixp23xx
@@ -157,6 +163,7 @@ core-$(CONFIG_FPE_FASTFPE)  += $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)             += arch/arm/vfp/
 
 # If we have a common platform directory, then include it in the build.
+core-$(CONFIG_PLAT_IOP)                += arch/arm/plat-iop/
 core-$(CONFIG_ARCH_OMAP)       += arch/arm/plat-omap/
 
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
index 2adc1527e0ebc9d7a3d4936b0eb4e767381e2e84..adddc71316852f5001314faf10678f5fc4e3ef8d 100644 (file)
@@ -51,7 +51,11 @@ OBJS         += head-at91rm9200.o
 endif
 
 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+ifeq ($(CONFIG_CPU_CP15),y)
 OBJS           += big-endian.o
+else
+# The endian should be set by h/w design.
+endif
 endif
 
 #
index 14a9ff9c68df4bfcdbca3fe97dcea28f702588a0..e5ab51b9cceb1bdfd155c9824ba6364d21cc1977 100644 (file)
 #ifdef DEBUG
 
 #if defined(CONFIG_DEBUG_ICEDCC)
+
+#ifdef CONFIG_CPU_V6
+               .macro  loadsp, rb
+               .endm
+               .macro  writeb, ch, rb
+               mcr     p14, 0, \ch, c0, c5, 0
+               .endm
+#else
                .macro  loadsp, rb
                .endm
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c0, c1, 0
                .endm
+#endif
+
 #else
 
 #include <asm/arch/debug-macro.S>
                add     \rb, \rb, #0x00010000   @ Ser1
 #endif
                .endm
-#elif defined(CONFIG_ARCH_IOP331)
-               .macro loadsp, rb
-                mov    \rb, #0xff000000
-                orr     \rb, \rb, #0x00ff0000
-                orr     \rb, \rb, #0x0000f700   @ location of the UART
-               .endm
 #elif defined(CONFIG_ARCH_S3C2410)
                .macro loadsp, rb
                mov     \rb, #0x50000000
                kphex   r6, 8           /* processor id */
                kputc   #':'
                kphex   r7, 8           /* architecture id */
+#ifdef CONFIG_CPU_CP15
                kputc   #':'
                mrc     p15, 0, r0, c1, c0
                kphex   r0, 8           /* control reg */
+#endif
                kputc   #'\n'
                kphex   r5, 8           /* decompressed kernel start */
                kputc   #'-'
@@ -503,7 +509,11 @@ call_kernel:       bl      cache_clean_flush
  */
 
 call_cache_fn: adr     r12, proc_types
+#ifdef CONFIG_CPU_CP15
                mrc     p15, 0, r6, c0, c0      @ get processor ID
+#else
+               ldr     r6, =CONFIG_PROCESSOR_ID
+#endif
 1:             ldr     r1, [r12, #0]           @ get value
                ldr     r2, [r12, #4]           @ get mask
                eor     r1, r1, r6              @ (real ^ match)
index ace3fb5835d9278833a0c539b8fff0b74e8af885..283891c736c4a9a92ab9f336f93b23ba83dfe956 100644 (file)
@@ -30,6 +30,25 @@ static void putstr(const char *ptr);
 #include <asm/arch/uncompress.h>
 
 #ifdef CONFIG_DEBUG_ICEDCC
+
+#ifdef CONFIG_CPU_V6
+
+static void icedcc_putc(int ch)
+{
+       int status, i = 0x4000000;
+
+       do {
+               if (--i < 0)
+                       return;
+
+               asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
+       } while (status & (1 << 29));
+
+       asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
+}
+
+#else
+
 static void icedcc_putc(int ch)
 {
        int status, i = 0x4000000;
@@ -44,6 +63,8 @@ static void icedcc_putc(int ch)
        asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
 }
 
+#endif
+
 #define putc(ch)       icedcc_putc(ch)
 #define flush()        do { } while (0)
 #endif
index bafe8b19be82a422ada8f2617a60b8022e584f08..6d094c1575400d0487b754ecb6a723ee474435dd 100644 (file)
@@ -57,7 +57,7 @@ icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq)
                        break;
        } while (i < ARRAY_SIZE(idx2s));
 
-       if (i > ARRAY_SIZE(idx2s))
+       if (i >= ARRAY_SIZE(idx2s))
                return vco;
 
        vco.s = idx2s[i];
@@ -119,7 +119,7 @@ icst307_ps_to_vco(const struct icst307_params *p, unsigned long period)
                        break;
        } while (i < ARRAY_SIZE(idx2s));
 
-       if (i > ARRAY_SIZE(idx2s))
+       if (i >= ARRAY_SIZE(idx2s))
                return vco;
 
        vco.s = idx2s[i];
index 943ef88c0379b79ee25505392cb21f3ade0a523f..3d377c5bdef6299332c068974753a0c41e8c939d 100644 (file)
@@ -55,7 +55,7 @@ icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq)
                        break;
        } while (i < ARRAY_SIZE(idx2s));
 
-       if (i > ARRAY_SIZE(idx2s))
+       if (i >= ARRAY_SIZE(idx2s))
                return vco;
 
        vco.s = idx2s[i];
@@ -118,7 +118,7 @@ icst525_ps_to_vco(const struct icst525_params *p, unsigned long period)
                        break;
        } while (i < ARRAY_SIZE(idx2s));
 
-       if (i > ARRAY_SIZE(idx2s))
+       if (i >= ARRAY_SIZE(idx2s))
                return vco;
 
        vco.s = idx2s[i];
index 4e0dcaef6eb204a4a5c344d2011baadcfd64502a..181ef1ead5b8362e1bef5fabe94f2659befceced 100644 (file)
@@ -121,6 +121,13 @@ static struct locomo_dev_info locomo_devices[] = {
                .offset         = 0,
                .length         = 0,
        },
+       {
+               .devid          = LOCOMO_DEVID_SPI,
+               .irq            = {},
+               .name           = "locomo-spi",
+               .offset         = LOCOMO_SPI,
+               .length         = 0x30,
+       },
 };
 
 
@@ -374,7 +381,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
        struct irqdesc *d;
        void __iomem *mapbase = get_irq_chipdata(irq);
 
-       req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F;
+       req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
        if (req) {
                irq = LOCOMO_IRQ_SPI_START;
                d = irq_desc + irq;
@@ -391,35 +398,35 @@ static void locomo_spi_ack_irq(unsigned int irq)
 {
        void __iomem *mapbase = get_irq_chipdata(irq);
        unsigned int r;
-       r = locomo_readl(mapbase + LOCOMO_SPIWE);
+       r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
        r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-       locomo_writel(r, mapbase + LOCOMO_SPIWE);
+       locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
 
-       r = locomo_readl(mapbase + LOCOMO_SPIIS);
+       r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
        r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-       locomo_writel(r, mapbase + LOCOMO_SPIIS);
+       locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
 
-       r = locomo_readl(mapbase + LOCOMO_SPIWE);
+       r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
        r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-       locomo_writel(r, mapbase + LOCOMO_SPIWE);
+       locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
 }
 
 static void locomo_spi_mask_irq(unsigned int irq)
 {
        void __iomem *mapbase = get_irq_chipdata(irq);
        unsigned int r;
-       r = locomo_readl(mapbase + LOCOMO_SPIIE);
+       r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
        r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-       locomo_writel(r, mapbase + LOCOMO_SPIIE);
+       locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
 }
 
 static void locomo_spi_unmask_irq(unsigned int irq)
 {
        void __iomem *mapbase = get_irq_chipdata(irq);
        unsigned int r;
-       r = locomo_readl(mapbase + LOCOMO_SPIIE);
+       r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
        r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-       locomo_writel(r, mapbase + LOCOMO_SPIIE);
+       locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
 }
 
 static struct irq_chip locomo_spi_chip = {
@@ -814,12 +821,15 @@ static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev)
        return (struct locomo *)dev_get_drvdata(ldev->dev.parent);
 }
 
-void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir)
+void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir)
 {
-       struct locomo *lchip = locomo_chip_driver(ldev);
+       struct locomo *lchip = dev_get_drvdata(dev);
        unsigned long flags;
        unsigned int r;
 
+       if (!lchip)
+               return;
+
        spin_lock_irqsave(&lchip->lock, flags);
 
        r = locomo_readl(lchip->base + LOCOMO_GPD);
@@ -836,12 +846,15 @@ void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned in
        spin_unlock_irqrestore(&lchip->lock, flags);
 }
 
-unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits)
+int locomo_gpio_read_level(struct device *dev, unsigned int bits)
 {
-       struct locomo *lchip = locomo_chip_driver(ldev);
+       struct locomo *lchip = dev_get_drvdata(dev);
        unsigned long flags;
        unsigned int ret;
 
+       if (!lchip)
+               return -ENODEV;
+
        spin_lock_irqsave(&lchip->lock, flags);
        ret = locomo_readl(lchip->base + LOCOMO_GPL);
        spin_unlock_irqrestore(&lchip->lock, flags);
@@ -850,12 +863,15 @@ unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits)
        return ret;
 }
 
-unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits)
+int locomo_gpio_read_output(struct device *dev, unsigned int bits)
 {
-       struct locomo *lchip = locomo_chip_driver(ldev);
+       struct locomo *lchip = dev_get_drvdata(dev);
        unsigned long flags;
        unsigned int ret;
 
+       if (!lchip)
+               return -ENODEV;
+
        spin_lock_irqsave(&lchip->lock, flags);
        ret = locomo_readl(lchip->base + LOCOMO_GPO);
        spin_unlock_irqrestore(&lchip->lock, flags);
@@ -864,12 +880,15 @@ unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits)
        return ret;
 }
 
-void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set)
+void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
 {
-       struct locomo *lchip = locomo_chip_driver(ldev);
+       struct locomo *lchip = dev_get_drvdata(dev);
        unsigned long flags;
        unsigned int r;
 
+       if (!lchip)
+               return;
+
        spin_lock_irqsave(&lchip->lock, flags);
 
        r = locomo_readl(lchip->base + LOCOMO_GPO);
@@ -1058,9 +1077,9 @@ void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
        struct locomo *lchip = locomo_chip_driver(dev);
 
        if (vr)
-               locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1);
+               locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);
        else
-               locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0);
+               locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
 
        spin_lock_irqsave(&lchip->lock, flags);
        locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
index 59b5ddec480f6992db54c2e8d0fdae5c9639b2ac..f412dedda68412b2c6ac239826e1adc14f03931a 100644 (file)
@@ -40,6 +40,7 @@
 #define SHARPSL_CHARGE_FINISH_TIME             (msecs_to_jiffies(10*60*1000)) /* 10 min */
 #define SHARPSL_BATCHK_TIME                    (msecs_to_jiffies(15*1000))    /* 15 sec */
 #define SHARPSL_BATCHK_TIME_SUSPEND            (60*10)                        /* 10 min */
+
 #define SHARPSL_WAIT_CO_TIME                   15  /* 15 sec */
 #define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
@@ -575,6 +576,9 @@ static int corgi_pxa_pm_enter(suspend_state_t state)
        while (corgi_enter_suspend(alarm_time,alarm_status,state))
                {}
 
+       if (sharpsl_pm.machinfo->earlyresume)
+               sharpsl_pm.machinfo->earlyresume();
+
        dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
 
        return 0;
index 2948b4589a8b4bc8bfea4ebb09d9c191c6a01e73..3b4802a849e444590175933b77fb73d5061cd724 100644 (file)
@@ -126,6 +126,7 @@ CONFIG_CRUNCH=y
 # EP93xx Platforms
 #
 CONFIG_MACH_EDB9302=y
+CONFIG_MACH_EDB9312=y
 CONFIG_MACH_EDB9315=y
 CONFIG_MACH_EDB9315A=y
 CONFIG_MACH_GESBC9312=y
similarity index 66%
rename from arch/arm/configs/ep80219_defconfig
rename to arch/arm/configs/iop32x_defconfig
index 3c73b707c2f387c3bb4aba5e69e9d32f700c67cd..0d67f66e78c259f224979191d90b21e256f1a66f 100644 (file)
@@ -1,50 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:34:12 2005
+# Linux kernel version: 2.6.18-rc7
+# Tue Sep 19 00:30:18 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_VECTORS_BASE=0xffff0000
+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_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 # 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_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=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_RT_MUTEXES=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_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,24 +65,52 @@ 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
 
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
 #
 # System Type
 #
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_IOP32X=y
+# CONFIG_ARCH_IOP33X is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
@@ -77,28 +118,19 @@ CONFIG_ARCH_IOP3XX=y
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
 
 #
-# IOP3xx Implementation Options
+# IOP32x Implementation Options
 #
 
 #
-# IOP3xx Platform Types
+# IOP32x Platform Types
 #
-# CONFIG_ARCH_IQ80321 is not set
+CONFIG_MACH_GLANTANK=y
+CONFIG_ARCH_IQ80321=y
 CONFIG_ARCH_IQ31244=y
-# CONFIG_ARCH_IQ80331 is not set
-# CONFIG_MACH_IQ80332 is not set
-CONFIG_ARCH_EP80219=y
-CONFIG_ARCH_IOP321=y
-# CONFIG_ARCH_IOP331 is not set
-
-#
-# IOP3xx Chipset Features
-#
+CONFIG_MACH_N2100=y
+CONFIG_PLAT_IOP=y
 
 #
 # Processor Type
@@ -109,7 +141,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -121,8 +152,7 @@ CONFIG_XSCALE_PMU=y
 # Bus support
 #
 CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -133,6 +163,19 @@ CONFIG_PCI_NAMES=y
 # Kernel Features
 #
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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=4096
+# CONFIG_RESOURCES_64BIT is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -140,7 +183,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
 # CONFIG_XIP_KERNEL is not set
 
 #
@@ -166,6 +209,93 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP 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_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
@@ -177,6 +307,13 @@ CONFIG_BINFMT_AOUT=y
 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)
@@ -200,6 +337,7 @@ 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
 
 #
 # RAM/ROM/Flash chip drivers
@@ -225,18 +363,18 @@ 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_XIP 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=y
-CONFIG_MTD_PHYSMAP_START=0xf0000000
-CONFIG_MTD_PHYSMAP_LEN=0x00800000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -245,7 +383,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # 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
 
 #
@@ -260,6 +397,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -272,7 +414,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 #
 # 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
@@ -284,17 +425,9 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
 # 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
 
 #
@@ -305,6 +438,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -316,6 +450,7 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -330,10 +465,12 @@ CONFIG_CHR_DEV_SG=y
 # 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
 
 #
 # 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
@@ -344,25 +481,19 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_DPT_I2O 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_BUSLOGIC is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA 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_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=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
@@ -377,8 +508,7 @@ CONFIG_BLK_DEV_MD=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=y
-# 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=y
@@ -392,6 +522,9 @@ CONFIG_BLK_DEV_DM=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
@@ -404,71 +537,8 @@ CONFIG_BLK_DEV_DM=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# 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)
-#
-# 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
@@ -480,6 +550,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -487,8 +562,10 @@ 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
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -526,16 +603,23 @@ CONFIG_E1000_NAPI=y
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
+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
 
 #
 # 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
@@ -558,6 +642,8 @@ CONFIG_E1000_NAPI=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
@@ -595,7 +681,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -603,6 +688,7 @@ CONFIG_SOUND_GAMEPORT=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
 
 #
@@ -610,7 +696,9 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -618,6 +706,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 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
@@ -631,8 +720,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -647,6 +736,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -671,14 +761,13 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 CONFIG_I2C_IOP3XX=y
-# CONFIG_I2C_ISA is not set
 # CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -689,15 +778,45 @@ CONFIG_I2C_IOP3XX=y
 # CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
 #
-# CONFIG_I2C_SENSOR is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
@@ -712,36 +831,45 @@ CONFIG_I2C_IOP3XX=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Other I2C Chip support
+# Misc devices
 #
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 
 #
-# Misc devices
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
 #
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -751,6 +879,7 @@ CONFIG_I2C_IOP3XX=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -758,6 +887,7 @@ CONFIG_I2C_IOP3XX=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -769,7 +899,125 @@ CONFIG_DUMMY_CONSOLE=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_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_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
 
 #
 # USB Gadget Support
@@ -781,11 +1029,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -795,22 +1050,22 @@ 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=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
+# 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
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -830,12 +1085,10 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=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_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -850,8 +1103,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
@@ -868,16 +1122,19 @@ CONFIG_JFFS2_RTIME=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=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 # CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -886,6 +1143,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
@@ -905,6 +1163,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
 
 #
@@ -921,11 +1180,34 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
+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 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 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 is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
 
 #
 # Security options
@@ -946,7 +1228,9 @@ CONFIG_DEBUG_USER=y
 # 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
similarity index 74%
rename from arch/arm/configs/iq80331_defconfig
rename to arch/arm/configs/iop33x_defconfig
index 46c79e1efe070644ed116f6b10eeb9a5cfbfa4ea..2a8fc153969d87e745c1ae8a432d34c1ef4d2801 100644 (file)
@@ -1,50 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 15:13:37 2005
+# Linux kernel version: 2.6.18-rc7
+# Tue Sep 19 00:30:42 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_VECTORS_BASE=0xffff0000
+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_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 # 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_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=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_RT_MUTEXES=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_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,24 +65,52 @@ 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
 
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
 #
 # System Type
 #
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+CONFIG_ARCH_IOP33X=y
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
@@ -77,28 +118,17 @@ CONFIG_ARCH_IOP3XX=y
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
 
 #
-# IOP3xx Implementation Options
+# IOP33x Implementation Options
 #
 
 #
-# IOP3xx Platform Types
+# IOP33x Platform Types
 #
-# CONFIG_ARCH_IQ80321 is not set
-# CONFIG_ARCH_IQ31244 is not set
 CONFIG_ARCH_IQ80331=y
-# CONFIG_MACH_IQ80332 is not set
-# CONFIG_ARCH_EP80219 is not set
-CONFIG_ARCH_IOP331=y
-
-#
-# IOP3xx Chipset Features
-#
-CONFIG_IOP331_STEPD=y
+CONFIG_MACH_IQ80332=y
+CONFIG_PLAT_IOP=y
 
 #
 # Processor Type
@@ -109,7 +139,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -121,8 +150,7 @@ CONFIG_XSCALE_PMU=y
 # Bus support
 #
 CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -133,6 +161,19 @@ CONFIG_PCI_NAMES=y
 # Kernel Features
 #
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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=4096
+# CONFIG_RESOURCES_64BIT is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -140,7 +181,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
 # CONFIG_XIP_KERNEL is not set
 
 #
@@ -166,6 +207,93 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP 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_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
@@ -177,6 +305,13 @@ CONFIG_BINFMT_AOUT=y
 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)
@@ -200,6 +335,7 @@ 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
 
 #
 # RAM/ROM/Flash chip drivers
@@ -222,6 +358,7 @@ 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_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
@@ -229,18 +366,18 @@ 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_XIP 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=y
-CONFIG_MTD_PHYSMAP_START=0xc0000000
-CONFIG_MTD_PHYSMAP_LEN=0x00800000
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -249,7 +386,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # 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
 
 #
@@ -264,6 +400,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -276,7 +417,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 #
 # 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
@@ -288,17 +428,9 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
 # 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
 
 #
@@ -309,6 +441,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -320,6 +453,7 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -334,10 +468,12 @@ CONFIG_CHR_DEV_SG=y
 # 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
 
 #
 # 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
@@ -348,25 +484,19 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_DPT_I2O 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_BUSLOGIC is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA 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_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=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
@@ -381,8 +511,7 @@ CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=y
-# 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=y
@@ -396,6 +525,9 @@ CONFIG_BLK_DEV_DM=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
@@ -408,71 +540,8 @@ CONFIG_BLK_DEV_DM=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# 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
-
+# Network device support
 #
-# 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
@@ -484,6 +553,10 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -501,14 +574,20 @@ CONFIG_E1000_NAPI=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_TIGON3 is not set
+# CONFIG_BNX2 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
@@ -531,6 +610,8 @@ CONFIG_E1000_NAPI=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
@@ -568,7 +649,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -576,6 +656,7 @@ CONFIG_SOUND_GAMEPORT=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
 
 #
@@ -583,7 +664,9 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -591,6 +674,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 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
@@ -604,8 +688,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -620,6 +704,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -644,14 +729,13 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 CONFIG_I2C_IOP3XX=y
-# CONFIG_I2C_ISA is not set
 # CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -662,15 +746,45 @@ CONFIG_I2C_IOP3XX=y
 # CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
 #
-# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI 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_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
@@ -685,36 +799,45 @@ CONFIG_I2C_IOP3XX=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Other I2C Chip support
+# Misc devices
 #
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 
 #
-# Misc devices
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
 #
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -724,6 +847,7 @@ CONFIG_I2C_IOP3XX=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -731,6 +855,7 @@ CONFIG_I2C_IOP3XX=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -742,8 +867,13 @@ CONFIG_DUMMY_CONSOLE=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
 #
 # USB Gadget Support
 #
@@ -754,11 +884,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -768,22 +905,22 @@ 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=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
+# 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
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -803,12 +940,10 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=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_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -834,16 +969,19 @@ 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=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 # CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -852,6 +990,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
@@ -871,6 +1010,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
 
 #
@@ -887,11 +1027,34 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
+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 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 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 is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
 
 #
 # Security options
@@ -912,5 +1075,7 @@ CONFIG_DEBUG_USER=y
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 # CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig
deleted file mode 100644 (file)
index 3246716..0000000
+++ /dev/null
@@ -1,922 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 02:10:38 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=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=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-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_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-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
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# IOP3xx Implementation Options
-#
-
-#
-# IOP3xx Platform Types
-#
-# CONFIG_ARCH_IQ80321 is not set
-CONFIG_ARCH_IQ31244=y
-# CONFIG_ARCH_IQ80331 is not set
-# CONFIG_MACH_IQ80332 is not set
-# CONFIG_ARCH_EP80219 is not set
-CONFIG_ARCH_IOP321=y
-# CONFIG_ARCH_IOP331 is not set
-
-#
-# IOP3xx Chipset Features
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-CONFIG_XSCALE_PMU=y
-
-#
-# Bus support
-#
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM 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=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# 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_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xf0000000
-CONFIG_MTD_PHYSMAP_LEN=0x00800000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 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
-
-#
-# 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 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 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=8192
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# 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
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O 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_DMX3191D is not set
-# CONFIG_SCSI_EATA 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_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=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_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-# CONFIG_MD_LINEAR is not set
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=y
-# CONFIG_MD_RAID6 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_CRYPT is not set
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH 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
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# 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)
-#
-# 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
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# 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_SK98LIN 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)
-#
-# 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_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-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 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
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_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
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-CONFIG_I2C_IOP3XX=y
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR 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
-
-#
-# XFS support
-#
-CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# 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_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_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_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_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN 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_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=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
-
-#
-# 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_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_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=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_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
deleted file mode 100644 (file)
index b000da7..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 13:24:10 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=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=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-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_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-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
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# IOP3xx Implementation Options
-#
-
-#
-# IOP3xx Platform Types
-#
-CONFIG_ARCH_IQ80321=y
-# CONFIG_ARCH_IQ31244 is not set
-# CONFIG_ARCH_IQ80331 is not set
-# CONFIG_MACH_IQ80332 is not set
-# CONFIG_ARCH_EP80219 is not set
-CONFIG_ARCH_IOP321=y
-# CONFIG_ARCH_IOP331 is not set
-
-#
-# IOP3xx Chipset Features
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-CONFIG_XSCALE_PMU=y
-
-#
-# Bus support
-#
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM 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=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# 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_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xf0000000
-CONFIG_MTD_PHYSMAP_LEN=0x00800000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 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
-
-#
-# 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 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 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=8192
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# 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
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE 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
-#
-# 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=y
-# 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)
-#
-# 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
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# 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_SK98LIN 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)
-#
-# 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
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-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 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
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_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
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-CONFIG_I2C_IOP3XX=y
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR 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
-
-#
-# XFS support
-#
-CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# 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_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_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_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_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN 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_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=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
-
-#
-# 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_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_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=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_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig
deleted file mode 100644 (file)
index 11959b7..0000000
+++ /dev/null
@@ -1,916 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 17:33:39 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=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=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-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_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-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
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-CONFIG_ARCH_IOP3XX=y
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# IOP3xx Implementation Options
-#
-
-#
-# IOP3xx Platform Types
-#
-# CONFIG_ARCH_IQ80321 is not set
-# CONFIG_ARCH_IQ31244 is not set
-# CONFIG_ARCH_IQ80331 is not set
-CONFIG_MACH_IQ80332=y
-# CONFIG_ARCH_EP80219 is not set
-CONFIG_ARCH_IOP331=y
-
-#
-# IOP3xx Chipset Features
-#
-# CONFIG_IOP331_STEPD is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-CONFIG_XSCALE_PMU=y
-
-#
-# Bus support
-#
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM 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=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_GEOMETRY is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# 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_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xc0000000
-CONFIG_MTD_PHYSMAP_LEN=0x00800000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 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
-
-#
-# 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 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 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=8192
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# 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
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O 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_DMX3191D is not set
-# CONFIG_SCSI_EATA 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_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=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_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=y
-# CONFIG_MD_RAID6 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_CRYPT is not set
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH 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
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# 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)
-#
-# 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
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# 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_SK98LIN 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)
-#
-# 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_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-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 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
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_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
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-CONFIG_I2C_IOP3XX=y
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR 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
-
-#
-# XFS support
-#
-CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# 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_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_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_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
-# 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_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=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
-
-#
-# 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_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_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=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_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
index f20814e6f4976b11441bd2a05b935c22a17259f7..a83222641045754afc8e0ec63a181d57cbd7cc72 100644 (file)
@@ -1,14 +1,19 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-git9
-# Sun Jun 25 23:56:32 2006
+# Linux kernel version: 2.6.18
+# Wed Sep 20 20:27:31 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -26,14 +31,15 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS 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_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -46,6 +52,8 @@ 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
@@ -84,7 +92,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
@@ -94,7 +102,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -122,13 +131,18 @@ CONFIG_ARCH_SMDK2410=y
 CONFIG_ARCH_S3C2440=y
 CONFIG_SMDK2440_CPU2440=y
 CONFIG_SMDK2440_CPU2442=y
+CONFIG_MACH_S3C2413=y
 CONFIG_MACH_SMDK2413=y
 CONFIG_MACH_VR1000=y
 CONFIG_MACH_RX3715=y
 CONFIG_MACH_OTOM=y
 CONFIG_MACH_NEXCODER_2440=y
+CONFIG_MACH_VSTMS=y
 CONFIG_S3C2410_CLOCK=y
+CONFIG_S3C2410_PM=y
+CONFIG_CPU_S3C2410_DMA=y
 CONFIG_CPU_S3C2410=y
+CONFIG_S3C2412_PM=y
 CONFIG_CPU_S3C2412=y
 CONFIG_CPU_S3C244X=y
 CONFIG_CPU_S3C2440=y
@@ -156,7 +170,7 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
 CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV4T=y
 CONFIG_CPU_ABRT_EV5TJ=y
@@ -200,6 +214,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -304,7 +319,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
 
@@ -460,6 +474,7 @@ CONFIG_BLK_DEV_NBD=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=y
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
@@ -640,6 +655,7 @@ CONFIG_SERIO_LIBPS2=y
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
@@ -716,6 +732,7 @@ CONFIG_S3C2410_WATCHDOG=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 CONFIG_S3C2410_RTC=y
 # CONFIG_DTLK is not set
@@ -857,12 +874,12 @@ CONFIG_VIDEO_V4L2=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_FIRMWARE_EDID=y
 # CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
@@ -995,7 +1012,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 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
@@ -1095,6 +1112,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
@@ -1202,14 +1220,19 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # CONFIG_PRINTK_TIME is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# 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_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
@@ -1251,3 +1274,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
index 33c55689f999ea3f7bcd6f4955d339b4d08fd343..ecf4f9472d94e950781e7bfdea05fd446bd40ade 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/completion.h>
+#include <linux/kthread.h>
 
 #include <asm/apm.h> /* apm_power_info */
 #include <asm/system.h>
@@ -80,7 +81,7 @@ struct apm_user {
  */
 static int suspends_pending;
 static int apm_disabled;
-static int arm_apm_active;
+static struct task_struct *kapmd_tsk;
 
 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
@@ -97,7 +98,6 @@ static LIST_HEAD(apm_user_list);
  * to be suspending the system.
  */
 static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
-static DECLARE_COMPLETION(kapmd_exit);
 static DEFINE_SPINLOCK(kapmd_queue_lock);
 static struct apm_queue kapmd_queue;
 
@@ -468,16 +468,13 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length)
 
 static int kapmd(void *arg)
 {
-       daemonize("kapmd");
-       current->flags |= PF_NOFREEZE;
-
        do {
                apm_event_t event;
 
                wait_event_interruptible(kapmd_wait,
-                               !queue_empty(&kapmd_queue) || !arm_apm_active);
+                               !queue_empty(&kapmd_queue) || kthread_should_stop());
 
-               if (!arm_apm_active)
+               if (kthread_should_stop())
                        break;
 
                spin_lock_irq(&kapmd_queue_lock);
@@ -508,7 +505,7 @@ static int kapmd(void *arg)
                }
        } while (1);
 
-       complete_and_exit(&kapmd_exit, 0);
+       return 0;
 }
 
 static int __init apm_init(void)
@@ -520,13 +517,14 @@ static int __init apm_init(void)
                return -ENODEV;
        }
 
-       arm_apm_active = 1;
-
-       ret = kernel_thread(kapmd, NULL, CLONE_KERNEL);
-       if (ret < 0) {
-               arm_apm_active = 0;
+       kapmd_tsk = kthread_create(kapmd, NULL, "kapmd");
+       if (IS_ERR(kapmd_tsk)) {
+               ret = PTR_ERR(kapmd_tsk);
+               kapmd_tsk = NULL;
                return ret;
        }
+       kapmd_tsk->flags |= PF_NOFREEZE;
+       wake_up_process(kapmd_tsk);
 
 #ifdef CONFIG_PROC_FS
        create_proc_info_entry("apm", 0, NULL, apm_get_info);
@@ -535,10 +533,7 @@ static int __init apm_init(void)
        ret = misc_register(&apm_device);
        if (ret != 0) {
                remove_proc_entry("apm", NULL);
-
-               arm_apm_active = 0;
-               wake_up(&kapmd_wait);
-               wait_for_completion(&kapmd_exit);
+               kthread_stop(kapmd_tsk);
        }
 
        return ret;
@@ -549,9 +544,7 @@ static void __exit apm_exit(void)
        misc_deregister(&apm_device);
        remove_proc_entry("apm", NULL);
 
-       arm_apm_active = 0;
-       wake_up(&kapmd_wait);
-       wait_for_completion(&kapmd_exit);
+       kthread_stop(kapmd_tsk);
 }
 
 module_init(apm_init);
index a5747e58a9dc66d37e0b7182b7f06be2795257a0..5617566477b493d5cc6034a8518b8f6e696195f3 100644 (file)
 
 #if defined(CONFIG_DEBUG_ICEDCC)
                @@ debug using ARM EmbeddedICE DCC channel
+
+#if defined(CONFIG_CPU_V6)
+
+               .macro  addruart, rx
+               .endm
+
+               .macro  senduart, rd, rx
+               mcr     p14, 0, \rd, c0, c5, 0
+               .endm
+
+               .macro  busyuart, rd, rx
+1001:
+               mrc     p14, 0, \rx, c0, c1, 0
+               tst     \rx, #0x20000000
+               beq     1001b
+               .endm
+
+               .macro  waituart, rd, rx
+               mov     \rd, #0x2000000
+1001:
+               subs    \rd, \rd, #1
+               bmi     1002f
+               mrc     p14, 0, \rx, c0, c1, 0
+               tst     \rx, #0x20000000
+               bne     1001b
+1002:
+               .endm
+
+#else
+
                .macro  addruart, rx
                .endm
 
                bne     1001b
 1002:
                .endm
+
+#endif /* CONFIG_CPU_V6 */
+
 #else
 #include <asm/arch/debug-macro.S>
-#endif
+#endif /* CONFIG_DEBUG_ICEDCC */
 
 /*
  * Useful debugging routines
index de4e331379013229082a76f86a3c314492ba206d..bd623b73445f79a9b37018e0da7d320d003c2a7c 100644 (file)
@@ -191,6 +191,9 @@ __dabt_svc:
 __irq_svc:
        svc_entry
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       bl      trace_hardirqs_off
+#endif
 #ifdef CONFIG_PREEMPT
        get_thread_info tsk
        ldr     r8, [tsk, #TI_PREEMPT]          @ get preempt count
@@ -211,6 +214,10 @@ preempt_return:
 #endif
        ldr     r0, [sp, #S_PSR]                @ irqs are already disabled
        msr     spsr_cxsf, r0
+#ifdef CONFIG_TRACE_IRQFLAGS
+       tst     r0, #PSR_I_BIT
+       bleq    trace_hardirqs_on
+#endif
        ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
 
        .ltorg
@@ -398,6 +405,9 @@ __dabt_usr:
 __irq_usr:
        usr_entry
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       bl      trace_hardirqs_off
+#endif
        get_thread_info tsk
 #ifdef CONFIG_PREEMPT
        ldr     r8, [tsk, #TI_PREEMPT]          @ get preempt count
@@ -412,6 +422,9 @@ __irq_usr:
        teq     r0, r7
        strne   r0, [r0, -r0]
 #endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+       bl      trace_hardirqs_on
+#endif
 
        mov     why, #0
        b       ret_to_user
index ac9eb3d30518ade76e1b01965fb969d90f856950..f359a189dcf2cda84f112dc0003e616cdd6434d4 100644 (file)
@@ -9,7 +9,6 @@
  * published by the Free Software Foundation.
  *
  *  Common kernel startup code (non-paged MM)
- *    for 32-bit CPUs which has a process ID register(CP15).
  *
  */
 #include <linux/linkage.h>
 ENTRY(stext)
        msr     cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
                                                @ and irqs disabled
+#ifndef CONFIG_CPU_CP15
+       ldr     r9, =CONFIG_PROCESSOR_ID
+#else
        mrc     p15, 0, r9, c0, c0              @ get processor id
+#endif
        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
        movs    r10, r5                         @ invalid processor (r5=0)?
        beq     __error_p                               @ yes, error 'p'
@@ -58,6 +61,7 @@ ENTRY(stext)
  */
        .type   __after_proc_init, %function
 __after_proc_init:
+#ifdef CONFIG_CPU_CP15
        mrc     p15, 0, r0, c1, c0, 0           @ read control reg
 #ifdef CONFIG_ALIGNMENT_TRAP
        orr     r0, r0, #CR_A
@@ -72,8 +76,14 @@ __after_proc_init:
 #endif
 #ifdef CONFIG_CPU_ICACHE_DISABLE
        bic     r0, r0, #CR_I
+#endif
+#ifdef CONFIG_CPU_HIGH_VECTOR
+       orr     r0, r0, #CR_V
+#else
+       bic     r0, r0, #CR_V
 #endif
        mcr     p15, 0, r0, c1, c0, 0           @ write control reg
+#endif /* CONFIG_CPU_CP15 */
 
        mov     pc, r13                         @ clear the BSS and jump
                                                @ to start_kernel
index 298363d97047755c3ac969baef5a95217a69bea8..1b061583408ed7f44158a7dfcf7b996e56f7a53f 100644 (file)
@@ -2,6 +2,7 @@
  *  linux/arch/arm/kernel/module.c
  *
  *  Copyright (C) 2002 Russell King.
+ *  Modified for nommu by Hyok S. Choi
  *
  * 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
@@ -32,6 +33,7 @@ extern void _etext;
 #define MODULE_START   (((unsigned long)&_etext + ~PGDIR_MASK) & PGDIR_MASK)
 #endif
 
+#ifdef CONFIG_MMU
 void *module_alloc(unsigned long size)
 {
        struct vm_struct *area;
@@ -46,6 +48,12 @@ void *module_alloc(unsigned long size)
 
        return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL);
 }
+#else /* CONFIG_MMU */
+void *module_alloc(unsigned long size)
+{
+       return size == 0 ? NULL : vmalloc(size);
+}
+#endif /* !CONFIG_MMU */
 
 void module_free(struct module *module, void *region)
 {
index 3079535afccd4be9daf1219c101ac8bc0959e7c7..bf35c178a8772d232fc5e5e1eb0e5ba91449a2fd 100644 (file)
@@ -221,16 +221,26 @@ void __show_regs(struct pt_regs *regs)
                processor_modes[processor_mode(regs)],
                thumb_mode(regs) ? " (T)" : "",
                get_fs() == get_ds() ? "kernel" : "user");
+#if CONFIG_CPU_CP15
        {
-               unsigned int ctrl, transbase, dac;
+               unsigned int ctrl;
                  __asm__ (
                "       mrc p15, 0, %0, c1, c0\n"
-               "       mrc p15, 0, %1, c2, c0\n"
-               "       mrc p15, 0, %2, c3, c0\n"
-               : "=r" (ctrl), "=r" (transbase), "=r" (dac));
-               printk("Control: %04X  Table: %08X  DAC: %08X\n",
-                       ctrl, transbase, dac);
+               : "=r" (ctrl));
+               printk("Control: %04X\n", ctrl);
        }
+#ifdef CONFIG_CPU_CP15_MMU
+       {
+               unsigned int transbase, dac;
+                 __asm__ (
+               "       mrc p15, 0, %0, c2, c0\n"
+               "       mrc p15, 0, %1, c3, c0\n"
+               : "=r" (transbase), "=r" (dac));
+               printk("Table: %08X  DAC: %08X\n",
+                       transbase, dac);
+       }
+#endif
+#endif
 }
 
 void show_regs(struct pt_regs * regs)
index 09a67d77185775937a6f70c9541172bbee416d67..f7d5165796ef2e337ea6a8473c4db562535efb1c 100644 (file)
@@ -69,10 +69,12 @@ EXPORT_SYMBOL(profile_pc);
  */
 int (*set_rtc)(void);
 
+#ifndef CONFIG_GENERIC_TIME
 static unsigned long dummy_gettimeoffset(void)
 {
        return 0;
 }
+#endif
 
 /*
  * Scheduler clock - returns current time in nanosec units.
@@ -230,6 +232,7 @@ static inline void do_leds(void)
 #define        do_leds()
 #endif
 
+#ifndef CONFIG_GENERIC_TIME
 void do_gettimeofday(struct timeval *tv)
 {
        unsigned long flags;
@@ -291,6 +294,7 @@ int do_settimeofday(struct timespec *tv)
 }
 
 EXPORT_SYMBOL(do_settimeofday);
+#endif /* !CONFIG_GENERIC_TIME */
 
 /**
  * save_time_delta - Save the offset between system time and RTC time
@@ -333,7 +337,7 @@ void timer_tick(struct pt_regs *regs)
        profile_tick(CPU_PROFILING, regs);
        do_leds();
        do_set_rtc();
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
@@ -500,8 +504,10 @@ device_initcall(timer_init_sysfs);
 
 void __init time_init(void)
 {
+#ifndef CONFIG_GENERIC_TIME
        if (system_timer->offset == NULL)
                system_timer->offset = dummy_gettimeoffset;
+#endif
        system_timer->init();
 
 #ifdef CONFIG_NO_IDLE_HZ
index aeeed806f9915574576e5ea628562a86d8f3a7b1..bede380c07a9ef2e285303756502792c2a7f0c45 100644 (file)
@@ -191,7 +191,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
        if (tsk != current)
                fp = thread_saved_fp(tsk);
        else
-               asm("mov%? %0, fp" : "=r" (fp));
+               asm("mov %0, fp" : "=r" (fp) : : "cc");
 
        c_backtrace(fp, 0x10);
        barrier();
index 0985b1c42c7c83f2523a91d87ba46756469e3358..dcf6136fedf9deb51f916a190634e0c333d416c1 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/hardware.h>
 #include "generic.h"
+#include "clock.h"
 
 static struct map_desc at91rm9200_io_desc[] __initdata = {
        {
@@ -26,87 +27,224 @@ static struct map_desc at91rm9200_io_desc[] __initdata = {
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_VA_BASE_SPI,
-               .pfn            = __phys_to_pfn(AT91_BASE_SPI),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_SSC2,
-               .pfn            = __phys_to_pfn(AT91_BASE_SSC2),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_SSC1,
-               .pfn            = __phys_to_pfn(AT91_BASE_SSC1),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_SSC0,
-               .pfn            = __phys_to_pfn(AT91_BASE_SSC0),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_US3,
-               .pfn            = __phys_to_pfn(AT91_BASE_US3),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_US2,
-               .pfn            = __phys_to_pfn(AT91_BASE_US2),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_US1,
-               .pfn            = __phys_to_pfn(AT91_BASE_US1),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_US0,
-               .pfn            = __phys_to_pfn(AT91_BASE_US0),
+               .pfn            = __phys_to_pfn(AT91RM9200_BASE_SPI),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_VA_BASE_EMAC,
-               .pfn            = __phys_to_pfn(AT91_BASE_EMAC),
+               .pfn            = __phys_to_pfn(AT91RM9200_BASE_EMAC),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_VA_BASE_TWI,
-               .pfn            = __phys_to_pfn(AT91_BASE_TWI),
+               .pfn            = __phys_to_pfn(AT91RM9200_BASE_TWI),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_VA_BASE_MCI,
-               .pfn            = __phys_to_pfn(AT91_BASE_MCI),
+               .pfn            = __phys_to_pfn(AT91RM9200_BASE_MCI),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_VA_BASE_UDP,
-               .pfn            = __phys_to_pfn(AT91_BASE_UDP),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_TCB1,
-               .pfn            = __phys_to_pfn(AT91_BASE_TCB1),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = AT91_VA_BASE_TCB0,
-               .pfn            = __phys_to_pfn(AT91_BASE_TCB0),
+               .pfn            = __phys_to_pfn(AT91RM9200_BASE_UDP),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = AT91_SRAM_VIRT_BASE,
-               .pfn            = __phys_to_pfn(AT91_SRAM_BASE),
-               .length         = AT91_SRAM_SIZE,
+               .pfn            = __phys_to_pfn(AT91RM9200_SRAM_BASE),
+               .length         = AT91RM9200_SRAM_SIZE,
                .type           = MT_DEVICE,
        },
 };
 
-void __init at91rm9200_map_io(void)
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk udc_clk = {
+       .name           = "udc_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_UDP,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+       .name           = "ohci_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_UHP,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ether_clk = {
+       .name           = "ether_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_EMAC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+       .name           = "mci_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_MCI,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+       .name           = "twi_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_TWI,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+       .name           = "usart0_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_US0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+       .name           = "usart1_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_US1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+       .name           = "usart2_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_US2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+       .name           = "usart3_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_US3,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi_clk = {
+       .name           = "spi_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_SPI,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioA_clk = {
+       .name           = "pioA_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_PIOA,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+       .name           = "pioB_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_PIOB,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+       .name           = "pioC_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_PIOC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioD_clk = {
+       .name           = "pioD_clk",
+       .pmc_mask       = 1 << AT91RM9200_ID_PIOD,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+       &pioA_clk,
+       &pioB_clk,
+       &pioC_clk,
+       &pioD_clk,
+       &usart0_clk,
+       &usart1_clk,
+       &usart2_clk,
+       &usart3_clk,
+       &mmc_clk,
+       &udc_clk,
+       &twi_clk,
+       &spi_clk,
+       // ssc 0 .. ssc2
+       // tc0 .. tc5
+       &ohci_clk,
+       &ether_clk,
+       // irq0 .. irq6
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+       .name           = "pck0",
+       .pmc_mask       = AT91_PMC_PCK0,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 0,
+};
+static struct clk pck1 = {
+       .name           = "pck1",
+       .pmc_mask       = AT91_PMC_PCK1,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 1,
+};
+static struct clk pck2 = {
+       .name           = "pck2",
+       .pmc_mask       = AT91_PMC_PCK2,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 2,
+};
+static struct clk pck3 = {
+       .name           = "pck3",
+       .pmc_mask       = AT91_PMC_PCK3,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 3,
+};
+
+static void __init at91rm9200_register_clocks(void)
 {
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+               clk_register(periph_clocks[i]);
+
+       clk_register(&pck0);
+       clk_register(&pck1);
+       clk_register(&pck2);
+       clk_register(&pck3);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91rm9200_gpio[] = {
+       {
+               .id             = AT91RM9200_ID_PIOA,
+               .offset         = AT91_PIOA,
+               .clock          = &pioA_clk,
+       }, {
+               .id             = AT91RM9200_ID_PIOB,
+               .offset         = AT91_PIOB,
+               .clock          = &pioB_clk,
+       }, {
+               .id             = AT91RM9200_ID_PIOC,
+               .offset         = AT91_PIOC,
+               .clock          = &pioC_clk,
+       }, {
+               .id             = AT91RM9200_ID_PIOD,
+               .offset         = AT91_PIOD,
+               .clock          = &pioD_clk,
+       }
+};
+
+/* --------------------------------------------------------------------
+ *  AT91RM9200 processor initialization
+ * -------------------------------------------------------------------- */
+void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
+{
+       /* Map peripherals */
        iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
+
+       /* Init clock subsystem */
+       at91_clock_init(main_clock);
+
+       /* Register the processor-specific clocks */
+       at91rm9200_register_clocks();
+
+       /* Initialize GPIO subsystem */
+       at91_gpio_init(at91rm9200_gpio, banks);
 }
 
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
 /*
  * The default interrupt priority levels (0 = lowest, 7 = highest).
  */
@@ -145,10 +283,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
        0       /* Advanced Interrupt Controller (IRQ6) */
 };
 
-void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS])
+void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
 {
        if (!priority)
                priority = at91rm9200_default_irq_priority;
 
+       /* Initialize the AIC interrupt controller */
        at91_aic_init(priority);
+
+       /* Enable GPIO interrupts */
+       at91_gpio_irq_setup();
 }
index dc79e0992af71955056aa78ad2165f62d93678fc..36eecd7161f5646d64d706513433b17becc3d232 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init onearm_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(PQFP_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -62,15 +53,18 @@ static struct at91_uart_config __initdata onearm_uart_config = {
 
 static void __init onearm_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 18.432 MHz crystal */
-       at91_clock_init(18432000);
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_PQFP);
 
        /* Setup the serial ports and console */
        at91_init_serial(&onearm_uart_config);
 }
 
+static void __init onearm_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata onearm_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 1,
index 2c138b542ebe65b345fd0dae41f50c549280a9f2..50e513681ae6b1c3d897f3919cf7fed71888872c 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init carmeva_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -63,15 +54,19 @@ static struct at91_uart_config __initdata carmeva_uart_config = {
 
 static void __init carmeva_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 20.000 MHz crystal */
-       at91_clock_init(20000000);
+       /* Initialize processor: 20.000 MHz crystal */
+       at91rm9200_initialize(20000000, AT91RM9200_BGA);
 
        /* Setup the serial ports and console */
        at91_init_serial(&carmeva_uart_config);
 }
 
+static void __init carmeva_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+
 static struct at91_eth_data __initdata carmeva_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 1,
index 794d3fbb449ba0b3d6efe1f4985cb9a6a6fb0275..8eeae491ce712c83d714b99c8ffa72b5c58fee48 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init csb337_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata csb337_uart_config = {
 
 static void __init csb337_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 3.6864 MHz crystal */
-       at91_clock_init(3686400);
+       /* Initialize processor: 3.6864 MHz crystal */
+       at91rm9200_initialize(3686400, AT91RM9200_BGA);
 
        /* Setup the LEDs */
        at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
@@ -74,6 +63,11 @@ static void __init csb337_map_io(void)
        at91_init_serial(&csb337_uart_config);
 }
 
+static void __init csb337_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata csb337_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC2,
        .is_rmii        = 0,
index c8b6f334246a9b41470e52ff3658854d760e16c2..a29fa0e822ce61af2ebec8f62b8450f89b9b0b0b 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init csb637_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -61,10 +52,8 @@ static struct at91_uart_config __initdata csb637_uart_config = {
 
 static void __init csb637_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 3.6864 MHz crystal */
-       at91_clock_init(3686400);
+       /* Initialize processor: 3.6864 MHz crystal */
+       at91rm9200_initialize(3686400, AT91RM9200_BGA);
 
        /* Setup the LEDs */
        at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -73,6 +62,11 @@ static void __init csb637_map_io(void)
        at91_init_serial(&csb637_uart_config);
 }
 
+static void __init csb637_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata csb637_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC0,
        .is_rmii        = 0,
index 65873037e02ad94572290e4848fb330b16b01491..c699f3984d4b086b25820257b2c6a11c9172cffd 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init dk_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata dk_uart_config = {
 
 static void __init dk_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 18.432 MHz crystal */
-       at91_clock_init(18432000);
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
 
        /* Setup the LEDs */
        at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -77,6 +66,11 @@ static void __init dk_map_io(void)
        at91_init_serial(&dk_uart_config);
 }
 
+static void __init dk_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata dk_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 1,
@@ -128,6 +122,29 @@ static struct spi_board_info dk_spi_devices[] = {
 #endif
 };
 
+static struct mtd_partition __initdata dk_nand_partition[] = {
+       {
+               .name   = "NAND Partition 1",
+               .offset = 0,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(dk_nand_partition);
+       return dk_nand_partition;
+}
+
+static struct at91_nand_data __initdata dk_nand_data = {
+       .ale            = 22,
+       .cle            = 21,
+       .det_pin        = AT91_PIN_PB1,
+       .rdy_pin        = AT91_PIN_PC2,
+       // .enable_pin  = ... not there
+       .partition_info = nand_partitions,
+};
+
 static void __init dk_board_init(void)
 {
        /* Serial */
@@ -153,6 +170,8 @@ static void __init dk_board_init(void)
        at91_set_gpio_output(AT91_PIN_PB7, 1);  /* this MMC card slot can optionally use SPI signaling (CS3). */
        at91_add_device_mmc(&dk_mmc_data);
 #endif
+       /* NAND */
+       at91_add_device_nand(&dk_nand_data);
        /* VGA */
 //     dk_add_device_video();
 }
index a3e2df968a66b1801f62b230f86fc106d4b1a332..c6e0d51fbea0c31c0a230531b7b89c227cbb68b1 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init eb9200_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -63,15 +54,18 @@ static struct at91_uart_config __initdata eb9200_uart_config = {
 
 static void __init eb9200_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 18.432 MHz crystal */
-       at91_clock_init(18432000);
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
 
        /* Setup the serial ports and console */
        at91_init_serial(&eb9200_uart_config);
 }
 
+static void __init eb9200_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata eb9200_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 1,
index 868192351ddaf8dcde4af7d35100e6e1e42a9543..830eb7932178dee09e72c554cc8fddfa72e70d9f 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init ek_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(BGA_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata ek_uart_config = {
 
 static void __init ek_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 18.432 MHz crystal */
-       at91_clock_init(18432000);
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
 
        /* Setup the LEDs */
        at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
@@ -77,6 +66,11 @@ static void __init ek_map_io(void)
        at91_init_serial(&ek_uart_config);
 }
 
+static void __init ek_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata ek_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 1,
index bf760c5e0c469692e8ae4547b0081205eec952b6..91e301924f2cc178f8f936478ac7a4d00229e189 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init kafa_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(PQFP_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata kafa_uart_config = {
 
 static void __init kafa_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 18.432 MHz crystal */
-       at91_clock_init(18432000);
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_PQFP);
 
        /* Set up the LEDs */
        at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
@@ -74,6 +63,11 @@ static void __init kafa_map_io(void)
        at91_init_serial(&kafa_uart_config);
 }
 
+static void __init kafa_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata kafa_eth_data = {
        .phy_irq_pin    = AT91_PIN_PC4,
        .is_rmii        = 0,
index f06d2b54cc9a880d5d872425d6b3ca5a730a90ab..272fe43bceca0c070f90bbeed8137ae0875e8bfc 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/hardware.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 #include "generic.h"
 
-static void __init kb9202_init_irq(void)
-{
-       /* Initialize AIC controller */
-       at91rm9200_init_irq(NULL);
-
-       /* Set up the GPIO interrupts */
-       at91_gpio_irq_setup(PQFP_GPIO_BANKS);
-}
 
 /*
  * Serial port configuration.
@@ -63,10 +54,8 @@ static struct at91_uart_config __initdata kb9202_uart_config = {
 
 static void __init kb9202_map_io(void)
 {
-       at91rm9200_map_io();
-
-       /* Initialize clocks: 10 MHz crystal */
-       at91_clock_init(10000000);
+       /* Initialize processor: 10 MHz crystal */
+       at91rm9200_initialize(10000000, AT91RM9200_PQFP);
 
        /* Set up the LEDs */
        at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
@@ -75,6 +64,11 @@ static void __init kb9202_map_io(void)
        at91_init_serial(&kb9202_uart_config);
 }
 
+static void __init kb9202_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
 static struct at91_eth_data __initdata kb9202_eth_data = {
        .phy_irq_pin    = AT91_PIN_PB29,
        .is_rmii        = 0,
@@ -95,6 +89,29 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = {
        .wire4          = 1,
 };
 
+static struct mtd_partition __initdata kb9202_nand_partition[] = {
+       {
+               .name   = "nand_fs",
+               .offset = 0,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
+       return kb9202_nand_partition;
+}
+
+static struct at91_nand_data __initdata kb9202_nand_data = {
+       .ale            = 22,
+       .cle            = 21,
+       // .det_pin     = ... not there
+       .rdy_pin        = AT91_PIN_PC29,
+       .enable_pin     = AT91_PIN_PC28,
+       .partition_info = nand_partitions,
+};
+
 static void __init kb9202_board_init(void)
 {
        /* Serial */
@@ -111,6 +128,8 @@ static void __init kb9202_board_init(void)
        at91_add_device_i2c();
        /* SPI */
        at91_add_device_spi(NULL, 0);
+       /* NAND */
+       at91_add_device_nand(&kb9202_nand_data);
 }
 
 MACHINE_START(KB9200, "KB920x")
index edc2cc837ae630b34381397f69fbbf7c157cf1e3..a43b061a7c852789d404f931658217a8a4fdd6e1 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <asm/hardware.h>
 
-#include "generic.h"
+#include "clock.h"
 
 
 /*
  * PLLB be used at other rates (on boards that don't need USB), etc.
  */
 
-struct clk {
-       const char      *name;          /* unique clock name */
-       const char      *function;      /* function of the clock */
-       struct device   *dev;           /* device associated with function */
-       unsigned long   rate_hz;
-       struct clk      *parent;
-       u32             pmc_mask;
-       void            (*mode)(struct clk *, int);
-       unsigned        id:2;           /* PCK0..3, or 32k/main/a/b */
-       unsigned        primary:1;
-       unsigned        pll:1;
-       unsigned        programmable:1;
-       u16             users;
-};
+#define clk_is_primary(x)      ((x)->type & CLK_TYPE_PRIMARY)
+#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
+#define clk_is_peripheral(x)   ((x)->type & CLK_TYPE_PERIPHERAL)
+
+
+static LIST_HEAD(clocks);
+static DEFINE_SPINLOCK(clk_lock);
 
-static spinlock_t      clk_lock;
-static u32             at91_pllb_usb_init;
+static u32 at91_pllb_usb_init;
 
 /*
  * Four primary clock sources:  two crystal oscillators (32K, main), and
@@ -67,21 +59,20 @@ static struct clk clk32k = {
        .rate_hz        = AT91_SLOW_CLOCK,
        .users          = 1,            /* always on */
        .id             = 0,
-       .primary        = 1,
+       .type           = CLK_TYPE_PRIMARY,
 };
 static struct clk main_clk = {
        .name           = "main",
        .pmc_mask       = AT91_PMC_MOSCS,       /* in PMC_SR */
        .id             = 1,
-       .primary        = 1,
+       .type           = CLK_TYPE_PRIMARY,
 };
 static struct clk plla = {
        .name           = "plla",
        .parent         = &main_clk,
        .pmc_mask       = AT91_PMC_LOCKA,       /* in PMC_SR */
        .id             = 2,
-       .primary        = 1,
-       .pll            = 1,
+       .type           = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
 };
 
 static void pllb_mode(struct clk *clk, int is_on)
@@ -94,6 +85,7 @@ static void pllb_mode(struct clk *clk, int is_on)
        } else
                value = 0;
 
+       // REVISIT: Add work-around for AT91RM9200 Errata #26 ?
        at91_sys_write(AT91_CKGR_PLLBR, value);
 
        do {
@@ -107,8 +99,7 @@ static struct clk pllb = {
        .pmc_mask       = AT91_PMC_LOCKB,       /* in PMC_SR */
        .mode           = pllb_mode,
        .id             = 3,
-       .primary        = 1,
-       .pll            = 1,
+       .type           = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
 };
 
 static void pmc_sys_mode(struct clk *clk, int is_on)
@@ -133,41 +124,6 @@ static struct clk uhpck = {
        .mode           = pmc_sys_mode,
 };
 
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-/*
- * The four programmable clocks can be parented by any primary clock.
- * You must configure pin multiplexing to bring these signals out.
- */
-static struct clk pck0 = {
-       .name           = "pck0",
-       .pmc_mask       = AT91_PMC_PCK0,
-       .mode           = pmc_sys_mode,
-       .programmable   = 1,
-       .id             = 0,
-};
-static struct clk pck1 = {
-       .name           = "pck1",
-       .pmc_mask       = AT91_PMC_PCK1,
-       .mode           = pmc_sys_mode,
-       .programmable   = 1,
-       .id             = 1,
-};
-static struct clk pck2 = {
-       .name           = "pck2",
-       .pmc_mask       = AT91_PMC_PCK2,
-       .mode           = pmc_sys_mode,
-       .programmable   = 1,
-       .id             = 2,
-};
-static struct clk pck3 = {
-       .name           = "pck3",
-       .pmc_mask       = AT91_PMC_PCK3,
-       .mode           = pmc_sys_mode,
-       .programmable   = 1,
-       .id             = 3,
-};
-#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
-
 
 /*
  * The master clock is divided from the CPU clock (by 1-4).  It's used for
@@ -187,131 +143,21 @@ static void pmc_periph_mode(struct clk *clk, int is_on)
                at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
 }
 
-static struct clk udc_clk = {
-       .name           = "udc_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_UDP,
-       .mode           = pmc_periph_mode,
-};
-static struct clk ohci_clk = {
-       .name           = "ohci_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_UHP,
-       .mode           = pmc_periph_mode,
-};
-static struct clk ether_clk = {
-       .name           = "ether_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_EMAC,
-       .mode           = pmc_periph_mode,
-};
-static struct clk mmc_clk = {
-       .name           = "mci_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_MCI,
-       .mode           = pmc_periph_mode,
-};
-static struct clk twi_clk = {
-       .name           = "twi_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_TWI,
-       .mode           = pmc_periph_mode,
-};
-static struct clk usart0_clk = {
-       .name           = "usart0_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_US0,
-       .mode           = pmc_periph_mode,
-};
-static struct clk usart1_clk = {
-       .name           = "usart1_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_US1,
-       .mode           = pmc_periph_mode,
-};
-static struct clk usart2_clk = {
-       .name           = "usart2_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_US2,
-       .mode           = pmc_periph_mode,
-};
-static struct clk usart3_clk = {
-       .name           = "usart3_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_US3,
-       .mode           = pmc_periph_mode,
-};
-static struct clk spi_clk = {
-       .name           = "spi0_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_SPI,
-       .mode           = pmc_periph_mode,
-};
-static struct clk pioA_clk = {
-       .name           = "pioA_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_PIOA,
-       .mode           = pmc_periph_mode,
-};
-static struct clk pioB_clk = {
-       .name           = "pioB_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_PIOB,
-       .mode           = pmc_periph_mode,
-};
-static struct clk pioC_clk = {
-       .name           = "pioC_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_PIOC,
-       .mode           = pmc_periph_mode,
-};
-static struct clk pioD_clk = {
-       .name           = "pioD_clk",
-       .parent         = &mck,
-       .pmc_mask       = 1 << AT91_ID_PIOD,
-       .mode           = pmc_periph_mode,
-};
-
-static struct clk *const clock_list[] = {
-       /* four primary clocks -- MUST BE FIRST! */
-       &clk32k,
-       &main_clk,
-       &plla,
-       &pllb,
-
-       /* PLLB children (USB) */
-       &udpck,
-       &uhpck,
-
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-       /* programmable clocks */
-       &pck0,
-       &pck1,
-       &pck2,
-       &pck3,
-#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
-
-       /* MCK and peripherals */
-       &mck,
-       &usart0_clk,
-       &usart1_clk,
-       &usart2_clk,
-       &usart3_clk,
-       &mmc_clk,
-       &udc_clk,
-       &twi_clk,
-       &spi_clk,
-       &pioA_clk,
-       &pioB_clk,
-       &pioC_clk,
-       &pioD_clk,
-       // ssc0..ssc2
-       // tc0..tc5
-       // irq0..irq6
-       &ohci_clk,
-       &ether_clk,
-};
+static struct clk __init *at91_css_to_clk(unsigned long css)
+{
+       switch (css) {
+               case AT91_PMC_CSS_SLOW:
+                       return &clk32k;
+               case AT91_PMC_CSS_MAIN:
+                       return &main_clk;
+               case AT91_PMC_CSS_PLLA:
+                       return &plla;
+               case AT91_PMC_CSS_PLLB:
+                       return &pllb;
+       }
 
+       return NULL;
+}
 
 /*
  * Associate a particular clock with a function (eg, "uart") and device.
@@ -329,14 +175,12 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char
        clk->dev = dev;
 }
 
-/* clocks are all static for now; no refcounting necessary */
+/* clocks cannot be de-registered no refcounting necessary */
 struct clk *clk_get(struct device *dev, const char *id)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-               struct clk *clk = clock_list[i];
+       struct clk *clk;
 
+       list_for_each_entry(clk, &clocks, node) {
                if (strcmp(id, clk->name) == 0)
                        return clk;
                if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0)
@@ -424,7 +268,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
        unsigned        prescale;
        unsigned long   actual;
 
-       if (!clk->programmable)
+       if (!clk_is_programmable(clk))
                return -EINVAL;
        spin_lock_irqsave(&clk_lock, flags);
 
@@ -446,7 +290,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        unsigned        prescale;
        unsigned long   actual;
 
-       if (!clk->programmable)
+       if (!clk_is_programmable(clk))
                return -EINVAL;
        if (clk->users)
                return -EBUSY;
@@ -484,7 +328,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 
        if (clk->users)
                return -EBUSY;
-       if (!parent->primary || !clk->programmable)
+       if (!clk_is_primary(parent) || !clk_is_programmable(clk))
                return -EINVAL;
        spin_lock_irqsave(&clk_lock, flags);
 
@@ -497,6 +341,18 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 }
 EXPORT_SYMBOL(clk_set_parent);
 
+/* establish PCK0..PCK3 parentage and rate */
+static void init_programmable_clock(struct clk *clk)
+{
+       struct clk      *parent;
+       u32             pckr;
+
+       pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+       parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
+       clk->parent = parent;
+       clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
+}
+
 #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
 
 /*------------------------------------------------------------------------*/
@@ -506,6 +362,7 @@ EXPORT_SYMBOL(clk_set_parent);
 static int at91_clk_show(struct seq_file *s, void *unused)
 {
        u32             scsr, pcsr, sr;
+       struct clk      *clk;
        unsigned        i;
 
        seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
@@ -523,9 +380,8 @@ static int at91_clk_show(struct seq_file *s, void *unused)
 
        seq_printf(s, "\n");
 
-       for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-               char            *state;
-               struct clk      *clk = clock_list[i];
+       list_for_each_entry(clk, &clocks, node) {
+               char    *state;
 
                if (clk->mode == pmc_sys_mode)
                        state = (scsr & clk->pmc_mask) ? "on" : "off";
@@ -568,6 +424,28 @@ postcore_initcall(at91_clk_debugfs_init);
 
 #endif
 
+/*------------------------------------------------------------------------*/
+
+/* Register a new clock */
+int __init clk_register(struct clk *clk)
+{
+       if (clk_is_peripheral(clk)) {
+               clk->parent = &mck;
+               clk->mode = pmc_periph_mode;
+               list_add_tail(&clk->node, &clocks);
+       }
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+       else if (clk_is_programmable(clk)) {
+               clk->mode = pmc_sys_mode;
+               init_programmable_clock(clk);
+               list_add_tail(&clk->node, &clocks);
+       }
+#endif
+
+       return 0;
+}
+
+
 /*------------------------------------------------------------------------*/
 
 static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
@@ -640,20 +518,17 @@ fail:
        return 0;
 }
 
-
 /*
  * Several unused clocks may be active.  Turn them off.
  */
-static void at91_periphclk_reset(void)
+static void __init at91_periphclk_reset(void)
 {
        unsigned long reg;
-       int i;
+       struct clk *clk;
 
        reg = at91_sys_read(AT91_PMC_PCSR);
 
-       for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
-               struct clk      *clk = clock_list[i];
-
+       list_for_each_entry(clk, &clocks, node) {
                if (clk->mode != pmc_periph_mode)
                        continue;
 
@@ -664,11 +539,25 @@ static void at91_periphclk_reset(void)
        at91_sys_write(AT91_PMC_PCDR, reg);
 }
 
+static struct clk *const standard_pmc_clocks[] __initdata = {
+       /* four primary clocks */
+       &clk32k,
+       &main_clk,
+       &plla,
+       &pllb,
+
+       /* PLLB children (USB) */
+       &udpck,
+       &uhpck,
+
+       /* MCK */
+       &mck
+};
+
 int __init at91_clock_init(unsigned long main_clock)
 {
        unsigned tmp, freq, mckr;
-
-       spin_lock_init(&clk_lock);
+       int i;
 
        /*
         * When the bootloader initialized the main oscillator correctly,
@@ -709,11 +598,15 @@ int __init at91_clock_init(unsigned long main_clock)
         * For now, assume this parentage won't change.
         */
        mckr = at91_sys_read(AT91_PMC_MCKR);
-       mck.parent = clock_list[mckr & AT91_PMC_CSS];
+       mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
        freq = mck.parent->rate_hz;
        freq /= (1 << ((mckr >> 2) & 3));               /* prescale */
        mck.rate_hz = freq / (1 + ((mckr >> 8) & 3));   /* mdiv */
 
+       /* Register the PMC's standard clocks */
+       for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
+               list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
+
        /* MCK and CPU clock are "always on" */
        clk_enable(&mck);
 
@@ -722,35 +615,8 @@ int __init at91_clock_init(unsigned long main_clock)
                (unsigned) main_clock / 1000000,
                ((unsigned) main_clock % 1000000) / 1000);
 
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
-       /* establish PCK0..PCK3 parentage */
-       for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) {
-               struct clk      *clk = clock_list[tmp], *parent;
-               u32             pckr;
-
-               if (!clk->programmable)
-                       continue;
-
-               pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-               parent = clock_list[pckr & AT91_PMC_CSS];
-               clk->parent = parent;
-               clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
-
-               if (clk->users == 0) {
-                       /* not being used, so switch it off */
-                       at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
-               }
-       }
-#else
        /* disable all programmable clocks */
        at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3);
-#endif
-
-       /* enable the PIO clocks */
-       clk_enable(&pioA_clk);
-       clk_enable(&pioB_clk);
-       clk_enable(&pioC_clk);
-       clk_enable(&pioD_clk);
 
        /* disable all other unused peripheral clocks */
        at91_periphclk_reset();
diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h
new file mode 100644 (file)
index 0000000..0592e66
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/clock.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define CLK_TYPE_PRIMARY       0x1
+#define CLK_TYPE_PLL           0x2
+#define CLK_TYPE_PROGRAMMABLE  0x4
+#define CLK_TYPE_PERIPHERAL    0x8
+
+
+struct clk {
+       struct list_head node;
+       const char      *name;          /* unique clock name */
+       const char      *function;      /* function of the clock */
+       struct device   *dev;           /* device associated with function */
+       unsigned long   rate_hz;
+       struct clk      *parent;
+       u32             pmc_mask;
+       void            (*mode)(struct clk *, int);
+       unsigned        id:2;           /* PCK0..3, or 32k/main/a/b */
+       unsigned        type;           /* clock type */
+       u16             users;
+};
+
+
+extern int __init clk_register(struct clk *clk);
index 4352acb88178a6930c1a0a39c6f76cda1f0c355d..01525530c287df93f1686a0985c351da25c495ab 100644 (file)
@@ -35,13 +35,13 @@ static struct at91_usbh_data usbh_data;
 
 static struct resource at91_usbh_resources[] = {
        [0] = {
-               .start  = AT91_UHP_BASE,
-               .end    = AT91_UHP_BASE + SZ_1M - 1,
+               .start  = AT91RM9200_UHP_BASE,
+               .end    = AT91RM9200_UHP_BASE + SZ_1M - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_UHP,
-               .end    = AT91_ID_UHP,
+               .start  = AT91RM9200_ID_UHP,
+               .end    = AT91RM9200_ID_UHP,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -80,13 +80,13 @@ static struct at91_udc_data udc_data;
 
 static struct resource at91_udc_resources[] = {
        [0] = {
-               .start  = AT91_BASE_UDP,
-               .end    = AT91_BASE_UDP + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_UDP,
+               .end    = AT91RM9200_BASE_UDP + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_UDP,
-               .end    = AT91_ID_UDP,
+               .start  = AT91RM9200_ID_UDP,
+               .end    = AT91RM9200_ID_UDP,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -131,13 +131,13 @@ static struct at91_eth_data eth_data;
 
 static struct resource at91_eth_resources[] = {
        [0] = {
-               .start  = AT91_BASE_EMAC,
-               .end    = AT91_BASE_EMAC + SZ_16K - 1,
+               .start  = AT91_VA_BASE_EMAC,
+               .end    = AT91_VA_BASE_EMAC + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_EMAC,
-               .end    = AT91_ID_EMAC,
+               .start  = AT91RM9200_ID_EMAC,
+               .end    = AT91RM9200_ID_EMAC,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data;
 
 static struct resource at91_mmc_resources[] = {
        [0] = {
-               .start  = AT91_BASE_MCI,
-               .end    = AT91_BASE_MCI + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_MCI,
+               .end    = AT91RM9200_BASE_MCI + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_MCI,
-               .end    = AT91_ID_MCI,
+               .start  = AT91RM9200_ID_MCI,
+               .end    = AT91RM9200_ID_MCI,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL;
 
 static struct resource at91_spi_resources[] = {
        [0] = {
-               .start  = AT91_BASE_SPI,
-               .end    = AT91_BASE_SPI + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_SPI,
+               .end    = AT91RM9200_BASE_SPI + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_SPI,
-               .end    = AT91_ID_SPI,
+               .start  = AT91RM9200_ID_SPI,
+               .end    = AT91RM9200_ID_SPI,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void)
 
 static struct resource uart0_resources[] = {
        [0] = {
-               .start  = AT91_BASE_US0,
-               .end    = AT91_BASE_US0 + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_US0,
+               .end    = AT91RM9200_BASE_US0 + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_US0,
-               .end    = AT91_ID_US0,
+               .start  = AT91RM9200_ID_US0,
+               .end    = AT91RM9200_ID_US0,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void)
 
 static struct resource uart1_resources[] = {
        [0] = {
-               .start  = AT91_BASE_US1,
-               .end    = AT91_BASE_US1 + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_US1,
+               .end    = AT91RM9200_BASE_US1 + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_US1,
-               .end    = AT91_ID_US1,
+               .start  = AT91RM9200_ID_US1,
+               .end    = AT91RM9200_ID_US1,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void)
 
 static struct resource uart2_resources[] = {
        [0] = {
-               .start  = AT91_BASE_US2,
-               .end    = AT91_BASE_US2 + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_US2,
+               .end    = AT91RM9200_BASE_US2 + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_US2,
-               .end    = AT91_ID_US2,
+               .start  = AT91RM9200_ID_US2,
+               .end    = AT91RM9200_ID_US2,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void)
 
 static struct resource uart3_resources[] = {
        [0] = {
-               .start  = AT91_BASE_US3,
-               .end    = AT91_BASE_US3 + SZ_16K - 1,
+               .start  = AT91RM9200_BASE_US3,
+               .end    = AT91RM9200_BASE_US3 + SZ_16K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = AT91_ID_US3,
-               .end    = AT91_ID_US3,
+               .start  = AT91RM9200_ID_US3,
+               .end    = AT91RM9200_ID_US3,
                .flags  = IORESOURCE_IRQ,
        },
 };
index 7979d8ab7e07bebe75828d3eaf8c6567682f67c4..694e411e285f6933254ccbf077c2aa69c50a2237 100644 (file)
@@ -8,18 +8,17 @@
  * published by the Free Software Foundation.
  */
 
+ /* Processors */
+extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
+
  /* Interrupts */
-extern void __init at91rm9200_init_irq(unsigned int priority[]);
+extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
-extern void __init at91_gpio_irq_setup(unsigned banks);
 
  /* Timer */
 struct sys_timer;
 extern struct sys_timer at91rm9200_timer;
 
- /* Memory Map */
-extern void __init at91rm9200_map_io(void);
-
  /* Clocks */
 extern int __init at91_clock_init(unsigned long main_clock);
 struct device;
@@ -29,3 +28,14 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons
 extern void at91_irq_suspend(void);
 extern void at91_irq_resume(void);
 
+ /* GPIO */
+#define AT91RM9200_PQFP                3       /* AT91RM9200 PQFP package has 3 banks */
+#define AT91RM9200_BGA         4       /* AT91RM9200 BGA package has 4 banks */
+
+struct at91_gpio_bank {
+       unsigned short id;              /* peripheral ID */
+       unsigned long offset;           /* offset from system peripheral base */
+       struct clk *clock;              /* associated clock */
+};
+extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
+extern void __init at91_gpio_irq_setup(void);
index cec199fd67217bd171303762431843a6722354c8..58c9bf5e95205f1e4ecbed09d85b175f284a5a22 100644 (file)
@@ -9,6 +9,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/clk.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/hardware.h>
 #include <asm/arch/gpio.h>
 
-static const u32 pio_controller_offset[4] = {
-       AT91_PIOA,
-       AT91_PIOB,
-       AT91_PIOC,
-       AT91_PIOD,
-};
+#include "generic.h"
+
+
+static struct at91_gpio_bank *gpio;
+static int gpio_banks;
+
 
 static inline void __iomem *pin_to_controller(unsigned pin)
 {
@@ -33,8 +34,8 @@ static inline void __iomem *pin_to_controller(unsigned pin)
 
        pin -= PIN_BASE;
        pin /= 32;
-       if (likely(pin < BGA_GPIO_BANKS))
-               return sys_base + pio_controller_offset[pin];
+       if (likely(pin < gpio_banks))
+               return sys_base + gpio[pin].offset;
 
        return NULL;
 }
@@ -179,7 +180,6 @@ EXPORT_SYMBOL(at91_set_multi_drive);
 
 /*--------------------------------------------------------------------------*/
 
-
 /*
  * assuming the pin is muxed as a gpio output, set its value.
  */
@@ -216,8 +216,8 @@ EXPORT_SYMBOL(at91_get_gpio_value);
 
 #ifdef CONFIG_PM
 
-static u32 wakeups[BGA_GPIO_BANKS];
-static u32 backups[BGA_GPIO_BANKS];
+static u32 wakeups[MAX_GPIO_BANKS];
+static u32 backups[MAX_GPIO_BANKS];
 
 static int gpio_irq_set_wake(unsigned pin, unsigned state)
 {
@@ -226,7 +226,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state)
        pin -= PIN_BASE;
        pin /= 32;
 
-       if (unlikely(pin >= BGA_GPIO_BANKS))
+       if (unlikely(pin >= MAX_GPIO_BANKS))
                return -EINVAL;
 
        if (state)
@@ -241,8 +241,8 @@ void at91_gpio_suspend(void)
 {
        int i;
 
-       for (i = 0; i < BGA_GPIO_BANKS; i++) {
-               u32 pio = pio_controller_offset[i];
+       for (i = 0; i < gpio_banks; i++) {
+               u32 pio = gpio[i].offset;
 
                /*
                 * Note: drivers should have disabled GPIO interrupts that
@@ -257,14 +257,14 @@ void at91_gpio_suspend(void)
                 * first place!
                 */
                backups[i] = at91_sys_read(pio + PIO_IMR);
-               at91_sys_write(pio_controller_offset[i] + PIO_IDR, backups[i]);
-               at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]);
+               at91_sys_write(pio + PIO_IDR, backups[i]);
+               at91_sys_write(pio + PIO_IER, wakeups[i]);
 
                if (!wakeups[i]) {
-                       disable_irq_wake(AT91_ID_PIOA + i);
-                       at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i));
+                       disable_irq_wake(gpio[i].id);
+                       at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id);
                } else {
-                       enable_irq_wake(AT91_ID_PIOA + i);
+                       enable_irq_wake(gpio[i].id);
 #ifdef CONFIG_PM_DEBUG
                        printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]);
 #endif
@@ -276,16 +276,13 @@ void at91_gpio_resume(void)
 {
        int i;
 
-       for (i = 0; i < BGA_GPIO_BANKS; i++) {
-               at91_sys_write(pio_controller_offset[i] + PIO_IDR, wakeups[i]);
-               at91_sys_write(pio_controller_offset[i] + PIO_IER, backups[i]);
-       }
+       for (i = 0; i < gpio_banks; i++) {
+               u32 pio = gpio[i].offset;
 
-       at91_sys_write(AT91_PMC_PCER,
-                         (1 << AT91_ID_PIOA)
-                       | (1 << AT91_ID_PIOB)
-                       | (1 << AT91_ID_PIOC)
-                       | (1 << AT91_ID_PIOD));
+               at91_sys_write(pio + PIO_IDR, wakeups[i]);
+               at91_sys_write(pio + PIO_IER, backups[i]);
+               at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id);
+       }
 }
 
 #else
@@ -377,20 +374,25 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs
        /* now it may re-trigger */
 }
 
-/* call this from board-specific init_irq */
-void __init at91_gpio_irq_setup(unsigned banks)
+/*--------------------------------------------------------------------------*/
+
+/*
+ * Called from the processor-specific init to enable GPIO interrupt support.
+ */
+void __init at91_gpio_irq_setup(void)
 {
-       unsigned        pioc, pin, id;
+       unsigned        pioc, pin;
 
-       if (banks > 4)
-               banks = 4;
-       for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA;
-                       pioc < banks;
-                       pioc++, id++) {
+       for (pioc = 0, pin = PIN_BASE;
+                       pioc < gpio_banks;
+                       pioc++) {
                void __iomem    *controller;
+               unsigned        id = gpio[pioc].id;
                unsigned        i;
 
-               controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc];
+               clk_enable(gpio[pioc].clock);   /* enable PIO controller's clock */
+
+               controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
                __raw_writel(~0, controller + PIO_IDR);
 
                set_irq_data(id, (void *) pin);
@@ -408,5 +410,16 @@ void __init at91_gpio_irq_setup(unsigned banks)
 
                set_irq_chained_handler(id, gpio_irq_handler);
        }
-       pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks);
+       pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
+}
+
+/*
+ * Called from the processor-specific init to enable GPIO pin support.
+ */
+void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
+{
+       BUG_ON(nr_banks > MAX_GPIO_BANKS);
+
+       gpio = data;
+       gpio_banks = nr_banks;
 }
index c3a5e777f9f8c3753656b59a3e3c42dfc9ebc86a..3e488117ca91bb2154d992c9bd815d0d619750f2 100644 (file)
@@ -34,8 +34,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 
-#include "generic.h"
-
 
 static void at91_aic_mask_irq(unsigned int irq)
 {
@@ -61,12 +59,12 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
                srctype = AT91_AIC_SRCTYPE_RISING;
                break;
        case IRQT_LOW:
-               if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0))        /* only supported on external interrupts */
+               if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0))  /* only supported on external interrupts */
                        return -EINVAL;
                srctype = AT91_AIC_SRCTYPE_LOW;
                break;
        case IRQT_FALLING:
-               if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0))        /* only supported on external interrupts */
+               if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0))  /* only supported on external interrupts */
                        return -EINVAL;
                srctype = AT91_AIC_SRCTYPE_FALLING;
                break;
index 47e5480feb7eef279a6c5a8b5a748b7f4c1dee19..32c95d8eaacf3dabe0866f9603104534b43839eb 100644 (file)
@@ -123,13 +123,13 @@ static int at91_pm_enter(suspend_state_t state)
                        (at91_sys_read(AT91_PMC_PCSR)
                                        | (1 << AT91_ID_FIQ)
                                        | (1 << AT91_ID_SYS)
-                                       | (1 << AT91_ID_IRQ0)
-                                       | (1 << AT91_ID_IRQ1)
-                                       | (1 << AT91_ID_IRQ2)
-                                       | (1 << AT91_ID_IRQ3)
-                                       | (1 << AT91_ID_IRQ4)
-                                       | (1 << AT91_ID_IRQ5)
-                                       | (1 << AT91_ID_IRQ6))
+                                       | (1 << AT91RM9200_ID_IRQ0)
+                                       | (1 << AT91RM9200_ID_IRQ1)
+                                       | (1 << AT91RM9200_ID_IRQ2)
+                                       | (1 << AT91RM9200_ID_IRQ3)
+                                       | (1 << AT91RM9200_ID_IRQ4)
+                                       | (1 << AT91RM9200_ID_IRQ5)
+                                       | (1 << AT91RM9200_ID_IRQ6))
                                & at91_sys_read(AT91_AIC_IMR),
                        state);
 
index f1b740083aee5dfc30967a09540614ddfeb714f9..e346b03cd92114ed29ef44770de626c404e4df34 100644 (file)
@@ -15,6 +15,12 @@ config MACH_EDB9302
          Say 'Y' here if you want your kernel to support the Cirrus
          Logic EDB9302 Evaluation Board.
 
+config MACH_EDB9312
+       bool "Support Cirrus Logic EDB9312"
+       help
+         Say 'Y' here if you want your kernel to support the Cirrus
+         Logic EDB9312 Evaluation Board.
+
 config MACH_EDB9315
        bool "Support Cirrus Logic EDB9315"
        help
index 1f5a6b0487ee542e43dd5e4498f0422fcd68712e..c2eb18b530c2d0367be36a4e86fb01105a83e552 100644 (file)
@@ -7,6 +7,7 @@ obj-n                   :=
 obj-                   :=
 
 obj-$(CONFIG_MACH_EDB9302)     += edb9302.o
+obj-$(CONFIG_MACH_EDB9312)     += edb9312.o
 obj-$(CONFIG_MACH_EDB9315)     += edb9315.o
 obj-$(CONFIG_MACH_EDB9315A)    += edb9315a.o
 obj-$(CONFIG_MACH_GESBC9312)   += gesbc9312.o
diff --git a/arch/arm/mach-ep93xx/edb9312.c b/arch/arm/mach-ep93xx/edb9312.c
new file mode 100644 (file)
index 0000000..9e39921
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/mach-ep93xx/edb9312.c
+ * Cirrus Logic EDB9312 support.
+ *
+ * Copyright (C) 2006 Infosys Technologies Limited
+ *     Toufeeq Hussain <toufeeq_hussain@infosys.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/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data edb9312_flash_data = {
+       .width          = 4,
+};
+
+static struct resource edb9312_flash_resource = {
+       .start          = 0x60000000,
+       .end            = 0x61ffffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device edb9312_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &edb9312_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &edb9312_flash_resource,
+};
+
+static void __init edb9312_init_machine(void)
+{
+       ep93xx_init_devices();
+       platform_device_register(&edb9312_flash);
+}
+
+MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
+       /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = edb9312_init_machine,
+MACHINE_END
index 823e25d4547e8b0b7a0ad26b51844c93df290492..a1ae49df5c3be95c6ba23070a7369ee56b173a4c 100644 (file)
@@ -69,16 +69,16 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
        if (addr)
                switch (size) {
                case 1:
-                       asm("ldr%?b     %0, [%1, %2]"
-                               : "=r" (v) : "r" (addr), "r" (where));
+                       asm("ldrb       %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                case 2:
-                       asm("ldr%?h     %0, [%1, %2]"
-                               : "=r" (v) : "r" (addr), "r" (where));
+                       asm("ldrh       %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                case 4:
-                       asm("ldr%?      %0, [%1, %2]"
-                               : "=r" (v) : "r" (addr), "r" (where));
+                       asm("ldr        %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                }
 
@@ -103,16 +103,19 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
        if (addr)
                switch (size) {
                case 1:
-                       asm("str%?b     %0, [%1, %2]"
-                               : : "r" (value), "r" (addr), "r" (where));
+                       asm("strb       %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
                        break;
                case 2:
-                       asm("str%?h     %0, [%1, %2]"
-                               : : "r" (value), "r" (addr), "r" (where));
+                       asm("strh       %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
                        break;
                case 4:
-                       asm("str%?      %0, [%1, %2]"
-                               : : "r" (value), "r" (addr), "r" (where));
+                       asm("str        %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
                        break;
                }
 
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
new file mode 100644 (file)
index 0000000..c072d94
--- /dev/null
@@ -0,0 +1,35 @@
+if ARCH_IOP32X
+
+menu "IOP32x Implementation Options"
+
+comment "IOP32x Platform Types"
+
+config MACH_GLANTANK
+       bool "Enable support for the IO-Data GLAN Tank"
+       help
+         Say Y here if you want to run your kernel on the GLAN Tank
+         NAS appliance or machines from IO-Data's HDL-Gxxx, HDL-GWxxx
+         and HDL-GZxxx series.
+
+config ARCH_IQ80321
+       bool "Enable support for IQ80321"
+       help
+         Say Y here if you want to run your kernel on the Intel IQ80321
+         evaluation kit for the IOP321 processor.
+
+config ARCH_IQ31244
+       bool "Enable support for EP80219/IQ31244"
+       help
+         Say Y here if you want to run your kernel on the Intel EP80219
+         evaluation kit for the Intel 80219 processor (a IOP321 variant)
+         or the IQ31244 evaluation kit for the IOP321 processor.
+
+config MACH_N2100
+       bool "Enable support for the Thecus n2100"
+       help
+         Say Y here if you want to run your kernel on the Thecus n2100
+         NAS appliance.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile
new file mode 100644 (file)
index 0000000..7b05b37
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y                  := irq.o
+obj-m                  :=
+obj-n                  :=
+obj-                   :=
+
+obj-$(CONFIG_MACH_GLANTANK) += glantank.o
+obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
+obj-$(CONFIG_ARCH_IQ31244) += iq31244.o
+obj-$(CONFIG_MACH_N2100) += n2100.o
diff --git a/arch/arm/mach-iop32x/Makefile.boot b/arch/arm/mach-iop32x/Makefile.boot
new file mode 100644 (file)
index 0000000..47000dc
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0xa0008000
+params_phys-y  := 0xa0000100
+initrd_phys-y  := 0xa0800000
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
new file mode 100644 (file)
index 0000000..b9b7650
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * arch/arm/mach-iop32x/glantank.c
+ *
+ * Board support code for the GLAN Tank.
+ *
+ * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+
+/*
+ * GLAN Tank timer tick configuration.
+ */
+static void __init glantank_timer_init(void)
+{
+       /* 33.333 MHz crystal.  */
+       iop3xx_init_time(200000000);
+}
+
+static struct sys_timer glantank_timer = {
+       .init           = glantank_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * GLAN Tank I/O.
+ */
+static struct map_desc glantank_io_desc[] __initdata = {
+       {       /* on-board devices */
+               .virtual        = GLANTANK_UART,
+               .pfn            = __phys_to_pfn(GLANTANK_UART),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE
+       },
+};
+
+void __init glantank_map_io(void)
+{
+       iop3xx_map_io();
+       iotable_init(glantank_io_desc, ARRAY_SIZE(glantank_io_desc));
+}
+
+
+/*
+ * GLAN Tank PCI.
+ */
+#define INTA   IRQ_IOP32X_XINT0
+#define INTB   IRQ_IOP32X_XINT1
+#define INTC   IRQ_IOP32X_XINT2
+#define INTD   IRQ_IOP32X_XINT3
+
+static inline int __init
+glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       static int pci_irq_table[][4] = {
+               /*
+                * PCI IDSEL/INTPIN->INTLINE
+                * A       B       C       D
+                */
+               {INTD, INTD, INTD, INTD}, /* UART (8250) */
+               {INTA, INTA, INTA, INTA}, /* Ethernet (E1000) */
+               {INTB, INTB, INTB, INTB}, /* IDE (AEC6280R) */
+               {INTC, INTC, INTC, INTC}, /* USB (NEC) */
+       };
+
+       BUG_ON(pin < 1 || pin > 4);
+
+       return pci_irq_table[slot % 4][pin - 1];
+}
+
+static struct hw_pci glantank_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = glantank_pci_map_irq,
+};
+
+static int __init glantank_pci_init(void)
+{
+       if (machine_is_glantank())
+               pci_common_init(&glantank_pci);
+
+       return 0;
+}
+
+subsys_initcall(glantank_pci_init);
+
+
+/*
+ * GLAN Tank machine initialization.
+ */
+static struct physmap_flash_data glantank_flash_data = {
+       .width          = 1,
+};
+
+static struct resource glantank_flash_resource = {
+       .start          = 0xf0000000,
+       .end            = 0xf007ffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device glantank_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &glantank_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &glantank_flash_resource,
+};
+
+static struct plat_serial8250_port glantank_serial_port[] = {
+       {
+               .mapbase        = GLANTANK_UART,
+               .membase        = (char *)GLANTANK_UART,
+               .irq            = IRQ_IOP32X_XINT3,
+               .flags          = UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = 1843200,
+       },
+       { },
+};
+
+static struct resource glantank_uart_resource = {
+       .start          = GLANTANK_UART,
+       .end            = GLANTANK_UART + 7,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device glantank_serial_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = glantank_serial_port,
+       },
+       .num_resources  = 1,
+       .resource       = &glantank_uart_resource,
+};
+
+static void glantank_power_off(void)
+{
+       __raw_writeb(0x01, 0xfe8d0004);
+
+       while (1)
+               ;
+}
+
+static void __init glantank_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&glantank_flash_device);
+       platform_device_register(&glantank_serial_device);
+
+       pm_power_off = glantank_power_off;
+}
+
+MACHINE_START(GLANTANK, "GLAN Tank")
+       /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+       .phys_io        = GLANTANK_UART,
+       .io_pg_offst    = ((GLANTANK_UART) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = glantank_map_io,
+       .init_irq       = iop32x_init_irq,
+       .timer          = &glantank_timer,
+       .init_machine   = glantank_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
new file mode 100644 (file)
index 0000000..be4aedf
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * arch/arm/mach-iop32x/iq31244.c
+ *
+ * Board support code for the Intel EP80219 and IQ31244 platforms.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright 2003 (c) MontaVista, Software, Inc.
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+
+/*
+ * The EP80219 and IQ31244 use the same machine ID.  To find out
+ * which of the two we're running on, we look at the processor ID.
+ */
+static int is_80219(void)
+{
+       extern int processor_id;
+       return !!((processor_id & 0xffffffe0) == 0x69052e20);
+}
+
+
+/*
+ * EP80219/IQ31244 timer tick configuration.
+ */
+static void __init iq31244_timer_init(void)
+{
+       if (is_80219()) {
+               /* 33.333 MHz crystal.  */
+               iop3xx_init_time(200000000);
+       } else {
+               /* 33.000 MHz crystal.  */
+               iop3xx_init_time(198000000);
+       }
+}
+
+static struct sys_timer iq31244_timer = {
+       .init           = iq31244_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * IQ31244 I/O.
+ */
+static struct map_desc iq31244_io_desc[] __initdata = {
+       {       /* on-board devices */
+               .virtual        = IQ31244_UART,
+               .pfn            = __phys_to_pfn(IQ31244_UART),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init iq31244_map_io(void)
+{
+       iop3xx_map_io();
+       iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
+}
+
+
+/*
+ * EP80219/IQ31244 PCI.
+ */
+static inline int __init
+ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if (slot == 0) {
+               /* CFlash */
+               irq = IRQ_IOP32X_XINT1;
+       } else if (slot == 1) {
+               /* 82551 Pro 100 */
+               irq = IRQ_IOP32X_XINT0;
+       } else if (slot == 2) {
+               /* PCI-X Slot */
+               irq = IRQ_IOP32X_XINT3;
+       } else if (slot == 3) {
+               /* SATA */
+               irq = IRQ_IOP32X_XINT2;
+       } else {
+               printk(KERN_ERR "ep80219_pci_map_irq() called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci ep80219_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = ep80219_pci_map_irq,
+};
+
+static inline int __init
+iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if (slot == 0) {
+               /* CFlash */
+               irq = IRQ_IOP32X_XINT1;
+       } else if (slot == 1) {
+               /* SATA */
+               irq = IRQ_IOP32X_XINT2;
+       } else if (slot == 2) {
+               /* PCI-X Slot */
+               irq = IRQ_IOP32X_XINT3;
+       } else if (slot == 3) {
+               /* 82546 GigE */
+               irq = IRQ_IOP32X_XINT0;
+       } else {
+               printk(KERN_ERR "iq31244_pci_map_irq called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci iq31244_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = iq31244_pci_map_irq,
+};
+
+static int __init iq31244_pci_init(void)
+{
+       if (machine_is_iq31244()) {
+               if (is_80219()) {
+                       pci_common_init(&ep80219_pci);
+               } else {
+                       pci_common_init(&iq31244_pci);
+               }
+       }
+
+       return 0;
+}
+
+subsys_initcall(iq31244_pci_init);
+
+
+/*
+ * IQ31244 machine initialisation.
+ */
+static struct physmap_flash_data iq31244_flash_data = {
+       .width          = 2,
+};
+
+static struct resource iq31244_flash_resource = {
+       .start          = 0xf0000000,
+       .end            = 0xf07fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq31244_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &iq31244_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &iq31244_flash_resource,
+};
+
+static struct plat_serial8250_port iq31244_serial_port[] = {
+       {
+               .mapbase        = IQ31244_UART,
+               .membase        = (char *)IQ31244_UART,
+               .irq            = IRQ_IOP32X_XINT1,
+               .flags          = UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = 1843200,
+       },
+       { },
+};
+
+static struct resource iq31244_uart_resource = {
+       .start          = IQ31244_UART,
+       .end            = IQ31244_UART + 7,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq31244_serial_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = iq31244_serial_port,
+       },
+       .num_resources  = 1,
+       .resource       = &iq31244_uart_resource,
+};
+
+/*
+ * This function will send a SHUTDOWN_COMPLETE message to the PIC
+ * controller over I2C.  We are not using the i2c subsystem since
+ * we are going to power off and it may be removed
+ */
+void ep80219_power_off(void)
+{
+       /*
+        * Send the Address byte w/ the start condition
+        */
+       *IOP3XX_IDBR1 = 0x60;
+       *IOP3XX_ICR1 = 0xE9;
+       mdelay(1);
+
+       /*
+        * Send the START_MSG byte w/ no start or stop condition
+        */
+       *IOP3XX_IDBR1 = 0x0F;
+       *IOP3XX_ICR1 = 0xE8;
+       mdelay(1);
+
+       /*
+        * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or
+        * stop condition
+        */
+       *IOP3XX_IDBR1 = 0x03;
+       *IOP3XX_ICR1 = 0xE8;
+       mdelay(1);
+
+       /*
+        * Send an ignored byte w/ stop condition
+        */
+       *IOP3XX_IDBR1 = 0x00;
+       *IOP3XX_ICR1 = 0xEA;
+
+       while (1)
+               ;
+}
+
+static void __init iq31244_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&iq31244_flash_device);
+       platform_device_register(&iq31244_serial_device);
+
+       if (is_80219())
+               pm_power_off = ep80219_power_off;
+}
+
+MACHINE_START(IQ31244, "Intel IQ31244")
+       /* Maintainer: Intel Corp. */
+       .phys_io        = IQ31244_UART,
+       .io_pg_offst    = ((IQ31244_UART) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = iq31244_map_io,
+       .init_irq       = iop32x_init_irq,
+       .timer          = &iq31244_timer,
+       .init_machine   = iq31244_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
new file mode 100644 (file)
index 0000000..1f37b55
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * arch/arm/mach-iop32x/iq80321.c
+ *
+ * Board support code for the Intel IQ80321 platform.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/*
+ * IQ80321 timer tick configuration.
+ */
+static void __init iq80321_timer_init(void)
+{
+       /* 33.333 MHz crystal.  */
+       iop3xx_init_time(200000000);
+}
+
+static struct sys_timer iq80321_timer = {
+       .init           = iq80321_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * IQ80321 I/O.
+ */
+static struct map_desc iq80321_io_desc[] __initdata = {
+       {       /* on-board devices */
+               .virtual        = IQ80321_UART,
+               .pfn            = __phys_to_pfn(IQ80321_UART),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init iq80321_map_io(void)
+{
+       iop3xx_map_io();
+       iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
+}
+
+
+/*
+ * IQ80321 PCI.
+ */
+static inline int __init
+iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if ((slot == 2 || slot == 6) && pin == 1) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP32X_XINT2;
+       } else if ((slot == 2 || slot == 6) && pin == 2) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP32X_XINT3;
+       } else if ((slot == 2 || slot == 6) && pin == 3) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP32X_XINT0;
+       } else if ((slot == 2 || slot == 6) && pin == 4) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP32X_XINT1;
+       } else if (slot == 4 || slot == 8) {
+               /* Gig-E */
+               irq = IRQ_IOP32X_XINT0;
+       } else {
+               printk(KERN_ERR "iq80321_pci_map_irq() called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci iq80321_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = iq80321_pci_map_irq,
+};
+
+static int __init iq80321_pci_init(void)
+{
+       if (machine_is_iq80321())
+               pci_common_init(&iq80321_pci);
+
+       return 0;
+}
+
+subsys_initcall(iq80321_pci_init);
+
+
+/*
+ * IQ80321 machine initialisation.
+ */
+static struct physmap_flash_data iq80321_flash_data = {
+       .width          = 1,
+};
+
+static struct resource iq80321_flash_resource = {
+       .start          = 0xf0000000,
+       .end            = 0xf07fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80321_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &iq80321_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &iq80321_flash_resource,
+};
+
+static struct plat_serial8250_port iq80321_serial_port[] = {
+       {
+               .mapbase        = IQ80321_UART,
+               .membase        = (char *)IQ80321_UART,
+               .irq            = IRQ_IOP32X_XINT1,
+               .flags          = UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = 1843200,
+       },
+       { },
+};
+
+static struct resource iq80321_uart_resource = {
+       .start          = IQ80321_UART,
+       .end            = IQ80321_UART + 7,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80321_serial_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = iq80321_serial_port,
+       },
+       .num_resources  = 1,
+       .resource       = &iq80321_uart_resource,
+};
+
+static void __init iq80321_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&iq80321_flash_device);
+       platform_device_register(&iq80321_serial_device);
+}
+
+MACHINE_START(IQ80321, "Intel IQ80321")
+       /* Maintainer: Intel Corp. */
+       .phys_io        = IQ80321_UART,
+       .io_pg_offst    = ((IQ80321_UART) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = iq80321_map_io,
+       .init_irq       = iop32x_init_irq,
+       .timer          = &iq80321_timer,
+       .init_machine   = iq80321_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
new file mode 100644 (file)
index 0000000..69d6302
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-iop32x/irq.c
+ *
+ * Generic IOP32X IRQ handling functionality
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+static u32 iop32x_mask;
+
+static inline void intctl_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intstr_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static void
+iop32x_irq_mask(unsigned int irq)
+{
+       iop32x_mask &= ~(1 << irq);
+       intctl_write(iop32x_mask);
+}
+
+static void
+iop32x_irq_unmask(unsigned int irq)
+{
+       iop32x_mask |= 1 << irq;
+       intctl_write(iop32x_mask);
+}
+
+struct irq_chip ext_chip = {
+       .name   = "IOP32x",
+       .ack    = iop32x_irq_mask,
+       .mask   = iop32x_irq_mask,
+       .unmask = iop32x_irq_unmask,
+};
+
+void __init iop32x_init_irq(void)
+{
+       int i;
+
+       intctl_write(0);
+       intstr_write(0);
+       if (machine_is_glantank() ||
+           machine_is_iq80321() ||
+           machine_is_iq31244() ||
+           machine_is_n2100())
+               *IOP3XX_PCIIRSR = 0x0f;
+
+       for (i = 0; i < NR_IRQS; i++) {
+               set_irq_chip(i, &ext_chip);
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+       }
+}
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
new file mode 100644 (file)
index 0000000..a2c94a4
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * arch/arm/mach-iop32x/n2100.c
+ *
+ * Board support code for the Thecus N2100 platform.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright 2003 (c) MontaVista, Software, Inc.
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/*
+ * N2100 timer tick configuration.
+ */
+static void __init n2100_timer_init(void)
+{
+       /* 33.000 MHz crystal.  */
+       iop3xx_init_time(198000000);
+}
+
+static struct sys_timer n2100_timer = {
+       .init           = n2100_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * N2100 I/O.
+ */
+static struct map_desc n2100_io_desc[] __initdata = {
+       {       /* on-board devices */
+               .virtual        = N2100_UART,
+               .pfn            = __phys_to_pfn(N2100_UART),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE
+       },
+};
+
+void __init n2100_map_io(void)
+{
+       iop3xx_map_io();
+       iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc));
+}
+
+
+/*
+ * N2100 PCI.
+ */
+static inline int __init
+n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if (PCI_SLOT(dev->devfn) == 1) {
+               /* RTL8110SB #1 */
+               irq = IRQ_IOP32X_XINT0;
+       } else if (PCI_SLOT(dev->devfn) == 2) {
+               /* RTL8110SB #2 */
+               irq = IRQ_IOP32X_XINT1;
+       } else if (PCI_SLOT(dev->devfn) == 3) {
+               /* Sil3512 */
+               irq = IRQ_IOP32X_XINT2;
+       } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) {
+               /* VT6212 INTA */
+               irq = IRQ_IOP32X_XINT1;
+       } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) {
+               /* VT6212 INTB */
+               irq = IRQ_IOP32X_XINT0;
+       } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) {
+               /* VT6212 INTC */
+               irq = IRQ_IOP32X_XINT2;
+       } else if (PCI_SLOT(dev->devfn) == 5) {
+               /* Mini-PCI slot */
+               irq = IRQ_IOP32X_XINT3;
+       } else {
+               printk(KERN_ERR "n2100_pci_map_irq() called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci n2100_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = n2100_pci_map_irq,
+};
+
+static int __init n2100_pci_init(void)
+{
+       if (machine_is_n2100())
+               pci_common_init(&n2100_pci);
+
+       return 0;
+}
+
+subsys_initcall(n2100_pci_init);
+
+
+/*
+ * N2100 machine initialisation.
+ */
+static struct physmap_flash_data n2100_flash_data = {
+       .width          = 2,
+};
+
+static struct resource n2100_flash_resource = {
+       .start          = 0xf0000000,
+       .end            = 0xf0ffffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device n2100_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &n2100_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &n2100_flash_resource,
+};
+
+
+static struct plat_serial8250_port n2100_serial_port[] = {
+       {
+               .mapbase        = N2100_UART,
+               .membase        = (char *)N2100_UART,
+               .irq            = 0,
+               .flags          = UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = 1843200,
+       },
+       { },
+};
+
+static struct resource n2100_uart_resource = {
+       .start          = N2100_UART,
+       .end            = N2100_UART + 7,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device n2100_serial_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = n2100_serial_port,
+       },
+       .num_resources  = 1,
+       .resource       = &n2100_uart_resource,
+};
+
+
+/*
+ * Pull PCA9532 GPIO #8 low to power off the machine.
+ */
+static void n2100_power_off(void)
+{
+       local_irq_disable();
+
+       /* Start condition, I2C address of PCA9532, write transaction.  */
+       *IOP3XX_IDBR0 = 0xc0;
+       *IOP3XX_ICR0 = 0xe9;
+       mdelay(1);
+
+       /* Write address 0x08.  */
+       *IOP3XX_IDBR0 = 0x08;
+       *IOP3XX_ICR0 = 0xe8;
+       mdelay(1);
+
+       /* Write data 0x01, stop condition.  */
+       *IOP3XX_IDBR0 = 0x01;
+       *IOP3XX_ICR0 = 0xea;
+
+       while (1)
+               ;
+}
+
+
+static struct timer_list power_button_poll_timer;
+
+static void power_button_poll(unsigned long dummy)
+{
+       if (gpio_line_get(N2100_POWER_BUTTON) == 0) {
+               ctrl_alt_del();
+               return;
+       }
+
+       power_button_poll_timer.expires = jiffies + (HZ / 10);
+       add_timer(&power_button_poll_timer);
+}
+
+
+static void __init n2100_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&n2100_flash_device);
+       platform_device_register(&n2100_serial_device);
+
+       pm_power_off = n2100_power_off;
+
+       init_timer(&power_button_poll_timer);
+       power_button_poll_timer.function = power_button_poll;
+       power_button_poll_timer.expires = jiffies + (HZ / 10);
+       add_timer(&power_button_poll_timer);
+}
+
+MACHINE_START(N2100, "Thecus N2100")
+       /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+       .phys_io        = N2100_UART,
+       .io_pg_offst    = ((N2100_UART) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = n2100_map_io,
+       .init_irq       = iop32x_init_irq,
+       .timer          = &n2100_timer,
+       .init_machine   = n2100_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig
new file mode 100644 (file)
index 0000000..9aa016b
--- /dev/null
@@ -0,0 +1,21 @@
+if ARCH_IOP33X
+
+menu "IOP33x Implementation Options"
+
+comment "IOP33x Platform Types"
+
+config ARCH_IQ80331
+       bool "Enable support for IQ80331"
+       help
+         Say Y here if you want to run your kernel on the Intel IQ80331
+         evaluation kit for the IOP331 chipset.
+
+config MACH_IQ80332
+       bool "Enable support for IQ80332"
+       help
+         Say Y here if you want to run your kernel on the Intel IQ80332
+         evaluation kit for the IOP332 chipset.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile
new file mode 100644 (file)
index 0000000..90081d8
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y                  := irq.o uart.o
+obj-m                  :=
+obj-n                  :=
+obj-                   :=
+
+obj-$(CONFIG_ARCH_IQ80331) += iq80331.o
+obj-$(CONFIG_MACH_IQ80332) += iq80332.o
diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot
new file mode 100644 (file)
index 0000000..67039c3
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
new file mode 100644 (file)
index 0000000..97a7b74
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * arch/arm/mach-iop33x/iq80331.c
+ *
+ * Board support code for the Intel IQ80331 platform.
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/*
+ * IQ80331 timer tick configuration.
+ */
+static void __init iq80331_timer_init(void)
+{
+       /* D-Step parts run at a higher internal bus frequency */
+       if (*IOP3XX_ATURID >= 0xa)
+               iop3xx_init_time(333000000);
+       else
+               iop3xx_init_time(266000000);
+}
+
+static struct sys_timer iq80331_timer = {
+       .init           = iq80331_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * IQ80331 PCI.
+ */
+static inline int __init
+iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if (slot == 1 && pin == 1) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP33X_XINT1;
+       } else if (slot == 1 && pin == 2) {
+               /* PCI-X Slot INTB */
+               irq = IRQ_IOP33X_XINT2;
+       } else if (slot == 1 && pin == 3) {
+               /* PCI-X Slot INTC */
+               irq = IRQ_IOP33X_XINT3;
+       } else if (slot == 1 && pin == 4) {
+               /* PCI-X Slot INTD */
+               irq = IRQ_IOP33X_XINT0;
+       } else if (slot == 2) {
+               /* GigE */
+               irq = IRQ_IOP33X_XINT2;
+       } else {
+               printk(KERN_ERR "iq80331_pci_map_irq() called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci iq80331_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = iq80331_pci_map_irq,
+};
+
+static int __init iq80331_pci_init(void)
+{
+       if (machine_is_iq80331())
+               pci_common_init(&iq80331_pci);
+
+       return 0;
+}
+
+subsys_initcall(iq80331_pci_init);
+
+
+/*
+ * IQ80331 machine initialisation.
+ */
+static struct physmap_flash_data iq80331_flash_data = {
+       .width          = 1,
+};
+
+static struct resource iq80331_flash_resource = {
+       .start          = 0xc0000000,
+       .end            = 0xc07fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80331_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &iq80331_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &iq80331_flash_resource,
+};
+
+static void __init iq80331_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&iop33x_uart0_device);
+       platform_device_register(&iop33x_uart1_device);
+       platform_device_register(&iq80331_flash_device);
+}
+
+MACHINE_START(IQ80331, "Intel IQ80331")
+       /* Maintainer: Intel Corp. */
+       .phys_io        = 0xfefff000,
+       .io_pg_offst    = ((0xfffff000) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = iop3xx_map_io,
+       .init_irq       = iop33x_init_irq,
+       .timer          = &iq80331_timer,
+       .init_machine   = iq80331_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
new file mode 100644 (file)
index 0000000..9887bfc
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * arch/arm/mach-iop33x/iq80332.c
+ *
+ * Board support code for the Intel IQ80332 platform.
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/*
+ * IQ80332 timer tick configuration.
+ */
+static void __init iq80332_timer_init(void)
+{
+       /* D-Step parts and the iop333 run at a higher internal bus frequency */
+       if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374)
+               iop3xx_init_time(333000000);
+       else
+               iop3xx_init_time(266000000);
+}
+
+static struct sys_timer iq80332_timer = {
+       .init           = iq80332_timer_init,
+       .offset         = iop3xx_gettimeoffset,
+};
+
+
+/*
+ * IQ80332 PCI.
+ */
+static inline int __init
+iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+
+       if (slot == 4 && pin == 1) {
+               /* PCI-X Slot INTA */
+               irq = IRQ_IOP33X_XINT0;
+       } else if (slot == 4 && pin == 2) {
+               /* PCI-X Slot INTB */
+               irq = IRQ_IOP33X_XINT1;
+       } else if (slot == 4 && pin == 3) {
+               /* PCI-X Slot INTC */
+               irq = IRQ_IOP33X_XINT2;
+       } else if (slot == 4 && pin == 4) {
+               /* PCI-X Slot INTD */
+               irq = IRQ_IOP33X_XINT3;
+       } else if (slot == 6) {
+               /* GigE */
+               irq = IRQ_IOP33X_XINT2;
+       } else {
+               printk(KERN_ERR "iq80332_pci_map_irq() called for unknown "
+                       "device PCI:%d:%d:%d\n", dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+               irq = -1;
+       }
+
+       return irq;
+}
+
+static struct hw_pci iq80332_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = iq80332_pci_map_irq,
+};
+
+static int __init iq80332_pci_init(void)
+{
+       if (machine_is_iq80332())
+               pci_common_init(&iq80332_pci);
+
+       return 0;
+}
+
+subsys_initcall(iq80332_pci_init);
+
+
+/*
+ * IQ80332 machine initialisation.
+ */
+static struct physmap_flash_data iq80332_flash_data = {
+       .width          = 1,
+};
+
+static struct resource iq80332_flash_resource = {
+       .start          = 0xc0000000,
+       .end            = 0xc07fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80332_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &iq80332_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &iq80332_flash_resource,
+};
+
+static void __init iq80332_init_machine(void)
+{
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&iop33x_uart0_device);
+       platform_device_register(&iop33x_uart1_device);
+       platform_device_register(&iq80332_flash_device);
+}
+
+MACHINE_START(IQ80332, "Intel IQ80332")
+       /* Maintainer: Intel Corp. */
+       .phys_io        = 0xfefff000,
+       .io_pg_offst    = ((0xfffff000) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = iop3xx_map_io,
+       .init_irq       = iop33x_init_irq,
+       .timer          = &iq80332_timer,
+       .init_machine   = iq80332_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
new file mode 100644 (file)
index 0000000..63304b3
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-iop33x/irq.c
+ *
+ * Generic IOP331 IRQ handling functionality
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+static u32 iop33x_mask0;
+static u32 iop33x_mask1;
+
+static inline void intctl0_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intctl1_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intstr0_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intstr1_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intbase_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static inline void intsize_write(u32 val)
+{
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val));
+       iop3xx_cp6_disable();
+}
+
+static void
+iop33x_irq_mask1 (unsigned int irq)
+{
+       iop33x_mask0 &= ~(1 << irq);
+       intctl0_write(iop33x_mask0);
+}
+
+static void
+iop33x_irq_mask2 (unsigned int irq)
+{
+       iop33x_mask1 &= ~(1 << (irq - 32));
+       intctl1_write(iop33x_mask1);
+}
+
+static void
+iop33x_irq_unmask1(unsigned int irq)
+{
+       iop33x_mask0 |= 1 << irq;
+       intctl0_write(iop33x_mask0);
+}
+
+static void
+iop33x_irq_unmask2(unsigned int irq)
+{
+       iop33x_mask1 |= (1 << (irq - 32));
+       intctl1_write(iop33x_mask1);
+}
+
+struct irq_chip iop33x_irqchip1 = {
+       .name   = "IOP33x-1",
+       .ack    = iop33x_irq_mask1,
+       .mask   = iop33x_irq_mask1,
+       .unmask = iop33x_irq_unmask1,
+};
+
+struct irq_chip iop33x_irqchip2 = {
+       .name   = "IOP33x-2",
+       .ack    = iop33x_irq_mask2,
+       .mask   = iop33x_irq_mask2,
+       .unmask = iop33x_irq_unmask2,
+};
+
+void __init iop33x_init_irq(void)
+{
+       int i;
+
+       intctl0_write(0);
+       intctl1_write(0);
+       intstr0_write(0);
+       intstr1_write(0);
+       intbase_write(0);
+       intsize_write(1);
+       if (machine_is_iq80331())
+               *IOP3XX_PCIIRSR = 0x0f;
+
+       for (i = 0; i < NR_IRQS; i++) {
+               set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2);
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+       }
+}
diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c
new file mode 100644 (file)
index 0000000..ac297cd
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/mach-iop33x/uart.c
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/hardware/iop3xx.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define IOP33X_UART_XTAL 33334000
+
+static struct plat_serial8250_port iop33x_uart0_data[] = {
+       {
+               .membase        = (char *)IOP33X_UART0_VIRT,
+               .mapbase        = IOP33X_UART0_PHYS,
+               .irq            = IRQ_IOP33X_UART0,
+               .uartclk        = IOP33X_UART_XTAL,
+               .regshift       = 2,
+               .iotype         = UPIO_MEM,
+               .flags          = UPF_SKIP_TEST,
+       },
+       { },
+};
+
+static struct resource iop33x_uart0_resources[] = {
+       [0] = {
+               .start  = IOP33X_UART0_PHYS,
+               .end    = IOP33X_UART0_PHYS + 0x3f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IOP33X_UART0,
+               .end    = IRQ_IOP33X_UART0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device iop33x_uart0_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = iop33x_uart0_data,
+       },
+       .num_resources  = 2,
+       .resource       = iop33x_uart0_resources,
+};
+
+
+static struct resource iop33x_uart1_resources[] = {
+       [0] = {
+               .start  = IOP33X_UART1_PHYS,
+               .end    = IOP33X_UART1_PHYS + 0x3f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IOP33X_UART1,
+               .end    = IRQ_IOP33X_UART1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct plat_serial8250_port iop33x_uart1_data[] = {
+       {
+               .membase        = (char *)IOP33X_UART1_VIRT,
+               .mapbase        = IOP33X_UART1_PHYS,
+               .irq            = IRQ_IOP33X_UART1,
+               .uartclk        = IOP33X_UART_XTAL,
+               .regshift       = 2,
+               .iotype         = UPIO_MEM,
+               .flags          = UPF_SKIP_TEST,
+       },
+       { },
+};
+
+struct platform_device iop33x_uart1_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM1,
+       .dev            = {
+               .platform_data          = iop33x_uart1_data,
+       },
+       .num_resources  = 2,
+       .resource       = iop33x_uart1_resources,
+};
diff --git a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig
deleted file mode 100644 (file)
index 4422f23..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-if ARCH_IOP3XX
-
-menu "IOP3xx Implementation Options"
-
-comment "IOP3xx Platform Types"
-
-config ARCH_IQ80321
-       bool "Enable support for IQ80321"
-       select ARCH_IOP321
-       help
-         Say Y here if you want to run your kernel on the Intel IQ80321
-         evaluation kit for the IOP321 chipset.
-
-config ARCH_IQ31244
-       bool "Enable support for IQ31244"
-       select ARCH_IOP321
-       help
-         Say Y here if you want to run your kernel on the Intel IQ31244
-         evaluation kit for the IOP321 chipset.
-
-config ARCH_IQ80331
-       bool "Enable support for IQ80331"
-       select ARCH_IOP331
-       help
-         Say Y here if you want to run your kernel on the Intel IQ80331
-         evaluation kit for the IOP331 chipset.
-
-config MACH_IQ80332
-       bool "Enable support for IQ80332"
-       select ARCH_IOP331
-       help
-         Say Y here if you want to run your kernel on the Intel IQ80332
-         evaluation kit for the IOP332 chipset.
-
-config ARCH_EP80219
-       bool "Enable support for EP80219"
-       select ARCH_IOP321
-       select ARCH_IQ31244
-       help
-         Say Y here if you want to run your kernel on the Intel EP80219
-         evaluation kit for the Intel 80219 chipset (a IOP321 variant).
-
-# Which IOP variant are we running?
-config ARCH_IOP321
-       bool
-       help
-         The IQ80321 uses the IOP321 variant.
-         The IQ31244 and EP80219 uses the IOP321 variant.
-
-config ARCH_IOP331
-       bool
-       default ARCH_IQ80331
-       help
-         The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant.
-
-comment "IOP3xx Chipset Features"
-
-config IOP331_STEPD
-       bool "Chip stepping D of the IOP80331 processor or IOP80333"
-       depends on (ARCH_IOP331)
-       help
-         Say Y here if you have StepD of the IOP80331 or IOP8033
-         based platforms.
-
-endmenu
-endif
diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile
deleted file mode 100644 (file)
index b17eb1f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y                  := common.o
-
-obj-m                  :=
-obj-n                  :=
-obj-                   :=
-
-obj-$(CONFIG_ARCH_IOP321)  += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o
-
-obj-$(CONFIG_ARCH_IOP331)  += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o
-
-obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o
-
-obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o
-
-obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o
-
-obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o
diff --git a/arch/arm/mach-iop3xx/Makefile.boot b/arch/arm/mach-iop3xx/Makefile.boot
deleted file mode 100644 (file)
index 6387aa2..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-   zreladdr-y  := 0xa0008000
-params_phys-y  := 0xa0000100
-initrd_phys-y  := 0xa0800000
-ifeq ($(CONFIG_ARCH_IOP331),y)
-   zreladdr-y  := 0x00008000
-params_phys-y  := 0x00000100
-initrd_phys-y  := 0x00800000
-endif
-
diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c
deleted file mode 100644 (file)
index d7f50e5..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/common.c
- *
- * Common routines shared across all IOP3xx implementations
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright 2003 (c) MontaVista, Software, Inc.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/delay.h>
-#include <asm/hardware.h>
-
-/*
- * Shared variables
- */
-unsigned long iop3xx_pcibios_min_io = 0;
-unsigned long iop3xx_pcibios_min_mem = 0;
-
-#ifdef CONFIG_ARCH_EP80219
-#include <linux/kernel.h>
-/*
- * Default power-off for EP80219
- */
-
-static inline void ep80219_send_to_pic(__u8 c) {
-}
-
-void ep80219_power_off(void)
-{
-       /*
-     * This function will send a SHUTDOWN_COMPLETE message to the PIC controller
-     * over I2C.  We are not using the i2c subsystem since we are going to power
-     * off and it may be removed
-     */
-
-       /* Send the Address byte w/ the start condition */
-       *IOP321_IDBR1 = 0x60;
-       *IOP321_ICR1 = 0xE9;
-    mdelay(1);
-
-       /* Send the START_MSG byte w/ no start or stop condition */
-       *IOP321_IDBR1 = 0x0F;
-       *IOP321_ICR1 = 0xE8;
-    mdelay(1);
-
-       /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */
-       *IOP321_IDBR1 = 0x03;
-       *IOP321_ICR1 = 0xE8;
-    mdelay(1);
-
-       /* Send an ignored byte w/ stop condition */
-       *IOP321_IDBR1 = 0x00;
-       *IOP321_ICR1 = 0xEA;
-
-       while (1) ;
-}
-
-#include <linux/init.h>
-#include <linux/pm.h>
-
-static int __init ep80219_init(void)
-{
-       pm_power_off = ep80219_power_off;
-       return 0;
-}
-arch_initcall(ep80219_init);
-#endif
diff --git a/arch/arm/mach-iop3xx/iop321-irq.c b/arch/arm/mach-iop3xx/iop321-irq.c
deleted file mode 100644 (file)
index 88ac333..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iop321-irq.c
- *
- * Generic IOP321 IRQ handling functionality
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- *
- * 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.
- *
- * Added IOP3XX chipset and IQ80321 board masking code.
- *
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-
-#include <asm/mach-types.h>
-
-static u32 iop321_mask /* = 0 */;
-
-static inline void intctl_write(u32 val)
-{
-       asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val));
-}
-
-static inline void intstr_write(u32 val)
-{
-       asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val));
-}
-
-static void
-iop321_irq_mask (unsigned int irq)
-{
-
-       iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS));
-
-       intctl_write(iop321_mask);
-}
-
-static void
-iop321_irq_unmask (unsigned int irq)
-{
-       iop321_mask |= (1 << (irq - IOP321_IRQ_OFS));
-
-       intctl_write(iop321_mask);
-}
-
-struct irq_chip ext_chip = {
-       .name   = "IOP",
-       .ack    = iop321_irq_mask,
-       .mask   = iop321_irq_mask,
-       .unmask = iop321_irq_unmask,
-};
-
-void __init iop321_init_irq(void)
-{
-       unsigned int i, tmp;
-
-       /* Enable access to coprocessor 6 for dealing with IRQs.
-        * From RMK:
-        * Basically, the Intel documentation here is poor.  It appears that
-        * you need to set the bit to be able to access the coprocessor from
-        * SVC mode.  Whether that allows access from user space or not is
-        * unclear.
-        */
-       asm volatile (
-               "mrc p15, 0, %0, c15, c1, 0\n\t"
-               "orr %0, %0, %1\n\t"
-               "mcr p15, 0, %0, c15, c1, 0\n\t"
-               /* The action is delayed, so we have to do this: */
-               "mrc p15, 0, %0, c15, c1, 0\n\t"
-               "mov %0, %0\n\t"
-               "sub pc, pc, #4"
-               : "=r" (tmp) : "i" (1 << 6) );
-
-       intctl_write(0);                // disable all interrupts
-       intstr_write(0);                // treat all as IRQ
-       if(machine_is_iq80321() ||
-          machine_is_iq31244())        // all interrupts are inputs to chip
-               *IOP321_PCIIRSR = 0x0f;
-
-       for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++)
-       {
-               set_irq_chip(i, &ext_chip);
-               set_irq_handler(i, do_level_IRQ);
-               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-
-       }
-}
-
diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c
deleted file mode 100644 (file)
index 8ba6a0e..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iop321-pci.c
- *
- * PCI support for the Intel IOP321 chipset
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/mach/pci.h>
-
-#include <asm/arch/iop321.h>
-
-// #define DEBUG
-
-#ifdef DEBUG
-#define  DBG(x...) printk(x)
-#else
-#define  DBG(x...) do { } while (0)
-#endif
-
-/*
- * This routine builds either a type0 or type1 configuration command.  If the
- * bus is on the 80321 then a type0 made, else a type1 is created.
- */
-static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where)
-{
-       struct pci_sys_data *sys = bus->sysdata;
-       u32 addr;
-
-       if (sys->busnr == bus->number)
-               addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
-       else
-               addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
-
-       addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
-
-       return addr;
-}
-
-/*
- * This routine checks the status of the last configuration cycle.  If an error
- * was detected it returns a 1, else it returns a 0.  The errors being checked
- * are parity, master abort, target abort (master and target).  These types of
- * errors occure during a config cycle where there is no device, like during
- * the discovery stage.
- */
-static int iop321_pci_status(void)
-{
-       unsigned int status;
-       int ret = 0;
-
-       /*
-        * Check the status registers.
-        */
-       status = *IOP321_ATUSR;
-       if (status & 0xf900)
-       {
-               DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
-               *IOP321_ATUSR = status & 0xf900;
-               ret = 1;
-       }
-       status = *IOP321_ATUISR;
-       if (status & 0x679f)
-       {
-               DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
-               *IOP321_ATUISR = status & 0x679f;
-               ret = 1;
-       }
-       return ret;
-}
-
-/*
- * Simply write the address register and read the configuration
- * data.  Note that the 4 nop's ensure that we are able to handle
- * a delayed abort (in theory.)
- */
-static inline u32 iop321_read(unsigned long addr)
-{
-       u32 val;
-
-       __asm__ __volatile__(
-               "str    %1, [%2]\n\t"
-               "ldr    %0, [%3]\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               : "=r" (val)
-               : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
-
-       return val;
-}
-
-/*
- * The read routines must check the error status of the last configuration
- * cycle.  If there was an error, the routine returns all hex f's.
- */
-static int
-iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 *value)
-{
-       unsigned long addr = iop321_cfg_address(bus, devfn, where);
-       u32 val = iop321_read(addr) >> ((where & 3) * 8);
-
-       if( iop321_pci_status() )
-               val = 0xffffffff;
-
-       *value = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 value)
-{
-       unsigned long addr = iop321_cfg_address(bus, devfn, where);
-       u32 val;
-
-       if (size != 4) {
-               val = iop321_read(addr);
-               if (!iop321_pci_status() == 0)
-                       return PCIBIOS_SUCCESSFUL;
-
-               where = (where & 3) * 8;
-
-               if (size == 1)
-                       val &= ~(0xff << where);
-               else
-                       val &= ~(0xffff << where);
-
-               *IOP321_OCCDR = val | value << where;
-       } else {
-               asm volatile(
-                       "str    %1, [%2]\n\t"
-                       "str    %0, [%3]\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       :
-                       : "r" (value), "r" (addr),
-                         "r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop321_ops = {
-       .read   = iop321_read_config,
-       .write  = iop321_write_config,
-};
-
-/*
- * When a PCI device does not exist during config cycles, the 80200 gets a
- * bus error instead of returning 0xffffffff. This handler simply returns.
- */
-int
-iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-       DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
-               addr, fsr, regs->ARM_pc, regs->ARM_lr);
-
-       /*
-        * If it was an imprecise abort, then we need to correct the
-        * return address to be _after_ the instruction.
-        */
-       if (fsr & (1 << 10))
-               regs->ARM_pc += 4;
-
-       return 0;
-}
-
-/*
- * Scan an IOP321 PCI bus.  sys->bus defines which bus we scan.
- */
-struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys)
-{
-       return pci_scan_bus(sys->busnr, &iop321_ops, sys);
-}
-
-void iop321_init(void)
-{
-       DBG("PCI:  Intel 80321 PCI init code.\n");
-       DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
-       DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n",
-                       *IOP321_OMWTVR0,
-                       *IOP321_OIOWTVR);
-       DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
-       DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n",
-                       *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
-       DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0);
-       DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n",
-                       *IOP321_IABAR1, *IOP321_IALR1);
-       DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n",
-                       *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
-       DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n",
-                       *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
-       DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n",
-                       *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
-
-       hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort");
-}
-
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
deleted file mode 100644 (file)
index b6d0969..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iop321-setup.c
- *
- * Author: Nicolas Pitre <nico@cam.org>
- * Copyright (C) 2001 MontaVista Software, Inc.
- * Copyright (C) 2004 Intel Corporation.
- *
- * 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/mm.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include <asm/setup.h>
-#include <asm/system.h>
-#include <asm/memory.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#define IOP321_UART_XTAL 1843200
-
-/*
- * Standard IO mapping for all IOP321 based systems
- */
-static struct map_desc iop321_std_desc[] __initdata = {
-        {      /* mem mapped registers */
-               .virtual        = IOP321_VIRT_MEM_BASE,
-               .pfn            = __phys_to_pfn(IOP321_PHYS_MEM_BASE),
-               .length         = 0x00002000,
-               .type           = MT_DEVICE
-        }, {   /* PCI IO space */
-               .virtual        = IOP321_PCI_LOWER_IO_VA,
-               .pfn            = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA),
-               .length         = IOP321_PCI_IO_WINDOW_SIZE,
-               .type           = MT_DEVICE
-        }
-};
-
-#ifdef CONFIG_ARCH_IQ80321
-#define UARTBASE IQ80321_UART
-#define IRQ_UART IRQ_IQ80321_UART
-#endif
-
-#ifdef CONFIG_ARCH_IQ31244
-#define UARTBASE IQ31244_UART
-#define IRQ_UART IRQ_IQ31244_UART
-#endif
-
-static struct uart_port iop321_serial_ports[] = {
-       {
-               .membase        = (char*)(UARTBASE),
-               .mapbase        = (UARTBASE),
-               .irq            = IRQ_UART,
-               .flags          = UPF_SKIP_TEST,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = IOP321_UART_XTAL,
-               .line           = 0,
-               .type           = PORT_16550A,
-               .fifosize       = 16
-       }
-};
-
-static struct resource iop32x_i2c_0_resources[] = {
-       [0] = {
-               .start = 0xfffff680,
-               .end = 0xfffff698,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP321_I2C_0,
-               .end = IRQ_IOP321_I2C_0,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop32x_i2c_1_resources[] = {
-       [0] = {
-               .start = 0xfffff6a0,
-               .end = 0xfffff6b8,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP321_I2C_1,
-               .end = IRQ_IOP321_I2C_1,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct platform_device iop32x_i2c_0_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 0,
-       .num_resources = 2,
-       .resource = iop32x_i2c_0_resources
-};
-
-static struct platform_device iop32x_i2c_1_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 1,
-       .num_resources = 2,
-       .resource = iop32x_i2c_1_resources
-};
-
-static struct platform_device *iop32x_devices[] __initdata = {
-       &iop32x_i2c_0_controller,
-       &iop32x_i2c_1_controller
-};
-
-void __init iop32x_init(void)
-{
-       if(iop_is_321())
-       {
-               platform_add_devices(iop32x_devices,
-                               ARRAY_SIZE(iop32x_devices));
-       }
-}
-
-void __init iop321_map_io(void)
-{
-       iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc));
-       early_serial_setup(&iop321_serial_ports[0]);
-}
-
-#ifdef CONFIG_ARCH_IQ80321
-extern void iq80321_map_io(void);
-extern struct sys_timer iop321_timer;
-extern void iop321_init_time(void);
-#endif
-
-#ifdef CONFIG_ARCH_IQ31244
-extern void iq31244_map_io(void);
-extern struct sys_timer iop321_timer;
-extern void iop321_init_time(void);
-#endif
-
-#if defined(CONFIG_ARCH_IQ80321)
-MACHINE_START(IQ80321, "Intel IQ80321")
-       /* Maintainer: Intel Corporation */
-       .phys_io        = IQ80321_UART,
-       .io_pg_offst    = ((IQ80321_UART) >> 18) & 0xfffc,
-       .map_io         = iq80321_map_io,
-       .init_irq       = iop321_init_irq,
-       .timer          = &iop321_timer,
-       .boot_params    = 0xa0000100,
-       .init_machine   = iop32x_init,
-MACHINE_END
-#elif defined(CONFIG_ARCH_IQ31244)
-MACHINE_START(IQ31244, "Intel IQ31244")
-       /* Maintainer: Intel Corp. */
-       .phys_io        = IQ31244_UART,
-       .io_pg_offst    = ((IQ31244_UART) >> 18) & 0xfffc,
-       .map_io         = iq31244_map_io,
-       .init_irq       = iop321_init_irq,
-       .timer          = &iop321_timer,
-       .boot_params    = 0xa0000100,
-       .init_machine   = iop32x_init,
-MACHINE_END
-#else
-#error No machine descriptor defined for this IOP3XX implementation
-#endif
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
deleted file mode 100644 (file)
index 04b1a6f..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iop321-time.c
- *
- * Timer code for IOP321 based systems
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright 2002-2003 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#define IOP321_TIME_SYNC 0
-
-static inline unsigned long get_elapsed(void)
-{
-       return LATCH - *IOP321_TU_TCR0;
-}
-
-static unsigned long iop321_gettimeoffset(void)
-{
-       unsigned long elapsed, usec;
-       u32 tisr1, tisr2;
-
-       /*
-        * If an interrupt was pending before we read the timer,
-        * we've already wrapped.  Factor this into the time.
-        * If an interrupt was pending after we read the timer,
-        * it may have wrapped between checking the interrupt
-        * status and reading the timer.  Re-read the timer to
-        * be sure its value is after the wrap.
-        */
-
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1));
-       elapsed = get_elapsed();
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2));
-
-       if(tisr1 & 1)
-               elapsed += LATCH;
-       else if (tisr2 & 1)
-               elapsed = LATCH + get_elapsed();
-
-       /*
-        * Now convert them to usec.
-        */
-       usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
-
-       return usec;
-}
-
-static irqreturn_t
-iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       u32 tisr;
-
-       write_seqlock(&xtime_lock);
-
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
-       tisr |= 1;
-       asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
-
-       timer_tick(regs);
-
-       write_sequnlock(&xtime_lock);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction iop321_timer_irq = {
-       .name           = "IOP321 Timer Tick",
-       .handler        = iop321_timer_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
-};
-
-static void __init iop321_timer_init(void)
-{
-       u32 timer_ctl;
-
-       setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
-
-       timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
-                       IOP321_TMR_RATIO_1_1;
-
-       asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
-
-       asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl));
-}
-
-struct sys_timer iop321_timer = {
-       .init           = &iop321_timer_init,
-       .offset         = iop321_gettimeoffset,
-};
diff --git a/arch/arm/mach-iop3xx/iop331-irq.c b/arch/arm/mach-iop3xx/iop331-irq.c
deleted file mode 100644 (file)
index cab1172..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iop331-irq.c
- *
- * Generic IOP331 IRQ handling functionality
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003 Intel Corp.
- *
- * 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/init.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-
-#include <asm/mach-types.h>
-
-static u32 iop331_mask0 = 0;
-static u32 iop331_mask1 = 0;
-
-static inline void intctl_write0(u32 val)
-{
-    // INTCTL0
-       asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val));
-}
-
-static inline void intctl_write1(u32 val)
-{
-    // INTCTL1
-    asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val));
-}
-
-static inline void intstr_write0(u32 val)
-{
-    // INTSTR0
-       asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val));
-}
-
-static inline void intstr_write1(u32 val)
-{
-    // INTSTR1
-       asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val));
-}
-
-static void
-iop331_irq_mask1 (unsigned int irq)
-{
-        iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS));
-        intctl_write0(iop331_mask0);
-}
-
-static void
-iop331_irq_mask2 (unsigned int irq)
-{
-        iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32));
-        intctl_write1(iop331_mask1);
-}
-
-static void
-iop331_irq_unmask1(unsigned int irq)
-{
-        iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS));
-        intctl_write0(iop331_mask0);
-}
-
-static void
-iop331_irq_unmask2(unsigned int irq)
-{
-        iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32));
-        intctl_write1(iop331_mask1);
-}
-
-struct irq_chip iop331_irqchip1 = {
-       .name   = "IOP-1",
-       .ack    = iop331_irq_mask1,
-       .mask   = iop331_irq_mask1,
-       .unmask = iop331_irq_unmask1,
-};
-
-struct irq_chip iop331_irqchip2 = {
-       .name   = "IOP-2",
-       .ack    = iop331_irq_mask2,
-       .mask   = iop331_irq_mask2,
-       .unmask = iop331_irq_unmask2,
-};
-
-void __init iop331_init_irq(void)
-{
-       unsigned int i, tmp;
-
-       /* Enable access to coprocessor 6 for dealing with IRQs.
-        * From RMK:
-        * Basically, the Intel documentation here is poor.  It appears that
-        * you need to set the bit to be able to access the coprocessor from
-        * SVC mode.  Whether that allows access from user space or not is
-        * unclear.
-        */
-       asm volatile (
-               "mrc p15, 0, %0, c15, c1, 0\n\t"
-               "orr %0, %0, %1\n\t"
-               "mcr p15, 0, %0, c15, c1, 0\n\t"
-               /* The action is delayed, so we have to do this: */
-               "mrc p15, 0, %0, c15, c1, 0\n\t"
-               "mov %0, %0\n\t"
-               "sub pc, pc, #4"
-               : "=r" (tmp) : "i" (1 << 6) );
-
-       intctl_write0(0);               // disable all interrupts
-       intctl_write1(0);
-       intstr_write0(0);               // treat all as IRQ
-       intstr_write1(0);
-       if(machine_is_iq80331())        // all interrupts are inputs to chip
-               *IOP331_PCIIRSR = 0x0f;
-
-       for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++)
-       {
-               set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2);
-               set_irq_handler(i, do_level_IRQ);
-               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-       }
-}
-
diff --git a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c
deleted file mode 100644 (file)
index 44dd213..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iop331-pci.c
- *
- * PCI support for the Intel IOP331 chipset
- *
- * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2003, 2004 Intel Corp.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/mach/pci.h>
-
-#include <asm/arch/iop331.h>
-
-#undef DEBUG
-#undef DEBUG1
-
-#ifdef DEBUG
-#define  DBG(x...) printk(x)
-#else
-#define  DBG(x...) do { } while (0)
-#endif
-
-#ifdef DEBUG1
-#define  DBG1(x...) printk(x)
-#else
-#define  DBG1(x...) do { } while (0)
-#endif
-
-/*
- * This routine builds either a type0 or type1 configuration command.  If the
- * bus is on the 80331 then a type0 made, else a type1 is created.
- */
-static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where)
-{
-       struct pci_sys_data *sys = bus->sysdata;
-       u32 addr;
-
-       if (sys->busnr == bus->number)
-               addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
-       else
-               addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
-
-       addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
-
-       return addr;
-}
-
-/*
- * This routine checks the status of the last configuration cycle.  If an error
- * was detected it returns a 1, else it returns a 0.  The errors being checked
- * are parity, master abort, target abort (master and target).  These types of
- * errors occure during a config cycle where there is no device, like during
- * the discovery stage.
- */
-static int iop331_pci_status(void)
-{
-       unsigned int status;
-       int ret = 0;
-
-       /*
-        * Check the status registers.
-        */
-       status = *IOP331_ATUSR;
-       if (status & 0xf900)
-       {
-               DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
-               *IOP331_ATUSR = status & 0xf900;
-               ret = 1;
-       }
-       status = *IOP331_ATUISR;
-       if (status & 0x679f)
-       {
-               DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
-               *IOP331_ATUISR = status & 0x679f;
-               ret = 1;
-       }
-       return ret;
-}
-
-/*
- * Simply write the address register and read the configuration
- * data.  Note that the 4 nop's ensure that we are able to handle
- * a delayed abort (in theory.)
- */
-static inline u32 iop331_read(unsigned long addr)
-{
-       u32 val;
-
-       __asm__ __volatile__(
-               "str    %1, [%2]\n\t"
-               "ldr    %0, [%3]\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               "nop\n\t"
-               : "=r" (val)
-               : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR));
-
-       return val;
-}
-
-/*
- * The read routines must check the error status of the last configuration
- * cycle.  If there was an error, the routine returns all hex f's.
- */
-static int
-iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 *value)
-{
-       unsigned long addr = iop331_cfg_address(bus, devfn, where);
-       u32 val = iop331_read(addr) >> ((where & 3) * 8);
-
-       if( iop331_pci_status() )
-               val = 0xffffffff;
-
-       *value = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 value)
-{
-       unsigned long addr = iop331_cfg_address(bus, devfn, where);
-       u32 val;
-
-       if (size != 4) {
-               val = iop331_read(addr);
-               if (!iop331_pci_status() == 0)
-                       return PCIBIOS_SUCCESSFUL;
-
-               where = (where & 3) * 8;
-
-               if (size == 1)
-                       val &= ~(0xff << where);
-               else
-                       val &= ~(0xffff << where);
-
-               *IOP331_OCCDR = val | value << where;
-       } else {
-               asm volatile(
-                       "str    %1, [%2]\n\t"
-                       "str    %0, [%3]\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       "nop\n\t"
-                       :
-                       : "r" (value), "r" (addr),
-                         "r" (IOP331_OCCAR), "r" (IOP331_OCCDR));
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop331_ops = {
-       .read   = iop331_read_config,
-       .write  = iop331_write_config,
-};
-
-/*
- * When a PCI device does not exist during config cycles, the XScale gets a
- * bus error instead of returning 0xffffffff. This handler simply returns.
- */
-int
-iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-       DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
-               addr, fsr, regs->ARM_pc, regs->ARM_lr);
-
-       /*
-        * If it was an imprecise abort, then we need to correct the
-        * return address to be _after_ the instruction.
-        */
-       if (fsr & (1 << 10))
-               regs->ARM_pc += 4;
-
-       return 0;
-}
-
-/*
- * Scan an IOP331 PCI bus.  sys->bus defines which bus we scan.
- */
-struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys)
-{
-       return pci_scan_bus(sys->busnr, &iop331_ops, sys);
-}
-
-void iop331_init(void)
-{
-       DBG1("PCI:  Intel 80331 PCI init code.\n");
-       DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD);
-       DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n",
-                       *IOP331_OMWTVR0,
-                       *IOP331_OIOWTVR);
-       DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1);
-       DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR);
-       DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0);
-       DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1);
-       DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR);
-       DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2);
-       DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3);
-
-       hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort");
-}
-
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
deleted file mode 100644 (file)
index 3cc98d8..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/iop331-setup.c
- *
- * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2004 Intel Corporation.
- *
- * 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/mm.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include <asm/setup.h>
-#include <asm/system.h>
-#include <asm/memory.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#define IOP331_UART_XTAL 33334000
-
-/*
- * Standard IO mapping for all IOP331 based systems
- */
-static struct map_desc iop331_std_desc[] __initdata = {
-       {       /* mem mapped registers */
-               .virtual        = IOP331_VIRT_MEM_BASE,
-               .pfn            = __phys_to_pfn(IOP331_PHYS_MEM_BASE),
-               .length         = 0x00002000,
-               .type           = MT_DEVICE
-       }, {    /* PCI IO space */
-               .virtual        = IOP331_PCI_LOWER_IO_VA,
-               .pfn            = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA),
-               .length         = IOP331_PCI_IO_WINDOW_SIZE,
-               .type           = MT_DEVICE
-       }
-};
-
-static struct resource iop33x_uart0_resources[] = {
-       [0] = {
-               .start = IOP331_UART0_PHYS,
-               .end = IOP331_UART0_PHYS + 0x3f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP331_UART0,
-               .end = IRQ_IOP331_UART0,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop33x_uart1_resources[] = {
-       [0] = {
-               .start = IOP331_UART1_PHYS,
-               .end = IOP331_UART1_PHYS + 0x3f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP331_UART1,
-               .end = IRQ_IOP331_UART1,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct plat_serial8250_port iop33x_uart0_data[] = {
-       {
-       .membase     = (char*)(IOP331_UART0_VIRT),
-       .mapbase     = (IOP331_UART0_PHYS),
-       .irq         = IRQ_IOP331_UART0,
-       .uartclk     = IOP331_UART_XTAL,
-       .regshift    = 2,
-       .iotype      = UPIO_MEM,
-       .flags       = UPF_SKIP_TEST,
-       },
-       {  },
-};
-
-static struct plat_serial8250_port iop33x_uart1_data[] = {
-       {
-       .membase     = (char*)(IOP331_UART1_VIRT),
-       .mapbase     = (IOP331_UART1_PHYS),
-       .irq         = IRQ_IOP331_UART1,
-       .uartclk     = IOP331_UART_XTAL,
-       .regshift    = 2,
-       .iotype      = UPIO_MEM,
-       .flags       = UPF_SKIP_TEST,
-       },
-       {  },
-};
-
-static struct platform_device iop33x_uart0 = {
-       .name = "serial8250",
-       .id = PLAT8250_DEV_PLATFORM,
-       .dev.platform_data = iop33x_uart0_data,
-       .num_resources = 2,
-       .resource = iop33x_uart0_resources,
-};
-
-static struct platform_device iop33x_uart1 = {
-       .name = "serial8250",
-       .id = PLAT8250_DEV_PLATFORM1,
-       .dev.platform_data = iop33x_uart1_data,
-       .num_resources = 2,
-       .resource = iop33x_uart1_resources,
-};
-
-static struct resource iop33x_i2c_0_resources[] = {
-       [0] = {
-               .start = 0xfffff680,
-               .end = 0xfffff698,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP331_I2C_0,
-               .end = IRQ_IOP331_I2C_0,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop33x_i2c_1_resources[] = {
-       [0] = {
-               .start = 0xfffff6a0,
-               .end = 0xfffff6b8,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP331_I2C_1,
-               .end = IRQ_IOP331_I2C_1,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct platform_device iop33x_i2c_0_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 0,
-       .num_resources = 2,
-       .resource = iop33x_i2c_0_resources
-};
-
-static struct platform_device iop33x_i2c_1_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 1,
-       .num_resources = 2,
-       .resource = iop33x_i2c_1_resources
-};
-
-static struct platform_device *iop33x_devices[] __initdata = {
-       &iop33x_uart0,
-       &iop33x_uart1,
-       &iop33x_i2c_0_controller,
-       &iop33x_i2c_1_controller
-};
-
-void __init iop33x_init(void)
-{
-       if(iop_is_331())
-       {
-               platform_add_devices(iop33x_devices,
-                               ARRAY_SIZE(iop33x_devices));
-       }
-}
-
-void __init iop331_map_io(void)
-{
-       iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc));
-}
-
-#ifdef CONFIG_ARCH_IOP331
-extern void iop331_init_irq(void);
-extern struct sys_timer iop331_timer;
-#endif
-
-#ifdef CONFIG_ARCH_IQ80331
-extern void iq80331_map_io(void);
-#endif
-
-#ifdef CONFIG_MACH_IQ80332
-extern void iq80332_map_io(void);
-#endif
-
-#if defined(CONFIG_ARCH_IQ80331)
-MACHINE_START(IQ80331, "Intel IQ80331")
-       /* Maintainer: Intel Corp. */
-       .phys_io        = 0xfefff000,
-       .io_pg_offst    = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
-       .map_io         = iq80331_map_io,
-       .init_irq       = iop331_init_irq,
-       .timer          = &iop331_timer,
-       .boot_params    = 0x0100,
-       .init_machine   = iop33x_init,
-MACHINE_END
-
-#elif defined(CONFIG_MACH_IQ80332)
-MACHINE_START(IQ80332, "Intel IQ80332")
-       /* Maintainer: Intel Corp. */
-       .phys_io        = 0xfefff000,
-       .io_pg_offst    = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
-       .map_io         = iq80332_map_io,
-       .init_irq       = iop331_init_irq,
-       .timer          = &iop331_timer,
-       .boot_params    = 0x0100,
-       .init_machine   = iop33x_init,
-MACHINE_END
-
-#else
-#error No machine descriptor defined for this IOP3XX implementation
-#endif
-
-
diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c
deleted file mode 100644 (file)
index 0c09e74..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iop331-time.c
- *
- * Timer code for IOP331 based systems
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- *
- * Copyright 2003 Intel Corp.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-static inline unsigned long get_elapsed(void)
-{
-       return LATCH - *IOP331_TU_TCR0;
-}
-
-static unsigned long iop331_gettimeoffset(void)
-{
-       unsigned long elapsed, usec;
-       u32 tisr1, tisr2;
-
-       /*
-        * If an interrupt was pending before we read the timer,
-        * we've already wrapped.  Factor this into the time.
-        * If an interrupt was pending after we read the timer,
-        * it may have wrapped between checking the interrupt
-        * status and reading the timer.  Re-read the timer to
-        * be sure its value is after the wrap.
-        */
-
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1));
-       elapsed = get_elapsed();
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2));
-
-       if(tisr1 & 1)
-               elapsed += LATCH;
-       else if (tisr2 & 1)
-               elapsed = LATCH + get_elapsed();
-
-       /*
-        * Now convert them to usec.
-        */
-       usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
-
-       return usec;
-}
-
-static irqreturn_t
-iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       u32 tisr;
-
-       write_seqlock(&xtime_lock);
-
-       asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
-       tisr |= 1;
-       asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
-
-       timer_tick(regs);
-
-       write_sequnlock(&xtime_lock);
-       return IRQ_HANDLED;
-}
-
-static struct irqaction iop331_timer_irq = {
-       .name           = "IOP331 Timer Tick",
-       .handler        = iop331_timer_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
-};
-
-static void __init iop331_timer_init(void)
-{
-       u32 timer_ctl;
-
-       setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq);
-
-       timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD |
-                       IOP331_TMR_RATIO_1_1;
-
-       asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
-
-       asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl));
-
-}
-
-struct sys_timer iop331_timer = {
-       .init           = iop331_timer_init,
-       .offset         = iop331_gettimeoffset,
-};
diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c
deleted file mode 100644 (file)
index e874b54..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/mm.c
- *
- * Low level memory initialization for iq80321 platform
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- *
- * 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/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-
-/*
- * IQ80321 specific IO mappings
- *
- * We use RedBoot's setup for the onboard devices.
- */
-static struct map_desc iq31244_io_desc[] __initdata = {
-       {       /* on-board devices */
-               .virtual        = IQ31244_UART,
-               .pfn            = __phys_to_pfn(IQ31244_UART),
-               .length         = 0x00100000,
-               .type           = MT_DEVICE
-       }
-};
-
-void __init iq31244_map_io(void)
-{
-       iop321_map_io();
-
-       iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
-}
diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
deleted file mode 100644 (file)
index f3c6413..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iq80321-pci.c
- *
- * PCI support for the Intel IQ80321 reference board
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- * Copyright (C) 2004 Intel Corp.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those systems that do not already have PCI
- * interrupts properly routed.  We assume 1 <= pin <= 4
- */
-#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)      \
-({ int _ctl_ = -1;                             \
-   unsigned int _idsel = idsel - minid;                \
-   if (_idsel <= maxid)                                \
-      _ctl_ = pci_irq_table[_idsel][pin-1];    \
-   _ctl_; })
-
-#define INTA   IRQ_IQ31244_INTA
-#define INTB   IRQ_IQ31244_INTB
-#define INTC   IRQ_IQ31244_INTC
-#define INTD   IRQ_IQ31244_INTD
-
-#define INTE   IRQ_IQ31244_I82546
-
-static inline int __init
-iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       static int pci_irq_table[][4] = {
-               /*
-                * PCI IDSEL/INTPIN->INTLINE
-                * A       B       C       D
-                */
-#ifdef CONFIG_ARCH_EP80219
-               {INTB, INTB, INTB, INTB}, /* CFlash */
-               {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */
-               {INTD, INTD, INTD, INTD}, /* PCI-X Slot */
-               {INTC, INTC, INTC, INTC}, /* SATA   */
-#else
-               {INTB, INTB, INTB, INTB}, /* CFlash */
-               {INTC, INTC, INTC, INTC}, /* SATA   */
-               {INTD, INTD, INTD, INTD}, /* PCI-X Slot */
-               {INTE, INTE, INTE, INTE}, /* 82546 GigE */
-#endif // CONFIG_ARCH_EP80219
-       };
-
-       BUG_ON(pin < 1 || pin > 4);
-
-       return PCI_IRQ_TABLE_LOOKUP(0, 7);
-}
-
-static int iq31244_setup(int nr, struct pci_sys_data *sys)
-{
-       struct resource *res;
-
-       if(nr != 0)
-               return 0;
-
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               panic("PCI: unable to alloc resources");
-
-       res[0].start = IOP321_PCI_LOWER_IO_VA;
-       res[0].end   = IOP321_PCI_UPPER_IO_VA;
-       res[0].name  = "IQ31244 PCI I/O Space";
-       res[0].flags = IORESOURCE_IO;
-
-       res[1].start = IOP321_PCI_LOWER_MEM_PA;
-       res[1].end   = IOP321_PCI_UPPER_MEM_PA;
-       res[1].name  = "IQ31244 PCI Memory Space";
-       res[1].flags = IORESOURCE_MEM;
-
-       request_resource(&ioport_resource, &res[0]);
-       request_resource(&iomem_resource, &res[1]);
-
-       sys->mem_offset = IOP321_PCI_MEM_OFFSET;
-       sys->io_offset  = IOP321_PCI_IO_OFFSET;
-
-       sys->resource[0] = &res[0];
-       sys->resource[1] = &res[1];
-       sys->resource[2] = NULL;
-
-       return 1;
-}
-
-static void iq31244_preinit(void)
-{
-       iop321_init();
-}
-
-static struct hw_pci iq31244_pci __initdata = {
-       .swizzle        = pci_std_swizzle,
-       .nr_controllers = 1,
-       .setup          = iq31244_setup,
-       .scan           = iop321_scan_bus,
-       .preinit        = iq31244_preinit,
-       .map_irq        = iq31244_map_irq
-};
-
-static int __init iq31244_pci_init(void)
-{
-       if (machine_is_iq31244())
-               pci_common_init(&iq31244_pci);
-       return 0;
-}
-
-subsys_initcall(iq31244_pci_init);
-
-
-
-
diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c
deleted file mode 100644 (file)
index d9cac5e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/mm.c
- *
- * Low level memory initialization for iq80321 platform
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- *
- * 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/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-
-/*
- * IQ80321 specific IO mappings
- *
- * We use RedBoot's setup for the onboard devices.
- */
-static struct map_desc iq80321_io_desc[] __initdata = {
-       {       /* on-board devices */
-               .virtual        = IQ80321_UART,
-               .pfn            = __phys_to_pfn(IQ80321_UART),
-               .length         = 0x00100000,
-               .type           = MT_DEVICE
-       }
-};
-
-void __init iq80321_map_io(void)
-{
-       iop321_map_io();
-
-       iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
-}
diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
deleted file mode 100644 (file)
index d9758d3..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iq80321-pci.c
- *
- * PCI support for the Intel IQ80321 reference board
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- * Copyright (C) 2004 Intel Corp.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those systems that do not already have PCI
- * interrupts properly routed.  We assume 1 <= pin <= 4
- */
-#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)      \
-({ int _ctl_ = -1;                             \
-   unsigned int _idsel = idsel - minid;                \
-   if (_idsel <= maxid)                                \
-      _ctl_ = pci_irq_table[_idsel][pin-1];    \
-   _ctl_; })
-
-#define INTA   IRQ_IQ80321_INTA
-#define INTB   IRQ_IQ80321_INTB
-#define INTC   IRQ_IQ80321_INTC
-#define INTD   IRQ_IQ80321_INTD
-
-#define INTE   IRQ_IQ80321_I82544
-
-static inline int __init
-iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       static int pci_irq_table[][4] = {
-               /*
-                * PCI IDSEL/INTPIN->INTLINE
-                * A       B       C       D
-                */
-               {INTE, INTE, INTE, INTE}, /* Gig-E */
-               {-1, -1, -1, -1},         /* Unused */
-               {INTC, INTD, INTA, INTB}, /* PCI-X Slot */
-               {-1, -1, -1, -1},
-       };
-
-       BUG_ON(pin < 1 || pin > 4);
-
-//     return PCI_IRQ_TABLE_LOOKUP(4, 7);
-       return pci_irq_table[idsel%4][pin-1];
-}
-
-static int iq80321_setup(int nr, struct pci_sys_data *sys)
-{
-       struct resource *res;
-
-       if(nr != 0)
-               return 0;
-
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               panic("PCI: unable to alloc resources");
-
-       res[0].start = IOP321_PCI_LOWER_IO_VA;
-       res[0].end   = IOP321_PCI_UPPER_IO_VA;
-       res[0].name  = "IQ80321 PCI I/O Space";
-       res[0].flags = IORESOURCE_IO;
-
-       res[1].start = IOP321_PCI_LOWER_MEM_PA;
-       res[1].end   = IOP321_PCI_UPPER_MEM_PA;
-       res[1].name  = "IQ80321 PCI Memory Space";
-       res[1].flags = IORESOURCE_MEM;
-
-       request_resource(&ioport_resource, &res[0]);
-       request_resource(&iomem_resource, &res[1]);
-
-       sys->mem_offset = IOP321_PCI_MEM_OFFSET;
-       sys->io_offset  = IOP321_PCI_IO_OFFSET;
-
-       sys->resource[0] = &res[0];
-       sys->resource[1] = &res[1];
-       sys->resource[2] = NULL;
-
-       return 1;
-}
-
-static void iq80321_preinit(void)
-{
-       iop321_init();
-}
-
-static struct hw_pci iq80321_pci __initdata = {
-       .swizzle        = pci_std_swizzle,
-       .nr_controllers = 1,
-       .setup          = iq80321_setup,
-       .scan           = iop321_scan_bus,
-       .preinit        = iq80321_preinit,
-       .map_irq        = iq80321_map_irq
-};
-
-static int __init iq80321_pci_init(void)
-{
-       if (machine_is_iq80321())
-               pci_common_init(&iq80321_pci);
-       return 0;
-}
-
-subsys_initcall(iq80321_pci_init);
-
-
-
-
diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c
deleted file mode 100644 (file)
index 129eb49..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/mm.c
- *
- * Low level memory initialization for iq80331 platform
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003 Intel Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-
-/*
- * IQ80331 specific IO mappings
- *
- * We use RedBoot's setup for the onboard devices.
- */
-
-void __init iq80331_map_io(void)
-{
-       iop331_map_io();
-}
diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
deleted file mode 100644 (file)
index 40d8610..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iq80331-pci.c
- *
- * PCI support for the Intel IQ80331 reference board
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003, 2004 Intel Corp.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those systems that do not already have PCI
- * interrupts properly routed.  We assume 1 <= pin <= 4
- */
-#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)      \
-({ int _ctl_ = -1;                             \
-   unsigned int _idsel = idsel - minid;                \
-   if (_idsel <= maxid)                                \
-      _ctl_ = pci_irq_table[_idsel][pin-1];    \
-   _ctl_; })
-
-#define INTA   IRQ_IQ80331_INTA
-#define INTB   IRQ_IQ80331_INTB
-#define INTC   IRQ_IQ80331_INTC
-#define INTD   IRQ_IQ80331_INTD
-
-//#define INTE IRQ_IQ80331_I82544
-
-static inline int __init
-iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       static int pci_irq_table[][4] = {
-               /*
-                * PCI IDSEL/INTPIN->INTLINE
-                * A       B       C       D
-                */
-               {INTB, INTC, INTD, INTA}, /* PCI-X Slot */
-               {INTC, INTC, INTC, INTC}, /* GigE  */
-       };
-
-       BUG_ON(pin < 1 || pin > 4);
-
-       return PCI_IRQ_TABLE_LOOKUP(1, 7);
-}
-
-static int iq80331_setup(int nr, struct pci_sys_data *sys)
-{
-       struct resource *res;
-
-       if(nr != 0)
-               return 0;
-
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               panic("PCI: unable to alloc resources");
-
-       res[0].start = IOP331_PCI_LOWER_IO_VA;
-       res[0].end   = IOP331_PCI_UPPER_IO_VA;
-       res[0].name  = "IQ80331 PCI I/O Space";
-       res[0].flags = IORESOURCE_IO;
-
-       res[1].start = IOP331_PCI_LOWER_MEM_PA;
-       res[1].end   = IOP331_PCI_UPPER_MEM_PA;
-       res[1].name  = "IQ80331 PCI Memory Space";
-       res[1].flags = IORESOURCE_MEM;
-
-       request_resource(&ioport_resource, &res[0]);
-       request_resource(&iomem_resource, &res[1]);
-
-       sys->mem_offset = IOP331_PCI_MEM_OFFSET;
-       sys->io_offset  = IOP331_PCI_IO_OFFSET;
-
-       sys->resource[0] = &res[0];
-       sys->resource[1] = &res[1];
-       sys->resource[2] = NULL;
-
-       return 1;
-}
-
-static void iq80331_preinit(void)
-{
-       iop331_init();
-}
-
-static struct hw_pci iq80331_pci __initdata = {
-       .swizzle        = pci_std_swizzle,
-       .nr_controllers = 1,
-       .setup          = iq80331_setup,
-       .scan           = iop331_scan_bus,
-       .preinit        = iq80331_preinit,
-       .map_irq        = iq80331_map_irq
-};
-
-static int __init iq80331_pci_init(void)
-{
-       if (machine_is_iq80331())
-               pci_common_init(&iq80331_pci);
-       return 0;
-}
-
-subsys_initcall(iq80331_pci_init);
-
-
-
-
diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c
deleted file mode 100644 (file)
index 2feaf75..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * linux/arch/arm/mach-iop3xx/mm.c
- *
- * Low level memory initialization for iq80332 platform
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2004 Intel Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-
-/*
- * IQ80332 specific IO mappings
- *
- * We use RedBoot's setup for the onboard devices.
- */
-
-void __init iq80332_map_io(void)
-{
-       iop331_map_io();
-}
diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
deleted file mode 100644 (file)
index afc0676..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * arch/arm/mach-iop3xx/iq80332-pci.c
- *
- * PCI support for the Intel IQ80332 reference board
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2004 Intel Corp.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those systems that do not already have PCI
- * interrupts properly routed.  We assume 1 <= pin <= 4
- */
-#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)      \
-({ int _ctl_ = -1;                             \
-   unsigned int _idsel = idsel - minid;                \
-   if (_idsel <= maxid)                                \
-      _ctl_ = pci_irq_table[_idsel][pin-1];    \
-   _ctl_; })
-
-#define INTA   IRQ_IQ80332_INTA
-#define INTB   IRQ_IQ80332_INTB
-#define INTC   IRQ_IQ80332_INTC
-#define INTD   IRQ_IQ80332_INTD
-
-//#define INTE IRQ_IQ80332_I82544
-
-static inline int __init
-iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       static int pci_irq_table[][8] = {
-               /*
-                * PCI IDSEL/INTPIN->INTLINE
-                * A       B       C       D
-                */
-               {-1,   -1,   -1,   -1},
-               {-1,   -1,   -1,   -1},
-               {-1,   -1,   -1,   -1},
-               {INTA, INTB, INTC, INTD}, /* PCI-X Slot */
-               {-1,   -1,   -1,   -1},
-               {INTC, INTC, INTC, INTC}, /* GigE  */
-               {-1,   -1,   -1,   -1},
-               {-1,   -1,   -1,   -1},
-       };
-
-       BUG_ON(pin < 1 || pin > 4);
-
-       return PCI_IRQ_TABLE_LOOKUP(1, 7);
-}
-
-static int iq80332_setup(int nr, struct pci_sys_data *sys)
-{
-       struct resource *res;
-
-       if(nr != 0)
-               return 0;
-
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               panic("PCI: unable to alloc resources");
-
-       res[0].start = IOP331_PCI_LOWER_IO_VA;
-       res[0].end   = IOP331_PCI_UPPER_IO_VA;
-       res[0].name  = "IQ80332 PCI I/O Space";
-       res[0].flags = IORESOURCE_IO;
-
-       res[1].start = IOP331_PCI_LOWER_MEM_PA;
-       res[1].end   = IOP331_PCI_UPPER_MEM_PA;
-       res[1].name  = "IQ80332 PCI Memory Space";
-       res[1].flags = IORESOURCE_MEM;
-
-       request_resource(&ioport_resource, &res[0]);
-       request_resource(&iomem_resource, &res[1]);
-
-       sys->mem_offset = IOP331_PCI_MEM_OFFSET;
-       sys->io_offset  = IOP331_PCI_IO_OFFSET;
-
-       sys->resource[0] = &res[0];
-       sys->resource[1] = &res[1];
-       sys->resource[2] = NULL;
-
-       return 1;
-}
-
-static void iq80332_preinit(void)
-{
-       iop331_init();
-}
-
-static struct hw_pci iq80332_pci __initdata = {
-       .swizzle        = pci_std_swizzle,
-       .nr_controllers = 1,
-       .setup          = iq80332_setup,
-       .scan           = iop331_scan_bus,
-       .preinit        = iq80332_preinit,
-       .map_irq        = iq80332_map_irq
-};
-
-static int __init iq80332_pci_init(void)
-{
-       if (machine_is_iq80332())
-               pci_common_init(&iq80332_pci);
-       return 0;
-}
-
-subsys_initcall(iq80332_pci_init);
-
-
-
-
index 7c25dbd5a181cb78723a5f969b55aebc94ba0029..35dd8b3824b0301a5d8fc9ecc4b849408c21324f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/bitops.h>
 #include <linux/time.h>
 #include <linux/timex.h>
+#include <linux/clocksource.h>
 
 #include <asm/hardware.h>
 #include <asm/uaccess.h>
@@ -255,16 +256,6 @@ static unsigned volatile last_jiffy_time;
 
 #define CLOCK_TICKS_PER_USEC   ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
 
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long ixp4xx_gettimeoffset(void)
-{
-       u32 elapsed;
-
-       elapsed = *IXP4XX_OSTS - last_jiffy_time;
-
-       return elapsed / CLOCK_TICKS_PER_USEC;
-}
-
 static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        write_seqlock(&xtime_lock);
@@ -309,7 +300,6 @@ static void __init ixp4xx_timer_init(void)
 
 struct sys_timer ixp4xx_timer = {
        .init           = ixp4xx_timer_init,
-       .offset         = ixp4xx_gettimeoffset,
 };
 
 static struct resource ixp46x_i2c_resources[] = {
@@ -365,3 +355,29 @@ void __init ixp4xx_sys_init(void)
                        ixp4xx_exp_bus_size >> 20);
 }
 
+cycle_t ixp4xx_get_cycles(void)
+{
+       return *IXP4XX_OSTS;
+}
+
+static struct clocksource clocksource_ixp4xx = {
+       .name           = "OSTS",
+       .rating         = 200,
+       .read           = ixp4xx_get_cycles,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 20,
+       .is_continuous  = 1,
+};
+
+unsigned long ixp4xx_timer_freq = FREQ;
+static int __init ixp4xx_clocksource_init(void)
+{
+       clocksource_ixp4xx.mult =
+               clocksource_hz2mult(ixp4xx_timer_freq,
+                                   clocksource_ixp4xx.shift);
+       clocksource_register(&clocksource_ixp4xx);
+
+       return 0;
+}
+
+device_initcall(ixp4xx_clocksource_init);
index 749a337494d3a710769dad39239e3140dcd43448..162c266e5f8fb8ff3883f4df29ddc69c7f80e3ab 100644 (file)
@@ -159,6 +159,8 @@ static void nslu2_power_off(void)
 
 static void __init nslu2_init(void)
 {
+       ixp4xx_timer_freq = NSLU2_FREQ;
+
        ixp4xx_sys_init();
 
        nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
index c753a3c5aadd4f09d9e0e7e0cbde7de606410a0d..62e42c7a628e55ac1f86616064667ea2e0188534 100644 (file)
@@ -172,9 +172,11 @@ static struct resource kp_resources[] = {
 };
 
 static struct omap_kp_platform_data kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = fsample_keymap,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = fsample_keymap,
+       .keymapsize     = ARRAY_SIZE(fsample_keymap),
+       .delay          = 4,
 };
 
 static struct platform_device kp_device = {
index cd3a06dfc0a83d2e5f0d280c4ace0f49cef988c3..6e113078f7ab4fa3415f42d68901e3e0ecc0aaaf 100644 (file)
@@ -167,10 +167,13 @@ static struct resource h2_kp_resources[] = {
 };
 
 static struct omap_kp_platform_data h2_kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = h2_keymap,
-       .rep    = 1,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = h2_keymap,
+       .keymapsize     = ARRAY_SIZE(h2_keymap),
+       .rep            = 1,
+       .delay          = 9,
+       .dbounce        = 1,
 };
 
 static struct platform_device h2_kp_device = {
index 7b206116cd0391882f6d093325150bf9577acd80..f225a083dee1bb13073127a6cc05c6a21e199cfa 100644 (file)
@@ -247,10 +247,13 @@ static struct resource h3_kp_resources[] = {
 };
 
 static struct omap_kp_platform_data h3_kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = h3_keymap,
-       .rep    = 1,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = h3_keymap,
+       .keymapsize     = ARRAY_SIZE(h3_keymap),
+       .rep            = 1,
+       .delay          = 9,
+       .dbounce        = 1,
 };
 
 static struct platform_device h3_kp_device = {
index 4cbc62db5b5dd5cd6a72da1c4efbdf2ec56b8aa2..cb00530ad279392725581ae81b57c07a215eb1e6 100644 (file)
@@ -159,9 +159,11 @@ static struct resource innovator_kp_resources[] = {
 };
 
 static struct omap_kp_platform_data innovator_kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = innovator_keymap,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = innovator_keymap,
+       .keymapsize     = ARRAY_SIZE(innovator_keymap),
+       .delay          = 4,
 };
 
 static struct platform_device innovator_kp_device = {
index 02b980d77b12d2079e84d23a27eea010005707be..dbc555d209ff914eeff8b0b51d77d814212e430b 100644 (file)
@@ -71,9 +71,11 @@ static struct resource nokia770_kp_resources[] = {
 };
 
 static struct omap_kp_platform_data nokia770_kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = nokia770_keymap
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = nokia770_keymap,
+       .keymapsize     = ARRAY_SIZE(nokia770_keymap)
+       .delay          = 4,
 };
 
 static struct platform_device nokia770_kp_device = {
index b742261c97ade63be4e744070d374ab66407bd4e..6b05647a6c01743504650c1021013b19dc367f51 100644 (file)
@@ -266,9 +266,11 @@ static const int osk_keymap[] = {
 };
 
 static struct omap_kp_platform_data osk_kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = (int *) osk_keymap,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = (int *) osk_keymap,
+       .keymapsize     = ARRAY_SIZE(osk_keymap),
+       .delay          = 9,
 };
 
 static struct resource osk5912_kp_resources[] = {
index 64b45d8ae357e9e7e3addb767707201672aa6031..fa4be962df67b454c09afc2ea956f11251904825 100644 (file)
@@ -171,9 +171,12 @@ static struct resource kp_resources[] = {
 };
 
 static struct omap_kp_platform_data kp_data = {
-       .rows   = 8,
-       .cols   = 8,
-       .keymap = p2_keymap,
+       .rows           = 8,
+       .cols           = 8,
+       .keymap         = p2_keymap,
+       .keymapsize     = ARRAY_SIZE(p2_keymap),
+       .delay          = 4,
+       .dbounce        = 1,
 };
 
 static struct platform_device kp_device = {
index f1958e882e8694e3bd480dd46b62af3f351c6d28..638490e62d5f5ebb7e07a21f586c521b9b2f2fe2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/clk.h>
 
 #include <asm/io.h>
+#include <asm/mach-types.h>
 
 #include <asm/arch/cpu.h>
 #include <asm/arch/usb.h>
@@ -586,77 +587,53 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
  *-------------------------------------------------------------------------*/
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
-/*
- * Resets some clocks that may be left on from bootloader,
- * but leaves serial clocks on. See also omap_late_clk_reset().
- */
-static inline void omap1_early_clk_reset(void)
-{
-       //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
-}
 
-static int __init omap1_late_clk_reset(void)
+static void __init omap1_clk_disable_unused(struct clk *clk)
 {
-       /* Turn off all unused clocks */
-       struct clk *p;
        __u32 regval32;
 
-       /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
-       regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
-       omap_writew(regval32, SOFT_REQ_REG);
-       omap_writew(0, SOFT_REQ_REG2);
-
-       list_for_each_entry(p, &clocks, node) {
-               if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
-                       p->enable_reg == 0)
-                       continue;
-
-               /* Clocks in the DSP domain need api_ck. Just assume bootloader
-                * has not enabled any DSP clocks */
-               if ((u32)p->enable_reg == DSP_IDLECT2) {
-                       printk(KERN_INFO "Skipping reset check for DSP domain "
-                              "clock \"%s\"\n", p->name);
-                       continue;
-               }
+       /* Clocks in the DSP domain need api_ck. Just assume bootloader
+        * has not enabled any DSP clocks */
+       if ((u32)clk->enable_reg == DSP_IDLECT2) {
+               printk(KERN_INFO "Skipping reset check for DSP domain "
+                      "clock \"%s\"\n", clk->name);
+               return;
+       }
 
-               /* Is the clock already disabled? */
-               if (p->flags & ENABLE_REG_32BIT) {
-                       if (p->flags & VIRTUAL_IO_ADDRESS)
-                               regval32 = __raw_readl(p->enable_reg);
-                       else
-                               regval32 = omap_readl(p->enable_reg);
-               } else {
-                       if (p->flags & VIRTUAL_IO_ADDRESS)
-                               regval32 = __raw_readw(p->enable_reg);
+       /* Is the clock already disabled? */
+       if (clk->flags & ENABLE_REG_32BIT) {
+               if (clk->flags & VIRTUAL_IO_ADDRESS)
+                       regval32 = __raw_readl(clk->enable_reg);
                        else
-                               regval32 = omap_readw(p->enable_reg);
-               }
-
-               if ((regval32 & (1 << p->enable_bit)) == 0)
-                       continue;
+                               regval32 = omap_readl(clk->enable_reg);
+       } else {
+               if (clk->flags & VIRTUAL_IO_ADDRESS)
+                       regval32 = __raw_readw(clk->enable_reg);
+               else
+                       regval32 = omap_readw(clk->enable_reg);
+       }
 
-               /* FIXME: This clock seems to be necessary but no-one
-                * has asked for its activation. */
-               if (p == &tc2_ck         // FIX: pm.c (SRAM), CCP, Camera
-                   || p == &ck_dpll1out.clk // FIX: SoSSI, SSR
-                   || p == &arm_gpio_ck // FIX: GPIO code for 1510
-                   ) {
-                       printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
-                              p->name);
-                       continue;
-               }
+       if ((regval32 & (1 << clk->enable_bit)) == 0)
+               return;
 
-               printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
-               p->disable(p);
-               printk(" done\n");
+       /* FIXME: This clock seems to be necessary but no-one
+        * has asked for its activation. */
+       if (clk == &tc2_ck              // FIX: pm.c (SRAM), CCP, Camera
+           || clk == &ck_dpll1out.clk  // FIX: SoSSI, SSR
+           || clk == &arm_gpio_ck      // FIX: GPIO code for 1510
+               ) {
+               printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
+                      clk->name);
+               return;
        }
 
-       return 0;
+       printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
+       clk->disable(clk);
+       printk(" done\n");
 }
-late_initcall(omap1_late_clk_reset);
 
 #else
-#define omap1_early_clk_reset()        {}
+#define omap1_clk_disable_unused       NULL
 #endif
 
 static struct clk_functions omap1_clk_functions = {
@@ -664,6 +641,7 @@ static struct clk_functions omap1_clk_functions = {
        .clk_disable            = omap1_clk_disable,
        .clk_round_rate         = omap1_clk_round_rate,
        .clk_set_rate           = omap1_clk_set_rate,
+       .clk_disable_unused     = omap1_clk_disable_unused,
 };
 
 int __init omap1_clk_init(void)
@@ -671,8 +649,13 @@ int __init omap1_clk_init(void)
        struct clk ** clkp;
        const struct omap_clock_config *info;
        int crystal_type = 0; /* Default 12 MHz */
+       u32 reg;
+
+       /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+       reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
+       omap_writew(reg, SOFT_REQ_REG);
+       omap_writew(0, SOFT_REQ_REG2);
 
-       omap1_early_clk_reset();
        clk_init(&omap1_clk_functions);
 
        /* By default all idlect1 clocks are allowed to idle */
@@ -772,6 +755,12 @@ int __init omap1_clk_init(void)
        omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
 #endif
 
+       /* Amstrad Delta wants BCLK high when inactive */
+       if (machine_is_ams_delta())
+               omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
+                               (1 << SDW_MCLK_INV_BIT),
+                               ULPD_CLOCK_CTRL);
+
        /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
        /* (on 730, bit 13 must not be cleared) */
        if (cpu_is_omap730())
index b7c68819c4e7e2391cf474491bd441f0d8b38bc6..f7df00205c4a6541827cb6e8331901b4c229e34b 100644 (file)
@@ -89,6 +89,7 @@ struct arm_idlect1_clk {
 #define EN_DSPTIMCK    5
 
 /* Various register defines for clock controls scattered around OMAP chip */
+#define SDW_MCLK_INV_BIT       2       /* In ULPD_CLKC_CTRL */
 #define USB_MCLK_EN_BIT                4       /* In ULPD_CLKC_CTRL */
 #define USB_HOST_HHC_UHOST_EN  9       /* In MOD_CONF_CTRL_0 */
 #define SWD_ULPD_PLL_CLK_REQ   1       /* In SWD_CLK_DIV_CTRL_SEL */
@@ -741,6 +742,18 @@ static struct clk i2c_fck = {
        .disable        = &omap1_clk_disable_generic,
 };
 
+static struct clk i2c_ick = {
+       .name           = "i2c_ick",
+       .id             = 1,
+       .flags          = CLOCK_IN_OMAP16XX |
+                         VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
+                         ALWAYS_ENABLED,
+       .parent         = &armper_ck.clk,
+       .recalc         = &followparent_recalc,
+       .enable         = &omap1_clk_enable_generic,
+       .disable        = &omap1_clk_disable_generic,
+};
+
 static struct clk * onchip_clks[] = {
        /* non-ULPD clocks */
        &ck_ref,
@@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = {
        /* Virtual clocks */
        &virtual_ck_mpu,
        &i2c_fck,
+       &i2c_ick,
 };
 
 #endif
index fa74ef7af15f730d8af3da0a150982c0b50ae675..5432335bc493de0d65e44155909bd5ff413d7195 100644 (file)
@@ -199,6 +199,17 @@ MUX_CFG("N14_1610_UWIRE_CS0",       8,    9,    1,   1,  21,   0,    1,     1,  1)
 MUX_CFG("P15_1610_UWIRE_CS3",   8,   12,    1,   1,  22,   0,    1,     1,  1)
 MUX_CFG("N15_1610_UWIRE_CS1",   7,   18,    2,   1,  14,   0,   NA,     0,  1)
 
+/* OMAP-1610 SPI */
+MUX_CFG("U19_1610_SPIF_SCK",    7,    21,   6,   1,  15,   0,    1,     1,  1)
+MUX_CFG("U18_1610_SPIF_DIN",    8,    0,    6,   1,  18,   1,    1,     0,  1)
+MUX_CFG("P20_1610_SPIF_DIN",    6,    27,   4,   1,   7,   1,    1,     0,  1)
+MUX_CFG("W21_1610_SPIF_DOUT",   8,    3,    6,   1,  19,   0,    1,     0,  1)
+MUX_CFG("R18_1610_SPIF_DOUT",   7,    9,    3,   1,  11,   0,    1,     0,  1)
+MUX_CFG("N14_1610_SPIF_CS0",    8,    9,    6,   1,  21,   0,    1,     1,  1)
+MUX_CFG("N15_1610_SPIF_CS1",    7,    18,   6,   1,  14,   0,    1,     1,  1)
+MUX_CFG("T19_1610_SPIF_CS2",    7,    15,   4,   1,  13,   0,    1,     1,  1)
+MUX_CFG("P15_1610_SPIF_CS3",    8,    12,   3,   1,  22,   0,    1,     1,  1)
+
 /* OMAP-1610 Flash */
 MUX_CFG("L3_1610_FLASH_CS2B_OE",10,    6,    1,         NA,   0,   0,   NA,     0,  1)
 MUX_CFG("M8_1610_FLASH_CS2B_WE",10,    3,    1,         NA,   0,   0,   NA,     0,  1)
index 7993b7bae2bdaaae807305b54527bec43a40abae..2db6b732b084837fe29e7f4d5f7213b213c88ee9 100644 (file)
@@ -166,8 +166,8 @@ static struct omap_uart_config apollon_uart_config __initdata = {
 
 static struct omap_mmc_config apollon_mmc_config __initdata = {
        .mmc [0] = {
-               .enabled        = 0,
-               .wire4          = 0,
+               .enabled        = 1,
+               .wire4          = 1,
                .wp_pin         = -1,
                .power_pin      = -1,
                .switch_pin     = -1,
@@ -257,6 +257,9 @@ static void __init omap_apollon_init(void)
        /* REVISIT: where's the correct place */
        omap_cfg_reg(W19_24XX_SYS_NIRQ);
 
+       /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
+       CONTROL_DEVCONF |= (1 << 24);
+
        /*
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on
index 4933fce766c8269569b3e4f8bec8843e5c987916..996aeda1285d058e6abe2b39df36bfb5bbcf75b1 100644 (file)
@@ -245,6 +245,7 @@ static struct omap_kp_platform_data h4_kp_data = {
        .rows           = 6,
        .cols           = 7,
        .keymap         = h4_keymap,
+       .keymapsize     = ARRAY_SIZE(h4_keymap),
        .rep            = 1,
        .row_gpios      = row_gpios,
        .col_gpios      = col_gpios,
index d1b648a4efbfde4ad325e1f136fab6d226fb2789..0de201c3d50b4a09d488109338d90a1df12597a9 100644 (file)
 #include "memory.h"
 #include "clock.h"
 
+#undef DEBUG
+
 //#define DOWN_VARIABLE_DPLL 1                 /* Experimental */
 
 static struct prcm_config *curr_prcm_set;
 static u32 curr_perf_level = PRCM_FULL_SPEED;
+static struct clk *vclk;
+static struct clk *sclk;
 
 /*-------------------------------------------------------------------------
  * Omap2 specific clock functions
@@ -79,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk)
        propagate_rate(clk);
 }
 
+static void omap2_set_osc_ck(int enable)
+{
+       if (enable)
+               PRCM_CLKSRC_CTRL &= ~(0x3 << 3);
+       else
+               PRCM_CLKSRC_CTRL |= 0x3 << 3;
+}
+
 /* Enable an APLL if off */
 static void omap2_clk_fixed_enable(struct clk *clk)
 {
@@ -101,12 +113,54 @@ static void omap2_clk_fixed_enable(struct clk *clk)
        else if (clk == &apll54_ck)
                cval = (1 << 6);
 
-       while (!CM_IDLEST_CKGEN & cval) {               /* Wait for lock */
+       while (!(CM_IDLEST_CKGEN & cval)) {             /* Wait for lock */
                ++i;
                udelay(1);
-               if (i == 100000)
+               if (i == 100000) {
+                       printk(KERN_ERR "Clock %s didn't lock\n", clk->name);
+                       break;
+               }
+       }
+}
+
+static void omap2_clk_wait_ready(struct clk *clk)
+{
+       unsigned long reg, other_reg, st_reg;
+       u32 bit;
+       int i;
+
+       reg = (unsigned long) clk->enable_reg;
+       if (reg == (unsigned long) &CM_FCLKEN1_CORE ||
+           reg == (unsigned long) &CM_FCLKEN2_CORE)
+               other_reg = (reg & ~0xf0) | 0x10;
+       else if (reg == (unsigned long) &CM_ICLKEN1_CORE ||
+                reg == (unsigned long) &CM_ICLKEN2_CORE)
+               other_reg = (reg & ~0xf0) | 0x00;
+       else
+               return;
+
+       /* No check for DSS or cam clocks */
+       if ((reg & 0x0f) == 0) {
+               if (clk->enable_bit <= 1 || clk->enable_bit == 31)
+                       return;
+       }
+
+       /* Check if both functional and interface clocks
+        * are running. */
+       bit = 1 << clk->enable_bit;
+       if (!(__raw_readl(other_reg) & bit))
+               return;
+       st_reg = (other_reg & ~0xf0) | 0x20;
+       i = 0;
+       while (!(__raw_readl(st_reg) & bit)) {
+               i++;
+               if (i == 100000) {
+                       printk(KERN_ERR "Timeout enabling clock %s\n", clk->name);
                        break;
+               }
        }
+       if (i)
+               pr_debug("Clock %s stable after %d loops\n", clk->name, i);
 }
 
 /* Enables clock without considering parent dependencies or use count
@@ -119,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk)
        if (clk->flags & ALWAYS_ENABLED)
                return 0;
 
+       if (unlikely(clk == &osc_ck)) {
+               omap2_set_osc_ck(1);
+               return 0;
+       }
+
        if (unlikely(clk->enable_reg == 0)) {
                printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
                       clk->name);
@@ -133,6 +192,9 @@ static int _omap2_clk_enable(struct clk * clk)
        regval32 = __raw_readl(clk->enable_reg);
        regval32 |= (1 << clk->enable_bit);
        __raw_writel(regval32, clk->enable_reg);
+       wmb();
+
+       omap2_clk_wait_ready(clk);
 
        return 0;
 }
@@ -155,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk)
 {
        u32 regval32;
 
+       if (unlikely(clk == &osc_ck)) {
+               omap2_set_osc_ck(0);
+               return;
+       }
+
        if (clk->enable_reg == 0)
                return;
 
@@ -166,6 +233,7 @@ static void _omap2_clk_disable(struct clk *clk)
        regval32 = __raw_readl(clk->enable_reg);
        regval32 &= ~(1 << clk->enable_bit);
        __raw_writel(regval32, clk->enable_reg);
+       wmb();
 }
 
 static int omap2_clk_enable(struct clk *clk)
@@ -695,12 +763,14 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
                reg_val = __raw_readl(reg);
                reg_val &= ~(field_mask << div_off);
                reg_val |= (field_val << div_off);
-
                __raw_writel(reg_val, reg);
+               wmb();
                clk->rate = clk->parent->rate / field_val;
 
-               if (clk->flags & DELAYED_APP)
+               if (clk->flags & DELAYED_APP) {
                        __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
+                       wmb();
+               }
                ret = 0;
        } else if (clk->set_rate != 0)
                ret = clk->set_rate(clk, rate);
@@ -836,10 +906,12 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
                reg_val = __raw_readl(reg) & ~(field_mask << src_off);
                reg_val |= (field_val << src_off);
                __raw_writel(reg_val, reg);
+               wmb();
 
-               if (clk->flags & DELAYED_APP)
+               if (clk->flags & DELAYED_APP) {
                        __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
-
+                       wmb();
+               }
                if (clk->usecount > 0)
                        _omap2_clk_enable(clk);
 
@@ -953,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
  * Omap2 clock reset and init functions
  *-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+static void __init omap2_clk_disable_unused(struct clk *clk)
+{
+       u32 regval32;
+
+       regval32 = __raw_readl(clk->enable_reg);
+       if ((regval32 & (1 << clk->enable_bit)) == 0)
+               return;
+
+       printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
+       _omap2_clk_disable(clk);
+}
+#else
+#define omap2_clk_disable_unused       NULL
+#endif
+
 static struct clk_functions omap2_clk_functions = {
        .clk_enable             = omap2_clk_enable,
        .clk_disable            = omap2_clk_disable,
        .clk_round_rate         = omap2_clk_round_rate,
        .clk_set_rate           = omap2_clk_set_rate,
        .clk_set_parent         = omap2_clk_set_parent,
+       .clk_disable_unused     = omap2_clk_disable_unused,
 };
 
 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
@@ -984,27 +1073,19 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
        sys->rate = sclk;
 }
 
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-static void __init omap2_disable_unused_clocks(void)
+/*
+ * Set clocks for bypass mode for reboot to work.
+ */
+void omap2_clk_prepare_for_reboot(void)
 {
-       struct clk *ck;
-       u32 regval32;
+       u32 rate;
 
-       list_for_each_entry(ck, &clocks, node) {
-               if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
-                       ck->enable_reg == 0)
-                       continue;
-
-               regval32 = __raw_readl(ck->enable_reg);
-               if ((regval32 & (1 << ck->enable_bit)) == 0)
-                       continue;
+       if (vclk == NULL || sclk == NULL)
+               return;
 
-               printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
-               _omap2_clk_disable(ck);
-       }
+       rate = clk_get_rate(sclk);
+       clk_set_rate(vclk, rate);
 }
-late_initcall(omap2_disable_unused_clocks);
-#endif
 
 /*
  * Switch the MPU rate if specified on cmdline.
@@ -1077,8 +1158,27 @@ int __init omap2_clk_init(void)
         */
        clk_enable(&sync_32k_ick);
        clk_enable(&omapctrl_ick);
+
+       /* Force the APLLs active during bootup to avoid disabling and
+        * enabling them unnecessarily. */
+       clk_enable(&apll96_ck);
+       clk_enable(&apll54_ck);
+
        if (cpu_is_omap2430())
                clk_enable(&sdrc_ick);
 
+       /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+       vclk = clk_get(NULL, "virt_prcm_set");
+       sclk = clk_get(NULL, "sys_ck");
+
+       return 0;
+}
+
+static int __init omap2_disable_aplls(void)
+{
+       clk_disable(&apll96_ck);
+       clk_disable(&apll54_ck);
+
        return 0;
 }
+late_initcall(omap2_disable_aplls);
index 2781dfbc51644815f778e84b047fc3d02eac0525..8816f5a33a289b12aa59669d291c1a5d20dc7fde 100644 (file)
@@ -560,7 +560,7 @@ static struct clk osc_ck = {                /* (*12, *13, 19.2, *26, 38.4)MHz */
        .name           = "osc_ck",
        .rate           = 26000000,             /* fixed up in clock init */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-                               RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+                               RATE_FIXED | RATE_PROPAGATES,
 };
 
 /* With out modem likely 12MHz, with modem likely 13MHz */
@@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = {
 };
 
 static struct clk mcspi1_ick = {
-       .name           = "mcspi1_ick",
+       .name           = "mcspi_ick",
+       .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = {
 };
 
 static struct clk mcspi1_fck = {
-       .name           = "mcspi1_fck",
+       .name           = "mcspi_fck",
+       .id             = 1,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = {
 };
 
 static struct clk mcspi2_ick = {
-       .name           = "mcspi2_ick",
+       .name           = "mcspi_ick",
+       .id             = 2,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = {
 };
 
 static struct clk mcspi2_fck = {
-       .name           = "mcspi2_fck",
+       .name           = "mcspi_fck",
+       .id             = 2,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = {
 };
 
 static struct clk mcspi3_ick = {
-       .name           = "mcspi3_ick",
+       .name           = "mcspi_ick",
+       .id             = 3,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_ICLKEN2_CORE,
@@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = {
 };
 
 static struct clk mcspi3_fck = {
-       .name           = "mcspi3_fck",
+       .name           = "mcspi_fck",
+       .id             = 3,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .enable_reg     = (void __iomem *)&CM_FCLKEN2_CORE,
index c7a48f921fef01b58464fbdb85fd760578817ba7..f4f04d87df32902ae37b377af9cbb352d906e021 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
 
 #include <asm/io.h>
 #include <asm/arch/gpmc.h>
 #define GPMC_CS0               0x60
 #define GPMC_CS_SIZE           0x30
 
+#define GPMC_CS_NUM            8
+#define GPMC_MEM_START         0x00000000
+#define GPMC_MEM_END           0x3FFFFFFF
+#define BOOT_ROM_SPACE         0x100000        /* 1MB */
+
+#define GPMC_CHUNK_SHIFT       24              /* 16 MB */
+#define GPMC_SECTION_SHIFT     28              /* 128 MB */
+
+static struct resource gpmc_mem_root;
+static struct resource gpmc_cs_mem[GPMC_CS_NUM];
+static spinlock_t      gpmc_mem_lock = SPIN_LOCK_UNLOCKED;
+static unsigned                gpmc_cs_map;
+
 static void __iomem *gpmc_base =
        (void __iomem *) IO_ADDRESS(GPMC_BASE);
 static void __iomem *gpmc_cs_base =
@@ -187,9 +202,168 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
        return 0;
 }
 
-unsigned long gpmc_cs_get_base_addr(int cs)
+static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+{
+       u32 l;
+       u32 mask;
+
+       mask = (1 << GPMC_SECTION_SHIFT) - size;
+       l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+       l &= ~0x3f;
+       l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
+       l &= ~(0x0f << 8);
+       l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
+       l |= 1 << 6;            /* CSVALID */
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+}
+
+static void gpmc_cs_disable_mem(int cs)
+{
+       u32 l;
+
+       l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+       l &= ~(1 << 6);         /* CSVALID */
+       gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+}
+
+static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
+{
+       u32 l;
+       u32 mask;
+
+       l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+       *base = (l & 0x3f) << GPMC_CHUNK_SHIFT;
+       mask = (l >> 8) & 0x0f;
+       *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT);
+}
+
+static int gpmc_cs_mem_enabled(int cs)
+{
+       u32 l;
+
+       l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+       return l & (1 << 6);
+}
+
+static void gpmc_cs_set_reserved(int cs, int reserved)
 {
-       return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24;
+       gpmc_cs_map &= ~(1 << cs);
+       gpmc_cs_map |= (reserved ? 1 : 0) << cs;
+}
+
+static int gpmc_cs_reserved(int cs)
+{
+       return gpmc_cs_map & (1 << cs);
+}
+
+static unsigned long gpmc_mem_align(unsigned long size)
+{
+       int order;
+
+       size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1);
+       order = GPMC_CHUNK_SHIFT - 1;
+       do {
+               size >>= 1;
+               order++;
+       } while (size);
+       size = 1 << order;
+       return size;
+}
+
+static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
+{
+       struct resource *res = &gpmc_cs_mem[cs];
+       int r;
+
+       size = gpmc_mem_align(size);
+       spin_lock(&gpmc_mem_lock);
+       res->start = base;
+       res->end = base + size - 1;
+       r = request_resource(&gpmc_mem_root, res);
+       spin_unlock(&gpmc_mem_lock);
+
+       return r;
+}
+
+int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+{
+       struct resource *res = &gpmc_cs_mem[cs];
+       int r = -1;
+
+       if (cs > GPMC_CS_NUM)
+               return -ENODEV;
+
+       size = gpmc_mem_align(size);
+       if (size > (1 << GPMC_SECTION_SHIFT))
+               return -ENOMEM;
+
+       spin_lock(&gpmc_mem_lock);
+       if (gpmc_cs_reserved(cs)) {
+               r = -EBUSY;
+               goto out;
+       }
+       if (gpmc_cs_mem_enabled(cs))
+               r = adjust_resource(res, res->start & ~(size - 1), size);
+       if (r < 0)
+               r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
+                                     size, NULL, NULL);
+       if (r < 0)
+               goto out;
+
+       gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1);
+       *base = res->start;
+       gpmc_cs_set_reserved(cs, 1);
+out:
+       spin_unlock(&gpmc_mem_lock);
+       return r;
+}
+
+void gpmc_cs_free(int cs)
+{
+       spin_lock(&gpmc_mem_lock);
+       if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) {
+               printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
+               BUG();
+               spin_unlock(&gpmc_mem_lock);
+               return;
+       }
+       gpmc_cs_disable_mem(cs);
+       release_resource(&gpmc_cs_mem[cs]);
+       gpmc_cs_set_reserved(cs, 0);
+       spin_unlock(&gpmc_mem_lock);
+}
+
+void __init gpmc_mem_init(void)
+{
+       int cs;
+       unsigned long boot_rom_space = 0;
+
+       if (cpu_is_omap242x()) {
+               u32 l;
+               l = omap_readl(OMAP242X_CONTROL_STATUS);
+               /* In case of internal boot the 1st MB is redirected to the
+                * boot ROM memory space.
+                */
+               if (l & (1 << 3))
+                       boot_rom_space = BOOT_ROM_SPACE;
+       } else
+               /* We assume internal boot if the mode can't be
+                * determined.
+                */
+               boot_rom_space = BOOT_ROM_SPACE;
+       gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+       gpmc_mem_root.end = GPMC_MEM_END;
+
+       /* Reserve all regions that has been set up by bootloader */
+       for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+               u32 base, size;
+
+               if (!gpmc_cs_mem_enabled(cs))
+                       continue;
+               gpmc_cs_get_memconf(cs, &base, &size);
+               if (gpmc_cs_insert_mem(cs, base, size) < 0)
+                       BUG();
+       }
 }
 
 void __init gpmc_init(void)
@@ -206,4 +380,6 @@ void __init gpmc_init(void)
        l &= 0x03 << 3;
        l |= (0x02 << 3) | (1 << 0);
        gpmc_write_reg(GPMC_SYSCONFIG, l);
+
+       gpmc_mem_init();
 }
index dfc3b35cc1ffaeb00f57ba31d55ab1f66797e251..1ed2fff4691a348b38faa68e4cff766bf0203e46 100644 (file)
@@ -41,18 +41,6 @@ static struct omap_irq_bank {
                .nr_irqs        = 96,
        }, {
                /* XXX: DSP INTC */
-
-#if 0
-       /*
-        * Commented out for now until we fix the IVA clocking
-        */
-#ifdef CONFIG_ARCH_OMAP2420
-       }, {
-               /* IVA INTC (2420 only) */
-               .base_reg       = OMAP24XX_IVA_INTC_BASE,
-               .nr_irqs        = 16,   /* Actually 32, but only 16 are used */
-#endif
-#endif
        }
 };
 
index 60ef084faffd04e8102ac9c3dbbc94d58b0cef2c..f538d0fdb13c35a47ec2bca1c3996f1b8e44c9c0 100644 (file)
@@ -104,6 +104,20 @@ MUX_CFG_24XX("P20_24XX_TSC_IRQ",   0x108,  0,      0,      0,      1)
 MUX_CFG_24XX("K15_24XX_UART3_TX",      0x118,  0,      0,      0,      1)
 MUX_CFG_24XX("K14_24XX_UART3_RX",      0x119,  0,      0,      0,      1)
 
+/* MMC/SDIO */
+MUX_CFG_24XX("G19_24XX_MMC_CLKO",      0x0f3,  0,      0,      0,      1)
+MUX_CFG_24XX("H18_24XX_MMC_CMD",       0x0f4,  0,      0,      0,      1)
+MUX_CFG_24XX("F20_24XX_MMC_DAT0",      0x0f5,  0,      0,      0,      1)
+MUX_CFG_24XX("H14_24XX_MMC_DAT1",      0x0f6,  0,      0,      0,      1)
+MUX_CFG_24XX("E19_24XX_MMC_DAT2",      0x0f7,  0,      0,      0,      1)
+MUX_CFG_24XX("D19_24XX_MMC_DAT3",      0x0f8,  0,      0,      0,      1)
+MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0",  0x0f9,  0,      0,      0,      1)
+MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1",  0x0fa,  0,      0,      0,      1)
+MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2",  0x0fb,  0,      0,      0,      1)
+MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3",  0x0fc,  0,      0,      0,      1)
+MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR",   0x0fd,  0,      0,      0,      1)
+MUX_CFG_24XX("H15_24XX_MMC_CLKI",      0x0fe,  0,      0,      0,      1)
+
 /* Keypad GPIO*/
 MUX_CFG_24XX("T19_24XX_KBR0",          0x106,  3,      1,      1,      1)
 MUX_CFG_24XX("R19_24XX_KBR1",          0x107,  3,      1,      1,      1)
index c2bf57ef68255309ab46096f6de08202af433a1b..90f530540c6529138c6a9e6a77d4ec21c7095d72 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "prcm-regs.h"
 
+extern void omap2_clk_prepare_for_reboot(void);
+
 u32 omap_prcm_get_reset_sources(void)
 {
        return RM_RSTST_WKUP & 0x7f;
@@ -28,12 +30,6 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources);
 /* Resets clock rates and reboots the system. Only called from system.h */
 void omap_prcm_arch_reset(char mode)
 {
-       u32 rate;
-       struct clk *vclk, *sclk;
-
-       vclk = clk_get(NULL, "virt_prcm_set");
-       sclk = clk_get(NULL, "sys_ck");
-       rate = clk_get_rate(sclk);
-       clk_set_rate(vclk, rate);       /* go to bypass for OMAP limitation */
+       omap2_clk_prepare_for_reboot();
        RM_RSTCTRL_WKUP |= 2;
 }
index bbd138be6a70779663bd4aa1798f629e4b81e007..df37594c30f83baef8a80d54b218ed56c83e4929 100644 (file)
@@ -2,6 +2,13 @@ if ARCH_S3C2410
 
 menu "S3C24XX Implementations"
 
+config MACH_AML_M5900
+       bool "AML M5900 Series"
+       select CPU_S3C2410
+       help
+          Say Y here if you are using the American Microsystems M5900 Series
+           <http://www.amltd.com>
+
 config MACH_ANUBIS
        bool "Simtec Electronics ANUBIS"
        select CPU_S3C2440
@@ -126,6 +133,12 @@ config MACH_NEXCODER_2440
        help
          Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
 
+config MACH_VSTMS
+       bool "VMSTMS"
+       select CPU_S3C2412
+       help
+         Say Y here if you are using an VSTMS board
+
 endmenu
 
 config S3C2410_CLOCK
@@ -133,10 +146,24 @@ config S3C2410_CLOCK
        help
          Clock code for the S3C2410, and similar processors
 
+config S3C2410_PM
+       bool
+       depends on CONFIG_PM
+       help
+         Power Management code common to S3C2410 and better
+
+config CPU_S3C2410_DMA
+       bool
+       depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
+       default y if CPU_S3C2410 || CPU_S3C2442
+       help
+         DMA device selection for S3C2410 and compatible CPUs
+
 config CPU_S3C2410
        bool
        depends on ARCH_S3C2410
        select S3C2410_CLOCK
+       select S3C2410_PM
        help
          Support for S3C2410 and S3C2410A family from the S3C24XX line
          of Samsung Mobile CPUs.
@@ -149,6 +176,13 @@ config CPU_S3C2412_ONLY
                   !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
        default y if CPU_S3C2412
 
+config S3C2412_PM
+       bool
+       default y if PM
+       depends on CPU_S3C2412
+       help
+         Internal config node to apply S3C2412 power management
+
 config CPU_S3C2412
        bool
        depends on ARCH_S3C2410
@@ -165,6 +199,7 @@ config CPU_S3C2440
        bool
        depends on ARCH_S3C2410
        select S3C2410_CLOCK
+       select S3C2410_PM
        select CPU_S3C244X
        help
          Support for S3C2440 Samsung Mobile CPU based systems.
@@ -173,6 +208,7 @@ config CPU_S3C2442
        bool
        depends on ARCH_S3C2420
        select S3C2410_CLOCK
+       select S3C2410_PM
        select CPU_S3C244X
        help
          Support for S3C2442 Samsung Mobile CPU based systems.
@@ -256,7 +292,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE
 
 config PM_SIMTEC
        bool
-       depends on PM && (ARCH_BAST || MACH_VR1000)
+       depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900)
        default y
 
 config S3C2410_LOWLEVEL_UART_PORT
index 0eadec916214ecde32fa0ed66532d4ee33732276..d66013365b6bc2e7fa9d2888272a5df8520cd17d 100644 (file)
@@ -9,6 +9,8 @@ obj-y                   := cpu.o irq.o time.o gpio.o clock.o devs.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
+obj-dma-y              :=
+obj-dma-n              :=
 
 # DMA
 obj-$(CONFIG_S3C2410_DMA)      += dma.o
@@ -20,6 +22,10 @@ obj-$(CONFIG_CPU_S3C2400)    += s3c2400-gpio.o
 
 obj-$(CONFIG_CPU_S3C2410)      += s3c2410.o
 obj-$(CONFIG_CPU_S3C2410)      += s3c2410-gpio.o
+obj-$(CONFIG_CPU_S3C2410)      += s3c2410-irq.o
+
+obj-$(CONFIG_S3C2410_PM)       += s3c2410-pm.o s3c2410-sleep.o
+obj-$(CONFIG_CPU_S3C2410_DMA)  += s3c2410-dma.o
 
 # Power Management support
 
@@ -30,6 +36,9 @@ obj-$(CONFIG_PM_SIMTEC)               += pm-simtec.o
 obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o
 obj-$(CONFIG_CPU_S3C2412)      += s3c2412-irq.o
 obj-$(CONFIG_CPU_S3C2412)      += s3c2412-clock.o
+obj-dma-$(CONFIG_CPU_S3C2412)  += s3c2412-dma.o
+
+obj-$(CONFIG_S3C2412_PM)       += s3c2412-pm.o
 
 #
 # S3C244X support
@@ -47,6 +56,7 @@ obj-$(CONFIG_CPU_S3C2440)     += s3c2440.o s3c2440-dsc.o
 obj-$(CONFIG_CPU_S3C2440)      += s3c2440-irq.o
 obj-$(CONFIG_CPU_S3C2440)      += s3c2440-clock.o
 obj-$(CONFIG_CPU_S3C2440)      += s3c2410-gpio.o
+obj-dma-$(CONFIG_CPU_S3C2440)  += s3c2440-dma.o
 
 # S3C2442 support
 
@@ -57,8 +67,13 @@ obj-$(CONFIG_CPU_S3C2442)    += s3c2442-clock.o
 
 obj-$(CONFIG_BAST_PC104_IRQ)   += bast-irq.o
 
+# merge in dma objects
+
+obj-y                          += $(obj-dma-y)
+
 # machine specific support
 
+obj-$(CONFIG_MACH_AML_M5900)   += mach-amlm5900.o
 obj-$(CONFIG_MACH_ANUBIS)      += mach-anubis.o
 obj-$(CONFIG_MACH_OSIRIS)      += mach-osiris.o
 obj-$(CONFIG_ARCH_BAST)                += mach-bast.o usb-simtec.o
@@ -71,5 +86,6 @@ obj-$(CONFIG_MACH_VR1000)     += mach-vr1000.o usb-simtec.o
 obj-$(CONFIG_MACH_RX3715)      += mach-rx3715.o
 obj-$(CONFIG_MACH_OTOM)                += mach-otom.o
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+obj-$(CONFIG_MACH_VSTMS)       += mach-vstms.o
 
 obj-$(CONFIG_MACH_SMDK)                += common-smdk.o
\ No newline at end of file
index def4441d24420e260278672a6fac06160ec46c53..440e9aa0211abafad0585c93cc26e86463d72210 100644 (file)
  * 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
- *
- * Modifications:
- *     08-Jan-2003 BJD  Moved from central IRQ code
- *     21-Aug-2005 BJD  Fixed missing code and compile errors
 */
 
 
index 1c3c6adae6c4c11b69339eebc46650c58f57ccce..9d4899eddf1f26ccccc8906504c25578c11a4378 100644 (file)
@@ -124,6 +124,15 @@ static struct cpu_table cpu_ids[] __initdata = {
                .init           = s3c2412_init,
                .name           = name_s3c2412,
        },
+       {                       /* a newer version of the s3c2412 */
+               .idcode         = 0x32412003,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2412_map_io,
+               .init_clocks    = s3c2412_init_clocks,
+               .init_uarts     = s3c2412_init_uarts,
+               .init           = s3c2412_init,
+               .name           = name_s3c2412,
+       },
        {
                .idcode         = 0x0,   /* S3C2400 doesn't have an idcode */
                .idmask         = 0xffffffff,
index 726e2eaf8797c58cd4c6016c34f2ba84d316256e..14fb0bade7165c68057eeb1cda6b03a353d2a176 100644 (file)
@@ -8,11 +8,6 @@
  * 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.
- *
- * Modifications:
- *      18-Aug-2004 BJD  Created initial version
- *     27-Aug-2004 BJD  Added timers 0 through 3
- *     10-Feb-2005 BJD  Added camera from guillaume.gourat@nexvision.tv
 */
 #include <linux/platform_device.h>
 
index cc92a7b2db889e7cbc5ec151e61a888718325046..d264bbbd8bef893fa660255fafbb88876f290b52 100644 (file)
@@ -1,35 +1,16 @@
-/* linux/arch/arm/mach-bast/dma.c
+/* linux/arch/arm/mach-s3c2410/dma.c
  *
- * (c) 2003-2005 Simtec Electronics
+ * (c) 2003-2005,2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 DMA core
  *
- * http://www.simtec.co.uk/products/EB2410ITX/
+ * http://armlinux.simtec.co.uk/
  *
  * 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.
- *
- * Changelog:
- *  27-Feb-2005 BJD  Added kmem cache for dma descriptors
- *  18-Nov-2004 BJD  Removed error for loading onto stopped channel
- *  10-Nov-2004 BJD  Ensure all external symbols exported for modules
- *  10-Nov-2004 BJD  Use sys_device and sysdev_class for power management
- *  08-Aug-2004 BJD  Apply rmk's suggestions
- *  21-Jul-2004 BJD  Ported to linux 2.6
- *  12-Jul-2004 BJD  Finished re-write and change of API
- *  06-Jul-2004 BJD  Rewrote dma code to try and cope with various problems
- *  23-May-2003 BJD  Created file
- *  19-Aug-2003 BJD  Cleanup, header fix, added URL
- *
- * This file is based on the Sangwook Lee/Samsung patches, re-written due
- * to various ommisions from the code (such as flexible dma configuration)
- * for use with the BAST system board.
- *
- * The re-write is pretty much complete, and should be good enough for any
- * possible DMA function
- */
+*/
 
 
 #ifdef CONFIG_S3C2410_DMA_DEBUG
 #include <asm/mach/dma.h>
 #include <asm/arch/map.h>
 
+#include "dma.h"
+
 /* io map for dma */
 static void __iomem *dma_base;
 static kmem_cache_t *dma_kmem;
 
+struct s3c24xx_dma_selection dma_sel;
+
 /* dma channel state information */
 struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
 
@@ -79,7 +64,6 @@ dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
        pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
        writel(val, dma_regaddr(chan, reg));
 }
-
 #endif
 
 #define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
@@ -151,12 +135,20 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
 #define dbg_showchan(chan) do { } while(0)
 #endif /* CONFIG_S3C2410_DMA_DEBUG */
 
-#define check_channel(chan) \
-  do { if ((chan) >= S3C2410_DMA_CHANNELS) { \
-    printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \
-    return -EINVAL; \
-  } } while(0)
+static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
 
+/* lookup_dma_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
+{
+       if (channel & DMACH_LOW_LEVEL)
+               return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+       else
+               return dma_chan_map[channel];
+}
 
 /* s3c2410_dma_stats_timeout
  *
@@ -321,8 +313,10 @@ static inline void
 s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
                     enum s3c2410_dma_buffresult result)
 {
+#if 0
        pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
                 chan->callback_fn, buf, buf->id, buf->size, result);
+#endif
 
        if (chan->callback_fn != NULL) {
                (chan->callback_fn)(chan, buf->id, buf->size, result);
@@ -439,7 +433,6 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
        return 0;
 }
 
-
 /* s3c2410_dma_enqueue
  *
  * queue an given buffer for dma transfer.
@@ -460,11 +453,12 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
 int s3c2410_dma_enqueue(unsigned int channel, void *id,
                        dma_addr_t data, int size)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
        struct s3c2410_dma_buf *buf;
        unsigned long flags;
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        pr_debug("%s: id=%p, data=%08x, size=%d\n",
                 __FUNCTION__, id, (unsigned int)data, size);
@@ -562,8 +556,10 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
 static inline void
 s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
 {
+#if 0
        pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
                 chan->number, chan->load_state);
+#endif
 
        switch (chan->load_state) {
        case S3C2410_DMALOAD_NONE:
@@ -718,7 +714,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
                if (chan->load_state == S3C2410_DMALOAD_NONE) {
                        pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
                                 chan->number, jiffies);
-                       s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+                       s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+                                        S3C2410_DMAOP_STOP);
                }
        }
 
@@ -726,37 +723,34 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
+
 /* s3c2410_request_dma
  *
  * get control of an dma channel
 */
 
-int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client,
+int s3c2410_dma_request(unsigned int channel,
+                       struct s3c2410_dma_client *client,
                        void *dev)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan;
        unsigned long flags;
        int err;
 
        pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
                 channel, client->name, dev);
 
-       check_channel(channel);
-
        local_irq_save(flags);
 
-       dbg_showchan(chan);
-
-       if (chan->in_use) {
-               if (client != chan->client) {
-                       printk(KERN_ERR "dma%d: already in use\n", channel);
-                       local_irq_restore(flags);
-                       return -EBUSY;
-               } else {
-                       printk(KERN_ERR "dma%d: client already has channel\n", channel);
-               }
+       chan = s3c2410_dma_map_channel(channel);
+       if (chan == NULL) {
+               local_irq_restore(flags);
+               return -EBUSY;
        }
 
+       dbg_showchan(chan);
+
        chan->client = client;
        chan->in_use = 1;
 
@@ -809,14 +803,14 @@ EXPORT_SYMBOL(s3c2410_dma_request);
 
 int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
        unsigned long flags;
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        local_irq_save(flags);
 
-
        if (chan->client != client) {
                printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
                       channel, chan->client, client);
@@ -837,8 +831,12 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
 
        if (chan->irq_claimed)
                free_irq(chan->irq, (void *)chan);
+
        chan->irq_claimed = 0;
 
+       if (!(channel & DMACH_LOW_LEVEL))
+               dma_chan_map[channel] = NULL;
+
        local_irq_restore(flags);
 
        return 0;
@@ -848,8 +846,8 @@ EXPORT_SYMBOL(s3c2410_dma_free);
 
 static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
 {
-       unsigned long tmp;
        unsigned long flags;
+       unsigned long tmp;
 
        pr_debug("%s:\n", __FUNCTION__);
 
@@ -997,9 +995,10 @@ s3c2410_dma_started(struct s3c2410_dma_chan *chan)
 int
 s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        switch (op) {
        case S3C2410_DMAOP_START:
@@ -1046,12 +1045,19 @@ int s3c2410_dma_config(dmach_t channel,
                       int xferunit,
                       int dcon)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
        pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
                 __FUNCTION__, channel, xferunit, dcon);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
+
+       printk("Initial dcon is %08x\n", dcon);
+
+       dcon |= chan->dcon & dma_sel.dcon_mask;
+
+       printk("New dcon is %08x\n", dcon);
 
        switch (xferunit) {
        case 1:
@@ -1086,9 +1092,10 @@ EXPORT_SYMBOL(s3c2410_dma_config);
 
 int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
 
@@ -1106,9 +1113,10 @@ EXPORT_SYMBOL(s3c2410_dma_setflags);
 
 int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
 
@@ -1121,9 +1129,10 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn);
 
 int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
 
@@ -1153,9 +1162,10 @@ int s3c2410_dma_devconfig(int channel,
                          int hwcfg,
                          unsigned long devaddr)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
                 __FUNCTION__, (int)source, hwcfg, devaddr);
@@ -1200,9 +1210,10 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
 
 int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
 {
-       struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
 
-       check_channel(channel);
+       if (chan == NULL)
+               return -EINVAL;
 
        if (src != NULL)
                *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
@@ -1252,7 +1263,7 @@ static int s3c2410_dma_resume(struct sys_device *dev)
 #define s3c2410_dma_resume  NULL
 #endif /* CONFIG_PM */
 
-static struct sysdev_class dma_sysclass = {
+struct sysdev_class dma_sysclass = {
        set_kset_name("s3c24xx-dma"),
        .suspend        = s3c2410_dma_suspend,
        .resume         = s3c2410_dma_resume,
@@ -1265,7 +1276,6 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
        memset(p, 0, sizeof(struct s3c2410_dma_buf));
 }
 
-
 /* initialisation code */
 
 static int __init s3c2410_init_dma(void)
@@ -1274,7 +1284,7 @@ static int __init s3c2410_init_dma(void)
        int channel;
        int ret;
 
-       printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n");
+       printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
 
        dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
        if (dma_base == NULL) {
@@ -1282,6 +1292,8 @@ static int __init s3c2410_init_dma(void)
                return -ENOMEM;
        }
 
+       printk("Registering sysclass\n");
+
        ret = sysdev_class_register(&dma_sysclass);
        if (ret != 0) {
                printk(KERN_ERR "dma sysclass registration failed\n");
@@ -1335,4 +1347,95 @@ static int __init s3c2410_init_dma(void)
        return ret;
 }
 
-__initcall(s3c2410_init_dma);
+core_initcall(s3c2410_init_dma);
+
+static inline int is_channel_valid(unsigned int channel)
+{
+       return (channel & DMA_CH_VALID);
+}
+
+/* s3c2410_dma_map_channel()
+ *
+ * turn the virtual channel number into a real, and un-used hardware
+ * channel.
+ *
+ * currently this code uses first-free channel from the specified harware
+ * map, not taking into account anything that the board setup code may
+ * have to say about the likely peripheral set to be in use.
+*/
+
+struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+{
+       struct s3c24xx_dma_map *ch_map;
+       struct s3c2410_dma_chan *dmach;
+       int ch;
+
+       if (dma_sel.map == NULL || channel > dma_sel.map_size)
+               return NULL;
+
+       ch_map = dma_sel.map + channel;
+
+       for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
+               if (!is_channel_valid(ch_map->channels[ch]))
+                       continue;
+
+               if (s3c2410_chans[ch].in_use == 0) {
+                       printk("mapped channel %d to %d\n", channel, ch);
+                       break;
+               }
+       }
+
+       if (ch >= S3C2410_DMA_CHANNELS)
+               return NULL;
+
+       /* update our channel mapping */
+
+       dmach = &s3c2410_chans[ch];
+       dma_chan_map[channel] = dmach;
+
+       /* select the channel */
+
+       (dma_sel.select)(dmach, ch_map);
+
+       return dmach;
+}
+
+static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
+{
+       /* show the channel configuration */
+
+       printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
+              (is_channel_valid(map->channels[0]) ? '0' : '-'),
+              (is_channel_valid(map->channels[1]) ? '1' : '-'),
+              (is_channel_valid(map->channels[2]) ? '2' : '-'),
+              (is_channel_valid(map->channels[3]) ? '3' : '-'));
+}
+
+static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
+{
+       if (1)
+               s3c24xx_dma_show_ch(map, ch);
+
+       return 0;
+}
+
+int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
+{
+       struct s3c24xx_dma_map *nmap;
+       size_t map_sz = sizeof(*nmap) * sel->map_size;
+       int ptr;
+
+       nmap = kmalloc(map_sz, GFP_KERNEL);
+       if (nmap == NULL)
+               return -ENOMEM;
+
+       memcpy(nmap, sel->map, map_sz);
+       memcpy(&dma_sel, sel, sizeof(*sel));
+
+       dma_sel.map = nmap;
+
+       for (ptr = 0; ptr < sel->map_size; ptr++)
+               s3c24xx_dma_check_entry(nmap+ptr, ptr);
+
+       return 0;
+}
diff --git a/arch/arm/mach-s3c2410/dma.h b/arch/arm/mach-s3c2410/dma.h
new file mode 100644 (file)
index 0000000..0ebfe0a
--- /dev/null
@@ -0,0 +1,45 @@
+/* arch/arm/mach-s3c2410/dma.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ *
+ * 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.
+*/
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+#define DMA_CH_VALID           (1<<31)
+
+struct s3c24xx_dma_addr {
+       unsigned long           from;
+       unsigned long           to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+       const char              *name;
+       struct s3c24xx_dma_addr  hw_addr;
+
+       unsigned long            channels[S3C2410_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+       struct s3c24xx_dma_map  *map;
+       unsigned long            map_size;
+       unsigned long            dcon_mask;
+
+       void    (*select)(struct s3c2410_dma_chan *chan,
+                         struct s3c24xx_dma_map *map);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
index cd39e86845848ec6a515383fef3c6d4bda3ac114..db6393c9986091328cd1f31b00beeb1219d42315 100644 (file)
  * 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
- *
- * Changelog
- *     13-Sep-2004  BJD  Implemented change of MISCCR
- *     14-Sep-2004  BJD  Added getpin call
- *     14-Sep-2004  BJD  Fixed bug in setpin() call
- *     30-Sep-2004  BJD  Fixed cfgpin() mask bug
- *     01-Oct-2004  BJD  Added getcfg() to get pin configuration
- *     01-Oct-2004  BJD  Fixed mask bug in pullup() call
- *     01-Oct-2004  BJD  Added getirq() to turn pin into irqno
- *     04-Oct-2004  BJD  Added irq filter controls for GPIO
- *     05-Nov-2004  BJD  EXPORT_SYMBOL() added for all code
- *     13-Mar-2005  BJD  Updates for __iomem
- *     26-Oct-2005  BJD  Added generic configuration types
- *     15-Jan-2006  LCVR Added support for the S3C2400
- */
+*/
 
 
 #include <linux/kernel.h>
index cd6139b359996ed3dd37528201023b7ed65a3157..3e9f3462c61b13f012eb5479228196e1f7405ad3 100644 (file)
@@ -181,17 +181,19 @@ s3c_irq_unmask(unsigned int irqno)
 }
 
 struct irqchip s3c_irq_level_chip = {
-       .ack       = s3c_irq_maskack,
-       .mask      = s3c_irq_mask,
-       .unmask    = s3c_irq_unmask,
-       .set_wake          = s3c_irq_wake
+       .name           = "s3c-level",
+       .ack            = s3c_irq_maskack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake
 };
 
 static struct irqchip s3c_irq_chip = {
-       .ack       = s3c_irq_ack,
-       .mask      = s3c_irq_mask,
-       .unmask    = s3c_irq_unmask,
-       .set_wake  = s3c_irq_wake
+       .name           = "s3c",
+       .ack            = s3c_irq_ack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake
 };
 
 static void
@@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
 }
 
 static struct irqchip s3c_irqext_chip = {
-       .mask       = s3c_irqext_mask,
-       .unmask     = s3c_irqext_unmask,
-       .ack        = s3c_irqext_ack,
-       .set_type    = s3c_irqext_type,
-       .set_wake    = s3c_irqext_wake
+       .name           = "s3c-ext",
+       .mask           = s3c_irqext_mask,
+       .unmask         = s3c_irqext_unmask,
+       .ack            = s3c_irqext_ack,
+       .set_type       = s3c_irqext_type,
+       .set_wake       = s3c_irqext_wake
 };
 
 static struct irqchip s3c_irq_eint0t4 = {
-       .ack       = s3c_irq_ack,
-       .mask      = s3c_irq_mask,
-       .unmask    = s3c_irq_unmask,
-       .set_wake  = s3c_irq_wake,
-       .set_type  = s3c_irqext_type,
+       .name           = "s3c-ext0",
+       .ack            = s3c_irq_ack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake,
+       .set_type       = s3c_irqext_type,
 };
 
 /* mask values for the parent registers for each of the interrupt types */
@@ -387,9 +391,10 @@ s3c_irq_uart0_ack(unsigned int irqno)
 }
 
 static struct irqchip s3c_irq_uart0 = {
-       .mask       = s3c_irq_uart0_mask,
-       .unmask     = s3c_irq_uart0_unmask,
-       .ack        = s3c_irq_uart0_ack,
+       .name           = "s3c-uart0",
+       .mask           = s3c_irq_uart0_mask,
+       .unmask         = s3c_irq_uart0_unmask,
+       .ack            = s3c_irq_uart0_ack,
 };
 
 /* UART1 */
@@ -413,9 +418,10 @@ s3c_irq_uart1_ack(unsigned int irqno)
 }
 
 static struct irqchip s3c_irq_uart1 = {
-       .mask       = s3c_irq_uart1_mask,
-       .unmask     = s3c_irq_uart1_unmask,
-       .ack        = s3c_irq_uart1_ack,
+       .name           = "s3c-uart1",
+       .mask           = s3c_irq_uart1_mask,
+       .unmask         = s3c_irq_uart1_unmask,
+       .ack            = s3c_irq_uart1_ack,
 };
 
 /* UART2 */
@@ -439,9 +445,10 @@ s3c_irq_uart2_ack(unsigned int irqno)
 }
 
 static struct irqchip s3c_irq_uart2 = {
-       .mask       = s3c_irq_uart2_mask,
-       .unmask     = s3c_irq_uart2_unmask,
-       .ack        = s3c_irq_uart2_ack,
+       .name           = "s3c-uart2",
+       .mask           = s3c_irq_uart2_mask,
+       .unmask         = s3c_irq_uart2_unmask,
+       .ack            = s3c_irq_uart2_ack,
 };
 
 /* ADC and Touchscreen */
@@ -465,9 +472,10 @@ s3c_irq_adc_ack(unsigned int irqno)
 }
 
 static struct irqchip s3c_irq_adc = {
-       .mask       = s3c_irq_adc_mask,
-       .unmask     = s3c_irq_adc_unmask,
-       .ack        = s3c_irq_adc_ack,
+       .name           = "s3c-adc",
+       .mask           = s3c_irq_adc_mask,
+       .unmask         = s3c_irq_adc_unmask,
+       .ack            = s3c_irq_adc_ack,
 };
 
 /* irq demux for adc */
@@ -569,23 +577,104 @@ s3c_irq_demux_uart2(unsigned int irq,
 }
 
 static void
-s3c_irq_demux_extint(unsigned int irq,
-                    struct irqdesc *desc,
-                    struct pt_regs *regs)
+s3c_irq_demux_extint8(unsigned int irq,
+                     struct irqdesc *desc,
+                     struct pt_regs *regs)
 {
        unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
        unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
 
        eintpnd &= ~eintmsk;
+       eintpnd &= ~0xff;       /* ignore lower irqs */
 
-       if (eintpnd) {
-               irq = fls(eintpnd);
-               irq += (IRQ_EINT4 - (4 + 1));
+       /* we may as well handle all the pending IRQs here */
 
+       while (eintpnd) {
+               irq = __ffs(eintpnd);
+               eintpnd &= ~(1<<irq);
+
+               irq += (IRQ_EINT4 - 4);
                desc_handle_irq(irq, irq_desc + irq, regs);
        }
+
+}
+
+static void
+s3c_irq_demux_extint4t7(unsigned int irq,
+                       struct irqdesc *desc,
+                       struct pt_regs *regs)
+{
+       unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+       unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+       eintpnd &= ~eintmsk;
+       eintpnd &= 0xff;        /* only lower irqs */
+
+       /* we may as well handle all the pending IRQs here */
+
+       while (eintpnd) {
+               irq = __ffs(eintpnd);
+               eintpnd &= ~(1<<irq);
+
+               irq += (IRQ_EINT4 - 4);
+
+               desc_handle_irq(irq, irq_desc + irq, regs);
+       }
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save irq_save[] = {
+       SAVE_ITEM(S3C2410_INTMSK),
+       SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+               save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+               save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+       s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+       save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+       return 0;
 }
 
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+               __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+               __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+       s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+       __raw_writel(save_eintmask, S3C24XX_EINTMASK);
+
+       return 0;
+}
+
+#else
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
+
 /* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
@@ -674,8 +763,8 @@ void __init s3c24xx_init_irq(void)
 
        /* setup the cascade irq handlers */
 
-       set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint);
-       set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint);
+       set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+       set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
 
        set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
        set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
new file mode 100644 (file)
index 0000000..ba5109a
--- /dev/null
@@ -0,0 +1,266 @@
+/***********************************************************************
+ *
+ * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+ *
+ * Copyright (c) 2006 American Microsystems Limited
+ *     David Anders <danders@amltd.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
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/arch/fb.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "devs.h"
+#include "cpu.h"
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+static struct resource amlm5900_nor_resource = {
+               .start = 0x00000000,
+               .end   = 0x01000000 - 1,
+               .flags = IORESOURCE_MEM,
+};
+
+
+
+static struct mtd_partition amlm5900_mtd_partitions[] = {
+       {
+               .name           = "System",
+               .size           = 0x240000,
+               .offset         = 0,
+               .mask_flags     = MTD_WRITEABLE,  /* force read-only */
+       }, {
+               .name           = "Kernel",
+               .size           = 0x100000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "Ramdisk",
+               .size           = 0x300000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "JFFS2",
+               .size           = 0x9A0000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "Settings",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data amlm5900_flash_data = {
+       .width          = 2,
+       .parts          = amlm5900_mtd_partitions,
+       .nr_parts       = ARRAY_SIZE(amlm5900_mtd_partitions),
+};
+
+static struct platform_device amlm5900_device_nor = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev = {
+                       .platform_data = &amlm5900_flash_data,
+               },
+       .num_resources  = 1,
+       .resource       = &amlm5900_nor_resource,
+};
+#endif
+
+static struct map_desc amlm5900_iodesc[] __initdata = {
+       {
+               .virtual        = (u32)S3C24XX_VA_SPI,
+               .pfn            = __phys_to_pfn(S3C2410_PA_SPI),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE
+       }
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg amlm5900_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+
+static struct platform_device *amlm5900_devices[] __initdata = {
+#ifdef CONFIG_FB_S3C2410
+       &s3c_device_lcd,
+#endif
+       &s3c_device_adc,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_usb,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+        &s3c_device_sdi,
+#ifdef CONFIG_MTD_PARTITIONS
+       &amlm5900_device_nor,
+#endif
+};
+
+static struct s3c24xx_board amlm5900_board __initdata = {
+       .devices       = amlm5900_devices,
+       .devices_count = ARRAY_SIZE(amlm5900_devices)
+};
+
+void __init amlm5900_map_io(void)
+{
+       s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+       s3c24xx_set_board(&amlm5900_board);
+}
+
+#ifdef CONFIG_FB_S3C2410
+static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
+       .width          = 160,
+       .height         = 160,
+
+/* commented out until stn patch is submitted
+*      .type           = S3C2410_LCDCON1_STN4,
+*/
+       .gpccon =       0xaaaaaaaa,
+       .gpccon_mask =  0xffffffff,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+
+       .gpdcon =       0xaaaaaaaa,
+       .gpdcon_mask =  0xffffffff,
+       .gpdup =        0x0000ffff,
+       .gpdup_mask =   0xffffffff,
+
+       .xres           = {
+               .min            = 160,
+               .max            = 160,
+               .defval         = 160,
+       },
+
+       .yres           = {
+               .min            = 160,
+               .max            = 160,
+               .defval         = 160,
+       },
+
+       .bpp            = {
+               .min            = 4,
+               .max            = 4,
+               .defval         = 4,
+       },
+
+       .regs           = {
+               .lcdcon1        = 0x00008225,
+               .lcdcon2        = 0x0027c000,
+               .lcdcon3        = 0x00182708,
+               .lcdcon4        = 0x00000002,
+               .lcdcon5        = 0x00000001,
+       }
+};
+#endif
+
+static irqreturn_t
+amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
+{
+       return IRQ_HANDLED;
+}
+
+static void amlm5900_init_pm(void)
+{
+       int ret = 0;
+
+       ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt,
+                               IRQF_TRIGGER_RISING | IRQF_SHARED,
+                               "amlm5900_wakeup", &amlm5900_wake_interrupt);
+       if (ret != 0) {
+               printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret);
+       } else {
+               enable_irq_wake(IRQ_EINT9);
+               /* configure the suspend/resume status pin */
+               s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP);
+               s3c2410_gpio_pullup(S3C2410_GPF2, 0);
+       }
+}
+static void __init amlm5900_init(void)
+{
+       amlm5900_init_pm();
+#ifdef CONFIG_FB_S3C2410
+       s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
+#endif
+}
+
+MACHINE_START(AML_M5900, "AML_M5900")
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = amlm5900_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = amlm5900_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
index 60641d452db33275c57d4b33adcc1caebf23cad3..e94cdcd965916437970151942ef26c31af8f1c6d 100644 (file)
@@ -4,15 +4,9 @@
  *     http://armlinux.simtec.co.uk/
  *     Ben Dooks <ben@simtec.co.uk>
  *
- *
- *
  * 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.
- *
- * Modifications:
- *     02-May-2005 BJD  Copied from mach-bast.c
- *     20-Sep-2005 BJD  Added static to non-exported items
 */
 
 #include <linux/kernel.h>
index d661c6b7ff5650811efa40a3afc66868aaa7ac21..e2205ff1b0ee97b76d9038815e6b864e77b3d93b 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Modifications:
- *     01-Nov-2004 BJD   Initial version
- *     12-Nov-2004 BJD   Updated for release
- *     04-Jan-2005 BJD   Fixes for pre-release
- *     22-Feb-2005 BJD   Updated for 2.6.11-rc5 relesa
- *     10-Mar-2005 LCVR  Replaced S3C2410_VA by S3C24XX_VA
- *     14-Mar-2005 BJD   void __iomem fixes
- *     20-Sep-2005 BJD   Added static to non-exported items
- *     26-Oct-2005 BJD   Added framebuffer data
 */
 
 #include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2410/mach-vstms.c
new file mode 100644 (file)
index 0000000..ea554e7
--- /dev/null
@@ -0,0 +1,168 @@
+/* linux/arch/arm/mach-s3c2410/mach-vstms.c
+ *
+ * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Derived from mach-smdk2413.c - (C) 2006 Simtec 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include <asm/arch/nand.h>
+
+#include "s3c2410.h"
+#include "s3c2412.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+
+
+static struct map_desc vstms_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       }
+};
+
+static struct mtd_partition vstms_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = 0x7C000,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "UBoot Config",
+               .offset = 0x7C000,
+               .size   = 0x4000,
+       },
+       [2] = {
+               .name   = "Kernel",
+               .offset = 0x80000,
+               .size   = 0x200000,
+       },
+       [3] = {
+               .name   = "RFS",
+               .offset = 0x280000,
+               .size   = 0x3d80000,
+       },
+};
+
+static struct s3c2410_nand_set vstms_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(vstms_nand_part),
+               .partitions     = vstms_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand vstms_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(vstms_nand_sets),
+       .sets           = vstms_nand_sets,
+};
+
+static struct platform_device *vstms_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+};
+
+static struct s3c24xx_board vstms_board __initdata = {
+       .devices       = vstms_devices,
+       .devices_count = ARRAY_SIZE(vstms_devices)
+};
+
+static void __init vstms_fixup(struct machine_desc *desc,
+                                 struct tag *tags, char **cmdline,
+                                 struct meminfo *mi)
+{
+       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+               mi->nr_banks=1;
+               mi->bank[0].start = 0x30000000;
+               mi->bank[0].size = SZ_64M;
+               mi->bank[0].node = 0;
+       }
+}
+
+static void __init vstms_map_io(void)
+{
+       s3c_device_nand.dev.platform_data = &vstms_nand_info;
+
+       s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+       s3c24xx_set_board(&vstms_board);
+}
+
+MACHINE_START(VSTMS, "VSTMS")
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .fixup          = vstms_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = vstms_map_io,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
index 7b244566a436891d6f2b9f32cf848f1f222a0627..42cd05e298f8dc5765e495712558f271ef4aa91d 100644 (file)
@@ -49,7 +49,8 @@ static __init int pm_simtec_init(void)
        /* check which machine we are running on */
 
        if (!machine_is_bast() && !machine_is_vr1000() &&
-           !machine_is_anubis() && !machine_is_osiris())
+           !machine_is_anubis() && !machine_is_osiris() &&
+           !machine_is_aml_m5900())
                return 0;
 
        printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
index a589fe76d9158d1eedac0ff04ae657ed38f22e53..b49a0b3b72b319562dcaf4763627ee52c85ad6de 100644 (file)
@@ -1,9 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/pm.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004,2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 Power Manager (Suspend-To-RAM) support
+ * S3C24XX Power Manager (Suspend-To-RAM) support
  *
  * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
  *
@@ -24,9 +24,6 @@
  * Parts based on arch/arm/mach-pxa/pm.c
  *
  * Thanks to Dimitry Andric for debugging
- *
- * Modifications:
- *     10-Mar-2005 LCVR  Changed S3C2410_VA_UART to S3C24XX_VA_UART
 */
 
 #include <linux/init.h>
@@ -38,6 +35,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 
+#include <asm/cacheflush.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 
 
 unsigned long s3c_pm_flags;
 
-/* cache functions from arch/arm/mm/proc-arm920.S */
-
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
-extern void arm920_flush_kern_cache_all(void);
-#else
-static void arm920_flush_kern_cache_all(void) { }
-#endif
-
 #define PFX "s3c24xx-pm: "
 
 static struct sleep_save core_save[] = {
@@ -92,19 +82,6 @@ static struct sleep_save core_save[] = {
        SAVE_ITEM(S3C2410_REFRESH),
 };
 
-/* this lot should be really saved by the IRQ code */
-static struct sleep_save irq_save[] = {
-       SAVE_ITEM(S3C2410_EXTINT0),
-       SAVE_ITEM(S3C2410_EXTINT1),
-       SAVE_ITEM(S3C2410_EXTINT2),
-       SAVE_ITEM(S3C2410_EINFLT0),
-       SAVE_ITEM(S3C2410_EINFLT1),
-       SAVE_ITEM(S3C2410_EINFLT2),
-       SAVE_ITEM(S3C2410_EINFLT3),
-       SAVE_ITEM(S3C2410_EINTMASK),
-       SAVE_ITEM(S3C2410_INTMSK)
-};
-
 static struct sleep_save gpio_save[] = {
        SAVE_ITEM(S3C2410_GPACON),
        SAVE_ITEM(S3C2410_GPADAT),
@@ -165,7 +142,7 @@ static struct sleep_save uart_save[] = {
 
 extern void printascii(const char *);
 
-static void pm_dbg(const char *fmt, ...)
+void pm_dbg(const char *fmt, ...)
 {
        va_list va;
        char buff[256];
@@ -509,6 +486,9 @@ static void s3c2410_pm_configure_extint(void)
        }
 }
 
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
 #define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
 
 /* s3c2410_pm_enter
@@ -519,7 +499,6 @@ static void s3c2410_pm_configure_extint(void)
 static int s3c2410_pm_enter(suspend_state_t state)
 {
        unsigned long regs_save[16];
-       unsigned long tmp;
 
        /* ensure the debug is initialised (if enabled) */
 
@@ -527,6 +506,11 @@ static int s3c2410_pm_enter(suspend_state_t state)
 
        DBG("s3c2410_pm_enter(%d)\n", state);
 
+       if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+               printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
+               return -EINVAL;
+       }
+
        if (state != PM_SUSPEND_MEM) {
                printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
                return -EINVAL;
@@ -554,17 +538,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
 
        DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
 
-       /* ensure at least GESTATUS3 has the resume address */
-
-       __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
-
-       DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
-       DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
-
        /* save all necessary core registers not covered by the drivers */
 
        s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
-       s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
        s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
        s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
 
@@ -581,10 +557,16 @@ static int s3c2410_pm_enter(suspend_state_t state)
        /* ack any outstanding external interrupts before we go to sleep */
 
        __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+       __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+       __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+       /* call cpu specific preperation */
+
+       pm_cpu_prep();
 
        /* flush cache back to ram */
 
-       arm920_flush_kern_cache_all();
+       flush_cache_all();
 
        s3c2410_pm_check_store();
 
@@ -592,23 +574,23 @@ static int s3c2410_pm_enter(suspend_state_t state)
 
        __raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
 
-       s3c2410_cpu_suspend(regs_save);
+       /* s3c2410_cpu_save will also act as our return point from when
+        * we resume as it saves its own register state, so use the return
+        * code to differentiate return from save and return from sleep */
+
+       if (s3c2410_cpu_save(regs_save) == 0) {
+               flush_cache_all();
+               pm_cpu_sleep();
+       }
 
        /* restore the cpu state */
 
        cpu_init();
 
-       /* unset the return-from-sleep flag, to ensure reset */
-
-       tmp = __raw_readl(S3C2410_GSTATUS2);
-       tmp &= S3C2410_GSTATUS2_OFFRESET;
-       __raw_writel(tmp, S3C2410_GSTATUS2);
-
        /* restore the system state */
 
        s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
        s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
-       s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
        s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
 
        s3c2410_pm_debug_init();
index 7a5e714c73866ca46daa6676cefa85c1cf5f2c85..ffe197a119fb096b2e3c1d9c6788094946011fcc 100644 (file)
@@ -34,13 +34,19 @@ extern unsigned long s3c_irqwake_eintmask;
 extern unsigned long s3c_irqwake_intallow;
 extern unsigned long s3c_irqwake_eintallow;
 
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
 /* Flags for PM Control */
 
 extern unsigned long s3c_pm_flags;
 
 /* from sleep.S */
 
-extern void s3c2410_cpu_suspend(unsigned long *saveblk);
+extern int  s3c2410_cpu_save(unsigned long *saveblk);
+extern void s3c2410_cpu_suspend(void);
 extern void s3c2410_cpu_resume(void);
 
 extern unsigned long s3c2410_sleep_save_phys;
@@ -57,3 +63,11 @@ struct sleep_save {
 
 extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
 extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
new file mode 100644 (file)
index 0000000..51e5098
--- /dev/null
@@ -0,0 +1,158 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
+ *
+ * (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include "dma.h"
+
+#include "cpu.h"
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+};
+
+static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+       .select         = s3c2410_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2410_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
+};
+
+static int s3c2410_dma_add(struct sys_device *sysdev)
+{
+       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
+}
+
+static struct sysdev_driver s3c2410_dma_driver = {
+       .add    = s3c2410_dma_add,
+};
+
+static int __init s3c2410_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
+}
+
+arch_initcall(s3c2410_dma_init);
+
+/* S3C2442 DMA contains the same selection table as the S3C2410 */
+
+static struct sysdev_driver s3c2442_dma_driver = {
+       .add    = s3c2410_dma_add,
+};
+
+static int __init s3c2442_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
+}
+
+arch_initcall(s3c2442_dma_init);
+
+
diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c
new file mode 100644 (file)
index 0000000..c796c9c
--- /dev/null
@@ -0,0 +1,48 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include "cpu.h"
+#include "pm.h"
+
+static int s3c2410_irq_add(struct sys_device *sysdev)
+{
+       return 0;
+}
+
+static struct sysdev_driver s3c2410_irq_driver = {
+       .add            = s3c2410_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
+};
+
+static int s3c2410_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
+}
+
+arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
new file mode 100644 (file)
index 0000000..e51d766
--- /dev/null
@@ -0,0 +1,120 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
+ *
+ * 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/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-gpio.h>
+
+#include "cpu.h"
+#include "pm.h"
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+extern void pm_dbg(const char *fmt, ...);
+#define DBG(fmt...) pm_dbg(fmt)
+#else
+#define DBG(fmt...) printk(KERN_DEBUG fmt)
+#endif
+
+static void s3c2410_pm_prepare(void)
+{
+       /* ensure at least GSTATUS3 has the resume address */
+
+       __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
+
+       DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+       DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF2, 1);
+
+}
+
+int s3c2410_pm_resume(struct sys_device *dev)
+{
+       unsigned long tmp;
+
+       /* unset the return-from-sleep flag, to ensure reset */
+
+       tmp = __raw_readl(S3C2410_GSTATUS2);
+       tmp &= S3C2410_GSTATUS2_OFFRESET;
+       __raw_writel(tmp, S3C2410_GSTATUS2);
+
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+
+       return 0;
+}
+
+static int s3c2410_pm_add(struct sys_device *dev)
+{
+       pm_cpu_prep = s3c2410_pm_prepare;
+       pm_cpu_sleep = s3c2410_cpu_suspend;
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2410_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
+};
+
+/* register ourselves */
+
+static int __init s3c2410_pm_drvinit(void)
+{
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
+}
+
+arch_initcall(s3c2410_pm_drvinit);
+
+static struct sysdev_driver s3c2440_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
+};
+
+static int __init s3c2440_pm_drvinit(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
+}
+
+arch_initcall(s3c2440_pm_drvinit);
+
+static struct sysdev_driver s3c2442_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
+};
+
+static int __init s3c2442_pm_drvinit(void)
+{
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
+}
+
+arch_initcall(s3c2442_pm_drvinit);
diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S
new file mode 100644 (file)
index 0000000..9179a10
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *     Cliff Brake, (c) 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
+ * (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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <asm/arch/map.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-serial.h>
+
+       /* s3c2410_cpu_suspend
+        *
+        * put the cpu into sleep mode
+       */
+
+ENTRY(s3c2410_cpu_suspend)
+       @@ prepare cpu to sleep
+
+       ldr     r4, =S3C2410_REFRESH
+       ldr     r5, =S3C24XX_MISCCR
+       ldr     r6, =S3C2410_CLKCON
+       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
+       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
+       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
+
+       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
+       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
+       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
+
+       teq     pc, #0                  @ first as a trial-run to load cache
+       bl      s3c2410_do_sleep
+       teq     r0, r0                  @ now do it for real
+       b       s3c2410_do_sleep        @
+
+       @@ align next bit of code to cache line
+       .align  8
+s3c2410_do_sleep:
+       streq   r7, [ r4 ]                      @ SDRAM sleep command
+       streq   r8, [ r5 ]                      @ SDRAM power-down config
+       streq   r9, [ r6 ]                      @ CPU sleep
+1:     beq     1b
+       mov     pc, r14
index a110cff9cf6bf06f4546972afe007138d537e21d..183e4033ce617b07b9c5bff936d454e21292b47d 100644 (file)
@@ -8,17 +8,6 @@
  * 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.
- *
- * Modifications:
- *     16-May-2003 BJD  Created initial version
- *     16-Aug-2003 BJD  Fixed header files and copyright, added URL
- *     05-Sep-2003 BJD  Moved to kernel v2.6
- *     18-Jan-2004 BJD  Added serial port configuration
- *     21-Aug-2004 BJD  Added new struct s3c2410_board handler
- *     28-Sep-2004 BJD  Updates for new serial port bits
- *     04-Nov-2004 BJD  Updated UART configuration process
- *     10-Jan-2005 BJD  Removed s3c2410_clock_tick_rate
- *     13-Aug-2005 DA   Removed UART from initial I/O mappings
 */
 
 #include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2410/s3c2412-dma.c
new file mode 100644 (file)
index 0000000..171f370
--- /dev/null
@@ -0,0 +1,160 @@
+/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
+ *
+ * (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include <asm/io.h>
+
+#include "dma.h"
+#include "cpu.h"
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
+
+static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
+       },
+};
+
+static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       writel(chan->regs + S3C2412_DMA_DMAREQSEL,
+              map->channels[0] | S3C2412_DMAREQSEL_HW);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
+       .select         = s3c2412_dma_select,
+       .dcon_mask      = 0,
+       .map            = s3c2412_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
+};
+
+static int s3c2412_dma_add(struct sys_device *sysdev)
+{
+       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
+}
+
+static struct sysdev_driver s3c2412_dma_driver = {
+       .add    = s3c2412_dma_add,
+};
+
+static int __init s3c2412_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
+}
+
+arch_initcall(s3c2412_dma_init);
index c80ec93dfea968104d1c3ce254c8ae589fd09700..7f741547658fbd34173815982ecc92d9411b6b2d 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "cpu.h"
 #include "irq.h"
+#include "pm.h"
 
 /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
  * having them turn up in both the INT* and the EINT* registers. Whilst
@@ -120,6 +121,8 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
 
 static struct sysdev_driver s3c2412_irq_driver = {
        .add            = s3c2412_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
 };
 
 static int s3c2412_irq_init(void)
diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2410/s3c2412-pm.c
new file mode 100644 (file)
index 0000000..19b6332
--- /dev/null
@@ -0,0 +1,128 @@
+/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-power.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-dsc.h>
+
+#include "cpu.h"
+#include "pm.h"
+
+#include "s3c2412.h"
+
+static void s3c2412_cpu_suspend(void)
+{
+       unsigned long tmp;
+
+       /* set our standby method to sleep */
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       /* issue the standby signal into the pm unit. Note, we
+        * issue a write-buffer drain just in case */
+
+       tmp = 0;
+
+       asm("b 1f\n\t"
+           ".align 5\n\t"
+           "1:\n\t"
+           "mcr p15, 0, %0, c7, c10, 4\n\t"
+           "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+       /* we should never get past here */
+
+       panic("sleep resumed to originator?");
+}
+
+static void s3c2412_pm_prepare(void)
+{
+}
+
+static int s3c2412_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = s3c2412_pm_prepare;
+       pm_cpu_sleep = s3c2412_cpu_suspend;
+
+       return 0;
+}
+
+static struct sleep_save s3c2412_sleep[] = {
+       SAVE_ITEM(S3C2412_DSC0),
+       SAVE_ITEM(S3C2412_DSC1),
+       SAVE_ITEM(S3C2413_GPJDAT),
+       SAVE_ITEM(S3C2413_GPJCON),
+       SAVE_ITEM(S3C2413_GPJUP),
+
+       /* save the PWRCFG to get back to original sleep method */
+
+       SAVE_ITEM(S3C2412_PWRCFG),
+
+       /* save the sleep configuration anyway, just in case these
+        * get damaged during wakeup */
+
+       SAVE_ITEM(S3C2412_GPBSLPCON),
+       SAVE_ITEM(S3C2412_GPCSLPCON),
+       SAVE_ITEM(S3C2412_GPDSLPCON),
+       SAVE_ITEM(S3C2412_GPESLPCON),
+       SAVE_ITEM(S3C2412_GPFSLPCON),
+       SAVE_ITEM(S3C2412_GPGSLPCON),
+       SAVE_ITEM(S3C2412_GPHSLPCON),
+       SAVE_ITEM(S3C2413_GPJSLPCON),
+};
+
+static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+       s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+}
+
+static int s3c2412_pm_resume(struct sys_device *dev)
+{
+       unsigned long tmp;
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+}
+
+static struct sysdev_driver s3c2412_pm_driver = {
+       .add            = s3c2412_pm_add,
+       .suspend        = s3c2412_pm_suspend,
+       .resume         = s3c2412_pm_resume,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
+}
+
+arch_initcall(s3c2412_pm_init);
index 2d163f7600be51606c9a1fc7dba7b21e3c87048f..e76431c41461f1f195fd77625da0134f77576155 100644 (file)
@@ -8,17 +8,6 @@
  * 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.
- *
- * Modifications:
- *     16-May-2003 BJD  Created initial version
- *     16-Aug-2003 BJD  Fixed header files and copyright, added URL
- *     05-Sep-2003 BJD  Moved to kernel v2.6
- *     18-Jan-2004 BJD  Added serial port configuration
- *     21-Aug-2004 BJD  Added new struct s3c2410_board handler
- *     28-Sep-2004 BJD  Updates for new serial port bits
- *     04-Nov-2004 BJD  Updated UART configuration process
- *     10-Jan-2005 BJD  Removed s3c2410_clock_tick_rate
- *     13-Aug-2005 DA   Removed UART from initial I/O mappings
 */
 
 #include <linux/kernel.h>
 
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
+
+static inline void s3c2412_init_gpio2(void)
+{
+       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+}
+#else
+#define s3c2412_init_gpio2() do { } while(0)
 #endif
 
 /* Initial IO mappings */
@@ -76,6 +72,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
        /* rename devices that are s3c2412/s3c2413 specific */
        s3c_device_sdi.name  = "s3c2412-sdi";
+       s3c_device_lcd.name  = "s3c2412-lcd";
        s3c_device_nand.name = "s3c2412-nand";
 }
 
@@ -110,7 +107,7 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
 {
        /* move base of IO */
 
-       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+       s3c2412_init_gpio2();
 
        /* set our idle function */
 
@@ -161,48 +158,8 @@ void __init s3c2412_init_clocks(int xtal)
  * as a driver which may support both 2410 and 2440 may try and use it.
 */
 
-#ifdef CONFIG_PM
-static struct sleep_save s3c2412_sleep[] = {
-       SAVE_ITEM(S3C2412_DSC0),
-       SAVE_ITEM(S3C2412_DSC1),
-       SAVE_ITEM(S3C2413_GPJDAT),
-       SAVE_ITEM(S3C2413_GPJCON),
-       SAVE_ITEM(S3C2413_GPJUP),
-
-       /* save the sleep configuration anyway, just in case these
-        * get damaged during wakeup */
-
-       SAVE_ITEM(S3C2412_GPBSLPCON),
-       SAVE_ITEM(S3C2412_GPCSLPCON),
-       SAVE_ITEM(S3C2412_GPDSLPCON),
-       SAVE_ITEM(S3C2412_GPESLPCON),
-       SAVE_ITEM(S3C2412_GPFSLPCON),
-       SAVE_ITEM(S3C2412_GPGSLPCON),
-       SAVE_ITEM(S3C2412_GPHSLPCON),
-       SAVE_ITEM(S3C2413_GPJSLPCON),
-};
-
-static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
-{
-       s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
-}
-
-static int s3c2412_resume(struct sys_device *dev)
-{
-       s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
-}
-
-#else
-#define s3c2412_suspend NULL
-#define s3c2412_resume  NULL
-#endif
-
 struct sysdev_class s3c2412_sysclass = {
        set_kset_name("s3c2412-core"),
-       .suspend        = s3c2412_suspend,
-       .resume         = s3c2412_resume
 };
 
 static int __init s3c2412_core_init(void)
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2410/s3c2440-dma.c
new file mode 100644 (file)
index 0000000..11e109c
--- /dev/null
@@ -0,0 +1,164 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
+ *
+ * (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include "dma.h"
+
+#include "cpu.h"
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
+               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
+               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+};
+
+static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
+       .select         = s3c2440_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2440_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
+};
+
+static int s3c2440_dma_add(struct sys_device *sysdev)
+{
+       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
+}
+
+static struct sysdev_driver s3c2440_dma_driver = {
+       .add    = s3c2440_dma_add,
+};
+
+static int __init s3c2440_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver);
+}
+
+arch_initcall(s3c2440_dma_init);
+
index 16fa2a3b38fa02de47a5d24e96bed959352d9143..c92ea66ba45e5599b99d59efae967268630a5046 100644 (file)
@@ -8,11 +8,6 @@
  * 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.
- *
- * Modifications:
- *     29-Aug-2004 BJD  Start of drive-strength control
- *     09-Nov-2004 BJD  Added symbol export
- *     11-Jan-2005 BJD  Include fix
 */
 
 #include <linux/kernel.h>
index 1667ba1fa43dc9b29d568ca8dd4a8ca86da83b01..fc08febe2e543891cd2b0599a0dcb403e8f32cdf 100644 (file)
@@ -119,7 +119,7 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
 }
 
 static struct sysdev_driver s3c2440_irq_driver = {
-       .add    = s3c2440_irq_add,
+       .add            = s3c2440_irq_add,
 };
 
 static int s3c2440_irq_init(void)
index 44c5affa9b89ac96e1b8729568afacb2daa80a29..0d13546c350005152d330b193fdf135f72605ade 100644 (file)
@@ -120,7 +120,9 @@ static int s3c244x_irq_add(struct sys_device *sysdev)
 }
 
 static struct sysdev_driver s3c2440_irq_driver = {
-       .add    = s3c244x_irq_add,
+       .add            = s3c244x_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
 };
 
 static int s3c2440_irq_init(void)
@@ -131,9 +133,12 @@ static int s3c2440_irq_init(void)
 arch_initcall(s3c2440_irq_init);
 
 static struct sysdev_driver s3c2442_irq_driver = {
-       .add    = s3c244x_irq_add,
+       .add            = s3c244x_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
 };
 
+
 static int s3c2442_irq_init(void)
 {
        return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
index a7561a79fc825dac89b97188554d5ff326411791..2018c2e1dcc5aecc97a9c9ec1825fc3c6b2fc29c 100644 (file)
 
        .text
 
-       /* s3c2410_cpu_suspend
+       /* s3c2410_cpu_save
         *
-        * put the cpu into sleep mode
+        * save enough of the CPU state to allow us to re-start
+        * pm.c code. as we store items like the sp/lr, we will
+        * end up returning from this function when the cpu resumes
+        * so the return value is set to mark this.
+        *
+        * This arangement means we avoid having to flush the cache
+        * from this code.
         *
         * entry:
-        *      r0 = sleep save block
+        *      r0 = pointer to save block
+        *
+        * exit:
+        *      r0 = 0 => we stored everything
+        *           1 => resumed from sleep
        */
 
-ENTRY(s3c2410_cpu_suspend)
+ENTRY(s3c2410_cpu_save)
        stmfd   sp!, { r4 - r12, lr }
 
        @@ store co-processor registers
@@ -62,44 +72,14 @@ ENTRY(s3c2410_cpu_suspend)
 
        stmia   r0, { r4 - r13 }
 
-       @@ flush the caches to ensure everything is back out to
-       @@ SDRAM before the core powers down
-
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
-       bl      arm920_flush_kern_cache_all
-#endif
-
-       @@ prepare cpu to sleep
-
-       ldr     r4, =S3C2410_REFRESH
-       ldr     r5, =S3C24XX_MISCCR
-       ldr     r6, =S3C2410_CLKCON
-       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
-       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
-       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
-
-       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
-       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
-       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
-
-       teq     pc, #0                  @ first as a trial-run to load cache
-       bl      s3c2410_do_sleep
-       teq     r0, r0                  @ now do it for real
-       b       s3c2410_do_sleep        @
-
-       @@ align next bit of code to cache line
-       .align  8
-s3c2410_do_sleep:
-       streq   r7, [ r4 ]                      @ SDRAM sleep command
-       streq   r8, [ r5 ]                      @ SDRAM power-down config
-       streq   r9, [ r6 ]                      @ CPU sleep
-1:     beq     1b
-       mov     pc, r14
+       mov     r0, #0
+       ldmfd   sp, { r4 - r12, pc }
 
        @@ return to the caller, after having the MMU
        @@ turned on, this restores the last bits from the
        @@ stack
 resume_with_mmu:
+       mov     r0, #1
        ldmfd   sp!, { r4 - r12, pc }
 
        .ltorg
index 6b22d8f0a00df5de142bed58ee9adbce2f0a2612..c635efa7cd3189cf97f1ec4550d4b987d6a2b870 100644 (file)
  * 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.
- *
- * Modifications:
- *     14-Sep-2004 BJD  Created
- *     18-Oct-2004 BJD  Cleanups, and added code to report OC cleared
- *     09-Aug-2005 BJD  Renamed s3c2410_report_oc to s3c2410_usb_report_oc
- *     09-Aug-2005 BJD  Ports powered only if both are enabled
 */
 
 #define DEBUG
index a0dfa390e34bd0c686e3fdf05776684cd4ee08f8..6496eb645ceeb9eed2f3a8b85def1fd7400d6e03 100644 (file)
@@ -91,30 +91,29 @@ static struct mcp_plat_data collie_mcp_data = {
 /*
  * low-level UART features.
  */
-static struct locomo_dev *uart_dev = NULL;
+struct platform_device collie_locomo_device;
 
 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-       if (!uart_dev) return;
-
        if (mctrl & TIOCM_RTS)
-               locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0);
+               locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
        else
-               locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1);
+               locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
 
        if (mctrl & TIOCM_DTR)
-               locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0);
+               locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
        else
-               locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1);
+               locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
 }
 
 static u_int collie_uart_get_mctrl(struct uart_port *port)
 {
        int ret = TIOCM_CD;
        unsigned int r;
-       if (!uart_dev) return ret;
 
-       r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
+       r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
+       if (r == -ENODEV)
+               return ret;
        if (r & LOCOMO_GPIO_CTS)
                ret |= TIOCM_CTS;
        if (r & LOCOMO_GPIO_DSR)
@@ -130,13 +129,11 @@ static struct sa1100_port_fns collie_port_fns __initdata = {
 
 static int collie_uart_probe(struct locomo_dev *dev)
 {
-       uart_dev = dev;
        return 0;
 }
 
 static int collie_uart_remove(struct locomo_dev *dev)
 {
-       uart_dev = NULL;
        return 0;
 }
 
@@ -170,7 +167,7 @@ static struct resource locomo_resources[] = {
        },
 };
 
-static struct platform_device locomo_device = {
+struct platform_device collie_locomo_device = {
        .name           = "locomo",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(locomo_resources),
@@ -178,7 +175,7 @@ static struct platform_device locomo_device = {
 };
 
 static struct platform_device *devices[] __initdata = {
-       &locomo_device,
+       &collie_locomo_device,
        &colliescoop_device,
 };
 
index 41b370090b60e2903ea8a3d1919fd19991332197..13bbd08ff841d2c006bd99646488193a7a7c619b 100644 (file)
@@ -117,7 +117,6 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh
        } else {
                switch (size) {
                case 1:
-                       addr &= ~3;
                        v = __raw_readb(addr);
                        break;
 
index b4f220dd5eb8bf60e6290e0419a6447c6827479b..c0bfb8212b7742abda15da17ffd47b09c3fe24e2 100644 (file)
@@ -15,6 +15,7 @@ config CPU_ARM610
        select CPU_32v3
        select CPU_CACHE_V3
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V3 if MMU
        select CPU_TLB_V3 if MMU
        help
@@ -24,6 +25,20 @@ config CPU_ARM610
          Say Y if you want support for the ARM610 processor.
          Otherwise, say N.
 
+# ARM7TDMI
+config CPU_ARM7TDMI
+       bool "Support ARM7TDMI processor"
+       depends on !MMU
+       select CPU_32v4T
+       select CPU_ABRT_LV4T
+       select CPU_CACHE_V4
+       help
+         A 32-bit RISC microprocessor based on the ARM7 processor core
+         which has no memory control unit and cache.
+
+         Say Y if you want support for the ARM7TDMI processor.
+         Otherwise, say N.
+
 # ARM710
 config CPU_ARM710
        bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC
@@ -31,6 +46,7 @@ config CPU_ARM710
        select CPU_32v3
        select CPU_CACHE_V3
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V3 if MMU
        select CPU_TLB_V3 if MMU
        help
@@ -50,6 +66,7 @@ config CPU_ARM720T
        select CPU_ABRT_LV4T
        select CPU_CACHE_V4
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WT if MMU
        select CPU_TLB_V4WT if MMU
        help
@@ -59,6 +76,36 @@ config CPU_ARM720T
          Say Y if you want support for the ARM720T processor.
          Otherwise, say N.
 
+# ARM740T
+config CPU_ARM740T
+       bool "Support ARM740T processor" if ARCH_INTEGRATOR
+       depends on !MMU
+       select CPU_32v4T
+       select CPU_ABRT_LV4T
+       select CPU_CACHE_V3     # although the core is v4t
+       select CPU_CP15_MPU
+       help
+         A 32-bit RISC processor with 8KB cache or 4KB variants,
+         write buffer and MPU(Protection Unit) built around
+         an ARM7TDMI core.
+
+         Say Y if you want support for the ARM740T processor.
+         Otherwise, say N.
+
+# ARM9TDMI
+config CPU_ARM9TDMI
+       bool "Support ARM9TDMI processor"
+       depends on !MMU
+       select CPU_32v4T
+       select CPU_ABRT_NOMMU
+       select CPU_CACHE_V4
+       help
+         A 32-bit RISC microprocessor based on the ARM9 processor core
+         which has no memory control unit and cache.
+
+         Say Y if you want support for the ARM9TDMI processor.
+         Otherwise, say N.
+
 # ARM920T
 config CPU_ARM920T
        bool "Support ARM920T processor"
@@ -68,6 +115,7 @@ config CPU_ARM920T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        help
@@ -89,6 +137,7 @@ config CPU_ARM922T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        help
@@ -108,6 +157,7 @@ config CPU_ARM925T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        help
@@ -126,6 +176,7 @@ config CPU_ARM926T
        select CPU_32v5
        select CPU_ABRT_EV5TJ
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        help
@@ -136,6 +187,39 @@ config CPU_ARM926T
          Say Y if you want support for the ARM926T processor.
          Otherwise, say N.
 
+# ARM940T
+config CPU_ARM940T
+       bool "Support ARM940T processor" if ARCH_INTEGRATOR
+       depends on !MMU
+       select CPU_32v4T
+       select CPU_ABRT_NOMMU
+       select CPU_CACHE_VIVT
+       select CPU_CP15_MPU
+       help
+         ARM940T is a member of the ARM9TDMI family of general-
+         purpose microprocessors with MPU and seperate 4KB
+         instruction and 4KB data cases, each with a 4-word line
+         length.
+
+         Say Y if you want support for the ARM940T processor.
+         Otherwise, say N.
+
+# ARM946E-S
+config CPU_ARM946E
+       bool "Support ARM946E-S processor" if ARCH_INTEGRATOR
+       depends on !MMU
+       select CPU_32v5
+       select CPU_ABRT_NOMMU
+       select CPU_CACHE_VIVT
+       select CPU_CP15_MPU
+       help
+         ARM946E-S is a member of the ARM9E-S family of high-
+         performance, 32-bit system-on-chip processor solutions.
+         The TCM and ARMv5TE 32-bit instruction set is supported.
+
+         Say Y if you want support for the ARM946E-S processor.
+         Otherwise, say N.
+
 # ARM1020 - needs validating
 config CPU_ARM1020
        bool "Support ARM1020T (rev 0) processor"
@@ -144,6 +228,7 @@ config CPU_ARM1020
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        help
@@ -161,6 +246,7 @@ config CPU_ARM1020E
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WBI if MMU
        depends on n
@@ -172,6 +258,7 @@ config CPU_ARM1022
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU # can probably do better
        select CPU_TLB_V4WBI if MMU
        help
@@ -189,6 +276,7 @@ config CPU_ARM1026
        select CPU_32v5
        select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU # can probably do better
        select CPU_TLB_V4WBI if MMU
        help
@@ -207,6 +295,7 @@ config CPU_SA110
        select CPU_ABRT_EV4
        select CPU_CACHE_V4WB
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_COPY_V4WB if MMU
        select CPU_TLB_V4WB if MMU
        help
@@ -227,16 +316,18 @@ config CPU_SA1100
        select CPU_ABRT_EV4
        select CPU_CACHE_V4WB
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_TLB_V4WB if MMU
 
 # XScale
 config CPU_XSCALE
        bool
-       depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000
+       depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000
        default y
        select CPU_32v5
        select CPU_ABRT_EV5T
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_TLB_V4WBI if MMU
 
 # XScale Core Version 3
@@ -247,6 +338,7 @@ config CPU_XSC3
        select CPU_32v5
        select CPU_ABRT_EV5T
        select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
        select CPU_TLB_V4WBI if MMU
        select IO_36
 
@@ -258,6 +350,7 @@ config CPU_V6
        select CPU_ABRT_EV6
        select CPU_CACHE_V6
        select CPU_CACHE_VIPT
+       select CPU_CP15_MMU
        select CPU_COPY_V6 if MMU
        select CPU_TLB_V6 if MMU
 
@@ -299,6 +392,9 @@ config CPU_32v6
        bool
 
 # The abort model
+config CPU_ABRT_NOMMU
+       bool
+
 config CPU_ABRT_EV4
        bool
 
@@ -380,6 +476,23 @@ config CPU_TLB_V6
 
 endif
 
+config CPU_CP15
+       bool
+       help
+         Processor has the CP15 register.
+
+config CPU_CP15_MMU
+       bool
+       select CPU_CP15
+       help
+         Processor has the CP15 register, which has MMU related registers.
+
+config CPU_CP15_MPU
+       bool
+       select CPU_CP15
+       help
+         Processor has the CP15 register, which has MPU related registers.
+
 #
 # CPU supports 36-bit I/O
 #
@@ -390,7 +503,7 @@ comment "Processor Features"
 
 config ARM_THUMB
        bool "Support Thumb user binaries"
-       depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6
+       depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6
        default y
        help
          Say Y if you want to include kernel support for running user space
@@ -411,23 +524,48 @@ config CPU_BIG_ENDIAN
          port must properly enable any big-endian related features
          of your chipset/board/processor.
 
+config CPU_HIGH_VECTOR
+       depends !MMU && CPU_CP15 && !CPU_ARM740T
+       bool "Select the High exception vector"
+       default n
+       help
+         Say Y here to select high exception vector(0xFFFF0000~).
+         The exception vector can be vary depending on the platform
+         design in nommu mode. If your platform needs to select
+         high exception vector, say Y.
+         Otherwise or if you are unsure, say N, and the low exception
+         vector (0x00000000~) will be used.
+
 config CPU_ICACHE_DISABLE
-       bool "Disable I-Cache"
-       depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
+       bool "Disable I-Cache (I-bit)"
+       depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3)
        help
          Say Y here to disable the processor instruction cache. Unless
          you have a reason not to or are unsure, say N.
 
 config CPU_DCACHE_DISABLE
-       bool "Disable D-Cache"
-       depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
+       bool "Disable D-Cache (C-bit)"
+       depends on CPU_CP15
        help
          Say Y here to disable the processor data cache. Unless
          you have a reason not to or are unsure, say N.
 
+config CPU_DCACHE_SIZE
+       hex
+       depends on CPU_ARM740T || CPU_ARM946E
+       default 0x00001000 if CPU_ARM740T
+       default 0x00002000 # default size for ARM946E-S
+       help
+         Some cores are synthesizable to have various sized cache. For
+         ARM946E-S case, it can vary from 0KB to 1MB.
+         To support such cache operations, it is efficient to know the size
+         before compile time.
+         If your SoC is configured to have a different size, define the value
+         here with proper conditions.
+
 config CPU_DCACHE_WRITETHROUGH
        bool "Force write through D-cache"
-       depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
+       depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
        default y if CPU_ARM925T
        help
          Say Y here to use the data cache in writethrough mode. Unless you
@@ -435,7 +573,7 @@ config CPU_DCACHE_WRITETHROUGH
 
 config CPU_CACHE_ROUND_ROBIN
        bool "Round robin I and D cache replacement algorithm"
-       depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+       depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
        help
          Say Y here to use the predictable round-robin cache replacement
          policy.  Unless you specifically require this or are unsure, say N.
index 21a2770226ee418e9756d2a6663a255850352333..d2f5672ecf62e2a06967884f9edf1c7b53975ab6 100644 (file)
@@ -6,7 +6,7 @@ obj-y                           := consistent.o extable.o fault.o init.o \
                                   iomap.o
 
 obj-$(CONFIG_MMU)              += fault-armv.o flush.o ioremap.o mmap.o \
-                                  mm-armv.o
+                                  pgd.o mmu.o
 
 ifneq ($(CONFIG_MMU),y)
 obj-y                          += nommu.o
@@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES)         += proc-syms.o
 obj-$(CONFIG_ALIGNMENT_TRAP)   += alignment.o
 obj-$(CONFIG_DISCONTIGMEM)     += discontig.o
 
+obj-$(CONFIG_CPU_ABRT_NOMMU)   += abort-nommu.o
 obj-$(CONFIG_CPU_ABRT_EV4)     += abort-ev4.o
 obj-$(CONFIG_CPU_ABRT_EV4T)    += abort-ev4t.o
 obj-$(CONFIG_CPU_ABRT_LV4T)    += abort-lv4t.o
@@ -33,7 +34,7 @@ obj-$(CONFIG_CPU_CACHE_V6)    += cache-v6.o
 obj-$(CONFIG_CPU_COPY_V3)      += copypage-v3.o
 obj-$(CONFIG_CPU_COPY_V4WT)    += copypage-v4wt.o
 obj-$(CONFIG_CPU_COPY_V4WB)    += copypage-v4wb.o
-obj-$(CONFIG_CPU_COPY_V6)      += copypage-v6.o mmu.o
+obj-$(CONFIG_CPU_COPY_V6)      += copypage-v6.o context.o
 obj-$(CONFIG_CPU_SA1100)       += copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)       += copypage-xscale.o
 obj-$(CONFIG_CPU_XSC3)         += copypage-xsc3.o
@@ -46,11 +47,16 @@ obj-$(CONFIG_CPU_TLB_V6)    += tlb-v6.o
 
 obj-$(CONFIG_CPU_ARM610)       += proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM710)       += proc-arm6_7.o
+obj-$(CONFIG_CPU_ARM7TDMI)     += proc-arm7tdmi.o
 obj-$(CONFIG_CPU_ARM720T)      += proc-arm720.o
+obj-$(CONFIG_CPU_ARM740T)      += proc-arm740.o
+obj-$(CONFIG_CPU_ARM9TDMI)     += proc-arm9tdmi.o
 obj-$(CONFIG_CPU_ARM920T)      += proc-arm920.o
 obj-$(CONFIG_CPU_ARM922T)      += proc-arm922.o
 obj-$(CONFIG_CPU_ARM925T)      += proc-arm925.o
 obj-$(CONFIG_CPU_ARM926T)      += proc-arm926.o
+obj-$(CONFIG_CPU_ARM940T)      += proc-arm940.o
+obj-$(CONFIG_CPU_ARM946E)      += proc-arm946.o
 obj-$(CONFIG_CPU_ARM1020)      += proc-arm1020.o
 obj-$(CONFIG_CPU_ARM1020E)     += proc-arm1020e.o
 obj-$(CONFIG_CPU_ARM1022)      += proc-arm1022.o
index db743e510214513740a31b28ee1aca1dc1c2bb43..9fb7b0e25ea1094cec42e47b76c69e45ddf13f44 100644 (file)
  */
 ENTRY(v4t_late_abort)
        tst     r3, #PSR_T_BIT                  @ check for thumb mode
+#ifdef CONFIG_CPU_CP15_MMU
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
+       bic     r1, r1, #1 << 11 | 1 << 10      @ clear bits 11 and 10 of FSR
+#else
+       mov     r0, #0                          @ clear r0, r1 (no FSR/FAR)
+       mov     r1, #0
+#endif
        bne     .data_thumb_abort
        ldr     r8, [r2]                        @ read arm instruction
-       bic     r1, r1, #1 << 11 | 1 << 10      @ clear bits 11 and 10 of FSR
        tst     r8, #1 << 20                    @ L = 1 -> write?
        orreq   r1, r1, #1 << 11                @ yes.
        and     r7, r8, #15 << 24
diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S
new file mode 100644 (file)
index 0000000..a7cc7f9
--- /dev/null
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: nommu_early_abort
+ *
+ * Params  : r2 = address of aborted instruction
+ *         : r3 = saved SPSR
+ *
+ * Returns : r0 = 0 (abort address)
+ *        : r1 = 0 (FSR)
+ *
+ * Note: There is no FSR/FAR on !CPU_CP15_MMU cores.
+ *       Just fill zero into the registers.
+ */
+       .align  5
+ENTRY(nommu_early_abort)
+       mov     r0, #0                          @ clear r0, r1 (no FSR/FAR)
+       mov     r1, #0
+       mov     pc, lr
index e0d21bbbe7d788e55854dfd3b2c5eb62cc96050a..aa109f074dd9d84d64e0873133c899ef22ebb449 100644 (file)
@@ -735,7 +735,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        /*
         * We got a fault - fix it up, or die.
         */
-       do_bad_area(current, current->mm, addr, fsr, regs);
+       do_bad_area(addr, fsr, regs);
        return 0;
 
  swp:
index b8ad5d58ebe2ff11f687704c8f31a86d83014dd3..b2908063ed6aa5be10ebdfd7ee00b37ef5e8021f 100644 (file)
@@ -29,9 +29,13 @@ ENTRY(v4_flush_user_cache_all)
  *     Clean and invalidate the entire cache.
  */
 ENTRY(v4_flush_kern_cache_all)
+#ifdef CPU_CP15
        mov     r0, #0
        mcr     p15, 0, r0, c7, c7, 0           @ flush ID cache
        mov     pc, lr
+#else
+       /* FALLTHROUGH */
+#endif
 
 /*
  *     flush_user_cache_range(start, end, flags)
@@ -44,9 +48,13 @@ ENTRY(v4_flush_kern_cache_all)
  *     - flags - vma_area_struct flags describing address space
  */
 ENTRY(v4_flush_user_cache_range)
+#ifdef CPU_CP15
        mov     ip, #0
        mcreq   p15, 0, ip, c7, c7, 0           @ flush ID cache
        mov     pc, lr
+#else
+       /* FALLTHROUGH */
+#endif
 
 /*
  *     coherent_kern_range(start, end)
@@ -108,8 +116,10 @@ ENTRY(v4_dma_inv_range)
  *     - end    - virtual end address
  */
 ENTRY(v4_dma_flush_range)
+#ifdef CPU_CP15
        mov     r0, #0
        mcr     p15, 0, r0, c7, c7, 0           @ flush ID cache
+#endif
        /* FALLTHROUGH */
 
 /*
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
new file mode 100644 (file)
index 0000000..79e8002
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/mm/context.c
+ *
+ *  Copyright (C) 2002-2003 Deep Blue Solutions Ltd, 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.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+
+unsigned int cpu_last_asid = { 1 << ASID_BITS };
+
+/*
+ * We fork()ed a process, and we need a new context for the child
+ * to run in.  We reserve version 0 for initial tasks so we will
+ * always allocate an ASID.
+ */
+void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+       mm->context.id = 0;
+}
+
+void __new_context(struct mm_struct *mm)
+{
+       unsigned int asid;
+
+       asid = ++cpu_last_asid;
+       if (asid == 0)
+               asid = cpu_last_asid = 1 << ASID_BITS;
+
+       /*
+        * If we've used up all our ASIDs, we need
+        * to start a new version and flush the TLB.
+        */
+       if ((asid & ~ASID_MASK) == 0)
+               flush_tlb_all();
+
+       mm->context.id = asid;
+}
index fc69dccdace19cdf7ee6d0f3212318698bc88666..df1645e14b4c11401cc11d454934b8de1b1717ee 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
+#include "mm.h"
+
 /*
  * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
  * specific hacks for copying pages efficiently.
@@ -27,8 +29,6 @@
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
                                  L_PTE_CACHEABLE)
 
-#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
-
 static DEFINE_SPINLOCK(minicache_lock);
 
 /*
index 269ce6913ee95958948b6ce142c8a1773206434f..3d0d3a963d20b6f135bd78c1ad2641aa3d313690 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 
+#include "mm.h"
+
 #if SHMLBA > 16384
 #error FIX ME
 #endif
@@ -24,8 +26,6 @@
 #define from_address   (0xffff8000)
 #define to_address     (0xffffc000)
 
-#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
-
 static DEFINE_SPINLOCK(v6_lock);
 
 /*
index 42a6ee255ce0a29a2ae4a53a13c655d3ac4bb802..84ebe0aa379e3b4ae3f017fd28d75ce8474a2665 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
+#include "mm.h"
+
 /*
  * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
  * specific hacks for copying pages efficiently.
@@ -29,8 +31,6 @@
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
                                  L_PTE_CACHEABLE)
 
-#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
-
 static DEFINE_SPINLOCK(minicache_lock);
 
 /*
index c5e0622c77650480f4dc148254d77f3545606d5d..5e658a8744984688ee171e16b67a44aee65c1331 100644 (file)
@@ -131,10 +131,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
        force_sig_info(sig, &si, tsk);
 }
 
-void
-do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-           unsigned int fsr, struct pt_regs *regs)
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
+       struct task_struct *tsk = current;
+       struct mm_struct *mm = tsk->active_mm;
+
        /*
         * If we are in kernel mode at this point, we
         * have no context to handle this fault with.
@@ -170,7 +171,7 @@ good_area:
        if (fsr & (1 << 11)) /* write? */
                mask = VM_WRITE;
        else
-               mask = VM_READ|VM_EXEC;
+               mask = VM_READ|VM_EXEC|VM_WRITE;
 
        fault = VM_FAULT_BADACCESS;
        if (!(vma->vm_flags & mask))
@@ -197,7 +198,7 @@ survive:
                return fault;
        }
 
-       if (tsk->pid != 1)
+       if (!is_init(tsk))
                goto out;
 
        /*
@@ -319,7 +320,6 @@ static int
 do_translation_fault(unsigned long addr, unsigned int fsr,
                     struct pt_regs *regs)
 {
-       struct task_struct *tsk;
        unsigned int index;
        pgd_t *pgd, *pgd_k;
        pmd_t *pmd, *pmd_k;
@@ -351,9 +351,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
        return 0;
 
 bad_area:
-       tsk = current;
-
-       do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
+       do_bad_area(addr, fsr, regs);
        return 0;
 }
 
@@ -364,8 +362,7 @@ bad_area:
 static int
 do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
-       struct task_struct *tsk = current;
-       do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
+       do_bad_area(addr, fsr, regs);
        return 0;
 }
 
index 73b59e83227f87d4183c5a97db0b9aee41aaaed2..49e9e3804de41ead9959b676a57279cfdd800baf 100644 (file)
@@ -1,6 +1,3 @@
-void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
-                unsigned long addr, unsigned int fsr, struct pt_regs *regs);
-
-void show_pte(struct mm_struct *mm, unsigned long addr);
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 
 unsigned long search_exception_table(unsigned long addr);
index d438ce41cdd5c5ef76d8b1b6d9507a35bbfb6205..454205b789d5a06f52965978a156681cfe34de69 100644 (file)
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 
+#include "mm.h"
+
 #ifdef CONFIG_CPU_CACHE_VIPT
 
 #define ALIAS_FLUSH_START      0xffff4000
 
-#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
-
 static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
 {
        unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
@@ -107,7 +107,7 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
 
        /* VIPT non-aliasing cache */
        if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) &&
-           vma->vm_flags | VM_EXEC) {
+           vma->vm_flags & VM_EXEC) {
                unsigned long addr = (unsigned long)kaddr;
                /* only flushing the kernel mapping on non-aliasing VIPT */
                __cpuc_coherent_kern_range(addr, addr + len);
index fe3f7f6250085c5c279306ba979cde87407d19d8..22217fe2650b61276b82a280ea9eecc18b48b613 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+#include "mm.h"
 
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end;
+extern void _text, _etext, __data_start, _end, __init_begin, __init_end;
 extern unsigned long phys_initrd_start;
 extern unsigned long phys_initrd_size;
 
@@ -38,12 +37,6 @@ extern unsigned long phys_initrd_size;
  */
 static struct meminfo meminfo __initdata = { 0, };
 
-/*
- * empty_zero_page is a special page that is used for
- * zero-initialized data and COW.
- */
-struct page *empty_zero_page;
-
 void show_mem(void)
 {
        int free = 0, total = 0, reserved = 0;
@@ -83,16 +76,6 @@ void show_mem(void)
        printk("%d pages swap cached\n", cached);
 }
 
-static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
-{
-       return pmd_offset(pgd, virt);
-}
-
-static inline pmd_t *pmd_off_k(unsigned long virt)
-{
-       return pmd_off(pgd_offset_k(virt), virt);
-}
-
 #define for_each_nodebank(iter,mi,no)                  \
        for (iter = 0; iter < mi->nr_banks; iter++)     \
                if (mi->bank[iter].node == no)
@@ -176,62 +159,20 @@ static int __init check_initrd(struct meminfo *mi)
        return initrd_node;
 }
 
-/*
- * Reserve the various regions of node 0
- */
-static __init void reserve_node_zero(pg_data_t *pgdat)
+static inline void map_memory_bank(struct membank *bank)
 {
-       unsigned long res_size = 0;
-
-       /*
-        * Register the kernel text and data with bootmem.
-        * Note that this can only be in node 0.
-        */
-#ifdef CONFIG_XIP_KERNEL
-       reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
-#else
-       reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
-#endif
-
-       /*
-        * Reserve the page tables.  These are already in use,
-        * and can only be in node 0.
-        */
-       reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-                            PTRS_PER_PGD * sizeof(pgd_t));
-
-       /*
-        * Hmm... This should go elsewhere, but we really really need to
-        * stop things allocating the low memory; ideally we need a better
-        * implementation of GFP_DMA which does not assume that DMA-able
-        * memory starts at zero.
-        */
-       if (machine_is_integrator() || machine_is_cintegrator())
-               res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+#ifdef CONFIG_MMU
+       struct map_desc map;
 
-       /*
-        * These should likewise go elsewhere.  They pre-reserve the
-        * screen memory region at the start of main system memory.
-        */
-       if (machine_is_edb7211())
-               res_size = 0x00020000;
-       if (machine_is_p720t())
-               res_size = 0x00014000;
+       map.pfn = __phys_to_pfn(bank->start);
+       map.virtual = __phys_to_virt(bank->start);
+       map.length = bank->size;
+       map.type = MT_MEMORY;
 
-#ifdef CONFIG_SA1111
-       /*
-        * Because of the SA1111 DMA bug, we want to preserve our
-        * precious DMA-able memory...
-        */
-       res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+       create_mapping(&map);
 #endif
-       if (res_size)
-               reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
 }
 
-void __init build_mem_type_table(void);
-void __init create_mapping(struct map_desc *md);
-
 static unsigned long __init
 bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
 {
@@ -248,23 +189,18 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
         * Calculate the pfn range, and map the memory banks for this node.
         */
        for_each_nodebank(i, mi, node) {
+               struct membank *bank = &mi->bank[i];
                unsigned long start, end;
-               struct map_desc map;
 
-               start = mi->bank[i].start >> PAGE_SHIFT;
-               end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
+               start = bank->start >> PAGE_SHIFT;
+               end = (bank->start + bank->size) >> PAGE_SHIFT;
 
                if (start_pfn > start)
                        start_pfn = start;
                if (end_pfn < end)
                        end_pfn = end;
 
-               map.pfn = __phys_to_pfn(mi->bank[i].start);
-               map.virtual = __phys_to_virt(mi->bank[i].start);
-               map.length = mi->bank[i].size;
-               map.type = MT_MEMORY;
-
-               create_mapping(&map);
+               map_memory_bank(bank);
        }
 
        /*
@@ -346,9 +282,9 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
        return end_pfn;
 }
 
-static void __init bootmem_init(struct meminfo *mi)
+void __init bootmem_init(struct meminfo *mi)
 {
-       unsigned long addr, memend_pfn = 0;
+       unsigned long memend_pfn = 0;
        int node, initrd_node, i;
 
        /*
@@ -360,26 +296,6 @@ static void __init bootmem_init(struct meminfo *mi)
 
        memcpy(&meminfo, mi, sizeof(meminfo));
 
-       /*
-        * Clear out all the mappings below the kernel image.
-        */
-       for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-#ifdef CONFIG_XIP_KERNEL
-       /* The XIP kernel is mapped in the module area -- skip over it */
-       addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
-#endif
-       for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-
-       /*
-        * Clear out all the kernel space mappings, except for the first
-        * memory bank, up to the end of the vmalloc region.
-        */
-       for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
-            addr < VMALLOC_END; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-
        /*
         * Locate which node contains the ramdisk image, if any.
         */
@@ -413,114 +329,6 @@ static void __init bootmem_init(struct meminfo *mi)
        max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;
 }
 
-/*
- * Set up device the mappings.  Since we clear out the page tables for all
- * mappings above VMALLOC_END, we will remove any debug device mappings.
- * This means you have to be careful how you debug this function, or any
- * called function.  This means you can't use any function or debugging
- * method which may touch any device, otherwise the kernel _will_ crash.
- */
-static void __init devicemaps_init(struct machine_desc *mdesc)
-{
-       struct map_desc map;
-       unsigned long addr;
-       void *vectors;
-
-       /*
-        * Allocate the vector page early.
-        */
-       vectors = alloc_bootmem_low_pages(PAGE_SIZE);
-       BUG_ON(!vectors);
-
-       for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-
-       /*
-        * Map the kernel if it is XIP.
-        * It is always first in the modulearea.
-        */
-#ifdef CONFIG_XIP_KERNEL
-       map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK);
-       map.virtual = MODULE_START;
-       map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK;
-       map.type = MT_ROM;
-       create_mapping(&map);
-#endif
-
-       /*
-        * Map the cache flushing regions.
-        */
-#ifdef FLUSH_BASE
-       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
-       map.virtual = FLUSH_BASE;
-       map.length = SZ_1M;
-       map.type = MT_CACHECLEAN;
-       create_mapping(&map);
-#endif
-#ifdef FLUSH_BASE_MINICACHE
-       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
-       map.virtual = FLUSH_BASE_MINICACHE;
-       map.length = SZ_1M;
-       map.type = MT_MINICLEAN;
-       create_mapping(&map);
-#endif
-
-       /*
-        * Create a mapping for the machine vectors at the high-vectors
-        * location (0xffff0000).  If we aren't using high-vectors, also
-        * create a mapping at the low-vectors virtual address.
-        */
-       map.pfn = __phys_to_pfn(virt_to_phys(vectors));
-       map.virtual = 0xffff0000;
-       map.length = PAGE_SIZE;
-       map.type = MT_HIGH_VECTORS;
-       create_mapping(&map);
-
-       if (!vectors_high()) {
-               map.virtual = 0;
-               map.type = MT_LOW_VECTORS;
-               create_mapping(&map);
-       }
-
-       /*
-        * Ask the machine support to map in the statically mapped devices.
-        */
-       if (mdesc->map_io)
-               mdesc->map_io();
-
-       /*
-        * Finally flush the caches and tlb to ensure that we're in a
-        * consistent state wrt the writebuffer.  This also ensures that
-        * any write-allocated cache lines in the vector page are written
-        * back.  After this point, we can start to touch devices again.
-        */
-       local_flush_tlb_all();
-       flush_cache_all();
-}
-
-/*
- * paging_init() sets up the page tables, initialises the zone memory
- * maps, and sets up the zero page, bad page and bad page tables.
- */
-void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
-{
-       void *zero_page;
-
-       build_mem_type_table();
-       bootmem_init(mi);
-       devicemaps_init(mdesc);
-
-       top_pmd = pmd_off_k(0xffff0000);
-
-       /*
-        * allocate the zero page.  Note that we count on this going ok.
-        */
-       zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
-       memzero(zero_page, PAGE_SIZE);
-       empty_zero_page = virt_to_page(zero_page);
-       flush_dcache_page(empty_zero_page);
-}
-
 static inline void free_area(unsigned long addr, unsigned long end, char *s)
 {
        unsigned int size = (end - addr) >> 10;
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
deleted file mode 100644 (file)
index 38769f5..0000000
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- *  linux/arch/arm/mm/mm-armv.c
- *
- *  Copyright (C) 1998-2005 Russell King
- *
- * 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.
- *
- *  Page table sludge for ARM v3 and v4 processor architectures.
- */
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
-#include <linux/nodemask.h>
-
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/tlbflush.h>
-
-#include <asm/mach/map.h>
-
-#define CPOLICY_UNCACHED       0
-#define CPOLICY_BUFFERED       1
-#define CPOLICY_WRITETHROUGH   2
-#define CPOLICY_WRITEBACK      3
-#define CPOLICY_WRITEALLOC     4
-
-static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
-static unsigned int ecc_mask __initdata = 0;
-pgprot_t pgprot_kernel;
-
-EXPORT_SYMBOL(pgprot_kernel);
-
-pmd_t *top_pmd;
-
-struct cachepolicy {
-       const char      policy[16];
-       unsigned int    cr_mask;
-       unsigned int    pmd;
-       unsigned int    pte;
-};
-
-static struct cachepolicy cache_policies[] __initdata = {
-       {
-               .policy         = "uncached",
-               .cr_mask        = CR_W|CR_C,
-               .pmd            = PMD_SECT_UNCACHED,
-               .pte            = 0,
-       }, {
-               .policy         = "buffered",
-               .cr_mask        = CR_C,
-               .pmd            = PMD_SECT_BUFFERED,
-               .pte            = PTE_BUFFERABLE,
-       }, {
-               .policy         = "writethrough",
-               .cr_mask        = 0,
-               .pmd            = PMD_SECT_WT,
-               .pte            = PTE_CACHEABLE,
-       }, {
-               .policy         = "writeback",
-               .cr_mask        = 0,
-               .pmd            = PMD_SECT_WB,
-               .pte            = PTE_BUFFERABLE|PTE_CACHEABLE,
-       }, {
-               .policy         = "writealloc",
-               .cr_mask        = 0,
-               .pmd            = PMD_SECT_WBWA,
-               .pte            = PTE_BUFFERABLE|PTE_CACHEABLE,
-       }
-};
-
-/*
- * These are useful for identifing cache coherency
- * problems by allowing the cache or the cache and
- * writebuffer to be turned off.  (Note: the write
- * buffer should not be on and the cache off).
- */
-static void __init early_cachepolicy(char **p)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
-               int len = strlen(cache_policies[i].policy);
-
-               if (memcmp(*p, cache_policies[i].policy, len) == 0) {
-                       cachepolicy = i;
-                       cr_alignment &= ~cache_policies[i].cr_mask;
-                       cr_no_alignment &= ~cache_policies[i].cr_mask;
-                       *p += len;
-                       break;
-               }
-       }
-       if (i == ARRAY_SIZE(cache_policies))
-               printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
-       flush_cache_all();
-       set_cr(cr_alignment);
-}
-
-static void __init early_nocache(char **__unused)
-{
-       char *p = "buffered";
-       printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
-       early_cachepolicy(&p);
-}
-
-static void __init early_nowrite(char **__unused)
-{
-       char *p = "uncached";
-       printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
-       early_cachepolicy(&p);
-}
-
-static void __init early_ecc(char **p)
-{
-       if (memcmp(*p, "on", 2) == 0) {
-               ecc_mask = PMD_PROTECTION;
-               *p += 2;
-       } else if (memcmp(*p, "off", 3) == 0) {
-               ecc_mask = 0;
-               *p += 3;
-       }
-}
-
-__early_param("nocache", early_nocache);
-__early_param("nowb", early_nowrite);
-__early_param("cachepolicy=", early_cachepolicy);
-__early_param("ecc=", early_ecc);
-
-static int __init noalign_setup(char *__unused)
-{
-       cr_alignment &= ~CR_A;
-       cr_no_alignment &= ~CR_A;
-       set_cr(cr_alignment);
-       return 1;
-}
-
-__setup("noalign", noalign_setup);
-
-#define FIRST_KERNEL_PGD_NR    (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
-
-static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
-{
-       return pmd_offset(pgd, virt);
-}
-
-static inline pmd_t *pmd_off_k(unsigned long virt)
-{
-       return pmd_off(pgd_offset_k(virt), virt);
-}
-
-/*
- * need to get a 16k page for level 1
- */
-pgd_t *get_pgd_slow(struct mm_struct *mm)
-{
-       pgd_t *new_pgd, *init_pgd;
-       pmd_t *new_pmd, *init_pmd;
-       pte_t *new_pte, *init_pte;
-
-       new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
-       if (!new_pgd)
-               goto no_pgd;
-
-       memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
-
-       /*
-        * Copy over the kernel and IO PGD entries
-        */
-       init_pgd = pgd_offset_k(0);
-       memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
-                      (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
-
-       clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
-
-       if (!vectors_high()) {
-               /*
-                * On ARM, first page must always be allocated since it
-                * contains the machine vectors.
-                */
-               new_pmd = pmd_alloc(mm, new_pgd, 0);
-               if (!new_pmd)
-                       goto no_pmd;
-
-               new_pte = pte_alloc_map(mm, new_pmd, 0);
-               if (!new_pte)
-                       goto no_pte;
-
-               init_pmd = pmd_offset(init_pgd, 0);
-               init_pte = pte_offset_map_nested(init_pmd, 0);
-               set_pte(new_pte, *init_pte);
-               pte_unmap_nested(init_pte);
-               pte_unmap(new_pte);
-       }
-
-       return new_pgd;
-
-no_pte:
-       pmd_free(new_pmd);
-no_pmd:
-       free_pages((unsigned long)new_pgd, 2);
-no_pgd:
-       return NULL;
-}
-
-void free_pgd_slow(pgd_t *pgd)
-{
-       pmd_t *pmd;
-       struct page *pte;
-
-       if (!pgd)
-               return;
-
-       /* pgd is always present and good */
-       pmd = pmd_off(pgd, 0);
-       if (pmd_none(*pmd))
-               goto free;
-       if (pmd_bad(*pmd)) {
-               pmd_ERROR(*pmd);
-               pmd_clear(pmd);
-               goto free;
-       }
-
-       pte = pmd_page(*pmd);
-       pmd_clear(pmd);
-       dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
-       pte_lock_deinit(pte);
-       pte_free(pte);
-       pmd_free(pmd);
-free:
-       free_pages((unsigned long) pgd, 2);
-}
-
-/*
- * Create a SECTION PGD between VIRT and PHYS in domain
- * DOMAIN with protection PROT.  This operates on half-
- * pgdir entry increments.
- */
-static inline void
-alloc_init_section(unsigned long virt, unsigned long phys, int prot)
-{
-       pmd_t *pmdp = pmd_off_k(virt);
-
-       if (virt & (1 << 20))
-               pmdp++;
-
-       *pmdp = __pmd(phys | prot);
-       flush_pmd_entry(pmdp);
-}
-
-/*
- * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT
- */
-static inline void
-alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
-{
-       int i;
-
-       for (i = 0; i < 16; i += 1) {
-               alloc_init_section(virt, phys, prot | PMD_SECT_SUPER);
-
-               virt += (PGDIR_SIZE / 2);
-       }
-}
-
-/*
- * Add a PAGE mapping between VIRT and PHYS in domain
- * DOMAIN with protection PROT.  Note that due to the
- * way we map the PTEs, we must allocate two PTE_SIZE'd
- * blocks - one for the Linux pte table, and one for
- * the hardware pte table.
- */
-static inline void
-alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
-{
-       pmd_t *pmdp = pmd_off_k(virt);
-       pte_t *ptep;
-
-       if (pmd_none(*pmdp)) {
-               ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
-                                              sizeof(pte_t));
-
-               __pmd_populate(pmdp, __pa(ptep) | prot_l1);
-       }
-       ptep = pte_offset_kernel(pmdp, virt);
-
-       set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
-}
-
-struct mem_types {
-       unsigned int    prot_pte;
-       unsigned int    prot_l1;
-       unsigned int    prot_sect;
-       unsigned int    domain;
-};
-
-static struct mem_types mem_types[] __initdata = {
-       [MT_DEVICE] = {
-               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-                               L_PTE_WRITE,
-               .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
-                               PMD_SECT_AP_WRITE,
-               .domain    = DOMAIN_IO,
-       },
-       [MT_CACHECLEAN] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
-               .domain    = DOMAIN_KERNEL,
-       },
-       [MT_MINICLEAN] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
-               .domain    = DOMAIN_KERNEL,
-       },
-       [MT_LOW_VECTORS] = {
-               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-                               L_PTE_EXEC,
-               .prot_l1   = PMD_TYPE_TABLE,
-               .domain    = DOMAIN_USER,
-       },
-       [MT_HIGH_VECTORS] = {
-               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-                               L_PTE_USER | L_PTE_EXEC,
-               .prot_l1   = PMD_TYPE_TABLE,
-               .domain    = DOMAIN_USER,
-       },
-       [MT_MEMORY] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
-               .domain    = DOMAIN_KERNEL,
-       },
-       [MT_ROM] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
-               .domain    = DOMAIN_KERNEL,
-       },
-       [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */
-               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-                               L_PTE_WRITE,
-               .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
-                               PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
-                               PMD_SECT_TEX(1),
-               .domain    = DOMAIN_IO,
-       },
-       [MT_NONSHARED_DEVICE] = {
-               .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV |
-                               PMD_SECT_AP_WRITE,
-               .domain    = DOMAIN_IO,
-       }
-};
-
-/*
- * Adjust the PMD section entries according to the CPU in use.
- */
-void __init build_mem_type_table(void)
-{
-       struct cachepolicy *cp;
-       unsigned int cr = get_cr();
-       unsigned int user_pgprot, kern_pgprot;
-       int cpu_arch = cpu_architecture();
-       int i;
-
-#if defined(CONFIG_CPU_DCACHE_DISABLE)
-       if (cachepolicy > CPOLICY_BUFFERED)
-               cachepolicy = CPOLICY_BUFFERED;
-#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
-       if (cachepolicy > CPOLICY_WRITETHROUGH)
-               cachepolicy = CPOLICY_WRITETHROUGH;
-#endif
-       if (cpu_arch < CPU_ARCH_ARMv5) {
-               if (cachepolicy >= CPOLICY_WRITEALLOC)
-                       cachepolicy = CPOLICY_WRITEBACK;
-               ecc_mask = 0;
-       }
-
-       /*
-        * Xscale must not have PMD bit 4 set for section mappings.
-        */
-       if (cpu_is_xscale())
-               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
-                       mem_types[i].prot_sect &= ~PMD_BIT4;
-
-       /*
-        * ARMv5 and lower, excluding Xscale, bit 4 must be set for
-        * page tables.
-        */
-       if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale())
-               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
-                       if (mem_types[i].prot_l1)
-                               mem_types[i].prot_l1 |= PMD_BIT4;
-
-       cp = &cache_policies[cachepolicy];
-       kern_pgprot = user_pgprot = cp->pte;
-
-       /*
-        * Enable CPU-specific coherency if supported.
-        * (Only available on XSC3 at the moment.)
-        */
-       if (arch_is_coherent()) {
-               if (cpu_is_xsc3()) {
-                       mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-                       mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT;
-               }
-       }
-
-       /*
-        * ARMv6 and above have extended page tables.
-        */
-       if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
-               /*
-                * bit 4 becomes XN which we must clear for the
-                * kernel memory mapping.
-                */
-               mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN;
-               mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN;
-
-               /*
-                * Mark cache clean areas and XIP ROM read only
-                * from SVC mode and no access from userspace.
-                */
-               mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
-               mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
-               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
-
-               /*
-                * Mark the device area as "shared device"
-                */
-               mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
-               mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
-
-               /*
-                * User pages need to be mapped with the ASID
-                * (iow, non-global)
-                */
-               user_pgprot |= L_PTE_ASID;
-
-#ifdef CONFIG_SMP
-               /*
-                * Mark memory with the "shared" attribute for SMP systems
-                */
-               user_pgprot |= L_PTE_SHARED;
-               kern_pgprot |= L_PTE_SHARED;
-               mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-#endif
-       }
-
-       for (i = 0; i < 16; i++) {
-               unsigned long v = pgprot_val(protection_map[i]);
-               v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
-               protection_map[i] = __pgprot(v);
-       }
-
-       mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
-       mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
-
-       if (cpu_arch >= CPU_ARCH_ARMv5) {
-#ifndef CONFIG_SMP
-               /*
-                * Only use write-through for non-SMP systems
-                */
-               mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
-               mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
-#endif
-       } else {
-               mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
-       }
-
-       pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
-                                L_PTE_DIRTY | L_PTE_WRITE |
-                                L_PTE_EXEC | kern_pgprot);
-
-       mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
-       mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
-       mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
-       mem_types[MT_ROM].prot_sect |= cp->pmd;
-
-       switch (cp->pmd) {
-       case PMD_SECT_WT:
-               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
-               break;
-       case PMD_SECT_WB:
-       case PMD_SECT_WBWA:
-               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
-               break;
-       }
-       printk("Memory policy: ECC %sabled, Data cache %s\n",
-               ecc_mask ? "en" : "dis", cp->policy);
-}
-
-#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
-
-/*
- * Create the page directory entries and any necessary
- * page tables for the mapping specified by `md'.  We
- * are able to cope here with varying sizes and address
- * offsets, and we take full advantage of sections and
- * supersections.
- */
-void __init create_mapping(struct map_desc *md)
-{
-       unsigned long virt, length;
-       int prot_sect, prot_l1, domain;
-       pgprot_t prot_pte;
-       unsigned long off = (u32)__pfn_to_phys(md->pfn);
-
-       if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
-               printk(KERN_WARNING "BUG: not creating mapping for "
-                      "0x%08llx at 0x%08lx in user region\n",
-                      __pfn_to_phys((u64)md->pfn), md->virtual);
-               return;
-       }
-
-       if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
-           md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
-               printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
-                      "overlaps vmalloc space\n",
-                      __pfn_to_phys((u64)md->pfn), md->virtual);
-       }
-
-       domain    = mem_types[md->type].domain;
-       prot_pte  = __pgprot(mem_types[md->type].prot_pte);
-       prot_l1   = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
-       prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
-
-       /*
-        * Catch 36-bit addresses
-        */
-       if(md->pfn >= 0x100000) {
-               if(domain) {
-                       printk(KERN_ERR "MM: invalid domain in supersection "
-                               "mapping for 0x%08llx at 0x%08lx\n",
-                               __pfn_to_phys((u64)md->pfn), md->virtual);
-                       return;
-               }
-               if((md->virtual | md->length | __pfn_to_phys(md->pfn))
-                       & ~SUPERSECTION_MASK) {
-                       printk(KERN_ERR "MM: cannot create mapping for "
-                               "0x%08llx at 0x%08lx invalid alignment\n",
-                               __pfn_to_phys((u64)md->pfn), md->virtual);
-                       return;
-               }
-
-               /*
-                * Shift bits [35:32] of address into bits [23:20] of PMD
-                * (See ARMv6 spec).
-                */
-               off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
-       }
-
-       virt   = md->virtual;
-       off   -= virt;
-       length = md->length;
-
-       if (mem_types[md->type].prot_l1 == 0 &&
-           (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
-               printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
-                      "be mapped using pages, ignoring.\n",
-                      __pfn_to_phys(md->pfn), md->virtual);
-               return;
-       }
-
-       while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
-               alloc_init_page(virt, virt + off, prot_l1, prot_pte);
-
-               virt   += PAGE_SIZE;
-               length -= PAGE_SIZE;
-       }
-
-       /* N.B. ARMv6 supersections are only defined to work with domain 0.
-        *      Since domain assignments can in fact be arbitrary, the
-        *      'domain == 0' check below is required to insure that ARMv6
-        *      supersections are only allocated for domain 0 regardless
-        *      of the actual domain assignments in use.
-        */
-       if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())
-               && domain == 0) {
-               /*
-                * Align to supersection boundary if !high pages.
-                * High pages have already been checked for proper
-                * alignment above and they will fail the SUPSERSECTION_MASK
-                * check because of the way the address is encoded into
-                * offset.
-                */
-               if (md->pfn <= 0x100000) {
-                       while ((virt & ~SUPERSECTION_MASK ||
-                               (virt + off) & ~SUPERSECTION_MASK) &&
-                               length >= (PGDIR_SIZE / 2)) {
-                               alloc_init_section(virt, virt + off, prot_sect);
-
-                               virt   += (PGDIR_SIZE / 2);
-                               length -= (PGDIR_SIZE / 2);
-                       }
-               }
-
-               while (length >= SUPERSECTION_SIZE) {
-                       alloc_init_supersection(virt, virt + off, prot_sect);
-
-                       virt   += SUPERSECTION_SIZE;
-                       length -= SUPERSECTION_SIZE;
-               }
-       }
-
-       /*
-        * A section mapping covers half a "pgdir" entry.
-        */
-       while (length >= (PGDIR_SIZE / 2)) {
-               alloc_init_section(virt, virt + off, prot_sect);
-
-               virt   += (PGDIR_SIZE / 2);
-               length -= (PGDIR_SIZE / 2);
-       }
-
-       while (length >= PAGE_SIZE) {
-               alloc_init_page(virt, virt + off, prot_l1, prot_pte);
-
-               virt   += PAGE_SIZE;
-               length -= PAGE_SIZE;
-       }
-}
-
-/*
- * In order to soft-boot, we need to insert a 1:1 mapping in place of
- * the user-mode pages.  This will then ensure that we have predictable
- * results when turning the mmu off
- */
-void setup_mm_for_reboot(char mode)
-{
-       unsigned long base_pmdval;
-       pgd_t *pgd;
-       int i;
-
-       if (current->mm && current->mm->pgd)
-               pgd = current->mm->pgd;
-       else
-               pgd = init_mm.pgd;
-
-       base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
-       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
-               base_pmdval |= PMD_BIT4;
-
-       for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
-               unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
-               pmd_t *pmd;
-
-               pmd = pmd_off(pgd, i << PGDIR_SHIFT);
-               pmd[0] = __pmd(pmdval);
-               pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
-               flush_pmd_entry(pmd);
-       }
-}
-
-/*
- * Create the architecture specific mappings
- */
-void __init iotable_init(struct map_desc *io_desc, int nr)
-{
-       int i;
-
-       for (i = 0; i < nr; i++)
-               create_mapping(io_desc + i);
-}
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
new file mode 100644 (file)
index 0000000..bb2bc9a
--- /dev/null
@@ -0,0 +1,22 @@
+/* the upper-most page table pointer */
+extern pmd_t *top_pmd;
+
+#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
+
+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
+{
+       return pmd_offset(pgd, virt);
+}
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+       return pmd_off(pgd_offset_k(virt), virt);
+}
+
+struct map_desc;
+struct meminfo;
+struct pglist_data;
+
+void __init create_mapping(struct map_desc *md);
+void __init bootmem_init(struct meminfo *mi);
+void reserve_node_zero(struct pglist_data *pgdat);
index 29e54807c5bc6a1a0e010495aad34b9fd60346f2..b0b5f46940705431a468efb6681a7636e40e988e 100644 (file)
@@ -114,3 +114,25 @@ full_search:
        }
 }
 
+
+/*
+ * You really shouldn't be using read() or write() on /dev/mem.  This
+ * might go away in the future.
+ */
+int valid_phys_addr_range(unsigned long addr, size_t size)
+{
+       if (addr + size > __pa(high_memory))
+               return 0;
+
+       return 1;
+}
+
+/*
+ * We don't use supersection mappings for mmap() on /dev/mem, which
+ * means that we can't map the memory area above the 4G barrier into
+ * userspace.
+ */
+int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
+{
+       return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
+}
index 0d90227a0a32e0d7365591d2f402c26ff1de894e..e566cbe4b222cd93186d6d06dd7b279fbbae4563 100644 (file)
 /*
  *  linux/arch/arm/mm/mmu.c
  *
- *  Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
+ *  Copyright (C) 1995-2005 Russell King
  *
  * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/mman.h>
+#include <linux/nodemask.h>
 
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/sizes.h>
+#include <asm/tlb.h>
 
-unsigned int cpu_last_asid = { 1 << ASID_BITS };
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mm.h"
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+extern void _stext, __data_start, _end;
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/*
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
+ */
+struct page *empty_zero_page;
 
 /*
- * We fork()ed a process, and we need a new context for the child
- * to run in.  We reserve version 0 for initial tasks so we will
- * always allocate an ASID.
+ * The pmd table for the upper-most set of pages.
  */
-void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+pmd_t *top_pmd;
+
+#define CPOLICY_UNCACHED       0
+#define CPOLICY_BUFFERED       1
+#define CPOLICY_WRITETHROUGH   2
+#define CPOLICY_WRITEBACK      3
+#define CPOLICY_WRITEALLOC     4
+
+static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
+static unsigned int ecc_mask __initdata = 0;
+pgprot_t pgprot_kernel;
+
+EXPORT_SYMBOL(pgprot_kernel);
+
+struct cachepolicy {
+       const char      policy[16];
+       unsigned int    cr_mask;
+       unsigned int    pmd;
+       unsigned int    pte;
+};
+
+static struct cachepolicy cache_policies[] __initdata = {
+       {
+               .policy         = "uncached",
+               .cr_mask        = CR_W|CR_C,
+               .pmd            = PMD_SECT_UNCACHED,
+               .pte            = 0,
+       }, {
+               .policy         = "buffered",
+               .cr_mask        = CR_C,
+               .pmd            = PMD_SECT_BUFFERED,
+               .pte            = PTE_BUFFERABLE,
+       }, {
+               .policy         = "writethrough",
+               .cr_mask        = 0,
+               .pmd            = PMD_SECT_WT,
+               .pte            = PTE_CACHEABLE,
+       }, {
+               .policy         = "writeback",
+               .cr_mask        = 0,
+               .pmd            = PMD_SECT_WB,
+               .pte            = PTE_BUFFERABLE|PTE_CACHEABLE,
+       }, {
+               .policy         = "writealloc",
+               .cr_mask        = 0,
+               .pmd            = PMD_SECT_WBWA,
+               .pte            = PTE_BUFFERABLE|PTE_CACHEABLE,
+       }
+};
+
+/*
+ * These are useful for identifing cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off.  (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static void __init early_cachepolicy(char **p)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
+               int len = strlen(cache_policies[i].policy);
+
+               if (memcmp(*p, cache_policies[i].policy, len) == 0) {
+                       cachepolicy = i;
+                       cr_alignment &= ~cache_policies[i].cr_mask;
+                       cr_no_alignment &= ~cache_policies[i].cr_mask;
+                       *p += len;
+                       break;
+               }
+       }
+       if (i == ARRAY_SIZE(cache_policies))
+               printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
+       flush_cache_all();
+       set_cr(cr_alignment);
+}
+__early_param("cachepolicy=", early_cachepolicy);
+
+static void __init early_nocache(char **__unused)
+{
+       char *p = "buffered";
+       printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
+       early_cachepolicy(&p);
+}
+__early_param("nocache", early_nocache);
+
+static void __init early_nowrite(char **__unused)
+{
+       char *p = "uncached";
+       printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
+       early_cachepolicy(&p);
+}
+__early_param("nowb", early_nowrite);
+
+static void __init early_ecc(char **p)
+{
+       if (memcmp(*p, "on", 2) == 0) {
+               ecc_mask = PMD_PROTECTION;
+               *p += 2;
+       } else if (memcmp(*p, "off", 3) == 0) {
+               ecc_mask = 0;
+               *p += 3;
+       }
+}
+__early_param("ecc=", early_ecc);
+
+static int __init noalign_setup(char *__unused)
 {
-       mm->context.id = 0;
+       cr_alignment &= ~CR_A;
+       cr_no_alignment &= ~CR_A;
+       set_cr(cr_alignment);
+       return 1;
 }
+__setup("noalign", noalign_setup);
+
+struct mem_types {
+       unsigned int    prot_pte;
+       unsigned int    prot_l1;
+       unsigned int    prot_sect;
+       unsigned int    domain;
+};
 
-void __new_context(struct mm_struct *mm)
+static struct mem_types mem_types[] __initdata = {
+       [MT_DEVICE] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_WRITE,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
+                               PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_IO,
+       },
+       [MT_CACHECLEAN] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
+               .domain    = DOMAIN_KERNEL,
+       },
+       [MT_MINICLEAN] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
+               .domain    = DOMAIN_KERNEL,
+       },
+       [MT_LOW_VECTORS] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_EXEC,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .domain    = DOMAIN_USER,
+       },
+       [MT_HIGH_VECTORS] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_USER | L_PTE_EXEC,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .domain    = DOMAIN_USER,
+       },
+       [MT_MEMORY] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_KERNEL,
+       },
+       [MT_ROM] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
+               .domain    = DOMAIN_KERNEL,
+       },
+       [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_WRITE,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
+                               PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
+                               PMD_SECT_TEX(1),
+               .domain    = DOMAIN_IO,
+       },
+       [MT_NONSHARED_DEVICE] = {
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV |
+                               PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_IO,
+       }
+};
+
+/*
+ * Adjust the PMD section entries according to the CPU in use.
+ */
+static void __init build_mem_type_table(void)
 {
-       unsigned int asid;
+       struct cachepolicy *cp;
+       unsigned int cr = get_cr();
+       unsigned int user_pgprot, kern_pgprot;
+       int cpu_arch = cpu_architecture();
+       int i;
 
-       asid = ++cpu_last_asid;
-       if (asid == 0)
-               asid = cpu_last_asid = 1 << ASID_BITS;
+#if defined(CONFIG_CPU_DCACHE_DISABLE)
+       if (cachepolicy > CPOLICY_BUFFERED)
+               cachepolicy = CPOLICY_BUFFERED;
+#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
+       if (cachepolicy > CPOLICY_WRITETHROUGH)
+               cachepolicy = CPOLICY_WRITETHROUGH;
+#endif
+       if (cpu_arch < CPU_ARCH_ARMv5) {
+               if (cachepolicy >= CPOLICY_WRITEALLOC)
+                       cachepolicy = CPOLICY_WRITEBACK;
+               ecc_mask = 0;
+       }
+
+       /*
+        * Xscale must not have PMD bit 4 set for section mappings.
+        */
+       if (cpu_is_xscale())
+               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+                       mem_types[i].prot_sect &= ~PMD_BIT4;
 
        /*
-        * If we've used up all our ASIDs, we need
-        * to start a new version and flush the TLB.
+        * ARMv5 and lower, excluding Xscale, bit 4 must be set for
+        * page tables.
         */
-       if ((asid & ~ASID_MASK) == 0)
-               flush_tlb_all();
+       if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale())
+               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+                       if (mem_types[i].prot_l1)
+                               mem_types[i].prot_l1 |= PMD_BIT4;
+
+       cp = &cache_policies[cachepolicy];
+       kern_pgprot = user_pgprot = cp->pte;
+
+       /*
+        * Enable CPU-specific coherency if supported.
+        * (Only available on XSC3 at the moment.)
+        */
+       if (arch_is_coherent()) {
+               if (cpu_is_xsc3()) {
+                       mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+                       mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT;
+               }
+       }
+
+       /*
+        * ARMv6 and above have extended page tables.
+        */
+       if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
+               /*
+                * bit 4 becomes XN which we must clear for the
+                * kernel memory mapping.
+                */
+               mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN;
+               mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN;
+
+               /*
+                * Mark cache clean areas and XIP ROM read only
+                * from SVC mode and no access from userspace.
+                */
+               mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+               mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+
+               /*
+                * Mark the device area as "shared device"
+                */
+               mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
+               mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
+
+               /*
+                * User pages need to be mapped with the ASID
+                * (iow, non-global)
+                */
+               user_pgprot |= L_PTE_ASID;
+
+#ifdef CONFIG_SMP
+               /*
+                * Mark memory with the "shared" attribute for SMP systems
+                */
+               user_pgprot |= L_PTE_SHARED;
+               kern_pgprot |= L_PTE_SHARED;
+               mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+#endif
+       }
+
+       for (i = 0; i < 16; i++) {
+               unsigned long v = pgprot_val(protection_map[i]);
+               v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
+               protection_map[i] = __pgprot(v);
+       }
+
+       mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
+       mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
+
+       if (cpu_arch >= CPU_ARCH_ARMv5) {
+#ifndef CONFIG_SMP
+               /*
+                * Only use write-through for non-SMP systems
+                */
+               mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+               mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+#endif
+       } else {
+               mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
+       }
+
+       pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+                                L_PTE_DIRTY | L_PTE_WRITE |
+                                L_PTE_EXEC | kern_pgprot);
+
+       mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
+       mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
+       mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+       mem_types[MT_ROM].prot_sect |= cp->pmd;
+
+       switch (cp->pmd) {
+       case PMD_SECT_WT:
+               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
+               break;
+       case PMD_SECT_WB:
+       case PMD_SECT_WBWA:
+               mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
+               break;
+       }
+       printk("Memory policy: ECC %sabled, Data cache %s\n",
+               ecc_mask ? "en" : "dis", cp->policy);
+}
+
+#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
+
+/*
+ * Create a SECTION PGD between VIRT and PHYS in domain
+ * DOMAIN with protection PROT.  This operates on half-
+ * pgdir entry increments.
+ */
+static inline void
+alloc_init_section(unsigned long virt, unsigned long phys, int prot)
+{
+       pmd_t *pmdp = pmd_off_k(virt);
+
+       if (virt & (1 << 20))
+               pmdp++;
+
+       *pmdp = __pmd(phys | prot);
+       flush_pmd_entry(pmdp);
+}
+
+/*
+ * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT
+ */
+static inline void
+alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
+{
+       int i;
+
+       for (i = 0; i < 16; i += 1) {
+               alloc_init_section(virt, phys, prot | PMD_SECT_SUPER);
+
+               virt += (PGDIR_SIZE / 2);
+       }
+}
+
+/*
+ * Add a PAGE mapping between VIRT and PHYS in domain
+ * DOMAIN with protection PROT.  Note that due to the
+ * way we map the PTEs, we must allocate two PTE_SIZE'd
+ * blocks - one for the Linux pte table, and one for
+ * the hardware pte table.
+ */
+static inline void
+alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
+{
+       pmd_t *pmdp = pmd_off_k(virt);
+       pte_t *ptep;
+
+       if (pmd_none(*pmdp)) {
+               ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
+                                              sizeof(pte_t));
+
+               __pmd_populate(pmdp, __pa(ptep) | prot_l1);
+       }
+       ptep = pte_offset_kernel(pmdp, virt);
+
+       set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
+}
+
+/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'.  We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections and
+ * supersections.
+ */
+void __init create_mapping(struct map_desc *md)
+{
+       unsigned long virt, length;
+       int prot_sect, prot_l1, domain;
+       pgprot_t prot_pte;
+       unsigned long off = (u32)__pfn_to_phys(md->pfn);
+
+       if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
+               printk(KERN_WARNING "BUG: not creating mapping for "
+                      "0x%08llx at 0x%08lx in user region\n",
+                      __pfn_to_phys((u64)md->pfn), md->virtual);
+               return;
+       }
+
+       if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
+           md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
+               printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
+                      "overlaps vmalloc space\n",
+                      __pfn_to_phys((u64)md->pfn), md->virtual);
+       }
+
+       domain    = mem_types[md->type].domain;
+       prot_pte  = __pgprot(mem_types[md->type].prot_pte);
+       prot_l1   = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
+       prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
+
+       /*
+        * Catch 36-bit addresses
+        */
+       if(md->pfn >= 0x100000) {
+               if(domain) {
+                       printk(KERN_ERR "MM: invalid domain in supersection "
+                               "mapping for 0x%08llx at 0x%08lx\n",
+                               __pfn_to_phys((u64)md->pfn), md->virtual);
+                       return;
+               }
+               if((md->virtual | md->length | __pfn_to_phys(md->pfn))
+                       & ~SUPERSECTION_MASK) {
+                       printk(KERN_ERR "MM: cannot create mapping for "
+                               "0x%08llx at 0x%08lx invalid alignment\n",
+                               __pfn_to_phys((u64)md->pfn), md->virtual);
+                       return;
+               }
+
+               /*
+                * Shift bits [35:32] of address into bits [23:20] of PMD
+                * (See ARMv6 spec).
+                */
+               off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+       }
+
+       virt   = md->virtual;
+       off   -= virt;
+       length = md->length;
+
+       if (mem_types[md->type].prot_l1 == 0 &&
+           (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
+               printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
+                      "be mapped using pages, ignoring.\n",
+                      __pfn_to_phys(md->pfn), md->virtual);
+               return;
+       }
+
+       while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
+               alloc_init_page(virt, virt + off, prot_l1, prot_pte);
+
+               virt   += PAGE_SIZE;
+               length -= PAGE_SIZE;
+       }
+
+       /* N.B. ARMv6 supersections are only defined to work with domain 0.
+        *      Since domain assignments can in fact be arbitrary, the
+        *      'domain == 0' check below is required to insure that ARMv6
+        *      supersections are only allocated for domain 0 regardless
+        *      of the actual domain assignments in use.
+        */
+       if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())
+               && domain == 0) {
+               /*
+                * Align to supersection boundary if !high pages.
+                * High pages have already been checked for proper
+                * alignment above and they will fail the SUPSERSECTION_MASK
+                * check because of the way the address is encoded into
+                * offset.
+                */
+               if (md->pfn <= 0x100000) {
+                       while ((virt & ~SUPERSECTION_MASK ||
+                               (virt + off) & ~SUPERSECTION_MASK) &&
+                               length >= (PGDIR_SIZE / 2)) {
+                               alloc_init_section(virt, virt + off, prot_sect);
+
+                               virt   += (PGDIR_SIZE / 2);
+                               length -= (PGDIR_SIZE / 2);
+                       }
+               }
+
+               while (length >= SUPERSECTION_SIZE) {
+                       alloc_init_supersection(virt, virt + off, prot_sect);
+
+                       virt   += SUPERSECTION_SIZE;
+                       length -= SUPERSECTION_SIZE;
+               }
+       }
+
+       /*
+        * A section mapping covers half a "pgdir" entry.
+        */
+       while (length >= (PGDIR_SIZE / 2)) {
+               alloc_init_section(virt, virt + off, prot_sect);
+
+               virt   += (PGDIR_SIZE / 2);
+               length -= (PGDIR_SIZE / 2);
+       }
+
+       while (length >= PAGE_SIZE) {
+               alloc_init_page(virt, virt + off, prot_l1, prot_pte);
+
+               virt   += PAGE_SIZE;
+               length -= PAGE_SIZE;
+       }
+}
+
+/*
+ * Create the architecture specific mappings
+ */
+void __init iotable_init(struct map_desc *io_desc, int nr)
+{
+       int i;
+
+       for (i = 0; i < nr; i++)
+               create_mapping(io_desc + i);
+}
+
+static inline void prepare_page_table(struct meminfo *mi)
+{
+       unsigned long addr;
+
+       /*
+        * Clear out all the mappings below the kernel image.
+        */
+       for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+
+#ifdef CONFIG_XIP_KERNEL
+       /* The XIP kernel is mapped in the module area -- skip over it */
+       addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+#endif
+       for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+
+       /*
+        * Clear out all the kernel space mappings, except for the first
+        * memory bank, up to the end of the vmalloc region.
+        */
+       for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
+            addr < VMALLOC_END; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+}
+
+/*
+ * Reserve the various regions of node 0
+ */
+void __init reserve_node_zero(pg_data_t *pgdat)
+{
+       unsigned long res_size = 0;
+
+       /*
+        * Register the kernel text and data with bootmem.
+        * Note that this can only be in node 0.
+        */
+#ifdef CONFIG_XIP_KERNEL
+       reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
+#else
+       reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
+#endif
+
+       /*
+        * Reserve the page tables.  These are already in use,
+        * and can only be in node 0.
+        */
+       reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
+                            PTRS_PER_PGD * sizeof(pgd_t));
+
+       /*
+        * Hmm... This should go elsewhere, but we really really need to
+        * stop things allocating the low memory; ideally we need a better
+        * implementation of GFP_DMA which does not assume that DMA-able
+        * memory starts at zero.
+        */
+       if (machine_is_integrator() || machine_is_cintegrator())
+               res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+
+       /*
+        * These should likewise go elsewhere.  They pre-reserve the
+        * screen memory region at the start of main system memory.
+        */
+       if (machine_is_edb7211())
+               res_size = 0x00020000;
+       if (machine_is_p720t())
+               res_size = 0x00014000;
+
+#ifdef CONFIG_SA1111
+       /*
+        * Because of the SA1111 DMA bug, we want to preserve our
+        * precious DMA-able memory...
+        */
+       res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+#endif
+       if (res_size)
+               reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
+}
+
+/*
+ * Set up device the mappings.  Since we clear out the page tables for all
+ * mappings above VMALLOC_END, we will remove any debug device mappings.
+ * This means you have to be careful how you debug this function, or any
+ * called function.  This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
+ */
+static void __init devicemaps_init(struct machine_desc *mdesc)
+{
+       struct map_desc map;
+       unsigned long addr;
+       void *vectors;
+
+       /*
+        * Allocate the vector page early.
+        */
+       vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+       BUG_ON(!vectors);
+
+       for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+
+       /*
+        * Map the kernel if it is XIP.
+        * It is always first in the modulearea.
+        */
+#ifdef CONFIG_XIP_KERNEL
+       map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+       map.virtual = MODULE_START;
+       map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+       map.type = MT_ROM;
+       create_mapping(&map);
+#endif
+
+       /*
+        * Map the cache flushing regions.
+        */
+#ifdef FLUSH_BASE
+       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+       map.virtual = FLUSH_BASE;
+       map.length = SZ_1M;
+       map.type = MT_CACHECLEAN;
+       create_mapping(&map);
+#endif
+#ifdef FLUSH_BASE_MINICACHE
+       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
+       map.virtual = FLUSH_BASE_MINICACHE;
+       map.length = SZ_1M;
+       map.type = MT_MINICLEAN;
+       create_mapping(&map);
+#endif
+
+       /*
+        * Create a mapping for the machine vectors at the high-vectors
+        * location (0xffff0000).  If we aren't using high-vectors, also
+        * create a mapping at the low-vectors virtual address.
+        */
+       map.pfn = __phys_to_pfn(virt_to_phys(vectors));
+       map.virtual = 0xffff0000;
+       map.length = PAGE_SIZE;
+       map.type = MT_HIGH_VECTORS;
+       create_mapping(&map);
+
+       if (!vectors_high()) {
+               map.virtual = 0;
+               map.type = MT_LOW_VECTORS;
+               create_mapping(&map);
+       }
+
+       /*
+        * Ask the machine support to map in the statically mapped devices.
+        */
+       if (mdesc->map_io)
+               mdesc->map_io();
+
+       /*
+        * Finally flush the caches and tlb to ensure that we're in a
+        * consistent state wrt the writebuffer.  This also ensures that
+        * any write-allocated cache lines in the vector page are written
+        * back.  After this point, we can start to touch devices again.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+       void *zero_page;
+
+       build_mem_type_table();
+       prepare_page_table(mi);
+       bootmem_init(mi);
+       devicemaps_init(mdesc);
+
+       top_pmd = pmd_off_k(0xffff0000);
+
+       /*
+        * allocate the zero page.  Note that we count on this going ok.
+        */
+       zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+       memzero(zero_page, PAGE_SIZE);
+       empty_zero_page = virt_to_page(zero_page);
+       flush_dcache_page(empty_zero_page);
+}
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages.  This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+       unsigned long base_pmdval;
+       pgd_t *pgd;
+       int i;
+
+       if (current->mm && current->mm->pgd)
+               pgd = current->mm->pgd;
+       else
+               pgd = init_mm.pgd;
+
+       base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
+       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+               base_pmdval |= PMD_BIT4;
+
+       for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
+               unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
+               pmd_t *pmd;
 
-       mm->context.id = asid;
+               pmd = pmd_off(pgd, i << PGDIR_SHIFT);
+               pmd[0] = __pmd(pmdval);
+               pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
+               flush_pmd_entry(pmd);
+       }
 }
index 1464ed817b5dc87b1d456a898bf66c8bc9b4007f..d0e66424a59720886d81908643ba1431afdd609e 100644 (file)
 #include <asm/io.h>
 #include <asm/page.h>
 
+#include "mm.h"
+
+extern void _stext, __data_start, _end;
+
+/*
+ * Reserve the various regions of node 0
+ */
+void __init reserve_node_zero(pg_data_t *pgdat)
+{
+       /*
+        * Register the kernel text and data with bootmem.
+        * Note that this can only be in node 0.
+        */
+#ifdef CONFIG_XIP_KERNEL
+       reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
+#else
+       reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
+#endif
+
+       /*
+        * Register the exception vector page.
+        * some architectures which the DRAM is the exception vector to trap,
+        * alloc_page breaks with error, although it is not NULL, but "0."
+        */
+       reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE);
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+       bootmem_init(mi);
+}
+
+/*
+ * We don't need to do anything here for nommu machines.
+ */
+void setup_mm_for_reboot(char mode)
+{
+}
+
 void flush_dcache_page(struct page *page)
 {
        __cpuc_flush_dcache_page(page_address(page));
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
new file mode 100644 (file)
index 0000000..20c1b0d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  linux/arch/arm/mm/pgd.c
+ *
+ *  Copyright (C) 1998-2005 Russell King
+ *
+ * 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/mm.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+#define FIRST_KERNEL_PGD_NR    (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
+
+/*
+ * need to get a 16k page for level 1
+ */
+pgd_t *get_pgd_slow(struct mm_struct *mm)
+{
+       pgd_t *new_pgd, *init_pgd;
+       pmd_t *new_pmd, *init_pmd;
+       pte_t *new_pte, *init_pte;
+
+       new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
+       if (!new_pgd)
+               goto no_pgd;
+
+       memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
+
+       /*
+        * Copy over the kernel and IO PGD entries
+        */
+       init_pgd = pgd_offset_k(0);
+       memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+                      (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+
+       clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+
+       if (!vectors_high()) {
+               /*
+                * On ARM, first page must always be allocated since it
+                * contains the machine vectors.
+                */
+               new_pmd = pmd_alloc(mm, new_pgd, 0);
+               if (!new_pmd)
+                       goto no_pmd;
+
+               new_pte = pte_alloc_map(mm, new_pmd, 0);
+               if (!new_pte)
+                       goto no_pte;
+
+               init_pmd = pmd_offset(init_pgd, 0);
+               init_pte = pte_offset_map_nested(init_pmd, 0);
+               set_pte(new_pte, *init_pte);
+               pte_unmap_nested(init_pte);
+               pte_unmap(new_pte);
+       }
+
+       return new_pgd;
+
+no_pte:
+       pmd_free(new_pmd);
+no_pmd:
+       free_pages((unsigned long)new_pgd, 2);
+no_pgd:
+       return NULL;
+}
+
+void free_pgd_slow(pgd_t *pgd)
+{
+       pmd_t *pmd;
+       struct page *pte;
+
+       if (!pgd)
+               return;
+
+       /* pgd is always present and good */
+       pmd = pmd_off(pgd, 0);
+       if (pmd_none(*pmd))
+               goto free;
+       if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
+               goto free;
+       }
+
+       pte = pmd_page(*pmd);
+       pmd_clear(pmd);
+       dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
+       pte_lock_deinit(pte);
+       pte_free(pte);
+       pmd_free(pmd);
+free:
+       free_pages((unsigned long) pgd, 2);
+}
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
new file mode 100644 (file)
index 0000000..4071381
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ *  linux/arch/arm/mm/arm740.S: utility functions for ARM740
+ *
+ *  Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com)
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+
+       .text
+/*
+ * cpu_arm740_proc_init()
+ * cpu_arm740_do_idle()
+ * cpu_arm740_dcache_clean_area()
+ * cpu_arm740_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm740_proc_init)
+ENTRY(cpu_arm740_do_idle)
+ENTRY(cpu_arm740_dcache_clean_area)
+ENTRY(cpu_arm740_switch_mm)
+       mov     pc, lr
+
+/*
+ * cpu_arm740_proc_fin()
+ */
+ENTRY(cpu_arm740_proc_fin)
+       stmfd   sp!, {lr}
+       mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+       msr     cpsr_c, ip
+       mrc     p15, 0, r0, c1, c0, 0
+       bic     r0, r0, #0x3f000000             @ bank/f/lock/s
+       bic     r0, r0, #0x0000000c             @ w-buffer/cache
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       mcr     p15, 0, r0, c7, c0, 0           @ invalidate cache
+       ldmfd   sp!, {pc}
+
+/*
+ * cpu_arm740_reset(loc)
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm740_reset)
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c0, 0           @ invalidate cache
+       mrc     p15, 0, ip, c1, c0, 0           @ get ctrl register
+       bic     ip, ip, #0x0000000c             @ ............wc..
+       mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
+       mov     pc, r0
+
+       __INIT
+
+       .type   __arm740_setup, #function
+__arm740_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c0, 0           @ invalidate caches
+
+       mcr     p15, 0, r0, c6, c3              @ disable area 3~7
+       mcr     p15, 0, r0, c6, c4
+       mcr     p15, 0, r0, c6, c5
+       mcr     p15, 0, r0, c6, c6
+       mcr     p15, 0, r0, c6, c7
+
+       mov     r0, #0x0000003F                 @ base = 0, size = 4GB
+       mcr     p15, 0, r0, c6, c0              @ set area 0, default
+
+       ldr     r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+       ldr     r1, =(CONFIG_DRAM_SIZE >> 12)   @ size of RAM (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c1              @ set area 1, RAM
+
+       ldr     r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+       ldr     r1, =(CONFIG_FLASH_SIZE >> 12)  @ size of FLASH (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c2              @ set area 2, ROM/FLASH
+
+       mov     r0, #0x06
+       mcr     p15, 0, r0, c2, c0              @ Region 1&2 cacheable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mov     r0, #0x00                       @ disable whole write buffer
+#else
+       mov     r0, #0x02                       @ Region 1 write bufferred
+#endif
+       mcr     p15, 0, r0, c3, c0
+
+       mov     r0, #0x10000
+       sub     r0, r0, #1                      @ r0 = 0xffff
+       mcr     p15, 0, r0, c5, c0              @ all read/write access
+
+       mrc     p15, 0, r0, c1, c0              @ get control register
+       bic     r0, r0, #0x3F000000             @ set to standard caching mode
+                                               @ need some benchmark
+       orr     r0, r0, #0x0000000d             @ MPU/Cache/WB
+
+       mov     pc, lr
+
+       .size   __arm740_setup, . - __arm740_setup
+
+       __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *          come through these
+ */
+       .type   arm740_processor_functions, #object
+ENTRY(arm740_processor_functions)
+       .word   v4t_late_abort
+       .word   cpu_arm740_proc_init
+       .word   cpu_arm740_proc_fin
+       .word   cpu_arm740_reset
+       .word   cpu_arm740_do_idle
+       .word   cpu_arm740_dcache_clean_area
+       .word   cpu_arm740_switch_mm
+       .word   0                       @ cpu_*_set_pte
+       .size   arm740_processor_functions, . - arm740_processor_functions
+
+       .section ".rodata"
+
+       .type   cpu_arch_name, #object
+cpu_arch_name:
+       .asciz  "armv4"
+       .size   cpu_arch_name, . - cpu_arch_name
+
+       .type   cpu_elf_name, #object
+cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
+
+       .type   cpu_arm740_name, #object
+cpu_arm740_name:
+       .ascii  "ARM740T"
+       .size   cpu_arm740_name, . - cpu_arm740_name
+
+       .align
+
+       .section ".proc.info.init", #alloc, #execinstr
+       .type   __arm740_proc_info,#object
+__arm740_proc_info:
+       .long   0x41807400
+       .long   0xfffffff0
+       .long   0
+       b       __arm740_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+       .long   cpu_arm740_name
+       .long   arm740_processor_functions
+       .long   0
+       .long   0
+       .long   v3_cache_fns                    @ cache model
+       .size   __arm740_proc_info, . - __arm740_proc_info
+
+
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
new file mode 100644 (file)
index 0000000..22d7e31
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ *  linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI
+ *
+ *  Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@samsung.com>
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+
+       .text
+/*
+ * cpu_arm7tdmi_proc_init()
+ * cpu_arm7tdmi_do_idle()
+ * cpu_arm7tdmi_dcache_clean_area()
+ * cpu_arm7tdmi_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm7tdmi_proc_init)
+ENTRY(cpu_arm7tdmi_do_idle)
+ENTRY(cpu_arm7tdmi_dcache_clean_area)
+ENTRY(cpu_arm7tdmi_switch_mm)
+               mov     pc, lr
+
+/*
+ * cpu_arm7tdmi_proc_fin()
+ */
+ENTRY(cpu_arm7tdmi_proc_fin)
+               mov     r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+               msr     cpsr_c, r0
+               mov     pc, lr
+
+/*
+ * Function: cpu_arm7tdmi_reset(loc)
+ * Params  : loc(r0)   address to jump to
+ * Purpose : Sets up everything for a reset and jump to the location for soft reset.
+ */
+ENTRY(cpu_arm7tdmi_reset)
+               mov     pc, r0
+
+               __INIT
+
+               .type   __arm7tdmi_setup, #function
+__arm7tdmi_setup:
+               mov     pc, lr
+               .size   __arm7tdmi_setup, . - __arm7tdmi_setup
+
+               __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *          come through these
+ */
+               .type   arm7tdmi_processor_functions, #object
+ENTRY(arm7tdmi_processor_functions)
+               .word   v4t_late_abort
+               .word   cpu_arm7tdmi_proc_init
+               .word   cpu_arm7tdmi_proc_fin
+               .word   cpu_arm7tdmi_reset
+               .word   cpu_arm7tdmi_do_idle
+               .word   cpu_arm7tdmi_dcache_clean_area
+               .word   cpu_arm7tdmi_switch_mm
+               .word   0               @ cpu_*_set_pte
+               .size   arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
+
+               .section ".rodata"
+
+               .type   cpu_arch_name, #object
+cpu_arch_name:
+               .asciz  "armv4t"
+               .size   cpu_arch_name, . - cpu_arch_name
+
+               .type   cpu_elf_name, #object
+cpu_elf_name:
+               .asciz  "v4"
+               .size   cpu_elf_name, . - cpu_elf_name
+
+               .type   cpu_arm7tdmi_name, #object
+cpu_arm7tdmi_name:
+               .asciz  "ARM7TDMI"
+               .size   cpu_arm7tdmi_name, . - cpu_arm7tdmi_name
+
+               .type   cpu_triscenda7_name, #object
+cpu_triscenda7_name:
+               .asciz  "Triscend-A7x"
+               .size   cpu_triscenda7_name, . - cpu_triscenda7_name
+
+               .type   cpu_at91_name, #object
+cpu_at91_name:
+               .asciz  "Atmel-AT91M40xxx"
+               .size   cpu_at91_name, . - cpu_at91_name
+
+               .type   cpu_s3c3410_name, #object
+cpu_s3c3410_name:
+               .asciz  "Samsung-S3C3410"
+               .size   cpu_s3c3410_name, . - cpu_s3c3410_name
+
+               .type   cpu_s3c44b0x_name, #object
+cpu_s3c44b0x_name:
+               .asciz  "Samsung-S3C44B0x"
+               .size   cpu_s3c44b0x_name, . - cpu_s3c44b0x_name
+
+               .type   cpu_s3c4510b, #object
+cpu_s3c4510b_name:
+               .asciz  "Samsung-S3C4510B"
+               .size   cpu_s3c4510b_name, . - cpu_s3c4510b_name
+
+               .type   cpu_s3c4530_name, #object
+cpu_s3c4530_name:
+               .asciz  "Samsung-S3C4530"
+               .size   cpu_s3c4530_name, . - cpu_s3c4530_name
+
+               .type   cpu_netarm_name, #object
+cpu_netarm_name:
+               .asciz  "NETARM"
+               .size   cpu_netarm_name, . - cpu_netarm_name
+
+               .align
+
+               .section ".proc.info.init", #alloc, #execinstr
+
+               .type   __arm7tdmi_proc_info, #object
+__arm7tdmi_proc_info:
+               .long   0x41007700
+               .long   0xfff8ff00
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_26BIT
+               .long   cpu_arm7tdmi_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __arm7tdmi_proc_info, . - __arm7dmi_proc_info
+
+               .type   __triscenda7_proc_info, #object
+__triscenda7_proc_info:
+               .long   0x0001d2ff
+               .long   0x0001ffff
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_triscenda7_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __triscenda7_proc_info, . - __triscenda7_proc_info
+
+               .type   __at91_proc_info, #object
+__at91_proc_info:
+               .long   0x14000040
+               .long   0xfff000e0
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_at91_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __at91_proc_info, . - __at91_proc_info
+
+               .type   __s3c4510b_proc_info, #object
+__s3c4510b_proc_info:
+               .long   0x36365000
+               .long   0xfffff000
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_s3c4510b_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __s3c4510b_proc_info, . - __s3c4510b_proc_info
+
+               .type   __s3c4530_proc_info, #object
+__s3c4530_proc_info:
+               .long   0x4c000000
+               .long   0xfff000e0
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_s3c4530_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __s3c4530_proc_info, . - __s3c4530_proc_info
+
+               .type   __s3c3410_proc_info, #object
+__s3c3410_proc_info:
+               .long   0x34100000
+               .long   0xffff0000
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_s3c3410_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __s3c3410_proc_info, . - __s3c3410_proc_info
+
+               .type   __s3c44b0x_proc_info, #object
+__s3c44b0x_proc_info:
+               .long   0x44b00000
+               .long   0xffff0000
+               .long   0
+               .long   0
+               b       __arm7tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_s3c44b0x_name
+               .long   arm7tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __s3c44b0x_proc_info, . - __s3c44b0x_proc_info
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
new file mode 100644 (file)
index 0000000..2397f4b
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ *  linux/arch/arm/mm/arm940.S: utility functions for ARM940T
+ *
+ *  Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com)
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+
+/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */
+#define CACHE_DLINESIZE        16
+#define CACHE_DSEGMENTS        4
+#define CACHE_DENTRIES 64
+
+       .text
+/*
+ * cpu_arm940_proc_init()
+ * cpu_arm940_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm940_proc_init)
+ENTRY(cpu_arm940_switch_mm)
+       mov     pc, lr
+
+/*
+ * cpu_arm940_proc_fin()
+ */
+ENTRY(cpu_arm940_proc_fin)
+       stmfd   sp!, {lr}
+       mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+       msr     cpsr_c, ip
+       bl      arm940_flush_kern_cache_all
+       mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
+       bic     r0, r0, #0x00001000             @ i-cache
+       bic     r0, r0, #0x00000004             @ d-cache
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       ldmfd   sp!, {pc}
+
+/*
+ * cpu_arm940_reset(loc)
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm940_reset)
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c5, 0           @ flush I cache
+       mcr     p15, 0, ip, c7, c6, 0           @ flush D cache
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
+       bic     ip, ip, #0x00000005             @ .............c.p
+       bic     ip, ip, #0x00001000             @ i-cache
+       mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
+       mov     pc, r0
+
+/*
+ * cpu_arm940_do_idle()
+ */
+       .align  5
+ENTRY(cpu_arm940_do_idle)
+       mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
+       mov     pc, lr
+
+/*
+ *     flush_user_cache_all()
+ */
+ENTRY(arm940_flush_user_cache_all)
+       /* FALLTHROUGH */
+
+/*
+ *     flush_kern_cache_all()
+ *
+ *     Clean and invalidate the entire cache.
+ */
+ENTRY(arm940_flush_kern_cache_all)
+       mov     r2, #VM_EXEC
+       /* FALLTHROUGH */
+
+/*
+ *     flush_user_cache_range(start, end, flags)
+ *
+ *     There is no efficient way to flush a range of cache entries
+ *     in the specified address range. Thus, flushes all.
+ *
+ *     - start - start address (inclusive)
+ *     - end   - end address (exclusive)
+ *     - flags - vm_flags describing address space
+ */
+ENTRY(arm940_flush_user_cache_range)
+       mov     ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mcr     p15, 0, ip, c7, c6, 0           @ flush D cache
+#else
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:     mcr     p15, 0, r3, c7, c14, 2          @ clean/flush D index
+       subs    r3, r3, #1 << 26
+       bcs     2b                              @ entries 63 to 0
+       subs    r1, r1, #1 << 4
+       bcs     1b                              @ segments 3 to 0
+#endif
+       tst     r2, #VM_EXEC
+       mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
+       mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     coherent_kern_range(start, end)
+ *
+ *     Ensure coherency between the Icache and the Dcache in the
+ *     region described by start, end.  If you have non-snooping
+ *     Harvard caches, you need to implement this function.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm940_coherent_kern_range)
+       /* FALLTHROUGH */
+
+/*
+ *     coherent_user_range(start, end)
+ *
+ *     Ensure coherency between the Icache and the Dcache in the
+ *     region described by start, end.  If you have non-snooping
+ *     Harvard caches, you need to implement this function.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm940_coherent_user_range)
+       /* FALLTHROUGH */
+
+/*
+ *     flush_kern_dcache_page(void *page)
+ *
+ *     Ensure no D cache aliasing occurs, either with itself or
+ *     the I cache
+ *
+ *     - addr  - page aligned address
+ */
+ENTRY(arm940_flush_kern_dcache_page)
+       mov     ip, #0
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:     mcr     p15, 0, r3, c7, c14, 2          @ clean/flush D index
+       subs    r3, r3, #1 << 26
+       bcs     2b                              @ entries 63 to 0
+       subs    r1, r1, #1 << 4
+       bcs     1b                              @ segments 7 to 0
+       mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_inv_range(start, end)
+ *
+ *     There is no efficient way to invalidate a specifid virtual
+ *     address range. Thus, invalidates all.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm940_dma_inv_range)
+       mov     ip, #0
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:     mcr     p15, 0, r3, c7, c6, 2           @ flush D entry
+       subs    r3, r3, #1 << 26
+       bcs     2b                              @ entries 63 to 0
+       subs    r1, r1, #1 << 4
+       bcs     1b                              @ segments 7 to 0
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_clean_range(start, end)
+ *
+ *     There is no efficient way to clean a specifid virtual
+ *     address range. Thus, cleans all.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm940_dma_clean_range)
+ENTRY(cpu_arm940_dcache_clean_area)
+       mov     ip, #0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:     mcr     p15, 0, r3, c7, c10, 2          @ clean D entry
+       subs    r3, r3, #1 << 26
+       bcs     2b                              @ entries 63 to 0
+       subs    r1, r1, #1 << 4
+       bcs     1b                              @ segments 7 to 0
+#endif
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_flush_range(start, end)
+ *
+ *     There is no efficient way to clean and invalidate a specifid
+ *     virtual address range.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm940_dma_flush_range)
+       mov     ip, #0
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mcr     p15, 0, r3, c7, c14, 2          @ clean/flush D entry
+#else
+       mcr     p15, 0, r3, c7, c10, 2          @ clean D entry
+#endif
+       subs    r3, r3, #1 << 26
+       bcs     2b                              @ entries 63 to 0
+       subs    r1, r1, #1 << 4
+       bcs     1b                              @ segments 7 to 0
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+ENTRY(arm940_cache_fns)
+       .long   arm940_flush_kern_cache_all
+       .long   arm940_flush_user_cache_all
+       .long   arm940_flush_user_cache_range
+       .long   arm940_coherent_kern_range
+       .long   arm940_coherent_user_range
+       .long   arm940_flush_kern_dcache_page
+       .long   arm940_dma_inv_range
+       .long   arm940_dma_clean_range
+       .long   arm940_dma_flush_range
+
+       __INIT
+
+       .type   __arm940_setup, #function
+__arm940_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mcr     p15, 0, r0, c7, c6, 0           @ invalidate D cache
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+
+       mcr     p15, 0, r0, c6, c3, 0           @ disable data area 3~7
+       mcr     p15, 0, r0, c6, c4, 0
+       mcr     p15, 0, r0, c6, c5, 0
+       mcr     p15, 0, r0, c6, c6, 0
+       mcr     p15, 0, r0, c6, c7, 0
+
+       mcr     p15, 0, r0, c6, c3, 1           @ disable instruction area 3~7
+       mcr     p15, 0, r0, c6, c4, 1
+       mcr     p15, 0, r0, c6, c5, 1
+       mcr     p15, 0, r0, c6, c6, 1
+       mcr     p15, 0, r0, c6, c7, 1
+
+       mov     r0, #0x0000003F                 @ base = 0, size = 4GB
+       mcr     p15, 0, r0, c6, c0, 0           @ set area 0, default
+       mcr     p15, 0, r0, c6, c0, 1
+
+       ldr     r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+       ldr     r1, =(CONFIG_DRAM_SIZE >> 12)   @ size of RAM (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c1, 0           @ set area 1, RAM
+       mcr     p15, 0, r0, c6, c1, 1
+
+       ldr     r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+       ldr     r1, =(CONFIG_FLASH_SIZE >> 12)  @ size of FLASH (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the area register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c2, 0           @ set area 2, ROM/FLASH
+       mcr     p15, 0, r0, c6, c2, 1
+
+       mov     r0, #0x06
+       mcr     p15, 0, r0, c2, c0, 0           @ Region 1&2 cacheable
+       mcr     p15, 0, r0, c2, c0, 1
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mov     r0, #0x00                       @ disable whole write buffer
+#else
+       mov     r0, #0x02                       @ Region 1 write bufferred
+#endif
+       mcr     p15, 0, r0, c3, c0, 0
+
+       mov     r0, #0x10000
+       sub     r0, r0, #1                      @ r0 = 0xffff
+       mcr     p15, 0, r0, c5, c0, 0           @ all read/write access
+       mcr     p15, 0, r0, c5, c0, 1
+
+       mrc     p15, 0, r0, c1, c0              @ get control register
+       orr     r0, r0, #0x00001000             @ I-cache
+       orr     r0, r0, #0x00000005             @ MPU/D-cache
+
+       mov     pc, lr
+
+       .size   __arm940_setup, . - __arm940_setup
+
+       __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *          come through these
+ */
+       .type   arm940_processor_functions, #object
+ENTRY(arm940_processor_functions)
+       .word   nommu_early_abort
+       .word   cpu_arm940_proc_init
+       .word   cpu_arm940_proc_fin
+       .word   cpu_arm940_reset
+       .word   cpu_arm940_do_idle
+       .word   cpu_arm940_dcache_clean_area
+       .word   cpu_arm940_switch_mm
+       .word   0               @ cpu_*_set_pte
+       .size   arm940_processor_functions, . - arm940_processor_functions
+
+       .section ".rodata"
+
+.type  cpu_arch_name, #object
+cpu_arch_name:
+       .asciz  "armv4t"
+       .size   cpu_arch_name, . - cpu_arch_name
+
+       .type   cpu_elf_name, #object
+cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
+
+       .type   cpu_arm940_name, #object
+cpu_arm940_name:
+       .ascii  "ARM940T"
+       .size   cpu_arm940_name, . - cpu_arm940_name
+
+       .align
+
+       .section ".proc.info.init", #alloc, #execinstr
+
+       .type   __arm940_proc_info,#object
+__arm940_proc_info:
+       .long   0x41009400
+       .long   0xff00fff0
+       .long   0
+       b       __arm940_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+       .long   cpu_arm940_name
+       .long   arm940_processor_functions
+       .long   0
+       .long   0
+       .long   arm940_cache_fns
+       .size   __arm940_proc_info, . - __arm940_proc_info
+
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
new file mode 100644 (file)
index 0000000..e186175
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ *  linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S
+ *
+ *  Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com)
+ *
+ *  (Many of cache codes are from proc-arm926.S)
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+
+/*
+ * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache,
+ * comprising 256 lines of 32 bytes (8 words).
+ */
+#define CACHE_DSIZE    (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */
+#define CACHE_DLINESIZE        32                      /* fixed */
+#define CACHE_DSEGMENTS        4                       /* fixed */
+#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE)
+#define CACHE_DLIMIT   (CACHE_DSIZE * 4)       /* benchmark needed */
+
+       .text
+/*
+ * cpu_arm946_proc_init()
+ * cpu_arm946_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm946_proc_init)
+ENTRY(cpu_arm946_switch_mm)
+       mov     pc, lr
+
+/*
+ * cpu_arm946_proc_fin()
+ */
+ENTRY(cpu_arm946_proc_fin)
+       stmfd   sp!, {lr}
+       mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+       msr     cpsr_c, ip
+       bl      arm946_flush_kern_cache_all
+       mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
+       bic     r0, r0, #0x00001000             @ i-cache
+       bic     r0, r0, #0x00000004             @ d-cache
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       ldmfd   sp!, {pc}
+
+/*
+ * cpu_arm946_reset(loc)
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm946_reset)
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c5, 0           @ flush I cache
+       mcr     p15, 0, ip, c7, c6, 0           @ flush D cache
+       mcr     p15, 0, ip, c7, c10, 4          @ drain WB
+       mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
+       bic     ip, ip, #0x00000005             @ .............c.p
+       bic     ip, ip, #0x00001000             @ i-cache
+       mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
+       mov     pc, r0
+
+/*
+ * cpu_arm946_do_idle()
+ */
+       .align  5
+ENTRY(cpu_arm946_do_idle)
+       mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
+       mov     pc, lr
+
+/*
+ *     flush_user_cache_all()
+ */
+ENTRY(arm946_flush_user_cache_all)
+       /* FALLTHROUGH */
+
+/*
+ *     flush_kern_cache_all()
+ *
+ *     Clean and invalidate the entire cache.
+ */
+ENTRY(arm946_flush_kern_cache_all)
+       mov     r2, #VM_EXEC
+       mov     ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mcr     p15, 0, ip, c7, c6, 0           @ flush D cache
+#else
+       mov     r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments
+1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries
+2:     mcr     p15, 0, r3, c7, c14, 2          @ clean/flush D index
+       subs    r3, r3, #1 << 4
+       bcs     2b                              @ entries n to 0
+       subs    r1, r1, #1 << 29
+       bcs     1b                              @ segments 3 to 0
+#endif
+       tst     r2, #VM_EXEC
+       mcrne   p15, 0, ip, c7, c5, 0           @ flush I cache
+       mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     flush_user_cache_range(start, end, flags)
+ *
+ *     Clean and invalidate a range of cache entries in the
+ *     specified address range.
+ *
+ *     - start - start address (inclusive)
+ *     - end   - end address (exclusive)
+ *     - flags - vm_flags describing address space
+ * (same as arm926)
+ */
+ENTRY(arm946_flush_user_cache_range)
+       mov     ip, #0
+       sub     r3, r1, r0                      @ calculate total size
+       cmp     r3, #CACHE_DLIMIT
+       bhs     __flush_whole_cache
+
+1:     tst     r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
+       mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
+       add     r0, r0, #CACHE_DLINESIZE
+       mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
+       mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
+       add     r0, r0, #CACHE_DLINESIZE
+#else
+       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
+       mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
+       add     r0, r0, #CACHE_DLINESIZE
+       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
+       mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
+       add     r0, r0, #CACHE_DLINESIZE
+#endif
+       cmp     r0, r1
+       blo     1b
+       tst     r2, #VM_EXEC
+       mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     coherent_kern_range(start, end)
+ *
+ *     Ensure coherency between the Icache and the Dcache in the
+ *     region described by start, end.  If you have non-snooping
+ *     Harvard caches, you need to implement this function.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ */
+ENTRY(arm946_coherent_kern_range)
+       /* FALLTHROUGH */
+
+/*
+ *     coherent_user_range(start, end)
+ *
+ *     Ensure coherency between the Icache and the Dcache in the
+ *     region described by start, end.  If you have non-snooping
+ *     Harvard caches, you need to implement this function.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ * (same as arm926)
+ */
+ENTRY(arm946_coherent_user_range)
+       bic     r0, r0, #CACHE_DLINESIZE - 1
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
+       add     r0, r0, #CACHE_DLINESIZE
+       cmp     r0, r1
+       blo     1b
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     flush_kern_dcache_page(void *page)
+ *
+ *     Ensure no D cache aliasing occurs, either with itself or
+ *     the I cache
+ *
+ *     - addr  - page aligned address
+ * (same as arm926)
+ */
+ENTRY(arm946_flush_kern_dcache_page)
+       add     r1, r0, #PAGE_SZ
+1:     mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
+       add     r0, r0, #CACHE_DLINESIZE
+       cmp     r0, r1
+       blo     1b
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_inv_range(start, end)
+ *
+ *     Invalidate (discard) the specified virtual address range.
+ *     May not write back any entries.  If 'start' or 'end'
+ *     are not cache line aligned, those lines must be written
+ *     back.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ * (same as arm926)
+ */
+ENTRY(arm946_dma_inv_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+       tst     r0, #CACHE_DLINESIZE - 1
+       mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
+       tst     r1, #CACHE_DLINESIZE - 1
+       mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
+#endif
+       bic     r0, r0, #CACHE_DLINESIZE - 1
+1:     mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
+       add     r0, r0, #CACHE_DLINESIZE
+       cmp     r0, r1
+       blo     1b
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_clean_range(start, end)
+ *
+ *     Clean the specified virtual address range.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ *
+ * (same as arm926)
+ */
+ENTRY(arm946_dma_clean_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+       bic     r0, r0, #CACHE_DLINESIZE - 1
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, #CACHE_DLINESIZE
+       cmp     r0, r1
+       blo     1b
+#endif
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+/*
+ *     dma_flush_range(start, end)
+ *
+ *     Clean and invalidate the specified virtual address range.
+ *
+ *     - start - virtual start address
+ *     - end   - virtual end address
+ *
+ * (same as arm926)
+ */
+ENTRY(arm946_dma_flush_range)
+       bic     r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
+#else
+       mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+#endif
+       add     r0, r0, #CACHE_DLINESIZE
+       cmp     r0, r1
+       blo     1b
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+ENTRY(arm946_cache_fns)
+       .long   arm946_flush_kern_cache_all
+       .long   arm946_flush_user_cache_all
+       .long   arm946_flush_user_cache_range
+       .long   arm946_coherent_kern_range
+       .long   arm946_coherent_user_range
+       .long   arm946_flush_kern_dcache_page
+       .long   arm946_dma_inv_range
+       .long   arm946_dma_clean_range
+       .long   arm946_dma_flush_range
+
+
+ENTRY(cpu_arm946_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, #CACHE_DLINESIZE
+       subs    r1, r1, #CACHE_DLINESIZE
+       bhi     1b
+#endif
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+
+       __INIT
+
+       .type   __arm946_setup, #function
+__arm946_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mcr     p15, 0, r0, c7, c6, 0           @ invalidate D cache
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+
+       mcr     p15, 0, r0, c6, c3, 0           @ disable memory region 3~7
+       mcr     p15, 0, r0, c6, c4, 0
+       mcr     p15, 0, r0, c6, c5, 0
+       mcr     p15, 0, r0, c6, c6, 0
+       mcr     p15, 0, r0, c6, c7, 0
+
+       mov     r0, #0x0000003F                 @ base = 0, size = 4GB
+       mcr     p15, 0, r0, c6, c0, 0           @ set region 0, default
+
+       ldr     r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+       ldr     r1, =(CONFIG_DRAM_SIZE >> 12)   @ size of RAM (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the region register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c1, 0           @ set region 1, RAM
+
+       ldr     r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+       ldr     r1, =(CONFIG_FLASH_SIZE >> 12)  @ size of FLASH (must be >= 4KB)
+       mov     r2, #10                         @ 11 is the minimum (4KB)
+1:     add     r2, r2, #1                      @ area size *= 2
+       mov     r1, r1, lsr #1
+       bne     1b                              @ count not zero r-shift
+       orr     r0, r0, r2, lsl #1              @ the region register value
+       orr     r0, r0, #1                      @ set enable bit
+       mcr     p15, 0, r0, c6, c2, 0           @ set region 2, ROM/FLASH
+
+       mov     r0, #0x06
+       mcr     p15, 0, r0, c2, c0, 0           @ region 1,2 d-cacheable
+       mcr     p15, 0, r0, c2, c0, 1           @ region 1,2 i-cacheable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+       mov     r0, #0x00                       @ disable whole write buffer
+#else
+       mov     r0, #0x02                       @ region 1 write bufferred
+#endif
+       mcr     p15, 0, r0, c3, c0, 0
+
+/*
+ *  Access Permission Settings for future permission control by PU.
+ *
+ *                             priv.   user
+ *     region 0 (whole)        rw      --      : b0001
+ *     region 1 (RAM)          rw      rw      : b0011
+ *     region 2 (FLASH)        rw      r-      : b0010
+ *     region 3~7 (none)       --      --      : b0000
+ */
+       mov     r0, #0x00000031
+       orr     r0, r0, #0x00000200
+       mcr     p15, 0, r0, c5, c0, 2           @ set data access permission
+       mcr     p15, 0, r0, c5, c0, 3           @ set inst. access permission
+
+       mrc     p15, 0, r0, c1, c0              @ get control register
+       orr     r0, r0, #0x00001000             @ I-cache
+       orr     r0, r0, #0x00000005             @ MPU/D-cache
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+       orr     r0, r0, #0x00004000             @ .1.. .... .... ....
+#endif
+       mov     pc, lr
+
+       .size   __arm946_setup, . - __arm946_setup
+
+       __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *          come through these
+ */
+       .type   arm946_processor_functions, #object
+ENTRY(arm946_processor_functions)
+       .word   nommu_early_abort
+       .word   cpu_arm946_proc_init
+       .word   cpu_arm946_proc_fin
+       .word   cpu_arm946_reset
+       .word   cpu_arm946_do_idle
+
+       .word   cpu_arm946_dcache_clean_area
+       .word   cpu_arm946_switch_mm
+       .word   0               @ cpu_*_set_pte
+       .size   arm946_processor_functions, . - arm946_processor_functions
+
+       .section ".rodata"
+
+       .type   cpu_arch_name, #object
+cpu_arch_name:
+       .asciz  "armv5te"
+       .size   cpu_arch_name, . - cpu_arch_name
+
+       .type   cpu_elf_name, #object
+cpu_elf_name:
+       .asciz  "v5t"
+       .size   cpu_elf_name, . - cpu_elf_name
+
+       .type   cpu_arm946_name, #object
+cpu_arm946_name:
+       .ascii  "ARM946E-S"
+       .size   cpu_arm946_name, . - cpu_arm946_name
+
+       .align
+
+       .section ".proc.info.init", #alloc, #execinstr
+       .type   __arm946_proc_info,#object
+__arm946_proc_info:
+       .long   0x41009460
+       .long   0xff00fff0
+       .long   0
+       b       __arm946_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+       .long   cpu_arm946_name
+       .long   arm946_processor_functions
+       .long   0
+       .long   0
+       .long   arm940_cache_fns
+       .size   __arm946_proc_info, . - __arm946_proc_info
+
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
new file mode 100644 (file)
index 0000000..918ebf6
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  linux/arch/arm/mm/proc-arm9tdmi.S: utility functions for ARM9TDMI
+ *
+ *  Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@samsung.com>
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+
+       .text
+/*
+ * cpu_arm9tdmi_proc_init()
+ * cpu_arm9tdmi_do_idle()
+ * cpu_arm9tdmi_dcache_clean_area()
+ * cpu_arm9tdmi_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm9tdmi_proc_init)
+ENTRY(cpu_arm9tdmi_do_idle)
+ENTRY(cpu_arm9tdmi_dcache_clean_area)
+ENTRY(cpu_arm9tdmi_switch_mm)
+               mov     pc, lr
+
+/*
+ * cpu_arm9tdmi_proc_fin()
+ */
+ENTRY(cpu_arm9tdmi_proc_fin)
+               mov     r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+               msr     cpsr_c, r0
+               mov     pc, lr
+
+/*
+ * Function: cpu_arm9tdmi_reset(loc)
+ * Params  : loc(r0)   address to jump to
+ * Purpose : Sets up everything for a reset and jump to the location for soft reset.
+ */
+ENTRY(cpu_arm9tdmi_reset)
+               mov     pc, r0
+
+               __INIT
+
+               .type   __arm9tdmi_setup, #function
+__arm9tdmi_setup:
+               mov     pc, lr
+               .size   __arm9tdmi_setup, . - __arm9tdmi_setup
+
+               __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *          come through these
+ */
+               .type   arm9tdmi_processor_functions, #object
+ENTRY(arm9tdmi_processor_functions)
+               .word   nommu_early_abort
+               .word   cpu_arm9tdmi_proc_init
+               .word   cpu_arm9tdmi_proc_fin
+               .word   cpu_arm9tdmi_reset
+               .word   cpu_arm9tdmi_do_idle
+               .word   cpu_arm9tdmi_dcache_clean_area
+               .word   cpu_arm9tdmi_switch_mm
+               .word   0               @ cpu_*_set_pte
+               .size   arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
+
+               .section ".rodata"
+
+               .type   cpu_arch_name, #object
+cpu_arch_name:
+               .asciz  "armv4t"
+               .size   cpu_arch_name, . - cpu_arch_name
+
+               .type   cpu_elf_name, #object
+cpu_elf_name:
+               .asciz  "v4"
+               .size   cpu_elf_name, . - cpu_elf_name
+
+               .type   cpu_arm9tdmi_name, #object
+cpu_arm9tdmi_name:
+               .asciz  "ARM9TDMI"
+               .size   cpu_arm9tdmi_name, . - cpu_arm9tdmi_name
+
+               .type   cpu_p2001_name, #object
+cpu_p2001_name:
+               .asciz  "P2001"
+               .size   cpu_p2001_name, . - cpu_p2001_name
+
+               .align
+
+               .section ".proc.info.init", #alloc, #execinstr
+
+               .type   __arm9tdmi_proc_info, #object
+__arm9tdmi_proc_info:
+               .long   0x41009900
+               .long   0xfff8ff00
+               .long   0
+               .long   0
+               b       __arm9tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_arm9tdmi_name
+               .long   arm9tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __arm9tdmi_proc_info, . - __arm9dmi_proc_info
+
+               .type   __p2001_proc_info, #object
+__p2001_proc_info:
+               .long   0x41029000
+               .long   0xffffffff
+               .long   0
+               .long   0
+               b       __arm9tdmi_setup
+               .long   cpu_arch_name
+               .long   cpu_elf_name
+               .long   HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
+               .long   cpu_p2001_name
+               .long   arm9tdmi_processor_functions
+               .long   0
+               .long   0
+               .long   v4_cache_fns
+               .size   __p2001_proc_info, . - __p2001_proc_info
index 3ca0c92e98a2ddba5a3b2f3d21a09cb775700abd..e8b377d637f664753917371a626563461c2ca94a 100644 (file)
@@ -311,12 +311,6 @@ ENTRY(xscale_flush_kern_dcache_page)
  *     - end    - virtual end address
  */
 ENTRY(xscale_dma_inv_range)
-       mrc     p15, 0, r2, c0, c0, 0           @ read ID
-       eor     r2, r2, #0x69000000
-       eor     r2, r2, #0x00052000
-       bics    r2, r2, #1
-       beq     xscale_dma_flush_range
-
        tst     r0, #CACHELINESIZE - 1
        bic     r0, r0, #CACHELINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -375,6 +369,30 @@ ENTRY(xscale_cache_fns)
        .long   xscale_dma_clean_range
        .long   xscale_dma_flush_range
 
+/*
+ * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
+ * clear the dirty bits, which means that if we invalidate a dirty line,
+ * the dirty data can still be written back to external memory later on.
+ *
+ * The recommended workaround is to always do a clean D-cache line before
+ * doing an invalidate D-cache line, so on the affected processors,
+ * dma_inv_range() is implemented as dma_flush_range().
+ *
+ * See erratum #25 of "Intel 80200 Processor Specification Update",
+ * revision January 22, 2003, available at:
+ *     http://www.intel.com/design/iio/specupdt/273415.htm
+ */
+ENTRY(xscale_80200_A0_A1_cache_fns)
+       .long   xscale_flush_kern_cache_all
+       .long   xscale_flush_user_cache_all
+       .long   xscale_flush_user_cache_range
+       .long   xscale_coherent_kern_range
+       .long   xscale_coherent_user_range
+       .long   xscale_flush_kern_dcache_page
+       .long   xscale_dma_flush_range
+       .long   xscale_dma_clean_range
+       .long   xscale_dma_flush_range
+
 ENTRY(cpu_xscale_dcache_clean_area)
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHELINESIZE
@@ -531,6 +549,11 @@ cpu_elf_name:
        .asciz  "v5"
        .size   cpu_elf_name, . - cpu_elf_name
 
+       .type   cpu_80200_A0_A1_name, #object
+cpu_80200_A0_A1_name:
+       .asciz  "XScale-80200 A0/A1"
+       .size   cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name
+
        .type   cpu_80200_name, #object
 cpu_80200_name:
        .asciz  "XScale-80200"
@@ -595,6 +618,29 @@ cpu_pxa270_name:
 
        .section ".proc.info.init", #alloc, #execinstr
 
+       .type   __80200_A0_A1_proc_info,#object
+__80200_A0_A1_proc_info:
+       .long   0x69052000
+       .long   0xfffffffe
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_BUFFERABLE | \
+               PMD_SECT_CACHEABLE | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
+       b       __xscale_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+       .long   cpu_80200_name
+       .long   xscale_processor_functions
+       .long   v4wbi_tlb_fns
+       .long   xscale_mc_user_fns
+       .long   xscale_80200_A0_A1_cache_fns
+       .size   __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info
+
        .type   __80200_proc_info,#object
 __80200_proc_info:
        .long   0x69052000
index 34fdc733743b9ec3a5c626c18541f24a4a46be87..6576143f25598253bba9e5d8701bdb44d8bd4234 100644 (file)
 #ifdef CONFIG_ARCH_IOP310
 #define XSCALE_PMU_IRQ  IRQ_XS80200_PMU
 #endif
-#ifdef CONFIG_ARCH_IOP321
-#define XSCALE_PMU_IRQ  IRQ_IOP321_CORE_PMU
+#ifdef CONFIG_ARCH_IOP32X
+#define XSCALE_PMU_IRQ  IRQ_IOP32X_CORE_PMU
 #endif
-#ifdef CONFIG_ARCH_IOP331
-#define XSCALE_PMU_IRQ  IRQ_IOP331_CORE_PMU
+#ifdef CONFIG_ARCH_IOP33X
+#define XSCALE_PMU_IRQ  IRQ_IOP33X_CORE_PMU
 #endif
 #ifdef CONFIG_ARCH_PXA
 #define XSCALE_PMU_IRQ  IRQ_PMU
@@ -88,7 +88,7 @@ static struct pmu_counter results[MAX_COUNTERS];
 /*
  * There are two versions of the PMU in current XScale processors
  * with differing register layouts and number of performance counters.
- * e.g. IOP321 is xsc1 whilst IOP331 is xsc2.
+ * e.g. IOP32x is xsc1 whilst IOP33x is xsc2.
  * We detect which register layout to use in xscale_detect_pmu()
  */
 enum { PMU_XSC1, PMU_XSC2 };
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
new file mode 100644 (file)
index 0000000..23da00b
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y                  := gpio.o i2c.o pci.o setup.o time.o
+obj-m                  :=
+obj-n                  :=
+obj-                   :=
diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c
new file mode 100644 (file)
index 0000000..eda4360
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/plat-iop/gpio.c
+ * GPIO handling for Intel IOP3xx processors.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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.
+ */
+
+#include <linux/device.h>
+#include <asm/hardware/iop3xx.h>
+
+void gpio_line_config(int line, int direction)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (direction == GPIO_IN) {
+               *IOP3XX_GPOE |= 1 << line;
+       } else if (direction == GPIO_OUT) {
+               *IOP3XX_GPOE &= ~(1 << line);
+       }
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_line_config);
+
+int gpio_line_get(int line)
+{
+       return !!(*IOP3XX_GPID & (1 << line));
+}
+EXPORT_SYMBOL(gpio_line_get);
+
+void gpio_line_set(int line, int value)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (value == GPIO_LOW) {
+               *IOP3XX_GPOD &= ~(1 << line);
+       } else if (value == GPIO_HIGH) {
+               *IOP3XX_GPOD |= 1 << line;
+       }
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_line_set);
diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c
new file mode 100644 (file)
index 0000000..e99909b
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/plat-iop/i2c.c
+ *
+ * Author: Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/hardware/iop3xx.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#ifdef CONFIG_ARCH_IOP32X
+#define IRQ_IOP3XX_I2C_0       IRQ_IOP32X_I2C_0
+#define IRQ_IOP3XX_I2C_1       IRQ_IOP32X_I2C_1
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+#define IRQ_IOP3XX_I2C_0       IRQ_IOP33X_I2C_0
+#define IRQ_IOP3XX_I2C_1       IRQ_IOP33X_I2C_1
+#endif
+
+static struct resource iop3xx_i2c0_resources[] = {
+       [0] = {
+               .start  = 0xfffff680,
+               .end    = 0xfffff697,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IOP3XX_I2C_0,
+               .end    = IRQ_IOP3XX_I2C_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device iop3xx_i2c0_device = {
+       .name           = "IOP3xx-I2C",
+       .id             = 0,
+       .num_resources  = 2,
+       .resource       = iop3xx_i2c0_resources,
+};
+
+
+static struct resource iop3xx_i2c1_resources[] = {
+       [0] = {
+               .start  = 0xfffff6a0,
+               .end    = 0xfffff6b7,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IOP3XX_I2C_1,
+               .end    = IRQ_IOP3XX_I2C_1,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device iop3xx_i2c1_device = {
+       .name           = "IOP3xx-I2C",
+       .id             = 1,
+       .num_resources  = 2,
+       .resource       = iop3xx_i2c1_resources,
+};
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
new file mode 100644 (file)
index 0000000..e647812
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * arch/arm/plat-iop/pci.c
+ *
+ * PCI support for the Intel IOP32X and IOP33X processors
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/iop3xx.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...) do { } while (0)
+#endif
+
+/*
+ * This routine builds either a type0 or type1 configuration command.  If the
+ * bus is on the 803xx then a type0 made, else a type1 is created.
+ */
+static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+       struct pci_sys_data *sys = bus->sysdata;
+       u32 addr;
+
+       if (sys->busnr == bus->number)
+               addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
+       else
+               addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
+
+       addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
+
+       return addr;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle.  If an error
+ * was detected it returns a 1, else it returns a 0.  The errors being checked
+ * are parity, master abort, target abort (master and target).  These types of
+ * errors occure during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop3xx_pci_status(void)
+{
+       unsigned int status;
+       int ret = 0;
+
+       /*
+        * Check the status registers.
+        */
+       status = *IOP3XX_ATUSR;
+       if (status & 0xf900) {
+               DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+               *IOP3XX_ATUSR = status & 0xf900;
+               ret = 1;
+       }
+
+       status = *IOP3XX_ATUISR;
+       if (status & 0x679f) {
+               DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+               *IOP3XX_ATUISR = status & 0x679f;
+               ret = 1;
+       }
+
+       return ret;
+}
+
+/*
+ * Simply write the address register and read the configuration
+ * data.  Note that the 4 nop's ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static inline u32 iop3xx_read(unsigned long addr)
+{
+       u32 val;
+
+       __asm__ __volatile__(
+               "str    %1, [%2]\n\t"
+               "ldr    %0, [%3]\n\t"
+               "nop\n\t"
+               "nop\n\t"
+               "nop\n\t"
+               "nop\n\t"
+               : "=r" (val)
+               : "r" (addr), "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR));
+
+       return val;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle.  If there was an error, the routine returns all hex f's.
+ */
+static int
+iop3xx_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+               int size, u32 *value)
+{
+       unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
+       u32 val = iop3xx_read(addr) >> ((where & 3) * 8);
+
+       if (iop3xx_pci_status())
+               val = 0xffffffff;
+
+       *value = val;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+               int size, u32 value)
+{
+       unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
+       u32 val;
+
+       if (size != 4) {
+               val = iop3xx_read(addr);
+               if (iop3xx_pci_status())
+                       return PCIBIOS_SUCCESSFUL;
+
+               where = (where & 3) * 8;
+
+               if (size == 1)
+                       val &= ~(0xff << where);
+               else
+                       val &= ~(0xffff << where);
+
+               *IOP3XX_OCCDR = val | value << where;
+       } else {
+               asm volatile(
+                       "str    %1, [%2]\n\t"
+                       "str    %0, [%3]\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       "nop\n\t"
+                       :
+                       : "r" (value), "r" (addr),
+                         "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR));
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop3xx_ops = {
+       .read   = iop3xx_read_config,
+       .write  = iop3xx_write_config,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the 80200 gets a
+ * bus error instead of returning 0xffffffff. This handler simply returns.
+ */
+static int
+iop3xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+       DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
+               addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+       /*
+        * If it was an imprecise abort, then we need to correct the
+        * return address to be _after_ the instruction.
+        */
+       if (fsr & (1 << 10))
+               regs->ARM_pc += 4;
+
+       return 0;
+}
+
+int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+       struct resource *res;
+
+       if (nr != 0)
+               return 0;
+
+       res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL);
+       if (!res)
+               panic("PCI: unable to alloc resources");
+
+       res[0].start = IOP3XX_PCI_LOWER_IO_VA;
+       res[0].end   = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
+       res[0].name  = "IOP3XX PCI I/O Space";
+       res[0].flags = IORESOURCE_IO;
+       request_resource(&ioport_resource, &res[0]);
+
+       res[1].start = IOP3XX_PCI_LOWER_MEM_PA;
+       res[1].end   = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
+       res[1].name  = "IOP3XX PCI Memory Space";
+       res[1].flags = IORESOURCE_MEM;
+       request_resource(&iomem_resource, &res[1]);
+
+       sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA;
+       sys->io_offset  = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA;
+
+       sys->resource[0] = &res[0];
+       sys->resource[1] = &res[1];
+       sys->resource[2] = NULL;
+
+       return 1;
+}
+
+struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+       return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
+}
+
+void iop3xx_pci_preinit(void)
+{
+       DBG("PCI:  Intel 803xx PCI init code.\n");
+       DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
+       DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n",
+                       *IOP3XX_OMWTVR0,
+                       *IOP3XX_OIOWTVR);
+       DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR);
+       DBG("ATU: IOP3XX_IABAR0=0x%08x IOP3XX_IALR0=0x%08x IOP3XX_IATVR0=%08x\n",
+                       *IOP3XX_IABAR0, *IOP3XX_IALR0, *IOP3XX_IATVR0);
+       DBG("ATU: IOP3XX_OMWTVR0=0x%08x\n", *IOP3XX_OMWTVR0);
+       DBG("ATU: IOP3XX_IABAR1=0x%08x IOP3XX_IALR1=0x%08x\n",
+                       *IOP3XX_IABAR1, *IOP3XX_IALR1);
+       DBG("ATU: IOP3XX_ERBAR=0x%08x IOP3XX_ERLR=0x%08x IOP3XX_ERTVR=%08x\n",
+                       *IOP3XX_ERBAR, *IOP3XX_ERLR, *IOP3XX_ERTVR);
+       DBG("ATU: IOP3XX_IABAR2=0x%08x IOP3XX_IALR2=0x%08x IOP3XX_IATVR2=%08x\n",
+                       *IOP3XX_IABAR2, *IOP3XX_IALR2, *IOP3XX_IATVR2);
+       DBG("ATU: IOP3XX_IABAR3=0x%08x IOP3XX_IALR3=0x%08x IOP3XX_IATVR3=%08x\n",
+                       *IOP3XX_IABAR3, *IOP3XX_IALR3, *IOP3XX_IATVR3);
+
+       hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
+}
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
new file mode 100644 (file)
index 0000000..4689db6
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/plat-iop/setup.c
+ *
+ * Author: Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/iop3xx.h>
+
+/*
+ * Standard IO mapping for all IOP3xx based systems
+ */
+static struct map_desc iop3xx_std_desc[] __initdata = {
+        {      /* mem mapped registers */
+               .virtual        = IOP3XX_PERIPHERAL_VIRT_BASE,
+               .pfn            = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
+               .length         = IOP3XX_PERIPHERAL_SIZE,
+               .type           = MT_DEVICE,
+        }, {   /* PCI IO space */
+               .virtual        = IOP3XX_PCI_LOWER_IO_VA,
+               .pfn            = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
+               .length         = IOP3XX_PCI_IO_WINDOW_SIZE,
+               .type           = MT_DEVICE,
+        },
+};
+
+void __init iop3xx_map_io(void)
+{
+       iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc));
+}
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
new file mode 100644 (file)
index 0000000..06282df
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/plat-iop/time.c
+ *
+ * Timer code for IOP32x and IOP33x based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#ifdef CONFIG_ARCH_IOP32X
+#define IRQ_IOP3XX_TIMER0      IRQ_IOP32X_TIMER0
+#else
+#ifdef CONFIG_ARCH_IOP33X
+#define IRQ_IOP3XX_TIMER0      IRQ_IOP33X_TIMER0
+#endif
+#endif
+
+static unsigned long ticks_per_jiffy;
+static unsigned long ticks_per_usec;
+static unsigned long next_jiffy_time;
+
+unsigned long iop3xx_gettimeoffset(void)
+{
+       unsigned long offset;
+
+       offset = next_jiffy_time - *IOP3XX_TU_TCR1;
+
+       return offset / ticks_per_usec;
+}
+
+static irqreturn_t
+iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       write_seqlock(&xtime_lock);
+
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1));
+       iop3xx_cp6_disable();
+
+       while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1)
+                                                       >= ticks_per_jiffy) {
+               timer_tick(regs);
+               next_jiffy_time -= ticks_per_jiffy;
+       }
+
+       write_sequnlock(&xtime_lock);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction iop3xx_timer_irq = {
+       .name           = "IOP3XX Timer Tick",
+       .handler        = iop3xx_timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+};
+
+void __init iop3xx_init_time(unsigned long tick_rate)
+{
+       u32 timer_ctl;
+
+       ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
+       ticks_per_usec = tick_rate / 1000000;
+       next_jiffy_time = 0xffffffff;
+
+       timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED |
+                       IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1;
+
+       /*
+        * We use timer 0 for our timer interrupt, and timer 1 as
+        * monotonic counter for tracking missed jiffies.
+        */
+       iop3xx_cp6_enable();
+       asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1));
+       asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl));
+       asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff));
+       asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl));
+       iop3xx_cp6_disable();
+
+       setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq);
+}
index 7f45c7c3e673d1898902fbac743de5e7cb655fd8..f1179ad4be1bb0f63e3d95059c8e3188b5bcc1e4 100644 (file)
@@ -100,6 +100,7 @@ void clk_disable(struct clk *clk)
                return;
 
        spin_lock_irqsave(&clockfw_lock, flags);
+       BUG_ON(clk->usecount == 0);
        if (arch_clock->clk_disable)
                arch_clock->clk_disable(clk);
        spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -322,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle);
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Disable any unused clocks left on by the bootloader
+ */
+static int __init clk_disable_unused(void)
+{
+       struct clk *ck;
+       unsigned long flags;
+
+       list_for_each_entry(ck, &clocks, node) {
+               if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
+                       ck->enable_reg == 0)
+                       continue;
+
+               spin_lock_irqsave(&clockfw_lock, flags);
+               if (arch_clock->clk_disable_unused)
+                       arch_clock->clk_disable_unused(ck);
+               spin_unlock_irqrestore(&clockfw_lock, flags);
+       }
+
+       return 0;
+}
+late_initcall(clk_disable_unused);
+#endif
+
 int __init clk_init(struct clk_functions * custom_clocks)
 {
        if (!custom_clocks) {
index 1812f237d12f9f0327531d73db6b302356847339..dbc3f44e07a603f8b891c2901e1223a846dc34f1 100644 (file)
@@ -148,7 +148,7 @@ static inline void omap_init_kp(void) {}
 
 #ifdef CONFIG_ARCH_OMAP24XX
 #define        OMAP_MMC1_BASE          0x4809c000
-#define OMAP_MMC1_INT          83
+#define OMAP_MMC1_INT          INT_24XX_MMC_IRQ
 #else
 #define        OMAP_MMC1_BASE          0xfffb7800
 #define OMAP_MMC1_INT          INT_MMC
@@ -225,7 +225,14 @@ static void __init omap_init_mmc(void)
        /* block 1 is always available and has just one pinout option */
        mmc = &mmc_conf->mmc[0];
        if (mmc->enabled) {
-               if (!cpu_is_omap24xx()) {
+               if (cpu_is_omap24xx()) {
+                       omap_cfg_reg(H18_24XX_MMC_CMD);
+                       omap_cfg_reg(H15_24XX_MMC_CLKI);
+                       omap_cfg_reg(G19_24XX_MMC_CLKO);
+                       omap_cfg_reg(F20_24XX_MMC_DAT0);
+                       omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
+                       omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+               } else {
                        omap_cfg_reg(MMC_CMD);
                        omap_cfg_reg(MMC_CLK);
                        omap_cfg_reg(MMC_DAT0);
@@ -236,7 +243,14 @@ static void __init omap_init_mmc(void)
                        }
                }
                if (mmc->wire4) {
-                       if (!cpu_is_omap24xx()) {
+                       if (cpu_is_omap24xx()) {
+                               omap_cfg_reg(H14_24XX_MMC_DAT1);
+                               omap_cfg_reg(E19_24XX_MMC_DAT2);
+                               omap_cfg_reg(D19_24XX_MMC_DAT3);
+                               omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
+                               omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
+                               omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+                       } else {
                                omap_cfg_reg(MMC_DAT1);
                                /* NOTE:  DAT2 can be on W10 (here) or M15 */
                                if (!mmc->nomux)
index 9eddc9507147121a892291563dd4902eda322810..1bbb431843ce056ced668044bd5d71a43036a14e 100644 (file)
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch)
                omap_writew(0, lch_base + i);
 }
 
-void omap_set_dma_priority(int dst_port, int priority)
+void omap_set_dma_priority(int lch, int dst_port, int priority)
 {
        unsigned long reg;
        u32 l;
 
-       switch (dst_port) {
-       case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
-               reg = OMAP_TC_OCPT1_PRIOR;
-               break;
-       case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
-               reg = OMAP_TC_OCPT2_PRIOR;
-               break;
-       case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
-               reg = OMAP_TC_EMIFF_PRIOR;
-               break;
-       case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
-               reg = OMAP_TC_EMIFS_PRIOR;
-               break;
-       default:
-               BUG();
-               return;
+       if (cpu_class_is_omap1()) {
+               switch (dst_port) {
+               case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
+                       reg = OMAP_TC_OCPT1_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
+                       reg = OMAP_TC_OCPT2_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
+                       reg = OMAP_TC_EMIFF_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
+                       reg = OMAP_TC_EMIFS_PRIOR;
+                       break;
+               default:
+                       BUG();
+                       return;
+               }
+               l = omap_readl(reg);
+               l &= ~(0xf << 8);
+               l |= (priority & 0xf) << 8;
+               omap_writel(l, reg);
+       }
+
+       if (cpu_is_omap24xx()) {
+               if (priority)
+                       OMAP_DMA_CCR_REG(lch) |= (1 << 6);
+               else
+                       OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
        }
-       l = omap_readl(reg);
-       l &= ~(0xf << 8);
-       l |= (priority & 0xf) << 8;
-       omap_writel(l, reg);
 }
 
 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
@@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
        OMAP1_DMA_LCH_CTRL_REG(lch) = w;
 }
 
+void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
+{
+       if (cpu_is_omap24xx()) {
+               OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
+               OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
+       }
+}
+
 /* Note that src_port is only for omap1 */
 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                             unsigned long src_start,
@@ -697,6 +714,32 @@ void omap_stop_dma(int lch)
        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 
+/*
+ * Allows changing the DMA callback function or data. This may be needed if
+ * the driver shares a single DMA channel for multiple dma triggers.
+ */
+int omap_set_dma_callback(int lch,
+                         void (* callback)(int lch, u16 ch_status, void *data),
+                         void *data)
+{
+       unsigned long flags;
+
+       if (lch < 0)
+               return -ENODEV;
+
+       spin_lock_irqsave(&dma_chan_lock, flags);
+       if (dma_chan[lch].dev_id == -1) {
+               printk(KERN_ERR "DMA callback for not set for free channel\n");
+               spin_unlock_irqrestore(&dma_chan_lock, flags);
+               return -EINVAL;
+       }
+       dma_chan[lch].callback = callback;
+       dma_chan[lch].data = data;
+       spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+       return 0;
+}
+
 /*
  * Returns current physical source address for the given DMA channel.
  * If the channel is running the caller must disable interrupts prior calling
@@ -1339,6 +1382,14 @@ static int __init omap_init_dma(void)
                        dma_chan_count = 16;
                } else
                        dma_chan_count = 9;
+               if (cpu_is_omap16xx()) {
+                       u16 w;
+
+                       /* this would prevent OMAP sleep */
+                       w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+                       w &= ~(1 << 8);
+                       omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+               }
        } else if (cpu_is_omap24xx()) {
                u8 revision = omap_readb(OMAP_DMA4_REVISION);
                printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
@@ -1414,11 +1465,13 @@ EXPORT_SYMBOL(omap_request_dma);
 EXPORT_SYMBOL(omap_free_dma);
 EXPORT_SYMBOL(omap_start_dma);
 EXPORT_SYMBOL(omap_stop_dma);
+EXPORT_SYMBOL(omap_set_dma_callback);
 EXPORT_SYMBOL(omap_enable_dma_irq);
 EXPORT_SYMBOL(omap_disable_dma_irq);
 
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
 EXPORT_SYMBOL(omap_set_dma_color_mode);
+EXPORT_SYMBOL(omap_set_dma_write_mode);
 
 EXPORT_SYMBOL(omap_set_dma_src_params);
 EXPORT_SYMBOL(omap_set_dma_src_index);
index 50524436de63e8896764048ca813d510f5e9bebc..bcbb8d7392be6d5b5ca729b29a32439a1ba5331a 100644 (file)
@@ -75,10 +75,14 @@ struct omap_dm_timer {
 #endif
        void __iomem *io_base;
        unsigned reserved:1;
+       unsigned enabled:1;
 };
 
 #ifdef CONFIG_ARCH_OMAP1
 
+#define omap_dm_clk_enable(x)
+#define omap_dm_clk_disable(x)
+
 static struct omap_dm_timer dm_timers[] = {
        { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
        { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
@@ -92,6 +96,9 @@ static struct omap_dm_timer dm_timers[] = {
 
 #elif defined(CONFIG_ARCH_OMAP2)
 
+#define omap_dm_clk_enable(x) clk_enable(x)
+#define omap_dm_clk_disable(x) clk_disable(x)
+
 static struct omap_dm_timer dm_timers[] = {
        { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
        { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
@@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 {
        u32 l;
 
-       if (timer != &dm_timers[0]) {
+       if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
                omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
                omap_dm_timer_wait_for_reset(timer);
        }
-       omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK);
+       omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
 
        /* Set to smart-idle mode */
        l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
        l |= 0x02 << 3;
+
+       if (cpu_class_is_omap2() && timer == &dm_timers[0]) {
+               /* Enable wake-up only for GPT1 on OMAP2 CPUs*/
+               l |= 1 << 2;
+               /* Non-posted mode */
+               omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0);
+       }
        omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
 }
 
 static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
-#ifdef CONFIG_ARCH_OMAP2
-       clk_enable(timer->iclk);
-       clk_enable(timer->fclk);
-#endif
+       omap_dm_timer_enable(timer);
        omap_dm_timer_reset(timer);
 }
 
@@ -223,15 +234,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 
 void omap_dm_timer_free(struct omap_dm_timer *timer)
 {
+       omap_dm_timer_enable(timer);
        omap_dm_timer_reset(timer);
-#ifdef CONFIG_ARCH_OMAP2
-       clk_disable(timer->iclk);
-       clk_disable(timer->fclk);
-#endif
+       omap_dm_timer_disable(timer);
+
        WARN_ON(!timer->reserved);
        timer->reserved = 0;
 }
 
+void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+       if (timer->enabled)
+               return;
+
+       omap_dm_clk_enable(timer->fclk);
+       omap_dm_clk_enable(timer->iclk);
+
+       timer->enabled = 1;
+}
+
+void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+       if (!timer->enabled)
+               return;
+
+       omap_dm_clk_disable(timer->iclk);
+       omap_dm_clk_disable(timer->fclk);
+
+       timer->enabled = 0;
+}
+
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
        return timer->irq;
@@ -276,7 +308,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
-        return timer->fclk;
+       return timer->fclk;
 }
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
@@ -406,11 +438,16 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
                                  unsigned int value)
 {
        omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
+       omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
 }
 
 unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
-       return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
+       unsigned int l;
+
+       l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
+
+       return l;
 }
 
 void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
@@ -420,12 +457,16 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 
 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
-       return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
+       unsigned int l;
+
+       l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
+
+       return l;
 }
 
 void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
-       return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
+       omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
 }
 
 int omap_dm_timers_active(void)
@@ -436,9 +477,14 @@ int omap_dm_timers_active(void)
                struct omap_dm_timer *timer;
 
                timer = &dm_timers[i];
+
+               if (!timer->enabled)
+                       continue;
+
                if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
-                   OMAP_TIMER_CTRL_ST)
+                   OMAP_TIMER_CTRL_ST) {
                        return 1;
+               }
        }
        return 0;
 }
index cd7f973fb286618e23c1370dd56b532e9b5cbc15..f55f99ae58aea6ab07402c2562ab00b84ff8c38e 100644 (file)
@@ -94,6 +94,8 @@
 #define OMAP24XX_GPIO_SYSCONFIG                0x0010
 #define OMAP24XX_GPIO_SYSSTATUS                0x0014
 #define OMAP24XX_GPIO_IRQSTATUS1       0x0018
+#define OMAP24XX_GPIO_IRQSTATUS2       0x0028
+#define OMAP24XX_GPIO_IRQENABLE2       0x002c
 #define OMAP24XX_GPIO_IRQENABLE1       0x001c
 #define OMAP24XX_GPIO_CTRL             0x0030
 #define OMAP24XX_GPIO_OE               0x0034
 #define OMAP24XX_GPIO_CLEARDATAOUT     0x0090
 #define OMAP24XX_GPIO_SETDATAOUT       0x0094
 
-#define OMAP_MPUIO_MASK                (~OMAP_MAX_GPIO_LINES & 0xff)
-
 struct gpio_bank {
        void __iomem *base;
        u16 irq;
@@ -216,11 +216,13 @@ static inline int gpio_valid(int gpio)
 {
        if (gpio < 0)
                return -1;
+#ifndef CONFIG_ARCH_OMAP24XX
        if (OMAP_GPIO_IS_MPUIO(gpio)) {
-               if ((gpio & OMAP_MPUIO_MASK) > 16)
+               if (gpio >= OMAP_MAX_GPIO_LINES + 16)
                        return -1;
                return 0;
        }
+#endif
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap15xx() && gpio < 16)
                return 0;
@@ -529,6 +531,10 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
                return;
        }
        __raw_writel(gpio_mask, reg);
+
+       /* Workaround for clearing DSP GPIO interrupts to allow retention */
+       if (cpu_is_omap2420())
+               __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2);
 }
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -662,6 +668,14 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
        }
 }
 
+static void _reset_gpio(struct gpio_bank *bank, int gpio)
+{
+       _set_gpio_direction(bank, get_gpio_index(gpio), 1);
+       _set_gpio_irqenable(bank, gpio, 0);
+       _clear_gpio_irqstatus(bank, gpio);
+       _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
+}
+
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
 static int gpio_wake_enable(unsigned int irq, unsigned int enable)
 {
@@ -672,9 +686,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)
        if (check_gpio(gpio) < 0)
                return -ENODEV;
        bank = get_gpio_bank(gpio);
-       spin_lock(&bank->lock);
        retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
-       spin_unlock(&bank->lock);
 
        return retval;
 }
@@ -696,7 +708,9 @@ int omap_request_gpio(int gpio)
        }
        bank->reserved_map |= (1 << get_gpio_index(gpio));
 
-       /* Set trigger to none. You need to enable the trigger after request_irq */
+       /* Set trigger to none. You need to enable the desired trigger with
+        * request_irq() or set_irq_type().
+        */
        _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
 
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -756,9 +770,7 @@ void omap_free_gpio(int gpio)
        }
 #endif
        bank->reserved_map &= ~(1 << get_gpio_index(gpio));
-       _set_gpio_direction(bank, get_gpio_index(gpio), 1);
-       _set_gpio_irqenable(bank, gpio, 0);
-       _clear_gpio_irqstatus(bank, gpio);
+       _reset_gpio(bank, gpio);
        spin_unlock(&bank->lock);
 }
 
@@ -898,6 +910,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 
 }
 
+static void gpio_irq_shutdown(unsigned int irq)
+{
+       unsigned int gpio = irq - IH_GPIO_BASE;
+       struct gpio_bank *bank = get_gpio_bank(gpio);
+
+       _reset_gpio(bank, gpio);
+}
+
 static void gpio_ack_irq(unsigned int irq)
 {
        unsigned int gpio = irq - IH_GPIO_BASE;
@@ -946,6 +966,7 @@ static void mpuio_unmask_irq(unsigned int irq)
 
 static struct irq_chip gpio_irq_chip = {
        .name           = "GPIO",
+       .shutdown       = gpio_irq_shutdown,
        .ack            = gpio_ack_irq,
        .mask           = gpio_mask_irq,
        .unmask         = gpio_unmask_irq,
@@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void)
                else
                        clk_enable(gpio_ick);
                gpio_fck = clk_get(NULL, "gpios_fck");
-               if (IS_ERR(gpio_ick))
+               if (IS_ERR(gpio_fck))
                        printk("Could not get gpios_fck\n");
                else
                        clk_enable(gpio_fck);
@@ -1144,8 +1165,8 @@ static int omap_gpio_resume(struct sys_device *dev)
                        wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
                        break;
                case METHOD_GPIO_24XX:
-                       wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-                       wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+                       wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
+                       wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
                        break;
                default:
                        continue;
index 196aac3ac329aad9df2eeb5bd4867eec89dd0c03..ade9a0fa6ef678033ff2f17f6dd8446389e7ae21 100644 (file)
@@ -75,8 +75,6 @@ static struct clk *mcbsp1_ick = 0;
 static struct clk *mcbsp1_fck = 0;
 static struct clk *mcbsp2_ick = 0;
 static struct clk *mcbsp2_fck = 0;
-static struct clk *sys_ck = 0;
-static struct clk *sys_clkout = 0;
 #endif
 
 static void omap_mcbsp_dump_reg(u8 id)
@@ -232,7 +230,6 @@ static void omap2_mcbsp2_mux_setup(void)
        omap_cfg_reg(W15_24XX_MCBSP2_DR);
        omap_cfg_reg(V15_24XX_MCBSP2_DX);
        omap_cfg_reg(V14_24XX_GPIO117);
-       omap_cfg_reg(W14_24XX_SYS_CLKOUT);
 }
 #endif
 
@@ -984,13 +981,7 @@ static int __init omap_mcbsp_init(void)
        if (cpu_is_omap24xx()) {
                mcbsp_info = mcbsp_24xx;
                mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
-
-               /* REVISIT: where's the right place? */
                omap2_mcbsp2_mux_setup();
-               sys_ck = clk_get(0, "sys_ck");
-               sys_clkout = clk_get(0, "sys_clkout");
-               clk_set_parent(sys_clkout, sys_ck);
-               clk_enable(sys_clkout);
        }
 #endif
        for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
deleted file mode 100644 (file)
index 04b4102..0000000
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/pm.c
- *
- * OMAP Power Management Routines
- *
- * Original code for the SA11x0:
- * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
- *
- * Modified for the PXA250 by Nicolas Pitre:
- * Copyright (c) 2002 Monta Vista Software, Inc.
- *
- * Modified for the OMAP1510 by David Singleton:
- * Copyright (c) 2002 Monta Vista Software, Inc.
- *
- * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/pm.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/pm.h>
-#include <linux/interrupt.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach/time.h>
-#include <asm/mach/irq.h>
-
-#include <asm/mach-types.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/pm.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/tps65010.h>
-#include <asm/arch/dsp_common.h>
-
-#include <asm/arch/clock.h>
-#include <asm/arch/sram.h>
-
-static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
-static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
-static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
-static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
-static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
-
-static void (*omap_sram_idle)(void) = NULL;
-static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
-
-/*
- * Let's power down on idle, but only if we are really
- * idle, because once we start down the path of
- * going idle we continue to do idle even if we get
- * a clock tick interrupt . .
- */
-void omap_pm_idle(void)
-{
-       unsigned int mask32 = 0;
-
-       /*
-        * If the DSP is being used let's just idle the CPU, the overhead
-        * to wake up from Big Sleep is big, milliseconds versus micro
-        * seconds for wait for interrupt.
-        */
-
-       local_irq_disable();
-       local_fiq_disable();
-       if (need_resched()) {
-               local_fiq_enable();
-               local_irq_enable();
-               return;
-       }
-       mask32 = omap_readl(ARM_SYSST);
-
-       /*
-        * Prevent the ULPD from entering low power state by setting
-        * POWER_CTRL_REG:4 = 0
-        */
-       omap_writew(omap_readw(ULPD_POWER_CTRL) &
-                   ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL);
-
-       /*
-        * Since an interrupt may set up a timer, we don't want to
-        * reprogram the hardware timer with interrupts enabled.
-        * Re-enable interrupts only after returning from idle.
-        */
-       timer_dyn_reprogram();
-
-       if ((mask32 & DSP_IDLE) == 0) {
-               __asm__ volatile ("mcr  p15, 0, r0, c7, c0, 4");
-       } else
-               omap_sram_idle();
-
-       local_fiq_enable();
-       local_irq_enable();
-}
-
-/*
- * Configuration of the wakeup event is board specific. For the
- * moment we put it into this helper function. Later it may move
- * to board specific files.
- */
-static void omap_pm_wakeup_setup(void)
-{
-       u32 level1_wake = 0;
-       u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
-
-       /*
-        * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
-        * and the L2 wakeup interrupts: keypad and UART2. Note that the
-        * drivers must still separately call omap_set_gpio_wakeup() to
-        * wake up to a GPIO interrupt.
-        */
-       if (cpu_is_omap730())
-               level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
-                       OMAP_IRQ_BIT(INT_730_IH2_IRQ);
-       else if (cpu_is_omap1510())
-               level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
-                       OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
-       else if (cpu_is_omap16xx())
-               level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
-                       OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
-
-       omap_writel(~level1_wake, OMAP_IH1_MIR);
-
-       if (cpu_is_omap730()) {
-               omap_writel(~level2_wake, OMAP_IH2_0_MIR);
-               omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
-       } else if (cpu_is_omap1510()) {
-               level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
-               omap_writel(~level2_wake,  OMAP_IH2_MIR);
-       } else if (cpu_is_omap16xx()) {
-               level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
-               omap_writel(~level2_wake, OMAP_IH2_0_MIR);
-
-               /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
-               omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
-               omap_writel(~0x0, OMAP_IH2_2_MIR);
-               omap_writel(~0x0, OMAP_IH2_3_MIR);
-       }
-
-       /*  New IRQ agreement, recalculate in cascade order */
-       omap_writel(1, OMAP_IH2_CONTROL);
-       omap_writel(1, OMAP_IH1_CONTROL);
-}
-
-void omap_pm_suspend(void)
-{
-       unsigned long arg0 = 0, arg1 = 0;
-
-       printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
-
-       omap_serial_wake_trigger(1);
-
-       if (machine_is_omap_osk()) {
-               /* Stop LED1 (D9) blink */
-               tps65010_set_led(LED1, OFF);
-       }
-
-       omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
-
-       /*
-        * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
-        */
-
-       local_irq_disable();
-       local_fiq_disable();
-
-       /*
-        * Step 2: save registers
-        *
-        * The omap is a strange/beautiful device. The caches, memory
-        * and register state are preserved across power saves.
-        * We have to save and restore very little register state to
-        * idle the omap.
-         *
-        * Save interrupt, MPUI, ARM and UPLD control registers.
-        */
-
-       if (cpu_is_omap730()) {
-               MPUI730_SAVE(OMAP_IH1_MIR);
-               MPUI730_SAVE(OMAP_IH2_0_MIR);
-               MPUI730_SAVE(OMAP_IH2_1_MIR);
-               MPUI730_SAVE(MPUI_CTRL);
-               MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI730_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI730_SAVE(EMIFS_CONFIG);
-               MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
-
-       } else if (cpu_is_omap1510()) {
-               MPUI1510_SAVE(OMAP_IH1_MIR);
-               MPUI1510_SAVE(OMAP_IH2_MIR);
-               MPUI1510_SAVE(MPUI_CTRL);
-               MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI1510_SAVE(EMIFS_CONFIG);
-               MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
-       } else if (cpu_is_omap16xx()) {
-               MPUI1610_SAVE(OMAP_IH1_MIR);
-               MPUI1610_SAVE(OMAP_IH2_0_MIR);
-               MPUI1610_SAVE(OMAP_IH2_1_MIR);
-               MPUI1610_SAVE(OMAP_IH2_2_MIR);
-               MPUI1610_SAVE(OMAP_IH2_3_MIR);
-               MPUI1610_SAVE(MPUI_CTRL);
-               MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI1610_SAVE(EMIFS_CONFIG);
-               MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
-       }
-
-       ARM_SAVE(ARM_CKCTL);
-       ARM_SAVE(ARM_IDLECT1);
-       ARM_SAVE(ARM_IDLECT2);
-       if (!(cpu_is_omap1510()))
-               ARM_SAVE(ARM_IDLECT3);
-       ARM_SAVE(ARM_EWUPCT);
-       ARM_SAVE(ARM_RSTCT1);
-       ARM_SAVE(ARM_RSTCT2);
-       ARM_SAVE(ARM_SYSST);
-       ULPD_SAVE(ULPD_CLOCK_CTRL);
-       ULPD_SAVE(ULPD_STATUS_REQ);
-
-       /* (Step 3 removed - we now allow deep sleep by default) */
-
-       /*
-        * Step 4: OMAP DSP Shutdown
-        */
-
-
-       /*
-        * Step 5: Wakeup Event Setup
-        */
-
-       omap_pm_wakeup_setup();
-
-       /*
-        * Step 6: ARM and Traffic controller shutdown
-        */
-
-       /* disable ARM watchdog */
-       omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
-       omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
-
-       /*
-        * Step 6b: ARM and Traffic controller shutdown
-        *
-        * Step 6 continues here. Prepare jump to power management
-        * assembly code in internal SRAM.
-        *
-        * Since the omap_cpu_suspend routine has been copied to
-        * SRAM, we'll do an indirect procedure call to it and pass the
-        * contents of arm_idlect1 and arm_idlect2 so it can restore
-        * them when it wakes up and it will return.
-        */
-
-       arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
-       arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
-
-       /*
-        * Step 6c: ARM and Traffic controller shutdown
-        *
-        * Jump to assembly code. The processor will stay there
-        * until wake up.
-        */
-        omap_sram_suspend(arg0, arg1);
-
-       /*
-        * If we are here, processor is woken up!
-        */
-
-       /*
-        * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
-        */
-
-       if (!(cpu_is_omap1510()))
-               ARM_RESTORE(ARM_IDLECT3);
-       ARM_RESTORE(ARM_CKCTL);
-       ARM_RESTORE(ARM_EWUPCT);
-       ARM_RESTORE(ARM_RSTCT1);
-       ARM_RESTORE(ARM_RSTCT2);
-       ARM_RESTORE(ARM_SYSST);
-       ULPD_RESTORE(ULPD_CLOCK_CTRL);
-       ULPD_RESTORE(ULPD_STATUS_REQ);
-
-       if (cpu_is_omap730()) {
-               MPUI730_RESTORE(EMIFS_CONFIG);
-               MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
-               MPUI730_RESTORE(OMAP_IH1_MIR);
-               MPUI730_RESTORE(OMAP_IH2_0_MIR);
-               MPUI730_RESTORE(OMAP_IH2_1_MIR);
-       } else if (cpu_is_omap1510()) {
-               MPUI1510_RESTORE(MPUI_CTRL);
-               MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
-               MPUI1510_RESTORE(EMIFS_CONFIG);
-               MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
-               MPUI1510_RESTORE(OMAP_IH1_MIR);
-               MPUI1510_RESTORE(OMAP_IH2_MIR);
-       } else if (cpu_is_omap16xx()) {
-               MPUI1610_RESTORE(MPUI_CTRL);
-               MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
-               MPUI1610_RESTORE(EMIFS_CONFIG);
-               MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
-
-               MPUI1610_RESTORE(OMAP_IH1_MIR);
-               MPUI1610_RESTORE(OMAP_IH2_0_MIR);
-               MPUI1610_RESTORE(OMAP_IH2_1_MIR);
-               MPUI1610_RESTORE(OMAP_IH2_2_MIR);
-               MPUI1610_RESTORE(OMAP_IH2_3_MIR);
-       }
-
-       omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
-
-       /*
-        * Reenable interrupts
-        */
-
-       local_irq_enable();
-       local_fiq_enable();
-
-       omap_serial_wake_trigger(0);
-
-       printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
-
-       if (machine_is_omap_osk()) {
-               /* Let LED1 (D9) blink again */
-               tps65010_set_led(LED1, BLINK);
-       }
-}
-
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-static int g_read_completed;
-
-/*
- * Read system PM registers for debugging
- */
-static int omap_pm_read_proc(
-       char *page_buffer,
-       char **my_first_byte,
-       off_t virtual_start,
-       int length,
-       int *eof,
-       void *data)
-{
-       int my_buffer_offset = 0;
-       char * const my_base = page_buffer;
-
-       ARM_SAVE(ARM_CKCTL);
-       ARM_SAVE(ARM_IDLECT1);
-       ARM_SAVE(ARM_IDLECT2);
-       if (!(cpu_is_omap1510()))
-               ARM_SAVE(ARM_IDLECT3);
-       ARM_SAVE(ARM_EWUPCT);
-       ARM_SAVE(ARM_RSTCT1);
-       ARM_SAVE(ARM_RSTCT2);
-       ARM_SAVE(ARM_SYSST);
-
-       ULPD_SAVE(ULPD_IT_STATUS);
-       ULPD_SAVE(ULPD_CLOCK_CTRL);
-       ULPD_SAVE(ULPD_SOFT_REQ);
-       ULPD_SAVE(ULPD_STATUS_REQ);
-       ULPD_SAVE(ULPD_DPLL_CTRL);
-       ULPD_SAVE(ULPD_POWER_CTRL);
-
-       if (cpu_is_omap730()) {
-               MPUI730_SAVE(MPUI_CTRL);
-               MPUI730_SAVE(MPUI_DSP_STATUS);
-               MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI730_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
-               MPUI730_SAVE(EMIFS_CONFIG);
-       } else if (cpu_is_omap1510()) {
-               MPUI1510_SAVE(MPUI_CTRL);
-               MPUI1510_SAVE(MPUI_DSP_STATUS);
-               MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
-               MPUI1510_SAVE(EMIFS_CONFIG);
-       } else if (cpu_is_omap16xx()) {
-               MPUI1610_SAVE(MPUI_CTRL);
-               MPUI1610_SAVE(MPUI_DSP_STATUS);
-               MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
-               MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
-               MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
-               MPUI1610_SAVE(EMIFS_CONFIG);
-       }
-
-       if (virtual_start == 0) {
-               g_read_completed = 0;
-
-               my_buffer_offset += sprintf(my_base + my_buffer_offset,
-                  "ARM_CKCTL_REG:            0x%-8x     \n"
-                  "ARM_IDLECT1_REG:          0x%-8x     \n"
-                  "ARM_IDLECT2_REG:          0x%-8x     \n"
-                  "ARM_IDLECT3_REG:          0x%-8x     \n"
-                  "ARM_EWUPCT_REG:           0x%-8x     \n"
-                  "ARM_RSTCT1_REG:           0x%-8x     \n"
-                  "ARM_RSTCT2_REG:           0x%-8x     \n"
-                  "ARM_SYSST_REG:            0x%-8x     \n"
-                  "ULPD_IT_STATUS_REG:       0x%-4x     \n"
-                  "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
-                  "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
-                  "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
-                  "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
-                  "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
-                  ARM_SHOW(ARM_CKCTL),
-                  ARM_SHOW(ARM_IDLECT1),
-                  ARM_SHOW(ARM_IDLECT2),
-                  ARM_SHOW(ARM_IDLECT3),
-                  ARM_SHOW(ARM_EWUPCT),
-                  ARM_SHOW(ARM_RSTCT1),
-                  ARM_SHOW(ARM_RSTCT2),
-                  ARM_SHOW(ARM_SYSST),
-                  ULPD_SHOW(ULPD_IT_STATUS),
-                  ULPD_SHOW(ULPD_CLOCK_CTRL),
-                  ULPD_SHOW(ULPD_SOFT_REQ),
-                  ULPD_SHOW(ULPD_DPLL_CTRL),
-                  ULPD_SHOW(ULPD_STATUS_REQ),
-                  ULPD_SHOW(ULPD_POWER_CTRL));
-
-               if (cpu_is_omap730()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
-                          "MPUI730_CTRL_REG         0x%-8x \n"
-                          "MPUI730_DSP_STATUS_REG:      0x%-8x \n"
-                          "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-        "MPUI730_DSP_API_CONFIG_REG:  0x%-8x \n"
-        "MPUI730_SDRAM_CONFIG_REG:    0x%-8x \n"
-        "MPUI730_EMIFS_CONFIG_REG:    0x%-8x \n",
-        MPUI730_SHOW(MPUI_CTRL),
-        MPUI730_SHOW(MPUI_DSP_STATUS),
-        MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
-        MPUI730_SHOW(MPUI_DSP_API_CONFIG),
-        MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
-        MPUI730_SHOW(EMIFS_CONFIG));
-               } else if (cpu_is_omap1510()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
-                          "MPUI1510_CTRL_REG             0x%-8x \n"
-                          "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
-                          "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-                          "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
-                          "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
-                          "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
-                          MPUI1510_SHOW(MPUI_CTRL),
-                          MPUI1510_SHOW(MPUI_DSP_STATUS),
-                          MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
-                          MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
-                          MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
-                          MPUI1510_SHOW(EMIFS_CONFIG));
-               } else if (cpu_is_omap16xx()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
-                          "MPUI1610_CTRL_REG             0x%-8x \n"
-                          "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
-                          "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-                          "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
-                          "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
-                          "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
-                          MPUI1610_SHOW(MPUI_CTRL),
-                          MPUI1610_SHOW(MPUI_DSP_STATUS),
-                          MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
-                          MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
-                          MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
-                          MPUI1610_SHOW(EMIFS_CONFIG));
-               }
-
-               g_read_completed++;
-       } else if (g_read_completed >= 1) {
-                *eof = 1;
-                return 0;
-       }
-       g_read_completed++;
-
-       *my_first_byte = page_buffer;
-       return  my_buffer_offset;
-}
-
-static void omap_pm_init_proc(void)
-{
-       struct proc_dir_entry *entry;
-
-       entry = create_proc_read_entry("driver/omap_pm",
-                                      S_IWUSR | S_IRUGO, NULL,
-          omap_pm_read_proc, NULL);
-}
-
-#endif /* DEBUG && CONFIG_PROC_FS */
-
-/*
- *     omap_pm_prepare - Do preliminary suspend work.
- *     @state:         suspend state we're entering.
- *
- */
-//#include <asm/hardware.h>
-
-static int omap_pm_prepare(suspend_state_t state)
-{
-       int error = 0;
-
-       switch (state)
-       {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               break;
-
-       case PM_SUSPEND_DISK:
-               return -ENOTSUPP;
-
-       default:
-               return -EINVAL;
-       }
-
-       return error;
-}
-
-
-/*
- *     omap_pm_enter - Actually enter a sleep state.
- *     @state:         State we're entering.
- *
- */
-
-static int omap_pm_enter(suspend_state_t state)
-{
-       switch (state)
-       {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               omap_pm_suspend();
-               break;
-
-       case PM_SUSPEND_DISK:
-               return -ENOTSUPP;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-/**
- *     omap_pm_finish - Finish up suspend sequence.
- *     @state:         State we're coming out of.
- *
- *     This is called after we wake back up (or if entering the sleep state
- *     failed).
- */
-
-static int omap_pm_finish(suspend_state_t state)
-{
-       return 0;
-}
-
-
-static irqreturn_t  omap_wakeup_interrupt(int  irq, void *  dev,
-                                    struct pt_regs *  regs)
-{
-       return IRQ_HANDLED;
-}
-
-static struct irqaction omap_wakeup_irq = {
-       .name           = "peripheral wakeup",
-       .flags          = IRQF_DISABLED,
-       .handler        = omap_wakeup_interrupt
-};
-
-
-
-static struct pm_ops omap_pm_ops ={
-       .pm_disk_mode = 0,
-        .prepare        = omap_pm_prepare,
-        .enter          = omap_pm_enter,
-        .finish         = omap_pm_finish,
-};
-
-static int __init omap_pm_init(void)
-{
-       printk("Power Management for TI OMAP.\n");
-       /*
-        * We copy the assembler sleep/wakeup routines to SRAM.
-        * These routines need to be in SRAM as that's the only
-        * memory the MPU can see when it wakes up.
-        */
-       if (cpu_is_omap730()) {
-               omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
-                                               omap730_idle_loop_suspend_sz);
-               omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
-        omap730_cpu_suspend_sz);
-       } else if (cpu_is_omap1510()) {
-               omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
-                                               omap1510_idle_loop_suspend_sz);
-               omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
-                                                  omap1510_cpu_suspend_sz);
-       } else if (cpu_is_omap16xx()) {
-               omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
-                                               omap1610_idle_loop_suspend_sz);
-               omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
-                                                  omap1610_cpu_suspend_sz);
-       }
-
-       if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
-               printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
-               return -ENODEV;
-       }
-
-       pm_idle = omap_pm_idle;
-
-       if (cpu_is_omap730())
-               setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
-       else if (cpu_is_omap16xx())
-               setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
-
-#if 0
-       /* --- BEGIN BOARD-DEPENDENT CODE --- */
-       /* Sleepx mask direction */
-       omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
-       /* Unmask sleepx signal */
-       omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
-       /* --- END BOARD-DEPENDENT CODE --- */
-#endif
-
-       /* Program new power ramp-up time
-        * (0 for most boards since we don't lower voltage when in deep sleep)
-        */
-       omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
-
-       /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
-       omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
-
-       /* Configure IDLECT3 */
-       if (cpu_is_omap730())
-               omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
-       else if (cpu_is_omap16xx())
-               omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
-
-       pm_set_ops(&omap_pm_ops);
-
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-       omap_pm_init_proc();
-#endif
-
-       if (cpu_is_omap16xx()) {
-               /* configure LOW_PWR pin */
-               omap_cfg_reg(T20_1610_LOW_PWR);
-       }
-
-       return 0;
-}
-__initcall(omap_pm_init);
-
index e75718301b0f460bc59ea9912905a5c0a34c6dc8..19014b2ff4c6315a6e190c3c2c03e17c33eb184b 100644 (file)
@@ -174,10 +174,7 @@ void __init omap_map_sram(void)
        if (cpu_is_omap24xx()) {
                omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
 
-               if (is_sram_locked())
-                       base = OMAP2_SRAM_PUB_PA;
-               else
-                       base = OMAP2_SRAM_PA;
+               base = OMAP2_SRAM_PA;
                base = ROUND_DOWN(base, PAGE_SIZE);
                omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
        }
index 281ecc7fcdfcc995e90fe94f3e9c1b2b345ed2e1..cf6df3378d3786d3bcaa2876f770b70db46cc6ca 100644 (file)
@@ -105,6 +105,8 @@ static inline unsigned long omap_32k_timer_read(int reg)
 
 static inline void omap_32k_timer_start(unsigned long load_val)
 {
+       if (!load_val)
+               load_val = 1;
        omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
        omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
 }
@@ -192,14 +194,11 @@ unsigned long long sched_clock(void)
  * issues with dynamic tick. In the dynamic tick case, we need to lock
  * with irqsave.
  */
-static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
-                                           struct pt_regs *regs)
+static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
+                                       struct pt_regs *regs)
 {
-       unsigned long flags;
        unsigned long now;
 
-       write_seqlock_irqsave(&xtime_lock, flags);
-
        omap_32k_timer_ack_irq();
        now = omap_32k_sync_timer_read();
 
@@ -215,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
         * continuous timer can be overridden from pm_idle to be longer.
         */
        omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id,
+                                       struct pt_regs *regs)
+{
+       return _omap_32k_timer_interrupt(irq, dev_id, regs);
+}
+
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
+                                           struct pt_regs *regs)
+{
+       unsigned long flags;
+
+       write_seqlock_irqsave(&xtime_lock, flags);
+       _omap_32k_timer_interrupt(irq, dev_id, regs);
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
        return IRQ_HANDLED;
@@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
  */
 void omap_32k_timer_reprogram(unsigned long next_tick)
 {
-       omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
+       unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1;
+       unsigned long now = omap_32k_sync_timer_read();
+       unsigned long idled = now - omap_32k_last_tick;
+
+       if (idled + 1 < ticks)
+               ticks -= idled;
+       else
+               ticks = 1;
+       omap_32k_timer_start(ticks);
 }
 
 static struct irqaction omap_32k_timer_irq;
@@ -252,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = {
        .enable         = omap_32k_timer_enable_dyn_tick,
        .disable        = omap_32k_timer_disable_dyn_tick,
        .reprogram      = omap_32k_timer_reprogram,
-       .handler        = omap_32k_timer_interrupt,
+       .handler        = omap_32k_timer_handler,
 };
 #endif /* CONFIG_NO_IDLE_HZ */
 
index e1372a25311d0ab1ec7f0996b64deb1278afc737..b02af1d740fab56b1f28c7525f7ac97f3006829f 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon Jun 26 22:26:08 2006
+# Last update: Sat Sep 23 13:20:43 2006
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -329,7 +329,7 @@ nimbra29x           ARCH_NIMBRA29X          NIMBRA29X               311
 nimbra210              ARCH_NIMBRA210          NIMBRA210               312
 hhp_d95xx              ARCH_HHP_D95XX          HHP_D95XX               313
 labarm                 ARCH_LABARM             LABARM                  314
-comcerto               ARCH_M825XX             M825XX                  315
+m825xx                 ARCH_M825XX             M825XX                  315
 m7100                  SA1100_M7100            M7100                   316
 nipc2                  ARCH_NIPC2              NIPC2                   317
 fu7202                 ARCH_FU7202             FU7202                  318
@@ -857,12 +857,12 @@ osiris                    MACH_OSIRIS             OSIRIS                  842
 maestro                        MACH_MAESTRO            MAESTRO                 843
 tunge2                 MACH_TUNGE2             TUNGE2                  844
 ixbbm                  MACH_IXBBM              IXBBM                   845
-mx27ads                        MACH_MX27               MX27                    846
+mx27ads                        MACH_MX27ADS            MX27ADS                 846
 ax8004                 MACH_AX8004             AX8004                  847
 at91sam9261ek          MACH_AT91SAM9261EK      AT91SAM9261EK           848
 loft                   MACH_LOFT               LOFT                    849
 magpie                 MACH_MAGPIE             MAGPIE                  850
-mx21ads                        MACH_MX21               MX21                    851
+mx21ads                        MACH_MX21ADS            MX21ADS                 851
 mb87m3400              MACH_MB87M3400          MB87M3400               852
 mguard_delta           MACH_MGUARD_DELTA       MGUARD_DELTA            853
 davinci_dvdp           MACH_DAVINCI_DVDP       DAVINCI_DVDP            854
@@ -1058,7 +1058,7 @@ akai9307          MACH_AKAI9307           AKAI9307                1044
 fontaine               MACH_FONTAINE           FONTAINE                1045
 wombat                 MACH_WOMBAT             WOMBAT                  1046
 acq300                 MACH_ACQ300             ACQ300                  1047
-mod_270                        MACH_MOD_270            MOD_270                 1048
+mod272                 MACH_MOD_270            MOD_270                 1048
 vmc_vc0820             MACH_VC0820             VC0820                  1049
 ani_aim                        MACH_ANI_AIM            ANI_AIM                 1050
 jellyfish              MACH_JELLYFISH          JELLYFISH               1051
@@ -1093,3 +1093,67 @@ msm6100                  MACH_MSM6100            MSM6100                 1079
 eti_b1                 MACH_ETI_B1             ETI_B1                  1080
 za9l_series            MACH_ZILOG_ZA9L         ZILOG_ZA9L              1081
 bit2440                        MACH_BIT2440            BIT2440                 1082
+nbi                    MACH_NBI                NBI                     1083
+smdk2443               MACH_SMDK2443           SMDK2443                1084
+vdavinci               MACH_VDAVINCI           VDAVINCI                1085
+atc6                   MACH_ATC6               ATC6                    1086
+multmdw                        MACH_MULTMDW            MULTMDW                 1087
+mba2440                        MACH_MBA2440            MBA2440                 1088
+ecsd                   MACH_ECSD               ECSD                    1089
+zire31                 MACH_ZIRE31             ZIRE31                  1090
+fsg                    MACH_FSG                FSG                     1091
+razor101               MACH_RAZOR101           RAZOR101                1092
+opera_tdm              MACH_OPERA_TDM          OPERA_TDM               1093
+comcerto               MACH_COMCERTO           COMCERTO                1094
+tb0319                 MACH_TB0319             TB0319                  1095
+kws8000                        MACH_KWS8000            KWS8000                 1096
+b2                     MACH_B2                 B2                      1097
+lcl54                  MACH_LCL54              LCL54                   1098
+at91sam9260ek          MACH_AT91SAM9260EK      AT91SAM9260EK           1099
+glantank               MACH_GLANTANK           GLANTANK                1100
+n2100                  MACH_N2100              N2100                   1101
+n4100                  MACH_N4100              N4100                   1102
+rsc4                   MACH_VERTICAL_RSC4      VERTICAL_RSC4           1103
+sg8100                 MACH_SG8100             SG8100                  1104
+im42xx                 MACH_IM42XX             IM42XX                  1105
+ftxx                   MACH_FTXX               FTXX                    1106
+lwfusion               MACH_LWFUSION           LWFUSION                1107
+qt2410                 MACH_QT2410             QT2410                  1108
+kixrp435               MACH_KIXRP435           KIXRP435                1109
+ccw9c                  MACH_CCW9C              CCW9C                   1110
+dabhs                  MACH_DABHS              DABHS                   1111
+gzmx                   MACH_GZMX               GZMX                    1112
+ipnw100ap              MACH_IPNW100AP          IPNW100AP               1113
+cc9p9360dev            MACH_CC9P9360DEV        CC9P9360DEV             1114
+cc9p9750dev            MACH_CC9P9750DEV        CC9P9750DEV             1115
+cc9p9360val            MACH_CC9P9360VAL        CC9P9360VAL             1116
+cc9p9750val            MACH_CC9P9750VAL        CC9P9750VAL             1117
+nx70v                  MACH_NX70V              NX70V                   1118
+at91rm9200df           MACH_AT91RM9200DF       AT91RM9200DF            1119
+se_pilot2              MACH_SE_PILOT2          SE_PILOT2               1120
+mtcn_t800              MACH_MTCN_T800          MTCN_T800               1121
+vcmx212                        MACH_VCMX212            VCMX212                 1122
+lynx                   MACH_LYNX               LYNX                    1123
+at91sam9260id          MACH_AT91SAM9260ID      AT91SAM9260ID           1124
+hw86052                        MACH_HW86052            HW86052                 1125
+pilz_pmi3              MACH_PILZ_PMI3          PILZ_PMI3               1126
+edb9302a               MACH_EDB9302A           EDB9302A                1127
+edb9307a               MACH_EDB9307A           EDB9307A                1128
+ct_dfs                 MACH_CT_DFS             CT_DFS                  1129
+pilz_pmi4              MACH_PILZ_PMI4          PILZ_PMI4               1130
+xceednp_ixp            MACH_XCEEDNP_IXP        XCEEDNP_IXP             1131
+smdk2442b              MACH_SMDK2442B          SMDK2442B               1132
+xnode                  MACH_XNODE              XNODE                   1133
+aidx270                        MACH_AIDX270            AIDX270                 1134
+rema                   MACH_REMA               REMA                    1135
+bps1000                        MACH_BPS1000            BPS1000                 1136
+hw90350                        MACH_HW90350            HW90350                 1137
+omap_sdp3430           MACH_OMAP_SDP3430       OMAP_SDP3430            1138
+bluetouch              MACH_BLUETOUCH          BLUETOUCH               1139
+vstms                  MACH_VSTMS              VSTMS                   1140
+xsbase270              MACH_XSBASE270          XSBASE270               1141
+at91sam9260ek_cn       MACH_AT91SAM9260EK_CN   AT91SAM9260EK_CN        1142
+adsturboxb             MACH_ADSTURBOXB         ADSTURBOXB              1143
+oti4110                        MACH_OTI4110            OTI4110                 1144
+hme_pxa                        MACH_HME_PXA            HME_PXA                 1145
+deisterdca             MACH_DEISTERDCA         DEISTERDCA              1146
index 96fdf30f6a3bb2098a39c5907ea89cd983a95b90..f2797896e6d5dbcc488f5c9b0be9f1ce497d7843 100644 (file)
@@ -355,3 +355,18 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand);
  * we check for an error.
  */
 #define VFP_EXCEPTION_ERROR    ((u32)-1 & ~VFP_NAN_FLAG)
+
+/*
+ * A flag to tell vfp instruction type.
+ *  OP_SCALAR - this operation always operates in scalar mode
+ *  OP_SD - the instruction exceptionally writes to a single precision result.
+ *  OP_DD - the instruction exceptionally writes to a double precision result.
+ */
+#define OP_SCALAR      (1 << 0)
+#define OP_SD          (1 << 1)
+#define OP_DD          (1 << 1)
+
+struct op {
+       u32 (* const fn)(int dd, int dn, int dm, u32 fpscr);
+       u32 flags;
+};
index add48e36c2dc2e36ead54cb031e2f6bd84cf3460..4fc05ee0a2ef3c5b04db9d81993b450892b33660 100644 (file)
@@ -659,22 +659,22 @@ static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr)
 }
 
 
-static u32 (* const fop_extfns[32])(int dd, int unused, int dm, u32 fpscr) = {
-       [FEXT_TO_IDX(FEXT_FCPY)]        = vfp_double_fcpy,
-       [FEXT_TO_IDX(FEXT_FABS)]        = vfp_double_fabs,
-       [FEXT_TO_IDX(FEXT_FNEG)]        = vfp_double_fneg,
-       [FEXT_TO_IDX(FEXT_FSQRT)]       = vfp_double_fsqrt,
-       [FEXT_TO_IDX(FEXT_FCMP)]        = vfp_double_fcmp,
-       [FEXT_TO_IDX(FEXT_FCMPE)]       = vfp_double_fcmpe,
-       [FEXT_TO_IDX(FEXT_FCMPZ)]       = vfp_double_fcmpz,
-       [FEXT_TO_IDX(FEXT_FCMPEZ)]      = vfp_double_fcmpez,
-       [FEXT_TO_IDX(FEXT_FCVT)]        = vfp_double_fcvts,
-       [FEXT_TO_IDX(FEXT_FUITO)]       = vfp_double_fuito,
-       [FEXT_TO_IDX(FEXT_FSITO)]       = vfp_double_fsito,
-       [FEXT_TO_IDX(FEXT_FTOUI)]       = vfp_double_ftoui,
-       [FEXT_TO_IDX(FEXT_FTOUIZ)]      = vfp_double_ftouiz,
-       [FEXT_TO_IDX(FEXT_FTOSI)]       = vfp_double_ftosi,
-       [FEXT_TO_IDX(FEXT_FTOSIZ)]      = vfp_double_ftosiz,
+static struct op fops_ext[32] = {
+       [FEXT_TO_IDX(FEXT_FCPY)]        = { vfp_double_fcpy,   0 },
+       [FEXT_TO_IDX(FEXT_FABS)]        = { vfp_double_fabs,   0 },
+       [FEXT_TO_IDX(FEXT_FNEG)]        = { vfp_double_fneg,   0 },
+       [FEXT_TO_IDX(FEXT_FSQRT)]       = { vfp_double_fsqrt,  0 },
+       [FEXT_TO_IDX(FEXT_FCMP)]        = { vfp_double_fcmp,   OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPE)]       = { vfp_double_fcmpe,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPZ)]       = { vfp_double_fcmpz,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPEZ)]      = { vfp_double_fcmpez, OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCVT)]        = { vfp_double_fcvts,  OP_SCALAR|OP_SD },
+       [FEXT_TO_IDX(FEXT_FUITO)]       = { vfp_double_fuito,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FSITO)]       = { vfp_double_fsito,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FTOUI)]       = { vfp_double_ftoui,  OP_SCALAR|OP_SD },
+       [FEXT_TO_IDX(FEXT_FTOUIZ)]      = { vfp_double_ftouiz, OP_SCALAR|OP_SD },
+       [FEXT_TO_IDX(FEXT_FTOSI)]       = { vfp_double_ftosi,  OP_SCALAR|OP_SD },
+       [FEXT_TO_IDX(FEXT_FTOSIZ)]      = { vfp_double_ftosiz, OP_SCALAR|OP_SD },
 };
 
 
@@ -1108,16 +1108,16 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr)
        return FPSCR_IOC;
 }
 
-static u32 (* const fop_fns[16])(int dd, int dn, int dm, u32 fpscr) = {
-       [FOP_TO_IDX(FOP_FMAC)]  = vfp_double_fmac,
-       [FOP_TO_IDX(FOP_FNMAC)] = vfp_double_fnmac,
-       [FOP_TO_IDX(FOP_FMSC)]  = vfp_double_fmsc,
-       [FOP_TO_IDX(FOP_FNMSC)] = vfp_double_fnmsc,
-       [FOP_TO_IDX(FOP_FMUL)]  = vfp_double_fmul,
-       [FOP_TO_IDX(FOP_FNMUL)] = vfp_double_fnmul,
-       [FOP_TO_IDX(FOP_FADD)]  = vfp_double_fadd,
-       [FOP_TO_IDX(FOP_FSUB)]  = vfp_double_fsub,
-       [FOP_TO_IDX(FOP_FDIV)]  = vfp_double_fdiv,
+static struct op fops[16] = {
+       [FOP_TO_IDX(FOP_FMAC)]  = { vfp_double_fmac,  0 },
+       [FOP_TO_IDX(FOP_FNMAC)] = { vfp_double_fnmac, 0 },
+       [FOP_TO_IDX(FOP_FMSC)]  = { vfp_double_fmsc,  0 },
+       [FOP_TO_IDX(FOP_FNMSC)] = { vfp_double_fnmsc, 0 },
+       [FOP_TO_IDX(FOP_FMUL)]  = { vfp_double_fmul,  0 },
+       [FOP_TO_IDX(FOP_FNMUL)] = { vfp_double_fnmul, 0 },
+       [FOP_TO_IDX(FOP_FADD)]  = { vfp_double_fadd,  0 },
+       [FOP_TO_IDX(FOP_FSUB)]  = { vfp_double_fsub,  0 },
+       [FOP_TO_IDX(FOP_FDIV)]  = { vfp_double_fdiv,  0 },
 };
 
 #define FREG_BANK(x)   ((x) & 0x0c)
@@ -1131,69 +1131,60 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
        unsigned int dn = vfp_get_dn(inst);
        unsigned int dm = vfp_get_dm(inst);
        unsigned int vecitr, veclen, vecstride;
-       u32 (*fop)(int, int, s32, u32);
+       struct op *fop;
 
-       veclen = fpscr & FPSCR_LENGTH_MASK;
        vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
 
+       fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
+
        /*
         * fcvtds takes an sN register number as destination, not dN.
         * It also always operates on scalars.
         */
-       if ((inst & FEXT_MASK) == FEXT_FCVT) {
-               veclen = 0;
+       if (fop->flags & OP_SD)
                dest = vfp_get_sd(inst);
-       else
+       else
                dest = vfp_get_dd(inst);
 
        /*
         * If destination bank is zero, vector length is always '1'.
         * ARM DDI0100F C5.1.3, C5.3.2.
         */
-       if (FREG_BANK(dest) == 0)
+       if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0))
                veclen = 0;
+       else
+               veclen = fpscr & FPSCR_LENGTH_MASK;
 
        pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
                 (veclen >> FPSCR_LENGTH_BIT) + 1);
 
-       fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
-       if (!fop)
+       if (!fop->fn)
                goto invalid;
 
        for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
                u32 except;
+               char type;
 
-               if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
-                       pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n",
-                                vecitr >> FPSCR_LENGTH_BIT,
-                                dest, dn, dm);
-               else if (op == FOP_EXT)
-                       pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
+               type = fop->flags & OP_SD ? 's' : 'd';
+               if (op == FOP_EXT)
+                       pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n",
                                 vecitr >> FPSCR_LENGTH_BIT,
-                                dest, dn, dm);
+                                type, dest, dn, dm);
                else
-                       pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
+                       pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n",
                                 vecitr >> FPSCR_LENGTH_BIT,
-                                dest, dn, FOP_TO_IDX(op), dm);
+                                type, dest, dn, FOP_TO_IDX(op), dm);
 
-               except = fop(dest, dn, dm, fpscr);
+               except = fop->fn(dest, dn, dm, fpscr);
                pr_debug("VFP: itr%d: exceptions=%08x\n",
                         vecitr >> FPSCR_LENGTH_BIT, except);
 
                exceptions |= except;
 
-               /*
-                * This ensures that comparisons only operate on scalars;
-                * comparisons always return with one FPSCR status bit set.
-                */
-               if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
-                       break;
-
                /*
                 * CHECK: It appears to be undefined whether we stop when
                 * we encounter an exception.  We continue.
                 */
-
                dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
                dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
                if (FREG_BANK(dm) != 0)
index 6c819aeae00631cdd2a12f56320da38b9d5189e4..7f343a4beca0542151e1a57f1f2c3612159daa14 100644 (file)
 
 #define fmrx(_vfp_) ({                 \
        u32 __v;                        \
-       asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_    \
-           : "=r" (__v));              \
+       asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx   %0, " #_vfp_    \
+           : "=r" (__v) : : "cc");     \
        __v;                            \
  })
 
 #define fmxr(_vfp_,_var_)              \
-       asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \
-          : : "r" (_var_))
+       asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr   " #_vfp_ ", %0" \
+          : : "r" (_var_) : "cc")
 
 u32 vfp_single_cpdo(u32 inst, u32 fpscr);
 u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs);
index 4178f6cc3d3714deec92f88f4480838b0450c447..dedbb449632edc1f65a40d39e06650df14831a98 100644 (file)
@@ -40,10 +40,19 @@ unsigned int VFP_arch;
 static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
 {
        struct thread_info *thread = v;
-       union vfp_state *vfp = &thread->vfpstate;
+       union vfp_state *vfp;
 
-       switch (cmd) {
-       case THREAD_NOTIFY_FLUSH:
+       if (likely(cmd == THREAD_NOTIFY_SWITCH)) {
+               /*
+                * Always disable VFP so we can lazily save/restore the
+                * old state.
+                */
+               fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
+               return NOTIFY_DONE;
+       }
+
+       vfp = &thread->vfpstate;
+       if (cmd == THREAD_NOTIFY_FLUSH) {
                /*
                 * Per-thread VFP initialisation.
                 */
@@ -56,29 +65,12 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
                 * Disable VFP to ensure we initialise it first.
                 */
                fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
-
-               /*
-                * FALLTHROUGH: Ensure we don't try to overwrite our newly
-                * initialised state information on the first fault.
-                */
-
-       case THREAD_NOTIFY_RELEASE:
-               /*
-                * Per-thread VFP cleanup.
-                */
-               if (last_VFP_context == vfp)
-                       last_VFP_context = NULL;
-               break;
-
-       case THREAD_NOTIFY_SWITCH:
-               /*
-                * Always disable VFP so we can lazily save/restore the
-                * old state.
-                */
-               fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
-               break;
        }
 
+       /* flush and release case: Per-thread VFP cleanup. */
+       if (last_VFP_context == vfp)
+               last_VFP_context = NULL;
+
        return NOTIFY_DONE;
 }
 
index 8f6c179cafbe54e6b76cb09109bf4ba2d077947b..ab5e9503bae5423132a8a2388bd2ce89ebfd2a47 100644 (file)
@@ -702,22 +702,22 @@ static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr)
        return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO);
 }
 
-static u32 (* const fop_extfns[32])(int sd, int unused, s32 m, u32 fpscr) = {
-       [FEXT_TO_IDX(FEXT_FCPY)]        = vfp_single_fcpy,
-       [FEXT_TO_IDX(FEXT_FABS)]        = vfp_single_fabs,
-       [FEXT_TO_IDX(FEXT_FNEG)]        = vfp_single_fneg,
-       [FEXT_TO_IDX(FEXT_FSQRT)]       = vfp_single_fsqrt,
-       [FEXT_TO_IDX(FEXT_FCMP)]        = vfp_single_fcmp,
-       [FEXT_TO_IDX(FEXT_FCMPE)]       = vfp_single_fcmpe,
-       [FEXT_TO_IDX(FEXT_FCMPZ)]       = vfp_single_fcmpz,
-       [FEXT_TO_IDX(FEXT_FCMPEZ)]      = vfp_single_fcmpez,
-       [FEXT_TO_IDX(FEXT_FCVT)]        = vfp_single_fcvtd,
-       [FEXT_TO_IDX(FEXT_FUITO)]       = vfp_single_fuito,
-       [FEXT_TO_IDX(FEXT_FSITO)]       = vfp_single_fsito,
-       [FEXT_TO_IDX(FEXT_FTOUI)]       = vfp_single_ftoui,
-       [FEXT_TO_IDX(FEXT_FTOUIZ)]      = vfp_single_ftouiz,
-       [FEXT_TO_IDX(FEXT_FTOSI)]       = vfp_single_ftosi,
-       [FEXT_TO_IDX(FEXT_FTOSIZ)]      = vfp_single_ftosiz,
+static struct op fops_ext[32] = {
+       [FEXT_TO_IDX(FEXT_FCPY)]        = { vfp_single_fcpy,   0 },
+       [FEXT_TO_IDX(FEXT_FABS)]        = { vfp_single_fabs,   0 },
+       [FEXT_TO_IDX(FEXT_FNEG)]        = { vfp_single_fneg,   0 },
+       [FEXT_TO_IDX(FEXT_FSQRT)]       = { vfp_single_fsqrt,  0 },
+       [FEXT_TO_IDX(FEXT_FCMP)]        = { vfp_single_fcmp,   OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPE)]       = { vfp_single_fcmpe,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPZ)]       = { vfp_single_fcmpz,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCMPEZ)]      = { vfp_single_fcmpez, OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FCVT)]        = { vfp_single_fcvtd,  OP_SCALAR|OP_DD },
+       [FEXT_TO_IDX(FEXT_FUITO)]       = { vfp_single_fuito,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FSITO)]       = { vfp_single_fsito,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FTOUI)]       = { vfp_single_ftoui,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FTOUIZ)]      = { vfp_single_ftouiz, OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FTOSI)]       = { vfp_single_ftosi,  OP_SCALAR },
+       [FEXT_TO_IDX(FEXT_FTOSIZ)]      = { vfp_single_ftosiz, OP_SCALAR },
 };
 
 
@@ -1151,16 +1151,16 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
        return FPSCR_IOC;
 }
 
-static u32 (* const fop_fns[16])(int sd, int sn, s32 m, u32 fpscr) = {
-       [FOP_TO_IDX(FOP_FMAC)]  = vfp_single_fmac,
-       [FOP_TO_IDX(FOP_FNMAC)] = vfp_single_fnmac,
-       [FOP_TO_IDX(FOP_FMSC)]  = vfp_single_fmsc,
-       [FOP_TO_IDX(FOP_FNMSC)] = vfp_single_fnmsc,
-       [FOP_TO_IDX(FOP_FMUL)]  = vfp_single_fmul,
-       [FOP_TO_IDX(FOP_FNMUL)] = vfp_single_fnmul,
-       [FOP_TO_IDX(FOP_FADD)]  = vfp_single_fadd,
-       [FOP_TO_IDX(FOP_FSUB)]  = vfp_single_fsub,
-       [FOP_TO_IDX(FOP_FDIV)]  = vfp_single_fdiv,
+static struct op fops[16] = {
+       [FOP_TO_IDX(FOP_FMAC)]  = { vfp_single_fmac,  0 },
+       [FOP_TO_IDX(FOP_FNMAC)] = { vfp_single_fnmac, 0 },
+       [FOP_TO_IDX(FOP_FMSC)]  = { vfp_single_fmsc,  0 },
+       [FOP_TO_IDX(FOP_FNMSC)] = { vfp_single_fnmsc, 0 },
+       [FOP_TO_IDX(FOP_FMUL)]  = { vfp_single_fmul,  0 },
+       [FOP_TO_IDX(FOP_FNMUL)] = { vfp_single_fnmul, 0 },
+       [FOP_TO_IDX(FOP_FADD)]  = { vfp_single_fadd,  0 },
+       [FOP_TO_IDX(FOP_FSUB)]  = { vfp_single_fsub,  0 },
+       [FOP_TO_IDX(FOP_FDIV)]  = { vfp_single_fdiv,  0 },
 };
 
 #define FREG_BANK(x)   ((x) & 0x18)
@@ -1174,70 +1174,63 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
        unsigned int sn = vfp_get_sn(inst);
        unsigned int sm = vfp_get_sm(inst);
        unsigned int vecitr, veclen, vecstride;
-       u32 (*fop)(int, int, s32, u32);
+       struct op *fop;
 
-       veclen = fpscr & FPSCR_LENGTH_MASK;
        vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
 
+       fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
+
        /*
         * fcvtsd takes a dN register number as destination, not sN.
         * Technically, if bit 0 of dd is set, this is an invalid
         * instruction.  However, we ignore this for efficiency.
         * It also only operates on scalars.
         */
-       if ((inst & FEXT_MASK) == FEXT_FCVT) {
-               veclen = 0;
+       if (fop->flags & OP_DD)
                dest = vfp_get_dd(inst);
-       else
+       else
                dest = vfp_get_sd(inst);
 
        /*
         * If destination bank is zero, vector length is always '1'.
         * ARM DDI0100F C5.1.3, C5.3.2.
         */
-       if (FREG_BANK(dest) == 0)
+       if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0)
                veclen = 0;
+       else
+               veclen = fpscr & FPSCR_LENGTH_MASK;
 
        pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
                 (veclen >> FPSCR_LENGTH_BIT) + 1);
 
-       fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
-       if (!fop)
+       if (!fop->fn)
                goto invalid;
 
        for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
                s32 m = vfp_get_float(sm);
                u32 except;
+               char type;
 
-               if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
-                       pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n",
-                                vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
-               else if (op == FOP_EXT)
-                       pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n",
-                                vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
+               type = fop->flags & OP_DD ? 'd' : 's';
+               if (op == FOP_EXT)
+                       pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n",
+                                vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
+                                sm, m);
                else
-                       pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n",
-                                vecitr >> FPSCR_LENGTH_BIT, dest, sn,
+                       pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n",
+                                vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
                                 FOP_TO_IDX(op), sm, m);
 
-               except = fop(dest, sn, m, fpscr);
+               except = fop->fn(dest, sn, m, fpscr);
                pr_debug("VFP: itr%d: exceptions=%08x\n",
                         vecitr >> FPSCR_LENGTH_BIT, except);
 
                exceptions |= except;
 
-               /*
-                * This ensures that comparisons only operate on scalars;
-                * comparisons always return with one FPSCR status bit set.
-                */
-               if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
-                       break;
-
                /*
                 * CHECK: It appears to be undefined whether we stop when
                 * we encounter an exception.  We continue.
                 */
-
                dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
                sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
                if (FREG_BANK(sm) != 0)
index db63d75d0715927bda8d6379a63dcdb8dd224822..80adbd005fc51812a8a0bc1701e37513c424f5b0 100644 (file)
@@ -194,7 +194,7 @@ EXPORT_SYMBOL(do_settimeofday);
 
 static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-        do_timer(regs);
+        do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index 761938b56679453d350adb663187b4d9b52399ac..a1f6d8a9cc32919084d14b5cf9181dbceb013ca6 100644 (file)
@@ -155,7 +155,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
         */
 good_area:
        if (READ_FAULT(fsr)) /* read? */
-               mask = VM_READ|VM_EXEC;
+               mask = VM_READ|VM_EXEC|VM_WRITE;
        else
                mask = VM_WRITE;
 
@@ -185,7 +185,7 @@ survive:
        }
 
        fault = -3; /* out of memory */
-       if (tsk->pid != 1)
+       if (!is_init(tsk))
                goto out;
 
        /*
index b0e6b5855a381d2096c9a9b581874be3fd5b634e..3e56b9f4358af4a3728c96ed2815eb033a0fc841 100644 (file)
@@ -148,7 +148,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * Call the generic timer interrupt handler
         */
        write_seqlock(&xtime_lock);
-       do_timer(regs);
+       do_timer(1);
        write_sequnlock(&xtime_lock);
 
        /*
index 9c22b76e129a32a18e49da042a675d23f8756ed2..ebacf1457d914cacae4069c21094639fbc906dd7 100644 (file)
@@ -227,7 +227,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        
        /* call the real timer interrupt handler */
 
-       do_timer(regs);
+       do_timer(1);
        
         cris_do_profile(regs); /* Save profiling information */
 
index 50f3f93293d64d33c8b1183a6971faf68eca0912..be0a01657d4fc88076e120b88264977acd25d2ed 100644 (file)
@@ -219,7 +219,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_HANDLED;
 
        /* call the real timer interrupt handler */
-       do_timer(regs);
+       do_timer(1);
 
        /*
         * If we have an externally synchronized Linux clock, then update
index 3d0284bccb940ba2d62c8c3e9e26f099065ff0b4..7e55884135ed8ee2cf460cd0c03c0f223853256d 100644 (file)
@@ -70,7 +70,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
         */
        write_seqlock(&xtime_lock);
 
-       do_timer(regs);
+       do_timer(1);
        update_process_times(user_mode(regs));
        profile_tick(CPU_PROFILING, regs);
 
index 688a5100604c943c614e5ffeb8fef25ba5c9b2fd..e569d17b4ae6b92b5ceccf554795d6cd83070945 100644 (file)
@@ -41,7 +41,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
        /* may need to kick the hardware timer */
        platform_timer_eoi();
 
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
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 ff9ce4b5eaa86489fec9dc55b272358ece1bf586..b42f2d914af3bb15eada724c854bc92581f47169 100644 (file)
 #include <linux/smp_lock.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/kthread.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -402,8 +403,6 @@ static int                  realmode_power_off = 1;
 #else
 static int                     realmode_power_off;
 #endif
-static int                     exit_kapmd __read_mostly;
-static int                     kapmd_running __read_mostly;
 #ifdef CONFIG_APM_ALLOW_INTS
 static int                     allow_ints = 1;
 #else
@@ -419,6 +418,8 @@ static const struct desc_struct     bad_bios_desc = { 0, 0x00409200 };
 
 static const char              driver_version[] = "1.16ac";    /* no spaces */
 
+static struct task_struct *kapmd_task;
+
 /*
  *     APM event names taken from the APM 1.2 specification. These are
  *     the message codes that the BIOS uses to tell us about events
@@ -1423,7 +1424,7 @@ static void apm_mainloop(void)
        set_current_state(TASK_INTERRUPTIBLE);
        for (;;) {
                schedule_timeout(APM_CHECK_TIMEOUT);
-               if (exit_kapmd)
+               if (kthread_should_stop())
                        break;
                /*
                 * Ok, check all events, check for idle (and mark us sleeping
@@ -1706,12 +1707,6 @@ static int apm(void *unused)
        char *          power_stat;
        char *          bat_stat;
 
-       kapmd_running = 1;
-
-       daemonize("kapmd");
-
-       current->flags |= PF_NOFREEZE;
-
 #ifdef CONFIG_SMP
        /* 2002/08/01 - WT
         * This is to avoid random crashes at boot time during initialization
@@ -1821,7 +1816,6 @@ static int apm(void *unused)
                console_blank_hook = NULL;
 #endif
        }
-       kapmd_running = 0;
 
        return 0;
 }
@@ -2220,7 +2214,7 @@ static int __init apm_init(void)
 {
        struct proc_dir_entry *apm_proc;
        struct desc_struct *gdt;
-       int ret;
+       int err;
 
        dmi_check_system(apm_dmi_table);
 
@@ -2329,12 +2323,17 @@ static int __init apm_init(void)
        if (apm_proc)
                apm_proc->owner = THIS_MODULE;
 
-       ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
-       if (ret < 0) {
-               printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n");
+       kapmd_task = kthread_create(apm, NULL, "kapmd");
+       if (IS_ERR(kapmd_task)) {
+               printk(KERN_ERR "apm: disabled - Unable to start kernel "
+                               "thread.\n");
+               err = PTR_ERR(kapmd_task);
+               kapmd_task = NULL;
                remove_proc_entry("apm", NULL);
-               return -ENOMEM;
+               return err;
        }
+       kapmd_task->flags |= PF_NOFREEZE;
+       wake_up_process(kapmd_task);
 
        if (num_online_cpus() > 1 && !smp ) {
                printk(KERN_NOTICE
@@ -2384,9 +2383,10 @@ static void __exit apm_exit(void)
        remove_proc_entry("apm", NULL);
        if (power_off)
                pm_power_off = NULL;
-       exit_kapmd = 1;
-       while (kapmd_running)
-               schedule();
+       if (kapmd_task) {
+               kthread_stop(kapmd_task);
+               kapmd_task = NULL;
+       }
 #ifdef CONFIG_PM_LEGACY
        pm_active = 0;
 #endif
index fe158042110bea08fd7774234dfdb3c7275712a0..f9436989473c23fa0f57ac4ddea21dc8a2f117f0 100644 (file)
@@ -65,7 +65,7 @@ static unsigned long efi_rt_eflags;
 static DEFINE_SPINLOCK(efi_rt_lock);
 static pgd_t efi_bak_pg_dir_pointer[2];
 
-static void efi_call_phys_prelog(void)
+static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
 {
        unsigned long cr4;
        unsigned long temp;
@@ -109,7 +109,7 @@ static void efi_call_phys_prelog(void)
        load_gdt(cpu_gdt_descr);
 }
 
-static void efi_call_phys_epilog(void)
+static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
 {
        unsigned long cr4;
        struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
index dbda706fdd14e9e704ee1ab846b3ba361ddeaaf3..0fc4997fb14330d94d429d769867902102c37fe4 100644 (file)
@@ -31,6 +31,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 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 020d873b7d2130584e84906186703c8cd6079498..82b26d5ce476554bd3eb6158cda3d664a6974224 100644 (file)
@@ -102,6 +102,8 @@ u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
                        { [0 ... NR_CPUS-1] = 0xff };
 EXPORT_SYMBOL(x86_cpu_to_apicid);
 
+u8 apicid_2_node[MAX_APICID];
+
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -645,7 +647,7 @@ static void map_cpu_to_logical_apicid(void)
 {
        int cpu = smp_processor_id();
        int apicid = logical_smp_processor_id();
-       int node = apicid_to_node(apicid);
+       int node = apicid_to_node(hard_smp_processor_id());
 
        if (!node_online(node))
                node = first_online_node;
@@ -954,6 +956,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
 
        irq_ctx_init(cpu);
 
+       x86_cpu_to_apicid[cpu] = apicid;
        /*
         * This grunge runs the startup process for
         * the targeted processor.
index 32413122c4c2650f1114db0f10bb1d8e12c116b8..f7e735c077c35df71c4ae0c2262113f3ea7a92e4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/nodemask.h>
 #include <asm/srat.h>
 #include <asm/topology.h>
+#include <asm/smp.h>
 
 /*
  * proximity macros and definitions
@@ -54,6 +55,7 @@ struct node_memory_chunk_s {
 static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
 
 static int num_memory_chunks;          /* total number of memory chunks */
+static u8 __initdata apicid_to_pxm[MAX_APICID];
 
 extern void * boot_ioremap(unsigned long, unsigned long);
 
@@ -69,6 +71,8 @@ static void __init parse_cpu_affinity_structure(char *p)
        /* mark this node as "seen" in node bitmap */
        BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain);
 
+       apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain;
+
        printk("CPU 0x%02X in proximity domain 0x%02X\n",
                cpu_affinity->apic_id, cpu_affinity->proximity_domain);
 }
@@ -235,6 +239,9 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
        printk("Number of logical nodes in system = %d\n", num_online_nodes());
        printk("Number of memory chunks in system = %d\n", num_memory_chunks);
 
+       for (i = 0; i < MAX_APICID; i++)
+               apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]);
+
        for (j = 0; j < num_memory_chunks; j++){
                struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
                printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
index a13037fe0ee383dc0088893af946ab5eb42bfd0e..6820b8d643c7779a07328a1668fc41e4e8035542 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 },
index efc7e7d5f4d0f518847b5232f38aad75ea9367f4..08502fc6d0cb8d0fc819682d26b499e5aab08efb 100644 (file)
@@ -739,7 +739,7 @@ survive:
                        retval = get_user_pages(current, current->mm,
                                        (unsigned long )to, 1, 1, 0, &pg, NULL);
 
-                       if (retval == -ENOMEM && current->pid == 1) {
+                       if (retval == -ENOMEM && is_init(current)) {
                                up_read(&current->mm->mmap_sem);
                                blk_congestion_wait(WRITE, HZ/50);
                                goto survive;
index 5e17a3f43b41ba89c15b17e7390f04dc730ada64..2581575786c135a0a0201cf63caf754a8654a755 100644 (file)
@@ -440,7 +440,7 @@ good_area:
                case 1:         /* read, present */
                        goto bad_area;
                case 0:         /* read, not present */
-                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                                goto bad_area;
        }
 
@@ -589,7 +589,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (tsk->pid == 1) {
+       if (is_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index f88e05ba8eb34acd2aac784da0e9c592dcb20ef4..ca2447e05e15d90a70012e4d2b725c8fa9a47e78 100644 (file)
@@ -138,11 +138,14 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
 static void ppro_start(struct op_msrs const * const msrs)
 {
        unsigned int low,high;
+       int i;
 
-       if (reset_value[0]) {
-               CTRL_READ(low, high, msrs, 0);
-               CTRL_SET_ACTIVE(low);
-               CTRL_WRITE(low, high, msrs, 0);
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (reset_value[i]) {
+                       CTRL_READ(low, high, msrs, i);
+                       CTRL_SET_ACTIVE(low);
+                       CTRL_WRITE(low, high, msrs, i);
+               }
        }
 }
 
@@ -150,11 +153,14 @@ static void ppro_start(struct op_msrs const * const msrs)
 static void ppro_stop(struct op_msrs const * const msrs)
 {
        unsigned int low,high;
+       int i;
 
-       if (reset_value[0]) {
-               CTRL_READ(low, high, msrs, 0);
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (!reset_value[i])
+                       continue;
+               CTRL_READ(low, high, msrs, i);
                CTRL_SET_INACTIVE(low);
-               CTRL_WRITE(low, high, msrs, 0);
+               CTRL_WRITE(low, high, msrs, i);
        }
 }
 
index b5195be6281895d3ea6fb42eca4cb4fb5b41308d..e1a1b11473e221a95e2988107f2d45a9572817e8 100644 (file)
@@ -320,7 +320,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
        }
 
        printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
-              dev->name, htonl(ifa->ifa_local));
+              dev->name, ntohl(ifa->ifa_local));
 
        /*
         * XXX Fix me
@@ -331,7 +331,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
        local = dev->priv;
        /* now do it for real */
        r = event == NETDEV_UP ?
-               netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
+               netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)):
                netdev_detach(local->simfd);
 
        printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
index 6928ef0d64d852abc4a41b7ff5cfc2e1f14d5249..16262687a103a1be82d04f8b6acba09d2f7a2bd0 100644 (file)
@@ -78,7 +78,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                         * xtime_lock.
                         */
                        write_seqlock(&xtime_lock);
-                       do_timer(regs);
+                       do_timer(1);
                        local_cpu_data->itm_next = new_itm;
                        write_sequnlock(&xtime_lock);
                } else
index 14ef7cceb208bbd45031036cecadfda5e5527487..59f3ab937615fb0fbe40ae08061b3aa47a32a775 100644 (file)
@@ -146,9 +146,11 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 #              error File is out of sync with <linux/mm.h>.  Please update.
 #      endif
 
+       if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
+               goto bad_area;
+
        mask = (  (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
-               | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
-               | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
+               | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
 
        if ((vma->vm_flags & mask) != mask)
                goto bad_area;
@@ -278,7 +280,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 
   out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index ded0be07a476f62aca9f42ed17ea3f757f0453f0..7a896893cd284b80dbd4d2793dca650ec6032848 100644 (file)
@@ -202,7 +202,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #ifndef CONFIG_SMP
        profile_tick(CPU_PROFILING, regs);
 #endif
-       do_timer(regs);
+       do_timer(1);
 
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
index dc18a33eefef36ccd10790525b2537e4cae89255..8d5f551b5754305e87474b617b8e437925b48f76 100644 (file)
@@ -299,7 +299,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (tsk->pid == 1) {
+       if (is_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 98e4b1adfa29f3836cf69ddd339f02017669bff5..1072e4946a4acab38173ba2246773c363782164c 100644 (file)
@@ -40,7 +40,7 @@ static inline int set_rtc_mmss(unsigned long nowtime)
  */
 static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
 {
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index aec15270d334b74795fbfdf7ec214434f35a923f..911f2ce3f53e11ec6d1e0deeba875735d5c2a13b 100644 (file)
@@ -144,7 +144,7 @@ good_area:
                case 1:         /* read, present */
                        goto acc_err;
                case 0:         /* read, not present */
-                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                                goto acc_err;
        }
 
@@ -181,7 +181,7 @@ good_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index f18b9d3ef16df601915abadca0d7f9d1df2b2726..dc4ea7e074a620e21e500b66b75ab10c21a31965 100644 (file)
@@ -65,7 +65,7 @@ static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
 #ifdef CONFIG_SUN3
        intersil_clear();
 #endif
-        do_timer(fp);
+        do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(fp));
 #endif
index 1db9872722200b91fc56dde75be3781dca13b567..db1e1ce0a34960392e44999cfc1e793e6e93532e 100644 (file)
@@ -51,7 +51,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
 
        write_seqlock(&xtime_lock);
 
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index 7fbea1bf7b4824afb61d2bacc1c28ab40d1e9458..0a067f3113a54704a454501a14452996ec8b87c2 100644 (file)
@@ -96,7 +96,7 @@ void mips_timer_interrupt(struct pt_regs *regs)
                timerlo = count;
 
                kstat_this_cpu.irqs[irq]++;
-               do_timer(regs);
+               do_timer(1);
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
@@ -137,7 +137,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
        }
 
        while (time_elapsed > 0) {
-               do_timer(regs);
+               do_timer(1);
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
@@ -156,7 +156,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
 
        if (jiffie_drift >= 999) {
                jiffie_drift -= 999;
-               do_timer(regs); /* increment jiffies by one */
+               do_timer(1); /* increment jiffies by one */
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
index d837b26fbe517e5602be5aec2ae5cb4d3b4ff244..7feca49350d18b4bc6ea2ed630c09bbfb3fd1937 100644 (file)
@@ -34,7 +34,7 @@ static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
        if (irq_src & 0x00000800) {     /* Check for timer interrupt */
                handled = 1;
                irq_src &= ~0x00000800;
-               do_timer(regs);
+               do_timer(1);
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
index 477c5334ec1b459eefb010c9ef5918ca1358b47b..50c17eaa7f252c0012efb15054c25797a793cea4 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "signal-common.h"
 
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
@@ -81,8 +83,6 @@ struct rt_sigframe_n32 {
 #endif
 };
 
-extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
-
 save_static_function(sysn32_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
index 170cb67f4ede504d67f38072a14735056daad8c2..6ab8d975a974213a3e7fe3c16014ebe4279d9c50 100644 (file)
@@ -434,7 +434,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /*
         * call the generic timer interrupt handling
         */
-       do_timer(regs);
+       do_timer(1);
 
        /*
         * If we have an externally synchronized Linux clock, then update
index a4f8c45c4e8ede95a018f85da394317a88153ba4..8423d859077949520de140f5b03d7cfdecda92e1 100644 (file)
@@ -171,7 +171,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (tsk->pid == 1) {
+       if (is_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 9fb2493fff02494c0bb8789d4e273f5ac786c4c4..6cd87cf0195a1ca8ce2dea022502527054ff1aec 100644 (file)
@@ -133,7 +133,7 @@ static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
                MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
 
                /* handle the timer call */
-               do_timer(regs);
+               do_timer(1);
 #ifndef CONFIG_SMP
                update_process_times(user_mode(regs));
 #endif
index b029ba79c27af0f685079ba562c3d980122cc884..c62a3a9ef867fa6e3af03ecb773b8418e3ebed37 100644 (file)
@@ -111,7 +111,7 @@ again:
        kstat_this_cpu.irqs[irq]++;             /* kstat only for bootcpu? */
 
        if (cpu == 0)
-               do_timer(regs);
+               do_timer(1);
 
        update_process_times(user_mode(regs));
 
index aee311884f3fa114c2a4fa5f5f4b0dc4fbe2d5f3..f50b982b0834ce8b2598d1b66d1c06b5306ca29f 100644 (file)
@@ -27,7 +27,7 @@
  *    - SEGREL32 handling
  *      We are not doing SEGREL32 handling correctly. According to the ABI, we
  *      should do a value offset, like this:
- *                     if (is_init(me, (void *)val))
+ *                     if (in_init(me, (void *)val))
  *                             val -= (uint32_t)me->module_init;
  *                     else
  *                             val -= (uint32_t)me->module_core;
 
 /* three functions to determine where in the module core
  * or init pieces the location is */
-static inline int is_init(struct module *me, void *loc)
+static inline int in_init(struct module *me, void *loc)
 {
        return (loc >= me->module_init &&
                loc <= (me->module_init + me->init_size));
 }
 
-static inline int is_core(struct module *me, void *loc)
+static inline int in_core(struct module *me, void *loc)
 {
        return (loc >= me->module_core &&
                loc <= (me->module_core + me->core_size));
 }
 
-static inline int is_local(struct module *me, void *loc)
+static inline int in_local(struct module *me, void *loc)
 {
-       return is_init(me, loc) || is_core(me, loc);
+       return in_init(me, loc) || in_core(me, loc);
 }
 
-static inline int is_local_section(struct module *me, void *loc, void *dot)
+static inline int in_local_section(struct module *me, void *loc, void *dot)
 {
-       return (is_init(me, loc) && is_init(me, dot)) ||
-               (is_core(me, loc) && is_core(me, dot));
+       return (in_init(me, loc) && in_init(me, dot)) ||
+               (in_core(me, loc) && in_core(me, dot));
 }
 
 
@@ -566,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        break;
                case R_PARISC_PCREL17F:
                        /* 17-bit PC relative address */
-                       val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
+                       val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
                        val = (val - dot - 8)/4;
                        CHECK_RELOC(val, 17)
                        *loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
                        break;
                case R_PARISC_PCREL22F:
                        /* 22-bit PC relative address; only defined for pa20 */
-                       val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
+                       val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
                        DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", 
                               strtab + sym->st_name, (unsigned long)loc, addend, 
                               val)
@@ -670,9 +670,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                               strtab + sym->st_name,
                               loc, val);
                        /* can we reach it locally? */
-                       if(!is_local_section(me, (void *)val, (void *)dot)) {
+                       if(!in_local_section(me, (void *)val, (void *)dot)) {
 
-                               if (is_local(me, (void *)val))
+                               if (in_local(me, (void *)val))
                                        /* this is the case where the
                                         * symbol is local to the
                                         * module, but in a different
@@ -680,14 +680,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                                         * in case it's more than 22
                                         * bits away */
                                        val = get_stub(me, val, addend, ELF_STUB_DIRECT,
-                                                      is_init(me, loc));
+                                                      in_init(me, loc));
                                else if (strncmp(strtab + sym->st_name, "$$", 2)
                                    == 0)
                                        val = get_stub(me, val, addend, ELF_STUB_MILLI,
-                                                      is_init(me, loc));
+                                                      in_init(me, loc));
                                else
                                        val = get_stub(me, val, addend, ELF_STUB_GOT,
-                                                      is_init(me, loc));
+                                                      in_init(me, loc));
                        }
                        DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
                               strtab + sym->st_name, loc, sym->st_value,
@@ -720,7 +720,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        break;
                case R_PARISC_FPTR64:
                        /* 64-bit function address */
-                       if(is_local(me, (void *)(val + addend))) {
+                       if(in_local(me, (void *)(val + addend))) {
                                *loc64 = get_fdesc(me, val+addend);
                                DEBUGP("FDESC for %s at %p points to %lx\n",
                                       strtab + sym->st_name, *loc64,
index 5facc9bff4ef68b584aa32fb263b99461e90eb77..700df10924dd8d671b9ae1d6f62b8763ad3f1c0a 100644 (file)
@@ -79,7 +79,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
                if (cpu == 0) {
                        write_seqlock(&xtime_lock);
-                       do_timer(regs);
+                       do_timer(1);
                        write_sequnlock(&xtime_lock);
                }
        }
index 7a3c3f791ade2aaac30bbadc0994da40ea12e80a..71f71da98e7deb6288a9acdeb6a0449e493787b6 100644 (file)
@@ -693,7 +693,7 @@ void timer_interrupt(struct pt_regs * regs)
                tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
                if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
                        tb_last_jiffy = tb_next_jiffy;
-                       do_timer(regs);
+                       do_timer(1);
                        timer_recalc_offset(tb_last_jiffy);
                        timer_check_rtc();
                }
index 78a0d59903ee69d2b8ac96de20e18c17fd5f9206..e8fa50624b70dae41c27ce669e10f472b18970a8 100644 (file)
@@ -333,7 +333,7 @@ good_area:
                /* protection fault */
                if (error_code & 0x08000000)
                        goto bad_area;
-               if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+               if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                        goto bad_area;
        }
 
@@ -386,7 +386,7 @@ bad_area_nosemaphore:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 903115d67fdcc5230b718abb6dfb25038881d5b8..311ed1993fc036de995f444bac92d1a327236c89 100644 (file)
@@ -337,7 +337,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
                   err->disposition == RTAS_DISP_NOT_RECOVERED &&
                   err->target == RTAS_TARGET_MEMORY &&
                   err->type == RTAS_TYPE_ECC_UNCORR &&
-                  !(current->pid == 0 || current->pid == 1)) {
+                  !(current->pid == 0 || is_init(current))) {
                /* Kill off a user process with an ECC error */
                printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
                       current->pid);
index 6ab8cc7226ab232b220d9d555f0ed66358c0f6c0..1e1f315547671503d0370a2e36bb31eb071b7167 100644 (file)
@@ -153,7 +153,7 @@ void timer_interrupt(struct pt_regs * regs)
                /* We are in an interrupt, no need to save/restore flags */
                write_seqlock(&xtime_lock);
                tb_last_stamp = jiffy_stamp;
-               do_timer(regs);
+               do_timer(1);
 
                /*
                 * update the rtc when needed, this should be performed on the
index d7a433049b4857b3acf2caa59e6f7c981d1c5f21..aafc8e8893d1ebc0ac969b097f77d9f976d616ee 100644 (file)
@@ -119,7 +119,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
         * generate the same exception over and over again and we get
         * nowhere.  Better to kill it and let the kernel panic.
         */
-       if (current->pid == 1) {
+       if (is_init(current)) {
                __sighandler_t handler;
 
                spin_lock_irq(&current->sighand->siglock);
index 5cdfb71fcb078ca50f56059a907e0104ab452194..465f451f3bc3a8a95908dcaa4d31757e04bc9f26 100644 (file)
@@ -239,7 +239,7 @@ good_area:
                /* protection fault */
                if (error_code & 0x08000000)
                        goto bad_area;
-               if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+               if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                        goto bad_area;
        }
 
@@ -291,7 +291,7 @@ bad_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index b216ca659cdff5876e8cbb8f04be03395fc03cc3..f900a516f099bfc6724068af74b77d6149625cf0 100644 (file)
@@ -51,6 +51,10 @@ config 64BIT
          Select this option if you have a 64 bit IBM zSeries machine
          and want to use the 64 bit addressing mode.
 
+config 32BIT
+       bool
+       default y if !64BIT
+
 config SMP
        bool "Symmetric multi-processing support"
        ---help---
@@ -149,6 +153,14 @@ config MARCH_Z990
          This will be slightly faster but does not work on
          older machines such as the z900.
 
+config MARCH_Z9_109
+       bool "IBM System z9"
+       help
+         Select this to enable optimizations for IBM System z9-109, IBM
+         System z9 Enterprise Class (z9 EC), and IBM System z9 Business
+         Class (z9 BC). The kernel will be slightly faster but will not
+         work on older machines such as the z990, z890, z900, and z800.
+
 endchoice
 
 config PACK_STACK
index 74ef57dcfa60b5bb9527d6651440995851aa9ebd..5deb9f7544a1da444b1ba0034685d511c74fc67b 100644 (file)
@@ -33,6 +33,7 @@ endif
 cflags-$(CONFIG_MARCH_G5)   += $(call cc-option,-march=g5)
 cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
 cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
+cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109)
 
 #
 # Prevent tail-call optimizations, to get clearer backtraces:
index b69ed742f98179834b4317d1a0320e205e23aef9..2b1e6c9a6e0e539826a3a8d45181ec5a7c72e76c 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
-#include <linux/page-flags.h>
+#include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
 #include <linux/sysctl.h>
@@ -157,12 +157,12 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer,
                .prod_nr    = {0xD3, 0xC9, 0xD5, 0xE4,
                               0xE7, 0xD2, 0xD9},       /* "LINUXKR" */
                .prod_fn    = 0xD5D3,                   /* "NL" */
-               .record_nr  = record_nr,
                .version_nr = 0xF2F6,                   /* "26" */
                .release_nr = 0xF0F1,                   /* "01" */
-               .mod_lvl    = (mod_lvl[0]) << 8 | mod_lvl[1],
        };
 
+       id.record_nr = record_nr;
+       id.mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1];
        return appldata_asm(&id, function, (void *) buffer, length);
 }
 /************************ timer, work, DIAG <END> ****************************/
index efd836c2e4a6cf0726a55dcad3c77bdca40a202f..2b137089f6251bbd920523770fa07821d25a79d1 100644 (file)
@@ -104,63 +104,6 @@ struct crypt_s390_query_status {
        u64 low;
 };
 
-/*
- * Standard fixup and ex_table sections for crypt_s390 inline functions.
- * label 0: the s390 crypto operation
- * label 1: just after 1 to catch illegal operation exception
- *          (unsupported model)
- * label 6: the return point after fixup
- * label 7: set error value if exception _in_ crypto operation
- * label 8: set error value if illegal operation exception
- * [ret] is the variable to receive the error code
- * [ERR] is the error code value
- */
-#ifndef CONFIG_64BIT
-#define __crypt_s390_fixup \
-       ".section .fixup,\"ax\" \n"     \
-       "7:     lhi     %0,%h[e1] \n"   \
-       "       bras    1,9f \n"        \
-       "       .long   6b \n"          \
-       "8:     lhi     %0,%h[e2] \n"   \
-       "       bras    1,9f \n"        \
-       "       .long   6b \n"          \
-       "9:     l       1,0(1) \n"      \
-       "       br      1 \n"           \
-       ".previous \n"                  \
-       ".section __ex_table,\"a\" \n"  \
-       "       .align  4 \n"           \
-       "       .long   0b,7b \n"       \
-       "       .long   1b,8b \n"       \
-       ".previous"
-#else /* CONFIG_64BIT */
-#define __crypt_s390_fixup \
-       ".section .fixup,\"ax\" \n"     \
-       "7:     lhi     %0,%h[e1] \n"   \
-       "       jg      6b \n"          \
-       "8:     lhi     %0,%h[e2] \n"   \
-       "       jg      6b \n"          \
-       ".previous\n"                   \
-       ".section __ex_table,\"a\" \n"  \
-       "       .align  8 \n"           \
-       "       .quad   0b,7b \n"       \
-       "       .quad   1b,8b \n"       \
-       ".previous"
-#endif /* CONFIG_64BIT */
-
-/*
- * Standard code for setting the result of s390 crypto instructions.
- * %0: the register which will receive the result
- * [result]: the register containing the result (e.g. second operand length
- * to compute number of processed bytes].
- */
-#ifndef CONFIG_64BIT
-#define __crypt_s390_set_result \
-       "       lr      %0,%[result] \n"
-#else /* CONFIG_64BIT */
-#define __crypt_s390_set_result \
-       "       lgr     %0,%[result] \n"
-#endif
-
 /*
  * Executes the KM (CIPHER MESSAGE) operation of the CPU.
  * @param func: the function code passed to KM; see crypt_s390_km_func
@@ -176,28 +119,24 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
 {
        register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
        register void* __param asm("1") = param;
-       register u8* __dest asm("4") = dest;
        register const u8* __src asm("2") = src;
        register long __src_len asm("3") = src_len;
+       register u8* __dest asm("4") = dest;
        int ret;
 
-       ret = 0;
-       __asm__ __volatile__ (
-               "0:     .insn   rre,0xB92E0000,%1,%2 \n" /* KM opcode */
+       asm volatile(
+               "0:     .insn   rre,0xb92e0000,%3,%1 \n" /* KM opcode */
                "1:     brc     1,0b \n" /* handle partial completion */
-               __crypt_s390_set_result
-               "6:     \n"
-               __crypt_s390_fixup
-               : "+d" (ret), "+a" (__dest), "+a" (__src),
-                 [result] "+d" (__src_len)
-               : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-                 "a" (__param)
-               : "cc", "memory"
-       );
-       if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
-               ret = src_len - ret;
-       }
-       return ret;
+               "       ahi     %0,%h7\n"
+               "2:     ahi     %0,%h8\n"
+               "3:\n"
+               EX_TABLE(0b,3b) EX_TABLE(1b,2b)
+               : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
+               : "d" (__func), "a" (__param), "0" (-EFAULT),
+                 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
+       if (ret < 0)
+               return ret;
+       return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
 }
 
 /*
@@ -215,28 +154,24 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
 {
        register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
        register void* __param asm("1") = param;
-       register u8* __dest asm("4") = dest;
        register const u8* __src asm("2") = src;
        register long __src_len asm("3") = src_len;
+       register u8* __dest asm("4") = dest;
        int ret;
 
-       ret = 0;
-       __asm__ __volatile__ (
-               "0:     .insn   rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
+       asm volatile(
+               "0:     .insn   rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
                "1:     brc     1,0b \n" /* handle partial completion */
-               __crypt_s390_set_result
-               "6:     \n"
-               __crypt_s390_fixup
-               : "+d" (ret), "+a" (__dest), "+a" (__src),
-                 [result] "+d" (__src_len)
-               : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-                 "a" (__param)
-               : "cc", "memory"
-       );
-       if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
-               ret = src_len - ret;
-       }
-       return ret;
+               "       ahi     %0,%h7\n"
+               "2:     ahi     %0,%h8\n"
+               "3:\n"
+               EX_TABLE(0b,3b) EX_TABLE(1b,2b)
+               : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
+               : "d" (__func), "a" (__param), "0" (-EFAULT),
+                 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
+       if (ret < 0)
+               return ret;
+       return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
 }
 
 /*
@@ -258,22 +193,19 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
        register long __src_len asm("3") = src_len;
        int ret;
 
-       ret = 0;
-       __asm__ __volatile__ (
-               "0:     .insn   rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
-               "1:     brc     1,0b \n" /* handle partical completion */
-               __crypt_s390_set_result
-               "6:     \n"
-               __crypt_s390_fixup
-               : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-               : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-                 "a" (__param)
-               : "cc", "memory"
-       );
-       if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
-               ret = src_len - ret;
-       }
-       return ret;
+       asm volatile(
+               "0:     .insn   rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
+               "1:     brc     1,0b \n" /* handle partial completion */
+               "       ahi     %0,%h6\n"
+               "2:     ahi     %0,%h7\n"
+               "3:\n"
+               EX_TABLE(0b,3b) EX_TABLE(1b,2b)
+               : "=d" (ret), "+a" (__src), "+d" (__src_len)
+               : "d" (__func), "a" (__param), "0" (-EFAULT),
+                 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
+       if (ret < 0)
+               return ret;
+       return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
 }
 
 /*
@@ -294,22 +226,19 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
        register long __src_len asm("3") = src_len;
        int ret;
 
-       ret = 0;
-       __asm__ __volatile__ (
-               "0:     .insn   rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
-               "1:     brc     1,0b \n" /* handle partical completion */
-               __crypt_s390_set_result
-               "6:     \n"
-               __crypt_s390_fixup
-               : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-               : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-                 "a" (__param)
-               : "cc", "memory"
-       );
-       if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
-               ret = src_len - ret;
-       }
-       return ret;
+       asm volatile(
+               "0:     .insn   rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
+               "1:     brc     1,0b \n" /* handle partial completion */
+               "       ahi     %0,%h6\n"
+               "2:     ahi     %0,%h7\n"
+               "3:\n"
+               EX_TABLE(0b,3b) EX_TABLE(1b,2b)
+               : "=d" (ret), "+a" (__src), "+d" (__src_len)
+               : "d" (__func), "a" (__param), "0" (-EFAULT),
+                 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
+       if (ret < 0)
+               return ret;
+       return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
 }
 
 /*
@@ -331,22 +260,19 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
        register long __src_len asm("3") = src_len;
        int ret;
 
-       ret = 0;
-       __asm__ __volatile__ (
-               "0:     .insn   rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
-               "1:     brc     1,0b \n" /* handle partical completion */
-               __crypt_s390_set_result
-               "6:     \n"
-               __crypt_s390_fixup
-               : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-               : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-                 "a" (__param)
-               : "cc", "memory"
-       );
-       if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
-               ret = src_len - ret;
-       }
-       return ret;
+       asm volatile(
+               "0:     .insn   rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
+               "1:     brc     1,0b \n" /* handle partial completion */
+               "       ahi     %0,%h6\n"
+               "2:     ahi     %0,%h7\n"
+               "3:\n"
+               EX_TABLE(0b,3b) EX_TABLE(1b,2b)
+               : "=d" (ret), "+a" (__src), "+d" (__src_len)
+               : "d" (__func), "a" (__param), "0" (-EFAULT),
+                 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
+       if (ret < 0)
+               return ret;
+       return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
 }
 
 /**
index 75144efbb92b647cd8ce83487d5bf3a2a7fd238b..443fa377d9ff893efbd09a6f7214dbbcebd53f0a 100644 (file)
@@ -333,22 +333,14 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
        register unsigned long _subcode asm("0") = subcode;
        register unsigned long _size asm("1") = size;
 
-       asm volatile ("   diag    %2,%0,0x204\n"
-                     "0: \n" ".section __ex_table,\"a\"\n"
-#ifndef __s390x__
-                     "    .align 4\n"
-                     "    .long  0b,0b\n"
-#else
-                     "    .align 8\n"
-                     "    .quad  0b,0b\n"
-#endif
-                     ".previous":"+d" (_subcode), "+d"(_size)
-                     :"d"(addr)
-                     :"memory");
+       asm volatile(
+               "       diag    %2,%0,0x204\n"
+               "0:\n"
+               EX_TABLE(0b,0b)
+               : "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory");
        if (_subcode)
                return -1;
-       else
-               return _size;
+       return _size;
 }
 
 /*
@@ -403,7 +395,8 @@ static void *diag204_get_buffer(enum diag204_format fmt, int *pages)
                *pages = 1;
                return diag204_alloc_rbuf();
        } else {/* INFO_EXT */
-               *pages = diag204(SUBC_RSI | INFO_EXT, 0, NULL);
+               *pages = diag204((unsigned long)SUBC_RSI |
+                                (unsigned long)INFO_EXT, 0, NULL);
                if (*pages <= 0)
                        return ERR_PTR(-ENOSYS);
                else
@@ -490,8 +483,7 @@ out:
 
 static void diag224(void *ptr)
 {
-       asm volatile("   diag    %0,%1,0x224\n"
-                    : :"d" (0), "d"(ptr) : "memory");
+       asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory");
 }
 
 static int diag224_get_name_table(void)
index 91b2884fa5c4c77ff6909d45631618e1dceec8be..c46e3d48e4104d827abc7c17c40bed215fe70461 100644 (file)
@@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs)
                current->ptrace &= ~PT_DTRACE;
                task_unlock(current);
                current->thread.fp_regs.fpc=0;
-               __asm__ __volatile__
-                       ("sr  0,0\n\t"
-                        "sfpc 0,0\n\t"
-                        : : :"0");
+               asm volatile("sfpc %0,0" : : "d" (0));
        }
         putname(filename);
 out:
index 4d53b2739357d21aa707d838184dedf29486e220..4aabeeaa7cf778b56104688272a4f007e939ca83 100644 (file)
@@ -4,97 +4,97 @@
 *
 *    Copyright (C) IBM Corp. 2000,2006
 *    Author(s): Gerhard Tonn (ton@de.ibm.com),
-*               Thomas Spatzier (tspat@de.ibm.com)
-*/ 
+*              Thomas Spatzier (tspat@de.ibm.com)
+*/
 
-       .globl  sys32_exit_wrapper 
+       .globl  sys32_exit_wrapper
 sys32_exit_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_exit                # branch to sys_exit
-    
-       .globl  sys32_read_wrapper 
+
+       .globl  sys32_read_wrapper
 sys32_read_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # char *
        llgfr   %r4,%r4                 # size_t
        jg      sys32_read              # branch to sys_read
 
-       .globl  sys32_write_wrapper 
+       .globl  sys32_write_wrapper
 sys32_write_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # const char *
        llgfr   %r4,%r4                 # size_t
        jg      sys32_write             # branch to system call
 
-       .globl  sys32_open_wrapper 
+       .globl  sys32_open_wrapper
 sys32_open_wrapper:
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        lgfr    %r4,%r4                 # int
        jg      sys_open                # branch to system call
 
-       .globl  sys32_close_wrapper 
+       .globl  sys32_close_wrapper
 sys32_close_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_close               # branch to system call
 
-       .globl  sys32_creat_wrapper 
+       .globl  sys32_creat_wrapper
 sys32_creat_wrapper:
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        jg      sys_creat               # branch to system call
 
-       .globl  sys32_link_wrapper 
+       .globl  sys32_link_wrapper
 sys32_link_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgtr   %r3,%r3                 # const char *
        jg      sys_link                # branch to system call
 
-       .globl  sys32_unlink_wrapper 
+       .globl  sys32_unlink_wrapper
 sys32_unlink_wrapper:
        llgtr   %r2,%r2                 # const char *
        jg      sys_unlink              # branch to system call
 
-       .globl  sys32_chdir_wrapper 
+       .globl  sys32_chdir_wrapper
 sys32_chdir_wrapper:
        llgtr   %r2,%r2                 # const char *
        jg      sys_chdir               # branch to system call
 
-       .globl  sys32_time_wrapper 
+       .globl  sys32_time_wrapper
 sys32_time_wrapper:
        llgtr   %r2,%r2                 # int *
        jg      compat_sys_time         # branch to system call
 
-       .globl  sys32_mknod_wrapper 
+       .globl  sys32_mknod_wrapper
 sys32_mknod_wrapper:
        llgtr   %r2,%r2                 # const char *
-       lgfr    %r3,%r3                 # int 
+       lgfr    %r3,%r3                 # int
        llgfr   %r4,%r4                 # dev
        jg      sys_mknod               # branch to system call
 
-       .globl  sys32_chmod_wrapper 
+       .globl  sys32_chmod_wrapper
 sys32_chmod_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # mode_t
        jg      sys_chmod               # branch to system call
 
-       .globl  sys32_lchown16_wrapper 
+       .globl  sys32_lchown16_wrapper
 sys32_lchown16_wrapper:
        llgtr   %r2,%r2                 # const char *
-       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t 
-       llgfr   %r4,%r4                 # __kernel_old_uid_emu31_t 
+       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t
+       llgfr   %r4,%r4                 # __kernel_old_uid_emu31_t
        jg      sys32_lchown16          # branch to system call
 
-       .globl  sys32_lseek_wrapper 
+       .globl  sys32_lseek_wrapper
 sys32_lseek_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        lgfr    %r3,%r3                 # off_t
        llgfr   %r4,%r4                 # unsigned int
        jg      sys_lseek               # branch to system call
 
-#sys32_getpid_wrapper                          # void 
+#sys32_getpid_wrapper                          # void
 
-       .globl  sys32_mount_wrapper 
+       .globl  sys32_mount_wrapper
 sys32_mount_wrapper:
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # char *
@@ -103,19 +103,19 @@ sys32_mount_wrapper:
        llgtr   %r6,%r6                 # void *
        jg      compat_sys_mount        # branch to system call
 
-       .globl  sys32_oldumount_wrapper 
+       .globl  sys32_oldumount_wrapper
 sys32_oldumount_wrapper:
        llgtr   %r2,%r2                 # char *
        jg      sys_oldumount           # branch to system call
 
-       .globl  sys32_setuid16_wrapper 
+       .globl  sys32_setuid16_wrapper
 sys32_setuid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t
        jg      sys32_setuid16          # branch to system call
 
-#sys32_getuid16_wrapper                        # void 
+#sys32_getuid16_wrapper                        # void
 
-       .globl  sys32_ptrace_wrapper 
+       .globl  sys32_ptrace_wrapper
 sys32_ptrace_wrapper:
        lgfr    %r2,%r2                 # long
        lgfr    %r3,%r3                 # long
@@ -123,168 +123,168 @@ sys32_ptrace_wrapper:
        llgfr   %r5,%r5                 # long
        jg      sys_ptrace              # branch to system call
 
-       .globl  sys32_alarm_wrapper 
+       .globl  sys32_alarm_wrapper
 sys32_alarm_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_alarm               # branch to system call
 
-#sys32_pause_wrapper                   # void 
+#sys32_pause_wrapper                   # void
 
-       .globl  compat_sys_utime_wrapper 
+       .globl  compat_sys_utime_wrapper
 compat_sys_utime_wrapper:
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # struct compat_utimbuf *
        jg      compat_sys_utime        # branch to system call
 
-       .globl  sys32_access_wrapper 
+       .globl  sys32_access_wrapper
 sys32_access_wrapper:
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        jg      sys_access              # branch to system call
 
-       .globl  sys32_nice_wrapper 
+       .globl  sys32_nice_wrapper
 sys32_nice_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_nice                # branch to system call
 
-#sys32_sync_wrapper                    # void 
+#sys32_sync_wrapper                    # void
 
-       .globl  sys32_kill_wrapper 
+       .globl  sys32_kill_wrapper
 sys32_kill_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
        jg      sys_kill                # branch to system call
 
-       .globl  sys32_rename_wrapper 
+       .globl  sys32_rename_wrapper
 sys32_rename_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgtr   %r3,%r3                 # const char *
        jg      sys_rename              # branch to system call
 
-       .globl  sys32_mkdir_wrapper 
+       .globl  sys32_mkdir_wrapper
 sys32_mkdir_wrapper:
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        jg      sys_mkdir               # branch to system call
 
-       .globl  sys32_rmdir_wrapper 
+       .globl  sys32_rmdir_wrapper
 sys32_rmdir_wrapper:
        llgtr   %r2,%r2                 # const char *
        jg      sys_rmdir               # branch to system call
 
-       .globl  sys32_dup_wrapper 
+       .globl  sys32_dup_wrapper
 sys32_dup_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_dup                 # branch to system call
 
-       .globl  sys32_pipe_wrapper 
+       .globl  sys32_pipe_wrapper
 sys32_pipe_wrapper:
        llgtr   %r2,%r2                 # u32 *
        jg      sys_pipe                # branch to system call
 
-       .globl  compat_sys_times_wrapper 
+       .globl  compat_sys_times_wrapper
 compat_sys_times_wrapper:
        llgtr   %r2,%r2                 # struct compat_tms *
        jg      compat_sys_times        # branch to system call
 
-       .globl  sys32_brk_wrapper 
+       .globl  sys32_brk_wrapper
 sys32_brk_wrapper:
        llgtr   %r2,%r2                 # unsigned long
        jg      sys_brk                 # branch to system call
 
-       .globl  sys32_setgid16_wrapper 
+       .globl  sys32_setgid16_wrapper
 sys32_setgid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t
        jg      sys32_setgid16          # branch to system call
 
-#sys32_getgid16_wrapper                        # void 
+#sys32_getgid16_wrapper                        # void
 
        .globl sys32_signal_wrapper
 sys32_signal_wrapper:
-       lgfr    %r2,%r2                 # int 
+       lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # __sighandler_t
        jg      sys_signal
 
-#sys32_geteuid16_wrapper               # void 
+#sys32_geteuid16_wrapper               # void
 
-#sys32_getegid16_wrapper               # void 
+#sys32_getegid16_wrapper               # void
 
-       .globl  sys32_acct_wrapper 
+       .globl  sys32_acct_wrapper
 sys32_acct_wrapper:
        llgtr   %r2,%r2                 # char *
        jg      sys_acct                # branch to system call
 
-       .globl  sys32_umount_wrapper 
+       .globl  sys32_umount_wrapper
 sys32_umount_wrapper:
        llgtr   %r2,%r2                 # char *
        lgfr    %r3,%r3                 # int
        jg      sys_umount              # branch to system call
 
-       .globl  compat_sys_ioctl_wrapper
+       .globl  compat_sys_ioctl_wrapper
 compat_sys_ioctl_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned int
        llgfr   %r4,%r4                 # unsigned int
        jg      compat_sys_ioctl        # branch to system call
 
-       .globl  compat_sys_fcntl_wrapper 
+       .globl  compat_sys_fcntl_wrapper
 compat_sys_fcntl_wrapper:
        llgfr   %r2,%r2                 # unsigned int
-       llgfr   %r3,%r3                 # unsigned int 
+       llgfr   %r3,%r3                 # unsigned int
        llgfr   %r4,%r4                 # unsigned long
        jg      compat_sys_fcntl        # branch to system call
 
-       .globl  sys32_setpgid_wrapper 
+       .globl  sys32_setpgid_wrapper
 sys32_setpgid_wrapper:
        lgfr    %r2,%r2                 # pid_t
        lgfr    %r3,%r3                 # pid_t
        jg      sys_setpgid             # branch to system call
 
-       .globl  sys32_umask_wrapper 
+       .globl  sys32_umask_wrapper
 sys32_umask_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_umask               # branch to system call
 
-       .globl  sys32_chroot_wrapper 
+       .globl  sys32_chroot_wrapper
 sys32_chroot_wrapper:
        llgtr   %r2,%r2                 # char *
        jg      sys_chroot              # branch to system call
 
        .globl sys32_ustat_wrapper
 sys32_ustat_wrapper:
-       llgfr   %r2,%r2                 # dev_t 
+       llgfr   %r2,%r2                 # dev_t
        llgtr   %r3,%r3                 # struct ustat *
        jg      sys_ustat
 
-       .globl  sys32_dup2_wrapper 
+       .globl  sys32_dup2_wrapper
 sys32_dup2_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned int
        jg      sys_dup2                # branch to system call
 
-#sys32_getppid_wrapper                 # void 
+#sys32_getppid_wrapper                 # void
 
-#sys32_getpgrp_wrapper                 # void 
+#sys32_getpgrp_wrapper                 # void
 
-#sys32_setsid_wrapper                  # void 
+#sys32_setsid_wrapper                  # void
 
-       .globl  sys32_sigaction_wrapper
+       .globl  sys32_sigaction_wrapper
 sys32_sigaction_wrapper:
-       lgfr    %r2,%r2                 # int 
+       lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # const struct old_sigaction *
        llgtr   %r4,%r4                 # struct old_sigaction32 *
        jg      sys32_sigaction         # branch to system call
 
-       .globl  sys32_setreuid16_wrapper 
+       .globl  sys32_setreuid16_wrapper
 sys32_setreuid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t 
-       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t
+       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t
        jg      sys32_setreuid16        # branch to system call
 
-       .globl  sys32_setregid16_wrapper 
+       .globl  sys32_setregid16_wrapper
 sys32_setregid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t 
-       llgfr   %r3,%r3                 # __kernel_old_gid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t
+       llgfr   %r3,%r3                 # __kernel_old_gid_emu31_t
        jg      sys32_setregid16        # branch to system call
 
        .globl sys_sigsuspend_wrapper
@@ -294,95 +294,95 @@ sys_sigsuspend_wrapper:
        llgfr   %r4,%r4                 # old_sigset_t
        jg      sys_sigsuspend
 
-       .globl  compat_sys_sigpending_wrapper 
+       .globl  compat_sys_sigpending_wrapper
 compat_sys_sigpending_wrapper:
        llgtr   %r2,%r2                 # compat_old_sigset_t *
        jg      compat_sys_sigpending   # branch to system call
 
-       .globl  sys32_sethostname_wrapper 
+       .globl  sys32_sethostname_wrapper
 sys32_sethostname_wrapper:
        llgtr   %r2,%r2                 # char *
        lgfr    %r3,%r3                 # int
        jg      sys_sethostname         # branch to system call
 
-       .globl  compat_sys_setrlimit_wrapper 
+       .globl  compat_sys_setrlimit_wrapper
 compat_sys_setrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
        jg      compat_sys_setrlimit    # branch to system call
 
-       .globl  compat_sys_old_getrlimit_wrapper 
+       .globl  compat_sys_old_getrlimit_wrapper
 compat_sys_old_getrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
        jg      compat_sys_old_getrlimit # branch to system call
 
-       .globl  compat_sys_getrlimit_wrapper 
+       .globl  compat_sys_getrlimit_wrapper
 compat_sys_getrlimit_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct rlimit_emu31 *
        jg      compat_sys_getrlimit    # branch to system call
 
-       .globl  sys32_mmap2_wrapper 
+       .globl  sys32_mmap2_wrapper
 sys32_mmap2_wrapper:
        llgtr   %r2,%r2                 # struct mmap_arg_struct_emu31 *
        jg      sys32_mmap2                     # branch to system call
 
-       .globl  compat_sys_getrusage_wrapper 
+       .globl  compat_sys_getrusage_wrapper
 compat_sys_getrusage_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct rusage_emu31 *
        jg      compat_sys_getrusage    # branch to system call
 
-       .globl  sys32_gettimeofday_wrapper 
+       .globl  sys32_gettimeofday_wrapper
 sys32_gettimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
        jg      sys32_gettimeofday      # branch to system call
 
-       .globl  sys32_settimeofday_wrapper 
+       .globl  sys32_settimeofday_wrapper
 sys32_settimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
        jg      sys32_settimeofday      # branch to system call
 
-       .globl  sys32_getgroups16_wrapper 
+       .globl  sys32_getgroups16_wrapper
 sys32_getgroups16_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # __kernel_old_gid_emu31_t *
        jg      sys32_getgroups16       # branch to system call
 
-       .globl  sys32_setgroups16_wrapper 
+       .globl  sys32_setgroups16_wrapper
 sys32_setgroups16_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # __kernel_old_gid_emu31_t *
        jg      sys32_setgroups16       # branch to system call
 
-       .globl  sys32_symlink_wrapper 
+       .globl  sys32_symlink_wrapper
 sys32_symlink_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgtr   %r3,%r3                 # const char *
        jg      sys_symlink             # branch to system call
 
-       .globl  sys32_readlink_wrapper 
+       .globl  sys32_readlink_wrapper
 sys32_readlink_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgtr   %r3,%r3                 # char *
        lgfr    %r4,%r4                 # int
        jg      sys_readlink            # branch to system call
 
-       .globl  sys32_uselib_wrapper 
+       .globl  sys32_uselib_wrapper
 sys32_uselib_wrapper:
        llgtr   %r2,%r2                 # const char *
        jg      sys_uselib              # branch to system call
 
-       .globl  sys32_swapon_wrapper 
+       .globl  sys32_swapon_wrapper
 sys32_swapon_wrapper:
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        jg      sys_swapon              # branch to system call
 
-       .globl  sys32_reboot_wrapper 
+       .globl  sys32_reboot_wrapper
 sys32_reboot_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
@@ -390,121 +390,121 @@ sys32_reboot_wrapper:
        llgtr   %r5,%r5                 # void *
        jg      sys_reboot              # branch to system call
 
-       .globl  old32_readdir_wrapper 
+       .globl  old32_readdir_wrapper
 old32_readdir_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # void *
        llgfr   %r4,%r4                 # unsigned int
        jg      compat_sys_old_readdir  # branch to system call
 
-       .globl  old32_mmap_wrapper 
+       .globl  old32_mmap_wrapper
 old32_mmap_wrapper:
        llgtr   %r2,%r2                 # struct mmap_arg_struct_emu31 *
        jg      old32_mmap              # branch to system call
 
-       .globl  sys32_munmap_wrapper 
+       .globl  sys32_munmap_wrapper
 sys32_munmap_wrapper:
        llgfr   %r2,%r2                 # unsigned long
-       llgfr   %r3,%r3                 # size_t 
+       llgfr   %r3,%r3                 # size_t
        jg      sys_munmap              # branch to system call
 
-       .globl  sys32_truncate_wrapper 
+       .globl  sys32_truncate_wrapper
 sys32_truncate_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # unsigned long
        jg      sys_truncate            # branch to system call
 
-       .globl  sys32_ftruncate_wrapper 
+       .globl  sys32_ftruncate_wrapper
 sys32_ftruncate_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned long
        jg      sys_ftruncate           # branch to system call
 
-       .globl  sys32_fchmod_wrapper 
+       .globl  sys32_fchmod_wrapper
 sys32_fchmod_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # mode_t
        jg      sys_fchmod              # branch to system call
 
-       .globl  sys32_fchown16_wrapper 
+       .globl  sys32_fchown16_wrapper
 sys32_fchown16_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # compat_uid_t
        llgfr   %r4,%r4                 # compat_uid_t
        jg      sys32_fchown16          # branch to system call
 
-       .globl  sys32_getpriority_wrapper 
+       .globl  sys32_getpriority_wrapper
 sys32_getpriority_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
        jg      sys_getpriority         # branch to system call
 
-       .globl  sys32_setpriority_wrapper 
+       .globl  sys32_setpriority_wrapper
 sys32_setpriority_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
        lgfr    %r4,%r4                 # int
        jg      sys_setpriority         # branch to system call
 
-       .globl  compat_sys_statfs_wrapper 
+       .globl  compat_sys_statfs_wrapper
 compat_sys_statfs_wrapper:
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # struct compat_statfs *
        jg      compat_sys_statfs       # branch to system call
 
-       .globl  compat_sys_fstatfs_wrapper 
+       .globl  compat_sys_fstatfs_wrapper
 compat_sys_fstatfs_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct compat_statfs *
        jg      compat_sys_fstatfs      # branch to system call
 
-       .globl  compat_sys_socketcall_wrapper 
+       .globl  compat_sys_socketcall_wrapper
 compat_sys_socketcall_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # u32 *
        jg      compat_sys_socketcall   # branch to system call
 
-       .globl  sys32_syslog_wrapper 
+       .globl  sys32_syslog_wrapper
 sys32_syslog_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # char *
        lgfr    %r4,%r4                 # int
        jg      sys_syslog              # branch to system call
 
-       .globl  compat_sys_setitimer_wrapper 
+       .globl  compat_sys_setitimer_wrapper
 compat_sys_setitimer_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct itimerval_emu31 *
        llgtr   %r4,%r4                 # struct itimerval_emu31 *
        jg      compat_sys_setitimer    # branch to system call
 
-       .globl  compat_sys_getitimer_wrapper 
+       .globl  compat_sys_getitimer_wrapper
 compat_sys_getitimer_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct itimerval_emu31 *
        jg      compat_sys_getitimer    # branch to system call
 
-       .globl  compat_sys_newstat_wrapper 
+       .globl  compat_sys_newstat_wrapper
 compat_sys_newstat_wrapper:
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # struct stat_emu31 *
        jg      compat_sys_newstat      # branch to system call
 
-       .globl  compat_sys_newlstat_wrapper 
+       .globl  compat_sys_newlstat_wrapper
 compat_sys_newlstat_wrapper:
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # struct stat_emu31 *
        jg      compat_sys_newlstat     # branch to system call
 
-       .globl  compat_sys_newfstat_wrapper 
+       .globl  compat_sys_newfstat_wrapper
 compat_sys_newfstat_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # struct stat_emu31 *
        jg      compat_sys_newfstat     # branch to system call
 
-#sys32_vhangup_wrapper                 # void 
+#sys32_vhangup_wrapper                 # void
 
-       .globl  compat_sys_wait4_wrapper 
+       .globl  compat_sys_wait4_wrapper
 compat_sys_wait4_wrapper:
        lgfr    %r2,%r2                 # pid_t
        llgtr   %r3,%r3                 # unsigned int *
@@ -512,17 +512,17 @@ compat_sys_wait4_wrapper:
        llgtr   %r5,%r5                 # struct rusage *
        jg      compat_sys_wait4        # branch to system call
 
-       .globl  sys32_swapoff_wrapper 
+       .globl  sys32_swapoff_wrapper
 sys32_swapoff_wrapper:
        llgtr   %r2,%r2                 # const char *
        jg      sys_swapoff             # branch to system call
 
-       .globl  sys32_sysinfo_wrapper 
+       .globl  sys32_sysinfo_wrapper
 sys32_sysinfo_wrapper:
        llgtr   %r2,%r2                 # struct sysinfo_emu31 *
        jg      sys32_sysinfo           # branch to system call
 
-       .globl  sys32_ipc_wrapper 
+       .globl  sys32_ipc_wrapper
 sys32_ipc_wrapper:
        llgfr   %r2,%r2                 # uint
        lgfr    %r3,%r3                 # int
@@ -531,59 +531,59 @@ sys32_ipc_wrapper:
        llgfr   %r6,%r6                 # u32
        jg      sys32_ipc               # branch to system call
 
-       .globl  sys32_fsync_wrapper 
+       .globl  sys32_fsync_wrapper
 sys32_fsync_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_fsync               # branch to system call
 
-#sys32_sigreturn_wrapper               # done in sigreturn_glue 
+#sys32_sigreturn_wrapper               # done in sigreturn_glue
 
-#sys32_clone_wrapper                   # done in clone_glue 
+#sys32_clone_wrapper                   # done in clone_glue
 
-       .globl  sys32_setdomainname_wrapper 
+       .globl  sys32_setdomainname_wrapper
 sys32_setdomainname_wrapper:
        llgtr   %r2,%r2                 # char *
        lgfr    %r3,%r3                 # int
        jg      sys_setdomainname       # branch to system call
 
-       .globl  sys32_newuname_wrapper 
+       .globl  sys32_newuname_wrapper
 sys32_newuname_wrapper:
        llgtr   %r2,%r2                 # struct new_utsname *
        jg      s390x_newuname          # branch to system call
 
-       .globl  compat_sys_adjtimex_wrapper
+       .globl  compat_sys_adjtimex_wrapper
 compat_sys_adjtimex_wrapper:
        llgtr   %r2,%r2                 # struct compat_timex *
        jg      compat_sys_adjtimex     # branch to system call
 
-       .globl  sys32_mprotect_wrapper 
+       .globl  sys32_mprotect_wrapper
 sys32_mprotect_wrapper:
        llgtr   %r2,%r2                 # unsigned long (actually pointer
        llgfr   %r3,%r3                 # size_t
        llgfr   %r4,%r4                 # unsigned long
        jg      sys_mprotect            # branch to system call
 
-       .globl  compat_sys_sigprocmask_wrapper 
+       .globl  compat_sys_sigprocmask_wrapper
 compat_sys_sigprocmask_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # compat_old_sigset_t *
        llgtr   %r4,%r4                 # compat_old_sigset_t *
        jg      compat_sys_sigprocmask          # branch to system call
 
-       .globl  sys32_init_module_wrapper 
+       .globl  sys32_init_module_wrapper
 sys32_init_module_wrapper:
        llgtr   %r2,%r2                 # void *
        llgfr   %r3,%r3                 # unsigned long
        llgtr   %r4,%r4                 # char *
        jg      sys32_init_module       # branch to system call
 
-       .globl  sys32_delete_module_wrapper 
+       .globl  sys32_delete_module_wrapper
 sys32_delete_module_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # unsigned int
        jg      sys32_delete_module     # branch to system call
 
-       .globl  sys32_quotactl_wrapper 
+       .globl  sys32_quotactl_wrapper
 sys32_quotactl_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # const char *
@@ -591,45 +591,45 @@ sys32_quotactl_wrapper:
        llgtr   %r5,%r5                 # caddr_t
        jg      sys_quotactl            # branch to system call
 
-       .globl  sys32_getpgid_wrapper 
+       .globl  sys32_getpgid_wrapper
 sys32_getpgid_wrapper:
        lgfr    %r2,%r2                 # pid_t
        jg      sys_getpgid             # branch to system call
 
-       .globl  sys32_fchdir_wrapper 
+       .globl  sys32_fchdir_wrapper
 sys32_fchdir_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_fchdir              # branch to system call
 
-       .globl  sys32_bdflush_wrapper 
+       .globl  sys32_bdflush_wrapper
 sys32_bdflush_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # long
        jg      sys_bdflush             # branch to system call
 
-       .globl  sys32_sysfs_wrapper 
+       .globl  sys32_sysfs_wrapper
 sys32_sysfs_wrapper:
        lgfr    %r2,%r2                 # int
        llgfr   %r3,%r3                 # unsigned long
        llgfr   %r4,%r4                 # unsigned long
        jg      sys_sysfs               # branch to system call
 
-       .globl  sys32_personality_wrapper 
+       .globl  sys32_personality_wrapper
 sys32_personality_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        jg      s390x_personality       # branch to system call
 
-       .globl  sys32_setfsuid16_wrapper 
+       .globl  sys32_setfsuid16_wrapper
 sys32_setfsuid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t
        jg      sys32_setfsuid16        # branch to system call
 
-       .globl  sys32_setfsgid16_wrapper 
+       .globl  sys32_setfsgid16_wrapper
 sys32_setfsgid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t
        jg      sys32_setfsgid16        # branch to system call
 
-       .globl  sys32_llseek_wrapper 
+       .globl  sys32_llseek_wrapper
 sys32_llseek_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned long
@@ -638,14 +638,14 @@ sys32_llseek_wrapper:
        llgfr   %r6,%r6                 # unsigned int
        jg      sys_llseek              # branch to system call
 
-       .globl  sys32_getdents_wrapper 
+       .globl  sys32_getdents_wrapper
 sys32_getdents_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # void *
        llgfr   %r4,%r4                 # unsigned int
        jg      compat_sys_getdents     # branch to system call
 
-       .globl  compat_sys_select_wrapper
+       .globl  compat_sys_select_wrapper
 compat_sys_select_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # compat_fd_set *
@@ -654,113 +654,113 @@ compat_sys_select_wrapper:
        llgtr   %r6,%r6                 # struct compat_timeval *
        jg      compat_sys_select       # branch to system call
 
-       .globl  sys32_flock_wrapper 
+       .globl  sys32_flock_wrapper
 sys32_flock_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned int
        jg      sys_flock               # branch to system call
 
-       .globl  sys32_msync_wrapper 
+       .globl  sys32_msync_wrapper
 sys32_msync_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # size_t
        lgfr    %r4,%r4                 # int
        jg      sys_msync               # branch to system call
 
-       .globl  compat_sys_readv_wrapper
+       .globl  compat_sys_readv_wrapper
 compat_sys_readv_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # const struct compat_iovec *
        llgfr   %r4,%r4                 # unsigned long
        jg      compat_sys_readv        # branch to system call
 
-       .globl  compat_sys_writev_wrapper
+       .globl  compat_sys_writev_wrapper
 compat_sys_writev_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # const struct compat_iovec *
        llgfr   %r4,%r4                 # unsigned long
        jg      compat_sys_writev       # branch to system call
 
-       .globl  sys32_getsid_wrapper 
+       .globl  sys32_getsid_wrapper
 sys32_getsid_wrapper:
        lgfr    %r2,%r2                 # pid_t
        jg      sys_getsid              # branch to system call
 
-       .globl  sys32_fdatasync_wrapper 
+       .globl  sys32_fdatasync_wrapper
 sys32_fdatasync_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        jg      sys_fdatasync           # branch to system call
 
-#sys32_sysctl_wrapper                  # tbd 
+#sys32_sysctl_wrapper                  # tbd
 
-       .globl  sys32_mlock_wrapper 
+       .globl  sys32_mlock_wrapper
 sys32_mlock_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # size_t
        jg      sys_mlock               # branch to system call
 
-       .globl  sys32_munlock_wrapper 
+       .globl  sys32_munlock_wrapper
 sys32_munlock_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # size_t
        jg      sys_munlock             # branch to system call
 
-       .globl  sys32_mlockall_wrapper 
+       .globl  sys32_mlockall_wrapper
 sys32_mlockall_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_mlockall            # branch to system call
 
-#sys32_munlockall_wrapper              # void 
+#sys32_munlockall_wrapper              # void
 
-       .globl  sys32_sched_setparam_wrapper 
+       .globl  sys32_sched_setparam_wrapper
 sys32_sched_setparam_wrapper:
        lgfr    %r2,%r2                 # pid_t
        llgtr   %r3,%r3                 # struct sched_param *
        jg      sys_sched_setparam      # branch to system call
 
-       .globl  sys32_sched_getparam_wrapper 
+       .globl  sys32_sched_getparam_wrapper
 sys32_sched_getparam_wrapper:
        lgfr    %r2,%r2                 # pid_t
        llgtr   %r3,%r3                 # struct sched_param *
        jg      sys_sched_getparam      # branch to system call
 
-       .globl  sys32_sched_setscheduler_wrapper 
+       .globl  sys32_sched_setscheduler_wrapper
 sys32_sched_setscheduler_wrapper:
        lgfr    %r2,%r2                 # pid_t
        lgfr    %r3,%r3                 # int
        llgtr   %r4,%r4                 # struct sched_param *
        jg      sys_sched_setscheduler  # branch to system call
 
-       .globl  sys32_sched_getscheduler_wrapper 
+       .globl  sys32_sched_getscheduler_wrapper
 sys32_sched_getscheduler_wrapper:
        lgfr    %r2,%r2                 # pid_t
        jg      sys_sched_getscheduler  # branch to system call
 
-#sys32_sched_yield_wrapper             # void 
+#sys32_sched_yield_wrapper             # void
 
-       .globl  sys32_sched_get_priority_max_wrapper 
+       .globl  sys32_sched_get_priority_max_wrapper
 sys32_sched_get_priority_max_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_sched_get_priority_max      # branch to system call
 
-       .globl  sys32_sched_get_priority_min_wrapper 
+       .globl  sys32_sched_get_priority_min_wrapper
 sys32_sched_get_priority_min_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_sched_get_priority_min      # branch to system call
 
-       .globl  sys32_sched_rr_get_interval_wrapper 
+       .globl  sys32_sched_rr_get_interval_wrapper
 sys32_sched_rr_get_interval_wrapper:
        lgfr    %r2,%r2                 # pid_t
        llgtr   %r3,%r3                 # struct compat_timespec *
        jg      sys32_sched_rr_get_interval     # branch to system call
 
-       .globl  compat_sys_nanosleep_wrapper 
+       .globl  compat_sys_nanosleep_wrapper
 compat_sys_nanosleep_wrapper:
        llgtr   %r2,%r2                 # struct compat_timespec *
        llgtr   %r3,%r3                 # struct compat_timespec *
        jg      compat_sys_nanosleep            # branch to system call
 
-       .globl  sys32_mremap_wrapper 
+       .globl  sys32_mremap_wrapper
 sys32_mremap_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # unsigned long
@@ -769,49 +769,49 @@ sys32_mremap_wrapper:
        llgfr   %r6,%r6                 # unsigned long
        jg      sys_mremap              # branch to system call
 
-       .globl  sys32_setresuid16_wrapper 
+       .globl  sys32_setresuid16_wrapper
 sys32_setresuid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t 
-       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t 
-       llgfr   %r4,%r4                 # __kernel_old_uid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_uid_emu31_t
+       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t
+       llgfr   %r4,%r4                 # __kernel_old_uid_emu31_t
        jg      sys32_setresuid16       # branch to system call
 
-       .globl  sys32_getresuid16_wrapper 
+       .globl  sys32_getresuid16_wrapper
 sys32_getresuid16_wrapper:
        llgtr   %r2,%r2                 # __kernel_old_uid_emu31_t *
        llgtr   %r3,%r3                 # __kernel_old_uid_emu31_t *
        llgtr   %r4,%r4                 # __kernel_old_uid_emu31_t *
        jg      sys32_getresuid16       # branch to system call
 
-       .globl  sys32_poll_wrapper 
+       .globl  sys32_poll_wrapper
 sys32_poll_wrapper:
-       llgtr   %r2,%r2                 # struct pollfd * 
-       llgfr   %r3,%r3                 # unsigned int 
-       lgfr    %r4,%r4                 # long 
+       llgtr   %r2,%r2                 # struct pollfd *
+       llgfr   %r3,%r3                 # unsigned int
+       lgfr    %r4,%r4                 # long
        jg      sys_poll                # branch to system call
 
-       .globl  compat_sys_nfsservctl_wrapper
+       .globl  compat_sys_nfsservctl_wrapper
 compat_sys_nfsservctl_wrapper:
-       lgfr    %r2,%r2                 # int 
+       lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct compat_nfsctl_arg*
        llgtr   %r4,%r4                 # union compat_nfsctl_res*
        jg      compat_sys_nfsservctl   # branch to system call
 
-       .globl  sys32_setresgid16_wrapper 
+       .globl  sys32_setresgid16_wrapper
 sys32_setresgid16_wrapper:
-       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t 
-       llgfr   %r3,%r3                 # __kernel_old_gid_emu31_t 
-       llgfr   %r4,%r4                 # __kernel_old_gid_emu31_t 
+       llgfr   %r2,%r2                 # __kernel_old_gid_emu31_t
+       llgfr   %r3,%r3                 # __kernel_old_gid_emu31_t
+       llgfr   %r4,%r4                 # __kernel_old_gid_emu31_t
        jg      sys32_setresgid16       # branch to system call
 
-       .globl  sys32_getresgid16_wrapper 
+       .globl  sys32_getresgid16_wrapper
 sys32_getresgid16_wrapper:
        llgtr   %r2,%r2                 # __kernel_old_gid_emu31_t *
        llgtr   %r3,%r3                 # __kernel_old_gid_emu31_t *
        llgtr   %r4,%r4                 # __kernel_old_gid_emu31_t *
        jg      sys32_getresgid16       # branch to system call
 
-       .globl  sys32_prctl_wrapper 
+       .globl  sys32_prctl_wrapper
 sys32_prctl_wrapper:
        lgfr    %r2,%r2                 # int
        llgfr   %r3,%r3                 # unsigned long
@@ -820,9 +820,9 @@ sys32_prctl_wrapper:
        llgfr   %r6,%r6                 # unsigned long
        jg      sys_prctl               # branch to system call
 
-#sys32_rt_sigreturn_wrapper            # done in rt_sigreturn_glue 
+#sys32_rt_sigreturn_wrapper            # done in rt_sigreturn_glue
 
-       .globl  sys32_rt_sigaction_wrapper 
+       .globl  sys32_rt_sigaction_wrapper
 sys32_rt_sigaction_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # const struct sigaction_emu31 *
@@ -830,7 +830,7 @@ sys32_rt_sigaction_wrapper:
        llgfr   %r5,%r5                 # size_t
        jg      sys32_rt_sigaction      # branch to system call
 
-       .globl  sys32_rt_sigprocmask_wrapper 
+       .globl  sys32_rt_sigprocmask_wrapper
 sys32_rt_sigprocmask_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # old_sigset_emu31 *
@@ -838,13 +838,13 @@ sys32_rt_sigprocmask_wrapper:
        llgfr   %r5,%r5                 # size_t
        jg      sys32_rt_sigprocmask    # branch to system call
 
-       .globl  sys32_rt_sigpending_wrapper 
+       .globl  sys32_rt_sigpending_wrapper
 sys32_rt_sigpending_wrapper:
        llgtr   %r2,%r2                 # sigset_emu31 *
        llgfr   %r3,%r3                 # size_t
        jg      sys32_rt_sigpending     # branch to system call
 
-       .globl  compat_sys_rt_sigtimedwait_wrapper
+       .globl  compat_sys_rt_sigtimedwait_wrapper
 compat_sys_rt_sigtimedwait_wrapper:
        llgtr   %r2,%r2                 # const sigset_emu31_t *
        llgtr   %r3,%r3                 # siginfo_emu31_t *
@@ -852,7 +852,7 @@ compat_sys_rt_sigtimedwait_wrapper:
        llgfr   %r5,%r5                 # size_t
        jg      compat_sys_rt_sigtimedwait      # branch to system call
 
-       .globl  sys32_rt_sigqueueinfo_wrapper 
+       .globl  sys32_rt_sigqueueinfo_wrapper
 sys32_rt_sigqueueinfo_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
@@ -865,7 +865,7 @@ compat_sys_rt_sigsuspend_wrapper:
        llgfr   %r3,%r3                 # compat_size_t
        jg      compat_sys_rt_sigsuspend
 
-       .globl  sys32_pread64_wrapper 
+       .globl  sys32_pread64_wrapper
 sys32_pread64_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # char *
@@ -874,7 +874,7 @@ sys32_pread64_wrapper:
        llgfr   %r6,%r6                 # u32
        jg      sys32_pread64           # branch to system call
 
-       .globl  sys32_pwrite64_wrapper 
+       .globl  sys32_pwrite64_wrapper
 sys32_pwrite64_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # const char *
@@ -883,26 +883,26 @@ sys32_pwrite64_wrapper:
        llgfr   %r6,%r6                 # u32
        jg      sys32_pwrite64          # branch to system call
 
-       .globl  sys32_chown16_wrapper 
+       .globl  sys32_chown16_wrapper
 sys32_chown16_wrapper:
        llgtr   %r2,%r2                 # const char *
-       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t 
-       llgfr   %r4,%r4                 # __kernel_old_gid_emu31_t 
+       llgfr   %r3,%r3                 # __kernel_old_uid_emu31_t
+       llgfr   %r4,%r4                 # __kernel_old_gid_emu31_t
        jg      sys32_chown16           # branch to system call
 
-       .globl  sys32_getcwd_wrapper 
+       .globl  sys32_getcwd_wrapper
 sys32_getcwd_wrapper:
        llgtr   %r2,%r2                 # char *
        llgfr   %r3,%r3                 # unsigned long
        jg      sys_getcwd              # branch to system call
 
-       .globl  sys32_capget_wrapper 
+       .globl  sys32_capget_wrapper
 sys32_capget_wrapper:
        llgtr   %r2,%r2                 # cap_user_header_t
        llgtr   %r3,%r3                 # cap_user_data_t
        jg      sys_capget              # branch to system call
 
-       .globl  sys32_capset_wrapper 
+       .globl  sys32_capset_wrapper
 sys32_capset_wrapper:
        llgtr   %r2,%r2                 # cap_user_header_t
        llgtr   %r3,%r3                 # const cap_user_data_t
@@ -910,11 +910,11 @@ sys32_capset_wrapper:
 
        .globl sys32_sigaltstack_wrapper
 sys32_sigaltstack_wrapper:
-       llgtr   %r2,%r2                 # const stack_emu31_t * 
-       llgtr   %r3,%r3                 # stack_emu31_t * 
+       llgtr   %r2,%r2                 # const stack_emu31_t *
+       llgtr   %r3,%r3                 # stack_emu31_t *
        jg      sys32_sigaltstack
 
-       .globl  sys32_sendfile_wrapper 
+       .globl  sys32_sendfile_wrapper
 sys32_sendfile_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
@@ -922,33 +922,33 @@ sys32_sendfile_wrapper:
        llgfr   %r5,%r5                 # size_t
        jg      sys32_sendfile          # branch to system call
 
-#sys32_vfork_wrapper                   # done in vfork_glue 
+#sys32_vfork_wrapper                   # done in vfork_glue
 
-       .globl  sys32_truncate64_wrapper 
+       .globl  sys32_truncate64_wrapper
 sys32_truncate64_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # unsigned long
        llgfr   %r4,%r4                 # unsigned long
        jg      sys32_truncate64        # branch to system call
 
-       .globl  sys32_ftruncate64_wrapper 
+       .globl  sys32_ftruncate64_wrapper
 sys32_ftruncate64_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # unsigned long
        llgfr   %r4,%r4                 # unsigned long
        jg      sys32_ftruncate64       # branch to system call
 
-       .globl sys32_lchown_wrapper     
+       .globl sys32_lchown_wrapper
 sys32_lchown_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # uid_t
        llgfr   %r4,%r4                 # gid_t
        jg      sys_lchown              # branch to system call
 
-#sys32_getuid_wrapper                  # void                   
-#sys32_getgid_wrapper                  # void 
-#sys32_geteuid_wrapper                 # void 
-#sys32_getegid_wrapper                 # void 
+#sys32_getuid_wrapper                  # void
+#sys32_getgid_wrapper                  # void
+#sys32_geteuid_wrapper                 # void
+#sys32_getegid_wrapper                 # void
 
        .globl sys32_setreuid_wrapper
 sys32_setreuid_wrapper:
@@ -962,111 +962,111 @@ sys32_setregid_wrapper:
        llgfr   %r3,%r3                 # gid_t
        jg      sys_setregid            # branch to system call
 
-       .globl  sys32_getgroups_wrapper 
+       .globl  sys32_getgroups_wrapper
 sys32_getgroups_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # gid_t *
        jg      sys_getgroups           # branch to system call
 
-       .globl  sys32_setgroups_wrapper 
+       .globl  sys32_setgroups_wrapper
 sys32_setgroups_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # gid_t *
        jg      sys_setgroups           # branch to system call
 
-       .globl sys32_fchown_wrapper     
+       .globl sys32_fchown_wrapper
 sys32_fchown_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgfr   %r3,%r3                 # uid_t
        llgfr   %r4,%r4                 # gid_t
        jg      sys_fchown              # branch to system call
 
-       .globl sys32_setresuid_wrapper  
+       .globl sys32_setresuid_wrapper
 sys32_setresuid_wrapper:
        llgfr   %r2,%r2                 # uid_t
        llgfr   %r3,%r3                 # uid_t
        llgfr   %r4,%r4                 # uid_t
        jg      sys_setresuid           # branch to system call
 
-       .globl sys32_getresuid_wrapper  
+       .globl sys32_getresuid_wrapper
 sys32_getresuid_wrapper:
        llgtr   %r2,%r2                 # uid_t *
        llgtr   %r3,%r3                 # uid_t *
        llgtr   %r4,%r4                 # uid_t *
        jg      sys_getresuid           # branch to system call
 
-       .globl sys32_setresgid_wrapper  
+       .globl sys32_setresgid_wrapper
 sys32_setresgid_wrapper:
        llgfr   %r2,%r2                 # gid_t
        llgfr   %r3,%r3                 # gid_t
        llgfr   %r4,%r4                 # gid_t
        jg      sys_setresgid           # branch to system call
 
-       .globl sys32_getresgid_wrapper  
+       .globl sys32_getresgid_wrapper
 sys32_getresgid_wrapper:
        llgtr   %r2,%r2                 # gid_t *
        llgtr   %r3,%r3                 # gid_t *
        llgtr   %r4,%r4                 # gid_t *
        jg      sys_getresgid           # branch to system call
 
-       .globl sys32_chown_wrapper      
+       .globl sys32_chown_wrapper
 sys32_chown_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgfr   %r3,%r3                 # uid_t
        llgfr   %r4,%r4                 # gid_t
        jg      sys_chown               # branch to system call
 
-       .globl sys32_setuid_wrapper     
+       .globl sys32_setuid_wrapper
 sys32_setuid_wrapper:
        llgfr   %r2,%r2                 # uid_t
        jg      sys_setuid              # branch to system call
 
-       .globl sys32_setgid_wrapper     
+       .globl sys32_setgid_wrapper
 sys32_setgid_wrapper:
        llgfr   %r2,%r2                 # gid_t
        jg      sys_setgid              # branch to system call
 
-       .globl sys32_setfsuid_wrapper   
+       .globl sys32_setfsuid_wrapper
 sys32_setfsuid_wrapper:
        llgfr   %r2,%r2                 # uid_t
        jg      sys_setfsuid            # branch to system call
 
-       .globl sys32_setfsgid_wrapper   
+       .globl sys32_setfsgid_wrapper
 sys32_setfsgid_wrapper:
        llgfr   %r2,%r2                 # gid_t
        jg      sys_setfsgid            # branch to system call
 
-       .globl  sys32_pivot_root_wrapper 
+       .globl  sys32_pivot_root_wrapper
 sys32_pivot_root_wrapper:
        llgtr   %r2,%r2                 # const char *
        llgtr   %r3,%r3                 # const char *
        jg      sys_pivot_root          # branch to system call
 
-       .globl  sys32_mincore_wrapper 
+       .globl  sys32_mincore_wrapper
 sys32_mincore_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # size_t
        llgtr   %r4,%r4                 # unsigned char *
        jg      sys_mincore             # branch to system call
 
-       .globl  sys32_madvise_wrapper 
+       .globl  sys32_madvise_wrapper
 sys32_madvise_wrapper:
        llgfr   %r2,%r2                 # unsigned long
        llgfr   %r3,%r3                 # size_t
        lgfr    %r4,%r4                 # int
        jg      sys_madvise             # branch to system call
 
-       .globl  sys32_getdents64_wrapper 
+       .globl  sys32_getdents64_wrapper
 sys32_getdents64_wrapper:
        llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # void *
        llgfr   %r4,%r4                 # unsigned int
        jg      sys_getdents64          # branch to system call
 
-       .globl  compat_sys_fcntl64_wrapper 
+       .globl  compat_sys_fcntl64_wrapper
 compat_sys_fcntl64_wrapper:
        llgfr   %r2,%r2                 # unsigned int
-       llgfr   %r3,%r3                 # unsigned int 
+       llgfr   %r3,%r3                 # unsigned int
        llgfr   %r4,%r4                 # unsigned long
        jg      compat_sys_fcntl64      # branch to system call
 
@@ -1087,10 +1087,10 @@ sys32_stime_wrapper:
        llgtr   %r2,%r2                 # long *
        jg      compat_sys_stime        # branch to system call
 
-       .globl  sys32_sysctl_wrapper
+       .globl  sys32_sysctl_wrapper
 sys32_sysctl_wrapper:
-       llgtr   %r2,%r2                 # struct __sysctl_args32 *
-       jg      sys32_sysctl
+       llgtr   %r2,%r2                 # struct __sysctl_args32 *
+       jg      sys32_sysctl
 
        .globl  sys32_fstat64_wrapper
 sys32_fstat64_wrapper:
@@ -1098,7 +1098,7 @@ sys32_fstat64_wrapper:
        llgtr   %r3,%r3                 # struct stat64 *
        jg      sys32_fstat64           # branch to system call
 
-       .globl  compat_sys_futex_wrapper 
+       .globl  compat_sys_futex_wrapper
 compat_sys_futex_wrapper:
        llgtr   %r2,%r2                 # u32 *
        lgfr    %r3,%r3                 # int
@@ -1213,22 +1213,22 @@ sys32_sched_getaffinity_wrapper:
        llgtr   %r4,%r4                 # unsigned long *
        jg      compat_sys_sched_getaffinity
 
-       .globl  sys32_exit_group_wrapper
+       .globl  sys32_exit_group_wrapper
 sys32_exit_group_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_exit_group          # branch to system call
 
-       .globl  sys32_set_tid_address_wrapper
+       .globl  sys32_set_tid_address_wrapper
 sys32_set_tid_address_wrapper:
        llgtr   %r2,%r2                 # int *
        jg      sys_set_tid_address     # branch to system call
 
-       .globl  sys_epoll_create_wrapper
+       .globl  sys_epoll_create_wrapper
 sys_epoll_create_wrapper:
        lgfr    %r2,%r2                 # int
        jg      sys_epoll_create        # branch to system call
 
-       .globl  sys_epoll_ctl_wrapper
+       .globl  sys_epoll_ctl_wrapper
 sys_epoll_ctl_wrapper:
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
@@ -1236,7 +1236,7 @@ sys_epoll_ctl_wrapper:
        llgtr   %r5,%r5                 # struct epoll_event *
        jg      sys_epoll_ctl           # branch to system call
 
-       .globl  sys_epoll_wait_wrapper
+       .globl  sys_epoll_wait_wrapper
 sys_epoll_wait_wrapper:
        lgfr    %r2,%r2                 # int
        llgtr   %r3,%r3                 # struct epoll_event *
index 4ef44e536b2c6495a7ff5e05c4f7e5d444d40042..1eae74e72f9525f91a11f56a012f815582157500 100644 (file)
@@ -25,11 +25,8 @@ static char cpcmd_buf[241];
  */
 int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
-       const int mask = 0x40000000L;
-       unsigned long flags;
-       int return_code;
-       int return_len;
-       int cmdlen;
+       unsigned long flags, cmdlen;
+       int return_code, return_len;
 
        spin_lock_irqsave(&cpcmd_lock, flags);
        cmdlen = strlen(cmd);
@@ -38,64 +35,44 @@ int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
        ASCEBC(cpcmd_buf, cmdlen);
 
        if (response != NULL && rlen > 0) {
+               register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+               register unsigned long reg3 asm ("3") = (addr_t) response;
+               register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
+               register unsigned long reg5 asm ("5") = rlen;
+
                memset(response, 0, rlen);
+               asm volatile(
 #ifndef CONFIG_64BIT
-               asm volatile (  "lra    2,0(%2)\n"
-                               "lr     4,%3\n"
-                               "o      4,%6\n"
-                               "lra    3,0(%4)\n"
-                               "lr     5,%5\n"
-                               "diag   2,4,0x8\n"
-                               "brc    8, 1f\n"
-                               "ar     5, %5\n"
-                               "1: \n"
-                               "lr     %0,4\n"
-                               "lr     %1,5\n"
-                               : "=d" (return_code), "=d" (return_len)
-                               : "a" (cpcmd_buf), "d" (cmdlen),
-                               "a" (response), "d" (rlen), "m" (mask)
-                               : "cc", "2", "3", "4", "5" );
+                       "       diag    %2,%0,0x8\n"
+                       "       brc     8,1f\n"
+                       "       ar      %1,%4\n"
 #else /* CONFIG_64BIT */
-                asm volatile ( "lrag   2,0(%2)\n"
-                               "lgr    4,%3\n"
-                               "o      4,%6\n"
-                               "lrag   3,0(%4)\n"
-                               "lgr    5,%5\n"
-                               "sam31\n"
-                               "diag   2,4,0x8\n"
-                               "sam64\n"
-                               "brc    8, 1f\n"
-                               "agr    5, %5\n"
-                               "1: \n"
-                               "lgr    %0,4\n"
-                               "lgr    %1,5\n"
-                               : "=d" (return_code), "=d" (return_len)
-                               : "a" (cpcmd_buf), "d" (cmdlen),
-                               "a" (response), "d" (rlen), "m" (mask)
-                               : "cc", "2", "3", "4", "5" );
+                       "       sam31\n"
+                       "       diag    %2,%0,0x8\n"
+                       "       sam64\n"
+                       "       brc     8,1f\n"
+                       "       agr     %1,%4\n"
 #endif /* CONFIG_64BIT */
+                       "1:\n"
+                       : "+d" (reg4), "+d" (reg5)
+                       : "d" (reg2), "d" (reg3), "d" (rlen) : "cc");
+               return_code = (int) reg4;
+               return_len = (int) reg5;
                 EBCASC(response, rlen);
         } else {
+               register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+               register unsigned long reg3 asm ("3") = cmdlen;
                return_len = 0;
+               asm volatile(
 #ifndef CONFIG_64BIT
-                asm volatile ( "lra    2,0(%1)\n"
-                               "lr     3,%2\n"
-                               "diag   2,3,0x8\n"
-                               "lr     %0,3\n"
-                               : "=d" (return_code)
-                               : "a" (cpcmd_buf), "d" (cmdlen)
-                               : "2", "3"  );
+                       "       diag    %1,%0,0x8\n"
 #else /* CONFIG_64BIT */
-                asm volatile ( "lrag   2,0(%1)\n"
-                               "lgr    3,%2\n"
-                               "sam31\n"
-                               "diag   2,3,0x8\n"
-                               "sam64\n"
-                               "lgr    %0,3\n"
-                               : "=d" (return_code)
-                               : "a" (cpcmd_buf), "d" (cmdlen)
-                               : "2", "3" );
+                       "       sam31\n"
+                       "       diag    %1,%0,0x8\n"
+                       "       sam64\n"
 #endif /* CONFIG_64BIT */
+                       : "+d" (reg3) : "d" (reg2) : "cc");
+               return_code = (int) reg3;
         }
        spin_unlock_irqrestore(&cpcmd_lock, flags);
        if (response_code != NULL)
index 0c712b78a7e82480f5392381c89112e8550d5da0..dddc3de304019d927bfe1cbec00b1ceb2d4ee1af 100644 (file)
@@ -4,8 +4,8 @@
  *
  *    Copyright (C) IBM Corp. 1999,2006
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Hartmut Penner (hp@de.ibm.com),
- *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *              Hartmut Penner (hp@de.ibm.com),
+ *              Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  *              Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
  * Stack layout for the system_call stack entry.
  * The first few entries are identical to the user_regs_struct.
  */
-SP_PTREGS    =  STACK_FRAME_OVERHEAD
-SP_ARGS      =  STACK_FRAME_OVERHEAD + __PT_ARGS
-SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
-SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
-SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 4
-SP_R2        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
-SP_R3        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 12
-SP_R4        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
-SP_R5        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 20
-SP_R6        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
-SP_R7        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 28
-SP_R8        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
-SP_R9        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 36
-SP_R10       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
-SP_R11       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 44
-SP_R12       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
-SP_R13       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 52
-SP_R14       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
-SP_R15       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 60
-SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
-SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
-SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
-SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
+SP_PTREGS    = STACK_FRAME_OVERHEAD
+SP_ARGS      = STACK_FRAME_OVERHEAD + __PT_ARGS
+SP_PSW      =  STACK_FRAME_OVERHEAD + __PT_PSW
+SP_R0       =  STACK_FRAME_OVERHEAD + __PT_GPRS
+SP_R1       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 4
+SP_R2       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
+SP_R3       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 12
+SP_R4       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
+SP_R5       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 20
+SP_R6       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
+SP_R7       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 28
+SP_R8       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
+SP_R9       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 36
+SP_R10      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
+SP_R11      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 44
+SP_R12      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
+SP_R13      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 52
+SP_R14      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
+SP_R15      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 60
+SP_ORIG_R2   = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
+SP_ILC      =  STACK_FRAME_OVERHEAD + __PT_ILC
+SP_TRAP      = STACK_FRAME_OVERHEAD + __PT_TRAP
+SP_SIZE      = STACK_FRAME_OVERHEAD + __PT_SIZE
 
 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
                 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
@@ -81,14 +81,14 @@ STACK_SIZE  = 1 << STACK_SHIFT
  *    R15 - kernel stack pointer
  */
 
-       .macro  STORE_TIMER lc_offset
+       .macro  STORE_TIMER lc_offset
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        stpt    \lc_offset
 #endif
        .endm
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       .macro  UPDATE_VTIME lc_from,lc_to,lc_sum
+       .macro  UPDATE_VTIME lc_from,lc_to,lc_sum
        lm      %r10,%r11,\lc_from
        sl      %r10,\lc_to
        sl      %r11,\lc_to+4
@@ -147,7 +147,7 @@ STACK_SIZE  = 1 << STACK_SHIFT
 2:
        .endm
 
-       .macro  CREATE_STACK_FRAME psworg,savearea
+       .macro  CREATE_STACK_FRAME psworg,savearea
        s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
        la      %r12,\psworg
@@ -160,7 +160,7 @@ STACK_SIZE  = 1 << STACK_SHIFT
        st      %r12,__SF_BACKCHAIN(%r15)       # clear back chain
        .endm
 
-       .macro  RESTORE_ALL psworg,sync
+       .macro  RESTORE_ALL psworg,sync
        mvc     \psworg(8),SP_PSW(%r15) # move user PSW to lowcore
        .if !\sync
        ni      \psworg+1,0xfd          # clear wait state bit
@@ -177,16 +177,16 @@ STACK_SIZE  = 1 << STACK_SHIFT
  * Returns:
  *  gpr2 = prev
  */
-        .globl  __switch_to
+       .globl  __switch_to
 __switch_to:
-        basr    %r1,0
+       basr    %r1,0
 __switch_to_base:
        tm      __THREAD_per(%r3),0xe8          # new process is using per ?
        bz      __switch_to_noper-__switch_to_base(%r1) # if not we're fine
-        stctl   %c9,%c11,__SF_EMPTY(%r15)      # We are using per stuff
-        clc     __THREAD_per(12,%r3),__SF_EMPTY(%r15)
-        be      __switch_to_noper-__switch_to_base(%r1)        # we got away w/o bashing TLB's
-        lctl    %c9,%c11,__THREAD_per(%r3)     # Nope we didn't
+       stctl   %c9,%c11,__SF_EMPTY(%r15)       # We are using per stuff
+       clc     __THREAD_per(12,%r3),__SF_EMPTY(%r15)
+       be      __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's
+       lctl    %c9,%c11,__THREAD_per(%r3)      # Nope we didn't
 __switch_to_noper:
        l       %r4,__THREAD_info(%r2)          # get thread_info of prev
        tm      __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
@@ -195,13 +195,13 @@ __switch_to_noper:
        l       %r4,__THREAD_info(%r3)          # get thread_info of next
        oi      __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
 __switch_to_no_mcck:
-        stm     %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
+       stm     %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
        st      %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
        l       %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
        lm      %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
        st      %r3,__LC_CURRENT        # __LC_CURRENT = current task struct
        lctl    %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
-       l       %r3,__THREAD_info(%r3)  # load thread_info from task struct
+       l       %r3,__THREAD_info(%r3)  # load thread_info from task struct
        st      %r3,__LC_THREAD_INFO
        ahi     %r3,STACK_SIZE
        st      %r3,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
@@ -213,7 +213,7 @@ __critical_start:
  * are executed with interrupts enabled.
  */
 
-       .globl  system_call
+       .globl  system_call
 system_call:
        STORE_TIMER __LC_SYNC_ENTER_TIMER
 sysc_saveall:
@@ -233,24 +233,24 @@ sysc_update:
 #endif
 sysc_do_svc:
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       sla     %r7,2             # *4 and test for svc 0
-       bnz     BASED(sysc_nr_ok) # svc number > 0
+       sla     %r7,2                   # *4 and test for svc 0
+       bnz     BASED(sysc_nr_ok)       # svc number > 0
        # svc 0: system call number in %r1
        cl      %r1,BASED(.Lnr_syscalls)
        bnl     BASED(sysc_nr_ok)
-       lr      %r7,%r1           # copy svc number to %r7
-       sla     %r7,2             # *4
+       lr      %r7,%r1           # copy svc number to %r7
+       sla     %r7,2             # *4
 sysc_nr_ok:
        mvc     SP_ARGS(4,%r15),SP_R7(%r15)
 sysc_do_restart:
        l       %r8,BASED(.Lsysc_table)
        tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
        l       %r8,0(%r7,%r8)    # get system call addr.
-        bnz     BASED(sysc_tracesys)
-        basr    %r14,%r8          # call sys_xxxx
-        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
-                                  # ATTENTION: check sys_execve_glue before
-                                  # changing anything here !!
+       bnz     BASED(sysc_tracesys)
+       basr    %r14,%r8          # call sys_xxxx
+       st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
+                                 # ATTENTION: check sys_execve_glue before
+                                 # changing anything here !!
 
 sysc_return:
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
@@ -258,14 +258,14 @@ sysc_return:
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_leave:
-        RESTORE_ALL __LC_RETURN_PSW,1
+       RESTORE_ALL __LC_RETURN_PSW,1
 
 #
 # recheck if there is more work to do
 #
 sysc_work_loop:
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
-       bz      BASED(sysc_leave)      # there is no work to do
+       bz      BASED(sysc_leave)       # there is no work to do
 #
 # One of the work bits is on. Find out which one.
 #
@@ -284,11 +284,11 @@ sysc_work:
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
-#      
-sysc_reschedule:        
-        l       %r1,BASED(.Lschedule)
-       la      %r14,BASED(sysc_work_loop)
-       br      %r1                    # call scheduler
+#
+sysc_reschedule:
+       l       %r1,BASED(.Lschedule)
+       la      %r14,BASED(sysc_work_loop)
+       br      %r1                     # call scheduler
 
 #
 # _TIF_MCCK_PENDING is set, call handler
@@ -301,11 +301,11 @@ sysc_mcck_pending:
 #
 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
-sysc_sigpending:     
+sysc_sigpending:
        ni      __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        l       %r1,BASED(.Ldo_signal)
-       basr    %r14,%r1               # call do_signal
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Ldo_signal)
+       basr    %r14,%r1                # call do_signal
        tm      __TI_flags+3(%r9),_TIF_RESTART_SVC
        bo      BASED(sysc_restart)
        tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
@@ -317,11 +317,11 @@ sysc_sigpending:
 #
 sysc_restart:
        ni      __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
-       l       %r7,SP_R2(%r15)        # load new svc number
+       l       %r7,SP_R2(%r15)         # load new svc number
        sla     %r7,2
        mvc     SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
-       lm      %r2,%r6,SP_R2(%r15)    # load svc arguments
-       b       BASED(sysc_do_restart) # restart svc
+       lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
+       b       BASED(sysc_do_restart)  # restart svc
 
 #
 # _TIF_SINGLE_STEP is set, call do_single_step
@@ -338,8 +338,8 @@ sysc_singlestep:
 # call trace before and after sys_call
 #
 sysc_tracesys:
-        l       %r1,BASED(.Ltrace)
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
+       l       %r1,BASED(.Ltrace)
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        la      %r3,0
        srl     %r7,2
        st      %r7,SP_R2(%r15)
@@ -347,19 +347,19 @@ sysc_tracesys:
        clc     SP_R2(4,%r15),BASED(.Lnr_syscalls)
        bnl     BASED(sysc_tracenogo)
        l       %r8,BASED(.Lsysc_table)
-       l       %r7,SP_R2(%r15)        # strace might have changed the 
-       sll     %r7,2                  #  system call
+       l       %r7,SP_R2(%r15)         # strace might have changed the
+       sll     %r7,2                   #  system call
        l       %r8,0(%r7,%r8)
 sysc_tracego:
        lm      %r3,%r6,SP_R3(%r15)
        l       %r2,SP_ORIG_R2(%r15)
-       basr    %r14,%r8          # call sys_xxx
-       st      %r2,SP_R2(%r15)   # store return value
+       basr    %r14,%r8                # call sys_xxx
+       st      %r2,SP_R2(%r15)         # store return value
 sysc_tracenogo:
        tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        bz      BASED(sysc_return)
+       bz      BASED(sysc_return)
        l       %r1,BASED(.Ltrace)
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        la      %r3,1
        la      %r14,BASED(sysc_return)
        br      %r1
@@ -367,17 +367,17 @@ sysc_tracenogo:
 #
 # a new process exits the kernel with ret_from_fork
 #
-        .globl  ret_from_fork
+       .globl  ret_from_fork
 ret_from_fork:
        l       %r13,__LC_SVC_NEW_PSW+4
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # forking a kernel thread ?
        bo      BASED(0f)
        st      %r15,SP_R15(%r15)       # store stack pointer for new kthread
-0:     l       %r1,BASED(.Lschedtail)
-       basr    %r14,%r1
+0:     l       %r1,BASED(.Lschedtail)
+       basr    %r14,%r1
        TRACE_IRQS_ON
-        stosm   __SF_EMPTY(%r15),0x03     # reenable interrupts
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        b       BASED(sysc_return)
 
 #
@@ -386,52 +386,51 @@ ret_from_fork:
 # but are called with different parameter.
 # return-address is set up above
 #
-sys_clone_glue: 
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        l       %r1,BASED(.Lclone)
-        br      %r1                   # branch to sys_clone
-
-sys_fork_glue:  
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        l       %r1,BASED(.Lfork)
-        br      %r1                   # branch to sys_fork
-
-sys_vfork_glue: 
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        l       %r1,BASED(.Lvfork)
-        br      %r1                   # branch to sys_vfork
-
-sys_execve_glue:        
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs
-        l       %r1,BASED(.Lexecve)
-       lr      %r12,%r14             # save return address
-        basr    %r14,%r1              # call sys_execve
-        ltr     %r2,%r2               # check if execve failed
-        bnz     0(%r12)               # it did fail -> store result in gpr2
-        b       4(%r12)               # SKIP ST 2,SP_R2(15) after BASR 14,8
-                                      # in system_call/sysc_tracesys
-
-sys_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        l       %r1,BASED(.Lsigreturn)
-        br      %r1                   # branch to sys_sigreturn
-
-sys_rt_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        l       %r1,BASED(.Lrt_sigreturn)
-        br      %r1                   # branch to sys_sigreturn
+sys_clone_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Lclone)
+       br      %r1                     # branch to sys_clone
 
-sys_sigaltstack_glue:
-        la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
-        l       %r1,BASED(.Lsigaltstack)
-        br      %r1                   # branch to sys_sigreturn
+sys_fork_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Lfork)
+       br      %r1                     # branch to sys_fork
 
+sys_vfork_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Lvfork)
+       br      %r1                     # branch to sys_vfork
+
+sys_execve_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Lexecve)
+       lr      %r12,%r14               # save return address
+       basr    %r14,%r1                # call sys_execve
+       ltr     %r2,%r2                 # check if execve failed
+       bnz     0(%r12)                 # it did fail -> store result in gpr2
+       b       4(%r12)                 # SKIP ST 2,SP_R2(15) after BASR 14,8
+                                       # in system_call/sysc_tracesys
+
+sys_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       l       %r1,BASED(.Lsigreturn)
+       br      %r1                     # branch to sys_sigreturn
+
+sys_rt_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       l       %r1,BASED(.Lrt_sigreturn)
+       br      %r1                     # branch to sys_sigreturn
+
+sys_sigaltstack_glue:
+       la      %r4,SP_PTREGS(%r15)     # load pt_regs as parameter
+       l       %r1,BASED(.Lsigaltstack)
+       br      %r1                     # branch to sys_sigreturn
 
 /*
  * Program check handler routine
  */
 
-        .globl  pgm_check_handler
+       .globl  pgm_check_handler
 pgm_check_handler:
 /*
  * First we need to check for a special case:
@@ -448,8 +447,8 @@ pgm_check_handler:
  */
        STORE_TIMER __LC_SYNC_ENTER_TIMER
        SAVE_ALL_BASE __LC_SAVE_AREA
-        tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
-        bnz     BASED(pgm_per)           # got per exception -> special case
+       tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
+       bnz     BASED(pgm_per)          # got per exception -> special case
        SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
        CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -461,29 +460,29 @@ pgm_check_handler:
 pgm_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-        l       %r3,__LC_PGM_ILC         # load program interruption code
+       l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
        nr      %r8,%r3
 pgm_do_call:
-        l       %r7,BASED(.Ljump_table)
-        sll     %r8,2
-        l       %r7,0(%r8,%r7)          # load address of handler routine
-        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       la      %r14,BASED(sysc_return)
-       br      %r7                      # branch to interrupt-handler
+       l       %r7,BASED(.Ljump_table)
+       sll     %r8,2
+       l       %r7,0(%r8,%r7)          # load address of handler routine
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       la      %r14,BASED(sysc_return)
+       br      %r7                     # branch to interrupt-handler
 
 #
 # handle per exception
 #
 pgm_per:
-        tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
-        bnz     BASED(pgm_per_std)       # ok, normal per event from user space
+       tm      __LC_PGM_OLD_PSW,0x40   # test if per event recording is on
+       bnz     BASED(pgm_per_std)      # ok, normal per event from user space
 # ok its one of the special cases, now we need to find out which one
-        clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
-        be      BASED(pgm_svcper)
+       clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
+       be      BASED(pgm_svcper)
 # no interesting special case, ignore PER event
-        lm      %r12,%r15,__LC_SAVE_AREA
-       lpsw    0x28
+       lm      %r12,%r15,__LC_SAVE_AREA
+       lpsw    0x28
 
 #
 # Normal per exception
@@ -507,10 +506,10 @@ pgm_no_vtime2:
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        tm      SP_PSW+1(%r15),0x01     # kernel per event ?
        bz      BASED(kernel_per)
-       l       %r3,__LC_PGM_ILC         # load program interruption code
+       l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
-       nr      %r8,%r3                  # clear per-event-bit and ilc
-       be      BASED(sysc_return)       # only per or per+check ?
+       nr      %r8,%r3                 # clear per-event-bit and ilc
+       be      BASED(sysc_return)      # only per or per+check ?
        b       BASED(pgm_do_call)
 
 #
@@ -552,7 +551,7 @@ kernel_per:
  * IO interrupt handler routine
  */
 
-        .globl io_int_handler
+       .globl io_int_handler
 io_int_handler:
        STORE_TIMER __LC_ASYNC_ENTER_TIMER
        stck    __LC_INT_CLOCK
@@ -569,42 +568,42 @@ io_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
-        l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
-        la      %r2,SP_PTREGS(%r15) # address of register-save area
-        basr    %r14,%r1          # branch to standard irq handler
+       l       %r1,BASED(.Ldo_IRQ)     # load address of do_IRQ
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       basr    %r14,%r1                # branch to standard irq handler
        TRACE_IRQS_ON
 
 io_return:
-        tm      SP_PSW+1(%r15),0x01    # returning to user ?
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
 #ifdef CONFIG_PREEMPT
-       bno     BASED(io_preempt)      # no -> check for preemptive scheduling
+       bno     BASED(io_preempt)       # no -> check for preemptive scheduling
 #else
-        bno     BASED(io_leave)        # no-> skip resched & signal
+       bno     BASED(io_leave)         # no-> skip resched & signal
 #endif
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
-       bnz     BASED(io_work)         # there is work to do (signals etc.)
+       bnz     BASED(io_work)          # there is work to do (signals etc.)
 io_leave:
-        RESTORE_ALL __LC_RETURN_PSW,0
+       RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
 #ifdef CONFIG_PREEMPT
 io_preempt:
        icm     %r0,15,__TI_precount(%r9)
-       bnz     BASED(io_leave)
+       bnz     BASED(io_leave)
        l       %r1,SP_R15(%r15)
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
-        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
 io_resume_loop:
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bno     BASED(io_leave)
-       mvc     __TI_precount(4,%r9),BASED(.Lc_pactive)
-        stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
-        l       %r1,BASED(.Lschedule)
+       mvc     __TI_precount(4,%r9),BASED(.Lc_pactive)
+       stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
+       l       %r1,BASED(.Lschedule)
        basr    %r14,%r1               # call schedule
-        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
-       xc      __TI_precount(4,%r9),__TI_precount(%r9)
+       stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
+       xc      __TI_precount(4,%r9),__TI_precount(%r9)
        b       BASED(io_resume_loop)
 #endif
 
@@ -615,16 +614,16 @@ io_work:
        l       %r1,__LC_KERNEL_STACK
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
-        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
 #
 # One of the work bits is on. Find out which one.
 # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED
-#              and _TIF_MCCK_PENDING
+#              and _TIF_MCCK_PENDING
 #
 io_work_loop:
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
-       bo      BASED(io_mcck_pending)
+       bo      BASED(io_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bo      BASED(io_reschedule)
        tm      __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
@@ -637,36 +636,36 @@ io_work_loop:
 io_mcck_pending:
        l       %r1,BASED(.Ls390_handle_mcck)
        la      %r14,BASED(io_work_loop)
-       br      %r1                    # TIF bit will be cleared by handler
+       br      %r1                     # TIF bit will be cleared by handler
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
-#      
-io_reschedule:        
-        l       %r1,BASED(.Lschedule)
-        stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
-       basr    %r14,%r1               # call scheduler
-        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
+#
+io_reschedule:
+       l       %r1,BASED(.Lschedule)
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       basr    %r14,%r1                # call scheduler
+       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
-       bz      BASED(io_leave)        # there is no work to do
+       bz      BASED(io_leave)         # there is no work to do
        b       BASED(io_work_loop)
 
 #
 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
-io_sigpending:     
-        stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        l       %r1,BASED(.Ldo_signal)
-       basr    %r14,%r1               # call do_signal
-        stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
+io_sigpending:
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       l       %r1,BASED(.Ldo_signal)
+       basr    %r14,%r1                # call do_signal
+       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        b       BASED(io_work_loop)
 
 /*
  * External interrupt handler routine
  */
 
-        .globl  ext_int_handler
+       .globl  ext_int_handler
 ext_int_handler:
        STORE_TIMER __LC_ASYNC_ENTER_TIMER
        stck    __LC_INT_CLOCK
@@ -683,8 +682,8 @@ ext_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
-       la      %r2,SP_PTREGS(%r15)    # address of register-save area
-       lh      %r3,__LC_EXT_INT_CODE  # get interruption code
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       lh      %r3,__LC_EXT_INT_CODE   # get interruption code
        l       %r1,BASED(.Ldo_extint)
        basr    %r14,%r1
        TRACE_IRQS_ON
@@ -696,13 +695,13 @@ __critical_end:
  * Machine check handler routines
  */
 
-        .globl mcck_int_handler
+       .globl mcck_int_handler
 mcck_int_handler:
        spt     __LC_CPU_TIMER_SAVE_AREA        # revalidate cpu timer
        lm      %r0,%r15,__LC_GPREGS_SAVE_AREA  # revalidate gprs
        SAVE_ALL_BASE __LC_SAVE_AREA+32
        la      %r12,__LC_MCK_OLD_PSW
-       tm      __LC_MCCK_CODE,0x80     # system damage?
+       tm      __LC_MCCK_CODE,0x80     # system damage?
        bo      BASED(mcck_int_main)    # yes -> rest of mcck code invalid
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        mvc     __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
@@ -741,7 +740,7 @@ mcck_int_main:
        l       %r15,__LC_PANIC_STACK   # load panic stack
 0:     CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
+       tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
        bno     BASED(mcck_no_vtime)    # no -> skip cleanup critical
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(mcck_no_vtime)
@@ -752,14 +751,14 @@ mcck_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
-       l       %r1,BASED(.Ls390_mcck)
-       basr    %r14,%r1                # call machine check handler
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       l       %r1,BASED(.Ls390_mcck)
+       basr    %r14,%r1                # call machine check handler
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
        bno     BASED(mcck_return)
-       l       %r1,__LC_KERNEL_STACK   # switch to kernel stack
+       l       %r1,__LC_KERNEL_STACK   # switch to kernel stack
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
-       xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
@@ -783,36 +782,36 @@ mcck_return:
        lm      %r0,%r15,SP_R0(%r15)    # load gprs 0-15
        lpsw    __LC_RETURN_MCCK_PSW    # back to caller
 
-        RESTORE_ALL __LC_RETURN_MCCK_PSW,0
+       RESTORE_ALL __LC_RETURN_MCCK_PSW,0
 
 #ifdef CONFIG_SMP
 /*
  * Restart interruption handler, kick starter for additional CPUs
  */
-        .globl restart_int_handler
+       .globl restart_int_handler
 restart_int_handler:
-        l       %r15,__LC_SAVE_AREA+60 # load ksp
-        lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
-        lam     %a0,%a15,__LC_AREGS_SAVE_AREA
-        lm      %r6,%r15,__SF_GPRS(%r15) # load registers from clone
-        stosm   __SF_EMPTY(%r15),0x04    # now we can turn dat on
-        basr    %r14,0
-        l       %r14,restart_addr-.(%r14)
-        br      %r14                   # branch to start_secondary
+       l       %r15,__LC_SAVE_AREA+60  # load ksp
+       lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
+       lam     %a0,%a15,__LC_AREGS_SAVE_AREA
+       lm      %r6,%r15,__SF_GPRS(%r15) # load registers from clone
+       stosm   __SF_EMPTY(%r15),0x04   # now we can turn dat on
+       basr    %r14,0
+       l       %r14,restart_addr-.(%r14)
+       br      %r14                    # branch to start_secondary
 restart_addr:
-        .long   start_secondary
+       .long   start_secondary
 #else
 /*
  * If we do not run with SMP enabled, let the new CPU crash ...
  */
-        .globl restart_int_handler
+       .globl restart_int_handler
 restart_int_handler:
-        basr    %r1,0
+       basr    %r1,0
 restart_base:
-        lpsw    restart_crash-restart_base(%r1)
-        .align 8
+       lpsw    restart_crash-restart_base(%r1)
+       .align  8
 restart_crash:
-        .long  0x000a0000,0x00000000
+       .long   0x000a0000,0x00000000
 restart_go:
 #endif
 
@@ -834,11 +833,11 @@ stack_overflow:
        be      BASED(0f)
        la      %r1,__LC_SAVE_AREA+16
 0:     mvc     SP_R12(16,%r15),0(%r1)  # move %r12-%r15 to stack
-        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
+       xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
        l       %r1,BASED(1f)           # branch to kernel_stack_overflow
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        br      %r1
-1:     .long  kernel_stack_overflow
+1:     .long   kernel_stack_overflow
 #endif
 
 cleanup_table_system_call:
@@ -940,10 +939,10 @@ cleanup_novtime:
 cleanup_system_call_insn:
        .long   sysc_saveall + 0x80000000
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       .long   system_call + 0x80000000
-       .long   sysc_vtime + 0x80000000
-       .long   sysc_stime + 0x80000000
-       .long   sysc_update + 0x80000000
+       .long   system_call + 0x80000000
+       .long   sysc_vtime + 0x80000000
+       .long   sysc_stime + 0x80000000
+       .long   sysc_update + 0x80000000
 #endif
 
 cleanup_sysc_return:
@@ -1009,57 +1008,57 @@ cleanup_io_leave_insn:
 /*
  * Integer constants
  */
-               .align 4
-.Lc_spsize:    .long  SP_SIZE
-.Lc_overhead:  .long  STACK_FRAME_OVERHEAD
-.Lc_pactive:   .long  PREEMPT_ACTIVE
-.Lnr_syscalls: .long  NR_syscalls
-.L0x018:       .short 0x018
-.L0x020:       .short 0x020
-.L0x028:       .short 0x028
-.L0x030:       .short 0x030
-.L0x038:       .short 0x038
-.Lc_1:         .long  1
+               .align  4
+.Lc_spsize:    .long   SP_SIZE
+.Lc_overhead:  .long   STACK_FRAME_OVERHEAD
+.Lc_pactive:   .long   PREEMPT_ACTIVE
+.Lnr_syscalls: .long   NR_syscalls
+.L0x018:       .short  0x018
+.L0x020:       .short  0x020
+.L0x028:       .short  0x028
+.L0x030:       .short  0x030
+.L0x038:       .short  0x038
+.Lc_1:         .long   1
 
 /*
  * Symbol constants
  */
-.Ls390_mcck:   .long  s390_do_machine_check
+.Ls390_mcck:   .long   s390_do_machine_check
 .Ls390_handle_mcck:
-              .long  s390_handle_mcck
-.Lmck_old_psw: .long  __LC_MCK_OLD_PSW
-.Ldo_IRQ:      .long  do_IRQ
-.Ldo_extint:   .long  do_extint
-.Ldo_signal:   .long  do_signal
-.Lhandle_per:  .long  do_single_step
-.Ljump_table:  .long  pgm_check_table
-.Lschedule:    .long  schedule
-.Lclone:       .long  sys_clone
-.Lexecve:      .long  sys_execve
-.Lfork:        .long  sys_fork
-.Lrt_sigreturn:.long  sys_rt_sigreturn
+               .long   s390_handle_mcck
+.Lmck_old_psw: .long   __LC_MCK_OLD_PSW
+.Ldo_IRQ:      .long   do_IRQ
+.Ldo_extint:   .long   do_extint
+.Ldo_signal:   .long   do_signal
+.Lhandle_per:  .long   do_single_step
+.Ljump_table:  .long   pgm_check_table
+.Lschedule:    .long   schedule
+.Lclone:       .long   sys_clone
+.Lexecve:      .long   sys_execve
+.Lfork:        .long   sys_fork
+.Lrt_sigreturn: .long  sys_rt_sigreturn
 .Lrt_sigsuspend:
-               .long  sys_rt_sigsuspend
-.Lsigreturn:   .long  sys_sigreturn
-.Lsigsuspend:  .long  sys_sigsuspend
-.Lsigaltstack: .long  sys_sigaltstack
-.Ltrace:       .long  syscall_trace
-.Lvfork:       .long  sys_vfork
-.Lschedtail:   .long  schedule_tail
-.Lsysc_table:  .long  sys_call_table
+               .long   sys_rt_sigsuspend
+.Lsigreturn:   .long   sys_sigreturn
+.Lsigsuspend:  .long   sys_sigsuspend
+.Lsigaltstack: .long   sys_sigaltstack
+.Ltrace:       .long   syscall_trace
+.Lvfork:       .long   sys_vfork
+.Lschedtail:   .long   schedule_tail
+.Lsysc_table:  .long   sys_call_table
 #ifdef CONFIG_TRACE_IRQFLAGS
-.Ltrace_irq_on:.long  trace_hardirqs_on
+.Ltrace_irq_on: .long  trace_hardirqs_on
 .Ltrace_irq_off:
-              .long  trace_hardirqs_off
+               .long   trace_hardirqs_off
 #endif
 .Lcritical_start:
-               .long  __critical_start + 0x80000000
+               .long   __critical_start + 0x80000000
 .Lcritical_end:
-               .long  __critical_end + 0x80000000
+               .long   __critical_end + 0x80000000
 .Lcleanup_critical:
-               .long  cleanup_critical
+               .long   cleanup_critical
 
-              .section .rodata, "a"
+               .section .rodata, "a"
 #define SYSCALL(esa,esame,emu) .long esa
 sys_call_table:
 #include "syscalls.S"
index 29bbfbab733273d3a9b1c5f9386f8f13ff98bcf9..0f758c329a5d5b0beb9b05ed7b87db799fdd5cfe 100644 (file)
@@ -4,8 +4,8 @@
  *
  *    Copyright (C) IBM Corp. 1999,2006
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Hartmut Penner (hp@de.ibm.com),
- *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *              Hartmut Penner (hp@de.ibm.com),
+ *              Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  *              Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
  * Stack layout for the system_call stack entry.
  * The first few entries are identical to the user_regs_struct.
  */
-SP_PTREGS    =  STACK_FRAME_OVERHEAD
-SP_ARGS      =  STACK_FRAME_OVERHEAD + __PT_ARGS
-SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
-SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
-SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
-SP_R2        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
-SP_R3        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
-SP_R4        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
-SP_R5        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
-SP_R6        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
-SP_R7        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
-SP_R8        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 64
-SP_R9        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 72
-SP_R10       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 80
-SP_R11       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 88
-SP_R12       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 96
-SP_R13       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 104
-SP_R14       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 112
-SP_R15       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 120
-SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
-SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
-SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
-SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
+SP_PTREGS    = STACK_FRAME_OVERHEAD
+SP_ARGS      = STACK_FRAME_OVERHEAD + __PT_ARGS
+SP_PSW      =  STACK_FRAME_OVERHEAD + __PT_PSW
+SP_R0       =  STACK_FRAME_OVERHEAD + __PT_GPRS
+SP_R1       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
+SP_R2       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
+SP_R3       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
+SP_R4       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
+SP_R5       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
+SP_R6       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
+SP_R7       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
+SP_R8       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 64
+SP_R9       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 72
+SP_R10      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 80
+SP_R11      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 88
+SP_R12      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 96
+SP_R13      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 104
+SP_R14      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 112
+SP_R15      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 120
+SP_ORIG_R2   = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
+SP_ILC      =  STACK_FRAME_OVERHEAD + __PT_ILC
+SP_TRAP      = STACK_FRAME_OVERHEAD + __PT_TRAP
+SP_SIZE      = STACK_FRAME_OVERHEAD + __PT_SIZE
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
@@ -71,14 +71,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
 #define TRACE_IRQS_OFF
 #endif
 
-       .macro  STORE_TIMER lc_offset
+       .macro  STORE_TIMER lc_offset
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        stpt    \lc_offset
 #endif
        .endm
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       .macro  UPDATE_VTIME lc_from,lc_to,lc_sum
+       .macro  UPDATE_VTIME lc_from,lc_to,lc_sum
        lg      %r10,\lc_from
        slg     %r10,\lc_to
        alg     %r10,\lc_sum
@@ -94,7 +94,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL_BASE savearea
+       .macro  SAVE_ALL_BASE savearea
        stmg    %r12,%r15,\savearea
        larl    %r13,system_call
        .endm
@@ -139,8 +139,8 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
        .endm
 
        .macro  CREATE_STACK_FRAME psworg,savearea
-       aghi    %r15,-SP_SIZE           # make room for registers & psw
-       mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+       aghi    %r15,-SP_SIZE           # make room for registers & psw
+       mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
        la      %r12,\psworg
        stg     %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
        icm     %r12,12,__LC_SVC_ILC
@@ -149,7 +149,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
        mvc     SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
        la      %r12,0
        stg     %r12,__SF_BACKCHAIN(%r15)
-        .endm
+       .endm
 
        .macro  RESTORE_ALL psworg,sync
        mvc     \psworg(16),SP_PSW(%r15) # move user PSW to lowcore
@@ -168,29 +168,29 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
  * Returns:
  *  gpr2 = prev
  */
-        .globl  __switch_to
+       .globl  __switch_to
 __switch_to:
        tm      __THREAD_per+4(%r3),0xe8 # is the new process using per ?
        jz      __switch_to_noper               # if not we're fine
-        stctg   %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff
-        clc     __THREAD_per(24,%r3),__SF_EMPTY(%r15)
-        je      __switch_to_noper            # we got away without bashing TLB's
-        lctlg   %c9,%c11,__THREAD_per(%r3)     # Nope we didn't
+       stctg   %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff
+       clc     __THREAD_per(24,%r3),__SF_EMPTY(%r15)
+       je      __switch_to_noper            # we got away without bashing TLB's
+       lctlg   %c9,%c11,__THREAD_per(%r3)      # Nope we didn't
 __switch_to_noper:
-       lg      %r4,__THREAD_info(%r2)              # get thread_info of prev
+       lg      %r4,__THREAD_info(%r2)              # get thread_info of prev
        tm      __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
        jz      __switch_to_no_mcck
        ni      __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
        lg      %r4,__THREAD_info(%r3)              # get thread_info of next
        oi      __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next
 __switch_to_no_mcck:
-        stmg    %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
+       stmg    %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
        stg     %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
        lg      %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
-        lmg     %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
+       lmg     %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
        stg     %r3,__LC_CURRENT        # __LC_CURRENT = current task struct
        lctl    %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
-       lg      %r3,__THREAD_info(%r3)  # load thread_info from task struct
+       lg      %r3,__THREAD_info(%r3)  # load thread_info from task struct
        stg     %r3,__LC_THREAD_INFO
        aghi    %r3,STACK_SIZE
        stg     %r3,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
@@ -202,14 +202,14 @@ __critical_start:
  * are executed with interrupts enabled.
  */
 
-       .globl  system_call
+       .globl  system_call
 system_call:
        STORE_TIMER __LC_SYNC_ENTER_TIMER
 sysc_saveall:
        SAVE_ALL_BASE __LC_SAVE_AREA
        SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-        CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 sysc_vtime:
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
@@ -222,45 +222,45 @@ sysc_update:
 #endif
 sysc_do_svc:
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-        slag    %r7,%r7,2         # *4 and test for svc 0
+       slag    %r7,%r7,2       # *4 and test for svc 0
        jnz     sysc_nr_ok
        # svc 0: system call number in %r1
        cl      %r1,BASED(.Lnr_syscalls)
        jnl     sysc_nr_ok
-       lgfr    %r7,%r1           # clear high word in r1
-       slag    %r7,%r7,2         # svc 0: system call number in %r1
+       lgfr    %r7,%r1         # clear high word in r1
+       slag    %r7,%r7,2       # svc 0: system call number in %r1
 sysc_nr_ok:
        mvc     SP_ARGS(8,%r15),SP_R7(%r15)
 sysc_do_restart:
-       larl    %r10,sys_call_table
+       larl    %r10,sys_call_table
 #ifdef CONFIG_COMPAT
        tm      __TI_flags+5(%r9),(_TIF_31BIT>>16)  # running in 31 bit mode ?
        jno     sysc_noemu
-       larl    %r10,sys_call_table_emu  # use 31 bit emulation system calls
+       larl    %r10,sys_call_table_emu  # use 31 bit emulation system calls
 sysc_noemu:
 #endif
        tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        lgf     %r8,0(%r7,%r10)   # load address of system call routine
-        jnz     sysc_tracesys
-        basr    %r14,%r8          # call sys_xxxx
-        stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
-                                  # ATTENTION: check sys_execve_glue before
-                                  # changing anything here !!
+       lgf     %r8,0(%r7,%r10) # load address of system call routine
+       jnz     sysc_tracesys
+       basr    %r14,%r8        # call sys_xxxx
+       stg     %r2,SP_R2(%r15) # store return value (change R2 on stack)
+                               # ATTENTION: check sys_execve_glue before
+                               # changing anything here !!
 
 sysc_return:
-        tm      SP_PSW+1(%r15),0x01    # returning to user ?
-        jno     sysc_leave
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       jno     sysc_leave
        tm      __TI_flags+7(%r9),_TIF_WORK_SVC
-       jnz     sysc_work         # there is work to do (signals etc.)
+       jnz     sysc_work       # there is work to do (signals etc.)
 sysc_leave:
-        RESTORE_ALL __LC_RETURN_PSW,1
+       RESTORE_ALL __LC_RETURN_PSW,1
 
 #
 # recheck if there is more work to do
 #
 sysc_work_loop:
        tm      __TI_flags+7(%r9),_TIF_WORK_SVC
-       jz      sysc_leave        # there is no work to do
+       jz      sysc_leave        # there is no work to do
 #
 # One of the work bits is on. Find out which one.
 #
@@ -279,25 +279,25 @@ sysc_work:
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
-#      
-sysc_reschedule:        
-       larl    %r14,sysc_work_loop
-        jg      schedule            # return point is sysc_return
+#
+sysc_reschedule:
+       larl    %r14,sysc_work_loop
+       jg      schedule        # return point is sysc_return
 
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
 sysc_mcck_pending:
        larl    %r14,sysc_work_loop
-       jg      s390_handle_mcck    # TIF bit will be cleared by handler
+       jg      s390_handle_mcck        # TIF bit will be cleared by handler
 
 #
 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
-sysc_sigpending:     
+sysc_sigpending:
        ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
-        la      %r2,SP_PTREGS(%r15) # load pt_regs
-       brasl   %r14,do_signal    # call do_signal
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       brasl   %r14,do_signal          # call do_signal
        tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
        jo      sysc_restart
        tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
@@ -309,11 +309,11 @@ sysc_sigpending:
 #
 sysc_restart:
        ni      __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
-       lg      %r7,SP_R2(%r15)        # load new svc number
-        slag    %r7,%r7,2              # *4
+       lg      %r7,SP_R2(%r15)         # load new svc number
+       slag    %r7,%r7,2               # *4
        mvc     SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
-       lmg     %r2,%r6,SP_R2(%r15)    # load svc arguments
-       j       sysc_do_restart        # restart svc
+       lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
+       j       sysc_do_restart         # restart svc
 
 #
 # _TIF_SINGLE_STEP is set, call do_single_step
@@ -326,49 +326,48 @@ sysc_singlestep:
        larl    %r14,sysc_return        # load adr. of system return
        jg      do_single_step          # branch to do_sigtrap
 
-
 #
 # call syscall_trace before and after system call
 # special linkage: %r12 contains the return address for trace_svc
 #
 sysc_tracesys:
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        la      %r3,0
        srl     %r7,2
-       stg     %r7,SP_R2(%r15)
-        brasl   %r14,syscall_trace
+       stg     %r7,SP_R2(%r15)
+       brasl   %r14,syscall_trace
        lghi    %r0,NR_syscalls
        clg     %r0,SP_R2(%r15)
        jnh     sysc_tracenogo
-       lg      %r7,SP_R2(%r15)   # strace might have changed the
-       sll     %r7,2              system call
+       lg      %r7,SP_R2(%r15)         # strace might have changed the
+       sll     %r7,2                   # system call
        lgf     %r8,0(%r7,%r10)
 sysc_tracego:
-       lmg     %r3,%r6,SP_R3(%r15)
-       lg      %r2,SP_ORIG_R2(%r15)
-        basr    %r14,%r8            # call sys_xxx
-        stg     %r2,SP_R2(%r15)     # store return value
+       lmg     %r3,%r6,SP_R3(%r15)
+       lg      %r2,SP_ORIG_R2(%r15)
+       basr    %r14,%r8                # call sys_xxx
+       stg     %r2,SP_R2(%r15)         # store return value
 sysc_tracenogo:
        tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        jz      sysc_return
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
+       jz      sysc_return
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        la      %r3,1
-       larl    %r14,sysc_return    # return point is sysc_return
+       larl    %r14,sysc_return        # return point is sysc_return
        jg      syscall_trace
 
 #
 # a new process exits the kernel with ret_from_fork
 #
-        .globl  ret_from_fork
+       .globl  ret_from_fork
 ret_from_fork:
        lg      %r13,__LC_SVC_NEW_PSW+8
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # forking a kernel thread ?
        jo      0f
        stg     %r15,SP_R15(%r15)       # store stack pointer for new kthread
-0:     brasl   %r14,schedule_tail
+0:     brasl   %r14,schedule_tail
        TRACE_IRQS_ON
-        stosm   24(%r15),0x03     # reenable interrupts
+       stosm   24(%r15),0x03           # reenable interrupts
        j       sysc_return
 
 #
@@ -377,78 +376,78 @@ ret_from_fork:
 # but are called with different parameter.
 # return-address is set up above
 #
-sys_clone_glue: 
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        jg      sys_clone              # branch to sys_clone
+sys_clone_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       jg      sys_clone               # branch to sys_clone
 
 #ifdef CONFIG_COMPAT
-sys32_clone_glue: 
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        jg      sys32_clone            # branch to sys32_clone
+sys32_clone_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       jg      sys32_clone             # branch to sys32_clone
 #endif
 
-sys_fork_glue:  
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        jg      sys_fork               # branch to sys_fork
-
-sys_vfork_glue: 
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        jg      sys_vfork              # branch to sys_vfork
-
-sys_execve_glue:        
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs
-       lgr     %r12,%r14             # save return address
-        brasl   %r14,sys_execve       # call sys_execve
-        ltgr    %r2,%r2               # check if execve failed
-        bnz     0(%r12)               # it did fail -> store result in gpr2
-        b       6(%r12)               # SKIP STG 2,SP_R2(15) in
-                                      # system_call/sysc_tracesys
+sys_fork_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       jg      sys_fork                # branch to sys_fork
+
+sys_vfork_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       jg      sys_vfork               # branch to sys_vfork
+
+sys_execve_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       lgr     %r12,%r14               # save return address
+       brasl   %r14,sys_execve         # call sys_execve
+       ltgr    %r2,%r2                 # check if execve failed
+       bnz     0(%r12)                 # it did fail -> store result in gpr2
+       b       6(%r12)                 # SKIP STG 2,SP_R2(15) in
+                                       # system_call/sysc_tracesys
 #ifdef CONFIG_COMPAT
-sys32_execve_glue:        
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs
-       lgr     %r12,%r14             # save return address
-        brasl   %r14,sys32_execve     # call sys32_execve
-        ltgr    %r2,%r2               # check if execve failed
-        bnz     0(%r12)               # it did fail -> store result in gpr2
-        b       6(%r12)               # SKIP STG 2,SP_R2(15) in
-                                      # system_call/sysc_tracesys
+sys32_execve_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       lgr     %r12,%r14               # save return address
+       brasl   %r14,sys32_execve       # call sys32_execve
+       ltgr    %r2,%r2                 # check if execve failed
+       bnz     0(%r12)                 # it did fail -> store result in gpr2
+       b       6(%r12)                 # SKIP STG 2,SP_R2(15) in
+                                       # system_call/sysc_tracesys
 #endif
 
-sys_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys_sigreturn         # branch to sys_sigreturn
+sys_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys_sigreturn           # branch to sys_sigreturn
 
 #ifdef CONFIG_COMPAT
-sys32_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys32_sigreturn       # branch to sys32_sigreturn
+sys32_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys32_sigreturn         # branch to sys32_sigreturn
 #endif
 
-sys_rt_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys_rt_sigreturn      # branch to sys_sigreturn
+sys_rt_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys_rt_sigreturn        # branch to sys_sigreturn
 
 #ifdef CONFIG_COMPAT
-sys32_rt_sigreturn_glue:     
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys32_rt_sigreturn    # branch to sys32_sigreturn
+sys32_rt_sigreturn_glue:
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys32_rt_sigreturn      # branch to sys32_sigreturn
 #endif
 
 sys_sigaltstack_glue:
-        la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys_sigaltstack       # branch to sys_sigreturn
+       la      %r4,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys_sigaltstack         # branch to sys_sigreturn
 
 #ifdef CONFIG_COMPAT
 sys32_sigaltstack_glue:
-        la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
-        jg      sys32_sigaltstack_wrapper # branch to sys_sigreturn
+       la      %r4,SP_PTREGS(%r15)     # load pt_regs as parameter
+       jg      sys32_sigaltstack_wrapper # branch to sys_sigreturn
 #endif
 
 /*
  * Program check handler routine
  */
 
-        .globl  pgm_check_handler
+       .globl  pgm_check_handler
 pgm_check_handler:
 /*
  * First we need to check for a special case:
@@ -465,8 +464,8 @@ pgm_check_handler:
  */
        STORE_TIMER __LC_SYNC_ENTER_TIMER
        SAVE_ALL_BASE __LC_SAVE_AREA
-        tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
-        jnz     pgm_per                  # got per exception -> special case
+       tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
+       jnz     pgm_per                  # got per exception -> special case
        SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
        CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -478,29 +477,29 @@ pgm_check_handler:
 pgm_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       lgf     %r3,__LC_PGM_ILC         # load program interruption code
+       lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
        ngr     %r8,%r3
 pgm_do_call:
-        sll     %r8,3
-        larl    %r1,pgm_check_table
-        lg      %r1,0(%r8,%r1)          # load address of handler routine
-        la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       sll     %r8,3
+       larl    %r1,pgm_check_table
+       lg      %r1,0(%r8,%r1)          # load address of handler routine
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
        larl    %r14,sysc_return
-        br      %r1                     # branch to interrupt-handler
+       br      %r1                     # branch to interrupt-handler
 
 #
 # handle per exception
 #
 pgm_per:
-        tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
-        jnz     pgm_per_std              # ok, normal per event from user space
+       tm      __LC_PGM_OLD_PSW,0x40   # test if per event recording is on
+       jnz     pgm_per_std             # ok, normal per event from user space
 # ok its one of the special cases, now we need to find out which one
-        clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
-        je      pgm_svcper
+       clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
+       je      pgm_svcper
 # no interesting special case, ignore PER event
        lmg     %r12,%r15,__LC_SAVE_AREA
-       lpswe   __LC_PGM_OLD_PSW
+       lpswe   __LC_PGM_OLD_PSW
 
 #
 # Normal per exception
@@ -524,9 +523,9 @@ pgm_no_vtime2:
        mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
-       lgf     %r3,__LC_PGM_ILC         # load program interruption code
+       lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
-       ngr     %r8,%r3                  # clear per-event-bit and ilc
+       ngr     %r8,%r3                 # clear per-event-bit and ilc
        je      sysc_return
        j       pgm_do_call
 
@@ -544,7 +543,7 @@ pgm_svcper:
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime3:
 #endif
-       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
+       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        lg      %r1,__TI_task(%r9)
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
@@ -568,7 +567,7 @@ kernel_per:
 /*
  * IO interrupt handler routine
  */
-        .globl io_int_handler
+       .globl io_int_handler
 io_int_handler:
        STORE_TIMER __LC_ASYNC_ENTER_TIMER
        stck    __LC_INT_CLOCK
@@ -585,42 +584,42 @@ io_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
-        la      %r2,SP_PTREGS(%r15)    # address of register-save area
-       brasl   %r14,do_IRQ            # call standard irq handler
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       brasl   %r14,do_IRQ             # call standard irq handler
        TRACE_IRQS_ON
 
 io_return:
-        tm      SP_PSW+1(%r15),0x01    # returning to user ?
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
 #ifdef CONFIG_PREEMPT
-       jno     io_preempt             # no -> check for preemptive scheduling
+       jno     io_preempt              # no -> check for preemptive scheduling
 #else
-        jno     io_leave               # no-> skip resched & signal
+       jno     io_leave                # no-> skip resched & signal
 #endif
        tm      __TI_flags+7(%r9),_TIF_WORK_INT
-       jnz     io_work                # there is work to do (signals etc.)
+       jnz     io_work                 # there is work to do (signals etc.)
 io_leave:
-        RESTORE_ALL __LC_RETURN_PSW,0
+       RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
 #ifdef CONFIG_PREEMPT
 io_preempt:
-       icm     %r0,15,__TI_precount(%r9)       
-       jnz     io_leave
+       icm     %r0,15,__TI_precount(%r9)
+       jnz     io_leave
        # switch to kernel stack
        lg      %r1,SP_R15(%r15)
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
-        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
 io_resume_loop:
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
        jno     io_leave
-       larl    %r1,.Lc_pactive
-       mvc     __TI_precount(4,%r9),0(%r1)
-        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
-       brasl   %r14,schedule          # call schedule
-        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
-       xc      __TI_precount(4,%r9),__TI_precount(%r9)
+       larl    %r1,.Lc_pactive
+       mvc     __TI_precount(4,%r9),0(%r1)
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       brasl   %r14,schedule           # call schedule
+       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
+       xc      __TI_precount(4,%r9),__TI_precount(%r9)
        j       io_resume_loop
 #endif
 
@@ -631,7 +630,7 @@ io_work:
        lg      %r1,__LC_KERNEL_STACK
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
-        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
 #
 # One of the work bits is on. Find out which one.
@@ -656,11 +655,11 @@ io_mcck_pending:
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
-#      
-io_reschedule:        
-       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
-       brasl   %r14,schedule           # call scheduler
-       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
+#
+io_reschedule:
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       brasl   %r14,schedule           # call scheduler
+       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        tm      __TI_flags+7(%r9),_TIF_WORK_INT
        jz      io_leave                # there is no work to do
        j       io_work_loop
@@ -668,17 +667,17 @@ io_reschedule:
 #
 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
-io_sigpending:     
-       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
-       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+io_sigpending:
+       stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_signal          # call do_signal
-       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
+       stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        j       io_work_loop
 
 /*
  * External interrupt handler routine
  */
-        .globl  ext_int_handler
+       .globl  ext_int_handler
 ext_int_handler:
        STORE_TIMER __LC_ASYNC_ENTER_TIMER
        stck    __LC_INT_CLOCK
@@ -695,9 +694,9 @@ ext_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
-       la      %r2,SP_PTREGS(%r15)    # address of register-save area
-       llgh    %r3,__LC_EXT_INT_CODE  # get interruption code
-       brasl   %r14,do_extint
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       llgh    %r3,__LC_EXT_INT_CODE   # get interruption code
+       brasl   %r14,do_extint
        TRACE_IRQS_ON
        j       io_return
 
@@ -706,14 +705,14 @@ __critical_end:
 /*
  * Machine check handler routines
  */
-        .globl mcck_int_handler
+       .globl mcck_int_handler
 mcck_int_handler:
        la      %r1,4095                # revalidate r1
        spt     __LC_CPU_TIMER_SAVE_AREA-4095(%r1)      # revalidate cpu timer
-       lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
+       lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
        SAVE_ALL_BASE __LC_SAVE_AREA+64
        la      %r12,__LC_MCK_OLD_PSW
-       tm      __LC_MCCK_CODE,0x80     # system damage?
+       tm      __LC_MCCK_CODE,0x80     # system damage?
        jo      mcck_int_main           # yes -> rest of mcck code invalid
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        la      %r14,4095
@@ -737,19 +736,19 @@ mcck_int_handler:
 #endif
        tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
        jno     mcck_int_main           # no -> skip cleanup critical
-       tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
+       tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
        jnz     mcck_int_main           # from user -> load kernel stack
        clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end)
        jhe     mcck_int_main
-       clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start)
+       clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start)
        jl      mcck_int_main
-       brasl   %r14,cleanup_critical
+       brasl   %r14,cleanup_critical
 mcck_int_main:
-       lg      %r14,__LC_PANIC_STACK   # are we already on the panic stack?
+       lg      %r14,__LC_PANIC_STACK   # are we already on the panic stack?
        slgr    %r14,%r15
        srag    %r14,%r14,PAGE_SHIFT
        jz      0f
-       lg      %r15,__LC_PANIC_STACK   # load panic stack
+       lg      %r15,__LC_PANIC_STACK   # load panic stack
 0:     CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
@@ -764,7 +763,7 @@ mcck_no_vtime:
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,s390_do_machine_check
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
        jno     mcck_return
        lg      %r1,__LC_KERNEL_STACK   # switch to kernel stack
        aghi    %r1,-SP_SIZE
@@ -794,28 +793,28 @@ mcck_return:
 /*
  * Restart interruption handler, kick starter for additional CPUs
  */
-        .globl restart_int_handler
+       .globl restart_int_handler
 restart_int_handler:
-        lg      %r15,__LC_SAVE_AREA+120 # load ksp
-        lghi    %r10,__LC_CREGS_SAVE_AREA
-        lctlg   %c0,%c15,0(%r10) # get new ctl regs
-        lghi    %r10,__LC_AREGS_SAVE_AREA
-        lam     %a0,%a15,0(%r10)
-        lmg     %r6,%r15,__SF_GPRS(%r15) # load registers from clone
-        stosm   __SF_EMPTY(%r15),0x04    # now we can turn dat on
-       jg      start_secondary
+       lg      %r15,__LC_SAVE_AREA+120 # load ksp
+       lghi    %r10,__LC_CREGS_SAVE_AREA
+       lctlg   %c0,%c15,0(%r10) # get new ctl regs
+       lghi    %r10,__LC_AREGS_SAVE_AREA
+       lam     %a0,%a15,0(%r10)
+       lmg     %r6,%r15,__SF_GPRS(%r15) # load registers from clone
+       stosm   __SF_EMPTY(%r15),0x04   # now we can turn dat on
+       jg      start_secondary
 #else
 /*
  * If we do not run with SMP enabled, let the new CPU crash ...
  */
-        .globl restart_int_handler
+       .globl restart_int_handler
 restart_int_handler:
-        basr    %r1,0
+       basr    %r1,0
 restart_base:
-        lpswe   restart_crash-restart_base(%r1)
-        .align 8
+       lpswe   restart_crash-restart_base(%r1)
+       .align 8
 restart_crash:
-        .long  0x000a0000,0x00000000,0x00000000,0x00000000
+       .long  0x000a0000,0x00000000,0x00000000,0x00000000
 restart_go:
 #endif
 
@@ -836,9 +835,9 @@ stack_overflow:
        chi     %r12,__LC_PGM_OLD_PSW
        je      0f
        la      %r1,__LC_SAVE_AREA+32
-0:     mvc     SP_R12(32,%r15),0(%r1)  # move %r12-%r15 to stack
-        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
-        la      %r2,SP_PTREGS(%r15)    # load pt_regs
+0:     mvc     SP_R12(32,%r15),0(%r1)  # move %r12-%r15 to stack
+       xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        jg      kernel_stack_overflow
 #endif
 
@@ -941,10 +940,10 @@ cleanup_novtime:
 cleanup_system_call_insn:
        .quad   sysc_saveall
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       .quad   system_call
-       .quad   sysc_vtime
-       .quad   sysc_stime
-       .quad   sysc_update
+       .quad   system_call
+       .quad   sysc_vtime
+       .quad   sysc_stime
+       .quad   sysc_update
 #endif
 
 cleanup_sysc_return:
@@ -1010,21 +1009,21 @@ cleanup_io_leave_insn:
 /*
  * Integer constants
  */
-               .align 4
+               .align  4
 .Lconst:
-.Lc_pactive:   .long  PREEMPT_ACTIVE
-.Lnr_syscalls: .long  NR_syscalls
-.L0x0130:      .short 0x130
-.L0x0140:      .short 0x140
-.L0x0150:      .short 0x150
-.L0x0160:      .short 0x160
-.L0x0170:      .short 0x170
+.Lc_pactive:   .long   PREEMPT_ACTIVE
+.Lnr_syscalls: .long   NR_syscalls
+.L0x0130:      .short  0x130
+.L0x0140:      .short  0x140
+.L0x0150:      .short  0x150
+.L0x0160:      .short  0x160
+.L0x0170:      .short  0x170
 .Lcritical_start:
-               .quad  __critical_start
+               .quad   __critical_start
 .Lcritical_end:
-               .quad  __critical_end
+               .quad   __critical_end
 
-              .section .rodata, "a"
+               .section .rodata, "a"
 #define SYSCALL(esa,esame,emu) .long esame
 sys_call_table:
 #include "syscalls.S"
index 0f1db268a8a96c9d55b75dd9c270773bc13ed64d..0cf59bb7a857d40eba3ecd9445a470af6b68d68d 100644 (file)
 #endif
 
 #ifndef CONFIG_IPL
-        .org   0
-        .long  0x00080000,0x80000000+startup   # Just a restart PSW
+       .org   0
+       .long  0x00080000,0x80000000+startup    # Just a restart PSW
 #else
 #ifdef CONFIG_IPL_TAPE
 #define IPL_BS 1024
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x27000000,0x60000001           # by ipl to addresses 0-23.
-        .long  0x02000000,0x20000000+IPL_BS    # (a PSW and two CCWs).
-        .long  0x00000000,0x00000000           # external old psw
-        .long  0x00000000,0x00000000           # svc old psw
-        .long  0x00000000,0x00000000           # program check old psw
-        .long  0x00000000,0x00000000           # machine check old psw
-        .long  0x00000000,0x00000000           # io old psw
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x000a0000,0x00000058           # external new psw
-        .long  0x000a0000,0x00000060           # svc new psw
-        .long  0x000a0000,0x00000068           # program check new psw
-        .long  0x000a0000,0x00000070           # machine check new psw
-        .long  0x00080000,0x80000000+.Lioint   # io new psw
+       .org   0
+       .long  0x00080000,0x80000000+iplstart   # The first 24 bytes are loaded
+       .long  0x27000000,0x60000001            # by ipl to addresses 0-23.
+       .long  0x02000000,0x20000000+IPL_BS     # (a PSW and two CCWs).
+       .long  0x00000000,0x00000000            # external old psw
+       .long  0x00000000,0x00000000            # svc old psw
+       .long  0x00000000,0x00000000            # program check old psw
+       .long  0x00000000,0x00000000            # machine check old psw
+       .long  0x00000000,0x00000000            # io old psw
+       .long  0x00000000,0x00000000
+       .long  0x00000000,0x00000000
+       .long  0x00000000,0x00000000
+       .long  0x000a0000,0x00000058            # external new psw
+       .long  0x000a0000,0x00000060            # svc new psw
+       .long  0x000a0000,0x00000068            # program check new psw
+       .long  0x000a0000,0x00000070            # machine check new psw
+       .long  0x00080000,0x80000000+.Lioint    # io new psw
 
-        .org   0x100
+       .org   0x100
 #
 # subroutine for loading from tape
-# Paramters:   
+# Paramters:
 #  R1 = device number
 #  R2 = load address
-.Lloader:      
-        st    %r14,.Lldret
-        la    %r3,.Lorbread                    # r3 = address of orb 
-       la    %r5,.Lirb                        # r5 = address of irb
-        st    %r2,.Lccwread+4                  # initialize CCW data addresses
-        lctl  %c6,%c6,.Lcr6               
-        slr   %r2,%r2
+.Lloader:
+       st      %r14,.Lldret
+       la      %r3,.Lorbread           # r3 = address of orb
+       la      %r5,.Lirb               # r5 = address of irb
+       st      %r2,.Lccwread+4         # initialize CCW data addresses
+       lctl    %c6,%c6,.Lcr6
+       slr     %r2,%r2
 .Lldlp:
-        la    %r6,3                            # 3 retries
+       la      %r6,3                   # 3 retries
 .Lssch:
-        ssch  0(%r3)                           # load chunk of IPL_BS bytes
-        bnz   .Llderr
+       ssch    0(%r3)                  # load chunk of IPL_BS bytes
+       bnz     .Llderr
 .Lw4end:
-        bas   %r14,.Lwait4io
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lrecov
-        slr   %r7,%r7
-        icm   %r7,3,10(%r5)                    # get residual count
-        lcr   %r7,%r7
-        la    %r7,IPL_BS(%r7)                  # IPL_BS-residual=#bytes read
-        ar    %r2,%r7                          # add to total size
-        tm    8(%r5),0x01                      # found a tape mark ?
-        bnz   .Ldone
-        l     %r0,.Lccwread+4                  # update CCW data addresses
-        ar    %r0,%r7
-        st    %r0,.Lccwread+4                
-        b     .Lldlp
+       bas     %r14,.Lwait4io
+       tm      8(%r5),0x82             # do we have a problem ?
+       bnz     .Lrecov
+       slr     %r7,%r7
+       icm     %r7,3,10(%r5)           # get residual count
+       lcr     %r7,%r7
+       la      %r7,IPL_BS(%r7)         # IPL_BS-residual=#bytes read
+       ar      %r2,%r7                 # add to total size
+       tm      8(%r5),0x01             # found a tape mark ?
+       bnz     .Ldone
+       l       %r0,.Lccwread+4         # update CCW data addresses
+       ar      %r0,%r7
+       st      %r0,.Lccwread+4
+       b       .Lldlp
 .Ldone:
-        l     %r14,.Lldret
-        br    %r14                             # r2 contains the total size
+       l       %r14,.Lldret
+       br      %r14                    # r2 contains the total size
 .Lrecov:
-        bas   %r14,.Lsense                     # do the sensing
-        bct   %r6,.Lssch                       # dec. retry count & branch
-        b     .Llderr
+       bas     %r14,.Lsense            # do the sensing
+       bct     %r6,.Lssch              # dec. retry count & branch
+       b       .Llderr
 #
 # Sense subroutine
 #
 .Lsense:
-        st    %r14,.Lsnsret
-        la    %r7,.Lorbsense              
-        ssch  0(%r7)                           # start sense command
-        bnz   .Llderr
-        bas   %r14,.Lwait4io
-        l     %r14,.Lsnsret
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Llderr
-        br    %r14
+       st      %r14,.Lsnsret
+       la      %r7,.Lorbsense
+       ssch    0(%r7)                  # start sense command
+       bnz     .Llderr
+       bas     %r14,.Lwait4io
+       l       %r14,.Lsnsret
+       tm      8(%r5),0x82             # do we have a problem ?
+       bnz     .Llderr
+       br      %r14
 #
 # Wait for interrupt subroutine
 #
 .Lwait4io:
-        lpsw  .Lwaitpsw                 
+       lpsw    .Lwaitpsw
 .Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-        bne   .Lwait4io
-        tsch  0(%r5)
-        slr   %r0,%r0
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lwtexit
-        tm    8(%r5),0x04                      # got device end ?
-        bz    .Lwait4io
+       c       %r1,0xb8                # compare subchannel number
+       bne     .Lwait4io
+       tsch    0(%r5)
+       slr     %r0,%r0
+       tm      8(%r5),0x82             # do we have a problem ?
+       bnz     .Lwtexit
+       tm      8(%r5),0x04             # got device end ?
+       bz      .Lwait4io
 .Lwtexit:
-        br    %r14
+       br      %r14
 .Llderr:
-        lpsw  .Lcrash              
+       lpsw    .Lcrash
 
-        .align 8
+       .align  8
 .Lorbread:
-       .long  0x00000000,0x0080ff00,.Lccwread
-        .align 8
+       .long   0x00000000,0x0080ff00,.Lccwread
+       .align  8
 .Lorbsense:
-        .long  0x00000000,0x0080ff00,.Lccwsense
-        .align 8
+       .long   0x00000000,0x0080ff00,.Lccwsense
+       .align  8
 .Lccwread:
-        .long  0x02200000+IPL_BS,0x00000000
+       .long   0x02200000+IPL_BS,0x00000000
 .Lccwsense:
-        .long  0x04200001,0x00000000
+       .long   0x04200001,0x00000000
 .Lwaitpsw:
-       .long  0x020a0000,0x80000000+.Lioint
+       .long   0x020a0000,0x80000000+.Lioint
 
-.Lirb: .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
-.Lldret:.long  0
+.Lirb: .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.Lcr6: .long   0xff000000
+       .align  8
+.Lcrash:.long  0x000a0000,0x00000000
+.Lldret:.long  0
 .Lsnsret: .long 0
-#endif  /* CONFIG_IPL_TAPE */
+#endif /* CONFIG_IPL_TAPE */
 
 #ifdef CONFIG_IPL_VM
-#define IPL_BS 0x730
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x02000018,0x60000050           # by ipl to addresses 0-23.
-        .long  0x02000068,0x60000050           # (a PSW and two CCWs).
-        .fill  80-24,1,0x40                    # bytes 24-79 are discarded !!
-        .long  0x020000f0,0x60000050           # The next 160 byte are loaded
-        .long  0x02000140,0x60000050           # to addresses 0x18-0xb7
-        .long  0x02000190,0x60000050           # They form the continuation
-        .long  0x020001e0,0x60000050           # of the CCW program started
-        .long  0x02000230,0x60000050           # by ipl and load the range
-        .long  0x02000280,0x60000050           # 0x0f0-0x730 from the image
-        .long  0x020002d0,0x60000050           # to the range 0x0f0-0x730
-        .long  0x02000320,0x60000050           # in memory. At the end of
-        .long  0x02000370,0x60000050           # the channel program the PSW
-        .long  0x020003c0,0x60000050           # at location 0 is loaded.
-        .long  0x02000410,0x60000050           # Initial processing starts
-        .long  0x02000460,0x60000050           # at 0xf0 = iplstart.
-        .long  0x020004b0,0x60000050
-        .long  0x02000500,0x60000050
-        .long  0x02000550,0x60000050
-        .long  0x020005a0,0x60000050
-        .long  0x020005f0,0x60000050
-        .long  0x02000640,0x60000050
-        .long  0x02000690,0x60000050
-        .long  0x020006e0,0x20000050
+#define IPL_BS 0x730
+       .org    0
+       .long   0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
+       .long   0x02000018,0x60000050           # by ipl to addresses 0-23.
+       .long   0x02000068,0x60000050           # (a PSW and two CCWs).
+       .fill   80-24,1,0x40                    # bytes 24-79 are discarded !!
+       .long   0x020000f0,0x60000050           # The next 160 byte are loaded
+       .long   0x02000140,0x60000050           # to addresses 0x18-0xb7
+       .long   0x02000190,0x60000050           # They form the continuation
+       .long   0x020001e0,0x60000050           # of the CCW program started
+       .long   0x02000230,0x60000050           # by ipl and load the range
+       .long   0x02000280,0x60000050           # 0x0f0-0x730 from the image
+       .long   0x020002d0,0x60000050           # to the range 0x0f0-0x730
+       .long   0x02000320,0x60000050           # in memory. At the end of
+       .long   0x02000370,0x60000050           # the channel program the PSW
+       .long   0x020003c0,0x60000050           # at location 0 is loaded.
+       .long   0x02000410,0x60000050           # Initial processing starts
+       .long   0x02000460,0x60000050           # at 0xf0 = iplstart.
+       .long   0x020004b0,0x60000050
+       .long   0x02000500,0x60000050
+       .long   0x02000550,0x60000050
+       .long   0x020005a0,0x60000050
+       .long   0x020005f0,0x60000050
+       .long   0x02000640,0x60000050
+       .long   0x02000690,0x60000050
+       .long   0x020006e0,0x20000050
 
-        .org   0xf0
+       .org    0xf0
 #
 # subroutine for loading cards from the reader
 #
-.Lloader:      
-       la    %r3,.Lorb                        # r2 = address of orb into r2
-       la    %r5,.Lirb                        # r4 = address of irb
-        la    %r6,.Lccws              
-        la    %r7,20
+.Lloader:
+       la      %r3,.Lorb               # r2 = address of orb into r2
+       la      %r5,.Lirb               # r4 = address of irb
+       la      %r6,.Lccws
+       la      %r7,20
 .Linit:
-        st    %r2,4(%r6)                       # initialize CCW data addresses
-        la    %r2,0x50(%r2)
-        la    %r6,8(%r6)
-        bct   7,.Linit
+       st      %r2,4(%r6)              # initialize CCW data addresses
+       la      %r2,0x50(%r2)
+       la      %r6,8(%r6)
+       bct     7,.Linit
 
-        lctl  %c6,%c6,.Lcr6                    # set IO subclass mask
-       slr   %r2,%r2
+       lctl    %c6,%c6,.Lcr6           # set IO subclass mask
+       slr     %r2,%r2
 .Lldlp:
-        ssch  0(%r3)                           # load chunk of 1600 bytes
-        bnz   .Llderr
+       ssch    0(%r3)                  # load chunk of 1600 bytes
+       bnz     .Llderr
 .Lwait4irq:
-        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
-        lpsw  .Lwaitpsw              
+       mvc     0x78(8),.Lnewpsw        # set up IO interrupt psw
+       lpsw    .Lwaitpsw
 .Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-       bne   .Lwait4irq
-       tsch  0(%r5)
+       c       %r1,0xb8                # compare subchannel number
+       bne     .Lwait4irq
+       tsch    0(%r5)
 
-       slr   %r0,%r0
-       ic    %r0,8(%r5)                       # get device status
-       chi   %r0,8                            # channel end ?
-       be    .Lcont
-       chi   %r0,12                           # channel end + device end ?
-       be    .Lcont
+       slr     %r0,%r0
+       ic      %r0,8(%r5)              # get device status
+       chi     %r0,8                   # channel end ?
+       be      .Lcont
+       chi     %r0,12                  # channel end + device end ?
+       be      .Lcont
 
-        l     %r0,4(%r5)
-        s     %r0,8(%r3)                       # r0/8 = number of ccws executed
-        mhi   %r0,10                           # *10 = number of bytes in ccws
-        lh    %r3,10(%r5)                      # get residual count
-        sr    %r0,%r3                          # #ccws*80-residual=#bytes read
-       ar    %r2,%r0
-       
-        br    %r14                             # r2 contains the total size
+       l       %r0,4(%r5)
+       s       %r0,8(%r3)              # r0/8 = number of ccws executed
+       mhi     %r0,10                  # *10 = number of bytes in ccws
+       lh      %r3,10(%r5)             # get residual count
+       sr      %r0,%r3                 # #ccws*80-residual=#bytes read
+       ar      %r2,%r0
+
+       br      %r14                    # r2 contains the total size
 
 .Lcont:
-       ahi   %r2,0x640                        # add 0x640 to total size
-        la    %r6,.Lccws             
-        la    %r7,20
+       ahi     %r2,0x640               # add 0x640 to total size
+       la      %r6,.Lccws
+       la      %r7,20
 .Lincr:
-        l     %r0,4(%r6)                       # update CCW data addresses
-        ahi   %r0,0x640
-        st    %r0,4(%r6)
-        ahi   %r6,8
-        bct   7,.Lincr
+       l       %r0,4(%r6)              # update CCW data addresses
+       ahi     %r0,0x640
+       st      %r0,4(%r6)
+       ahi     %r6,8
+       bct     7,.Lincr
 
-        b     .Lldlp
+       b       .Lldlp
 .Llderr:
-        lpsw  .Lcrash              
+       lpsw    .Lcrash
 
-        .align 8
-.Lorb: .long  0x00000000,0x0080ff00,.Lccws
-.Lirb: .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-.Lloadp:.long  0,0
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
+       .align  8
+.Lorb: .long   0x00000000,0x0080ff00,.Lccws
+.Lirb: .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.Lcr6: .long   0xff000000
+.Lloadp:.long  0,0
+       .align  8
+.Lcrash:.long  0x000a0000,0x00000000
 .Lnewpsw:
-        .long  0x00080000,0x80000000+.Lioint
+       .long   0x00080000,0x80000000+.Lioint
 .Lwaitpsw:
-        .long  0x020a0000,0x80000000+.Lioint
+       .long   0x020a0000,0x80000000+.Lioint
 
-        .align 8
-.Lccws: .rept  19
-        .long  0x02600050,0x00000000
-        .endr
-        .long  0x02200050,0x00000000
-#endif  /* CONFIG_IPL_VM */
+       .align  8
+.Lccws: .rept  19
+       .long   0x02600050,0x00000000
+       .endr
+       .long   0x02200050,0x00000000
+#endif /* CONFIG_IPL_VM */
 
 iplstart:
-        lh    %r1,0xb8                         # test if subchannel number
-        bct   %r1,.Lnoload                     #  is valid
-       l     %r1,0xb8                         # load ipl subchannel number
-        la    %r2,IPL_BS                       # load start address
-        bas   %r14,.Lloader                    # load rest of ipl image
-        l     %r12,.Lparm                      # pointer to parameter area
-        st    %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
+       lh      %r1,0xb8                # test if subchannel number
+       bct     %r1,.Lnoload            #  is valid
+       l       %r1,0xb8                # load ipl subchannel number
+       la      %r2,IPL_BS              # load start address
+       bas     %r14,.Lloader           # load rest of ipl image
+       l       %r12,.Lparm             # pointer to parameter area
+       st      %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
 
 #
 # load parameter file from ipl device
 #
 .Lagain1:
-       l     %r2,.Linitrd                     # ramdisk loc. is temp
-        bas   %r14,.Lloader                    # load parameter file
-        ltr   %r2,%r2                          # got anything ?
-        bz    .Lnopf
-       chi   %r2,895
-       bnh   .Lnotrunc
-       la    %r2,895
+       l       %r2,.Linitrd            # ramdisk loc. is temp
+       bas     %r14,.Lloader           # load parameter file
+       ltr     %r2,%r2                 # got anything ?
+       bz      .Lnopf
+       chi     %r2,895
+       bnh     .Lnotrunc
+       la      %r2,895
 .Lnotrunc:
-       l     %r4,.Linitrd
-       clc   0(3,%r4),.L_hdr                  # if it is HDRx
-       bz    .Lagain1                         # skip dataset header
-       clc   0(3,%r4),.L_eof                  # if it is EOFx
-       bz    .Lagain1                         # skip dateset trailer
-        la    %r5,0(%r4,%r2)
-        lr    %r3,%r2
+       l       %r4,.Linitrd
+       clc     0(3,%r4),.L_hdr         # if it is HDRx
+       bz      .Lagain1                # skip dataset header
+       clc     0(3,%r4),.L_eof         # if it is EOFx
+       bz      .Lagain1                # skip dateset trailer
+       la      %r5,0(%r4,%r2)
+       lr      %r3,%r2
 .Lidebc:
-        tm    0(%r5),0x80                      # high order bit set ?
-        bo    .Ldocv                           #  yes -> convert from EBCDIC
-        ahi   %r5,-1
-        bct   %r3,.Lidebc
-        b     .Lnocv
+       tm      0(%r5),0x80             # high order bit set ?
+       bo      .Ldocv                  #  yes -> convert from EBCDIC
+       ahi     %r5,-1
+       bct     %r3,.Lidebc
+       b       .Lnocv
 .Ldocv:
-        l     %r3,.Lcvtab
-        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
-        tr    256(256,%r4),0(%r3)
-        tr    512(256,%r4),0(%r3)
-        tr    768(122,%r4),0(%r3)
-.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
-       mvc   0(256,%r3),0(%r4)
-       mvc   256(256,%r3),256(%r4)
-       mvc   512(256,%r3),512(%r4)
-       mvc   768(122,%r3),768(%r4)
-        slr   %r0,%r0
-        b     .Lcntlp
+       l       %r3,.Lcvtab
+       tr      0(256,%r4),0(%r3)       # convert parameters to ascii
+       tr      256(256,%r4),0(%r3)
+       tr      512(256,%r4),0(%r3)
+       tr      768(122,%r4),0(%r3)
+.Lnocv: la     %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
+       mvc     0(256,%r3),0(%r4)
+       mvc     256(256,%r3),256(%r4)
+       mvc     512(256,%r3),512(%r4)
+       mvc     768(122,%r3),768(%r4)
+       slr     %r0,%r0
+       b       .Lcntlp
 .Ldelspc:
-        ic    %r0,0(%r2,%r3)
-        chi   %r0,0x20                         # is it a space ?
-        be    .Lcntlp
-        ahi   %r2,1
-        b     .Leolp
+       ic      %r0,0(%r2,%r3)
+       chi     %r0,0x20                # is it a space ?
+       be      .Lcntlp
+       ahi     %r2,1
+       b       .Leolp
 .Lcntlp:
-        brct  %r2,.Ldelspc
+       brct    %r2,.Ldelspc
 .Leolp:
-        slr   %r0,%r0
-        stc   %r0,0(%r2,%r3)                   # terminate buffer
+       slr     %r0,%r0
+       stc     %r0,0(%r2,%r3)          # terminate buffer
 .Lnopf:
 
 #
 # load ramdisk from ipl device
-#      
+#
 .Lagain2:
-       l     %r2,.Linitrd                     # addr of ramdisk
-       st    %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
-        bas   %r14,.Lloader                    # load ramdisk
-       st    %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
-        ltr   %r2,%r2
-        bnz   .Lrdcont
-        st    %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
+       l       %r2,.Linitrd            # addr of ramdisk
+       st      %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
+       bas     %r14,.Lloader           # load ramdisk
+       st      %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd
+       ltr     %r2,%r2
+       bnz     .Lrdcont
+       st      %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
 .Lrdcont:
-       l     %r2,.Linitrd
+       l       %r2,.Linitrd
 
-       clc   0(3,%r2),.L_hdr                  # skip HDRx and EOFx 
-       bz    .Lagain2
-       clc   0(3,%r2),.L_eof
-       bz    .Lagain2
+       clc     0(3,%r2),.L_hdr         # skip HDRx and EOFx
+       bz      .Lagain2
+       clc     0(3,%r2),.L_eof
+       bz      .Lagain2
 
 #ifdef CONFIG_IPL_VM
 #
 # reset files in VM reader
 #
-        stidp __LC_CPUID                       # store cpuid
-       tm    __LC_CPUID,0xff                  # running VM ?
-       bno   .Lnoreset
-        la    %r2,.Lreset              
-        lhi   %r3,26
-       diag  %r2,%r3,8
-       la    %r5,.Lirb
-       stsch 0(%r5)                           # check if irq is pending
-       tm    30(%r5),0x0f                     # by verifying if any of the
-       bnz   .Lwaitforirq                     # activity or status control
-       tm    31(%r5),0xff                     # bits is set in the schib
-       bz    .Lnoreset
+       stidp   __LC_CPUID              # store cpuid
+       tm      __LC_CPUID,0xff         # running VM ?
+       bno     .Lnoreset
+       la      %r2,.Lreset
+       lhi     %r3,26
+       diag    %r2,%r3,8
+       la      %r5,.Lirb
+       stsch   0(%r5)                  # check if irq is pending
+       tm      30(%r5),0x0f            # by verifying if any of the
+       bnz     .Lwaitforirq            # activity or status control
+       tm      31(%r5),0xff            # bits is set in the schib
+       bz      .Lnoreset
 .Lwaitforirq:
-       mvc   0x78(8),.Lrdrnewpsw              # set up IO interrupt psw
+       mvc     0x78(8),.Lrdrnewpsw     # set up IO interrupt psw
 .Lwaitrdrirq:
-       lpsw  .Lrdrwaitpsw
+       lpsw    .Lrdrwaitpsw
 .Lrdrint:
-       c     %r1,0xb8                         # compare subchannel number
-       bne   .Lwaitrdrirq
-       la    %r5,.Lirb
-       tsch  0(%r5)
+       c       %r1,0xb8                # compare subchannel number
+       bne     .Lwaitrdrirq
+       la      %r5,.Lirb
+       tsch    0(%r5)
 .Lnoreset:
-        b     .Lnoload
+       b       .Lnoload
 
-       .align 8
+       .align  8
 .Lrdrnewpsw:
-       .long  0x00080000,0x80000000+.Lrdrint
+       .long   0x00080000,0x80000000+.Lrdrint
 .Lrdrwaitpsw:
-       .long  0x020a0000,0x80000000+.Lrdrint
+       .long   0x020a0000,0x80000000+.Lrdrint
 #endif
 
 #
 # everything loaded, go for it
 #
 .Lnoload:
-        l     %r1,.Lstartup
-        br    %r1
+       l       %r1,.Lstartup
+       br      %r1
 
-.Linitrd:.long _end + 0x400000                # default address of initrd
+.Linitrd:.long _end + 0x400000         # default address of initrd
 .Lparm:        .long  PARMAREA
 .Lstartup: .long startup
-.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
-.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
-        .byte  0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
-        .byte  0xc8,0xd6,0xd3,0xc4             # "change rdr all keep nohold"
-.L_eof: .long  0xc5d6c600       /* C'EOF' */
-.L_hdr: .long  0xc8c4d900       /* C'HDR' */
+.Lcvtab:.long  _ebcasc                 # ebcdic to ascii table
+.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
+       .byte   0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
+       .byte   0xc8,0xd6,0xd3,0xc4     # "change rdr all keep nohold"
+.L_eof: .long  0xc5d6c600       /* C'EOF' */
+.L_hdr: .long  0xc8c4d900       /* C'HDR' */
 
-#endif  /* CONFIG_IPL */
+#endif /* CONFIG_IPL */
 
 #
 # SALIPL loader support. Based on a patch by Rob van der Heij.
 # This entry point is called directly from the SALIPL loader and
 # doesn't need a builtin ipl record.
 #
-        .org  0x800
-       .globl start
+       .org    0x800
+       .globl  start
 start:
-       stm   %r0,%r15,0x07b0           # store registers
-       basr  %r12,%r0
+       stm     %r0,%r15,0x07b0         # store registers
+       basr    %r12,%r0
 .base:
-       l     %r11,.parm
-       l     %r8,.cmd                  # pointer to command buffer
+       l       %r11,.parm
+       l       %r8,.cmd                # pointer to command buffer
 
-       ltr   %r9,%r9                   # do we have SALIPL parameters?
-       bp    .sk8x8
+       ltr     %r9,%r9                 # do we have SALIPL parameters?
+       bp      .sk8x8
 
-       mvc   0(64,%r8),0x00b0          # copy saved registers
-       xc    64(240-64,%r8),0(%r8)     # remainder of buffer
-       tr    0(64,%r8),.lowcase        
-       b     .gotr
+       mvc     0(64,%r8),0x00b0        # copy saved registers
+       xc      64(240-64,%r8),0(%r8)   # remainder of buffer
+       tr      0(64,%r8),.lowcase
+       b       .gotr
 .sk8x8:
-       mvc   0(240,%r8),0(%r9)         # copy iplparms into buffer
+       mvc     0(240,%r8),0(%r9)       # copy iplparms into buffer
 .gotr:
-       l     %r10,.tbl                 # EBCDIC to ASCII table
-       tr    0(240,%r8),0(%r10)
-       stidp __LC_CPUID                # Are we running on VM maybe
-       cli   __LC_CPUID,0xff
-       bnz   .test
-       .long 0x83300060                # diag 3,0,x'0060' - storage size
-       b     .done
+       l       %r10,.tbl               # EBCDIC to ASCII table
+       tr      0(240,%r8),0(%r10)
+       stidp   __LC_CPUID              # Are we running on VM maybe
+       cli     __LC_CPUID,0xff
+       bnz     .test
+       .long   0x83300060              # diag 3,0,x'0060' - storage size
+       b       .done
 .test:
-       mvc   0x68(8),.pgmnw            # set up pgm check handler
-       l     %r2,.fourmeg
-       lr    %r3,%r2
-       bctr  %r3,%r0                   # 4M-1
-.loop:  iske  %r0,%r3
-       ar    %r3,%r2
+       mvc     0x68(8),.pgmnw          # set up pgm check handler
+       l       %r2,.fourmeg
+       lr      %r3,%r2
+       bctr    %r3,%r0                 # 4M-1
+.loop: iske    %r0,%r3
+       ar      %r3,%r2
 .pgmx:
-       sr    %r3,%r2
-       la    %r3,1(%r3)
+       sr      %r3,%r2
+       la      %r3,1(%r3)
 .done:
-        l     %r1,.memsize
-       st    %r3,ARCH_OFFSET(%r1)
-       slr   %r0,%r0
-       st    %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
-       st    %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
-       j     startup                   # continue with startup
-.tbl:  .long _ebcasc                   # translate table
-.cmd:  .long COMMAND_LINE              # address of command line buffer
-.parm: .long PARMAREA
+       l       %r1,.memsize
+       st      %r3,ARCH_OFFSET(%r1)
+       slr     %r0,%r0
+       st      %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
+       st      %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
+       j       startup                 # continue with startup
+.tbl:  .long   _ebcasc                 # translate table
+.cmd:  .long   COMMAND_LINE            # address of command line buffer
+.parm: .long   PARMAREA
 .memsize: .long memory_size
 .fourmeg: .long 0x00400000             # 4M
-.pgmnw:        .long 0x00080000,.pgmx
+.pgmnw:        .long   0x00080000,.pgmx
 .lowcase:
-       .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 
+       .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
        .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
-       .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 
+       .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
        .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
-       .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 
+       .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
        .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
-       .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 
+       .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
        .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
-       .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 
+       .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
        .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
-       .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 
+       .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
        .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
-       .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 
+       .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
        .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
-       .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 
+       .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
        .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
 
-       .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 
+       .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
        .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
-       .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 
+       .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
        .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
-       .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 
+       .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
        .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
-       .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 
+       .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
        .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
-       .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87   # .abcdefg 
+       .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87   # .abcdefg
        .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf   # hi
-       .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97   # .jklmnop
+       .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97   # .jklmnop
        .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf   # qr
        .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7   # ..stuvwx
        .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef   # yz
-       .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
+       .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
        .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
 
 #ifdef CONFIG_64BIT
index a8bdd96494c77dcd5b694cd2619ccad9b26b5856..48998d50b00abd7bdbc48640354ca15e56b03fe9 100644 (file)
 # this is called either by the ipl loader or directly by PSW restart
 # or linload or SALIPL
 #
-       .org  0x10000
-startup:basr  %r13,0                    # get base
-.LPG0: l     %r13,0f-.LPG0(%r13)
-       b     0(%r13)
-0:     .long startup_continue
+       .org    0x10000
+startup:basr   %r13,0                  # get base
+.LPG0: l       %r13,0f-.LPG0(%r13)
+       b       0(%r13)
+0:     .long   startup_continue
 
 #
 # params at 10400 (setup.h)
 #
-       .org   PARMAREA
-       .quad                         # IPL_DEVICE
-       .quad                         # INITRD_START
-       .quad                         # INITRD_SIZE
+       .org    PARMAREA
+       .quad   0                       # IPL_DEVICE
+       .quad   0                       # INITRD_START
+       .quad   0                       # INITRD_SIZE
 
-       .org   COMMAND_LINE
-       .byte  "root=/dev/ram0 ro"
-       .byte  0
+       .org    COMMAND_LINE
+       .byte   "root=/dev/ram0 ro"
+       .byte   0
 
-       .org   0x11000
+       .org    0x11000
 
 startup_continue:
-       basr  %r13,0                     # get base
-.LPG1:  sll   %r13,1                     # remove high order bit
-        srl   %r13,1
-        lhi   %r1,1                      # mode 1 = esame
-       mvi   __LC_AR_MODE_ID,1          # set esame flag
-        slr   %r0,%r0                    # set cpuid to zero
-        sigp  %r1,%r0,0x12               # switch to esame mode
-       sam64                            # switch to 64 bit mode
-       lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-       lg    %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
-                                        # move IPL device to lowcore
-        mvc   __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
+       basr    %r13,0                  # get base
+.LPG1: sll     %r13,1                  # remove high order bit
+       srl     %r13,1
+       lhi     %r1,1                   # mode 1 = esame
+       mvi     __LC_AR_MODE_ID,1       # set esame flag
+       slr     %r0,%r0                 # set cpuid to zero
+       sigp    %r1,%r0,0x12            # switch to esame mode
+       sam64                           # switch to 64 bit mode
+       lctlg   %c0,%c15,.Lctl-.LPG1(%r13)      # load control registers
+       lg      %r12,.Lparmaddr-.LPG1(%r13)     # pointer to parameter area
+                                       # move IPL device to lowcore
+       mvc     __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
 #
 # Setup stack
 #
-       larl  %r15,init_thread_union
-       lg    %r14,__TI_task(%r15)      # cache current in lowcore
-       stg   %r14,__LC_CURRENT
-       aghi  %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
-       stg   %r15,__LC_KERNEL_STACK    # set end of kernel stack
-       aghi  %r15,-160
-       xc    __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+       larl    %r15,init_thread_union
+       lg      %r14,__TI_task(%r15)    # cache current in lowcore
+       stg     %r14,__LC_CURRENT
+       aghi    %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
+       stg     %r15,__LC_KERNEL_STACK  # set end of kernel stack
+       aghi    %r15,-160
+       xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
 
-       brasl %r14,ipl_save_parameters
+       brasl   %r14,ipl_save_parameters
 #
 # clear bss memory
 #
-       larl  %r2,__bss_start           # start of bss segment
-        larl  %r3,_end                  # end of bss segment
-        sgr   %r3,%r2                   # length of bss
-        sgr   %r4,%r4                   #
-        sgr   %r5,%r5                   # set src,length and pad to zero
-        mvcle %r2,%r4,0                 # clear mem
-        jo    .-4                       # branch back, if not finish
+       larl    %r2,__bss_start         # start of bss segment
+       larl    %r3,_end                # end of bss segment
+       sgr     %r3,%r2                 # length of bss
+       sgr     %r4,%r4                 #
+       sgr     %r5,%r5                 # set src,length and pad to zero
+       mvcle   %r2,%r4,0               # clear mem
+       jo      .-4                     # branch back, if not finish
 
-       l     %r2,.Lrcp-.LPG1(%r13)     # Read SCP forced command word
+       l       %r2,.Lrcp-.LPG1(%r13)   # Read SCP forced command word
 .Lservicecall:
-       stosm .Lpmask-.LPG1(%r13),0x01  # authorize ext interrupts
+       stosm   .Lpmask-.LPG1(%r13),0x01        # authorize ext interrupts
 
-       stctg %r0,%r0,.Lcr-.LPG1(%r13)  # get cr0
-       la    %r1,0x200                 # set bit 22
-       og    %r1,.Lcr-.LPG1(%r13)      # or old cr0 with r1
-       stg   %r1,.Lcr-.LPG1(%r13)
-       lctlg %r0,%r0,.Lcr-.LPG1(%r13)  # load modified cr0
+       stctg   %r0,%r0,.Lcr-.LPG1(%r13)        # get cr0
+       la      %r1,0x200               # set bit 22
+       og      %r1,.Lcr-.LPG1(%r13)    # or old cr0 with r1
+       stg     %r1,.Lcr-.LPG1(%r13)
+       lctlg   %r0,%r0,.Lcr-.LPG1(%r13)        # load modified cr0
 
-       mvc   __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
-       larl  %r1,.Lsclph
-       stg   %r1,__LC_EXT_NEW_PSW+8    # set handler
+       mvc     __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
+       larl    %r1,.Lsclph
+       stg     %r1,__LC_EXT_NEW_PSW+8  # set handler
 
-       larl  %r4,.Lsccb                # %r4 is our index for sccb stuff
-       lgr   %r1,%r4                   # our sccb
-       .insn rre,0xb2200000,%r2,%r1    # service call
-       ipm   %r1
-       srl   %r1,28                    # get cc code
-       xr    %r3,%r3
-       chi   %r1,3
-       be    .Lfchunk-.LPG1(%r13)      # leave
-       chi   %r1,2
-       be    .Lservicecall-.LPG1(%r13)
-       lpswe .Lwaitsclp-.LPG1(%r13)
+       larl    %r4,.Lsccb              # %r4 is our index for sccb stuff
+       lgr     %r1,%r4                 # our sccb
+       .insn   rre,0xb2200000,%r2,%r1  # service call
+       ipm     %r1
+       srl     %r1,28                  # get cc code
+       xr      %r3,%r3
+       chi     %r1,3
+       be      .Lfchunk-.LPG1(%r13)    # leave
+       chi     %r1,2
+       be      .Lservicecall-.LPG1(%r13)
+       lpswe   .Lwaitsclp-.LPG1(%r13)
 .Lsclph:
-       lh    %r1,.Lsccbr-.Lsccb(%r4)
-       chi   %r1,0x10                  # 0x0010 is the sucess code
-       je    .Lprocsccb                # let's process the sccb
-       chi   %r1,0x1f0
-       bne   .Lfchunk-.LPG1(%r13)      # unhandled error code
-       c     %r2,.Lrcp-.LPG1(%r13)     # Did we try Read SCP forced
-       bne   .Lfchunk-.LPG1(%r13)      # if no, give up
-       l     %r2,.Lrcp2-.LPG1(%r13)    # try with Read SCP
-       b     .Lservicecall-.LPG1(%r13)
+       lh      %r1,.Lsccbr-.Lsccb(%r4)
+       chi     %r1,0x10                # 0x0010 is the sucess code
+       je      .Lprocsccb              # let's process the sccb
+       chi     %r1,0x1f0
+       bne     .Lfchunk-.LPG1(%r13)    # unhandled error code
+       c       %r2,.Lrcp-.LPG1(%r13)   # Did we try Read SCP forced
+       bne     .Lfchunk-.LPG1(%r13)    # if no, give up
+       l       %r2,.Lrcp2-.LPG1(%r13)  # try with Read SCP
+       b       .Lservicecall-.LPG1(%r13)
 .Lprocsccb:
-       lghi  %r1,0
-       icm   %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
-       jnz   .Lscnd
-       lg    %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one
+       lghi    %r1,0
+       icm     %r1,3,.Lscpincr1-.Lsccb(%r4)    # use this one if != 0
+       jnz     .Lscnd
+       lg      %r1,.Lscpincr2-.Lsccb(%r4)      # otherwise use this one
 .Lscnd:
-       xr    %r3,%r3                   # same logic
-       ic    %r3,.Lscpa1-.Lsccb(%r4)
-       chi   %r3,0x00
-       jne   .Lcompmem
-       l     %r3,.Lscpa2-.Lsccb(%r4)
+       xr      %r3,%r3                 # same logic
+       ic      %r3,.Lscpa1-.Lsccb(%r4)
+       chi     %r3,0x00
+       jne     .Lcompmem
+       l       %r3,.Lscpa2-.Lsccb(%r4)
 .Lcompmem:
-       mlgr  %r2,%r1                   # mem in MB on 128-bit
-       l     %r1,.Lonemb-.LPG1(%r13)
-       mlgr  %r2,%r1                   # mem size in bytes in %r3
-       b     .Lfchunk-.LPG1(%r13)
+       mlgr    %r2,%r1                 # mem in MB on 128-bit
+       l       %r1,.Lonemb-.LPG1(%r13)
+       mlgr    %r2,%r1                 # mem size in bytes in %r3
+       b       .Lfchunk-.LPG1(%r13)
 
-       .align 4
+       .align  4
 .Lpmask:
-       .byte 0
-       .align 8
+       .byte   0
+       .align  8
 .Lcr:
-       .quad 0x00  # place holder for cr0
+       .quad   0x00  # place holder for cr0
 .Lwaitsclp:
-       .quad  0x0102000180000000,.Lsclph
+       .quad   0x0102000180000000,.Lsclph
 .Lrcp:
-       .int 0x00120001 # Read SCP forced code
+       .int    0x00120001 # Read SCP forced code
 .Lrcp2:
-       .int 0x00020001 # Read SCP code
+       .int    0x00020001 # Read SCP code
 .Lonemb:
-       .int 0x100000
+       .int    0x100000
 
 .Lfchunk:
-                                        # set program check new psw mask
-       mvc   __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
+                                       # set program check new psw mask
+       mvc     __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
 
 #
 # find memory chunks.
 #
-       lgr   %r9,%r3                    # end of mem
-       larl  %r1,.Lchkmem               # set program check address
-       stg   %r1,__LC_PGM_NEW_PSW+8
-       la    %r1,1                      # test in increments of 128KB
-       sllg  %r1,%r1,17
-       larl  %r3,memory_chunk
-       slgr  %r4,%r4                    # set start of chunk to zero
-       slgr  %r5,%r5                    # set end of chunk to zero
-       slr  %r6,%r6                     # set access code to zero
-       la    %r10,MEMORY_CHUNKS         # number of chunks
+       lgr     %r9,%r3                 # end of mem
+       larl    %r1,.Lchkmem            # set program check address
+       stg     %r1,__LC_PGM_NEW_PSW+8
+       la      %r1,1                   # test in increments of 128KB
+       sllg    %r1,%r1,17
+       larl    %r3,memory_chunk
+       slgr    %r4,%r4                 # set start of chunk to zero
+       slgr    %r5,%r5                 # set end of chunk to zero
+       slr     %r6,%r6                 # set access code to zero
+       la      %r10,MEMORY_CHUNKS      # number of chunks
 .Lloop:
-       tprot 0(%r5),0                   # test protection of first byte
-       ipm   %r7
-       srl   %r7,28
-       clr   %r6,%r7                    # compare cc with last access code
-       je    .Lsame
-       j     .Lchkmem
+       tprot   0(%r5),0                # test protection of first byte
+       ipm     %r7
+       srl     %r7,28
+       clr     %r6,%r7                 # compare cc with last access code
+       je      .Lsame
+       j       .Lchkmem
 .Lsame:
-       algr  %r5,%r1                    # add 128KB to end of chunk
-                                        # no need to check here,
-       brc   12,.Lloop                  # this is the same chunk
-.Lchkmem:                               # > 16EB or tprot got a program check
-       clgr  %r4,%r5                    # chunk size > 0?
-       je    .Lchkloop
-       stg   %r4,0(%r3)                 # store start address of chunk
-       lgr   %r0,%r5
-       slgr  %r0,%r4
-       stg   %r0,8(%r3)                 # store size of chunk
-       st    %r6,20(%r3)                # store type of chunk
-       la    %r3,24(%r3)
-       larl  %r8,memory_size
-       stg   %r5,0(%r8)                 # store memory size
-       ahi   %r10,-1                    # update chunk number
+       algr    %r5,%r1                 # add 128KB to end of chunk
+                                       # no need to check here,
+       brc     12,.Lloop               # this is the same chunk
+.Lchkmem:                              # > 16EB or tprot got a program check
+       clgr    %r4,%r5                 # chunk size > 0?
+       je      .Lchkloop
+       stg     %r4,0(%r3)              # store start address of chunk
+       lgr     %r0,%r5
+       slgr    %r0,%r4
+       stg     %r0,8(%r3)              # store size of chunk
+       st      %r6,20(%r3)             # store type of chunk
+       la      %r3,24(%r3)
+       larl    %r8,memory_size
+       stg     %r5,0(%r8)              # store memory size
+       ahi     %r10,-1                 # update chunk number
 .Lchkloop:
-       lr    %r6,%r7                    # set access code to last cc
+       lr      %r6,%r7                 # set access code to last cc
        # we got an exception or we're starting a new
        # chunk , we must check if we should
        # still try to find valid memory (if we detected
        # the amount of available storage), and if we
        # have chunks left
-       lghi  %r4,1
-       sllg  %r4,%r4,31
-       clgr  %r5,%r4
-       je    .Lhsaskip
-       xr    %r0, %r0
-       clgr  %r0, %r9                   # did we detect memory?
-       je    .Ldonemem                  # if not, leave
-       chi   %r10, 0                    # do we have chunks left?
-       je    .Ldonemem
+       lghi    %r4,1
+       sllg    %r4,%r4,31
+       clgr    %r5,%r4
+       je      .Lhsaskip
+       xr      %r0, %r0
+       clgr    %r0, %r9                # did we detect memory?
+       je      .Ldonemem               # if not, leave
+       chi     %r10, 0                 # do we have chunks left?
+       je      .Ldonemem
 .Lhsaskip:
-       algr  %r5,%r1                    # add 128KB to end of chunk
-       lgr   %r4,%r5                    # potential new chunk
-       clgr  %r5,%r9                    # should we go on?
-       jl    .Lloop
-.Ldonemem:             
+       algr    %r5,%r1                 # add 128KB to end of chunk
+       lgr     %r4,%r5                 # potential new chunk
+       clgr    %r5,%r9                 # should we go on?
+       jl      .Lloop
+.Ldonemem:
 
-       larl  %r12,machine_flags
+       larl    %r12,machine_flags
 #
 # find out if we are running under VM
 #
-        stidp  __LC_CPUID               # store cpuid
-       tm     __LC_CPUID,0xff          # running under VM ?
-       bno    0f-.LPG1(%r13)
-        oi     7(%r12),1                # set VM flag
-0:      lh     %r0,__LC_CPUID+4         # get cpu version
-        chi    %r0,0x7490               # running on a P/390 ?
-        bne    1f-.LPG1(%r13)
-        oi     7(%r12),4                # set P/390 flag
+       stidp   __LC_CPUID              # store cpuid
+       tm      __LC_CPUID,0xff         # running under VM ?
+       bno     0f-.LPG1(%r13)
+       oi      7(%r12),1               # set VM flag
+0:     lh      %r0,__LC_CPUID+4        # get cpu version
+       chi     %r0,0x7490              # running on a P/390 ?
+       bne     1f-.LPG1(%r13)
+       oi      7(%r12),4               # set P/390 flag
 1:
 
 #
 # find out if we have the MVPG instruction
 #
-       la     %r1,0f-.LPG1(%r13)       # set program check address
-       stg    %r1,__LC_PGM_NEW_PSW+8
-       sgr    %r0,%r0
-       lghi   %r1,0
-       lghi   %r2,0
-       mvpg   %r1,%r2                  # test MVPG instruction
-       oi     7(%r12),16               # set MVPG flag
+       la      %r1,0f-.LPG1(%r13)      # set program check address
+       stg     %r1,__LC_PGM_NEW_PSW+8
+       sgr     %r0,%r0
+       lghi    %r1,0
+       lghi    %r2,0
+       mvpg    %r1,%r2                 # test MVPG instruction
+       oi      7(%r12),16              # set MVPG flag
 0:
 
 #
 # find out if the diag 0x44 works in 64 bit mode
 #
-       la     %r1,0f-.LPG1(%r13)       # set program check address
-       stg    %r1,__LC_PGM_NEW_PSW+8
-       diag   0,0,0x44                 # test diag 0x44
-       oi     7(%r12),32               # set diag44 flag
-0:     
+       la      %r1,0f-.LPG1(%r13)      # set program check address
+       stg     %r1,__LC_PGM_NEW_PSW+8
+       diag    0,0,0x44                # test diag 0x44
+       oi      7(%r12),32              # set diag44 flag
+0:
 
 #
 # find out if we have the IDTE instruction
 #
-       la     %r1,0f-.LPG1(%r13)       # set program check address
-       stg    %r1,__LC_PGM_NEW_PSW+8
+       la      %r1,0f-.LPG1(%r13)      # set program check address
+       stg     %r1,__LC_PGM_NEW_PSW+8
        .long   0xb2b10000              # store facility list
        tm      0xc8,0x08               # check bit for clearing-by-ASCE
        bno     0f-.LPG1(%r13)
@@ -263,45 +263,45 @@ startup_continue:
        oi      6(%r12),2               # set MVCOS flag
 1:
 
-        lpswe .Lentry-.LPG1(13)         # jump to _stext in primary-space,
-                                        # virtual and never return ...
-        .align 16
-.Lentry:.quad  0x0000000180000000,_stext
-.Lctl:  .quad  0x04b50002               # cr0: various things
-        .quad  0                        # cr1: primary space segment table
-        .quad  .Lduct                   # cr2: dispatchable unit control table
-        .quad  0                        # cr3: instruction authorization
-        .quad  0                        # cr4: instruction authorization
-        .quad  0xffffffffffffffff       # cr5: primary-aste origin
-        .quad  0                        # cr6:  I/O interrupts
-        .quad  0                        # cr7:  secondary space segment table
-        .quad  0                        # cr8:  access registers translation
-        .quad  0                        # cr9:  tracing off
-        .quad  0                        # cr10: tracing off
-        .quad  0                        # cr11: tracing off
-        .quad  0                        # cr12: tracing off
-        .quad  0                        # cr13: home space segment table
-        .quad  0xc0000000               # cr14: machine check handling off
-        .quad  0                        # cr15: linkage stack operations
-.Lduct: .long 0,0,0,0,0,0,0,0
-       .long 0,0,0,0,0,0,0,0
-.Lpcmsk:.quad  0x0000000180000000
+       lpswe   .Lentry-.LPG1(13)       # jump to _stext in primary-space,
+                                       # virtual and never return ...
+       .align  16
+.Lentry:.quad  0x0000000180000000,_stext
+.Lctl: .quad   0x04b50002              # cr0: various things
+       .quad   0                       # cr1: primary space segment table
+       .quad   .Lduct                  # cr2: dispatchable unit control table
+       .quad   0                       # cr3: instruction authorization
+       .quad   0                       # cr4: instruction authorization
+       .quad   0xffffffffffffffff      # cr5: primary-aste origin
+       .quad   0                       # cr6:  I/O interrupts
+       .quad   0                       # cr7:  secondary space segment table
+       .quad   0                       # cr8:  access registers translation
+       .quad   0                       # cr9:  tracing off
+       .quad   0                       # cr10: tracing off
+       .quad   0                       # cr11: tracing off
+       .quad   0                       # cr12: tracing off
+       .quad   0                       # cr13: home space segment table
+       .quad   0xc0000000              # cr14: machine check handling off
+       .quad   0                       # cr15: linkage stack operations
+.Lduct: .long  0,0,0,0,0,0,0,0
+       .long   0,0,0,0,0,0,0,0
+.Lpcmsk:.quad  0x0000000180000000
 .L4malign:.quad 0xffffffffffc00000
-.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
-.Lnop: .long  0x07000700
+.Lscan2g:.quad 0x80000000 + 0x20000 - 8        # 2GB + 128K - 8
+.Lnop: .long   0x07000700
 .Lparmaddr:
        .quad   PARMAREA
 
-       .globl ipl_schib
+       .globl  ipl_schib
 ipl_schib:
        .rept 13
        .long 0
        .endr
 
-       .globl ipl_flags
+       .globl  ipl_flags
 ipl_flags:
-       .long 0
-       .globl ipl_devno
+       .long   0
+       .globl  ipl_devno
 ipl_devno:
        .word 0
 
@@ -309,47 +309,47 @@ ipl_devno:
 .globl s390_readinfo_sccb
 s390_readinfo_sccb:
 .Lsccb:
-       .hword 0x1000                   # length, one page
-       .byte 0x00,0x00,0x00
-       .byte 0x80                      # variable response bit set
+       .hword  0x1000                  # length, one page
+       .byte   0x00,0x00,0x00
+       .byte   0x80                    # variable response bit set
 .Lsccbr:
-       .hword 0x00                     # response code
+       .hword  0x00                    # response code
 .Lscpincr1:
-       .hword 0x00
+       .hword  0x00
 .Lscpa1:
-       .byte 0x00
-       .fill 89,1,0
+       .byte   0x00
+       .fill   89,1,0
 .Lscpa2:
-       .int 0x00
+       .int    0x00
 .Lscpincr2:
-       .quad 0x00
-       .fill 3984,1,0
+       .quad   0x00
+       .fill   3984,1,0
        .org    0x13000
 
 #ifdef CONFIG_SHARED_KERNEL
-       .org   0x100000
+       .org    0x100000
 #endif
-       
+
 #
 # startup-code, running in absolute addressing mode
 #
-        .globl _stext
-_stext:        basr  %r13,0                    # get base
+       .globl  _stext
+_stext:        basr    %r13,0                  # get base
 .LPG3:
 # check control registers
-        stctg  %c0,%c15,0(%r15)
-       oi     6(%r15),0x40             # enable sigp emergency signal
-       oi     4(%r15),0x10             # switch on low address proctection
-        lctlg  %c0,%c15,0(%r15)
+       stctg   %c0,%c15,0(%r15)
+       oi      6(%r15),0x40            # enable sigp emergency signal
+       oi      4(%r15),0x10            # switch on low address proctection
+       lctlg   %c0,%c15,0(%r15)
 
-        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
-        brasl  %r14,start_kernel        # go to C code
+       lam     0,15,.Laregs-.LPG3(%r13)        # load acrs needed by uaccess
+       brasl   %r14,start_kernel       # go to C code
 #
 # We returned from start_kernel ?!? PANIK
 #
-        basr  %r13,0
-       lpswe .Ldw-.(%r13)           # load disabled wait psw
+       basr    %r13,0
+       lpswe   .Ldw-.(%r13)            # load disabled wait psw
 
-            .align 8
-.Ldw:       .quad  0x0002000180000000,0x0000000000000000
-.Laregs:    .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+       .align  8
+.Ldw:  .quad   0x0002000180000000,0x0000000000000000
+.Laregs:.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
index 6555cc48e28f8ed40d8d74723222aac20ac6a52e..1f5e782b3d050173741898bfb4ca4fdb6af0e963 100644 (file)
@@ -120,24 +120,15 @@ static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
 
 static int diag308(unsigned long subcode, void *addr)
 {
-       register unsigned long _addr asm("0") = (unsigned long)addr;
+       register unsigned long _addr asm("0") = (unsigned long) addr;
        register unsigned long _rc asm("1") = 0;
 
-       asm volatile (
-               "   diag %0,%2,0x308\n"
-               "0: \n"
-               ".section __ex_table,\"a\"\n"
-#ifdef CONFIG_64BIT
-               "   .align 8\n"
-               "   .quad 0b, 0b\n"
-#else
-               "   .align 4\n"
-               "   .long 0b, 0b\n"
-#endif
-               ".previous\n"
+       asm volatile(
+               "       diag    %0,%2,0x308\n"
+               "0:\n"
+               EX_TABLE(0b,0b)
                : "+d" (_addr), "+d" (_rc)
-               : "d" (subcode) : "cc", "memory" );
-
+               : "d" (subcode) : "cc", "memory");
        return _rc;
 }
 
index d3cbfa3005eca0017fb63ca6ddfe88d979659bcc..6603fbb41d070d202a834b9ec4ef380775645663 100644 (file)
@@ -45,7 +45,7 @@
 #include <asm/irq.h>
 #include <asm/timer.h>
 
-asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
 /*
  * Return saved PC of a blocked thread. used in kernel/sched.
@@ -177,7 +177,8 @@ void show_regs(struct pt_regs *regs)
 
 extern void kernel_thread_starter(void);
 
-__asm__(".align 4\n"
+asm(
+       ".align 4\n"
        "kernel_thread_starter:\n"
        "    la    2,0(10)\n"
        "    basr  14,9\n"
index 4562cdbce8eb4400f1dc9d20cf3a3ab485bfc9c7..0340477f3b084d7f35498dff495d9755928647d7 100644 (file)
@@ -32,58 +32,58 @@ do_reipl_asm:       basr    %r13,0
                st      %r13, __LC_PSW_SAVE_AREA+4
 
                lctl    %c6,%c6,.Lall-.Lpg0(%r13)
-                lr      %r1,%r2
-               mvc     __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13)
-                stsch   .Lschib-.Lpg0(%r13)                                    
-               oi      .Lschib+5-.Lpg0(%r13),0x84 
-.Lecs:         xi      .Lschib+27-.Lpg0(%r13),0x01 
-               msch    .Lschib-.Lpg0(%r13) 
-                lhi     %r0,5
-.Lssch:                ssch    .Liplorb-.Lpg0(%r13)           
+               lr      %r1,%r2
+               mvc     __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13)
+               stsch   .Lschib-.Lpg0(%r13)
+               oi      .Lschib+5-.Lpg0(%r13),0x84
+.Lecs:         xi      .Lschib+27-.Lpg0(%r13),0x01
+               msch    .Lschib-.Lpg0(%r13)
+               lhi     %r0,5
+.Lssch:                ssch    .Liplorb-.Lpg0(%r13)
                jz      .L001
-                brct    %r0,.Lssch  
+               brct    %r0,.Lssch
                bas     %r14,.Ldisab-.Lpg0(%r13)
-.L001:         mvc     __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13)  
-.Ltpi:         lpsw    .Lwaitpsw-.Lpg0(%r13)          
+.L001:         mvc     __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13)
+.Ltpi:         lpsw    .Lwaitpsw-.Lpg0(%r13)
 .Lcont:                c       %r1,__LC_SUBCHANNEL_ID
                jnz     .Ltpi
                clc     __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13)
                jnz     .Ltpi
-               tsch    .Liplirb-.Lpg0(%r13)           
+               tsch    .Liplirb-.Lpg0(%r13)
                tm      .Liplirb+9-.Lpg0(%r13),0xbf
-                jz      .L002
-                bas     %r14,.Ldisab-.Lpg0(%r13)    
-.L002:         tm      .Liplirb+8-.Lpg0(%r13),0xf3    
-                jz      .L003
-                bas     %r14,.Ldisab-.Lpg0(%r13)       
+               jz      .L002
+               bas     %r14,.Ldisab-.Lpg0(%r13)
+.L002:         tm      .Liplirb+8-.Lpg0(%r13),0xf3
+               jz      .L003
+               bas     %r14,.Ldisab-.Lpg0(%r13)
 .L003:         spx     .Lnull-.Lpg0(%r13)
-               st      %r1,__LC_SUBCHANNEL_ID
-                lpsw   0
-               sigp    0,0,0(6)               
-.Ldisab:       st      %r14,.Ldispsw+4-.Lpg0(%r13)
+               st      %r1,__LC_SUBCHANNEL_ID
+               lpsw    0
+               sigp    0,0,0(6)
+.Ldisab:       st      %r14,.Ldispsw+4-.Lpg0(%r13)
                lpsw    .Ldispsw-.Lpg0(%r13)
-                .align         8
+               .align  8
 .Lclkcmp:      .quad   0x0000000000000000
 .Lall:         .long   0xff000000
-.Lnull:                .long   0x00000000
+.Lnull:                .long   0x00000000
 .Lctlsave1:    .long   0x00000000
 .Lctlsave2:    .long   0x00000000
-                .align         8
-.Lnewpsw:      .long   0x00080000,0x80000000+.Lpg1
-.Lpcnew:       .long   0x00080000,0x80000000+.Lecs
-.Lionew:       .long   0x00080000,0x80000000+.Lcont
+               .align  8
+.Lnewpsw:      .long   0x00080000,0x80000000+.Lpg1
+.Lpcnew:       .long   0x00080000,0x80000000+.Lecs
+.Lionew:       .long   0x00080000,0x80000000+.Lcont
 .Lwaitpsw:     .long   0x020a0000,0x00000000+.Ltpi
-.Ldispsw:      .long   0x000a0000,0x00000000
-.Liplccws:     .long   0x02000000,0x60000018
-               .long   0x08000008,0x20000001
+.Ldispsw:      .long   0x000a0000,0x00000000
+.Liplccws:     .long   0x02000000,0x60000018
+               .long   0x08000008,0x20000001
 .Liplorb:      .long   0x0049504c,0x0040ff80
                .long   0x00000000+.Liplccws
-.Lschib:        .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
+.Lschib:       .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
 .Liplirb:      .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
@@ -92,6 +92,3 @@ do_reipl_asm: basr    %r13,0
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
-       
-
-       
index 95bd1e234f6320ded22f19dd1ea616145d2e2db1..de7435054f7ccd4c45754824d8808d7ee83cfb8e 100644 (file)
@@ -4,7 +4,7 @@
  *  S390 version
  *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
-                Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+                Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  */
 
 #include <asm/lowcore.h>
@@ -32,46 +32,46 @@ do_reipl_asm:       basr    %r13,0
                stctg   %c0,%c0,.Lregsave-.Lpg0(%r13)
                ni      .Lregsave+4-.Lpg0(%r13),0xef
                lctlg   %c0,%c0,.Lregsave-.Lpg0(%r13)
-                lgr     %r1,%r2
-               mvc     __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
-                stsch   .Lschib-.Lpg0(%r13)                                    
-               oi      .Lschib+5-.Lpg0(%r13),0x84 
-.Lecs:         xi      .Lschib+27-.Lpg0(%r13),0x01 
-               msch    .Lschib-.Lpg0(%r13) 
-               lghi    %r0,5
-.Lssch:                ssch    .Liplorb-.Lpg0(%r13)           
+               lgr     %r1,%r2
+               mvc     __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
+               stsch   .Lschib-.Lpg0(%r13)
+               oi      .Lschib+5-.Lpg0(%r13),0x84
+.Lecs:         xi      .Lschib+27-.Lpg0(%r13),0x01
+               msch    .Lschib-.Lpg0(%r13)
+               lghi    %r0,5
+.Lssch:                ssch    .Liplorb-.Lpg0(%r13)
                jz      .L001
-               brct    %r0,.Lssch   
+               brct    %r0,.Lssch
                bas     %r14,.Ldisab-.Lpg0(%r13)
-.L001:         mvc     __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) 
-.Ltpi:         lpswe   .Lwaitpsw-.Lpg0(%r13)          
+.L001:         mvc     __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13)
+.Ltpi:         lpswe   .Lwaitpsw-.Lpg0(%r13)
 .Lcont:                c       %r1,__LC_SUBCHANNEL_ID
                jnz     .Ltpi
                clc     __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13)
                jnz     .Ltpi
-               tsch    .Liplirb-.Lpg0(%r13)           
+               tsch    .Liplirb-.Lpg0(%r13)
                tm      .Liplirb+9-.Lpg0(%r13),0xbf
-                jz      .L002
-                bas     %r14,.Ldisab-.Lpg0(%r13)    
-.L002:         tm      .Liplirb+8-.Lpg0(%r13),0xf3    
-                jz      .L003
-                bas     %r14,.Ldisab-.Lpg0(%r13)       
+               jz      .L002
+               bas     %r14,.Ldisab-.Lpg0(%r13)
+.L002:         tm      .Liplirb+8-.Lpg0(%r13),0xf3
+               jz      .L003
+               bas     %r14,.Ldisab-.Lpg0(%r13)
 .L003:         spx     .Lnull-.Lpg0(%r13)
-               st      %r1,__LC_SUBCHANNEL_ID
-                lhi     %r1,0            # mode 0 = esa
-                slr     %r0,%r0          # set cpuid to zero
-                sigp    %r1,%r0,0x12     # switch to esa mode
-                lpsw   0
-.Ldisab:       sll    %r14,1
-               srl    %r14,1            # need to kill hi bit to avoid specification exceptions.
-               st     %r14,.Ldispsw+12-.Lpg0(%r13)
+               st      %r1,__LC_SUBCHANNEL_ID
+               lhi     %r1,0            # mode 0 = esa
+               slr     %r0,%r0          # set cpuid to zero
+               sigp    %r1,%r0,0x12     # switch to esa mode
+               lpsw    0
+.Ldisab:       sll     %r14,1
+               srl     %r14,1           # need to kill hi bit to avoid specification exceptions.
+               st      %r14,.Ldispsw+12-.Lpg0(%r13)
                lpswe   .Ldispsw-.Lpg0(%r13)
-                .align         8
+               .align  8
 .Lclkcmp:      .quad   0x0000000000000000
 .Lall:         .quad   0x00000000ff000000
 .Lregsave:     .quad   0x0000000000000000
-.Lnull:                .long   0x0000000000000000
-                .align         16
+.Lnull:                .long   0x0000000000000000
+               .align  16
 /*
  * These addresses have to be 31 bit otherwise
  * the sigp will throw a specifcation exception
@@ -81,26 +81,26 @@ do_reipl_asm:       basr    %r13,0
  * 31bit lpswe instruction a fact they appear to have
  * ommited from the pop.
  */
-.Lnewpsw:      .quad   0x0000000080000000
-               .quad   .Lpg1
-.Lpcnew:       .quad   0x0000000080000000
-               .quad   .Lecs
-.Lionew:       .quad   0x0000000080000000
-               .quad   .Lcont
+.Lnewpsw:      .quad   0x0000000080000000
+               .quad   .Lpg1
+.Lpcnew:       .quad   0x0000000080000000
+               .quad   .Lecs
+.Lionew:       .quad   0x0000000080000000
+               .quad   .Lcont
 .Lwaitpsw:     .quad   0x0202000080000000
-               .quad   .Ltpi
-.Ldispsw:      .quad   0x0002000080000000
-               .quad   0x0000000000000000
-.Liplccws:     .long   0x02000000,0x60000018
-               .long   0x08000008,0x20000001
+               .quad   .Ltpi
+.Ldispsw:      .quad   0x0002000080000000
+               .quad   0x0000000000000000
+.Liplccws:     .long   0x02000000,0x60000018
+               .long   0x08000008,0x20000001
 .Liplorb:      .long   0x0049504c,0x0040ff80
                .long   0x00000000+.Liplccws
-.Lschib:        .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
-               .long   0x00000000,0x00000000
+.Lschib:       .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
+               .long   0x00000000,0x00000000
 .Liplirb:      .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
@@ -109,4 +109,3 @@ do_reipl_asm:       basr    %r13,0
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
                .long   0x00000000,0x00000000
-       
index 2a25ec7147ffef7be275feeb9a915dfaec6f70b3..f9899ff2e5b0a928a297e2998a5f6b8bb40f7363 100644 (file)
@@ -3,7 +3,7 @@
  *
  * (C) Copyright IBM Corp. 2005
  *
- * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ * Author(s): Rolf Adelsberger,
  *           Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  */
        .text
        .globl          relocate_kernel
        relocate_kernel:
-               basr    %r13,0          #base address
+               basr    %r13,0          # base address
        .base:
-               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQ (external)
-               spx     zero64-.base(%r13)      #absolute addressing mode
+               stnsm   sys_msk-.base(%r13),0xf8        # disable DAT and IRQ (external)
+               spx     zero64-.base(%r13)      # absolute addressing mode
                stctl   %c0,%c15,ctlregs-.base(%r13)
                stm     %r0,%r15,gprregs-.base(%r13)
                la      %r1,load_psw-.base(%r13)
-               mvc     0(8,%r0),0(%r1)
+               mvc     0(8,%r0),0(%r1)
                la      %r0,.back-.base(%r13)
                st      %r0,4(%r0)
                oi      4(%r0),0x80
        .back_pgm:
                lm      %r0,%r15,gprregs-.base(%r13)
        .start_reloc:
-               lhi     %r10,-1         #preparing the mask
-               sll     %r10,12         #shift it such that it becomes 0xf000
+               lhi     %r10,-1         # preparing the mask
+               sll     %r10,12         # shift it such that it becomes 0xf000
        .top:
-               lhi     %r7,4096        #load PAGE_SIZE in r7
-               lhi     %r9,4096        #load PAGE_SIZE in r9
-               l       %r5,0(%r2)      #read another word for indirection page
-               ahi     %r2,4           #increment pointer
-               tml     %r5,0x1         #is it a destination page?
-               je      .indir_check    #NO, goto "indir_check"
-               lr      %r6,%r5         #r6 = r5
-               nr      %r6,%r10        #mask it out and...
-               j       .top            #...next iteration
+               lhi     %r7,4096        # load PAGE_SIZE in r7
+               lhi     %r9,4096        # load PAGE_SIZE in r9
+               l       %r5,0(%r2)      # read another word for indirection page
+               ahi     %r2,4           # increment pointer
+               tml     %r5,0x1         # is it a destination page?
+               je      .indir_check    # NO, goto "indir_check"
+               lr      %r6,%r5         # r6 = r5
+               nr      %r6,%r10        # mask it out and...
+               j       .top            # ...next iteration
        .indir_check:
-               tml     %r5,0x2         #is it a indirection page?
-               je      .done_test      #NO, goto "done_test"
-               nr      %r5,%r10        #YES, mask out,
-               lr      %r2,%r5         #move it into the right register,
-               j       .top            #and read next...
+               tml     %r5,0x2         # is it a indirection page?
+               je      .done_test      # NO, goto "done_test"
+               nr      %r5,%r10        # YES, mask out,
+               lr      %r2,%r5         # move it into the right register,
+               j       .top            # and read next...
        .done_test:
-               tml     %r5,0x4         #is it the done indicator?
-               je      .source_test    #NO! Well, then it should be the source indicator...
-               j       .done           #ok, lets finish it here...
+               tml     %r5,0x4         # is it the done indicator?
+               je      .source_test    # NO! Well, then it should be the source indicator...
+               j       .done           # ok, lets finish it here...
        .source_test:
-               tml     %r5,0x8         #it should be a source indicator...
-               je      .top            #NO, ignore it...
-               lr      %r8,%r5         #r8 = r5
-               nr      %r8,%r10        #masking
-       0:      mvcle   %r6,%r8,0x0     #copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+               tml     %r5,0x8         # it should be a source indicator...
+               je      .top            # NO, ignore it...
+               lr      %r8,%r5         # r8 = r5
+               nr      %r8,%r10        # masking
+       0:      mvcle   %r6,%r8,0x0     # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
                jo      0b
                j       .top
        .done:
-               sr      %r0,%r0         #clear register r0
-               la      %r4,load_psw-.base(%r13)        #load psw-address into the register
-               o       %r3,4(%r4)      #or load address into psw
+               sr      %r0,%r0         # clear register r0
+               la      %r4,load_psw-.base(%r13)        # load psw-address into the register
+               o       %r3,4(%r4)      # or load address into psw
                st      %r3,4(%r4)
-               mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               mvc     0(8,%r0),0(%r4) # copy psw to absolute address 0
                tm      have_diag308-.base(%r13),0x01
                jno     .no_diag308
                diag    %r0,%r0,0x308
        .no_diag308:
-               sr      %r1,%r1         #clear %r1
-               sr      %r2,%r2         #clear %r2
-               sigp    %r1,%r2,0x12    #set cpuid to zero
-               lpsw    0               #hopefully start new kernel...
+               sr      %r1,%r1         # clear %r1
+               sr      %r2,%r2         # clear %r2
+               sigp    %r1,%r2,0x12    # set cpuid to zero
+               lpsw    0               # hopefully start new kernel...
 
                .align  8
        zero64:
index 8cdb86e8911ff98ec92c39ae3db8be106c76f836..4fb443042d9cc39bd64cf8502aed48636cd608bd 100644 (file)
@@ -3,7 +3,7 @@
  *
  * (C) Copyright IBM Corp. 2005
  *
- * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ * Author(s): Rolf Adelsberger,
  *           Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  */
        .text
        .globl          relocate_kernel
        relocate_kernel:
-               basr    %r13,0          #base address
+               basr    %r13,0          # base address
        .base:
-               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQs
-               spx     zero64-.base(%r13)      #absolute addressing mode
+               stnsm   sys_msk-.base(%r13),0xf8        # disable DAT and IRQs
+               spx     zero64-.base(%r13)      # absolute addressing mode
                stctg   %c0,%c15,ctlregs-.base(%r13)
                stmg    %r0,%r15,gprregs-.base(%r13)
                lghi    %r0,3
                la      %r0,.back_pgm-.base(%r13)
                stg     %r0,0x1d8(%r0)
                la      %r1,load_psw-.base(%r13)
-               mvc     0(8,%r0),0(%r1)
+               mvc     0(8,%r0),0(%r1)
                la      %r0,.back-.base(%r13)
                st      %r0,4(%r0)
                oi      4(%r0),0x80
                lghi    %r0,0
                diag    %r0,%r0,0x308
        .back:
-               lhi     %r1,1           #mode 1 = esame
-               sigp    %r1,%r0,0x12    #switch to esame mode
-               sam64                   #switch to 64 bit addressing mode
+               lhi     %r1,1           # mode 1 = esame
+               sigp    %r1,%r0,0x12    # switch to esame mode
+               sam64                   # switch to 64 bit addressing mode
                basr    %r13,0
        .back_base:
                oi      have_diag308-.back_base(%r13),0x01
        .back_pgm:
                lmg     %r0,%r15,gprregs-.base(%r13)
        .top:
-               lghi    %r7,4096        #load PAGE_SIZE in r7
-               lghi    %r9,4096        #load PAGE_SIZE in r9
-               lg      %r5,0(%r2)      #read another word for indirection page
-               aghi    %r2,8           #increment pointer
-               tml     %r5,0x1         #is it a destination page?
-               je      .indir_check    #NO, goto "indir_check"
-               lgr     %r6,%r5         #r6 = r5
-               nill    %r6,0xf000      #mask it out and...
-               j       .top            #...next iteration
+               lghi    %r7,4096        # load PAGE_SIZE in r7
+               lghi    %r9,4096        # load PAGE_SIZE in r9
+               lg      %r5,0(%r2)      # read another word for indirection page
+               aghi    %r2,8           # increment pointer
+               tml     %r5,0x1         # is it a destination page?
+               je      .indir_check    # NO, goto "indir_check"
+               lgr     %r6,%r5         # r6 = r5
+               nill    %r6,0xf000      # mask it out and...
+               j       .top            # ...next iteration
        .indir_check:
-               tml     %r5,0x2         #is it a indirection page?
-               je      .done_test      #NO, goto "done_test"
-               nill    %r5,0xf000      #YES, mask out,
-               lgr     %r2,%r5         #move it into the right register,
-               j       .top            #and read next...
+               tml     %r5,0x2         # is it a indirection page?
+               je      .done_test      # NO, goto "done_test"
+               nill    %r5,0xf000      # YES, mask out,
+               lgr     %r2,%r5         # move it into the right register,
+               j       .top            # and read next...
        .done_test:
-               tml     %r5,0x4         #is it the done indicator?
-               je      .source_test    #NO! Well, then it should be the source indicator...
-               j       .done           #ok, lets finish it here...
+               tml     %r5,0x4         # is it the done indicator?
+               je      .source_test    # NO! Well, then it should be the source indicator...
+               j       .done           # ok, lets finish it here...
        .source_test:
-               tml     %r5,0x8         #it should be a source indicator...
-               je      .top            #NO, ignore it...
-               lgr     %r8,%r5         #r8 = r5
-               nill    %r8,0xf000      #masking
-       0:      mvcle   %r6,%r8,0x0     #copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+               tml     %r5,0x8         # it should be a source indicator...
+               je      .top            # NO, ignore it...
+               lgr     %r8,%r5         # r8 = r5
+               nill    %r8,0xf000      # masking
+       0:      mvcle   %r6,%r8,0x0     # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
                jo      0b
-               j       .top
+               j       .top
        .done:
-               sgr     %r0,%r0         #clear register r0
-               la      %r4,load_psw-.base(%r13)        #load psw-address into the register
-               o       %r3,4(%r4)      #or load address into psw
+               sgr     %r0,%r0         # clear register r0
+               la      %r4,load_psw-.base(%r13)        # load psw-address into the register
+               o       %r3,4(%r4)      # or load address into psw
                st      %r3,4(%r4)
-               mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               mvc     0(8,%r0),0(%r4) # copy psw to absolute address 0
                tm      have_diag308-.base(%r13),0x01
                jno     .no_diag308
                diag    %r0,%r0,0x308
        .no_diag308:
-               sam31                   #31 bit mode
-               sr      %r1,%r1         #erase register r1
-               sr      %r2,%r2         #erase register r2
-               sigp    %r1,%r2,0x12    #set cpuid to zero
-               lpsw    0               #hopefully start new kernel...
+               sam31                   # 31 bit mode
+               sr      %r1,%r1         # erase register r1
+               sr      %r2,%r2         # erase register r2
+               sigp    %r1,%r2,0x12    # set cpuid to zero
+               lpsw    0               # hopefully start new kernel...
 
-               .align  8
+               .align  8
        zero64:
                .quad   0
        load_psw:
index 8dfb690c159f339e0db0fe83d416f6fc82df8ebb..191303f6c1d8b87fab68349af8c220c0b9dc0e4b 100644 (file)
@@ -26,17 +26,17 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
 {
        int old_val, new_val;
 
-        __asm__ __volatile__("   l     %0,0(%3)\n"
-                             "0: ltr   %1,%0\n"
-                            "   jhe   1f\n"
-                            "   lhi   %1,0\n"
-                            "1: ar    %1,%4\n"
-                             "   cs    %0,%1,0(%3)\n"
-                             "   jl    0b\n"
-                             : "=&d" (old_val), "=&d" (new_val),
-                              "=m" (sem->count)
-                            : "a" (&sem->count), "d" (incr), "m" (sem->count)
-                            : "cc" );
+       asm volatile(
+               "       l       %0,0(%3)\n"
+               "0:     ltr     %1,%0\n"
+               "       jhe     1f\n"
+               "       lhi     %1,0\n"
+               "1:     ar      %1,%4\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b\n"
+               : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count)
+               : "a" (&sem->count), "d" (incr), "m" (sem->count)
+               : "cc");
        return old_val;
 }
 
index e3d9325f6022b04e3bf307bdc3549362231c75ea..a21cfbb9d97edd97b30111bb492392fe5deb8bae 100644 (file)
@@ -101,7 +101,7 @@ void __devinit cpu_init (void)
         /*
          * Store processor id in lowcore (used e.g. in timer_interrupt)
          */
-        asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
+       asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
         S390_lowcore.cpu_data.cpu_addr = addr;
 
         /*
index b2e6f4c8d382a463976a6ed74341f87f331ef81f..a8e6199755d4ecc86197aa0f95cfad26314df31b 100644 (file)
@@ -63,7 +63,7 @@ static void smp_ext_bitcall(int, ec_bit_sig);
 static void smp_ext_bitcall_others(ec_bit_sig);
 
 /*
- * Structure and data for smp_call_function(). This is designed to minimise
+5B * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
 static DEFINE_SPINLOCK(call_lock);
@@ -418,59 +418,49 @@ void smp_send_reschedule(int cpu)
 /*
  * parameter area for the set/clear control bit callbacks
  */
-typedef struct
-{
-       __u16 start_ctl;
-       __u16 end_ctl;
+struct ec_creg_mask_parms {
        unsigned long orvals[16];
        unsigned long andvals[16];
-} ec_creg_mask_parms;
+};
 
 /*
  * callback for setting/clearing control bits
  */
 void smp_ctl_bit_callback(void *info) {
-       ec_creg_mask_parms *pp;
+       struct ec_creg_mask_parms *pp = info;
        unsigned long cregs[16];
        int i;
        
-       pp = (ec_creg_mask_parms *) info;
-       __ctl_store(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl);
-       for (i = pp->start_ctl; i <= pp->end_ctl; i++)
+       __ctl_store(cregs, 0, 15);
+       for (i = 0; i <= 15; i++)
                cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i];
-       __ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl);
+       __ctl_load(cregs, 0, 15);
 }
 
 /*
  * Set a bit in a control register of all cpus
  */
-void smp_ctl_set_bit(int cr, int bit) {
-        ec_creg_mask_parms parms;
+void smp_ctl_set_bit(int cr, int bit)
+{
+       struct ec_creg_mask_parms parms;
 
-       parms.start_ctl = cr;
-       parms.end_ctl = cr;
+       memset(&parms.orvals, 0, sizeof(parms.orvals));
+       memset(&parms.andvals, 0xff, sizeof(parms.andvals));
        parms.orvals[cr] = 1 << bit;
-       parms.andvals[cr] = -1L;
-       preempt_disable();
-       smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
-        __ctl_set_bit(cr, bit);
-       preempt_enable();
+       on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
 }
 
 /*
  * Clear a bit in a control register of all cpus
  */
-void smp_ctl_clear_bit(int cr, int bit) {
-        ec_creg_mask_parms parms;
+void smp_ctl_clear_bit(int cr, int bit)
+{
+       struct ec_creg_mask_parms parms;
 
-       parms.start_ctl = cr;
-       parms.end_ctl = cr;
-       parms.orvals[cr] = 0;
+       memset(&parms.orvals, 0, sizeof(parms.orvals));
+       memset(&parms.andvals, 0xff, sizeof(parms.andvals));
        parms.andvals[cr] = ~(1L << bit);
-       preempt_disable();
-       smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
-        __ctl_clear_bit(cr, bit);
-       preempt_enable();
+       on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
 }
 
 /*
@@ -650,9 +640,9 @@ __cpu_up(unsigned int cpu)
        sf->gprs[9] = (unsigned long) sf;
        cpu_lowcore->save_area[15] = (unsigned long) sf;
        __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15);
-       __asm__ __volatile__("stam  0,15,0(%0)"
-                            : : "a" (&cpu_lowcore->access_regs_save_area)
-                            : "memory");
+       asm volatile(
+               "       stam    0,15,0(%0)"
+               : : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
        cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
         cpu_lowcore->current_task = (unsigned long) idle;
         cpu_lowcore->cpu_data.cpu_nr = cpu;
@@ -708,7 +698,7 @@ int
 __cpu_disable(void)
 {
        unsigned long flags;
-       ec_creg_mask_parms cr_parms;
+       struct ec_creg_mask_parms cr_parms;
        int cpu = smp_processor_id();
 
        spin_lock_irqsave(&smp_reserve_lock, flags);
@@ -724,30 +714,21 @@ __cpu_disable(void)
                pfault_fini();
 #endif
 
-       /* disable all external interrupts */
+       memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals));
+       memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals));
 
-       cr_parms.start_ctl = 0;
-       cr_parms.end_ctl = 0;
+       /* disable all external interrupts */
        cr_parms.orvals[0] = 0;
        cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 |
                                1<<11 | 1<<10 | 1<< 6 | 1<< 4);
-       smp_ctl_bit_callback(&cr_parms);
-
        /* disable all I/O interrupts */
-
-       cr_parms.start_ctl = 6;
-       cr_parms.end_ctl = 6;
        cr_parms.orvals[6] = 0;
        cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 |
                                1<<27 | 1<<26 | 1<<25 | 1<<24);
-       smp_ctl_bit_callback(&cr_parms);
-
        /* disable most machine checks */
-
-       cr_parms.start_ctl = 14;
-       cr_parms.end_ctl = 14;
        cr_parms.orvals[14] = 0;
        cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24);
+
        smp_ctl_bit_callback(&cr_parms);
 
        spin_unlock_irqrestore(&smp_reserve_lock, flags);
index 74e6178fbaf25c11ee55e9b320c38a5437cd571a..abab42e9f5f8718cfcda91702803e8d797f70544 100644 (file)
@@ -166,7 +166,7 @@ EXPORT_SYMBOL(do_settimeofday);
 void account_ticks(struct pt_regs *regs)
 {
        __u64 tmp;
-       __u32 ticks, xticks;
+       __u32 ticks;
 
        /* Calculate how many ticks have passed. */
        if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) {
@@ -204,6 +204,7 @@ void account_ticks(struct pt_regs *regs)
         */
        write_seqlock(&xtime_lock);
        if (S390_lowcore.jiffy_timer > xtime_cc) {
+               __u32 xticks;
                tmp = S390_lowcore.jiffy_timer - xtime_cc;
                if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
                        xticks = __div(tmp, CLK_TICKS_PER_JIFFY);
@@ -212,13 +213,11 @@ void account_ticks(struct pt_regs *regs)
                        xticks = 1;
                        xtime_cc += CLK_TICKS_PER_JIFFY;
                }
-               while (xticks--)
-                       do_timer(regs);
+               do_timer(xticks);
        }
        write_sequnlock(&xtime_lock);
 #else
-       for (xticks = ticks; xticks > 0; xticks--)
-               do_timer(regs);
+       do_timer(ticks);
 #endif
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -351,10 +350,12 @@ void __init time_init(void)
        int cc;
 
         /* kick the TOD clock */
-        asm volatile ("STCK 0(%1)\n\t"
-                      "IPM  %0\n\t"
-                      "SRL  %0,28" : "=r" (cc) : "a" (&init_timer_cc) 
-                                  : "memory", "cc");
+       asm volatile(
+               "       stck    0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (cc), "=m" (init_timer_cc)
+               : "a" (&init_timer_cc) : "cc");
         switch (cc) {
         case 0: /* clock in set state: all is fine */
                 break;
index c4982c963424921aebaaad4fa15560b05ca22bd5..3eb4fab048b8c18f16c6327fb5bc4c096eb11579 100644 (file)
@@ -597,8 +597,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
                local_irq_enable();
 
        if (MACHINE_HAS_IEEE)
-               __asm__ volatile ("stfpc %0\n\t" 
-                                 : "=m" (current->thread.fp_regs.fpc));
+               asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
 
 #ifdef CONFIG_MATHEMU
         else if (regs->psw.mask & PSW_MASK_PSTATE) {
index c42ffedfdb4940988178ee325802634d06bcf4e2..b0cfa6c4883d57e7a848970beca6657c3907b0b5 100644 (file)
@@ -5,5 +5,6 @@
 EXTRA_AFLAGS := -traditional
 
 lib-y += delay.o string.o uaccess_std.o
+lib-$(CONFIG_32BIT) += div64.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
 lib-$(CONFIG_SMP) += spinlock.o
index 468f4ea33f99efdf1f83802ed4433146ac485b57..027c4742a0017a2cdef12b51a4dd282709dc59b9 100644 (file)
@@ -27,9 +27,7 @@ void __delay(unsigned long loops)
          * yield the megahertz number of the cpu. The important function
          * is udelay and that is done using the tod clock. -- martin.
          */
-        __asm__ __volatile__(
-                "0: brct %0,0b"
-                : /* no outputs */ : "r" ((loops/2) + 1));
+       asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1));
 }
 
 /*
@@ -38,13 +36,12 @@ void __delay(unsigned long loops)
  */
 void __udelay(unsigned long usecs)
 {
-        uint64_t start_cc, end_cc;
+       uint64_t start_cc;
 
         if (usecs == 0)
                 return;
-        asm volatile ("STCK %0" : "=m" (start_cc));
+       start_cc = get_clock();
         do {
                cpu_relax();
-                asm volatile ("STCK %0" : "=m" (end_cc));
-        } while (((end_cc - start_cc)/4096) < usecs);
+       } while (((get_clock() - start_cc)/4096) < usecs);
 }
diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c
new file mode 100644 (file)
index 0000000..0481f34
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *  arch/s390/lib/div64.c
+ *
+ *  __div64_32 implementation for 31 bit.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_MARCH_G5
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 31 bit integer using signed 64/32 bit division.
+ */
+static uint32_t __div64_31(uint64_t *n, uint32_t base)
+{
+       register uint32_t reg2 asm("2");
+       register uint32_t reg3 asm("3");
+       uint32_t *words = (uint32_t *) n;
+       uint32_t tmp;
+
+       /* Special case base==1, remainder = 0, quotient = n */
+       if (base == 1)
+               return 0;
+       /*
+        * Special case base==0 will cause a fixed point divide exception
+        * on the dr instruction and may not happen anyway. For the
+        * following calculation we can assume base > 1. The first
+        * signed 64 / 32 bit division with an upper half of 0 will
+        * give the correct upper half of the 64 bit quotient.
+        */
+       reg2 = 0UL;
+       reg3 = words[0];
+       asm volatile(
+               "       dr      %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[0] = reg3;
+       reg3 = words[1];
+       /*
+        * To get the lower half of the 64 bit quotient and the 32 bit
+        * remainder we have to use a little trick. Since we only have
+        * a signed division the quotient can get too big. To avoid this
+        * the 64 bit dividend is halved, then the signed division will
+        * work. Afterwards the quotient and the remainder are doubled.
+        * If the last bit of the dividend has been one the remainder
+        * is increased by one then checked against the base. If the
+        * remainder has overflown subtract base and increase the
+        * quotient. Simple, no ?
+        */
+       asm volatile(
+               "       nr      %2,%1\n"
+               "       srdl    %0,1\n"
+               "       dr      %0,%3\n"
+               "       alr     %0,%0\n"
+               "       alr     %1,%1\n"
+               "       alr     %0,%2\n"
+               "       clr     %0,%3\n"
+               "       jl      0f\n"
+               "       slr     %0,%3\n"
+               "       alr     %1,%2\n"
+               "0:\n"
+               : "+d" (reg2), "+d" (reg3), "=d" (tmp)
+               : "d" (base), "2" (1UL) : "cc" );
+       words[1] = reg3;
+       return reg2;
+}
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 32 bit integer using the unsigned 64/31 bit division.
+ */
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       uint32_t r;
+
+       /*
+        * If the most significant bit of base is set, divide n by
+        * (base/2). That allows to use 64/31 bit division and gives a
+        * good approximation of the result: n = (base/2)*q + r. The
+        * result needs to be corrected with two simple transformations.
+        * If base is already < 2^31-1 __div64_31 can be used directly.
+        */
+       r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
+       if ((signed) base < 0) {
+               uint64_t q = *n;
+               /*
+                * First transformation:
+                * n = (base/2)*q + r
+                *   = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
+                * Since r < (base/2), r + (base/2) < base.
+                * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
+                * n = ((base/2)*2)*q1 + r1 with r1 < base.
+                */
+               if (q & 1)
+                       r += base/2;
+               q >>= 1;
+               /*
+                * Second transformation. ((base/2)*2) could have lost the
+                * last bit.
+                * n = ((base/2)*2)*q1 + r1
+                *   = base*q1 - ((base&1) ? q1 : 0) + r1
+                */
+               if (base & 1) {
+                       int64_t rx = r - q;
+                       /*
+                        * base is >= 2^31. The worst case for the while
+                        * loop is n=2^64-1 base=2^31+1. That gives a
+                        * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
+                        * base >= 2^31 the loop is finished after a maximum
+                        * of three iterations.
+                        */
+                       while (rx < 0) {
+                               rx += base;
+                               q--;
+                       }
+                       r = rx;
+               }
+               *n = q;
+       }
+       return r;
+}
+
+#else /* MARCH_G5 */
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       register uint32_t reg2 asm("2");
+       register uint32_t reg3 asm("3");
+       uint32_t *words = (uint32_t *) n;
+
+       reg2 = 0UL;
+       reg3 = words[0];
+       asm volatile(
+               "       dlr     %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[0] = reg3;
+       reg3 = words[1];
+       asm volatile(
+               "       dlr     %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[1] = reg3;
+       return reg2;
+}
+
+#endif /* MARCH_G5 */
+
+EXPORT_SYMBOL(__div64_32);
index 86c96d6c191a3819bb094cb7d0698b3401a0c147..121b2935a422a2e724ce97cd9dd49aaa61cc26a7 100644 (file)
@@ -35,7 +35,7 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
        tmp1 = -4096UL;
        asm volatile(
                "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
-               "   jz    4f\n"
+               "   jz    7f\n"
                "1:"ALR"  %0,%3\n"
                "  "SLR"  %1,%3\n"
                "  "SLR"  %2,%3\n"
@@ -44,13 +44,23 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
                "   nr    %4,%3\n"      /* %4 = (ptr + 4095) & -4096 */
                "  "SLR"  %4,%1\n"
                "  "CLR"  %0,%4\n"      /* copy crosses next page boundary? */
-               "   jnh   5f\n"
+               "   jnh   4f\n"
                "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n"
                "  "SLR"  %0,%4\n"
-               "   j     5f\n"
-               "4:"SLR"  %0,%0\n"
-               "5: \n"
-               EX_TABLE(0b,2b) EX_TABLE(3b,5b)
+               "  "ALR"  %2,%4\n"
+               "4:"LHI"  %4,-1\n"
+               "  "ALR"  %4,%0\n"      /* copy remaining size, subtract 1 */
+               "   bras  %3,6f\n"      /* memset loop */
+               "   xc    0(1,%2),0(%2)\n"
+               "5: xc    0(256,%2),0(%2)\n"
+               "   la    %2,256(%2)\n"
+               "6:"AHI"  %4,-256\n"
+               "   jnm   5b\n"
+               "   ex    %4,0(%3)\n"
+               "   j     8f\n"
+               "7:"SLR"  %0,%0\n"
+               "8: \n"
+               EX_TABLE(0b,2b) EX_TABLE(3b,4b)
                : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
                : "d" (reg0) : "cc", "memory");
        return size;
index 9a4d4a29ea79d6c8a6760c0b8122ed1b586d4f3e..f44f0078b354538d86908b949e4d6f4a4cee8d7e 100644 (file)
@@ -35,25 +35,35 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
        tmp1 = -256UL;
        asm volatile(
                "0: mvcp  0(%0,%2),0(%1),%3\n"
-               "   jz    5f\n"
+               "   jz    8f\n"
                "1:"ALR"  %0,%3\n"
                "   la    %1,256(%1)\n"
                "   la    %2,256(%2)\n"
                "2: mvcp  0(%0,%2),0(%1),%3\n"
                "   jnz   1b\n"
-               "   j     5f\n"
+               "   j     8f\n"
                "3: la    %4,255(%1)\n" /* %4 = ptr + 255 */
                "  "LHI"  %3,-4096\n"
                "   nr    %4,%3\n"      /* %4 = (ptr + 255) & -4096 */
                "  "SLR"  %4,%1\n"
                "  "CLR"  %0,%4\n"      /* copy crosses next page boundary? */
-               "   jnh   6f\n"
+               "   jnh   5f\n"
                "4: mvcp  0(%4,%2),0(%1),%3\n"
                "  "SLR"  %0,%4\n"
-               "   j     6f\n"
-               "5:"SLR"  %0,%0\n"
-               "6: \n"
-               EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
+               "  "ALR"  %2,%4\n"
+               "5:"LHI"  %4,-1\n"
+               "  "ALR"  %4,%0\n"      /* copy remaining size, subtract 1 */
+               "   bras  %3,7f\n"      /* memset loop */
+               "   xc    0(1,%2),0(%2)\n"
+               "6: xc    0(256,%2),0(%2)\n"
+               "   la    %2,256(%2)\n"
+               "7:"AHI"  %4,-256\n"
+               "   jnm   6b\n"
+               "   ex    %4,0(%3)\n"
+               "   j     9f\n"
+               "8:"SLR"  %0,%0\n"
+               "9: \n"
+               EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b)
                : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
                : : "cc", "memory");
        return size;
@@ -67,16 +77,22 @@ size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x)
        asm volatile(
                "0: mvcp  0(%0,%2),0(%1),%3\n"
                "  "SLR"  %0,%0\n"
-               "   j     3f\n"
+               "   j     5f\n"
                "1: la    %4,255(%1)\n" /* %4 = ptr + 255 */
                "  "LHI"  %3,-4096\n"
                "   nr    %4,%3\n"      /* %4 = (ptr + 255) & -4096 */
                "  "SLR"  %4,%1\n"
                "  "CLR"  %0,%4\n"      /* copy crosses next page boundary? */
-               "   jnh   3f\n"
+               "   jnh   5f\n"
                "2: mvcp  0(%4,%2),0(%1),%3\n"
                "  "SLR"  %0,%4\n"
-               "3:\n"
+               "  "ALR"  %2,%4\n"
+               "3:"LHI"  %4,-1\n"
+               "  "ALR"  %4,%0\n"      /* copy remaining size, subtract 1 */
+               "   bras  %3,4f\n"
+               "   xc    0(1,%2),0(%2)\n"
+               "4: ex    %4,0(%3)\n"
+               "5:\n"
                EX_TABLE(0b,1b) EX_TABLE(2b,3b)
                : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
                : : "cc", "memory");
index b4957c84e4d66395a7633752079742ae5db77316..6b9aec5a2c18dae0283d61904b37b6018691e36c 100644 (file)
@@ -1564,52 +1564,52 @@ static int emu_tceb (struct pt_regs *regs, int rx, long val) {
 }
 
 static inline void emu_load_regd(int reg) {
-        if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
+       if ((reg&9) != 0)       /* test if reg in {0,2,4,6} */
                 return;
-        asm volatile (            /* load reg from fp_regs.fprs[reg] */
-                "     bras  1,0f\n"
-                "     ld    0,0(%1)\n"
-                "0:   ex    %0,0(1)"
-                : /* no output */
-                : "a" (reg<<4),"a" (&current->thread.fp_regs.fprs[reg].d)
-                : "1" );
+       asm volatile(           /* load reg from fp_regs.fprs[reg] */
+               "       bras    1,0f\n"
+               "       ld      0,0(%1)\n"
+               "0:     ex      %0,0(1)"
+               : /* no output */
+               : "a" (reg<<4),"a" (&current->thread.fp_regs.fprs[reg].d)
+               : "1");
 }
 
 static inline void emu_load_rege(int reg) {
-        if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
+       if ((reg&9) != 0)       /* test if reg in {0,2,4,6} */
                 return;
-        asm volatile (            /* load reg from fp_regs.fprs[reg] */
-                "     bras  1,0f\n"
-                "     le    0,0(%1)\n"
-                "0:   ex    %0,0(1)"
-                : /* no output */
-                : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                : "1" );
+       asm volatile(           /* load reg from fp_regs.fprs[reg] */
+               "       bras    1,0f\n"
+               "       le      0,0(%1)\n"
+               "0:     ex      %0,0(1)"
+               : /* no output */
+               : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
+               : "1");
 }
 
 static inline void emu_store_regd(int reg) {
-        if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
+       if ((reg&9) != 0)       /* test if reg in {0,2,4,6} */
                 return;
-        asm volatile (            /* store reg to fp_regs.fprs[reg] */
-                "     bras  1,0f\n"
-                "     std   0,0(%1)\n"
-                "0:   ex    %0,0(1)"
-                : /* no output */
-                : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
-                : "1" );
+       asm volatile(           /* store reg to fp_regs.fprs[reg] */
+               "       bras    1,0f\n"
+               "       std     0,0(%1)\n"
+               "0:     ex      %0,0(1)"
+               : /* no output */
+               : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
+               : "1");
 }
 
 
 static inline void emu_store_rege(int reg) {
-        if ((reg&9) != 0)         /* test if reg in {0,2,4,6} */
+       if ((reg&9) != 0)       /* test if reg in {0,2,4,6} */
                 return;
-        asm volatile (            /* store reg to fp_regs.fprs[reg] */
-                "     bras  1,0f\n"
-                "     ste   0,0(%1)\n"
-                "0:   ex    %0,0(1)"
-                : /* no output */
-                : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                : "1" );
+       asm volatile(           /* store reg to fp_regs.fprs[reg] */
+               "       bras    1,0f\n"
+               "       ste     0,0(%1)\n"
+               "0:     ex      %0,0(1)"
+               : /* no output */
+               : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
+               : "1");
 }
 
 int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
@@ -2089,23 +2089,22 @@ int math_emu_ldr(__u8 *opcode) {
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
                 /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     ld    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc & 0xf0),
-                          "a" (&fp_regs->fprs[opc & 0xf].d)
-                        : "1" );
+               asm volatile(           /* load rx from fp_regs.fprs[ry] */
+                       "       bras    1,0f\n"
+                       "       ld      0,0(%1)\n"
+                       "0:     ex      %0,0(1)"
+                       : /* no output */
+                       : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].d)
+                       : "1");
         } else if ((opc & 0x9) == 0) {     /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     std   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc & 0xf) << 4),
-                          "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
-                        : "1" );
+               asm volatile (          /* store ry to fp_regs.fprs[rx] */
+                       "       bras    1,0f\n"
+                       "       std     0,0(%1)\n"
+                       "0:     ex      %0,0(1)"
+                       : /* no output */
+                       : "a" ((opc & 0xf) << 4),
+                         "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d)
+                       : "1");
         } else  /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
                 fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
        return 0;
@@ -2120,23 +2119,22 @@ int math_emu_ler(__u8 *opcode) {
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
                 /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     le    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc & 0xf0),
-                          "a" (&fp_regs->fprs[opc & 0xf].f)
-                        : "1" );
+               asm volatile(           /* load rx from fp_regs.fprs[ry] */
+                       "       bras    1,0f\n"
+                       "       le      0,0(%1)\n"
+                       "0:     ex      %0,0(1)"
+                       : /* no output */
+                       : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].f)
+                       : "1");
         } else if ((opc & 0x9) == 0) {     /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     ste   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc & 0xf) << 4),
-                          "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
-                        : "1" );
+               asm volatile(           /* store ry to fp_regs.fprs[rx] */
+                       "       bras    1,0f\n"
+                       "       ste     0,0(%1)\n"
+                       "0:     ex      %0,0(1)"
+                       : /* no output */
+                       : "a" ((opc & 0xf) << 4),
+                         "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f)
+                       : "1");
         } else  /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
                 fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf];
        return 0;
index ab556b600f738651d1e5b4ea8e8390b25757bf88..5b6ca4570ea41e6b44aba008cf0ce520f7a86580 100644 (file)
@@ -4,48 +4,51 @@
 #include <asm/byteorder.h>
 
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) ({          \
-        unsigned int __sh = (ah);                      \
-        unsigned int __sl = (al);                      \
-        __asm__ ("   alr  %1,%3\n"                     \
-                 "   brc  12,0f\n"                     \
-                 "   ahi  %0,1\n"                      \
-                 "0: alr  %0,%2"                       \
-                 : "+&d" (__sh), "+d" (__sl)           \
-                 : "d" (bh), "d" (bl) : "cc" );                \
-        (sh) = __sh;                                   \
-        (sl) = __sl;                                   \
+       unsigned int __sh = (ah);                       \
+       unsigned int __sl = (al);                       \
+       asm volatile(                                   \
+               "       alr     %1,%3\n"                \
+               "       brc     12,0f\n"                \
+               "       ahi     %0,1\n"                 \
+               "0:     alr  %0,%2"                     \
+               : "+&d" (__sh), "+d" (__sl)             \
+               : "d" (bh), "d" (bl) : "cc");           \
+       (sh) = __sh;                                    \
+       (sl) = __sl;                                    \
 })
 
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) ({          \
-       unsigned int __sh = (ah);                       \
-       unsigned int __sl = (al);                       \
-       __asm__ ("   slr  %1,%3\n"                      \
-                "   brc  3,0f\n"                       \
-                "   ahi  %0,-1\n"                      \
-                "0: slr  %0,%2"                                \
-                : "+&d" (__sh), "+d" (__sl)            \
-                : "d" (bh), "d" (bl) : "cc" );         \
-       (sh) = __sh;                                    \
-       (sl) = __sl;                                    \
+       unsigned int __sh = (ah);                       \
+       unsigned int __sl = (al);                       \
+       asm volatile(                                   \
+               "       slr     %1,%3\n"                \
+               "       brc     3,0f\n"                 \
+               "       ahi     %0,-1\n"                \
+               "0:     slr     %0,%2"                  \
+               : "+&d" (__sh), "+d" (__sl)             \
+               : "d" (bh), "d" (bl) : "cc");           \
+       (sh) = __sh;                                    \
+       (sl) = __sl;                                    \
 })
 
 /* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */
 #define umul_ppmm(wh, wl, u, v) ({                     \
-        unsigned int __wh = u;                         \
-        unsigned int __wl = v;                         \
-        __asm__ ("   ltr  1,%0\n"                      \
-                 "   mr   0,%1\n"                      \
-                 "   jnm  0f\n"                                \
-                 "   alr  0,%1\n"                      \
-                 "0: ltr  %1,%1\n"                     \
-                 "   jnm  1f\n"                                \
-                 "   alr  0,%0\n"                      \
-                 "1: lr   %0,0\n"                      \
-                 "   lr   %1,1\n"                      \
-                 : "+d" (__wh), "+d" (__wl)            \
-                 : : "0", "1", "cc" );                 \
-        wh = __wh;                                     \
-        wl = __wl;                                     \
+       unsigned int __wh = u;                          \
+       unsigned int __wl = v;                          \
+       asm volatile(                                   \
+               "       ltr     1,%0\n"                 \
+               "       mr      0,%1\n"                 \
+               "       jnm     0f\n"                           \
+               "       alr     0,%1\n"                 \
+               "0:     ltr     %1,%1\n"                        \
+               "       jnm     1f\n"                           \
+               "       alr     0,%0\n"                 \
+               "1:     lr      %0,0\n"                 \
+               "       lr      %1,1\n"                 \
+               : "+d" (__wh), "+d" (__wl)              \
+               : : "0", "1", "cc");                    \
+       wh = __wh;                                      \
+       wl = __wl;                                      \
 })
 
 #define udiv_qrnnd(q, r, n1, n0, d)                    \
index 9b11e3e20903f0305916fcd6e6037a71cefdf43f..226275d5c4f60a39a506635d961399e51479e25c 100644 (file)
@@ -142,17 +142,17 @@ dcss_diag (__u8 func, void *parameter,
 
        rx = (unsigned long) parameter;
        ry = (unsigned long) func;
-       __asm__ __volatile__(
+       asm volatile(
 #ifdef CONFIG_64BIT
-               "   sam31\n" // switch to 31 bit
-               "   diag    %0,%1,0x64\n"
-               "   sam64\n" // switch back to 64 bit
+               "       sam31\n"
+               "       diag    %0,%1,0x64\n"
+               "       sam64\n"
 #else
-               "   diag    %0,%1,0x64\n"
+               "       diag    %0,%1,0x64\n"
 #endif
-               "   ipm     %2\n"
-               "   srl     %2,28\n"
-               : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" );
+               "       ipm     %2\n"
+               "       srl     %2,28\n"
+               : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
        *ret1 = rx;
        *ret2 = ry;
        return rc;
index 44f0cda7e72e44bb9ae47e6fc42fd284ceb430ab..9c3c19fe62fcd99dfb3893730d7f54b354b731f5 100644 (file)
@@ -353,8 +353,9 @@ no_context:
 */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (tsk->pid == 1) {
+       if (is_init(tsk)) {
                yield();
+               down_read(&mm->mmap_sem);
                goto survive;
        }
        printk("VM: killing process %s\n", tsk->comm);
@@ -423,20 +424,13 @@ int pfault_init(void)
 
        if (pfault_disable)
                return -1;
-        __asm__ __volatile__(
-                "    diag  %1,%0,0x258\n"
-               "0:  j     2f\n"
-               "1:  la    %0,8\n"
+       asm volatile(
+               "       diag    %1,%0,0x258\n"
+               "0:     j       2f\n"
+               "1:     la      %0,8\n"
                "2:\n"
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-#ifndef CONFIG_64BIT
-               "   .long  0b,1b\n"
-#else /* CONFIG_64BIT */
-               "   .quad  0b,1b\n"
-#endif /* CONFIG_64BIT */
-               ".previous"
-                : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
+               EX_TABLE(0b,1b)
+               : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc");
         __ctl_set_bit(0, 9);
         return rc;
 }
@@ -449,18 +443,11 @@ void pfault_fini(void)
        if (pfault_disable)
                return;
        __ctl_clear_bit(0,9);
-        __asm__ __volatile__(
-                "    diag  %0,0,0x258\n"
+       asm volatile(
+               "       diag    %0,0,0x258\n"
                "0:\n"
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-#ifndef CONFIG_64BIT
-               "   .long  0b,0b\n"
-#else /* CONFIG_64BIT */
-               "   .quad  0b,0b\n"
-#endif /* CONFIG_64BIT */
-               ".previous"
-               : : "a" (&refbk), "m" (refbk) : "cc" );
+               EX_TABLE(0b,0b)
+               : : "a" (&refbk), "m" (refbk) : "cc");
 }
 
 asmlinkage void
index cfd9b8f7a5239b11b7c81272f65474ab80423a02..127044e1707cd075fc7717b3a38321e3b6688ba2 100644 (file)
@@ -45,26 +45,17 @@ void diag10(unsigned long addr)
 {
         if (addr >= 0x7ff00000)
                 return;
+       asm volatile(
 #ifdef CONFIG_64BIT
-        asm volatile (
-               "   sam31\n"
-               "   diag %0,%0,0x10\n"
-               "0: sam64\n"
-               ".section __ex_table,\"a\"\n"
-               "   .align 8\n"
-               "   .quad 0b, 0b\n"
-               ".previous\n"
-               : : "a" (addr));
+               "       sam31\n"
+               "       diag    %0,%0,0x10\n"
+               "0:     sam64\n"
 #else
-        asm volatile (
-               "   diag %0,%0,0x10\n"
+               "       diag    %0,%0,0x10\n"
                "0:\n"
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-               "   .long 0b, 0b\n"
-               ".previous\n"
-               : : "a" (addr));
 #endif
+               EX_TABLE(0b,0b)
+               : : "a" (addr));
 }
 
 void show_mem(void)
@@ -156,11 +147,10 @@ void __init paging_init(void)
        S390_lowcore.kernel_asce = pgdir_k;
 
         /* enable virtual mapping in kernel mode */
-        __asm__ __volatile__("    LCTL  1,1,%0\n"
-                             "    LCTL  7,7,%0\n"
-                             "    LCTL  13,13,%0\n"
-                             "    SSM   %1" 
-                            : : "m" (pgdir_k), "m" (ssm_mask));
+       __ctl_load(pgdir_k, 1, 1);
+       __ctl_load(pgdir_k, 7, 7);
+       __ctl_load(pgdir_k, 13, 13);
+       __raw_local_irq_ssm(ssm_mask);
 
         local_flush_tlb();
         return;
@@ -241,11 +231,10 @@ void __init paging_init(void)
        S390_lowcore.kernel_asce = pgdir_k;
 
         /* enable virtual mapping in kernel mode */
-        __asm__ __volatile__("lctlg 1,1,%0\n\t"
-                             "lctlg 7,7,%0\n\t"
-                             "lctlg 13,13,%0\n\t"
-                             "ssm   %1"
-                            : :"m" (pgdir_k), "m" (ssm_mask));
+       __ctl_load(pgdir_k, 1, 1);
+       __ctl_load(pgdir_k, 7, 7);
+       __ctl_load(pgdir_k, 13, 13);
+       __raw_local_irq_ssm(ssm_mask);
 
         local_flush_tlb();
 
index 149d9713eddf0432ff8321972cd31320652f4c30..f664a196c4f58dd635cd6ec960fd7808a8e8532f 100644 (file)
@@ -117,7 +117,7 @@ static long last_rtc_update;
  */
 void handle_timer_tick(struct pt_regs *regs)
 {
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index c69fd603226aa80a20ba084aebd545e65c5142c3..68663b8f99aec28619ea7cb92d16978c5a08be25 100644 (file)
@@ -69,7 +69,7 @@ good_area:
                if (!(vma->vm_flags & VM_WRITE))
                        goto bad_area;
        } else {
-               if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+               if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                        goto bad_area;
        }
 
@@ -149,7 +149,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index b8162e59030e447c6fcc1d12cdb0c59e15ce34e6..3b61e06f9d7258622d9aaa6123d433b66dd0f7d9 100644 (file)
@@ -298,7 +298,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs)
        asm ("getcon cr62, %0" : "=r" (current_ctc));
        ctc_last_interrupt = (unsigned long) current_ctc;
 
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index f08d0eaf6497d34c716d8f0c5ee4baf2aa4eb27c..8e2f6c28b7390fc712a8d07f8e8e567fbd7b6853 100644 (file)
@@ -277,7 +277,7 @@ bad_area:
                        show_regs(regs);
 #endif
                }
-               if (tsk->pid == 1) {
+               if (is_init(tsk)) {
                        panic("INIT had user mode bad_area\n");
                }
                tsk->thread.address = address;
@@ -319,14 +319,14 @@ no_context:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (current->pid == 1) {
+       if (is_init(current)) {
                panic("INIT out of memory\n");
                yield();
                goto survive;
        }
        printk("fault:Out of memory\n");
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index bfd31aac2df3b2c7992f082fd08b9f5ba78da4c2..e19b1bad9bc56e0c1710c4c1d006b6867fdc5984 100644 (file)
@@ -712,7 +712,7 @@ static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs)
 {
        write_seqlock(&xtime_lock);     /* Dummy, to show that we remember */
        pcic_clear_clock_irq();
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index 845081b0126760ac14e8b7c2735ad089bee991f2..6f84fa1b58e5e54b94c8ce42b05ee82c484c837b 100644 (file)
@@ -128,7 +128,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 #endif
        clear_clock_irq();
 
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index 577505b692ae0643b046223187d071de9106f618..ef095b6c43b157dc7ad076b641893b59e25775de 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/ptrace.h>
 #include <asm/asmmacro.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 /* Work around cpp -rob */
 #define ALLOC #alloc
@@ -366,6 +367,9 @@ fixupretl:
        blu     1f
         cmp    %o1, %g1
        bgeu    1f
+        ld     [%g6 + TI_PREEMPT], %g1
+       cmp     %g1, 0
+       bne     1f
         nop
        save    %sp, -64, %sp
        mov     %i0, %o0
index b0b4feeec09826f84a70e29d9ad8b77d6347ab7c..ca1193482f07d2df1cd292bd6cce62531bad3426 100644 (file)
@@ -465,7 +465,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                profile_tick(CPU_PROFILING, regs);
                update_process_times(user_mode(regs));
 #endif
-               do_timer(regs);
+               do_timer(1);
 
                /* Guarantee that the following sequences execute
                 * uninterrupted.
@@ -496,7 +496,7 @@ void timer_tick_interrupt(struct pt_regs *regs)
 {
        write_seqlock(&xtime_lock);
 
-       do_timer(regs);
+       do_timer(1);
 
        timer_check_rtc();
 
index 642541769a179970c077dba52e23c2d1d90984a3..9c581328e76a191e3b4aa4903840276db2c3aab2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/limits.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
+#include <linux/tty.h>
 #include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/timex.h>
@@ -422,7 +423,9 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
                           Solaris setpgrp and setsid? */
                        ret = sys_setpgid(0, 0);
                        if (ret) return ret;
+                       mutex_lock(&tty_mutex);
                        current->signal->tty = NULL;
+                       mutex_unlock(&tty_mutex);
                        return process_group(current);
                }
        case 2: /* getsid */
index 79610b5ce67ed5978aa5b74ee109411616c76e60..773a134e7fdb806fd6b63c80ceb3576ede57a370 100644 (file)
@@ -598,6 +598,11 @@ out:
        mconsole_reply(req, err_msg, err, 0);
 }
 
+struct mconsole_output {
+       struct list_head list;
+       struct mc_request *req;
+};
+
 static DEFINE_SPINLOCK(console_lock);
 static LIST_HEAD(clients);
 static char console_buf[MCONSOLE_MAX_DATA];
@@ -622,10 +627,10 @@ static void console_write(struct console *console, const char *string,
                        return;
 
                list_for_each(ele, &clients){
-                       struct mconsole_entry *entry;
+                       struct mconsole_output *entry;
 
-                       entry = list_entry(ele, struct mconsole_entry, list);
-                       mconsole_reply_len(&entry->request, console_buf,
+                       entry = list_entry(ele, struct mconsole_output, list);
+                       mconsole_reply_len(entry->req, console_buf,
                                           console_index, 0, 1);
                }
 
@@ -649,10 +654,10 @@ late_initcall(mc_add_console);
 static void with_console(struct mc_request *req, void (*proc)(void *),
                         void *arg)
 {
-       struct mconsole_entry entry;
+       struct mconsole_output entry;
        unsigned long flags;
 
-       entry.request = *req;
+       entry.req = req;
        list_add(&entry.list, &clients);
        spin_lock_irqsave(&console_lock, flags);
 
index 5b2f5fe9e426d3d45043bae9a49badb804a9426e..17068eb746c0bda5204a8ffd49ee0ab5de16c46a 100644 (file)
@@ -131,6 +131,10 @@ int mconsole_get_request(int fd, struct mc_request *req)
 int mconsole_reply_len(struct mc_request *req, const char *str, int total,
                       int err, int more)
 {
+       /* XXX This is a stack consumption problem.  It'd be nice to
+        * make it global and serialize access to it, but there are a
+        * ton of callers to this function.
+        */
        struct mconsole_reply reply;
        int len, n;
 
index 664c2e2fb8209de464e27a951407e7d9fb58ae56..300a54a6523eb925de5e5308b5170c622f7b3811 100644 (file)
@@ -119,11 +119,6 @@ static int uml_net_open(struct net_device *dev)
                goto out;
        }
 
-       if(!lp->have_mac){
-               dev_ip_addr(dev, &lp->mac[2]);
-               set_ether_mac(dev, lp->mac);
-       }
-
        lp->fd = (*lp->open)(&lp->user);
        if(lp->fd < 0){
                err = lp->fd;
@@ -287,6 +282,37 @@ void uml_net_user_timer_expire(unsigned long _conn)
 #endif
 }
 
+static void setup_etheraddr(char *str, unsigned char *addr)
+{
+       char *end;
+       int i;
+
+       if(str == NULL)
+               goto random;
+
+       for(i=0;i<6;i++){
+               addr[i] = simple_strtoul(str, &end, 16);
+               if((end == str) ||
+                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
+                       printk(KERN_ERR
+                              "setup_etheraddr: failed to parse '%s' "
+                              "as an ethernet address\n", str);
+                       goto random;
+               }
+               str = end + 1;
+       }
+       if(addr[0] & 1){
+               printk(KERN_ERR
+                      "Attempt to assign a broadcast ethernet address to a "
+                      "device disallowed\n");
+               goto random;
+       }
+       return;
+
+random:
+       random_ether_addr(addr);
+}
+
 static DEFINE_SPINLOCK(devices_lock);
 static LIST_HEAD(devices);
 
@@ -322,15 +348,13 @@ static int eth_configure(int n, void *init, char *mac,
        list_add(&device->list, &devices);
        spin_unlock(&devices_lock);
 
-       if (setup_etheraddr(mac, device->mac))
-               device->have_mac = 1;
+       setup_etheraddr(mac, device->mac);
 
        printk(KERN_INFO "Netdevice %d ", n);
-       if (device->have_mac)
-               printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
-                      device->mac[0], device->mac[1],
-                      device->mac[2], device->mac[3],
-                      device->mac[4], device->mac[5]);
+       printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
+              device->mac[0], device->mac[1],
+              device->mac[2], device->mac[3],
+              device->mac[4], device->mac[5]);
        printk(": ");
        dev = alloc_etherdev(size);
        if (dev == NULL) {
@@ -396,7 +420,6 @@ static int eth_configure(int n, void *init, char *mac,
                  .dev                  = dev,
                  .fd                   = -1,
                  .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
-                 .have_mac             = device->have_mac,
                  .protocol             = transport->kern->protocol,
                  .open                 = transport->user->open,
                  .close                = transport->user->close,
@@ -411,14 +434,12 @@ static int eth_configure(int n, void *init, char *mac,
        init_timer(&lp->tl);
        spin_lock_init(&lp->lock);
        lp->tl.function = uml_net_user_timer_expire;
-       if (lp->have_mac)
-               memcpy(lp->mac, device->mac, sizeof(lp->mac));
+       memcpy(lp->mac, device->mac, sizeof(lp->mac));
 
        if (transport->user->init) 
                (*transport->user->init)(&lp->user, dev);
 
-       if (device->have_mac)
-               set_ether_mac(dev, device->mac);
+       set_ether_mac(dev, device->mac);
 
        return 0;
 }
@@ -747,47 +768,6 @@ static void close_devices(void)
 
 __uml_exitcall(close_devices);
 
-int setup_etheraddr(char *str, unsigned char *addr)
-{
-       char *end;
-       int i;
-
-       if(str == NULL)
-               return(0);
-       for(i=0;i<6;i++){
-               addr[i] = simple_strtoul(str, &end, 16);
-               if((end == str) ||
-                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
-                       printk(KERN_ERR 
-                              "setup_etheraddr: failed to parse '%s' "
-                              "as an ethernet address\n", str);
-                       return(0);
-               }
-               str = end + 1;
-       }
-       if(addr[0] & 1){
-               printk(KERN_ERR 
-                      "Attempt to assign a broadcast ethernet address to a "
-                      "device disallowed\n");
-               return(0);
-       }
-       return(1);
-}
-
-void dev_ip_addr(void *d, unsigned char *bin_buf)
-{
-       struct net_device *dev = d;
-       struct in_device *ip = dev->ip_ptr;
-       struct in_ifaddr *in;
-
-       if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
-               printk(KERN_WARNING "dev_ip_addr - device not assigned an "
-                      "IP address\n");
-               return;
-       }
-       memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
-}
-
 struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
 {
        if((skb != NULL) && (skb_tailroom(skb) < extra)){
@@ -825,7 +805,7 @@ int dev_netmask(void *d, void *m)
        struct net_device *dev = d;
        struct in_device *ip = dev->ip_ptr;
        struct in_ifaddr *in;
-       __u32 *mask_out = m;
+       __be32 *mask_out = m;
 
        if(ip == NULL) 
                return(1);
index 107c5e43fa00fec37d6fcf8c3b01851274a9b87e..f3a3f8a29c7af877d327692f2f30f89a7ef6f081 100644 (file)
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
+#include <sys/time.h>
 #include "user.h"
 #include "user_util.h"
 #include "kern_util.h"
index 3683ed44315d6e2da21707c9293bf82eb22e326b..9016c68beee8d3287761b1da07001c5915bde7c6 100644 (file)
@@ -8,6 +8,7 @@
 #include "chan_user.h"
 #include "os.h"
 
+/* This address is used only as a unique identifer */
 static int null_chan;
 
 static void *null_init(char *str, int device, const struct chan_opts *opts)
index ae9909415b9cdb372c1f1f0c1602a21a4c2e86b3..73b2bdd6d2d3b867165e116b7a1b430f34096c9b 100644 (file)
 
 #define RNG_MISCDEV_MINOR              183 /* official */
 
+/* Changed at init time, in the non-modular case, and at module load
+ * time, in the module case.  Presumably, the module subsystem
+ * protects against a module being loaded twice at the same time.
+ */
 static int random_fd = -1;
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
index 6d2cf32a9e8f880eeaf7439e874ef4640f3ec7dc..911539293871d271ed306c36fd1b113f6acc9203 100644 (file)
@@ -9,6 +9,8 @@
 /*
  * Don't register by default -- as this registeres very early in the
  * boot process it becomes the default console.
+ *
+ * Initialized at init time.
  */
 static int use_stderr_console = 0;
 
index 5e44adb07051723333236caa67d9358e2cb7aabc..e4bfcfe8550ba91cc7515c3d3bd46bd7e39ba325 100644 (file)
@@ -108,6 +108,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
        return line_open(vts, tty);
 }
 
+/* Set in an initcall, checked in an exitcall */
 static int con_init_done = 0;
 
 static const struct tty_operations console_ops = {
index 34085315aa57e045232a20abeea45ec1111dda79..fda4a3940698c26a8be776ce5141e5fa3e03189f 100644 (file)
@@ -668,18 +668,15 @@ static int ubd_add(int n)
        if(dev->file == NULL)
                goto out;
 
-       if (ubd_open_dev(dev))
-               goto out;
-
        err = ubd_file_size(dev, &dev->size);
        if(err < 0)
-               goto out_close;
+               goto out;
 
        dev->size = ROUND_BLOCK(dev->size);
 
        err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
        if(err)
-               goto out_close;
+               goto out;
 
        if(fake_major != MAJOR_NR)
                ubd_new_disk(fake_major, dev->size, n,
@@ -691,8 +688,6 @@ static int ubd_add(int n)
                make_ide_entries(ubd_gendisk[n]->disk_name);
 
        err = 0;
-out_close:
-       ubd_close(dev);
 out:
        return err;
 }
@@ -986,8 +981,6 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
        __u64 offset;
        int len;
 
-       if(req->rq_status == RQ_INACTIVE) return(1);
-
        /* This should be impossible now */
        if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
                printk("Write attempted on readonly ubd device %s\n",
index 769fba43ee039a2bfb93fd33d32f23a49ba623cd..280459fb0b2619ded00ce874565a5d6c93ef6c49 100644 (file)
@@ -18,7 +18,6 @@ struct uml_net {
        struct platform_device pdev;
        int index;
        unsigned char mac[ETH_ALEN];
-       int have_mac;
 };
 
 struct uml_net_private {
@@ -29,7 +28,6 @@ struct uml_net_private {
        struct net_device_stats stats;
        int fd;
        unsigned char mac[ETH_ALEN];
-       int have_mac;
        unsigned short (*protocol)(struct sk_buff *);
        int (*open)(void *);
        void (*close)(int, void *);
@@ -62,7 +60,6 @@ struct transport {
 
 extern struct net_device *ether_init(int);
 extern unsigned short ether_protocol(struct sk_buff *);
-extern int setup_etheraddr(char *str, unsigned char *addr);
 extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
 extern int tap_setup_common(char *str, char *type, char **dev_name, 
                            char **mac_out, char **gate_addr);
@@ -70,14 +67,3 @@ extern void register_transport(struct transport *new);
 extern unsigned short eth_protocol(struct sk_buff *skb);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 47ef7cb49a8e3f19619d7417ca856c7762907f3c..19f207cd70fe4b3bf6ed33dee917a58622055d9a 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -25,9 +25,8 @@ struct net_user_info {
 };
 
 extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, unsigned char *bin_buf);
-extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
-                                              unsigned char *, void *), 
+extern void iter_addresses(void *d, void (*cb)(unsigned char *,
+                                              unsigned char *, void *),
                           void *arg);
 
 extern void *get_output_buffer(int *len_out);
@@ -52,14 +51,3 @@ extern char *split_if_spec(char *str, ...);
 extern int dev_netmask(void *d, void *m);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index d21ebad666b4246f45c99d2667dbcc82702b6f6c..8b7f2cdedf945148ffd96306ac04024dc9a0a7ee 100644 (file)
@@ -16,9 +16,13 @@ int uml_exitcode = 0;
 static int read_proc_exitcode(char *page, char **start, off_t off,
                              int count, int *eof, void *data)
 {
-       int len;
+       int len, val;
 
-       len = sprintf(page, "%d\n", uml_exitcode);
+       /* Save uml_exitcode in a local so that we don't need to guarantee
+        * that sprintf accesses it atomically.
+        */
+       val = uml_exitcode;
+       len = sprintf(page, "%d\n", val);
        len -= off;
        if(len <= off+count) *eof = 1;
        *start = page + off;
index 79c22707a6375c84cbda0f89df31abf0eda28836..4cd2ff546ef6f9d322b2f882ca182bf5315cf7c9 100644 (file)
@@ -61,8 +61,10 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 #endif
 
        *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
-       *pte = pte_mkexec(*pte);
-       *pte = pte_wrprotect(*pte);
+       /* This is wrong for the code page, but it doesn't matter since the
+        * stub is mapped by hand with the correct permissions.
+        */
+       *pte = pte_mkwrite(*pte);
        return(0);
 
  out_pmd:
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
deleted file mode 100644 (file)
index 0f3d5d0..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/config.h"
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/interrupt.h"
-#include "linux/string.h"
-#include "linux/mm.h"
-#include "linux/slab.h"
-#include "linux/utsname.h"
-#include "linux/fs.h"
-#include "linux/utime.h"
-#include "linux/smp_lock.h"
-#include "linux/module.h"
-#include "linux/init.h"
-#include "linux/capability.h"
-#include "linux/vmalloc.h"
-#include "linux/spinlock.h"
-#include "linux/proc_fs.h"
-#include "linux/ptrace.h"
-#include "linux/random.h"
-#include "linux/personality.h"
-#include "asm/unistd.h"
-#include "asm/mman.h"
-#include "asm/segment.h"
-#include "asm/stat.h"
-#include "asm/pgtable.h"
-#include "asm/processor.h"
-#include "asm/tlbflush.h"
-#include "asm/uaccess.h"
-#include "asm/user.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "kern.h"
-#include "signal_kern.h"
-#include "init.h"
-#include "irq_user.h"
-#include "mem_user.h"
-#include "tlb.h"
-#include "frame_kern.h"
-#include "sigcontext.h"
-#include "os.h"
-#include "mode.h"
-#include "mode_kern.h"
-#include "choose-mode.h"
-
-/* This is a per-cpu array.  A processor only modifies its entry and it only
- * cares about its entry, so it's OK if another processor is modifying its
- * entry.
- */
-struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
-
-int external_pid(void *t)
-{
-       struct task_struct *task = t ? t : current;
-
-       return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
-}
-
-int pid_to_processor_id(int pid)
-{
-       int i;
-
-       for(i = 0; i < ncpus; i++){
-               if(cpu_tasks[i].pid == pid) return(i);
-       }
-       return(-1);
-}
-
-void free_stack(unsigned long stack, int order)
-{
-       free_pages(stack, order);
-}
-
-unsigned long alloc_stack(int order, int atomic)
-{
-       unsigned long page;
-       gfp_t flags = GFP_KERNEL;
-
-       if (atomic)
-               flags = GFP_ATOMIC;
-       page = __get_free_pages(flags, order);
-       if(page == 0)
-               return(0);
-       stack_protections(page);
-       return(page);
-}
-
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       int pid;
-
-       current->thread.request.u.thread.proc = fn;
-       current->thread.request.u.thread.arg = arg;
-       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
-                     &current->thread.regs, 0, NULL, NULL);
-       if(pid < 0)
-               panic("do_fork failed in kernel_thread, errno = %d", pid);
-       return(pid);
-}
-
-void set_current(void *t)
-{
-       struct task_struct *task = t;
-
-       cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
-               { external_pid(task), task });
-}
-
-void *_switch_to(void *prev, void *next, void *last)
-{
-        struct task_struct *from = prev;
-        struct task_struct *to= next;
-
-        to->thread.prev_sched = from;
-        set_current(to);
-
-       do {
-               current->thread.saved_task = NULL ;
-               CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
-               if(current->thread.saved_task)
-                       show_regs(&(current->thread.regs));
-               next= current->thread.saved_task;
-               prev= current;
-       } while(current->thread.saved_task);
-
-        return(current->thread.prev_sched);
-
-}
-
-void interrupt_end(void)
-{
-       if(need_resched()) schedule();
-       if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
-}
-
-void release_thread(struct task_struct *task)
-{
-       CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
-}
-
-void exit_thread(void)
-{
-       unprotect_stack((unsigned long) current_thread);
-}
-
-void *get_current(void)
-{
-       return(current);
-}
-
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
-               unsigned long stack_top, struct task_struct * p,
-               struct pt_regs *regs)
-{
-       int ret;
-
-       p->thread = (struct thread_struct) INIT_THREAD;
-       ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
-                               clone_flags, sp, stack_top, p, regs);
-
-       if (ret || !current->thread.forking)
-               goto out;
-
-       clear_flushed_tls(p);
-
-       /*
-        * Set a new TLS for the child thread?
-        */
-       if (clone_flags & CLONE_SETTLS)
-               ret = arch_copy_tls(p);
-
-out:
-       return ret;
-}
-
-void initial_thread_cb(void (*proc)(void *), void *arg)
-{
-       int save_kmalloc_ok = kmalloc_ok;
-
-       kmalloc_ok = 0;
-       CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
-                        arg);
-       kmalloc_ok = save_kmalloc_ok;
-}
-
-unsigned long stack_sp(unsigned long page)
-{
-       return(page + PAGE_SIZE - sizeof(void *));
-}
-
-int current_pid(void)
-{
-       return(current->pid);
-}
-
-void default_idle(void)
-{
-       CHOOSE_MODE(uml_idle_timer(), (void) 0);
-
-       while(1){
-               /* endless idle loop with no priority at all */
-
-               /*
-                * although we are an idle CPU, we do not want to
-                * get into the scheduler unnecessarily.
-                */
-               if(need_resched())
-                       schedule();
-
-               idle_sleep(10);
-       }
-}
-
-void cpu_idle(void)
-{
-       CHOOSE_MODE(init_idle_tt(), init_idle_skas());
-}
-
-int page_size(void)
-{
-       return(PAGE_SIZE);
-}
-
-void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
-                     pte_t *pte_out)
-{
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
-       pte_t ptent;
-
-       if(task->mm == NULL)
-               return(ERR_PTR(-EINVAL));
-       pgd = pgd_offset(task->mm, addr);
-       if(!pgd_present(*pgd))
-               return(ERR_PTR(-EINVAL));
-
-       pud = pud_offset(pgd, addr);
-       if(!pud_present(*pud))
-               return(ERR_PTR(-EINVAL));
-
-       pmd = pmd_offset(pud, addr);
-       if(!pmd_present(*pmd))
-               return(ERR_PTR(-EINVAL));
-
-       pte = pte_offset_kernel(pmd, addr);
-       ptent = *pte;
-       if(!pte_present(ptent))
-               return(ERR_PTR(-EINVAL));
-
-       if(pte_out != NULL)
-               *pte_out = ptent;
-       return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
-}
-
-char *current_cmd(void)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
-       return("(Unknown)");
-#else
-       void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
-       return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
-#endif
-}
-
-void force_sigbus(void)
-{
-       printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
-              current->pid);
-       lock_kernel();
-       sigaddset(&current->pending.signal, SIGBUS);
-       recalc_sigpending();
-       current->flags |= PF_SIGNALED;
-       do_exit(SIGBUS | 0x80);
-}
-
-void dump_thread(struct pt_regs *regs, struct user *u)
-{
-}
-
-void enable_hlt(void)
-{
-       panic("enable_hlt");
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
-void disable_hlt(void)
-{
-       panic("disable_hlt");
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void *um_kmalloc(int size)
-{
-       return kmalloc(size, GFP_KERNEL);
-}
-
-void *um_kmalloc_atomic(int size)
-{
-       return kmalloc(size, GFP_ATOMIC);
-}
-
-void *um_vmalloc(int size)
-{
-       return vmalloc(size);
-}
-
-void *um_vmalloc_atomic(int size)
-{
-       return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-int __cant_sleep(void) {
-       return in_atomic() || irqs_disabled() || in_interrupt();
-       /* Is in_interrupt() really needed? */
-}
-
-unsigned long get_fault_addr(void)
-{
-       return((unsigned long) current->thread.fault_addr);
-}
-
-EXPORT_SYMBOL(get_fault_addr);
-
-void not_implemented(void)
-{
-       printk(KERN_DEBUG "Something isn't implemented in here\n");
-}
-
-EXPORT_SYMBOL(not_implemented);
-
-int user_context(unsigned long sp)
-{
-       unsigned long stack;
-
-       stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
-       return(stack != (unsigned long) current_thread);
-}
-
-extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
-
-void do_uml_exitcalls(void)
-{
-       exitcall_t *call;
-
-       call = &__uml_exitcall_end;
-       while (--call >= &__uml_exitcall_begin)
-               (*call)();
-}
-
-char *uml_strdup(char *string)
-{
-       return kstrdup(string, GFP_KERNEL);
-}
-
-int copy_to_user_proc(void __user *to, void *from, int size)
-{
-       return(copy_to_user(to, from, size));
-}
-
-int copy_from_user_proc(void *to, void __user *from, int size)
-{
-       return(copy_from_user(to, from, size));
-}
-
-int clear_user_proc(void __user *buf, int size)
-{
-       return(clear_user(buf, size));
-}
-
-int strlen_user_proc(char __user *str)
-{
-       return(strlen_user(str));
-}
-
-int smp_sigio_handler(void)
-{
-#ifdef CONFIG_SMP
-       int cpu = current_thread->cpu;
-       IPI_handler(cpu);
-       if(cpu != 0)
-               return(1);
-#endif
-       return(0);
-}
-
-int cpu(void)
-{
-       return(current_thread->cpu);
-}
-
-static atomic_t using_sysemu = ATOMIC_INIT(0);
-int sysemu_supported;
-
-void set_using_sysemu(int value)
-{
-       if (value > sysemu_supported)
-               return;
-       atomic_set(&using_sysemu, value);
-}
-
-int get_using_sysemu(void)
-{
-       return atomic_read(&using_sysemu);
-}
-
-static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
-{
-       if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
-               *eof = 1;
-
-       return strlen(buf);
-}
-
-static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
-{
-       char tmp[2];
-
-       if (copy_from_user(tmp, buf, 1))
-               return -EFAULT;
-
-       if (tmp[0] >= '0' && tmp[0] <= '2')
-               set_using_sysemu(tmp[0] - '0');
-       return count; /*We use the first char, but pretend to write everything*/
-}
-
-int __init make_proc_sysemu(void)
-{
-       struct proc_dir_entry *ent;
-       if (!sysemu_supported)
-               return 0;
-
-       ent = create_proc_entry("sysemu", 0600, &proc_root);
-
-       if (ent == NULL)
-       {
-               printk(KERN_WARNING "Failed to register /proc/sysemu\n");
-               return(0);
-       }
-
-       ent->read_proc  = proc_read_sysemu;
-       ent->write_proc = proc_write_sysemu;
-
-       return 0;
-}
-
-late_initcall(make_proc_sysemu);
-
-int singlestepping(void * t)
-{
-       struct task_struct *task = t ? t : current;
-
-       if ( ! (task->ptrace & PT_DTRACE) )
-               return(0);
-
-       if (task->thread.singlestep_syscall)
-               return(1);
-
-       return 2;
-}
-
-/*
- * Only x86 and x86_64 have an arch_align_stack().
- * All other arches have "#define arch_align_stack(x) (x)"
- * in their asm/system.h
- * As this is included in UML from asm-um/system-generic.h,
- * we can use it to behave as the subarch does.
- */
-#ifndef arch_align_stack
-unsigned long arch_align_stack(unsigned long sp)
-{
-       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() % 8192;
-       return sp & ~0xf;
-}
-#endif
index 820affbf3e163cc4b99abc627fac7421786b8d57..a92965f8f9cdd57d600e229e136dee8fafa64d5a 100644 (file)
@@ -93,7 +93,7 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
-       do_timer(regs);
+       do_timer(1);
 
        nsecs = get_time();
        xtime.tv_sec = nsecs / NSEC_PER_SEC;
index 61a23fff4395e822f1ee481a9ab589003201b1ba..c7b195c7e51fa3ddc3d46da245f2f0f5ce7fa6fe 100644 (file)
@@ -120,7 +120,7 @@ out_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (current->pid == 1) {
+       if (is_init(current)) {
                up_read(&mm->mmap_sem);
                yield();
                down_read(&mm->mmap_sem);
index b170b4704dc40aa25137f6ab29ece4b36eb03078..4203681e508d0a680635347c53a2168fdd3a68be 100644 (file)
@@ -132,6 +132,9 @@ err:
        else if(found < 0)
                printf("read returned errno %d\n", -found);
 
+out:
+       close(fd);
+
        return;
 
 found:
@@ -141,11 +144,12 @@ found:
 
        if(strncmp(buf, "tmpfs", strlen("tmpfs"))){
                printf("not tmpfs\n");
-               return;
+               goto out;
        }
 
        printf("OK\n");
        default_tmpdir = "/dev/shm";
+       goto out;
 }
 
 /*
index a0b46695f186f03921a7a09b66cde5af0bf5bfa8..f4d1a4d3cdc231696e55802039541e5b024b3c76 100644 (file)
@@ -51,7 +51,7 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
        if (mach_tick)
          mach_tick ();
 
-       do_timer (regs);
+       do_timer (1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
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 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 6a55f87ba97f917ed2814bc3c11c3f21a3ad096b..697f0aa794b960a663b15ee09e161f86890119ab 100644 (file)
@@ -3,7 +3,8 @@
 #include <linux/pci.h>
 #include <linux/cache.h>
 #include <linux/module.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
+
 #include <asm/proto.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
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 1c255ee76e7c81870768f54adc9a5fe149dc0239..7ea3bf2a858c6299c1c686fc0530b1da14bbef63 100644 (file)
@@ -415,16 +415,16 @@ void main_timer_handler(struct pt_regs *regs)
                                (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1;
        }
 
-       if (lost > 0) {
+       if (lost > 0)
                handle_lost_ticks(lost, regs);
-               jiffies += lost;
-       }
+       else
+               lost = 0;
 
 /*
  * Do the timer stuff.
  */
 
-       do_timer(regs);
+       do_timer(lost + 1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index d0564f1bcb0b9aa62a42919bcbeb24f8c2725397..f8aeccf105fa919b529ee45eb670beda4ecebf8d 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) {
@@ -229,6 +222,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..07c086382059fbe626844ed45aad23dd701119eb 100644 (file)
@@ -155,8 +155,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 +165,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 1a17b0733ab5d38ad81ccdf4263e2d58571d9e24..3751b4788e288748112c05df0121a1186aac5fab 100644 (file)
@@ -244,7 +244,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
 
 int unhandled_signal(struct task_struct *tsk, int sig)
 {
-       if (tsk->pid == 1)
+       if (is_init(tsk))
                return 1;
        if (tsk->ptrace & PT_PTRACED)
                return 0;
@@ -464,7 +464,7 @@ good_area:
                case PF_PROT:           /* read, present */
                        goto bad_area;
                case 0:                 /* read, not present */
-                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                                goto bad_area;
        }
 
@@ -580,7 +580,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) { 
+       if (is_init(current)) {
                yield();
                goto again;
        }
index 412ab32de391788de830fe5786adffe2ac3ca854..241db201f40e59300bb97691bdcc4b2608c80c23 100644 (file)
@@ -175,7 +175,7 @@ again:
 
                last_ccount_stamp = next;
                next += CCOUNT_PER_JIFFY;
-               do_timer (regs); /* Linux handler in kernel/timer.c */
+               do_timer (1); /* Linux handler in kernel/timer.c */
 
                if (ntp_synced() &&
                    xtime.tv_sec - last_rtc_update >= 659 &&
index a945a33e85a129d0e268b1e20cf9a54710ec93c6..dd0dbec2e57e4f39b51ab7a73359a0117e638b48 100644 (file)
@@ -144,7 +144,7 @@ bad_area:
         */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (current->pid == 1) {
+       if (is_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index d96164e602fea496c7b33b35d4e685261eef7647..15d64414bd6018e2394d3485ec6070730614eb5a 100644 (file)
@@ -201,7 +201,7 @@ static void dev_ip_addr(void *d, char *buf, char *bin_buf)
        struct net_device *dev = d;
        struct in_device *ip = dev->ip_ptr;
        struct in_ifaddr *in;
-       u32 addr;
+       __be32 addr;
 
        if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
                printk(KERN_WARNING "Device not assigned an IP address!\n");
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..165509e8659ef7642ec0e60ec5d6c511a46ccafe 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,7 +1474,6 @@ static int __init as_init(void)
                return 0;
        }
 
-       kmem_cache_destroy(arq_pool);
        return ret;
 }
 
@@ -1833,10 +1484,9 @@ static void __exit as_exit(void)
        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 2b4ef2b89b8d74b376a2011b5455039fd3730e20..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)))
@@ -450,8 +453,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
  **/
 void blk_trace_shutdown(request_queue_t *q)
 {
-       blk_trace_startstop(q, 0);
-       blk_trace_remove(q);
+       if (q->blk_trace) {
+               blk_trace_startstop(q, 0);
+               blk_trace_remove(q);
+       }
 }
 
 /*
@@ -471,6 +476,9 @@ static void blk_check_time(unsigned long long *t)
        *t -= (a + b) / 2;
 }
 
+/*
+ * calibrate our inter-CPU timings
+ */
 static void blk_trace_check_cpu_time(void *data)
 {
        unsigned long long *t;
@@ -488,20 +496,6 @@ static void blk_trace_check_cpu_time(void *data)
        put_cpu();
 }
 
-/*
- * Call blk_trace_check_cpu_time() on each CPU to calibrate our inter-CPU
- * timings
- */
-static void blk_trace_calibrate_offsets(void)
-{
-       unsigned long flags;
-
-       smp_call_function(blk_trace_check_cpu_time, NULL, 1, 1);
-       local_irq_save(flags);
-       blk_trace_check_cpu_time(NULL);
-       local_irq_restore(flags);
-}
-
 static void blk_trace_set_ht_offsets(void)
 {
 #if defined(CONFIG_SCHED_SMT)
@@ -530,7 +524,7 @@ static void blk_trace_set_ht_offsets(void)
 static __init int blk_trace_init(void)
 {
        mutex_init(&blk_tree_mutex);
-       blk_trace_calibrate_offsets();
+       on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1);
        blk_trace_set_ht_offsets();
 
        return 0;
index 3a3aee08ec5f4850f0a1877b3bdf86d9b03d9625..99116e2a310aaa3506f724a93fcb1b1f06b4d2fc 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",
@@ -2468,7 +2165,7 @@ static void __exit cfq_exit(void)
        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 25d1f42568cc19714a2f8a5469ecd2842e9ea7e5..653919d50cd4d06aea68d8e027d15a473e5b4f5a 100644 (file)
@@ -295,10 +295,15 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
 
 static int __init genhd_device_init(void)
 {
+       int err;
+
        bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
        blk_dev_init();
-       subsystem_register(&block_subsys);
-       return 0;
+       err = subsystem_register(&block_subsys);
+       if (err < 0)
+               printk(KERN_WARNING "%s: subsystem_register error: %d\n",
+                       __FUNCTION__, err);
+       return err;
 }
 
 subsys_initcall(genhd_device_init);
index 9c3a06bcb7ba97b02d12de6638944ac79e33baa2..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;
@@ -1847,8 +1821,7 @@ static void blk_release_queue(struct kobject *kobj)
        if (q->queue_tags)
                __blk_queue_free_tags(q);
 
-       if (q->blk_trace)
-               blk_trace_shutdown(q);
+       blk_trace_shutdown(q);
 
        kmem_cache_free(requestq_cachep, q);
 }
@@ -2030,14 +2003,13 @@ EXPORT_SYMBOL(blk_get_queue);
 
 static inline void blk_free_request(request_queue_t *q, struct request *rq)
 {
-       if (rq->flags & REQ_ELVPRIV)
+       if (rq->cmd_flags & REQ_ELVPRIV)
                elv_put_request(q, rq);
        mempool_free(rq, q->rq.rq_pool);
 }
 
-static inline struct request *
-blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
-                 int priv, gfp_t gfp_mask)
+static struct request *
+blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask)
 {
        struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
 
@@ -2045,17 +2017,17 @@ blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
                return NULL;
 
        /*
-        * first three bits are identical in rq->flags and bio->bi_rw,
+        * first three bits are identical in rq->cmd_flags and bio->bi_rw,
         * see bio.h and blkdev.h
         */
-       rq->flags = rw;
+       rq->cmd_flags = rw | REQ_ALLOCED;
 
        if (priv) {
-               if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
+               if (unlikely(elv_set_request(q, rq, gfp_mask))) {
                        mempool_free(rq, q->rq.rq_pool);
                        return NULL;
                }
-               rq->flags |= REQ_ELVPRIV;
+               rq->cmd_flags |= REQ_ELVPRIV;
        }
 
        return rq;
@@ -2142,13 +2114,13 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
        struct io_context *ioc = NULL;
        int may_queue, priv;
 
-       may_queue = elv_may_queue(q, rw, bio);
+       may_queue = elv_may_queue(q, rw);
        if (may_queue == ELV_MQUEUE_NO)
                goto rq_starved;
 
        if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
                if (rl->count[rw]+1 >= q->nr_requests) {
-                       ioc = current_io_context(GFP_ATOMIC);
+                       ioc = current_io_context(GFP_ATOMIC, q->node);
                        /*
                         * The queue will fill after this allocation, so set
                         * it as full, and mark this process as "batching".
@@ -2190,7 +2162,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
 
        spin_unlock_irq(q->queue_lock);
 
-       rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
+       rq = blk_alloc_request(q, rw, priv, gfp_mask);
        if (unlikely(!rq)) {
                /*
                 * Allocation failed presumably due to memory. Undo anything
@@ -2226,7 +2198,6 @@ rq_starved:
                ioc->nr_batch_requests--;
        
        rq_init(q, rq);
-       rq->rl = rl;
 
        blk_add_trace_generic(q, bio, rw, BLK_TA_GETRQ);
 out:
@@ -2269,7 +2240,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
                         * up to a big batch of them for a small period time.
                         * See ioc_batching, ioc_set_batching
                         */
-                       ioc = current_io_context(GFP_NOIO);
+                       ioc = current_io_context(GFP_NOIO, q->node);
                        ioc_set_batching(q, ioc);
 
                        spin_lock_irq(q->queue_lock);
@@ -2300,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
@@ -2352,7 +2342,8 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
         * must not attempt merges on this) and that it acts as a soft
         * barrier
         */
-       rq->flags |= REQ_SPECIAL | REQ_SOFTBARRIER;
+       rq->cmd_type = REQ_TYPE_SPECIAL;
+       rq->cmd_flags |= REQ_SOFTBARRIER;
 
        rq->special = data;
 
@@ -2366,11 +2357,7 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
 
        drive_stat_acct(rq, rq->nr_sectors, 1);
        __elv_add_request(q, rq, where, 0);
-
-       if (blk_queue_plugged(q))
-               __generic_unplug_device(q);
-       else
-               q->request_fn(q);
+       blk_start_queueing(q);
        spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
@@ -2559,7 +2546,7 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
        int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
 
        rq->rq_disk = bd_disk;
-       rq->flags |= REQ_NOMERGE;
+       rq->cmd_flags |= REQ_NOMERGE;
        rq->end_io = done;
        WARN_ON(irqs_disabled());
        spin_lock_irq(q->queue_lock);
@@ -2599,10 +2586,9 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
                rq->sense_len = 0;
        }
 
-       rq->waiting = &wait;
+       rq->end_io_data = &wait;
        blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
        wait_for_completion(&wait);
-       rq->waiting = NULL;
 
        if (rq->errors)
                err = -EIO;
@@ -2711,8 +2697,6 @@ EXPORT_SYMBOL_GPL(disk_round_stats);
  */
 void __blk_put_request(request_queue_t *q, struct request *req)
 {
-       struct request_list *rl = req->rl;
-
        if (unlikely(!q))
                return;
        if (unlikely(--req->ref_count))
@@ -2720,18 +2704,16 @@ void __blk_put_request(request_queue_t *q, struct request *req)
 
        elv_completed_request(q, req);
 
-       req->rq_status = RQ_INACTIVE;
-       req->rl = NULL;
-
        /*
         * Request may not have originated from ll_rw_blk. if not,
         * it didn't come out of our reserved rq pools
         */
-       if (rl) {
+       if (req->cmd_flags & REQ_ALLOCED) {
                int rw = rq_data_dir(req);
-               int priv = req->flags & REQ_ELVPRIV;
+               int priv = req->cmd_flags & REQ_ELVPRIV;
 
                BUG_ON(!list_empty(&req->queuelist));
+               BUG_ON(!hlist_unhashed(&req->hash));
 
                blk_free_request(q, req);
                freed_request(q, rw, priv);
@@ -2765,9 +2747,9 @@ EXPORT_SYMBOL(blk_put_request);
  */
 void blk_end_sync_rq(struct request *rq, int error)
 {
-       struct completion *waiting = rq->waiting;
+       struct completion *waiting = rq->end_io_data;
 
-       rq->waiting = NULL;
+       rq->end_io_data = NULL;
        __blk_put_request(rq->q, rq);
 
        /*
@@ -2830,7 +2812,7 @@ static int attempt_merge(request_queue_t *q, struct request *req,
 
        if (rq_data_dir(req) != rq_data_dir(next)
            || req->rq_disk != next->rq_disk
-           || next->waiting || next->special)
+           || next->special)
                return 0;
 
        /*
@@ -2891,22 +2873,24 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq)
 
 static void init_request_from_bio(struct request *req, struct bio *bio)
 {
-       req->flags |= REQ_CMD;
+       req->cmd_type = REQ_TYPE_FS;
 
        /*
         * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
         */
        if (bio_rw_ahead(bio) || bio_failfast(bio))
-               req->flags |= REQ_FAILFAST;
+               req->cmd_flags |= REQ_FAILFAST;
 
        /*
         * REQ_BARRIER implies no merging, but lets make it explicit
         */
        if (unlikely(bio_barrier(bio)))
-               req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
+               req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
 
        if (bio_sync(bio))
-               req->flags |= REQ_RW_SYNC;
+               req->cmd_flags |= REQ_RW_SYNC;
+       if (bio_rw_meta(bio))
+               req->cmd_flags |= REQ_RW_META;
 
        req->errors = 0;
        req->hard_sector = req->sector = bio->bi_sector;
@@ -2915,7 +2899,6 @@ static void init_request_from_bio(struct request *req, struct bio *bio)
        req->nr_phys_segments = bio_phys_segments(req->q, bio);
        req->nr_hw_segments = bio_hw_segments(req->q, bio);
        req->buffer = bio_data(bio);    /* see ->buffer comment above */
-       req->waiting = NULL;
        req->bio = req->biotail = bio;
        req->ioprio = bio_prio(bio);
        req->rq_disk = bio->bi_bdev->bd_disk;
@@ -2925,17 +2908,11 @@ static void init_request_from_bio(struct request *req, struct bio *bio)
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
        struct request *req;
-       int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
-       unsigned short prio;
-       sector_t sector;
+       int el_ret, nr_sectors, barrier, err;
+       const unsigned short prio = bio_prio(bio);
+       const int sync = bio_sync(bio);
 
-       sector = bio->bi_sector;
        nr_sectors = bio_sectors(bio);
-       cur_nr_sectors = bio_cur_sectors(bio);
-       prio = bio_prio(bio);
-
-       rw = bio_data_dir(bio);
-       sync = bio_sync(bio);
 
        /*
         * low level driver can indicate that it wants pages above a
@@ -2944,8 +2921,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
         */
        blk_queue_bounce(q, &bio);
 
-       spin_lock_prefetch(q->queue_lock);
-
        barrier = bio_barrier(bio);
        if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) {
                err = -EOPNOTSUPP;
@@ -2973,7 +2948,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
                        req->ioprio = ioprio_best(req->ioprio, prio);
                        drive_stat_acct(req, nr_sectors, 0);
                        if (!attempt_back_merge(q, req))
-                               elv_merged_request(q, req);
+                               elv_merged_request(q, req, el_ret);
                        goto out;
 
                case ELEVATOR_FRONT_MERGE:
@@ -2993,14 +2968,14 @@ static int __make_request(request_queue_t *q, struct bio *bio)
                         * not touch req->buffer either...
                         */
                        req->buffer = bio_data(bio);
-                       req->current_nr_sectors = cur_nr_sectors;
-                       req->hard_cur_sectors = cur_nr_sectors;
-                       req->sector = req->hard_sector = sector;
+                       req->current_nr_sectors = bio_cur_sectors(bio);
+                       req->hard_cur_sectors = req->current_nr_sectors;
+                       req->sector = req->hard_sector = bio->bi_sector;
                        req->nr_sectors = req->hard_nr_sectors += nr_sectors;
                        req->ioprio = ioprio_best(req->ioprio, prio);
                        drive_stat_acct(req, nr_sectors, 0);
                        if (!attempt_front_merge(q, req))
-                               elv_merged_request(q, req);
+                               elv_merged_request(q, req, el_ret);
                        goto out;
 
                /* ELV_NO_MERGE: elevator says don't/can't merge. */
@@ -3013,7 +2988,7 @@ get_rq:
         * Grab a free request. This is might sleep but can not fail.
         * Returns with the queue unlocked.
         */
-       req = get_request_wait(q, rw, bio);
+       req = get_request_wait(q, bio_data_dir(bio), bio);
 
        /*
         * After dropping the lock and possibly sleeping here, our request
@@ -3307,7 +3282,7 @@ static int __end_that_request_first(struct request *req, int uptodate,
                req->errors = 0;
 
        if (!uptodate) {
-               if (blk_fs_request(req) && !(req->flags & REQ_QUIET))
+               if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))
                        printk("end_request: I/O error, dev %s, sector %llu\n",
                                req->rq_disk ? req->rq_disk->disk_name : "?",
                                (unsigned long long)req->sector);
@@ -3570,8 +3545,8 @@ EXPORT_SYMBOL(end_request);
 
 void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio)
 {
-       /* first two bits are identical in rq->flags and bio->bi_rw */
-       rq->flags |= (bio->bi_rw & 3);
+       /* first two bits are identical in rq->cmd_flags and bio->bi_rw */
+       rq->cmd_flags |= (bio->bi_rw & 3);
 
        rq->nr_phys_segments = bio_phys_segments(q, bio);
        rq->nr_hw_segments = bio_hw_segments(q, bio);
@@ -3659,25 +3634,22 @@ EXPORT_SYMBOL(put_io_context);
 /* Called by the exitting task */
 void exit_io_context(void)
 {
-       unsigned long flags;
        struct io_context *ioc;
        struct cfq_io_context *cic;
 
-       local_irq_save(flags);
        task_lock(current);
        ioc = current->io_context;
        current->io_context = NULL;
-       ioc->task = NULL;
        task_unlock(current);
-       local_irq_restore(flags);
 
+       ioc->task = NULL;
        if (ioc->aic && ioc->aic->exit)
                ioc->aic->exit(ioc->aic);
        if (ioc->cic_root.rb_node != NULL) {
                cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node);
                cic->exit(ioc);
        }
+
        put_io_context(ioc);
 }
 
@@ -3689,7 +3661,7 @@ void exit_io_context(void)
  * but since the current task itself holds a reference, the context can be
  * used in general code, so long as it stays within `current` context.
  */
-struct io_context *current_io_context(gfp_t gfp_flags)
+static struct io_context *current_io_context(gfp_t gfp_flags, int node)
 {
        struct task_struct *tsk = current;
        struct io_context *ret;
@@ -3698,11 +3670,11 @@ struct io_context *current_io_context(gfp_t gfp_flags)
        if (likely(ret))
                return ret;
 
-       ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
+       ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node);
        if (ret) {
                atomic_set(&ret->refcount, 1);
                ret->task = current;
-               ret->set_ioprio = NULL;
+               ret->ioprio_changed = 0;
                ret->last_waited = jiffies; /* doesn't matter... */
                ret->nr_batch_requests = 0; /* because this is 0 */
                ret->aic = NULL;
@@ -3722,10 +3694,10 @@ EXPORT_SYMBOL(current_io_context);
  *
  * This is always called in the context of the task which submitted the I/O.
  */
-struct io_context *get_io_context(gfp_t gfp_flags)
+struct io_context *get_io_context(gfp_t gfp_flags, int node)
 {
        struct io_context *ret;
-       ret = current_io_context(gfp_flags);
+       ret = current_io_context(gfp_flags, node);
        if (likely(ret))
                atomic_inc(&ret->refcount);
        return ret;
@@ -3838,9 +3810,6 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count)
        ssize_t ret = queue_var_store(&ra_kb, page, count);
 
        spin_lock_irq(q->queue_lock);
-       if (ra_kb > (q->max_sectors >> 1))
-               ra_kb = (q->max_sectors >> 1);
-
        q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
        spin_unlock_irq(q->queue_lock);
 
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 b06b0e2b9c62b536a321d12295988af5801012b3..b32b77ff2dcd7c1814c66318a477b74840b88e2f 100644 (file)
@@ -228,7 +228,7 @@ error:
 
 /**
  * class_destroy - destroys a struct class structure
- * @cs: pointer to the struct class that is to be destroyed
+ * @cls: pointer to the struct class that is to be destroyed
  *
  * Note, the pointer to be destroyed must have been created with a call
  * to class_create().
@@ -658,9 +658,9 @@ int class_device_register(struct class_device *class_dev)
 
 /**
  * class_device_create - creates a class device and registers it with sysfs
- * @cs: pointer to the struct class that this device should be registered to.
+ * @cls: pointer to the struct class that this device should be registered to.
  * @parent: pointer to the parent struct class_device of this new device, if any.
- * @dev: the dev_t for the char device to be added.
+ * @devt: the dev_t for the char device to be added.
  * @device: a pointer to a struct device that is assiociated with this class device.
  * @fmt: string for the class device's name
  *
@@ -766,7 +766,7 @@ void class_device_unregister(struct class_device *class_dev)
 /**
  * class_device_destroy - removes a class device that was created with class_device_create()
  * @cls: the pointer to the struct class that this device was registered * with.
- * @dev: the dev_t of the device that was previously registered.
+ * @devt: the dev_t of the device that was previously registered.
  *
  * This call unregisters and cleans up a class device that was created with a
  * call to class_device_create()
index 77bf8826e2f97b9d19cfaad6457df1371e660262..14615694ae9aa3e707435f2f04a1c6dde4586c5c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
+#include <linux/kthread.h>
 
 #include <linux/firmware.h>
 #include "base.h"
@@ -511,7 +512,6 @@ request_firmware_work_func(void *arg)
                WARN_ON(1);
                return 0;
        }
-       daemonize("%s/%s", "firmware", fw_work->name);
        ret = _request_firmware(&fw, fw_work->name, fw_work->device,
                fw_work->uevent);
        if (ret < 0)
@@ -546,9 +546,9 @@ request_firmware_nowait(
        const char *name, struct device *device, void *context,
        void (*cont)(const struct firmware *fw, void *context))
 {
+       struct task_struct *task;
        struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
                                                GFP_ATOMIC);
-       int ret;
 
        if (!fw_work)
                return -ENOMEM;
@@ -566,14 +566,14 @@ request_firmware_nowait(
                .uevent = uevent,
        };
 
-       ret = kernel_thread(request_firmware_work_func, fw_work,
-                           CLONE_FS | CLONE_FILES);
+       task = kthread_run(request_firmware_work_func, fw_work,
+                           "firmware/%s", name);
 
-       if (ret < 0) {
+       if (IS_ERR(task)) {
                fw_work->cont(NULL, fw_work->context);
                module_put(fw_work->module);
                kfree(fw_work);
-               return ret;
+               return PTR_ERR(task);
        }
        return 0;
 }
index a360215dbce79cc1ff85f4b03651000ae17436b0..2568640430fb06e927d41f67918eb29a46d7163d 100644 (file)
@@ -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 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..c211065ad8294cc337711aea863f4df6f8d1bbc0 100644 (file)
@@ -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;
        }
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 c774121684d7f8951ff8b0acafef0e74ce11e23d..d6bb8da955a213c0c192dd3272ea435393a0a180 100644 (file)
 #include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/loop.h>
+#include <linux/compat.h>
 #include <linux/suspend.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>         /* for invalidate_bdev() */
 #include <linux/completion.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
+#include <linux/kthread.h>
 
 #include <asm/uaccess.h>
 
@@ -522,15 +524,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
                goto out;
        if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
                goto out;
-       lo->lo_pending++;
        loop_add_bio(lo, old_bio);
+       wake_up(&lo->lo_event);
        spin_unlock_irq(&lo->lo_lock);
-       complete(&lo->lo_bh_done);
        return 0;
 
 out:
-       if (lo->lo_pending == 0)
-               complete(&lo->lo_bh_done);
        spin_unlock_irq(&lo->lo_lock);
        bio_io_error(old_bio, old_bio->bi_size);
        return 0;
@@ -570,14 +569,18 @@ static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
  * to avoid blocking in our make_request_fn. it also does loop decrypting
  * on reads for block backed loop, as that is too heavy to do from
  * b_end_io context where irqs may be disabled.
+ *
+ * Loop explanation:  loop_clr_fd() sets lo_state to Lo_rundown before
+ * calling kthread_stop().  Therefore once kthread_should_stop() is
+ * true, make_request will not place any more requests.  Therefore
+ * once kthread_should_stop() is true and lo_bio is NULL, we are
+ * done with the loop.
  */
 static int loop_thread(void *data)
 {
        struct loop_device *lo = data;
        struct bio *bio;
 
-       daemonize("loop%d", lo->lo_number);
-
        /*
         * loop can be used in an encrypted device,
         * hence, it mustn't be stopped at all
@@ -587,47 +590,21 @@ static int loop_thread(void *data)
 
        set_user_nice(current, -20);
 
-       lo->lo_state = Lo_bound;
-       lo->lo_pending = 1;
+       while (!kthread_should_stop() || lo->lo_bio) {
 
-       /*
-        * complete it, we are running
-        */
-       complete(&lo->lo_done);
-
-       for (;;) {
-               int pending;
+               wait_event_interruptible(lo->lo_event,
+                               lo->lo_bio || kthread_should_stop());
 
-               if (wait_for_completion_interruptible(&lo->lo_bh_done))
+               if (!lo->lo_bio)
                        continue;
-
                spin_lock_irq(&lo->lo_lock);
-
-               /*
-                * could be completed because of tear-down, not pending work
-                */
-               if (unlikely(!lo->lo_pending)) {
-                       spin_unlock_irq(&lo->lo_lock);
-                       break;
-               }
-
                bio = loop_get_bio(lo);
-               lo->lo_pending--;
-               pending = lo->lo_pending;
                spin_unlock_irq(&lo->lo_lock);
 
                BUG_ON(!bio);
                loop_handle_bio(lo, bio);
-
-               /*
-                * upped both for pending work and tear-down, lo_pending
-                * will hit zero then
-                */
-               if (unlikely(!pending))
-                       break;
        }
 
-       complete(&lo->lo_done);
        return 0;
 }
 
@@ -840,12 +817,26 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
 
        set_blocksize(bdev, lo_blocksize);
 
-       error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
-       if (error < 0)
-               goto out_putf;
-       wait_for_completion(&lo->lo_done);
+       lo->lo_thread = kthread_create(loop_thread, lo, "loop%d",
+                                               lo->lo_number);
+       if (IS_ERR(lo->lo_thread)) {
+               error = PTR_ERR(lo->lo_thread);
+               goto out_clr;
+       }
+       lo->lo_state = Lo_bound;
+       wake_up_process(lo->lo_thread);
        return 0;
 
+out_clr:
+       lo->lo_thread = NULL;
+       lo->lo_device = NULL;
+       lo->lo_backing_file = NULL;
+       lo->lo_flags = 0;
+       set_capacity(disks[lo->lo_number], 0);
+       invalidate_bdev(bdev, 0);
+       bd_set_size(bdev, 0);
+       mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
+       lo->lo_state = Lo_unbound;
  out_putf:
        fput(file);
  out:
@@ -907,12 +898,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
 
        spin_lock_irq(&lo->lo_lock);
        lo->lo_state = Lo_rundown;
-       lo->lo_pending--;
-       if (!lo->lo_pending)
-               complete(&lo->lo_bh_done);
        spin_unlock_irq(&lo->lo_lock);
 
-       wait_for_completion(&lo->lo_done);
+       kthread_stop(lo->lo_thread);
 
        lo->lo_backing_file = NULL;
 
@@ -925,6 +913,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        lo->lo_sizelimit = 0;
        lo->lo_encrypt_key_size = 0;
        lo->lo_flags = 0;
+       lo->lo_thread = NULL;
        memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
        memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
        memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1177,6 +1166,162 @@ static int lo_ioctl(struct inode * inode, struct file * file,
        return err;
 }
 
+#ifdef CONFIG_COMPAT
+struct compat_loop_info {
+       compat_int_t    lo_number;      /* ioctl r/o */
+       compat_dev_t    lo_device;      /* ioctl r/o */
+       compat_ulong_t  lo_inode;       /* ioctl r/o */
+       compat_dev_t    lo_rdevice;     /* ioctl r/o */
+       compat_int_t    lo_offset;
+       compat_int_t    lo_encrypt_type;
+       compat_int_t    lo_encrypt_key_size;    /* ioctl w/o */
+       compat_int_t    lo_flags;       /* ioctl r/o */
+       char            lo_name[LO_NAME_SIZE];
+       unsigned char   lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+       compat_ulong_t  lo_init[2];
+       char            reserved[4];
+};
+
+/*
+ * Transfer 32-bit compatibility structure in userspace to 64-bit loop info
+ * - noinlined to reduce stack space usage in main part of driver
+ */
+static noinline int
+loop_info64_from_compat(const struct compat_loop_info *arg,
+                       struct loop_info64 *info64)
+{
+       struct compat_loop_info info;
+
+       if (copy_from_user(&info, arg, sizeof(info)))
+               return -EFAULT;
+
+       memset(info64, 0, sizeof(*info64));
+       info64->lo_number = info.lo_number;
+       info64->lo_device = info.lo_device;
+       info64->lo_inode = info.lo_inode;
+       info64->lo_rdevice = info.lo_rdevice;
+       info64->lo_offset = info.lo_offset;
+       info64->lo_sizelimit = 0;
+       info64->lo_encrypt_type = info.lo_encrypt_type;
+       info64->lo_encrypt_key_size = info.lo_encrypt_key_size;
+       info64->lo_flags = info.lo_flags;
+       info64->lo_init[0] = info.lo_init[0];
+       info64->lo_init[1] = info.lo_init[1];
+       if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
+               memcpy(info64->lo_crypt_name, info.lo_name, LO_NAME_SIZE);
+       else
+               memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE);
+       memcpy(info64->lo_encrypt_key, info.lo_encrypt_key, LO_KEY_SIZE);
+       return 0;
+}
+
+/*
+ * Transfer 64-bit loop info to 32-bit compatibility structure in userspace
+ * - noinlined to reduce stack space usage in main part of driver
+ */
+static noinline int
+loop_info64_to_compat(const struct loop_info64 *info64,
+                     struct compat_loop_info __user *arg)
+{
+       struct compat_loop_info info;
+
+       memset(&info, 0, sizeof(info));
+       info.lo_number = info64->lo_number;
+       info.lo_device = info64->lo_device;
+       info.lo_inode = info64->lo_inode;
+       info.lo_rdevice = info64->lo_rdevice;
+       info.lo_offset = info64->lo_offset;
+       info.lo_encrypt_type = info64->lo_encrypt_type;
+       info.lo_encrypt_key_size = info64->lo_encrypt_key_size;
+       info.lo_flags = info64->lo_flags;
+       info.lo_init[0] = info64->lo_init[0];
+       info.lo_init[1] = info64->lo_init[1];
+       if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
+               memcpy(info.lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
+       else
+               memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE);
+       memcpy(info.lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
+
+       /* error in case values were truncated */
+       if (info.lo_device != info64->lo_device ||
+           info.lo_rdevice != info64->lo_rdevice ||
+           info.lo_inode != info64->lo_inode ||
+           info.lo_offset != info64->lo_offset ||
+           info.lo_init[0] != info64->lo_init[0] ||
+           info.lo_init[1] != info64->lo_init[1])
+               return -EOVERFLOW;
+
+       if (copy_to_user(arg, &info, sizeof(info)))
+               return -EFAULT;
+       return 0;
+}
+
+static int
+loop_set_status_compat(struct loop_device *lo,
+                      const struct compat_loop_info __user *arg)
+{
+       struct loop_info64 info64;
+       int ret;
+
+       ret = loop_info64_from_compat(arg, &info64);
+       if (ret < 0)
+               return ret;
+       return loop_set_status(lo, &info64);
+}
+
+static int
+loop_get_status_compat(struct loop_device *lo,
+                      struct compat_loop_info __user *arg)
+{
+       struct loop_info64 info64;
+       int err = 0;
+
+       if (!arg)
+               err = -EINVAL;
+       if (!err)
+               err = loop_get_status(lo, &info64);
+       if (!err)
+               err = loop_info64_to_compat(&info64, arg);
+       return err;
+}
+
+static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+       int err;
+
+       lock_kernel();
+       switch(cmd) {
+       case LOOP_SET_STATUS:
+               mutex_lock(&lo->lo_ctl_mutex);
+               err = loop_set_status_compat(
+                       lo, (const struct compat_loop_info __user *) arg);
+               mutex_unlock(&lo->lo_ctl_mutex);
+               break;
+       case LOOP_GET_STATUS:
+               mutex_lock(&lo->lo_ctl_mutex);
+               err = loop_get_status_compat(
+                       lo, (struct compat_loop_info __user *) arg);
+               mutex_unlock(&lo->lo_ctl_mutex);
+               break;
+       case LOOP_CLR_FD:
+       case LOOP_GET_STATUS64:
+       case LOOP_SET_STATUS64:
+               arg = (unsigned long) compat_ptr(arg);
+       case LOOP_SET_FD:
+       case LOOP_CHANGE_FD:
+               err = lo_ioctl(inode, file, cmd, arg);
+               break;
+       default:
+               err = -ENOIOCTLCMD;
+               break;
+       }
+       unlock_kernel();
+       return err;
+}
+#endif
+
 static int lo_open(struct inode *inode, struct file *file)
 {
        struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1204,6 +1349,9 @@ static struct block_device_operations lo_fops = {
        .open =         lo_open,
        .release =      lo_release,
        .ioctl =        lo_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = lo_compat_ioctl,
+#endif
 };
 
 /*
@@ -1287,9 +1435,9 @@ static int __init loop_init(void)
                if (!lo->lo_queue)
                        goto out_mem4;
                mutex_init(&lo->lo_ctl_mutex);
-               init_completion(&lo->lo_done);
-               init_completion(&lo->lo_bh_done);
                lo->lo_number = i;
+               lo->lo_thread = NULL;
+               init_waitqueue_head(&lo->lo_event);
                spin_lock_init(&lo->lo_lock);
                disk->major = LOOP_MAJOR;
                disk->first_minor = i;
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..38578b9dbfd1a2bf137dab3c76b6d6235148a82f 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();
        }
@@ -719,14 +719,12 @@ static int pd_special_command(struct pd_unit *disk,
 
        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..888d1aceeeff4084e1b48eff355cac3bdabedcd7 100644 (file)
@@ -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 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 23f96213f4acad7e9c5f72b51e1e392e22a208c8..efcc28ec9d9a2a1b719fc8e5a5e87d527a71ab20 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  AVM BlueFRITZ! USB driver
  *
- *  Copyright (C) 2003  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2003-2006  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -59,7 +59,6 @@ static struct usb_device_id bfusb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, bfusb_table);
 
-
 #define BFUSB_MAX_BLOCK_SIZE   256
 
 #define BFUSB_BLOCK_TIMEOUT    3000
@@ -70,7 +69,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table);
 #define BFUSB_MAX_BULK_TX      2
 #define BFUSB_MAX_BULK_RX      2
 
-struct bfusb {
+struct bfusb_data {
        struct hci_dev          *hdev;
 
        unsigned long           state;
@@ -92,137 +91,136 @@ struct bfusb {
        struct sk_buff_head     completed_q;
 };
 
-struct bfusb_scb {
+struct bfusb_data_scb {
        struct urb *urb;
 };
 
 static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
 static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
 
-static struct urb *bfusb_get_completed(struct bfusb *bfusb)
+static struct urb *bfusb_get_completed(struct bfusb_data *data)
 {
        struct sk_buff *skb;
        struct urb *urb = NULL;
 
-       BT_DBG("bfusb %p", bfusb);
+       BT_DBG("bfusb %p", data);
 
-       skb = skb_dequeue(&bfusb->completed_q);
+       skb = skb_dequeue(&data->completed_q);
        if (skb) {
-               urb = ((struct bfusb_scb *) skb->cb)->urb;
+               urb = ((struct bfusb_data_scb *) skb->cb)->urb;
                kfree_skb(skb);
        }
 
        return urb;
 }
 
-static void bfusb_unlink_urbs(struct bfusb *bfusb)
+static void bfusb_unlink_urbs(struct bfusb_data *data)
 {
        struct sk_buff *skb;
        struct urb *urb;
 
-       BT_DBG("bfusb %p", bfusb);
+       BT_DBG("bfusb %p", data);
 
-       while ((skb = skb_dequeue(&bfusb->pending_q))) {
-               urb = ((struct bfusb_scb *) skb->cb)->urb;
+       while ((skb = skb_dequeue(&data->pending_q))) {
+               urb = ((struct bfusb_data_scb *) skb->cb)->urb;
                usb_kill_urb(urb);
-               skb_queue_tail(&bfusb->completed_q, skb);
+               skb_queue_tail(&data->completed_q, skb);
        }
 
-       while ((urb = bfusb_get_completed(bfusb)))
+       while ((urb = bfusb_get_completed(data)))
                usb_free_urb(urb);
 }
 
-
-static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
+static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)
 {
-       struct bfusb_scb *scb = (void *) skb->cb;
-       struct urb *urb = bfusb_get_completed(bfusb);
+       struct bfusb_data_scb *scb = (void *) skb->cb;
+       struct urb *urb = bfusb_get_completed(data);
        int err, pipe;
 
-       BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
+       BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);
 
        if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
                return -ENOMEM;
 
-       pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
 
-       usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len,
+       usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,
                        bfusb_tx_complete, skb);
 
        scb->urb = urb;
 
-       skb_queue_tail(&bfusb->pending_q, skb);
+       skb_queue_tail(&data->pending_q, skb);
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk tx submit failed urb %p err %d", 
-                                       bfusb->hdev->name, urb, err);
-               skb_unlink(skb, &bfusb->pending_q);
+                                       data->hdev->name, urb, err);
+               skb_unlink(skb, &data->pending_q);
                usb_free_urb(urb);
        } else
-               atomic_inc(&bfusb->pending_tx);
+               atomic_inc(&data->pending_tx);
 
        return err;
 }
 
-static void bfusb_tx_wakeup(struct bfusb *bfusb)
+static void bfusb_tx_wakeup(struct bfusb_data *data)
 {
        struct sk_buff *skb;
 
-       BT_DBG("bfusb %p", bfusb);
+       BT_DBG("bfusb %p", data);
 
-       if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
-               set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
+       if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {
+               set_bit(BFUSB_TX_WAKEUP, &data->state);
                return;
        }
 
        do {
-               clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
+               clear_bit(BFUSB_TX_WAKEUP, &data->state);
 
-               while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
-                               (skb = skb_dequeue(&bfusb->transmit_q))) {
-                       if (bfusb_send_bulk(bfusb, skb) < 0) {
-                               skb_queue_head(&bfusb->transmit_q, skb);
+               while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) &&
+                               (skb = skb_dequeue(&data->transmit_q))) {
+                       if (bfusb_send_bulk(data, skb) < 0) {
+                               skb_queue_head(&data->transmit_q, skb);
                                break;
                        }
                }
 
-       } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
+       } while (test_bit(BFUSB_TX_WAKEUP, &data->state));
 
-       clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
+       clear_bit(BFUSB_TX_PROCESS, &data->state);
 }
 
 static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
-       struct bfusb *bfusb = (struct bfusb *) skb->dev;
+       struct bfusb_data *data = (struct bfusb_data *) skb->dev;
 
-       BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
+       BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);
 
-       atomic_dec(&bfusb->pending_tx);
+       atomic_dec(&data->pending_tx);
 
-       if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
+       if (!test_bit(HCI_RUNNING, &data->hdev->flags))
                return;
 
        if (!urb->status)
-               bfusb->hdev->stat.byte_tx += skb->len;
+               data->hdev->stat.byte_tx += skb->len;
        else
-               bfusb->hdev->stat.err_tx++;
+               data->hdev->stat.err_tx++;
 
-       read_lock(&bfusb->lock);
+       read_lock(&data->lock);
 
-       skb_unlink(skb, &bfusb->pending_q);
-       skb_queue_tail(&bfusb->completed_q, skb);
+       skb_unlink(skb, &data->pending_q);
+       skb_queue_tail(&data->completed_q, skb);
 
-       bfusb_tx_wakeup(bfusb);
+       bfusb_tx_wakeup(data);
 
-       read_unlock(&bfusb->lock);
+       read_unlock(&data->lock);
 }
 
 
-static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
+static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)
 {
-       struct bfusb_scb *scb;
+       struct bfusb_data_scb *scb;
        struct sk_buff *skb;
        int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
 
@@ -231,28 +229,29 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
        if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
                return -ENOMEM;
 
-       if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) {
+       skb = bt_skb_alloc(size, GFP_ATOMIC);
+       if (!skb) {
                usb_free_urb(urb);
                return -ENOMEM;
        }
 
-       skb->dev = (void *) bfusb;
+       skb->dev = (void *) data;
 
-       scb = (struct bfusb_scb *) skb->cb;
+       scb = (struct bfusb_data_scb *) skb->cb;
        scb->urb = urb;
 
-       pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
+       pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep);
 
-       usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size,
+       usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,
                        bfusb_rx_complete, skb);
 
-       skb_queue_tail(&bfusb->pending_q, skb);
+       skb_queue_tail(&data->pending_q, skb);
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk rx submit failed urb %p err %d",
-                                       bfusb->hdev->name, urb, err);
-               skb_unlink(skb, &bfusb->pending_q);
+                                       data->hdev->name, urb, err);
+               skb_unlink(skb, &data->pending_q);
                kfree_skb(skb);
                usb_free_urb(urb);
        }
@@ -260,15 +259,15 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
        return err;
 }
 
-static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
+static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)
 {
-       BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
+       BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);
 
        if (hdr & 0x10) {
-               BT_ERR("%s error in block", bfusb->hdev->name);
-               if (bfusb->reassembly)
-                       kfree_skb(bfusb->reassembly);
-               bfusb->reassembly = NULL;
+               BT_ERR("%s error in block", data->hdev->name);
+               if (data->reassembly)
+                       kfree_skb(data->reassembly);
+               data->reassembly = NULL;
                return -EIO;
        }
 
@@ -277,46 +276,46 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                unsigned char pkt_type;
                int pkt_len = 0;
 
-               if (bfusb->reassembly) {
-                       BT_ERR("%s unexpected start block", bfusb->hdev->name);
-                       kfree_skb(bfusb->reassembly);
-                       bfusb->reassembly = NULL;
+               if (data->reassembly) {
+                       BT_ERR("%s unexpected start block", data->hdev->name);
+                       kfree_skb(data->reassembly);
+                       data->reassembly = NULL;
                }
 
                if (len < 1) {
-                       BT_ERR("%s no packet type found", bfusb->hdev->name);
+                       BT_ERR("%s no packet type found", data->hdev->name);
                        return -EPROTO;
                }
 
-               pkt_type = *data++; len--;
+               pkt_type = *buf++; len--;
 
                switch (pkt_type) {
                case HCI_EVENT_PKT:
                        if (len >= HCI_EVENT_HDR_SIZE) {
-                               struct hci_event_hdr *hdr = (struct hci_event_hdr *) data;
+                               struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf;
                                pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
                        } else {
-                               BT_ERR("%s event block is too short", bfusb->hdev->name);
+                               BT_ERR("%s event block is too short", data->hdev->name);
                                return -EILSEQ;
                        }
                        break;
 
                case HCI_ACLDATA_PKT:
                        if (len >= HCI_ACL_HDR_SIZE) {
-                               struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data;
+                               struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf;
                                pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
                        } else {
-                               BT_ERR("%s data block is too short", bfusb->hdev->name);
+                               BT_ERR("%s data block is too short", data->hdev->name);
                                return -EILSEQ;
                        }
                        break;
 
                case HCI_SCODATA_PKT:
                        if (len >= HCI_SCO_HDR_SIZE) {
-                               struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data;
+                               struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf;
                                pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
                        } else {
-                               BT_ERR("%s audio block is too short", bfusb->hdev->name);
+                               BT_ERR("%s audio block is too short", data->hdev->name);
                                return -EILSEQ;
                        }
                        break;
@@ -324,27 +323,27 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
 
                skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
                if (!skb) {
-                       BT_ERR("%s no memory for the packet", bfusb->hdev->name);
+                       BT_ERR("%s no memory for the packet", data->hdev->name);
                        return -ENOMEM;
                }
 
-               skb->dev = (void *) bfusb->hdev;
+               skb->dev = (void *) data->hdev;
                bt_cb(skb)->pkt_type = pkt_type;
 
-               bfusb->reassembly = skb;
+               data->reassembly = skb;
        } else {
-               if (!bfusb->reassembly) {
-                       BT_ERR("%s unexpected continuation block", bfusb->hdev->name);
+               if (!data->reassembly) {
+                       BT_ERR("%s unexpected continuation block", data->hdev->name);
                        return -EIO;
                }
        }
 
        if (len > 0)
-               memcpy(skb_put(bfusb->reassembly, len), data, len);
+               memcpy(skb_put(data->reassembly, len), buf, len);
 
        if (hdr & 0x08) {
-               hci_recv_frame(bfusb->reassembly);
-               bfusb->reassembly = NULL;
+               hci_recv_frame(data->reassembly);
+               data->reassembly = NULL;
        }
 
        return 0;
@@ -353,22 +352,22 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
 static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
-       struct bfusb *bfusb = (struct bfusb *) skb->dev;
+       struct bfusb_data *data = (struct bfusb_data *) skb->dev;
        unsigned char *buf = urb->transfer_buffer;
        int count = urb->actual_length;
        int err, hdr, len;
 
        BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
 
-       read_lock(&bfusb->lock);
+       read_lock(&data->lock);
 
-       if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags))
+       if (!test_bit(HCI_RUNNING, &data->hdev->flags))
                goto unlock;
 
        if (urb->status || !count)
                goto resubmit;
 
-       bfusb->hdev->stat.byte_rx += count;
+       data->hdev->stat.byte_rx += count;
 
        skb_put(skb, count);
 
@@ -387,90 +386,89 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
 
                if (count < len) {
                        BT_ERR("%s block extends over URB buffer ranges",
-                                       bfusb->hdev->name);
+                                       data->hdev->name);
                }
 
                if ((hdr & 0xe1) == 0xc1)
-                       bfusb_recv_block(bfusb, hdr, buf, len);
+                       bfusb_recv_block(data, hdr, buf, len);
 
                count -= len;
                buf   += len;
        }
 
-       skb_unlink(skb, &bfusb->pending_q);
+       skb_unlink(skb, &data->pending_q);
        kfree_skb(skb);
 
-       bfusb_rx_submit(bfusb, urb);
+       bfusb_rx_submit(data, urb);
 
-       read_unlock(&bfusb->lock);
+       read_unlock(&data->lock);
 
        return;
 
 resubmit:
-       urb->dev = bfusb->udev;
+       urb->dev = data->udev;
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
                BT_ERR("%s bulk resubmit failed urb %p err %d",
-                                       bfusb->hdev->name, urb, err);
+                                       data->hdev->name, urb, err);
        }
 
 unlock:
-       read_unlock(&bfusb->lock);
+       read_unlock(&data->lock);
 }
 
-
 static int bfusb_open(struct hci_dev *hdev)
 {
-       struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+       struct bfusb_data *data = hdev->driver_data;
        unsigned long flags;
        int i, err;
 
-       BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+       BT_DBG("hdev %p bfusb %p", hdev, data);
 
        if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
-       write_lock_irqsave(&bfusb->lock, flags);
+       write_lock_irqsave(&data->lock, flags);
 
-       err = bfusb_rx_submit(bfusb, NULL);
+       err = bfusb_rx_submit(data, NULL);
        if (!err) {
                for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
-                       bfusb_rx_submit(bfusb, NULL);
+                       bfusb_rx_submit(data, NULL);
        } else {
                clear_bit(HCI_RUNNING, &hdev->flags);
        }
 
-       write_unlock_irqrestore(&bfusb->lock, flags);
+       write_unlock_irqrestore(&data->lock, flags);
 
        return err;
 }
 
 static int bfusb_flush(struct hci_dev *hdev)
 {
-       struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+       struct bfusb_data *data = hdev->driver_data;
 
-       BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+       BT_DBG("hdev %p bfusb %p", hdev, data);
 
-       skb_queue_purge(&bfusb->transmit_q);
+       skb_queue_purge(&data->transmit_q);
 
        return 0;
 }
 
 static int bfusb_close(struct hci_dev *hdev)
 {
-       struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+       struct bfusb_data *data = hdev->driver_data;
        unsigned long flags;
 
-       BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+       BT_DBG("hdev %p bfusb %p", hdev, data);
 
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
-       write_lock_irqsave(&bfusb->lock, flags);
-       write_unlock_irqrestore(&bfusb->lock, flags);
+       write_lock_irqsave(&data->lock, flags);
+       write_unlock_irqrestore(&data->lock, flags);
 
-       bfusb_unlink_urbs(bfusb);
+       bfusb_unlink_urbs(data);
        bfusb_flush(hdev);
 
        return 0;
@@ -479,7 +477,7 @@ static int bfusb_close(struct hci_dev *hdev)
 static int bfusb_send_frame(struct sk_buff *skb)
 {
        struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-       struct bfusb *bfusb;
+       struct bfusb_data *data;
        struct sk_buff *nskb;
        unsigned char buf[3];
        int sent = 0, size, count;
@@ -494,7 +492,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return -EBUSY;
 
-       bfusb = (struct bfusb *) hdev->driver_data;
+       data = hdev->driver_data;
 
        switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
@@ -514,12 +512,13 @@ static int bfusb_send_frame(struct sk_buff *skb)
        count = skb->len;
 
        /* Max HCI frame size seems to be 1511 + 1 */
-       if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) {
+       nskb = bt_skb_alloc(count + 32, GFP_ATOMIC);
+       if (!nskb) {
                BT_ERR("Can't allocate memory for new packet");
                return -ENOMEM;
        }
 
-       nskb->dev = (void *) bfusb;
+       nskb->dev = (void *) data;
 
        while (count) {
                size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
@@ -536,18 +535,18 @@ static int bfusb_send_frame(struct sk_buff *skb)
        }
 
        /* Don't send frame with multiple size of bulk max packet */
-       if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
+       if ((nskb->len % data->bulk_pkt_size) == 0) {
                buf[0] = 0xdd;
                buf[1] = 0x00;
                memcpy(skb_put(nskb, 2), buf, 2);
        }
 
-       read_lock(&bfusb->lock);
+       read_lock(&data->lock);
 
-       skb_queue_tail(&bfusb->transmit_q, nskb);
-       bfusb_tx_wakeup(bfusb);
+       skb_queue_tail(&data->transmit_q, nskb);
+       bfusb_tx_wakeup(data);
 
-       read_unlock(&bfusb->lock);
+       read_unlock(&data->lock);
 
        kfree_skb(skb);
 
@@ -556,11 +555,11 @@ static int bfusb_send_frame(struct sk_buff *skb)
 
 static void bfusb_destruct(struct hci_dev *hdev)
 {
-       struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
+       struct bfusb_data *data = hdev->driver_data;
 
-       BT_DBG("hdev %p bfusb %p", hdev, bfusb);
+       BT_DBG("hdev %p bfusb %p", hdev, data);
 
-       kfree(bfusb);
+       kfree(data);
 }
 
 static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
@@ -568,25 +567,24 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg
        return -ENOIOCTLCMD;
 }
 
-
-static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
+static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count)
 {
        unsigned char *buf;
        int err, pipe, len, size, sent = 0;
 
-       BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev);
+       BT_DBG("bfusb %p udev %p", data, data->udev);
 
        BT_INFO("BlueFRITZ! USB loading firmware");
 
-       pipe = usb_sndctrlpipe(bfusb->udev, 0);
+       pipe = usb_sndctrlpipe(data->udev, 0);
 
-       if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
+       if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
                                0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
                BT_ERR("Can't change to loading configuration");
                return -EBUSY;
        }
 
-       bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+       data->udev->toggle[0] = data->udev->toggle[1] = 0;
 
        buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
        if (!buf) {
@@ -594,14 +592,14 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
                return -ENOMEM;
        }
 
-       pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
 
        while (count) {
                size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
 
                memcpy(buf, firmware + sent, size);
 
-               err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
+               err = usb_bulk_msg(data->udev, pipe, buf, size,
                                        &len, BFUSB_BLOCK_TIMEOUT);
 
                if (err || (len != size)) {
@@ -613,21 +611,23 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
                count -= size;
        }
 
-       if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
-                               &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
+       err = usb_bulk_msg(data->udev, pipe, NULL, 0,
+                                       &len, BFUSB_BLOCK_TIMEOUT);
+       if (err < 0) {
                BT_ERR("Error in null packet request");
                goto error;
        }
 
-       pipe = usb_sndctrlpipe(bfusb->udev, 0);
+       pipe = usb_sndctrlpipe(data->udev, 0);
 
-        if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-                               0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
+       err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
+                               0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+       if (err < 0) {
                BT_ERR("Can't change to running configuration");
                goto error;
        }
 
-       bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+       data->udev->toggle[0] = data->udev->toggle[1] = 0;
 
        BT_INFO("BlueFRITZ! USB device ready");
 
@@ -637,9 +637,9 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
 error:
        kfree(buf);
 
-       pipe = usb_sndctrlpipe(bfusb->udev, 0);
+       pipe = usb_sndctrlpipe(data->udev, 0);
 
-       usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
+       usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
                                0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
 
        return err;
@@ -652,7 +652,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        struct usb_host_endpoint *bulk_out_ep;
        struct usb_host_endpoint *bulk_in_ep;
        struct hci_dev *hdev;
-       struct bfusb *bfusb;
+       struct bfusb_data *data;
 
        BT_DBG("intf %p id %p", intf, id);
 
@@ -672,23 +672,24 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        }
 
        /* Initialize control structure and load firmware */
-       if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+       data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL);
+       if (!data) {
                BT_ERR("Can't allocate memory for control structure");
                goto done;
        }
 
-       bfusb->udev = udev;
-       bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
-       bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
-       bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
+       data->udev = udev;
+       data->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
+       data->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
+       data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
 
-       rwlock_init(&bfusb->lock);
+       rwlock_init(&data->lock);
 
-       bfusb->reassembly = NULL;
+       data->reassembly = NULL;
 
-       skb_queue_head_init(&bfusb->transmit_q);
-       skb_queue_head_init(&bfusb->pending_q);
-       skb_queue_head_init(&bfusb->completed_q);
+       skb_queue_head_init(&data->transmit_q);
+       skb_queue_head_init(&data->pending_q);
+       skb_queue_head_init(&data->completed_q);
 
        if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
                BT_ERR("Firmware request failed");
@@ -697,7 +698,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        BT_DBG("firmware data %p size %d", firmware->data, firmware->size);
 
-       if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
+       if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
                BT_ERR("Firmware loading failed");
                goto release;
        }
@@ -711,10 +712,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
                goto error;
        }
 
-       bfusb->hdev = hdev;
+       data->hdev = hdev;
 
        hdev->type = HCI_USB;
-       hdev->driver_data = bfusb;
+       hdev->driver_data = data;
        SET_HCIDEV_DEV(hdev, &intf->dev);
 
        hdev->open     = bfusb_open;
@@ -732,7 +733,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
                goto error;
        }
 
-       usb_set_intfdata(intf, bfusb);
+       usb_set_intfdata(intf, data);
 
        return 0;
 
@@ -740,7 +741,7 @@ release:
        release_firmware(firmware);
 
 error:
-       kfree(bfusb);
+       kfree(data);
 
 done:
        return -EIO;
@@ -748,8 +749,8 @@ done:
 
 static void bfusb_disconnect(struct usb_interface *intf)
 {
-       struct bfusb *bfusb = usb_get_intfdata(intf);
-       struct hci_dev *hdev = bfusb->hdev;
+       struct bfusb_data *data = usb_get_intfdata(intf);
+       struct hci_dev *hdev = data->hdev;
 
        BT_DBG("intf %p", intf);
 
@@ -779,7 +780,8 @@ static int __init bfusb_init(void)
 
        BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
 
-       if ((err = usb_register(&bfusb_driver)) < 0)
+       err = usb_register(&bfusb_driver);
+       if (err < 0)
                BT_ERR("Failed to register BlueFRITZ! USB driver");
 
        return err;
index 93ba25b7ea328303fad462372ddb575e69ea207e..420b645c4c9f0d20db0e5790e44a3c854890f6c8 100644 (file)
@@ -241,15 +241,11 @@ static int hci_uart_send_frame(struct sk_buff *skb)
 
 static void hci_uart_destruct(struct hci_dev *hdev)
 {
-       struct hci_uart *hu;
-
        if (!hdev)
                return;
 
        BT_DBG("%s", hdev->name);
-
-       hu = (struct hci_uart *) hdev->driver_data;
-       kfree(hu);
+       kfree(hdev->driver_data);
 }
 
 /* ------ LDISC part ------ */
@@ -272,7 +268,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
                return -EEXIST;
 
        if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
-               BT_ERR("Can't allocate controll structure");
+               BT_ERR("Can't allocate control structure");
                return -ENFILE;
        }
 
@@ -360,7 +356,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
  *     
  * Return Value:    None
  */
-static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
+static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
 {
        struct hci_uart *hu = (void *)tty->disc_data;
 
@@ -375,7 +371,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char
        hu->hdev->stat.byte_rx += count;
        spin_unlock(&hu->rx_lock);
 
-       if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle)
+       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
+                                       tty->driver->unthrottle)
                tty->driver->unthrottle(tty);
 }
 
index e2d4beac74207c711bdafaf11399d0170d73d07b..0801af4ad2b9cab68ca22db8206e98031a090fb6 100644 (file)
@@ -96,6 +96,9 @@ static struct usb_device_id bluetooth_ids[] = {
        /* Ericsson with non-standard id */
        { USB_DEVICE(0x0bdb, 0x1002) },
 
+       /* Canyon CN-BTU1 with HID interfaces */
+       { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET },
+
        { }     /* Terminating entry */
 };
 
index aac67a3a6019958a5ad77347aa0dcc11c6609c99..a278d98a915126a2dac78c6d1865fc11d89181cf 100644 (file)
@@ -2,9 +2,9 @@
  *
  *  Bluetooth virtual HCI driver
  *
- *  Copyright (C) 2000-2001 Qualcomm Incorporated
- *  Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
- *  Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2000-2001  Qualcomm Incorporated
+ *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
+ *  Copyright (C) 2004-200 Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -72,21 +72,21 @@ static int vhci_open_dev(struct hci_dev *hdev)
 
 static int vhci_close_dev(struct hci_dev *hdev)
 {
-       struct vhci_data *vhci = hdev->driver_data;
+       struct vhci_data *data = hdev->driver_data;
 
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
-       skb_queue_purge(&vhci->readq);
+       skb_queue_purge(&data->readq);
 
        return 0;
 }
 
 static int vhci_flush(struct hci_dev *hdev)
 {
-       struct vhci_data *vhci = hdev->driver_data;
+       struct vhci_data *data = hdev->driver_data;
 
-       skb_queue_purge(&vhci->readq);
+       skb_queue_purge(&data->readq);
 
        return 0;
 }
@@ -94,7 +94,7 @@ static int vhci_flush(struct hci_dev *hdev)
 static int vhci_send_frame(struct sk_buff *skb)
 {
        struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-       struct vhci_data *vhci;
+       struct vhci_data *data;
 
        if (!hdev) {
                BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -104,15 +104,15 @@ static int vhci_send_frame(struct sk_buff *skb)
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return -EBUSY;
 
-       vhci = hdev->driver_data;
+       data = hdev->driver_data;
 
        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
-       skb_queue_tail(&vhci->readq, skb);
+       skb_queue_tail(&data->readq, skb);
 
-       if (vhci->flags & VHCI_FASYNC)
-               kill_fasync(&vhci->fasync, SIGIO, POLL_IN);
+       if (data->flags & VHCI_FASYNC)
+               kill_fasync(&data->fasync, SIGIO, POLL_IN);
 
-       wake_up_interruptible(&vhci->read_wait);
+       wake_up_interruptible(&data->read_wait);
 
        return 0;
 }
@@ -122,7 +122,7 @@ static void vhci_destruct(struct hci_dev *hdev)
        kfree(hdev->driver_data);
 }
 
-static inline ssize_t vhci_get_user(struct vhci_data *vhci,
+static inline ssize_t vhci_get_user(struct vhci_data *data,
                                        const char __user *buf, size_t count)
 {
        struct sk_buff *skb;
@@ -139,7 +139,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci,
                return -EFAULT;
        }
 
-       skb->dev = (void *) vhci->hdev;
+       skb->dev = (void *) data->hdev;
        bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
        skb_pull(skb, 1);
 
@@ -148,7 +148,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci,
        return count;
 }
 
-static inline ssize_t vhci_put_user(struct vhci_data *vhci,
+static inline ssize_t vhci_put_user(struct vhci_data *data,
                        struct sk_buff *skb, char __user *buf, int count)
 {
        char __user *ptr = buf;
@@ -161,42 +161,43 @@ static inline ssize_t vhci_put_user(struct vhci_data *vhci,
 
        total += len;
 
-       vhci->hdev->stat.byte_tx += len;
+       data->hdev->stat.byte_tx += len;
 
        switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
-               vhci->hdev->stat.cmd_tx++;
+               data->hdev->stat.cmd_tx++;
                break;
 
        case HCI_ACLDATA_PKT:
-               vhci->hdev->stat.acl_tx++;
+               data->hdev->stat.acl_tx++;
                break;
 
        case HCI_SCODATA_PKT:
-               vhci->hdev->stat.cmd_tx++;
+               data->hdev->stat.cmd_tx++;
                break;
        };
 
        return total;
 }
 
-static loff_t vhci_llseek(struct file * file, loff_t offset, int origin)
+static loff_t vhci_llseek(struct file *file, loff_t offset, int origin)
 {
        return -ESPIPE;
 }
 
-static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
+static ssize_t vhci_read(struct file *file,
+                               char __user *buf, size_t count, loff_t *pos)
 {
        DECLARE_WAITQUEUE(wait, current);
-       struct vhci_data *vhci = file->private_data;
+       struct vhci_data *data = file->private_data;
        struct sk_buff *skb;
        ssize_t ret = 0;
 
-       add_wait_queue(&vhci->read_wait, &wait);
+       add_wait_queue(&data->read_wait, &wait);
        while (count) {
                set_current_state(TASK_INTERRUPTIBLE);
 
-               skb = skb_dequeue(&vhci->readq);
+               skb = skb_dequeue(&data->readq);
                if (!skb) {
                        if (file->f_flags & O_NONBLOCK) {
                                ret = -EAGAIN;
@@ -213,7 +214,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
                }
 
                if (access_ok(VERIFY_WRITE, buf, count))
-                       ret = vhci_put_user(vhci, skb, buf, count);
+                       ret = vhci_put_user(data, skb, buf, count);
                else
                        ret = -EFAULT;
 
@@ -221,7 +222,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
                break;
        }
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&vhci->read_wait, &wait);
+       remove_wait_queue(&data->read_wait, &wait);
 
        return ret;
 }
@@ -229,21 +230,21 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo
 static ssize_t vhci_write(struct file *file,
                        const char __user *buf, size_t count, loff_t *pos)
 {
-       struct vhci_data *vhci = file->private_data;
+       struct vhci_data *data = file->private_data;
 
        if (!access_ok(VERIFY_READ, buf, count))
                return -EFAULT;
 
-       return vhci_get_user(vhci, buf, count);
+       return vhci_get_user(data, buf, count);
 }
 
 static unsigned int vhci_poll(struct file *file, poll_table *wait)
 {
-       struct vhci_data *vhci = file->private_data;
+       struct vhci_data *data = file->private_data;
 
-       poll_wait(file, &vhci->read_wait, wait);
+       poll_wait(file, &data->read_wait, wait);
 
-       if (!skb_queue_empty(&vhci->readq))
+       if (!skb_queue_empty(&data->readq))
                return POLLIN | POLLRDNORM;
 
        return POLLOUT | POLLWRNORM;
@@ -257,26 +258,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file,
 
 static int vhci_open(struct inode *inode, struct file *file)
 {
-       struct vhci_data *vhci;
+       struct vhci_data *data;
        struct hci_dev *hdev;
 
-       vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
-       if (!vhci)
+       data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
+       if (!data)
                return -ENOMEM;
 
-       skb_queue_head_init(&vhci->readq);
-       init_waitqueue_head(&vhci->read_wait);
+       skb_queue_head_init(&data->readq);
+       init_waitqueue_head(&data->read_wait);
 
        hdev = hci_alloc_dev();
        if (!hdev) {
-               kfree(vhci);
+               kfree(data);
                return -ENOMEM;
        }
 
-       vhci->hdev = hdev;
+       data->hdev = hdev;
 
-       hdev->type = HCI_VHCI;
-       hdev->driver_data = vhci;
+       hdev->type = HCI_VIRTUAL;
+       hdev->driver_data = data;
 
        hdev->open     = vhci_open_dev;
        hdev->close    = vhci_close_dev;
@@ -288,20 +289,20 @@ static int vhci_open(struct inode *inode, struct file *file)
 
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
-               kfree(vhci);
+               kfree(data);
                hci_free_dev(hdev);
                return -EBUSY;
        }
 
-       file->private_data = vhci;
+       file->private_data = data;
 
        return nonseekable_open(inode, file);
 }
 
 static int vhci_release(struct inode *inode, struct file *file)
 {
-       struct vhci_data *vhci = file->private_data;
-       struct hci_dev *hdev = vhci->hdev;
+       struct vhci_data *data = file->private_data;
+       struct hci_dev *hdev = data->hdev;
 
        if (hci_unregister_dev(hdev) < 0) {
                BT_ERR("Can't unregister HCI device %s", hdev->name);
@@ -316,17 +317,17 @@ static int vhci_release(struct inode *inode, struct file *file)
 
 static int vhci_fasync(int fd, struct file *file, int on)
 {
-       struct vhci_data *vhci = file->private_data;
+       struct vhci_data *data = file->private_data;
        int err;
 
-       err = fasync_helper(fd, file, on, &vhci->fasync);
+       err = fasync_helper(fd, file, on, &data->fasync);
        if (err < 0)
                return err;
 
        if (on)
-               vhci->flags |= VHCI_FASYNC;
+               data->flags |= VHCI_FASYNC;
        else
-               vhci->flags &= ~VHCI_FASYNC;
+               data->flags &= ~VHCI_FASYNC;
 
        return 0;
 }
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 1b21c3a911d954f571634e05fc6b6be2815f1592..bde1c665d9f4b1cf6e70cfa9ba32ec7bd765d3cc 100644 (file)
@@ -831,14 +831,6 @@ config DS1302
          will get access to the real time clock (or hardware clock) built
          into your computer.
 
-config S3C2410_RTC
-       bool "S3C2410 RTC Driver"
-       depends on ARCH_S3C2410
-       help
-         RTC (Realtime Clock) driver for the clock inbuilt into the
-         Samsung S3C2410. This can provide periodic interrupt rates
-         from 1Hz to 64Hz for user programs, and wakeup from Alarm.
-
 config COBALT_LCD
        bool "Support for Cobalt LCD"
        depends on MIPS_COBALT
@@ -1014,6 +1006,7 @@ config GPIO_VR41XX
 
 config RAW_DRIVER
        tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+       depends on BLOCK
        help
          The raw driver permits block devices to be bound to /dev/raw/rawN. 
          Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 
index b583d0cd9fbe207b00fc97abca82a2ecd15fa70f..19114df59bbdf72e973812808f66caaa65ca4df2 100644 (file)
@@ -69,7 +69,6 @@ obj-$(CONFIG_EFI_RTC)         += efirtc.o
 obj-$(CONFIG_SGI_DS1286)       += ds1286.o
 obj-$(CONFIG_SGI_IP27_RTC)     += ip27-rtc.o
 obj-$(CONFIG_DS1302)           += ds1302.o
-obj-$(CONFIG_S3C2410_RTC)      += s3c2410-rtc.o
 ifeq ($(CONFIG_GENERIC_NVRAM),y)
   obj-$(CONFIG_NVRAM)  += generic_nvram.o
 else
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 5e59c0b42731990818df9c713adb635f378ec236..4711d9b3a59545f870d769f4818f967923bf21a9 100644 (file)
@@ -746,11 +746,9 @@ void gs_set_termios (struct tty_struct * tty,
                gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
        }
 
-#if 0
        /* This is an optimization that is only allowed for dumb cards */
        /* Smart cards require knowledge of iflags and oflags too: that 
           might change hardware cooking mode.... */
-#endif
        if (old_termios) {
                if(   (tiosp->c_iflag == old_termios->c_iflag)
                   && (tiosp->c_oflag == old_termios->c_oflag)
@@ -774,14 +772,7 @@ void gs_set_termios (struct tty_struct * tty,
                if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
        }
 
-       baudrate = tiosp->c_cflag & CBAUD;
-       if (baudrate & CBAUDEX) {
-               baudrate &= ~CBAUDEX;
-               if ((baudrate < 1) || (baudrate > 4))
-                       tiosp->c_cflag &= ~CBAUDEX;
-               else
-                       baudrate += 15;
-       }
+       baudrate = tty_get_baud_rate(tty);
 
        baudrate = gs_baudrates[baudrate];
        if ((tiosp->c_cflag & CBAUD) == B38400) {
index ccd7e7102234cf09cfda77bdb49db017389d197a..8efbc9c0e5450e53868af1117556c1b89db29270 100644 (file)
 #define INTEL_RNG_ADDR                         0xFFBC015F
 #define INTEL_RNG_ADDR_LEN                     3
 
+/*
+ * LPC bridge PCI config space registers
+ */
+#define FWH_DEC_EN1_REG_OLD                    0xe3
+#define FWH_DEC_EN1_REG_NEW                    0xd9 /* high byte of 16-bit register */
+#define FWH_F8_EN_MASK                         0x80
+
+#define BIOS_CNTL_REG_OLD                      0x4e
+#define BIOS_CNTL_REG_NEW                      0xdc
+#define BIOS_CNTL_WRITE_ENABLE_MASK            0x01
+#define BIOS_CNTL_LOCK_ENABLE_MASK             0x02
+
+/*
+ * Magic address at which Intel Firmware Hubs get accessed
+ */
+#define INTEL_FWH_ADDR                         0xffff0000
+#define INTEL_FWH_ADDR_LEN                     2
+
+/*
+ * Intel Firmware Hub command codes (write to any address inside the device)
+ */
+#define INTEL_FWH_RESET_CMD                    0xff /* aka READ_ARRAY */
+#define INTEL_FWH_READ_ID_CMD                  0x90
+
+/*
+ * Intel Firmware Hub Read ID command result addresses
+ */
+#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS    0x000000
+#define INTEL_FWH_DEVICE_CODE_ADDRESS          0x000001
+
+/*
+ * Intel Firmware Hub Read ID command result values
+ */
+#define INTEL_FWH_MANUFACTURER_CODE            0x89
+#define INTEL_FWH_DEVICE_CODE_8M               0xac
+#define INTEL_FWH_DEVICE_CODE_4M               0xad
+
 /*
  * Data for PCI driver interface
  *
  * want to register another driver on the same PCI id.
  */
 static const struct pci_device_id pci_tbl[] = {
-       { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+/* AA
+       { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+/* AB
+       { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+/* ??
+       { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+/* BAM, CAM, DBM, FBM, GxM
+       { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
+       { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
+       { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
+       { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
+       { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
+       { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
+       { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
+       { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
+       { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
+       { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
+       { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
+       { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
+       { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+/* E
+       { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E  */
        { 0, }, /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, pci_tbl);
@@ -138,22 +213,115 @@ static struct hwrng intel_rng = {
 };
 
 
+#ifdef CONFIG_SMP
+static char __initdata waitflag;
+
+static void __init intel_init_wait(void *unused)
+{
+       while (waitflag)
+               cpu_relax();
+}
+#endif
+
 static int __init mod_init(void)
 {
        int err = -ENODEV;
+       unsigned i;
+       struct pci_dev *dev = NULL;
        void __iomem *mem;
-       u8 hw_status;
+       unsigned long flags;
+       u8 bios_cntl_off, fwh_dec_en1_off;
+       u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
+       u8 hw_status, mfc, dvc;
 
-       if (!pci_dev_present(pci_tbl))
+       for (i = 0; !dev && pci_tbl[i].vendor; ++i)
+               dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+
+       if (!dev)
                goto out; /* Device not found. */
 
+       /* Check for Intel 82802 */
+       if (dev->device < 0x2640) {
+               fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+               bios_cntl_off = BIOS_CNTL_REG_OLD;
+       } else {
+               fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+               bios_cntl_off = BIOS_CNTL_REG_NEW;
+       }
+
+       pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
+       pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
+
+       mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+       if (mem == NULL) {
+               pci_dev_put(dev);
+               err = -EBUSY;
+               goto out;
+       }
+
+       /*
+        * Since the BIOS code/data is going to disappear from its normal
+        * location with the Read ID command, all activity on the system
+        * must be stopped until the state is back to normal.
+        */
+#ifdef CONFIG_SMP
+       set_mb(waitflag, 1);
+       if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
+               set_mb(waitflag, 0);
+               pci_dev_put(dev);
+               printk(KERN_ERR PFX "cannot run on all processors\n");
+               err = -EAGAIN;
+               goto err_unmap;
+       }
+#endif
+       local_irq_save(flags);
+
+       if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+               pci_write_config_byte(dev,
+                                     fwh_dec_en1_off,
+                                     fwh_dec_en1_val | FWH_F8_EN_MASK);
+       if (!(bios_cntl_val &
+             (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+               pci_write_config_byte(dev,
+                                     bios_cntl_off,
+                                     bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
+
+       writeb(INTEL_FWH_RESET_CMD, mem);
+       writeb(INTEL_FWH_READ_ID_CMD, mem);
+       mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+       dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+       writeb(INTEL_FWH_RESET_CMD, mem);
+
+       if (!(bios_cntl_val &
+             (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+               pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
+       if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+               pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
+
+       local_irq_restore(flags);
+#ifdef CONFIG_SMP
+       /* Tell other CPUs to resume. */
+       set_mb(waitflag, 0);
+#endif
+
+       iounmap(mem);
+       pci_dev_put(dev);
+
+       if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+           (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+            dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+               printk(KERN_ERR PFX "FWH not detected\n");
+               err = -ENODEV;
+               goto out;
+       }
+
        err = -ENOMEM;
        mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
        if (!mem)
                goto out;
        intel_rng.priv = (unsigned long)mem;
 
-       /* Check for Intel 82802 */
+       /* Check for Random Number Generator */
        err = -ENODEV;
        hw_status = hwstatus_get(mem);
        if ((hw_status & INTEL_RNG_PRESENT) == 0)
index 8c09997cc3d63b9108c7c4f948a9eb611a580bff..6b4d82a4565fbf9ec533891f8043b6aa3d5ca707 100644 (file)
@@ -612,16 +612,6 @@ MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
 #define        MINOR2BRD(min)          (((min) & 0xc0) >> 6)
 #define        MINOR2PORT(min)         ((min) & 0x3f)
 
-/*
- *     Define a baud rate table that converts termios baud rate selector
- *     into the actual baud rate value. All baud rate calculations are based
- *     on the actual baud rate required.
- */
-static unsigned int    stli_baudrates[] = {
-       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
 /*****************************************************************************/
 
 /*
@@ -2747,15 +2737,7 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio
 /*
  *     Start of by setting the baud, char size, parity and stop bit info.
  */
-       pp->baudout = tiosp->c_cflag & CBAUD;
-       if (pp->baudout & CBAUDEX) {
-               pp->baudout &= ~CBAUDEX;
-               if ((pp->baudout < 1) || (pp->baudout > 4))
-                       tiosp->c_cflag &= ~CBAUDEX;
-               else
-                       pp->baudout += 15;
-       }
-       pp->baudout = stli_baudrates[pp->baudout];
+       pp->baudout = tty_get_baud_rate(portp->tty);
        if ((tiosp->c_cflag & CBAUD) == B38400) {
                if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
                        pp->baudout = 57600;
index f875fda3b089d54332341671388716c99ebd05eb..1ecea7d448f14618e19112b6c84dd75a25c25d7d 100644 (file)
@@ -906,7 +906,7 @@ static int __init lp_init (void)
        lp_class = class_create(THIS_MODULE, "printer");
        if (IS_ERR(lp_class)) {
                err = PTR_ERR(lp_class);
-               goto out_devfs;
+               goto out_reg;
        }
 
        if (parport_register_driver (&lp_driver)) {
@@ -927,7 +927,7 @@ static int __init lp_init (void)
 
 out_class:
        class_destroy(lp_class);
-out_devfs:
+out_reg:
        unregister_chrdev(LP_MAJOR, "lp");
        return err;
 }
index 4ac70ec697f07f7b6b15c52d231709b7dd64577b..6511012cbdcd86d971a6cdebcf6e1baad66ccded 100644 (file)
@@ -551,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
        return virtr + wrote;
 }
 
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char __user * buf,
                         size_t count, loff_t *ppos)
 {
@@ -830,7 +830,7 @@ static const struct file_operations null_fops = {
        .splice_write   = splice_write_null,
 };
 
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
 static const struct file_operations port_fops = {
        .llseek         = memory_lseek,
        .read           = read_port,
@@ -908,7 +908,7 @@ static int memory_open(struct inode * inode, struct file * filp)
                case 3:
                        filp->f_op = &null_fops;
                        break;
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
                case 4:
                        filp->f_op = &port_fops;
                        break;
@@ -955,7 +955,7 @@ static const struct {
        {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
        {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
        {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
        {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
 #endif
        {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
index 84e5a68635f12203c361cf837aab3f2bd4fdbca0..ecfaf180e5bd8b106ee12e06da33fc0c1a88f702 100644 (file)
@@ -188,16 +188,6 @@ static void pc8736x_gpio_set(unsigned minor, int val)
        pc8736x_gpio_shadow[port] = val;
 }
 
-static void pc8736x_gpio_set_high(unsigned index)
-{
-       pc8736x_gpio_set(index, 1);
-}
-
-static void pc8736x_gpio_set_low(unsigned index)
-{
-       pc8736x_gpio_set(index, 0);
-}
-
 static int pc8736x_gpio_current(unsigned minor)
 {
        int port, bit;
index 4c3a5ca9d8f7a98f882cdbeed12f0949af940a55..b430a12eb8190d9266ccd0de322c243021a1086e 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
 
@@ -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 579868af4a54d91be8f0707c96053e3d9bfb7b5e..c596a08c07b3591da8025955a236fd8fb908303b 100644 (file)
@@ -288,31 +288,34 @@ static struct cdev raw_cdev = {
 static int __init raw_init(void)
 {
        dev_t dev = MKDEV(RAW_MAJOR, 0);
+       int ret;
 
-       if (register_chrdev_region(dev, MAX_RAW_MINORS, "raw"))
+       ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
+       if (ret)
                goto error;
 
        cdev_init(&raw_cdev, &raw_fops);
-       if (cdev_add(&raw_cdev, dev, MAX_RAW_MINORS)) {
+       ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
+       if (ret) {
                kobject_put(&raw_cdev.kobj);
-               unregister_chrdev_region(dev, MAX_RAW_MINORS);
-               goto error;
+               goto error_region;
        }
 
        raw_class = class_create(THIS_MODULE, "raw");
        if (IS_ERR(raw_class)) {
                printk(KERN_ERR "Error creating raw class.\n");
                cdev_del(&raw_cdev);
-               unregister_chrdev_region(dev, MAX_RAW_MINORS);
-               goto error;
+               ret = PTR_ERR(raw_class);
+               goto error_region;
        }
        class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
        return 0;
 
+error_region:
+       unregister_chrdev_region(dev, MAX_RAW_MINORS);
 error:
-       printk(KERN_ERR "error register raw device\n");
-       return 1;
+       return ret;
 }
 
 static void __exit raw_exit(void)
index ab6429b4a84e424a9e390d3946bbd1ff6a8c316f..656f8c0ca52effdc31f343360a91309278ae5760 100644 (file)
@@ -1262,10 +1262,8 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
         * Once the read clears, read the RTC time (again via ioctl). Easy.
         */
 
-       while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) {
-               barrier();
+       while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100)
                cpu_relax();
-       }
 
        /*
         * Only the values that we read from the RTC are set. We leave
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
deleted file mode 100644 (file)
index 5458ef1..0000000
+++ /dev/null
@@ -1,591 +0,0 @@
-/* drivers/char/s3c2410_rtc.c
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Internal RTC Driver
- *
- *  Changelog:
- *     08-Nov-2004     BJD     Initial creation
- *     12-Nov-2004     BJD     Added periodic IRQ and PM code
- *     22-Nov-2004     BJD     Sign-test on alarm code to check for <0
- *     10-Mar-2005     LCVR    Changed S3C2410_VA_RTC to S3C24XX_VA_RTC
-*/
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/clk.h>
-
-#include <asm/hardware.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/rtc.h>
-
-#include <asm/mach/time.h>
-
-#include <asm/arch/regs-rtc.h>
-
-/* need this for the RTC_AF definitions */
-#include <linux/mc146818rtc.h>
-
-#undef S3C24XX_VA_RTC
-#define S3C24XX_VA_RTC s3c2410_rtc_base
-
-static struct resource *s3c2410_rtc_mem;
-
-static void __iomem *s3c2410_rtc_base;
-static int s3c2410_rtc_alarmno = NO_IRQ;
-static int s3c2410_rtc_tickno  = NO_IRQ;
-static int s3c2410_rtc_freq    = 1;
-
-static DEFINE_SPINLOCK(s3c2410_rtc_pie_lock);
-
-/* IRQ Handlers */
-
-static irqreturn_t s3c2410_rtc_alarmirq(int irq, void *id, struct pt_regs *r)
-{
-       rtc_update(1, RTC_AF | RTC_IRQF);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t s3c2410_rtc_tickirq(int irq, void *id, struct pt_regs *r)
-{
-       rtc_update(1, RTC_PF | RTC_IRQF);
-       return IRQ_HANDLED;
-}
-
-/* Update control registers */
-static void s3c2410_rtc_setaie(int to)
-{
-       unsigned int tmp;
-
-       pr_debug("%s: aie=%d\n", __FUNCTION__, to);
-
-       tmp = readb(S3C2410_RTCALM);
-
-       if (to)
-               tmp |= S3C2410_RTCALM_ALMEN;
-       else
-               tmp &= ~S3C2410_RTCALM_ALMEN;
-
-
-       writeb(tmp, S3C2410_RTCALM);
-}
-
-static void s3c2410_rtc_setpie(int to)
-{
-       unsigned int tmp;
-
-       pr_debug("%s: pie=%d\n", __FUNCTION__, to);
-
-       spin_lock_irq(&s3c2410_rtc_pie_lock);
-       tmp = readb(S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE;
-
-       if (to)
-               tmp |= S3C2410_TICNT_ENABLE;
-
-       writeb(tmp, S3C2410_TICNT);
-       spin_unlock_irq(&s3c2410_rtc_pie_lock);
-}
-
-static void s3c2410_rtc_setfreq(int freq)
-{
-       unsigned int tmp;
-
-       spin_lock_irq(&s3c2410_rtc_pie_lock);
-       tmp = readb(S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
-
-       s3c2410_rtc_freq = freq;
-
-       tmp |= (128 / freq)-1;
-
-       writeb(tmp, S3C2410_TICNT);
-       spin_unlock_irq(&s3c2410_rtc_pie_lock);
-}
-
-/* Time read/write */
-
-static int s3c2410_rtc_gettime(struct rtc_time *rtc_tm)
-{
-       unsigned int have_retried = 0;
-
- retry_get_time:
-       rtc_tm->tm_min  = readb(S3C2410_RTCMIN);
-       rtc_tm->tm_hour = readb(S3C2410_RTCHOUR);
-       rtc_tm->tm_mday = readb(S3C2410_RTCDATE);
-       rtc_tm->tm_mon  = readb(S3C2410_RTCMON);
-       rtc_tm->tm_year = readb(S3C2410_RTCYEAR);
-       rtc_tm->tm_sec  = readb(S3C2410_RTCSEC);
-
-       /* the only way to work out wether the system was mid-update
-        * when we read it is to check the second counter, and if it
-        * is zero, then we re-try the entire read
-        */
-
-       if (rtc_tm->tm_sec == 0 && !have_retried) {
-               have_retried = 1;
-               goto retry_get_time;
-       }
-
-       pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
-                rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
-                rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
-
-       BCD_TO_BIN(rtc_tm->tm_sec);
-       BCD_TO_BIN(rtc_tm->tm_min);
-       BCD_TO_BIN(rtc_tm->tm_hour);
-       BCD_TO_BIN(rtc_tm->tm_mday);
-       BCD_TO_BIN(rtc_tm->tm_mon);
-       BCD_TO_BIN(rtc_tm->tm_year);
-
-       rtc_tm->tm_year += 100;
-       rtc_tm->tm_mon -= 1;
-
-       return 0;
-}
-
-
-static int s3c2410_rtc_settime(struct rtc_time *tm)
-{
-       /* the rtc gets round the y2k problem by just not supporting it */
-
-       if (tm->tm_year < 100)
-               return -EINVAL;
-
-       writeb(BIN2BCD(tm->tm_sec),  S3C2410_RTCSEC);
-       writeb(BIN2BCD(tm->tm_min),  S3C2410_RTCMIN);
-       writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR);
-       writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE);
-       writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON);
-       writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR);
-
-       return 0;
-}
-
-static int s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm)
-{
-       struct rtc_time *alm_tm = &alrm->time;
-       unsigned int alm_en;
-
-       alm_tm->tm_sec  = readb(S3C2410_ALMSEC);
-       alm_tm->tm_min  = readb(S3C2410_ALMMIN);
-       alm_tm->tm_hour = readb(S3C2410_ALMHOUR);
-       alm_tm->tm_mon  = readb(S3C2410_ALMMON);
-       alm_tm->tm_mday = readb(S3C2410_ALMDATE);
-       alm_tm->tm_year = readb(S3C2410_ALMYEAR);
-
-       alm_en = readb(S3C2410_RTCALM);
-
-       pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
-                alm_en,
-                alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
-                alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
-
-
-       /* decode the alarm enable field */
-
-       if (alm_en & S3C2410_RTCALM_SECEN) {
-               BCD_TO_BIN(alm_tm->tm_sec);
-       } else {
-               alm_tm->tm_sec = 0xff;
-       }
-
-       if (alm_en & S3C2410_RTCALM_MINEN) {
-               BCD_TO_BIN(alm_tm->tm_min);
-       } else {
-               alm_tm->tm_min = 0xff;
-       }
-
-       if (alm_en & S3C2410_RTCALM_HOUREN) {
-               BCD_TO_BIN(alm_tm->tm_hour);
-       } else {
-               alm_tm->tm_hour = 0xff;
-       }
-
-       if (alm_en & S3C2410_RTCALM_DAYEN) {
-               BCD_TO_BIN(alm_tm->tm_mday);
-       } else {
-               alm_tm->tm_mday = 0xff;
-       }
-
-       if (alm_en & S3C2410_RTCALM_MONEN) {
-               BCD_TO_BIN(alm_tm->tm_mon);
-               alm_tm->tm_mon -= 1;
-       } else {
-               alm_tm->tm_mon = 0xff;
-       }
-
-       if (alm_en & S3C2410_RTCALM_YEAREN) {
-               BCD_TO_BIN(alm_tm->tm_year);
-       } else {
-               alm_tm->tm_year = 0xffff;
-       }
-
-       /* todo - set alrm->enabled ? */
-
-       return 0;
-}
-
-static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm)
-{
-       struct rtc_time *tm = &alrm->time;
-       unsigned int alrm_en;
-
-       pr_debug("s3c2410_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
-                alrm->enabled,
-                tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
-                tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
-
-       if (alrm->enabled || 1) {
-               alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
-               writeb(0x00, S3C2410_RTCALM);
-
-               if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
-                       alrm_en |= S3C2410_RTCALM_SECEN;
-                       writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC);
-               }
-
-               if (tm->tm_min < 60 && tm->tm_min >= 0) {
-                       alrm_en |= S3C2410_RTCALM_MINEN;
-                       writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN);
-               }
-
-               if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
-                       alrm_en |= S3C2410_RTCALM_HOUREN;
-                       writeb(BIN2BCD(tm->tm_hour), S3C2410_ALMHOUR);
-               }
-
-               pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en);
-
-               writeb(alrm_en, S3C2410_RTCALM);
-               enable_irq_wake(s3c2410_rtc_alarmno);
-       } else {
-               alrm_en = readb(S3C2410_RTCALM);
-               alrm_en &= ~S3C2410_RTCALM_ALMEN;
-               writeb(alrm_en, S3C2410_RTCALM);
-               disable_irq_wake(s3c2410_rtc_alarmno);
-       }
-
-       return 0;
-}
-
-static int s3c2410_rtc_ioctl(unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
-               s3c2410_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0);
-               return 0;
-
-       case RTC_PIE_OFF:
-       case RTC_PIE_ON:
-               s3c2410_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0);
-               return 0;
-
-       case RTC_IRQP_READ:
-               return put_user(s3c2410_rtc_freq, (unsigned long __user *)arg);
-
-       case RTC_IRQP_SET:
-               if (arg < 1 || arg > 64)
-                       return -EINVAL;
-
-               if (!capable(CAP_SYS_RESOURCE))
-                       return -EACCES;
-
-               /* check for power of 2 */
-
-               if ((arg & (arg-1)) != 0)
-                       return -EINVAL;
-
-               pr_debug("s3c2410_rtc: setting frequency %ld\n", arg);
-
-               s3c2410_rtc_setfreq(arg);
-               return 0;
-
-       case RTC_UIE_ON:
-       case RTC_UIE_OFF:
-               return -EINVAL;
-       }
-
-       return -EINVAL;
-}
-
-static int s3c2410_rtc_proc(char *buf)
-{
-       unsigned int rtcalm = readb(S3C2410_RTCALM);
-       unsigned int ticnt = readb (S3C2410_TICNT);
-       char *p = buf;
-
-       p += sprintf(p, "alarm_IRQ\t: %s\n",
-                    (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
-       p += sprintf(p, "periodic_IRQ\t: %s\n",
-                    (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
-       p += sprintf(p, "periodic_freq\t: %d\n", s3c2410_rtc_freq);
-
-       return p - buf;
-}
-
-static int s3c2410_rtc_open(void)
-{
-       int ret;
-
-       ret = request_irq(s3c2410_rtc_alarmno, s3c2410_rtc_alarmirq,
-                         IRQF_DISABLED,  "s3c2410-rtc alarm", NULL);
-
-       if (ret)
-               printk(KERN_ERR "IRQ%d already in use\n", s3c2410_rtc_alarmno);
-
-       ret = request_irq(s3c2410_rtc_tickno, s3c2410_rtc_tickirq,
-                         IRQF_DISABLED,  "s3c2410-rtc tick", NULL);
-
-       if (ret) {
-               printk(KERN_ERR "IRQ%d already in use\n", s3c2410_rtc_tickno);
-               goto tick_err;
-       }
-
-       return ret;
-
- tick_err:
-       free_irq(s3c2410_rtc_alarmno, NULL);
-       return ret;
-}
-
-static void s3c2410_rtc_release(void)
-{
-       /* do not clear AIE here, it may be needed for wake */
-
-       s3c2410_rtc_setpie(0);
-       free_irq(s3c2410_rtc_alarmno, NULL);
-       free_irq(s3c2410_rtc_tickno, NULL);
-}
-
-static struct rtc_ops s3c2410_rtcops = {
-       .owner          = THIS_MODULE,
-       .open           = s3c2410_rtc_open,
-       .release        = s3c2410_rtc_release,
-       .ioctl          = s3c2410_rtc_ioctl,
-       .read_time      = s3c2410_rtc_gettime,
-       .set_time       = s3c2410_rtc_settime,
-       .read_alarm     = s3c2410_rtc_getalarm,
-       .set_alarm      = s3c2410_rtc_setalarm,
-       .proc           = s3c2410_rtc_proc,
-};
-
-static void s3c2410_rtc_enable(struct platform_device *pdev, int en)
-{
-       unsigned int tmp;
-
-       if (s3c2410_rtc_base == NULL)
-               return;
-
-       if (!en) {
-               tmp = readb(S3C2410_RTCCON);
-               writeb(tmp & ~S3C2410_RTCCON_RTCEN, S3C2410_RTCCON);
-
-               tmp = readb(S3C2410_TICNT);
-               writeb(tmp & ~S3C2410_TICNT_ENABLE, S3C2410_TICNT);
-       } else {
-               /* re-enable the device, and check it is ok */
-
-               if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){
-                       dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
-
-                       tmp = readb(S3C2410_RTCCON);
-                       writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON);
-               }
-
-               if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){
-                       dev_info(&pdev->dev, "removing S3C2410_RTCCON_CNTSEL\n");
-
-                       tmp = readb(S3C2410_RTCCON);
-                       writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON);
-               }
-
-               if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){
-                       dev_info(&pdev->dev, "removing S3C2410_RTCCON_CLKRST\n");
-
-                       tmp = readb(S3C2410_RTCCON);
-                       writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON);
-               }
-       }
-}
-
-static int s3c2410_rtc_remove(struct platform_device *dev)
-{
-       unregister_rtc(&s3c2410_rtcops);
-
-       s3c2410_rtc_setpie(0);
-       s3c2410_rtc_setaie(0);
-
-       if (s3c2410_rtc_mem != NULL) {
-               pr_debug("s3c2410_rtc: releasing s3c2410_rtc_mem\n");
-               iounmap(s3c2410_rtc_base);
-               release_resource(s3c2410_rtc_mem);
-               kfree(s3c2410_rtc_mem);
-       }
-
-       return 0;
-}
-
-static int s3c2410_rtc_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       int ret;
-
-       pr_debug("%s: probe=%p\n", __FUNCTION__, pdev);
-
-       /* find the IRQs */
-
-       s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
-       if (s3c2410_rtc_tickno < 0) {
-               dev_err(&pdev->dev, "no irq for rtc tick\n");
-               return -ENOENT;
-       }
-
-       s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
-       if (s3c2410_rtc_alarmno < 0) {
-               dev_err(&pdev->dev, "no irq for alarm\n");
-               return -ENOENT;
-       }
-
-       pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n",
-                s3c2410_rtc_tickno, s3c2410_rtc_alarmno);
-
-       /* get the memory region */
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "failed to get memory region resource\n");
-               return -ENOENT;
-       }
-
-       s3c2410_rtc_mem = request_mem_region(res->start, res->end-res->start+1,
-                                    pdev->name);
-
-       if (s3c2410_rtc_mem == NULL) {
-               dev_err(&pdev->dev, "failed to reserve memory region\n");
-               ret = -ENOENT;
-               goto exit_err;
-       }
-
-       s3c2410_rtc_base = ioremap(res->start, res->end - res->start + 1);
-       if (s3c2410_rtc_base == NULL) {
-               dev_err(&pdev->dev, "failed ioremap()\n");
-               ret = -EINVAL;
-               goto exit_err;
-       }
-
-       s3c2410_rtc_mem = res;
-       pr_debug("s3c2410_rtc_base=%p\n", s3c2410_rtc_base);
-
-       pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON));
-
-       /* check to see if everything is setup correctly */
-
-       s3c2410_rtc_enable(pdev, 1);
-
-       pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON));
-
-       s3c2410_rtc_setfreq(s3c2410_rtc_freq);
-
-       /* register RTC and exit */
-
-       register_rtc(&s3c2410_rtcops);
-       return 0;
-
- exit_err:
-       dev_err(&pdev->dev, "error %d during initialisation\n", ret);
-
-       return ret;
-}
-
-#ifdef CONFIG_PM
-
-/* S3C2410 RTC Power management control */
-
-static struct timespec s3c2410_rtc_delta;
-
-static int ticnt_save;
-
-static int s3c2410_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct rtc_time tm;
-       struct timespec time;
-
-       time.tv_nsec = 0;
-
-       /* save TICNT for anyone using periodic interrupts */
-
-       ticnt_save = readb(S3C2410_TICNT);
-
-       /* calculate time delta for suspend */
-
-       s3c2410_rtc_gettime(&tm);
-       rtc_tm_to_time(&tm, &time.tv_sec);
-       save_time_delta(&s3c2410_rtc_delta, &time);
-       s3c2410_rtc_enable(pdev, 0);
-
-       return 0;
-}
-
-static int s3c2410_rtc_resume(struct platform_device *pdev)
-{
-       struct rtc_time tm;
-       struct timespec time;
-
-       time.tv_nsec = 0;
-
-       s3c2410_rtc_enable(pdev, 1);
-       s3c2410_rtc_gettime(&tm);
-       rtc_tm_to_time(&tm, &time.tv_sec);
-       restore_time_delta(&s3c2410_rtc_delta, &time);
-
-       writeb(ticnt_save, S3C2410_TICNT);
-       return 0;
-}
-#else
-#define s3c2410_rtc_suspend NULL
-#define s3c2410_rtc_resume  NULL
-#endif
-
-static struct platform_driver s3c2410_rtcdrv = {
-       .probe          = s3c2410_rtc_probe,
-       .remove         = s3c2410_rtc_remove,
-       .suspend        = s3c2410_rtc_suspend,
-       .resume         = s3c2410_rtc_resume,
-       .driver         = {
-               .name   = "s3c2410-rtc",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static char __initdata banner[] = "S3C2410 RTC, (c) 2004 Simtec Electronics\n";
-
-static int __init s3c2410_rtc_init(void)
-{
-       printk(banner);
-       return platform_driver_register(&s3c2410_rtcdrv);
-}
-
-static void __exit s3c2410_rtc_exit(void)
-{
-       platform_driver_unregister(&s3c2410_rtcdrv);
-}
-
-module_init(s3c2410_rtc_init);
-module_exit(s3c2410_rtc_exit);
-
-MODULE_DESCRIPTION("S3C24XX RTC Driver");
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
index b956c7babd18a8a4933d6a99e74bd86ceb63c62d..99e5272e3c53e1ef1aa32f0733b1bbf0e9f2487e 100644 (file)
@@ -44,7 +44,7 @@ struct nsc_gpio_ops scx200_gpio_ops = {
        .gpio_change    = scx200_gpio_change,
        .gpio_current   = scx200_gpio_current
 };
-EXPORT_SYMBOL(scx200_gpio_ops);
+EXPORT_SYMBOL_GPL(scx200_gpio_ops);
 
 static int scx200_gpio_open(struct inode *inode, struct file *file)
 {
@@ -69,7 +69,7 @@ static const struct file_operations scx200_gpio_fileops = {
        .release = scx200_gpio_release,
 };
 
-struct cdev scx200_gpio_cdev;  /* use 1 cdev for all pins */
+static struct cdev scx200_gpio_cdev;  /* use 1 cdev for all pins */
 
 static int __init scx200_gpio_init(void)
 {
index 71093a9fc462ac8f562a8c8e980a7d7deceadd89..74cff839c8572c9bf560640b0ea513938627fd54 100644 (file)
@@ -33,7 +33,7 @@ extern void poke_blanked_console(void);
 
 /* Variables for selection control. */
 /* Use a dynamic buffer, instead of static (Dec 1994) */
-struct vc_data *sel_cons;              /* must not be disallocated */
+struct vc_data *sel_cons;              /* must not be deallocated */
 static volatile int sel_start = -1;    /* cleared by clear_selection */
 static int sel_end;
 static int sel_buffer_lth;
index a1d303f9a33dd30fa2260b82cacf4fdf1fa78308..c0ef0f0e5800dcd74a90e38cc483bc2e37ac60f0 100644 (file)
@@ -1087,24 +1087,16 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
        spin_unlock_irqrestore(&bp->lock, flags);
        dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
-       baud = C_BAUD(tty);
+       baud = tty_get_baud_rate(tty);
 
-       if (baud & CBAUDEX) {
-               baud &= ~CBAUDEX;
-               if (baud < 1 || baud > 2)
-                       port->tty->termios->c_cflag &= ~CBAUDEX;
-               else
-                       baud += 15;
-       }
-       if (baud == 15) {
+       if (baud == 38400) {
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
                        baud ++;
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
                        baud += 2;
        }
 
-
-       if (!baud_table[baud]) {
+       if (!baud) {
                /* Drop DTR & exit */
                dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
                if (!SX_CRTSCTS (tty)) {
@@ -1134,7 +1126,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                                  "This is an untested option, please be carefull.\n",
                                  port_No (port), tmp);
        else
-               tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
+               tmp = (((SX_OSCFREQ + baud/2) / baud +
                         CD186x_TPC/2) / CD186x_TPC);
 
        if ((tmp < 0x10) && time_before(again, jiffies)) {
index ee3ca8f1768e9be995a62a252404ad4712d5d6bc..0ad6cb081db4d1b3681a7b069d9439454e3bd9fc 100644 (file)
@@ -208,7 +208,7 @@ static void send_sig_all(int sig)
        struct task_struct *p;
 
        for_each_process(p) {
-               if (p->mm && p->pid != 1)
+               if (p->mm && !is_init(p))
                        /* Not swapper, init nor kernel thread */
                        force_sig(sig, p);
        }
index bb0d9199e994867544bfc82da5d6530cd6dfe787..333741770f1e079f2fbe0df98b69699a4194f924 100644 (file)
@@ -129,6 +129,7 @@ LIST_HEAD(tty_drivers);                     /* linked list of tty drivers */
 /* Semaphore to protect creating and releasing a tty. This is shared with
    vt.c for deeply disgusting hack reasons */
 DEFINE_MUTEX(tty_mutex);
+EXPORT_SYMBOL(tty_mutex);
 
 #ifdef CONFIG_UNIX98_PTYS
 extern struct tty_driver *ptm_driver;  /* Unix98 pty masters; for /dev/ptmx */
@@ -160,17 +161,11 @@ static void release_mem(struct tty_struct *tty, int idx);
  *     been initialized in any way but has been zeroed
  *
  *     Locking: none
- *     FIXME: use kzalloc
  */
 
 static struct tty_struct *alloc_tty_struct(void)
 {
-       struct tty_struct *tty;
-
-       tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
-       if (tty)
-               memset(tty, 0, sizeof(struct tty_struct));
-       return tty;
+       return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
 }
 
 static void tty_buffer_free_all(struct tty_struct *);
@@ -483,10 +478,9 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
                tb->used += space;
                copied += space;
                chars += space;
-       }
-       /* There is a small chance that we need to split the data over
-          several buffers. If this is the case we must loop */
-       while (unlikely(size > copied));
+               /* There is a small chance that we need to split the data over
+                  several buffers. If this is the case we must loop */
+       } while (unlikely(size > copied));
        return copied;
 }
 EXPORT_SYMBOL(tty_insert_flip_string);
@@ -521,10 +515,9 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
                copied += space;
                chars += space;
                flags += space;
-       }
-       /* There is a small chance that we need to split the data over
-          several buffers. If this is the case we must loop */
-       while (unlikely(size > copied));
+               /* There is a small chance that we need to split the data over
+                  several buffers. If this is the case we must loop */
+       } while (unlikely(size > copied));
        return copied;
 }
 EXPORT_SYMBOL(tty_insert_flip_string_flags);
@@ -626,9 +619,9 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
  
 static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
 {
-       down(&tty->termios_sem);
+       mutex_lock(&tty->termios_mutex);
        tty->termios->c_line = num;
-       up(&tty->termios_sem);
+       mutex_unlock(&tty->termios_mutex);
 }
 
 /*
@@ -1346,9 +1339,9 @@ static void do_tty_hangup(void *data)
         */
        if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
        {
-               down(&tty->termios_sem);
+               mutex_lock(&tty->termios_mutex);
                *tty->termios = tty->driver->init_termios;
-               up(&tty->termios_sem);
+               mutex_unlock(&tty->termios_mutex);
        }
        
        /* Defer ldisc switch */
@@ -2072,8 +2065,9 @@ fail_no_mem:
 
        /* call the tty release_mem routine to clean out this slot */
 release_mem_out:
-       printk(KERN_INFO "init_dev: ldisc open failed, "
-                        "clearing slot %d\n", idx);
+       if (printk_ratelimit())
+               printk(KERN_INFO "init_dev: ldisc open failed, "
+                                "clearing slot %d\n", idx);
        release_mem(tty, idx);
        goto end_init;
 }
@@ -2726,6 +2720,8 @@ static int tty_fasync(int fd, struct file * filp, int on)
  *     Locking:
  *             Called functions take tty_ldisc_lock
  *             current->signal->tty check is safe without locks
+ *
+ *     FIXME: may race normal receive processing
  */
 
 static int tiocsti(struct tty_struct *tty, char __user *p)
@@ -2748,18 +2744,21 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
  *     @tty; tty
  *     @arg: user buffer for result
  *
- *     Copies the kernel idea of the window size into the user buffer. No
- *     locking is done.
+ *     Copies the kernel idea of the window size into the user buffer.
  *
- *     FIXME: Returning random values racing a window size set is wrong
- *     should lock here against that
+ *     Locking: tty->termios_sem is taken to ensure the winsize data
+ *             is consistent.
  */
 
 static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
 {
-       if (copy_to_user(arg, &tty->winsize, sizeof(*arg)))
-               return -EFAULT;
-       return 0;
+       int err;
+
+       mutex_lock(&tty->termios_mutex);
+       err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
+       mutex_unlock(&tty->termios_mutex);
+
+       return err ? -EFAULT: 0;
 }
 
 /**
@@ -2772,12 +2771,11 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
  *     actually has driver level meaning and triggers a VC resize.
  *
  *     Locking:
- *             The console_sem is used to ensure we do not try and resize
- *     the console twice at once.
- *     FIXME: Two racing size sets may leave the console and kernel
- *             parameters disagreeing. Is this exploitable ?
- *     FIXME: Random values racing a window size get is wrong
- *     should lock here against that
+ *             Called function use the console_sem is used to ensure we do
+ *     not try and resize the console twice at once.
+ *             The tty->termios_sem is used to ensure we don't double
+ *     resize and get confused. Lock order - tty->termios.sem before
+ *     console sem
  */
 
 static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
@@ -2787,17 +2785,18 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
 
        if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
                return -EFAULT;
+
+       mutex_lock(&tty->termios_mutex);
        if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
-               return 0;
+               goto done;
+
 #ifdef CONFIG_VT
        if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
-               int rc;
-
-               acquire_console_sem();
-               rc = vc_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row);
-               release_console_sem();
-               if (rc)
-                       return -ENXIO;
+               if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col,
+                                       tmp_ws.ws_row)) {
+                       mutex_unlock(&tty->termios_mutex);
+                       return -ENXIO;
+               }
        }
 #endif
        if (tty->pgrp > 0)
@@ -2806,6 +2805,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
                kill_pg(real_tty->pgrp, SIGWINCH, 1);
        tty->winsize = tmp_ws;
        real_tty->winsize = tmp_ws;
+done:
+       mutex_unlock(&tty->termios_mutex);
        return 0;
 }
 
@@ -2880,9 +2881,7 @@ static int fionbio(struct file *file, int __user *p)
  *     Locking:
  *             Takes tasklist lock internally to walk sessions
  *             Takes task_lock() when updating signal->tty
- *
- *     FIXME: tty_mutex is needed to protect signal->tty references.
- *     FIXME: why task_lock on the signal->tty reference ??
+ *             Takes tty_mutex() to protect tty instance
  *
  */
 
@@ -2917,9 +2916,11 @@ static int tiocsctty(struct tty_struct *tty, int arg)
                } else
                        return -EPERM;
        }
+       mutex_lock(&tty_mutex);
        task_lock(current);
        current->signal->tty = tty;
        task_unlock(current);
+       mutex_unlock(&tty_mutex);
        current->signal->tty_old_pgrp = 0;
        tty->session = current->signal->session;
        tty->pgrp = process_group(current);
@@ -2959,8 +2960,6 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
  *     permitted where the tty session is our session.
  *
  *     Locking: None
- *
- *     FIXME: current->signal->tty referencing is unsafe.
  */
 
 static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -3039,19 +3038,20 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
  *     timed break functionality.
  *
  *     Locking:
- *             None
+ *             atomic_write_lock serializes
  *
- *     FIXME:
- *             What if two overlap
  */
 
 static int send_break(struct tty_struct *tty, unsigned int duration)
 {
+       if (mutex_lock_interruptible(&tty->atomic_write_lock))
+               return -EINTR;
        tty->driver->break_ctl(tty, -1);
        if (!signal_pending(current)) {
                msleep_interruptible(duration);
        }
        tty->driver->break_ctl(tty, 0);
+       mutex_unlock(&tty->atomic_write_lock);
        if (signal_pending(current))
                return -EINTR;
        return 0;
@@ -3144,6 +3144,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
        if (tty_paranoia_check(tty, inode, "tty_ioctl"))
                return -EINVAL;
 
+       /* CHECKME: is this safe as one end closes ? */
+
        real_tty = tty;
        if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
            tty->driver->subtype == PTY_TYPE_MASTER)
@@ -3580,7 +3582,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
        tty_buffer_init(tty);
        INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
        init_MUTEX(&tty->buf.pty_sem);
-       init_MUTEX(&tty->termios_sem);
+       mutex_init(&tty->termios_mutex);
        init_waitqueue_head(&tty->write_wait);
        init_waitqueue_head(&tty->read_wait);
        INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
index 4ad47d321bd426eb9e34364b4ad4c44c200fab43..3b6fa7b0be8ba81c1f9d658cf63740394225172d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/mutex.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -131,7 +132,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
 
        /* FIXME: we need to decide on some locking/ordering semantics
           for the set_termios notification eventually */
-       down(&tty->termios_sem);
+       mutex_lock(&tty->termios_mutex);
 
        *tty->termios = *new_termios;
        unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
@@ -176,7 +177,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
                        (ld->set_termios)(tty, &old_termios);
                tty_ldisc_deref(ld);
        }
-       up(&tty->termios_sem);
+       mutex_unlock(&tty->termios_mutex);
 }
 
 /**
@@ -284,13 +285,13 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
 {
        struct sgttyb tmp;
 
-       down(&tty->termios_sem);
+       mutex_lock(&tty->termios_mutex);
        tmp.sg_ispeed = 0;
        tmp.sg_ospeed = 0;
        tmp.sg_erase = tty->termios->c_cc[VERASE];
        tmp.sg_kill = tty->termios->c_cc[VKILL];
        tmp.sg_flags = get_sgflags(tty);
-       up(&tty->termios_sem);
+       mutex_unlock(&tty->termios_mutex);
        
        return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
@@ -345,12 +346,12 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
        if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
                return -EFAULT;
 
-       down(&tty->termios_sem);                
+       mutex_lock(&tty->termios_mutex);
        termios =  *tty->termios;
        termios.c_cc[VERASE] = tmp.sg_erase;
        termios.c_cc[VKILL] = tmp.sg_kill;
        set_sgflags(&termios, tmp.sg_flags);
-       up(&tty->termios_sem);
+       mutex_unlock(&tty->termios_mutex);
        change_termios(tty, &termios);
        return 0;
 }
@@ -422,24 +423,28 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
  *
  *     Send a high priority character to the tty even if stopped
  *
- *     Locking: none
- *
- *     FIXME: overlapping calls with start/stop tty lose state of tty
+ *     Locking: none for xchar method, write ordering for write method.
  */
 
-static void send_prio_char(struct tty_struct *tty, char ch)
+static int send_prio_char(struct tty_struct *tty, char ch)
 {
        int     was_stopped = tty->stopped;
 
        if (tty->driver->send_xchar) {
                tty->driver->send_xchar(tty, ch);
-               return;
+               return 0;
        }
+
+       if (mutex_lock_interruptible(&tty->atomic_write_lock))
+               return -ERESTARTSYS;
+
        if (was_stopped)
                start_tty(tty);
        tty->driver->write(tty, &ch, 1);
        if (was_stopped)
                stop_tty(tty);
+       mutex_unlock(&tty->atomic_write_lock);
+       return 0;
 }
 
 int n_tty_ioctl(struct tty_struct * tty, struct file * file,
@@ -513,11 +518,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                                break;
                        case TCIOFF:
                                if (STOP_CHAR(tty) != __DISABLED_CHAR)
-                                       send_prio_char(tty, STOP_CHAR(tty));
+                                       return send_prio_char(tty, STOP_CHAR(tty));
                                break;
                        case TCION:
                                if (START_CHAR(tty) != __DISABLED_CHAR)
-                                       send_prio_char(tty, START_CHAR(tty));
+                                       return send_prio_char(tty, START_CHAR(tty));
                                break;
                        default:
                                return -EINVAL;
@@ -592,11 +597,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                case TIOCSSOFTCAR:
                        if (get_user(arg, (unsigned int __user *) arg))
                                return -EFAULT;
-                       down(&tty->termios_sem);
+                       mutex_lock(&tty->termios_mutex);
                        tty->termios->c_cflag =
                                ((tty->termios->c_cflag & ~CLOCAL) |
                                 (arg ? CLOCAL : 0));
-                       up(&tty->termios_sem);
+                       mutex_unlock(&tty->termios_mutex);
                        return 0;
                default:
                        return -ENOIOCTLCMD;
index a9247b5213d58e10708cef11b85892ccc8cb6a68..bd7a98c6ea7afb6b94bb392381157aa9e945c339 100644 (file)
@@ -474,14 +474,15 @@ static const struct file_operations vcs_fops = {
 
 static struct class *vc_class;
 
-void vcs_make_devfs(struct tty_struct *tty)
+void vcs_make_sysfs(struct tty_struct *tty)
 {
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
                        NULL, "vcs%u", tty->index + 1);
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
                        NULL, "vcsa%u", tty->index + 1);
 }
-void vcs_remove_devfs(struct tty_struct *tty)
+
+void vcs_remove_sysfs(struct tty_struct *tty)
 {
        class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
        class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
index da7e66a2a38b5dcda25270c6b4329069f36a886f..fb75da940b59c971472812795b3094966b5c8b73 100644 (file)
  *
  * Removed console_lock, enabled interrupts across all console operations
  * 13 March 2001, Andrew Morton
+ *
+ * Fixed UTF-8 mode so alternate charset modes always work according
+ * to control sequences interpreted in do_con_trol function
+ * preserving backward VT100 semigraphics compatibility,
+ * malformed UTF sequences represented as sequences of replacement glyphs,
+ * original codes or '?' as a last resort if replacement glyph is undefined
+ * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
  */
 
 #include <linux/module.h>
@@ -128,8 +135,8 @@ const struct consw *conswitchp;
 #define DEFAULT_BELL_PITCH     750
 #define DEFAULT_BELL_DURATION  (HZ/8)
 
-extern void vcs_make_devfs(struct tty_struct *tty);
-extern void vcs_remove_devfs(struct tty_struct *tty);
+extern void 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
@@ -730,7 +737,8 @@ int vc_allocate(unsigned int currcons)      /* return 0 on success */
            visual_init(vc, currcons, 1);
            if (!*vc->vc_uni_pagedir_loc)
                con_set_default_unimap(vc);
-           vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
+           if (!vc->vc_kmalloced)
+               vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
            if (!vc->vc_screenbuf) {
                kfree(vc);
                vc_cons[currcons].d = NULL;
@@ -878,8 +886,17 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
        return err;
 }
 
+int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
+{
+       int rc;
+
+       acquire_console_sem();
+       rc = vc_resize(vc, cols, lines);
+       release_console_sem();
+       return rc;
+}
 
-void vc_disallocate(unsigned int currcons)
+void vc_deallocate(unsigned int currcons)
 {
        WARN_CONSOLE_UNLOCKED();
 
@@ -2005,17 +2022,23 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
                /* Do no translation at all in control states */
                if (vc->vc_state != ESnormal) {
                        tc = c;
-               } else if (vc->vc_utf) {
+               } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
                    /* Combine UTF-8 into Unicode */
-                   /* Incomplete characters silently ignored */
+                   /* Malformed sequences as sequences of replacement glyphs */
+rescan_last_byte:
                    if(c > 0x7f) {
-                       if (vc->vc_utf_count > 0 && (c & 0xc0) == 0x80) {
-                               vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
-                               vc->vc_utf_count--;
-                               if (vc->vc_utf_count == 0)
-                                   tc = c = vc->vc_utf_char;
-                               else continue;
+                       if (vc->vc_utf_count) {
+                              if ((c & 0xc0) == 0x80) {
+                                      vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+                                              if (--vc->vc_utf_count) {
+                                              vc->vc_npar++;
+                                              continue;
+                                              }
+                                      tc = c = vc->vc_utf_char;
+                              } else
+                                      goto replacement_glyph;
                        } else {
+                               vc->vc_npar = 0;
                                if ((c & 0xe0) == 0xc0) {
                                    vc->vc_utf_count = 1;
                                    vc->vc_utf_char = (c & 0x1f);
@@ -2032,14 +2055,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
                                    vc->vc_utf_count = 5;
                                    vc->vc_utf_char = (c & 0x01);
                                } else
-                                   vc->vc_utf_count = 0;
+                                   goto replacement_glyph;
                                continue;
                              }
                    } else {
+                     if (vc->vc_utf_count)
+                             goto replacement_glyph;
                      tc = c;
-                     vc->vc_utf_count = 0;
                    }
-               } else {        /* no utf */
+               } else {        /* no utf or alternate charset mode */
                  tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
                }
 
@@ -2054,31 +2078,33 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
                  * direct-to-font zone in UTF-8 mode.
                  */
                 ok = tc && (c >= 32 ||
-                           (!vc->vc_utf && !(((vc->vc_disp_ctrl ? CTRL_ALWAYS
-                                               : CTRL_ACTION) >> c) & 1)))
+                           !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
+                                 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
                        && (c != 127 || vc->vc_disp_ctrl)
                        && (c != 128+27);
 
                if (vc->vc_state == ESnormal && ok) {
                        /* Now try to find out how to display it */
                        tc = conv_uni_to_pc(vc, tc);
-                       if ( tc == -4 ) {
+                       if (tc & ~charmask) {
+                               if ( tc == -4 ) {
                                 /* If we got -4 (not found) then see if we have
                                    defined a replacement character (U+FFFD) */
-                                tc = conv_uni_to_pc(vc, 0xfffd);
-
-                               /* One reason for the -4 can be that we just
-                                  did a clear_unimap();
-                                  try at least to show something. */
-                               if (tc == -4)
-                                    tc = c;
-                        } else if ( tc == -3 ) {
-                                /* Bad hash table -- hope for the best */
-                                tc = c;
-                        }
-                       if (tc & ~charmask)
-                                continue; /* Conversion failed */
+replacement_glyph:
+                                       tc = conv_uni_to_pc(vc, 0xfffd);
+                                       if (!(tc & ~charmask))
+                                               goto display_glyph;
+                               } else if ( tc != -3 )
+                                       continue; /* nothing to display */
+                                /* no hash table or no replacement --
+                                * hope for the best */
+                               if ( c & ~charmask )
+                                       tc = '?';
+                               else
+                                       tc = c;
+                       }
 
+display_glyph:
                        if (vc->vc_need_wrap || vc->vc_decim)
                                FLUSH
                        if (vc->vc_need_wrap) {
@@ -2102,6 +2128,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
                                vc->vc_x++;
                                draw_to = (vc->vc_pos += 2);
                        }
+                       if (vc->vc_utf_count) {
+                               if (vc->vc_npar) {
+                                       vc->vc_npar--;
+                                       goto display_glyph;
+                               }
+                               vc->vc_utf_count = 0;
+                               c = orig;
+                               goto rescan_last_byte;
+                       }
                        continue;
                }
                FLUSH
@@ -2498,7 +2533,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
                                tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
                        }
                        release_console_sem();
-                       vcs_make_devfs(tty);
+                       vcs_make_sysfs(tty);
                        return ret;
                }
        }
@@ -2511,7 +2546,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
  * and taking a ref against the tty while we're in the process of forgetting
  * about it and cleaning things up.
  *
- * This is because vcs_remove_devfs() can sleep and will drop the BKL.
+ * This is because vcs_remove_sysfs() can sleep and will drop the BKL.
  */
 static void con_close(struct tty_struct *tty, struct file *filp)
 {
@@ -2524,7 +2559,7 @@ static void con_close(struct tty_struct *tty, struct file *filp)
                        vc->vc_tty = NULL;
                tty->driver_data = NULL;
                release_console_sem();
-               vcs_remove_devfs(tty);
+               vcs_remove_sysfs(tty);
                mutex_unlock(&tty_mutex);
                /*
                 * tty_mutex is released, but we still hold BKL, so there is
@@ -3765,6 +3800,7 @@ EXPORT_SYMBOL(default_blu);
 EXPORT_SYMBOL(update_region);
 EXPORT_SYMBOL(redraw_screen);
 EXPORT_SYMBOL(vc_resize);
+EXPORT_SYMBOL(vc_lock_resize);
 EXPORT_SYMBOL(fg_console);
 EXPORT_SYMBOL(console_blank_hook);
 EXPORT_SYMBOL(console_blanked);
index a5628a8b66207a4420c99f91565a6746495b14ee..a53e382cc10747b2e73a9386c67a78f73700582f 100644 (file)
@@ -96,7 +96,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
                if (!perm)
                        return -EPERM;
                if (!i && v == K_NOSUCHMAP) {
-                       /* disallocate map */
+                       /* deallocate map */
                        key_map = key_maps[s];
                        if (s && key_map) {
                            key_maps[s] = NULL;
@@ -819,20 +819,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                if (arg > MAX_NR_CONSOLES)
                        return -ENXIO;
                if (arg == 0) {
-                   /* disallocate all unused consoles, but leave 0 */
+                   /* deallocate all unused consoles, but leave 0 */
                        acquire_console_sem();
                        for (i=1; i<MAX_NR_CONSOLES; i++)
                                if (! VT_BUSY(i))
-                                       vc_disallocate(i);
+                                       vc_deallocate(i);
                        release_console_sem();
                } else {
-                       /* disallocate a single console, if possible */
+                       /* deallocate a single console, if possible */
                        arg--;
                        if (VT_BUSY(arg))
                                return -EBUSY;
                        if (arg) {                            /* leave 0 */
                                acquire_console_sem();
-                               vc_disallocate(arg);
+                               vc_deallocate(arg);
                                release_console_sem();
                        }
                }
@@ -847,11 +847,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                if (get_user(ll, &vtsizes->v_rows) ||
                    get_user(cc, &vtsizes->v_cols))
                        return -EFAULT;
-               for (i = 0; i < MAX_NR_CONSOLES; i++) {
-                       acquire_console_sem();
-                       vc_resize(vc_cons[i].d, cc, ll);
-                       release_console_sem();
-               }
+               for (i = 0; i < MAX_NR_CONSOLES; i++)
+                       vc_lock_resize(vc_cons[i].d, cc, ll);
                return 0;
        }
 
index f114d7b5bb2a0f195933cb377099c09fa4becb83..77ab7e020da0a8ee2672a379d79f93aed3235899 100644 (file)
@@ -165,6 +165,13 @@ config EP93XX_WATCHDOG
          To compile this driver as a module, choose M here: the
          module will be called ep93xx_wdt.
 
+config OMAP_WATCHDOG
+       tristate "OMAP Watchdog"
+       depends on WATCHDOG && (ARCH_OMAP16XX || ARCH_OMAP24XX)
+       help
+         Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog.  Say 'Y' here to
+         enable the OMAP1610/OMAP1710 watchdog timer.
+
 # X86 (i386 + ia64 + x86_64) Architecture
 
 config ACQUIRE_WDT
index 6ab77b61a6434635a8a6e2ba8716d2b000bcf56a..5099f8be8cc51efab2bc38d98dfd2df495833daf 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
 
 # ARM Architecture
 obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
+obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
 obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
new file mode 100644 (file)
index 0000000..8f90b90
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * linux/drivers/char/watchdog/omap_wdt.c
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx 32KHz (non-secure) watchdog
+ *
+ * Author: MontaVista Software, Inc.
+ *      <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ *     Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ *     (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ *     Based on SoftDog driver by Alan Cox <alan@redhat.com>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ *     1. Modified to support OMAP1610 32-KHz watchdog timer
+ *     2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ *     Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/moduleparam.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/bitops.h>
+
+#include <asm/arch/prcm.h>
+
+#include "omap_wdt.h"
+
+static unsigned timer_margin;
+module_param(timer_margin, uint, 0);
+MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
+
+static int omap_wdt_users;
+static struct clk *armwdt_ck = NULL;
+static struct clk *mpu_wdt_ick = NULL;
+static struct clk *mpu_wdt_fck = NULL;
+
+static unsigned int wdt_trgr_pattern = 0x1234;
+
+static void omap_wdt_ping(void)
+{
+       /* wait for posted write to complete */
+       while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
+               cpu_relax();
+       wdt_trgr_pattern = ~wdt_trgr_pattern;
+       omap_writel(wdt_trgr_pattern, (OMAP_WATCHDOG_TGR));
+       /* wait for posted write to complete */
+       while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
+               cpu_relax();
+       /* reloaded WCRR from WLDR */
+}
+
+static void omap_wdt_enable(void)
+{
+       /* Sequence to enable the watchdog */
+       omap_writel(0xBBBB, OMAP_WATCHDOG_SPR);
+       while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
+               cpu_relax();
+       omap_writel(0x4444, OMAP_WATCHDOG_SPR);
+       while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
+               cpu_relax();
+}
+
+static void omap_wdt_disable(void)
+{
+       /* sequence required to disable watchdog */
+       omap_writel(0xAAAA, OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
+               cpu_relax();
+       omap_writel(0x5555, OMAP_WATCHDOG_SPR); /* TIMER_MODE */
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
+               cpu_relax();
+}
+
+static void omap_wdt_adjust_timeout(unsigned new_timeout)
+{
+       if (new_timeout < TIMER_MARGIN_MIN)
+               new_timeout = TIMER_MARGIN_DEFAULT;
+       if (new_timeout > TIMER_MARGIN_MAX)
+               new_timeout = TIMER_MARGIN_MAX;
+       timer_margin = new_timeout;
+}
+
+static void omap_wdt_set_timeout(void)
+{
+       u32 pre_margin = GET_WLDR_VAL(timer_margin);
+
+       /* just count up at 32 KHz */
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
+               cpu_relax();
+       omap_writel(pre_margin, OMAP_WATCHDOG_LDR);
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
+               cpu_relax();
+}
+
+/*
+ *     Allow only one task to hold it open
+ */
+
+static int omap_wdt_open(struct inode *inode, struct file *file)
+{
+       if (test_and_set_bit(1, (unsigned long *)&omap_wdt_users))
+               return -EBUSY;
+
+       if (cpu_is_omap16xx())
+               clk_enable(armwdt_ck);  /* Enable the clock */
+
+       if (cpu_is_omap24xx()) {
+               clk_enable(mpu_wdt_ick);    /* Enable the interface clock */
+               clk_enable(mpu_wdt_fck);    /* Enable the functional clock */
+       }
+
+       /* initialize prescaler */
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
+               cpu_relax();
+       omap_writel((1 << 5) | (PTV << 2), OMAP_WATCHDOG_CNTRL);
+       while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
+               cpu_relax();
+
+       omap_wdt_set_timeout();
+       omap_wdt_enable();
+       return 0;
+}
+
+static int omap_wdt_release(struct inode *inode, struct file *file)
+{
+       /*
+        *      Shut off the timer unless NOWAYOUT is defined.
+        */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+       omap_wdt_disable();
+
+       if (cpu_is_omap16xx()) {
+               clk_disable(armwdt_ck); /* Disable the clock */
+               clk_put(armwdt_ck);
+               armwdt_ck = NULL;
+       }
+
+       if (cpu_is_omap24xx()) {
+               clk_disable(mpu_wdt_ick);       /* Disable the clock */
+               clk_disable(mpu_wdt_fck);       /* Disable the clock */
+               clk_put(mpu_wdt_ick);
+               clk_put(mpu_wdt_fck);
+               mpu_wdt_ick = NULL;
+               mpu_wdt_fck = NULL;
+       }
+#else
+       printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
+#endif
+       omap_wdt_users = 0;
+       return 0;
+}
+
+static ssize_t
+omap_wdt_write(struct file *file, const char __user *data,
+               size_t len, loff_t *ppos)
+{
+       /* Refresh LOAD_TIME. */
+       if (len)
+               omap_wdt_ping();
+       return len;
+}
+
+static int
+omap_wdt_ioctl(struct inode *inode, struct file *file,
+       unsigned int cmd, unsigned long arg)
+{
+       int new_margin;
+       static struct watchdog_info ident = {
+               .identity = "OMAP Watchdog",
+               .options = WDIOF_SETTIMEOUT,
+               .firmware_version = 0,
+       };
+
+       switch (cmd) {
+       default:
+               return -ENOIOCTLCMD;
+       case WDIOC_GETSUPPORT:
+               return copy_to_user((struct watchdog_info __user *)arg, &ident,
+                               sizeof(ident));
+       case WDIOC_GETSTATUS:
+               return put_user(0, (int __user *)arg);
+       case WDIOC_GETBOOTSTATUS:
+               if (cpu_is_omap16xx())
+                       return put_user(omap_readw(ARM_SYSST),
+                                       (int __user *)arg);
+               if (cpu_is_omap24xx())
+                       return put_user(omap_prcm_get_reset_sources(),
+                                       (int __user *)arg);
+       case WDIOC_KEEPALIVE:
+               omap_wdt_ping();
+               return 0;
+       case WDIOC_SETTIMEOUT:
+               if (get_user(new_margin, (int __user *)arg))
+                       return -EFAULT;
+               omap_wdt_adjust_timeout(new_margin);
+
+               omap_wdt_disable();
+               omap_wdt_set_timeout();
+               omap_wdt_enable();
+
+               omap_wdt_ping();
+               /* Fall */
+       case WDIOC_GETTIMEOUT:
+               return put_user(timer_margin, (int __user *)arg);
+       }
+}
+
+static struct file_operations omap_wdt_fops = {
+       .owner = THIS_MODULE,
+       .write = omap_wdt_write,
+       .ioctl = omap_wdt_ioctl,
+       .open = omap_wdt_open,
+       .release = omap_wdt_release,
+};
+
+static struct miscdevice omap_wdt_miscdev = {
+       .minor = WATCHDOG_MINOR,
+       .name = "watchdog",
+       .fops = &omap_wdt_fops
+};
+
+static int __init omap_wdt_probe(struct platform_device *pdev)
+{
+       struct resource *res, *mem;
+       int ret;
+
+       /* reserve static register mappings */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENOENT;
+
+       mem = request_mem_region(res->start, res->end - res->start + 1,
+                                pdev->name);
+       if (mem == NULL)
+               return -EBUSY;
+
+       platform_set_drvdata(pdev, mem);
+
+       omap_wdt_users = 0;
+
+       if (cpu_is_omap16xx()) {
+               armwdt_ck = clk_get(&pdev->dev, "armwdt_ck");
+               if (IS_ERR(armwdt_ck)) {
+                       ret = PTR_ERR(armwdt_ck);
+                       armwdt_ck = NULL;
+                       goto fail;
+               }
+       }
+
+       if (cpu_is_omap24xx()) {
+               mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick");
+               if (IS_ERR(mpu_wdt_ick)) {
+                       ret = PTR_ERR(mpu_wdt_ick);
+                       mpu_wdt_ick = NULL;
+                       goto fail;
+               }
+               mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck");
+               if (IS_ERR(mpu_wdt_fck)) {
+                       ret = PTR_ERR(mpu_wdt_fck);
+                       mpu_wdt_fck = NULL;
+                       goto fail;
+               }
+       }
+
+       omap_wdt_disable();
+       omap_wdt_adjust_timeout(timer_margin);
+
+       omap_wdt_miscdev.dev = &pdev->dev;
+       ret = misc_register(&omap_wdt_miscdev);
+       if (ret)
+               goto fail;
+
+       pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin);
+
+       /* autogate OCP interface clock */
+       omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG);
+       return 0;
+
+fail:
+       if (armwdt_ck)
+               clk_put(armwdt_ck);
+       if (mpu_wdt_ick)
+               clk_put(mpu_wdt_ick);
+       if (mpu_wdt_fck)
+               clk_put(mpu_wdt_fck);
+       release_resource(mem);
+       return ret;
+}
+
+static void omap_wdt_shutdown(struct platform_device *pdev)
+{
+       omap_wdt_disable();
+}
+
+static int omap_wdt_remove(struct platform_device *pdev)
+{
+       struct resource *mem = platform_get_drvdata(pdev);
+       misc_deregister(&omap_wdt_miscdev);
+       release_resource(mem);
+       if (armwdt_ck)
+               clk_put(armwdt_ck);
+       if (mpu_wdt_ick)
+               clk_put(mpu_wdt_ick);
+       if (mpu_wdt_fck)
+               clk_put(mpu_wdt_fck);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* REVISIT ... not clear this is the best way to handle system suspend; and
+ * it's very inappropriate for selective device suspend (e.g. suspending this
+ * through sysfs rather than by stopping the watchdog daemon).  Also, this
+ * may not play well enough with NOWAYOUT...
+ */
+
+static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       if (omap_wdt_users)
+               omap_wdt_disable();
+       return 0;
+}
+
+static int omap_wdt_resume(struct platform_device *pdev)
+{
+       if (omap_wdt_users) {
+               omap_wdt_enable();
+               omap_wdt_ping();
+       }
+       return 0;
+}
+
+#else
+#define        omap_wdt_suspend        NULL
+#define        omap_wdt_resume         NULL
+#endif
+
+static struct platform_driver omap_wdt_driver = {
+       .probe          = omap_wdt_probe,
+       .remove         = omap_wdt_remove,
+       .shutdown       = omap_wdt_shutdown,
+       .suspend        = omap_wdt_suspend,
+       .resume         = omap_wdt_resume,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "omap_wdt",
+       },
+};
+
+static int __init omap_wdt_init(void)
+{
+       return platform_driver_register(&omap_wdt_driver);
+}
+
+static void __exit omap_wdt_exit(void)
+{
+       platform_driver_unregister(&omap_wdt_driver);
+}
+
+module_init(omap_wdt_init);
+module_exit(omap_wdt_exit);
+
+MODULE_AUTHOR("George G. Davis");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/omap_wdt.h b/drivers/char/watchdog/omap_wdt.h
new file mode 100644 (file)
index 0000000..52a532a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  linux/drivers/char/watchdog/omap_wdt.h
+ *
+ *  BRIEF MODULE DESCRIPTION
+ *      OMAP Watchdog timer register definitions
+ *
+ *  Copyright (C) 2004 Texas Instruments.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _OMAP_WATCHDOG_H
+#define _OMAP_WATCHDOG_H
+
+#define OMAP1610_WATCHDOG_BASE         0xfffeb000
+#define OMAP2420_WATCHDOG_BASE         0x48022000      /*WDT Timer 2 */
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP_WATCHDOG_BASE             OMAP2420_WATCHDOG_BASE
+#else
+#define OMAP_WATCHDOG_BASE             OMAP1610_WATCHDOG_BASE
+#define RM_RSTST_WKUP                  0
+#endif
+
+#define OMAP_WATCHDOG_REV              (OMAP_WATCHDOG_BASE + 0x00)
+#define OMAP_WATCHDOG_SYS_CONFIG       (OMAP_WATCHDOG_BASE + 0x10)
+#define OMAP_WATCHDOG_STATUS           (OMAP_WATCHDOG_BASE + 0x14)
+#define OMAP_WATCHDOG_CNTRL            (OMAP_WATCHDOG_BASE + 0x24)
+#define OMAP_WATCHDOG_CRR              (OMAP_WATCHDOG_BASE + 0x28)
+#define OMAP_WATCHDOG_LDR              (OMAP_WATCHDOG_BASE + 0x2c)
+#define OMAP_WATCHDOG_TGR              (OMAP_WATCHDOG_BASE + 0x30)
+#define OMAP_WATCHDOG_WPS              (OMAP_WATCHDOG_BASE + 0x34)
+#define OMAP_WATCHDOG_SPR              (OMAP_WATCHDOG_BASE + 0x48)
+
+/* Using the prescaler, the OMAP watchdog could go for many
+ * months before firing.  These limits work without scaling,
+ * with the 60 second default assumed by most tools and docs.
+ */
+#define TIMER_MARGIN_MAX       (24 * 60 * 60)  /* 1 day */
+#define TIMER_MARGIN_DEFAULT   60      /* 60 secs */
+#define TIMER_MARGIN_MIN       1
+
+#define PTV                    0       /* prescale */
+#define GET_WLDR_VAL(secs)     (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+
+#endif                         /* _OMAP_WATCHDOG_H */
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 b9e3886d9e1618cc4b85345e81a8a2c23fb876ea..b8b596d5778dbe03295395eccbad2176a25c3bfa 100644 (file)
@@ -123,6 +123,26 @@ static void __init dmi_save_devices(struct dmi_header *dm)
                dev->type = *d++ & 0x7f;
                dev->name = dmi_string(dm, *d);
                dev->device_data = NULL;
+               list_add(&dev->list, &dmi_devices);
+       }
+}
+
+static void __init dmi_save_oem_strings_devices(struct dmi_header *dm)
+{
+       int i, count = *(u8 *)(dm + 1);
+       struct dmi_device *dev;
+
+       for (i = 1; i <= count; i++) {
+               dev = dmi_alloc(sizeof(*dev));
+               if (!dev) {
+                       printk(KERN_ERR
+                          "dmi_save_oem_strings_devices: out of memory.\n");
+                       break;
+               }
+
+               dev->type = DMI_DEV_TYPE_OEM_STRING;
+               dev->name = dmi_string(dm, i);
+               dev->device_data = NULL;
 
                list_add(&dev->list, &dmi_devices);
        }
@@ -181,6 +201,9 @@ static void __init dmi_decode(struct dmi_header *dm)
        case 10:        /* Onboard Devices Information */
                dmi_save_devices(dm);
                break;
+       case 11:        /* OEM Strings */
+               dmi_save_oem_strings_devices(dm);
+               break;
        case 38:        /* IPMI Device Information */
                dmi_save_ipmi_device(dm);
        }
index 0e31a0c496e8ae44ce3ed29322d6169787480e91..9b88b25b6edbdfb098dc189c1e54c0efb60e5b4b 100644 (file)
@@ -53,7 +53,7 @@ config SENSORS_ADM1021
 
 config SENSORS_ADM1025
        tristate "Analog Devices ADM1025 and compatibles"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        select HWMON_VID
        help
          If you say yes here you get support for Analog Devices ADM1025
@@ -94,6 +94,16 @@ config SENSORS_ADM9240
          This driver can also be built as a module.  If so, the module
          will be called adm9240.
 
+config SENSORS_K8TEMP
+       tristate "AMD K8 processor sensor"
+       depends on HWMON && X86 && PCI && EXPERIMENTAL
+       help
+         If you say yes here you get support for the temperature
+         sensor(s) inside your AMD K8 CPU.
+
+         This driver can also be built as a module.  If so, the module
+         will be called k8temp.
+
 config SENSORS_ASB100
        tristate "Asus ASB100 Bach"
        depends on HWMON && I2C && EXPERIMENTAL
@@ -121,7 +131,7 @@ config SENSORS_ATXP1
 
 config SENSORS_DS1621
        tristate "Dallas Semiconductor DS1621 and DS1625"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for Dallas Semiconductor
          DS1621 and DS1625 sensor chips.
@@ -141,7 +151,7 @@ config SENSORS_F71805F
 
 config SENSORS_FSCHER
        tristate "FSC Hermes"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for Fujitsu Siemens
          Computers Hermes sensor chips.
@@ -151,7 +161,7 @@ config SENSORS_FSCHER
 
 config SENSORS_FSCPOS
        tristate "FSC Poseidon"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for Fujitsu Siemens
          Computers Poseidon sensor chips.
@@ -171,7 +181,7 @@ config SENSORS_GL518SM
 
 config SENSORS_GL520SM
        tristate "Genesys Logic GL520SM"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        select HWMON_VID
        help
          If you say yes here you get support for Genesys Logic GL520SM
@@ -186,15 +196,15 @@ config SENSORS_IT87
        select I2C_ISA
        select HWMON_VID
        help
-         If you say yes here you get support for ITE IT87xx sensor chips
-         and clones: SiS960.
+         If you say yes here you get support for ITE IT8705F, IT8712F,
+         IT8716F and IT8718F sensor chips, and the SiS960 clone.
 
          This driver can also be built as a module.  If so, the module
          will be called it87.
 
 config SENSORS_LM63
        tristate "National Semiconductor LM63"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for the National Semiconductor
          LM63 remote diode digital temperature sensor with integrated fan
@@ -231,7 +241,7 @@ config SENSORS_LM75
 
 config SENSORS_LM77
        tristate "National Semiconductor LM77"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for National Semiconductor LM77
          sensor chips.
@@ -241,7 +251,7 @@ config SENSORS_LM77
 
 config SENSORS_LM78
        tristate "National Semiconductor LM78 and compatibles"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        select I2C_ISA
        select HWMON_VID
        help
@@ -284,7 +294,7 @@ config SENSORS_LM85
 
 config SENSORS_LM87
        tristate "National Semiconductor LM87"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        select HWMON_VID
        help
          If you say yes here you get support for National Semiconductor LM87
@@ -309,7 +319,7 @@ config SENSORS_LM90
 
 config SENSORS_LM92
        tristate "National Semiconductor LM92 and compatibles"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for National Semiconductor LM92
          and Maxim MAX6635 sensor chips.
@@ -319,7 +329,7 @@ config SENSORS_LM92
 
 config SENSORS_MAX1619
        tristate "Maxim MAX1619 sensor chip"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        help
          If you say yes here you get support for MAX1619 sensor chip.
 
@@ -354,7 +364,7 @@ config SENSORS_SIS5595
 
 config SENSORS_SMSC47M1
        tristate "SMSC LPC47M10x and compatibles"
-       depends on HWMON && I2C && EXPERIMENTAL
+       depends on HWMON && I2C
        select I2C_ISA
        help
          If you say yes here you get support for the integrated fan
@@ -407,8 +417,19 @@ config SENSORS_VIA686A
          This driver can also be built as a module.  If so, the module
          will be called via686a.
 
+config SENSORS_VT1211
+       tristate "VIA VT1211"
+       depends on HWMON && EXPERIMENTAL
+       select HWMON_VID
+       help
+         If you say yes here then you get support for hardware monitoring
+         features of the VIA VT1211 Super-I/O chip.
+
+         This driver can also be built as a module.  If so, the module
+         will be called vt1211.
+
 config SENSORS_VT8231
-       tristate "VT8231"
+       tristate "VIA VT8231"
        depends on HWMON && I2C && PCI && EXPERIMENTAL
        select HWMON_VID
        select I2C_ISA
index 31415843a91ae6c2e1da679c7a7b4f9f04c3812e..af01cc64f7d265e31b7c9700f9c9eeefd596f43a 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
 obj-$(CONFIG_SENSORS_GL520SM)  += gl520sm.o
 obj-$(CONFIG_SENSORS_HDAPS)    += hdaps.o
 obj-$(CONFIG_SENSORS_IT87)     += it87.o
+obj-$(CONFIG_SENSORS_K8TEMP)   += k8temp.o
 obj-$(CONFIG_SENSORS_LM63)     += lm63.o
 obj-$(CONFIG_SENSORS_LM70)     += lm70.o
 obj-$(CONFIG_SENSORS_LM75)     += lm75.o
@@ -45,6 +46,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_VIA686A)  += via686a.o
+obj-$(CONFIG_SENSORS_VT1211)   += vt1211.o
 obj-$(CONFIG_SENSORS_VT8231)   += vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)        += w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)        += w83l785ts.o
index 35ad1b0327268dac11cf8a3f465a884aef0f42a2..e5cb0fdab9b15d8529274531a8879a31dd2cb0a0 100644 (file)
@@ -1354,13 +1354,39 @@ LEAVE_UPDATE:
                return NULL;
 }
 
+#ifdef CONFIG_PM
+static int abituguru_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct abituguru_data *data = platform_get_drvdata(pdev);
+       /* make sure all communications with the uguru are done and no new
+          ones are started */
+       mutex_lock(&data->update_lock);
+       return 0;
+}
+
+static int abituguru_resume(struct platform_device *pdev)
+{
+       struct abituguru_data *data = platform_get_drvdata(pdev);
+       /* See if the uGuru is still ready */
+       if (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT)
+               data->uguru_ready = 0;
+       mutex_unlock(&data->update_lock);
+       return 0;
+}
+#else
+#define abituguru_suspend      NULL
+#define abituguru_resume       NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver abituguru_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = ABIT_UGURU_NAME,
        },
-       .probe  = abituguru_probe,
-       .remove = __devexit_p(abituguru_remove),
+       .probe          = abituguru_probe,
+       .remove         = __devexit_p(abituguru_remove),
+       .suspend        = abituguru_suspend,
+       .resume         = abituguru_resume,
 };
 
 static int __init abituguru_detect(void)
index 2b6e74dd4a82079c6eb18b44719846c33ae961ed..c466329b2ef4745100f00346c4f989958f42828e 100644 (file)
@@ -190,6 +190,21 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, adm1021_detect);
 }
 
+static struct attribute *adm1021_attributes[] = {
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group adm1021_group = {
+       .attrs = adm1021_attributes,
+};
+
 static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
 {
        int i;
@@ -287,22 +302,19 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
                adm1021_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1021_group)))
+               goto error2;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto error2;
+               goto error3;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
        return 0;
 
+error3:
+       sysfs_remove_group(&new_client->dev.kobj, &adm1021_group);
 error2:
        i2c_detach_client(new_client);
 error1:
@@ -326,6 +338,7 @@ static int adm1021_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &adm1021_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index a4c859c9fbf82c3f6ef09649e621441c6842044d..8c562885b54b031fe03746322b188a5566366d12 100644 (file)
@@ -315,6 +315,49 @@ static int adm1025_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, adm1025_detect);
 }
 
+static struct attribute *adm1025_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in5_max.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       NULL
+};
+
+static const struct attribute_group adm1025_group = {
+       .attrs = adm1025_attributes,
+};
+
+static struct attribute *adm1025_attributes_opt[] = {
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+       NULL
+};
+
+static const struct attribute_group adm1025_group_opt = {
+       .attrs = adm1025_attributes_opt,
+};
+
 /*
  * The following function does more than just detection. If detection
  * succeeds, it also registers the new chip.
@@ -415,46 +458,31 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
        adm1025_init_client(new_client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1025_group)))
                goto exit_detach;
-       }
-
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in5_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in5_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in5_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-       device_create_file(&new_client->dev, &dev_attr_vrm);
 
        /* Pin 11 is either in4 (+12V) or VID4 */
        if (!(config & 0x20)) {
-               device_create_file(&new_client->dev, &dev_attr_in4_input);
-               device_create_file(&new_client->dev, &dev_attr_in4_min);
-               device_create_file(&new_client->dev, &dev_attr_in4_max);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_max)))
+                       goto exit_remove;
+       }
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
        }
 
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &adm1025_group);
+       sysfs_remove_group(&new_client->dev.kobj, &adm1025_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -511,6 +539,8 @@ static int adm1025_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &adm1025_group);
+       sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 6d4f8b8d358edde71408f52554555aafcd21e594..b4618b2705f76ae1805ab5dd5f24c2c76833d241 100644 (file)
@@ -323,15 +323,6 @@ static int adm1026_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, adm1026_detect);
 }
 
-static int adm1026_detach_client(struct i2c_client *client)
-{
-       struct adm1026_data *data = i2c_get_clientdata(client);
-       hwmon_device_unregister(data->class_dev);
-       i2c_detach_client(client);
-       kfree(data);
-       return 0;
-}
-
 static int adm1026_read_value(struct i2c_client *client, u8 reg)
 {
        int res;
@@ -1450,6 +1441,135 @@ static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
 static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
 static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
 
+static struct attribute *adm1026_attributes[] = {
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in6_input.dev_attr.attr,
+       &sensor_dev_attr_in6_max.dev_attr.attr,
+       &sensor_dev_attr_in6_min.dev_attr.attr,
+       &sensor_dev_attr_in7_input.dev_attr.attr,
+       &sensor_dev_attr_in7_max.dev_attr.attr,
+       &sensor_dev_attr_in7_min.dev_attr.attr,
+       &sensor_dev_attr_in8_input.dev_attr.attr,
+       &sensor_dev_attr_in8_max.dev_attr.attr,
+       &sensor_dev_attr_in8_min.dev_attr.attr,
+       &sensor_dev_attr_in9_input.dev_attr.attr,
+       &sensor_dev_attr_in9_max.dev_attr.attr,
+       &sensor_dev_attr_in9_min.dev_attr.attr,
+       &sensor_dev_attr_in10_input.dev_attr.attr,
+       &sensor_dev_attr_in10_max.dev_attr.attr,
+       &sensor_dev_attr_in10_min.dev_attr.attr,
+       &sensor_dev_attr_in11_input.dev_attr.attr,
+       &sensor_dev_attr_in11_max.dev_attr.attr,
+       &sensor_dev_attr_in11_min.dev_attr.attr,
+       &sensor_dev_attr_in12_input.dev_attr.attr,
+       &sensor_dev_attr_in12_max.dev_attr.attr,
+       &sensor_dev_attr_in12_min.dev_attr.attr,
+       &sensor_dev_attr_in13_input.dev_attr.attr,
+       &sensor_dev_attr_in13_max.dev_attr.attr,
+       &sensor_dev_attr_in13_min.dev_attr.attr,
+       &sensor_dev_attr_in14_input.dev_attr.attr,
+       &sensor_dev_attr_in14_max.dev_attr.attr,
+       &sensor_dev_attr_in14_min.dev_attr.attr,
+       &sensor_dev_attr_in15_input.dev_attr.attr,
+       &sensor_dev_attr_in15_max.dev_attr.attr,
+       &sensor_dev_attr_in15_min.dev_attr.attr,
+       &sensor_dev_attr_in16_input.dev_attr.attr,
+       &sensor_dev_attr_in16_max.dev_attr.attr,
+       &sensor_dev_attr_in16_min.dev_attr.attr,
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &sensor_dev_attr_fan3_input.dev_attr.attr,
+       &sensor_dev_attr_fan3_div.dev_attr.attr,
+       &sensor_dev_attr_fan3_min.dev_attr.attr,
+       &sensor_dev_attr_fan4_input.dev_attr.attr,
+       &sensor_dev_attr_fan4_div.dev_attr.attr,
+       &sensor_dev_attr_fan4_min.dev_attr.attr,
+       &sensor_dev_attr_fan5_input.dev_attr.attr,
+       &sensor_dev_attr_fan5_div.dev_attr.attr,
+       &sensor_dev_attr_fan5_min.dev_attr.attr,
+       &sensor_dev_attr_fan6_input.dev_attr.attr,
+       &sensor_dev_attr_fan6_div.dev_attr.attr,
+       &sensor_dev_attr_fan6_min.dev_attr.attr,
+       &sensor_dev_attr_fan7_input.dev_attr.attr,
+       &sensor_dev_attr_fan7_div.dev_attr.attr,
+       &sensor_dev_attr_fan7_min.dev_attr.attr,
+       &sensor_dev_attr_fan8_input.dev_attr.attr,
+       &sensor_dev_attr_fan8_div.dev_attr.attr,
+       &sensor_dev_attr_fan8_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_min.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_min.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_offset.dev_attr.attr,
+       &sensor_dev_attr_temp2_offset.dev_attr.attr,
+       &sensor_dev_attr_temp3_offset.dev_attr.attr,
+       &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+       &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
+       &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
+       &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
+       &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
+       &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit.dev_attr.attr,
+       &sensor_dev_attr_temp3_crit.dev_attr.attr,
+       &dev_attr_temp1_crit_enable.attr,
+       &dev_attr_temp2_crit_enable.attr,
+       &dev_attr_temp3_crit_enable.attr,
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_alarm_mask.attr,
+       &dev_attr_gpio.attr,
+       &dev_attr_gpio_mask.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_pwm3.attr,
+       &dev_attr_pwm1_enable.attr,
+       &dev_attr_pwm2_enable.attr,
+       &dev_attr_pwm3_enable.attr,
+       &dev_attr_temp1_auto_point1_pwm.attr,
+       &dev_attr_temp2_auto_point1_pwm.attr,
+       &dev_attr_temp3_auto_point1_pwm.attr,
+       &dev_attr_temp1_auto_point2_pwm.attr,
+       &dev_attr_temp2_auto_point2_pwm.attr,
+       &dev_attr_temp3_auto_point2_pwm.attr,
+       &dev_attr_analog_out.attr,
+       NULL
+};
+
+static const struct attribute_group adm1026_group = {
+       .attrs = adm1026_attributes,
+};
+
 static int adm1026_detect(struct i2c_adapter *adapter, int address,
                          int kind)
 {
@@ -1554,145 +1674,20 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
        adm1026_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group)))
+               goto exitdetach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exitdetach;
+               goto exitremove;
        }
 
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in11_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in11_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in11_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in12_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in12_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in12_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in13_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in13_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in13_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in14_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in14_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in14_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in15_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in15_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in15_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in16_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in16_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in16_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan4_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan4_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan4_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan5_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan5_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan5_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan6_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan6_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan6_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan7_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan7_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan7_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan8_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan8_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan8_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_offset.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_offset.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_offset.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp1_auto_point1_temp.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp2_auto_point1_temp.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp3_auto_point1_temp.dev_attr);
-       device_create_file(&new_client->dev,
-               &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr);
-       device_create_file(&new_client->dev,
-               &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr);
-       device_create_file(&new_client->dev,
-               &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp1_auto_point2_temp.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp2_auto_point2_temp.dev_attr);
-       device_create_file(&new_client->dev, 
-               &sensor_dev_attr_temp3_auto_point2_temp.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
-       device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-       device_create_file(&new_client->dev, &dev_attr_vrm);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_alarm_mask);
-       device_create_file(&new_client->dev, &dev_attr_gpio);
-       device_create_file(&new_client->dev, &dev_attr_gpio_mask);
-       device_create_file(&new_client->dev, &dev_attr_pwm1);
-       device_create_file(&new_client->dev, &dev_attr_pwm2);
-       device_create_file(&new_client->dev, &dev_attr_pwm3);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_point1_pwm);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_point1_pwm);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_point1_pwm);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_point2_pwm);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_point2_pwm);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_point2_pwm);
-       device_create_file(&new_client->dev, &dev_attr_analog_out);
        return 0;
 
        /* Error out and cleanup code */
+exitremove:
+       sysfs_remove_group(&new_client->dev.kobj, &adm1026_group);
 exitdetach:
        i2c_detach_client(new_client);
 exitfree:
@@ -1700,6 +1695,17 @@ exitfree:
 exit:
        return err;
 }
+
+static int adm1026_detach_client(struct i2c_client *client)
+{
+       struct adm1026_data *data = i2c_get_clientdata(client);
+       hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &adm1026_group);
+       i2c_detach_client(client);
+       kfree(data);
+       return 0;
+}
+
 static int __init sm_adm1026_init(void)
 {
        return i2c_add_driver(&adm1026_driver);
index 3bf2da621aedb39f548f139c31f17ab8d88bac81..122683fc91d096f271e3a372f17b5c8d51bfd2cb 100644 (file)
@@ -730,6 +730,61 @@ static int adm1031_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, adm1031_detect);
 }
 
+static struct attribute *adm1031_attributes[] = {
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_auto_fan1_channel.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_crit.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_crit.attr,
+
+       &dev_attr_auto_temp1_off.attr,
+       &dev_attr_auto_temp1_min.attr,
+       &dev_attr_auto_temp1_max.attr,
+
+       &dev_attr_auto_temp2_off.attr,
+       &dev_attr_auto_temp2_min.attr,
+       &dev_attr_auto_temp2_max.attr,
+
+       &dev_attr_auto_fan1_min_pwm.attr,
+
+       &dev_attr_alarms.attr,
+
+       NULL
+};
+
+static const struct attribute_group adm1031_group = {
+       .attrs = adm1031_attributes,
+};
+
+static struct attribute *adm1031_attributes_opt[] = {
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_div.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_auto_fan2_channel.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp3_min.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_temp3_crit.attr,
+       &dev_attr_auto_temp3_off.attr,
+       &dev_attr_auto_temp3_min.attr,
+       &dev_attr_auto_temp3_max.attr,
+       &dev_attr_auto_fan2_min_pwm.attr,
+       NULL
+};
+
+static const struct attribute_group adm1031_group_opt = {
+       .attrs = adm1031_attributes_opt,
+};
+
 /* This function is called by i2c_probe */
 static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
 {
@@ -789,57 +844,26 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
        adm1031_init_client(new_client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1031_group)))
                goto exit_detach;
-       }
-
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_pwm1);
-       device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-
-       device_create_file(&new_client->dev, &dev_attr_auto_temp1_off);
-       device_create_file(&new_client->dev, &dev_attr_auto_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_auto_temp1_max);
-
-       device_create_file(&new_client->dev, &dev_attr_auto_temp2_off);
-       device_create_file(&new_client->dev, &dev_attr_auto_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_auto_temp2_max);
-
-       device_create_file(&new_client->dev, &dev_attr_auto_fan1_min_pwm);
-
-       device_create_file(&new_client->dev, &dev_attr_alarms);
 
        if (kind == adm1031) {
-               device_create_file(&new_client->dev, &dev_attr_fan2_input);
-               device_create_file(&new_client->dev, &dev_attr_fan2_div);
-               device_create_file(&new_client->dev, &dev_attr_fan2_min);
-               device_create_file(&new_client->dev, &dev_attr_pwm2);
-               device_create_file(&new_client->dev,
-                                  &dev_attr_auto_fan2_channel);
-               device_create_file(&new_client->dev, &dev_attr_temp3_input);
-               device_create_file(&new_client->dev, &dev_attr_temp3_min);
-               device_create_file(&new_client->dev, &dev_attr_temp3_max);
-               device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-               device_create_file(&new_client->dev, &dev_attr_auto_temp3_off);
-               device_create_file(&new_client->dev, &dev_attr_auto_temp3_min);
-               device_create_file(&new_client->dev, &dev_attr_auto_temp3_max);
-               device_create_file(&new_client->dev, &dev_attr_auto_fan2_min_pwm);
+               if ((err = sysfs_create_group(&new_client->dev.kobj,
+                                               &adm1031_group_opt)))
+                       goto exit_remove;
+       }
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
        }
 
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &adm1031_group);
+       sysfs_remove_group(&new_client->dev.kobj, &adm1031_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -854,6 +878,8 @@ static int adm1031_detach_client(struct i2c_client *client)
        int ret;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &adm1031_group);
+       sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
        if ((ret = i2c_detach_client(client)) != 0) {
                return ret;
        }
index 43f6991b588c6792b3e988f879afbce8c24cd3a1..377961c4a41eb7f737681388418324757a48e0e1 100644 (file)
@@ -465,6 +465,45 @@ static ssize_t chassis_clear(struct device *dev,
 }
 static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear);
 
+static struct attribute *adm9240_attributes[] = {
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &dev_attr_temp1_input.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_aout_output.attr,
+       &dev_attr_chassis_clear.attr,
+       &dev_attr_cpu0_vid.attr,
+       NULL
+};
+
+static const struct attribute_group adm9240_group = {
+       .attrs = adm9240_attributes,
+};
+
 
 /*** sensor chip detect and driver install ***/
 
@@ -548,72 +587,19 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
        adm9240_init_client(new_client);
 
        /* populate sysfs filesystem */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove;
        }
 
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in0_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in0_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in0_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in1_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in1_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in2_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in2_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in2_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in3_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in3_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in3_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in4_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in4_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in4_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in5_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in5_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_in5_max.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_temp1_max_hyst.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan1_div.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan1_min.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan2_input.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan2_div.dev_attr);
-       device_create_file(&new_client->dev,
-                       &sensor_dev_attr_fan2_min.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_aout_output);
-       device_create_file(&new_client->dev, &dev_attr_chassis_clear);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -635,6 +621,7 @@ static int adm9240_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &adm9240_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index facc1ccb8338fd2515d2f271e89645e321572de1..57b1c7b7ac3f5d54601e799a3b0e5f3aaac50708 100644 (file)
@@ -298,12 +298,6 @@ sysfs_in(4);
 sysfs_in(5);
 sysfs_in(6);
 
-#define device_create_file_in(client, offset) do { \
-       device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-       device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-       device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
 /* 3 Fans */
 static ssize_t show_fan(struct device *dev, char *buf, int nr)
 {
@@ -421,12 +415,6 @@ sysfs_fan(1);
 sysfs_fan(2);
 sysfs_fan(3);
 
-#define device_create_file_fan(client, offset) do { \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
 /* 4 Temp. Sensors */
 static int sprintf_temp_from_reg(u16 reg, char *buf, int nr)
 {
@@ -515,12 +503,6 @@ sysfs_temp(3);
 sysfs_temp(4);
 
 /* VID */
-#define device_create_file_temp(client, num) do { \
-       device_create_file(&client->dev, &dev_attr_temp##num##_input); \
-       device_create_file(&client->dev, &dev_attr_temp##num##_max); \
-       device_create_file(&client->dev, &dev_attr_temp##num##_max_hyst); \
-} while (0)
-
 static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct asb100_data *data = asb100_update_device(dev);
@@ -528,8 +510,6 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char
 }
 
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
 
 /* VRM */
 static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
@@ -549,8 +529,6 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const
 
 /* Alarms */
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm);
 
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -559,8 +537,6 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
 }
 
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms)
 
 /* 1 PWM */
 static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf)
@@ -607,10 +583,65 @@ static ssize_t set_pwm_enable1(struct device *dev, struct device_attribute *attr
 static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
 static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
                show_pwm_enable1, set_pwm_enable1);
-#define device_create_file_pwm1(client) do { \
-       device_create_file(&new_client->dev, &dev_attr_pwm1); \
-       device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \
-} while (0)
+
+static struct attribute *asb100_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in5_max.attr,
+       &dev_attr_in6_input.attr,
+       &dev_attr_in6_min.attr,
+       &dev_attr_in6_max.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan3_min.attr,
+       &dev_attr_fan3_div.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_max_hyst.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_temp3_max_hyst.attr,
+       &dev_attr_temp4_input.attr,
+       &dev_attr_temp4_max.attr,
+       &dev_attr_temp4_max_hyst.attr,
+
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm1_enable.attr,
+
+       NULL
+};
+
+static const struct attribute_group asb100_group = {
+       .attrs = asb100_attributes,
+};
 
 /* This function is called when:
        asb100_driver is inserted (when this module is loaded), for each
@@ -810,38 +841,19 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
        data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group)))
+               goto ERROR3;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto ERROR3;
+               goto ERROR4;
        }
 
-       device_create_file_in(new_client, 0);
-       device_create_file_in(new_client, 1);
-       device_create_file_in(new_client, 2);
-       device_create_file_in(new_client, 3);
-       device_create_file_in(new_client, 4);
-       device_create_file_in(new_client, 5);
-       device_create_file_in(new_client, 6);
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       device_create_file_fan(new_client, 3);
-
-       device_create_file_temp(new_client, 1);
-       device_create_file_temp(new_client, 2);
-       device_create_file_temp(new_client, 3);
-       device_create_file_temp(new_client, 4);
-
-       device_create_file_vid(new_client);
-       device_create_file_vrm(new_client);
-
-       device_create_file_alarms(new_client);
-
-       device_create_file_pwm1(new_client);
-
        return 0;
 
+ERROR4:
+       sysfs_remove_group(&new_client->dev.kobj, &asb100_group);
 ERROR3:
        i2c_detach_client(data->lm75[1]);
        i2c_detach_client(data->lm75[0]);
@@ -861,8 +873,10 @@ static int asb100_detach_client(struct i2c_client *client)
        int err;
 
        /* main client */
-       if (data)
+       if (data) {
                hwmon_device_unregister(data->class_dev);
+               sysfs_remove_group(&client->dev.kobj, &asb100_group);
+       }
 
        if ((err = i2c_detach_client(client)))
                return err;
index 728a1e8b91904fe570e6767322d6e0a69dc84e2b..0ccdd0750c44c47968097b5422e6190c7317a2f8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
@@ -116,8 +117,7 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att
 {
        struct atxp1_data *data;
        struct i2c_client *client;
-       char vid;
-       char cvid;
+       int vid, cvid;
        unsigned int vcore;
 
        client = to_i2c_client(dev);
@@ -251,6 +251,17 @@ static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *att
 */
 static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
 
+static struct attribute *atxp1_attributes[] = {
+       &dev_attr_gpio1.attr,
+       &dev_attr_gpio2.attr,
+       &dev_attr_cpu0_vid.attr,
+       NULL
+};
+
+static const struct attribute_group atxp1_group = {
+       .attrs = atxp1_attributes,
+};
+
 
 static int atxp1_attach_adapter(struct i2c_adapter *adapter)
 {
@@ -320,21 +331,23 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
                goto exit_free;
        }
 
+       /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_gpio1);
-       device_create_file(&new_client->dev, &dev_attr_gpio2);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-
        dev_info(&new_client->dev, "Using VRM: %d.%d\n",
                         data->vrm / 10, data->vrm % 10);
 
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &atxp1_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -349,6 +362,7 @@ static int atxp1_detach_client(struct i2c_client * client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &atxp1_group);
 
        err = i2c_detach_client(client);
 
index 478eb4bb8570958464f57f582c8ee6d52c4edadb..c849c0c6ee9ce37edb2b86061aa595476946686c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include "lm75.h"
 
 /* Addresses to scan */
@@ -178,6 +179,18 @@ static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL);
 static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min);
 static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
 
+static struct attribute *ds1621_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group ds1621_group = {
+       .attrs = ds1621_attributes,
+};
+
 
 static int ds1621_attach_adapter(struct i2c_adapter *adapter)
 {
@@ -253,21 +266,19 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address,
        ds1621_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &ds1621_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       
        return 0;
 
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
+      exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &ds1621_group);
       exit_detach:
        i2c_detach_client(new_client);
       exit_free:
@@ -282,6 +293,7 @@ static int ds1621_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &ds1621_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index fd72440faf76167e08a22d9409255a70c4dba256..de17a72149d98ffb999b156b91a4942ee9cec2aa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated
  *             hardware monitoring features
- * Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2005-2006  Jean Delvare <khali@linux-fr.org>
  *
  * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
  * complete hardware monitoring features: voltage, fan and temperature
@@ -31,6 +31,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include <asm/io.h>
 
 static struct platform_device *pdev;
@@ -147,7 +148,7 @@ struct f71805f_data {
        u8 temp_high[3];
        u8 temp_hyst[3];
        u8 temp_mode;
-       u8 alarms[3];
+       unsigned long alarms;
 };
 
 static inline long in_from_reg(u8 reg)
@@ -311,10 +312,9 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
                        data->temp[nr] = f71805f_read8(data,
                                         F71805F_REG_TEMP(nr));
                }
-               for (nr = 0; nr < 3; nr++) {
-                       data->alarms[nr] = f71805f_read8(data,
-                                          F71805F_REG_STATUS(nr));
-               }
+               data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0))
+                       + (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8)
+                       + (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16);
 
                data->last_updated = jiffies;
                data->valid = 1;
@@ -557,8 +557,7 @@ static ssize_t show_alarms_in(struct device *dev, struct device_attribute
 {
        struct f71805f_data *data = f71805f_update_device(dev);
 
-       return sprintf(buf, "%d\n", data->alarms[0] |
-                                   ((data->alarms[1] & 0x01) << 8));
+       return sprintf(buf, "%lu\n", data->alarms & 0x1ff);
 }
 
 static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
@@ -566,7 +565,7 @@ static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
 {
        struct f71805f_data *data = f71805f_update_device(dev);
 
-       return sprintf(buf, "%d\n", data->alarms[2] & 0x07);
+       return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07);
 }
 
 static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
@@ -574,7 +573,17 @@ static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
 {
        struct f71805f_data *data = f71805f_update_device(dev);
 
-       return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07);
+       return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07);
+}
+
+static ssize_t show_alarm(struct device *dev, struct device_attribute
+                         *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int bitnr = attr->index;
+
+       return sprintf(buf, "%lu\n", (data->alarms >> bitnr) & 1);
 }
 
 static ssize_t show_name(struct device *dev, struct device_attribute
@@ -585,88 +594,189 @@ static ssize_t show_name(struct device *dev, struct device_attribute
        return sprintf(buf, "%s\n", data->name);
 }
 
-static struct device_attribute f71805f_dev_attr[] = {
-       __ATTR(in0_input, S_IRUGO, show_in0, NULL),
-       __ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max),
-       __ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min),
-       __ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL),
-       __ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL),
-       __ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL),
-       __ATTR(name, S_IRUGO, show_name, NULL),
+static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
+static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
+static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
+static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 1);
+static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 1);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
+static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 2);
+static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 2);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
+static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 3);
+static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 3);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
+static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 4);
+static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 4);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5);
+static SENSOR_DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 5);
+static SENSOR_DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6);
+static SENSOR_DEVICE_ATTR(in6_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 6);
+static SENSOR_DEVICE_ATTR(in6_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7);
+static SENSOR_DEVICE_ATTR(in7_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 7);
+static SENSOR_DEVICE_ATTR(in7_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 7);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8);
+static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR,
+                         show_in_max, set_in_max, 8);
+static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR,
+                         show_in_min, set_in_min, 8);
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
+                         show_fan_min, set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
+                         show_fan_min, set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
+                         show_fan_min, set_fan_min, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
+                   show_temp_max, set_temp_max, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
+                   show_temp_hyst, set_temp_hyst, 0);
+static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR,
+                   show_temp_max, set_temp_max, 1);
+static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
+                   show_temp_hyst, set_temp_hyst, 1);
+static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR,
+                   show_temp_max, set_temp_max, 2);
+static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
+                   show_temp_hyst, set_temp_hyst, 2);
+static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
+
+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
+static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12);
+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13);
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17);
+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18);
+static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL);
+static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL);
+static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static struct attribute *f71805f_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in0_min.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in6_input.dev_attr.attr,
+       &sensor_dev_attr_in6_max.dev_attr.attr,
+       &sensor_dev_attr_in6_min.dev_attr.attr,
+       &sensor_dev_attr_in7_input.dev_attr.attr,
+       &sensor_dev_attr_in7_max.dev_attr.attr,
+       &sensor_dev_attr_in7_min.dev_attr.attr,
+       &sensor_dev_attr_in8_input.dev_attr.attr,
+       &sensor_dev_attr_in8_max.dev_attr.attr,
+       &sensor_dev_attr_in8_min.dev_attr.attr,
+
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp1_type.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp2_type.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp3_type.dev_attr.attr,
+
+       &sensor_dev_attr_in0_alarm.dev_attr.attr,
+       &sensor_dev_attr_in1_alarm.dev_attr.attr,
+       &sensor_dev_attr_in2_alarm.dev_attr.attr,
+       &sensor_dev_attr_in3_alarm.dev_attr.attr,
+       &sensor_dev_attr_in4_alarm.dev_attr.attr,
+       &sensor_dev_attr_in5_alarm.dev_attr.attr,
+       &sensor_dev_attr_in6_alarm.dev_attr.attr,
+       &sensor_dev_attr_in7_alarm.dev_attr.attr,
+       &sensor_dev_attr_in8_alarm.dev_attr.attr,
+       &dev_attr_alarms_in.attr,
+       &sensor_dev_attr_temp1_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp3_alarm.dev_attr.attr,
+       &dev_attr_alarms_temp.attr,
+       &dev_attr_alarms_fan.attr,
+
+       &dev_attr_name.attr,
+       NULL
 };
 
-static struct sensor_device_attribute f71805f_sensor_attr[] = {
-       SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
-       SENSOR_ATTR(in1_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 1),
-       SENSOR_ATTR(in1_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 1),
-       SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
-       SENSOR_ATTR(in2_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 2),
-       SENSOR_ATTR(in2_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 2),
-       SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
-       SENSOR_ATTR(in3_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 3),
-       SENSOR_ATTR(in3_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 3),
-       SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
-       SENSOR_ATTR(in4_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 4),
-       SENSOR_ATTR(in4_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 4),
-       SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
-       SENSOR_ATTR(in5_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 5),
-       SENSOR_ATTR(in5_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 5),
-       SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
-       SENSOR_ATTR(in6_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 6),
-       SENSOR_ATTR(in6_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 6),
-       SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
-       SENSOR_ATTR(in7_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 7),
-       SENSOR_ATTR(in7_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 7),
-       SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
-       SENSOR_ATTR(in8_max, S_IRUGO | S_IWUSR,
-                   show_in_max, set_in_max, 8),
-       SENSOR_ATTR(in8_min, S_IRUGO | S_IWUSR,
-                   show_in_min, set_in_min, 8),
-
-       SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
-       SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR,
-                   show_temp_max, set_temp_max, 0),
-       SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
-                   show_temp_hyst, set_temp_hyst, 0),
-       SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
-       SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
-       SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR,
-                   show_temp_max, set_temp_max, 1),
-       SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
-                   show_temp_hyst, set_temp_hyst, 1),
-       SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
-       SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
-       SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR,
-                   show_temp_max, set_temp_max, 2),
-       SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
-                   show_temp_hyst, set_temp_hyst, 2),
-       SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
+static const struct attribute_group f71805f_group = {
+       .attrs = f71805f_attributes,
 };
 
-static struct sensor_device_attribute f71805f_fan_attr[] = {
-       SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
-       SENSOR_ATTR(fan1_min, S_IRUGO | S_IWUSR,
-                   show_fan_min, set_fan_min, 0),
-       SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
-       SENSOR_ATTR(fan2_min, S_IRUGO | S_IWUSR,
-                   show_fan_min, set_fan_min, 1),
-       SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
-       SENSOR_ATTR(fan3_min, S_IRUGO | S_IWUSR,
-                   show_fan_min, set_fan_min, 2),
+static struct attribute *f71805f_attributes_fan[3][4] = {
+       {
+               &sensor_dev_attr_fan1_input.dev_attr.attr,
+               &sensor_dev_attr_fan1_min.dev_attr.attr,
+               &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan2_input.dev_attr.attr,
+               &sensor_dev_attr_fan2_min.dev_attr.attr,
+               &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan3_input.dev_attr.attr,
+               &sensor_dev_attr_fan3_min.dev_attr.attr,
+               &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+               NULL
+       }
+};
+
+static const struct attribute_group f71805f_group_fan[3] = {
+       { .attrs = f71805f_attributes_fan[0] },
+       { .attrs = f71805f_attributes_fan[1] },
+       { .attrs = f71805f_attributes_fan[2] },
 };
 
 /*
@@ -714,43 +824,35 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, data);
 
-       data->class_dev = hwmon_device_register(&pdev->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
-               dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
-               goto exit_free;
-       }
-
        /* Initialize the F71805F chip */
        f71805f_init_device(data);
 
        /* Register sysfs interface files */
-       for (i = 0; i < ARRAY_SIZE(f71805f_dev_attr); i++) {
-               err = device_create_file(&pdev->dev, &f71805f_dev_attr[i]);
-               if (err)
-                       goto exit_class;
-       }
-       for (i = 0; i < ARRAY_SIZE(f71805f_sensor_attr); i++) {
-               err = device_create_file(&pdev->dev,
-                                        &f71805f_sensor_attr[i].dev_attr);
-               if (err)
-                       goto exit_class;
-       }
-       for (i = 0; i < ARRAY_SIZE(f71805f_fan_attr); i++) {
-               if (!(data->fan_enabled & (1 << (i / 2))))
+       if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
+               goto exit_free;
+       for (i = 0; i < 3; i++) {
+               if (!(data->fan_enabled & (1 << i)))
                        continue;
-               err = device_create_file(&pdev->dev,
-                                        &f71805f_fan_attr[i].dev_attr);
-               if (err)
-                       goto exit_class;
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &f71805f_group_fan[i])))
+                       goto exit_remove_files;
+       }
+
+       data->class_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+               goto exit_remove_files;
        }
 
        return 0;
 
-exit_class:
-       dev_err(&pdev->dev, "Sysfs interface creation failed\n");
-       hwmon_device_unregister(data->class_dev);
+exit_remove_files:
+       sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
+       for (i = 0; i < 3; i++)
+               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
 exit_free:
+       platform_set_drvdata(pdev, NULL);
        kfree(data);
 exit:
        return err;
@@ -759,9 +861,13 @@ exit:
 static int __devexit f71805f_remove(struct platform_device *pdev)
 {
        struct f71805f_data *data = platform_get_drvdata(pdev);
+       int i;
 
        platform_set_drvdata(pdev, NULL);
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
+       for (i = 0; i < 3; i++)
+               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
        kfree(data);
 
        return 0;
index 6bc76b407636d8a1a8199669d588d51f96bd9b8e..19717752cfcad64a6efd3d786a79d3b53b861578 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /*
  * Addresses to scan
@@ -240,47 +241,45 @@ sysfs_alarms(FSCHER_REG_EVENTS)
 sysfs_control(FSCHER_REG_CONTROL)
 sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET)
   
-#define device_create_file_fan(client, offset) \
-do { \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_status); \
-       device_create_file(&client->dev, &dev_attr_pwm##offset); \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-       device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-} while (0)
-
-#define device_create_file_temp(client, offset) \
-do { \
-       device_create_file(&client->dev, &dev_attr_temp##offset##_status); \
-       device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-} while (0)
-
-#define device_create_file_in(client, offset) \
-do { \
-       device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-} while (0)
-
-#define device_create_file_revision(client) \
-do { \
-       device_create_file(&client->dev, &dev_attr_revision); \
-} while (0)
-
-#define device_create_file_alarms(client) \
-do { \
-       device_create_file(&client->dev, &dev_attr_alarms); \
-} while (0)
-
-#define device_create_file_control(client) \
-do { \
-       device_create_file(&client->dev, &dev_attr_control); \
-} while (0)
-
-#define device_create_file_watchdog(client) \
-do { \
-       device_create_file(&client->dev, &dev_attr_watchdog_status); \
-       device_create_file(&client->dev, &dev_attr_watchdog_control); \
-       device_create_file(&client->dev, &dev_attr_watchdog_preset); \
-} while (0)
-  
+static struct attribute *fscher_attributes[] = {
+       &dev_attr_revision.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_control.attr,
+
+       &dev_attr_watchdog_status.attr,
+       &dev_attr_watchdog_control.attr,
+       &dev_attr_watchdog_preset.attr,
+
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+
+       &dev_attr_fan1_status.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan1_input.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_fan2_status.attr,
+       &dev_attr_fan2_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_fan3_status.attr,
+       &dev_attr_fan3_div.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_pwm3.attr,
+
+       &dev_attr_temp1_status.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_status.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp3_status.attr,
+       &dev_attr_temp3_input.attr,
+       NULL
+};
+
+static const struct attribute_group fscher_group = {
+       .attrs = fscher_attributes,
+};
+
 /*
  * Real code
  */
@@ -342,31 +341,19 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
        fscher_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file_revision(new_client);
-       device_create_file_alarms(new_client);
-       device_create_file_control(new_client);
-       device_create_file_watchdog(new_client);
-
-       device_create_file_in(new_client, 0);
-       device_create_file_in(new_client, 1);
-       device_create_file_in(new_client, 2);
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       device_create_file_fan(new_client, 3);
-
-       device_create_file_temp(new_client, 1);
-       device_create_file_temp(new_client, 2);
-       device_create_file_temp(new_client, 3);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &fscher_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -381,6 +368,7 @@ static int fscher_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &fscher_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 6dc4846b9eebb98ce6d661dfd49b40edfdc28536..ea506a77f9c9d25f701b5cc222c471439f56ca6a 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /*
  * Addresses to scan
@@ -432,6 +433,44 @@ static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
 static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
 static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
 
+static struct attribute *fscpos_attributes[] = {
+       &dev_attr_event.attr,
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+
+       &dev_attr_wdog_control.attr,
+       &dev_attr_wdog_preset.attr,
+       &dev_attr_wdog_state.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_status.attr,
+       &dev_attr_temp1_reset.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_status.attr,
+       &dev_attr_temp2_reset.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp3_status.attr,
+       &dev_attr_temp3_reset.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_status.attr,
+       &dev_attr_fan1_ripple.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_status.attr,
+       &dev_attr_fan2_ripple.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan3_status.attr,
+       &dev_attr_fan3_ripple.attr,
+       NULL
+};
+
+static const struct attribute_group fscpos_group = {
+       .attrs = fscpos_attributes,
+};
+
 static int fscpos_attach_adapter(struct i2c_adapter *adapter)
 {
        if (!(adapter->class & I2C_CLASS_HWMON))
@@ -497,42 +536,19 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
        dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_event);
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_wdog_control);
-       device_create_file(&new_client->dev, &dev_attr_wdog_preset);
-       device_create_file(&new_client->dev, &dev_attr_wdog_state);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_status);
-       device_create_file(&new_client->dev, &dev_attr_temp1_reset);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_status);
-       device_create_file(&new_client->dev, &dev_attr_temp2_reset);
-       device_create_file(&new_client->dev, &dev_attr_temp3_input);
-       device_create_file(&new_client->dev, &dev_attr_temp3_status);
-       device_create_file(&new_client->dev, &dev_attr_temp3_reset);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_status);
-       device_create_file(&new_client->dev, &dev_attr_fan1_ripple);
-       device_create_file(&new_client->dev, &dev_attr_pwm1);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_status);
-       device_create_file(&new_client->dev, &dev_attr_fan2_ripple);
-       device_create_file(&new_client->dev, &dev_attr_pwm2);
-       device_create_file(&new_client->dev, &dev_attr_fan3_input);
-       device_create_file(&new_client->dev, &dev_attr_fan3_status);
-       device_create_file(&new_client->dev, &dev_attr_fan3_ripple);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &fscpos_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -547,6 +563,7 @@ static int fscpos_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &fscpos_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 6606aabdb49d5d7b7d3125a496a5a496ceb0e0b8..c103640455a324614f253c741807d34de7e31af7 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
@@ -340,6 +341,42 @@ static DEVICE_ATTR(beep_enable, S_IWUSR|S_IRUGO,
 static DEVICE_ATTR(beep_mask, S_IWUSR|S_IRUGO,
        show_beep_mask, set_beep_mask);
 
+static struct attribute *gl518_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_max.attr,
+
+       &dev_attr_fan1_auto.attr,
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+
+       &dev_attr_alarms.attr,
+       &dev_attr_beep_enable.attr,
+       &dev_attr_beep_mask.attr,
+       NULL
+};
+
+static const struct attribute_group gl518_group = {
+       .attrs = gl518_attributes,
+};
+
 /*
  * Real code
  */
@@ -420,43 +457,19 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
        gl518_init_client((struct i2c_client *) new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_fan1_auto);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_beep_enable);
-       device_create_file(&new_client->dev, &dev_attr_beep_mask);
-
        return 0;
 
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
-
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &gl518_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -490,6 +503,7 @@ static int gl518_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &gl518_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 14e810f3c2c09db43ab6687efbfaa8076c65fc5c..ebe7b9aaa91696f092bda00593400f4a1215ab27 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /* Type of the extra sensor */
 static unsigned short extra_sensor_type;
@@ -190,55 +191,29 @@ static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL);
 #define sysfs_vid(n) \
 sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT)
 
-#define device_create_file_vid(client, n) \
-device_create_file(&client->dev, &dev_attr_cpu##n##_vid)
-
 #define sysfs_in(n) \
 sysfs_ro_n(in, n, _input, GL520_REG_IN##n##INPUT) \
 sysfs_rw_n(in, n, _min, GL520_REG_IN##n##_MIN) \
 sysfs_rw_n(in, n, _max, GL520_REG_IN##n##_MAX) \
 
-#define device_create_file_in(client, n) \
-({device_create_file(&client->dev, &dev_attr_in##n##_input); \
-device_create_file(&client->dev, &dev_attr_in##n##_min); \
-device_create_file(&client->dev, &dev_attr_in##n##_max);})
-
 #define sysfs_fan(n) \
 sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \
 sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \
 sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV)
 
-#define device_create_file_fan(client, n) \
-({device_create_file(&client->dev, &dev_attr_fan##n##_input); \
-device_create_file(&client->dev, &dev_attr_fan##n##_min); \
-device_create_file(&client->dev, &dev_attr_fan##n##_div);})
-
 #define sysfs_fan_off(n) \
 sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) \
 
-#define device_create_file_fan_off(client, n) \
-device_create_file(&client->dev, &dev_attr_fan##n##_off)
-
 #define sysfs_temp(n) \
 sysfs_ro_n(temp, n, _input, GL520_REG_TEMP##n##_INPUT) \
 sysfs_rw_n(temp, n, _max, GL520_REG_TEMP##n##_MAX) \
 sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP##n##_MAX_HYST)
 
-#define device_create_file_temp(client, n) \
-({device_create_file(&client->dev, &dev_attr_temp##n##_input); \
-device_create_file(&client->dev, &dev_attr_temp##n##_max); \
-device_create_file(&client->dev, &dev_attr_temp##n##_max_hyst);})
-
 #define sysfs_alarms() \
 sysfs_ro(alarms, , GL520_REG_ALARMS) \
 sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \
 sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK)
 
-#define device_create_file_alarms(client) \
-({device_create_file(&client->dev, &dev_attr_alarms); \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask);})
-
 
 sysfs_vid(0)
 
@@ -511,6 +486,59 @@ static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data,
        return count;
 }
 
+static struct attribute *gl520_attributes[] = {
+       &dev_attr_cpu0_vid.attr,
+
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan1_off.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+
+       &dev_attr_alarms.attr,
+       &dev_attr_beep_enable.attr,
+       &dev_attr_beep_mask.attr,
+       NULL
+};
+
+static const struct attribute_group gl520_group = {
+       .attrs = gl520_attributes,
+};
+
+static struct attribute *gl520_attributes_opt[] = {
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_max_hyst.attr,
+       NULL
+};
+
+static const struct attribute_group gl520_group_opt = {
+       .attrs = gl520_attributes_opt,
+};
+
 
 /*
  * Real code
@@ -572,33 +600,39 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
        gl520_init_client(new_client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &gl520_group)))
                goto exit_detach;
-       }
-
-       device_create_file_vid(new_client, 0);
 
-       device_create_file_in(new_client, 0);
-       device_create_file_in(new_client, 1);
-       device_create_file_in(new_client, 2);
-       device_create_file_in(new_client, 3);
-       if (!data->two_temps)
-               device_create_file_in(new_client, 4);
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       device_create_file_fan_off(new_client, 1);
+       if (data->two_temps) {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp2_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp2_max))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp2_max_hyst)))
+                       goto exit_remove_files;
+       } else {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_min))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_max)))
+                       goto exit_remove_files;
+       }
 
-       device_create_file_temp(new_client, 1);
-       if (data->two_temps)
-               device_create_file_temp(new_client, 2);
 
-       device_create_file_alarms(new_client);
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
+       }
 
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &gl520_group);
+       sysfs_remove_group(&new_client->dev.kobj, &gl520_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -652,6 +686,8 @@ static int gl520_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &gl520_group);
+       sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 42b632889dd891e7f91259f45ee9a7ceb2aee07c..8e7b5607f5a116c1b5ef73af39c42fa67e356e2e 100644 (file)
@@ -587,7 +587,9 @@ static int __init hdaps_init(void)
        input_set_abs_params(hdaps_idev, ABS_Y,
                        -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
 
-       input_register_device(hdaps_idev);
+       ret = input_register_device(hdaps_idev);
+       if (ret)
+               goto out_idev;
 
        /* start up our timer for the input device */
        init_timer(&hdaps_timer);
@@ -598,6 +600,8 @@ static int __init hdaps_init(void)
        printk(KERN_INFO "hdaps: driver successfully loaded.\n");
        return 0;
 
+out_idev:
+       input_free_device(hdaps_idev);
 out_group:
        sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
 out_device:
index b0ee57492228bc42f8d3154378249978b713cffa..323ef06719c160537942a002b5495a79159c2b28 100644 (file)
@@ -4,10 +4,12 @@
 
     Supports: IT8705F  Super I/O chip w/LPC interface
               IT8712F  Super I/O chip w/LPC interface & SMBus
+              IT8716F  Super I/O chip w/LPC interface
+              IT8718F  Super I/O chip w/LPC interface
               Sis950   A clone of the IT8705F
 
     Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> 
-    Largely inspired by lm78.c of the same package
+    Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.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
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/*
-    djg@pdp8.net David Gesswein 7/18/01
-    Modified to fix bug with not all alarms enabled.
-    Added ability to read battery voltage and select temperature sensor
-    type at module load time.
-*/
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -42,6 +37,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include <asm/io.h>
 
 
@@ -50,12 +46,13 @@ static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 static unsigned short isa_address;
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_2(it87, it8712);
+I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718);
 
 #define        REG     0x2e    /* The register to read/write */
 #define        DEV     0x07    /* Register: Logical device select */
 #define        VAL     0x2f    /* The value to read/write */
 #define PME    0x04    /* The device with the fan registers in it */
+#define GPIO   0x07    /* The device with the IT8718F VID value in it */
 #define        DEVID   0x20    /* Register: Device ID */
 #define        DEVREV  0x22    /* Register: Device Revision */
 
@@ -77,10 +74,10 @@ static int superio_inw(int reg)
 }
 
 static inline void
-superio_select(void)
+superio_select(int ldn)
 {
        outb(DEV, REG);
-       outb(PME, VAL);
+       outb(ldn, VAL);
 }
 
 static inline void
@@ -99,20 +96,27 @@ superio_exit(void)
        outb(0x02, VAL);
 }
 
+/* Logical device 4 registers */
 #define IT8712F_DEVID 0x8712
 #define IT8705F_DEVID 0x8705
+#define IT8716F_DEVID 0x8716
+#define IT8718F_DEVID 0x8718
 #define IT87_ACT_REG  0x30
 #define IT87_BASE_REG 0x60
 
+/* Logical device 7 registers (IT8712F and later) */
+#define IT87_SIO_PINX2_REG     0x2c    /* Pin selection */
+#define IT87_SIO_VID_REG       0xfc    /* VID value */
+
 /* Update battery voltage after every reading if true */
 static int update_vbat;
 
 /* Not all BIOSes properly configure the PWM registers */
 static int fix_pwm_polarity;
 
-/* Chip Type */
-
+/* Values read from Super-I/O config space */
 static u16 chip_type;
+static u8 vid_value;
 
 /* Many IT87 constants specified below */
 
@@ -131,13 +135,21 @@ static u16 chip_type;
 #define IT87_REG_ALARM2        0x02
 #define IT87_REG_ALARM3        0x03
 
+/* The IT8718F has the VID value in a different register, in Super-I/O
+   configuration space. */
 #define IT87_REG_VID           0x0a
+/* Warning: register 0x0b is used for something completely different in
+   new chips/revisions. I suspect only 16-bit tachometer mode will work
+   for these. */
 #define IT87_REG_FAN_DIV       0x0b
+#define IT87_REG_FAN_16BIT     0x0c
 
 /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
 
 #define IT87_REG_FAN(nr)       (0x0d + (nr))
 #define IT87_REG_FAN_MIN(nr)   (0x10 + (nr))
+#define IT87_REG_FANX(nr)      (0x18 + (nr))
+#define IT87_REG_FANX_MIN(nr)  (0x1b + (nr))
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
@@ -169,7 +181,16 @@ static inline u8 FAN_TO_REG(long rpm, int div)
                             254);
 }
 
+static inline u16 FAN16_TO_REG(long rpm)
+{
+       if (rpm == 0)
+               return 0xffff;
+       return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
+}
+
 #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
+/* The divider is fixed to 2 in 16-bit mode */
+#define FAN16_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:1350000/((val)*2))
 
 #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
                                        ((val)+500)/1000),-128,127))
@@ -181,7 +202,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 static int DIV_TO_REG(int val)
 {
        int answer = 0;
-       while ((val >>= 1) != 0)
+       while (answer < 7 && (val >>= 1))
                answer++;
        return answer;
 }
@@ -203,10 +224,11 @@ struct it87_data {
        unsigned long last_updated;     /* In jiffies */
 
        u8 in[9];               /* Register value */
-       u8 in_max[9];           /* Register value */
-       u8 in_min[9];           /* Register value */
-       u8 fan[3];              /* Register value */
-       u8 fan_min[3];          /* Register value */
+       u8 in_max[8];           /* Register value */
+       u8 in_min[8];           /* Register value */
+       u8 has_fan;             /* Bitfield, fans enabled */
+       u16 fan[3];             /* Register values, possibly combined */
+       u16 fan_min[3];         /* Register values, possibly combined */
        u8 temp[3];             /* Register value */
        u8 temp_high[3];        /* Register value */
        u8 temp_low[3];         /* Register value */
@@ -545,15 +567,15 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 
        struct i2c_client *client = to_i2c_client(dev);
        struct it87_data *data = i2c_get_clientdata(client);
-       int val = simple_strtol(buf, NULL, 10);
-       int i, min[3];
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       int min;
        u8 old;
 
        mutex_lock(&data->update_lock);
        old = it87_read_value(client, IT87_REG_FAN_DIV);
 
-       for (i = 0; i < 3; i++)
-               min[i] = FAN_FROM_REG(data->fan_min[i], DIV_FROM_REG(data->fan_div[i]));
+       /* Save fan min limit */
+       min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
 
        switch (nr) {
        case 0:
@@ -573,10 +595,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
                val |= 0x1 << 6;
        it87_write_value(client, IT87_REG_FAN_DIV, val);
 
-       for (i = 0; i < 3; i++) {
-               data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i]));
-               it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]);
-       }
+       /* Restore fan min limit */
+       data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+       it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
+
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -657,6 +679,59 @@ show_pwm_offset(1);
 show_pwm_offset(2);
 show_pwm_offset(3);
 
+/* A different set of callbacks for 16-bit fans */
+static ssize_t show_fan16(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       struct it87_data *data = it87_update_device(dev);
+       return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan[nr]));
+}
+
+static ssize_t show_fan16_min(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       struct it87_data *data = it87_update_device(dev);
+       return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan_min[nr]));
+}
+
+static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct it87_data *data = i2c_get_clientdata(client);
+       int val = simple_strtol(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       data->fan_min[nr] = FAN16_TO_REG(val);
+       it87_write_value(client, IT87_REG_FAN_MIN(nr),
+                        data->fan_min[nr] & 0xff);
+       it87_write_value(client, IT87_REG_FANX_MIN(nr),
+                        data->fan_min[nr] >> 8);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/* We want to use the same sysfs file names as 8-bit fans, but we need
+   different variable names, so we have to use SENSOR_ATTR instead of
+   SENSOR_DEVICE_ATTR. */
+#define show_fan16_offset(offset) \
+static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \
+       = SENSOR_ATTR(fan##offset##_input, S_IRUGO,             \
+               show_fan16, NULL, offset - 1);                  \
+static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \
+       = SENSOR_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,     \
+               show_fan16_min, set_fan16_min, offset - 1)
+
+show_fan16_offset(1);
+show_fan16_offset(2);
+show_fan16_offset(3);
+
 /* Alarms */
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -684,8 +759,6 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf
        return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm)
 
 static ssize_t
 show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
@@ -694,8 +767,88 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
+
+static struct attribute *it87_attributes[] = {
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in6_input.dev_attr.attr,
+       &sensor_dev_attr_in7_input.dev_attr.attr,
+       &sensor_dev_attr_in8_input.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in6_min.dev_attr.attr,
+       &sensor_dev_attr_in7_min.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &sensor_dev_attr_in6_max.dev_attr.attr,
+       &sensor_dev_attr_in7_max.dev_attr.attr,
+
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_min.dev_attr.attr,
+       &sensor_dev_attr_temp2_min.dev_attr.attr,
+       &sensor_dev_attr_temp3_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_type.dev_attr.attr,
+       &sensor_dev_attr_temp2_type.dev_attr.attr,
+       &sensor_dev_attr_temp3_type.dev_attr.attr,
+
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group it87_group = {
+       .attrs = it87_attributes,
+};
+
+static struct attribute *it87_attributes_opt[] = {
+       &sensor_dev_attr_fan1_input16.dev_attr.attr,
+       &sensor_dev_attr_fan1_min16.dev_attr.attr,
+       &sensor_dev_attr_fan2_input16.dev_attr.attr,
+       &sensor_dev_attr_fan2_min16.dev_attr.attr,
+       &sensor_dev_attr_fan3_input16.dev_attr.attr,
+       &sensor_dev_attr_fan3_min16.dev_attr.attr,
+
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &sensor_dev_attr_fan3_input.dev_attr.attr,
+       &sensor_dev_attr_fan3_min.dev_attr.attr,
+       &sensor_dev_attr_fan3_div.dev_attr.attr,
+
+       &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm1.dev_attr.attr,
+       &sensor_dev_attr_pwm2.dev_attr.attr,
+       &sensor_dev_attr_pwm3.dev_attr.attr,
+
+       &dev_attr_vrm.attr,
+       &dev_attr_cpu0_vid.attr,
+       NULL
+};
+
+static const struct attribute_group it87_group_opt = {
+       .attrs = it87_attributes_opt,
+};
 
 /* This function is called when:
      * it87_driver is inserted (when this module is loaded), for each
@@ -721,10 +874,12 @@ static int __init it87_find(unsigned short *address)
        superio_enter();
        chip_type = superio_inw(DEVID);
        if (chip_type != IT8712F_DEVID
+        && chip_type != IT8716F_DEVID
+        && chip_type != IT8718F_DEVID
         && chip_type != IT8705F_DEVID)
                goto exit;
 
-       superio_select();
+       superio_select(PME);
        if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
                pr_info("it87: Device not activated, skipping\n");
                goto exit;
@@ -740,6 +895,21 @@ static int __init it87_find(unsigned short *address)
        pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
                chip_type, *address, superio_inb(DEVREV) & 0x0f);
 
+       /* Read GPIO config and VID value from LDN 7 (GPIO) */
+       if (chip_type != IT8705F_DEVID) {
+               int reg;
+
+               superio_select(GPIO);
+               if (chip_type == it8718)
+                       vid_value = superio_inb(IT87_SIO_VID_REG);
+
+               reg = superio_inb(IT87_SIO_PINX2_REG);
+               if (reg & (1 << 0))
+                       pr_info("it87: in3 is VCC (+5V)\n");
+               if (reg & (1 << 1))
+                       pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
+       }
+
 exit:
        superio_exit();
        return err;
@@ -800,8 +970,19 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
                i = it87_read_value(new_client, IT87_REG_CHIPID);
                if (i == 0x90) {
                        kind = it87;
-                       if ((is_isa) && (chip_type == IT8712F_DEVID))
-                               kind = it8712;
+                       if (is_isa) {
+                               switch (chip_type) {
+                               case IT8712F_DEVID:
+                                       kind = it8712;
+                                       break;
+                               case IT8716F_DEVID:
+                                       kind = it8716;
+                                       break;
+                               case IT8718F_DEVID:
+                                       kind = it8718;
+                                       break;
+                               }
+                       }
                }
                else {
                        if (kind == 0)
@@ -818,6 +999,10 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
                name = "it87";
        } else if (kind == it8712) {
                name = "it8712";
+       } else if (kind == it8716) {
+               name = "it8716";
+       } else if (kind == it8718) {
+               name = "it8718";
        }
 
        /* Fill in the remaining client fields and put it into the global list */
@@ -842,76 +1027,103 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
        it87_init_client(new_client, data);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &it87_group)))
                goto ERROR3;
+
+       /* Do not create fan files for disabled fans */
+       if (data->type == it8716 || data->type == it8718) {
+               /* 16-bit tachometers */
+               if (data->has_fan & (1 << 0)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan1_input16.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan1_min16.dev_attr)))
+                               goto ERROR4;
+               }
+               if (data->has_fan & (1 << 1)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan2_input16.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan2_min16.dev_attr)))
+                               goto ERROR4;
+               }
+               if (data->has_fan & (1 << 2)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan3_input16.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan3_min16.dev_attr)))
+                               goto ERROR4;
+               }
+       } else {
+               /* 8-bit tachometers with clock divider */
+               if (data->has_fan & (1 << 0)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan1_input.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan1_min.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan1_div.dev_attr)))
+                               goto ERROR4;
+               }
+               if (data->has_fan & (1 << 1)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan2_input.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan2_min.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan2_div.dev_attr)))
+                               goto ERROR4;
+               }
+               if (data->has_fan & (1 << 2)) {
+                       if ((err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan3_input.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan3_min.dev_attr))
+                        || (err = device_create_file(&new_client->dev,
+                            &sensor_dev_attr_fan3_div.dev_attr)))
+                               goto ERROR4;
+               }
        }
 
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
-       device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
        if (enable_pwm_interface) {
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr);
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm2_enable.dev_attr);
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm3_enable.dev_attr);
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr);
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr);
-               device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr);
+               if ((err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm1_enable.dev_attr))
+                || (err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm2_enable.dev_attr))
+                || (err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm3_enable.dev_attr))
+                || (err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm1.dev_attr))
+                || (err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm2.dev_attr))
+                || (err = device_create_file(&new_client->dev,
+                    &sensor_dev_attr_pwm3.dev_attr)))
+                       goto ERROR4;
        }
 
-       if (data->type == it8712) {
+       if (data->type == it8712 || data->type == it8716
+        || data->type == it8718) {
                data->vrm = vid_which_vrm();
-               device_create_file_vrm(new_client);
-               device_create_file_vid(new_client);
+               /* VID reading from Super-I/O config space if available */
+               data->vid = vid_value;
+               if ((err = device_create_file(&new_client->dev,
+                    &dev_attr_vrm))
+                || (err = device_create_file(&new_client->dev,
+                    &dev_attr_cpu0_vid)))
+                       goto ERROR4;
+       }
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR4;
        }
 
        return 0;
 
+ERROR4:
+       sysfs_remove_group(&new_client->dev.kobj, &it87_group);
+       sysfs_remove_group(&new_client->dev.kobj, &it87_group_opt);
 ERROR3:
        i2c_detach_client(new_client);
 ERROR2:
@@ -929,6 +1141,8 @@ static int it87_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &it87_group);
+       sysfs_remove_group(&client->dev.kobj, &it87_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
@@ -1045,6 +1259,22 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
                data->manual_pwm_ctl[i] = 0xff;
        }
 
+       /* Some chips seem to have default value 0xff for all limit
+        * registers. For low voltage limits it makes no sense and triggers
+        * alarms, so change to 0 instead. For high temperature limits, it
+        * means -1 degree C, which surprisingly doesn't trigger an alarm,
+        * but is still confusing, so change to 127 degrees C. */
+       for (i = 0; i < 8; i++) {
+               tmp = it87_read_value(client, IT87_REG_VIN_MIN(i));
+               if (tmp == 0xff)
+                       it87_write_value(client, IT87_REG_VIN_MIN(i), 0);
+       }
+       for (i = 0; i < 3; i++) {
+               tmp = it87_read_value(client, IT87_REG_TEMP_HIGH(i));
+               if (tmp == 0xff)
+                       it87_write_value(client, IT87_REG_TEMP_HIGH(i), 127);
+       }
+
        /* Check if temperature channnels are reset manually or by some reason */
        tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
        if ((tmp & 0x3f) == 0) {
@@ -1068,6 +1298,18 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
                data->fan_main_ctrl |= 0x70;
                it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
        }
+       data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
+
+       /* Set tachometers to 16-bit mode if needed */
+       if (data->type == it8716 || data->type == it8718) {
+               tmp = it87_read_value(client, IT87_REG_FAN_16BIT);
+               if (~tmp & 0x07 & data->has_fan) {
+                       dev_dbg(&client->dev,
+                               "Setting fan1-3 to 16-bit mode\n");
+                       it87_write_value(client, IT87_REG_FAN_16BIT,
+                                        tmp | 0x07);
+               }
+       }
 
        /* Set current fan mode registers and the default settings for the
         * other mode registers */
@@ -1118,18 +1360,26 @@ static struct it87_data *it87_update_device(struct device *dev)
                        data->in_max[i] =
                            it87_read_value(client, IT87_REG_VIN_MAX(i));
                }
+               /* in8 (battery) has no limit registers */
                data->in[8] =
                    it87_read_value(client, IT87_REG_VIN(8));
-               /* Temperature sensor doesn't have limit registers, set
-                  to min and max value */
-               data->in_min[8] = 0;
-               data->in_max[8] = 255;
 
                for (i = 0; i < 3; i++) {
-                       data->fan[i] =
-                           it87_read_value(client, IT87_REG_FAN(i));
+                       /* Skip disabled fans */
+                       if (!(data->has_fan & (1 << i)))
+                               continue;
+
                        data->fan_min[i] =
                            it87_read_value(client, IT87_REG_FAN_MIN(i));
+                       data->fan[i] = it87_read_value(client,
+                                      IT87_REG_FAN(i));
+                       /* Add high byte if in 16-bit mode */
+                       if (data->type == it8716 || data->type == it8718) {
+                               data->fan[i] |= it87_read_value(client,
+                                               IT87_REG_FANX(i)) << 8;
+                               data->fan_min[i] |= it87_read_value(client,
+                                               IT87_REG_FANX_MIN(i)) << 8;
+                       }
                }
                for (i = 0; i < 3; i++) {
                        data->temp[i] =
@@ -1140,10 +1390,14 @@ static struct it87_data *it87_update_device(struct device *dev)
                            it87_read_value(client, IT87_REG_TEMP_LOW(i));
                }
 
-               i = it87_read_value(client, IT87_REG_FAN_DIV);
-               data->fan_div[0] = i & 0x07;
-               data->fan_div[1] = (i >> 3) & 0x07;
-               data->fan_div[2] = (i & 0x40) ? 3 : 1;
+               /* Newer chips don't have clock dividers */
+               if ((data->has_fan & 0x07) && data->type != it8716
+                && data->type != it8718) {
+                       i = it87_read_value(client, IT87_REG_FAN_DIV);
+                       data->fan_div[0] = i & 0x07;
+                       data->fan_div[1] = (i >> 3) & 0x07;
+                       data->fan_div[2] = (i & 0x40) ? 3 : 1;
+               }
 
                data->alarms =
                        it87_read_value(client, IT87_REG_ALARM1) |
@@ -1153,9 +1407,11 @@ static struct it87_data *it87_update_device(struct device *dev)
 
                data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
                /* The 8705 does not have VID capability */
-               if (data->type == it8712) {
+               if (data->type == it8712 || data->type == it8716) {
                        data->vid = it87_read_value(client, IT87_REG_VID);
-                       data->vid &= 0x1f;
+                       /* The older IT8712F revisions had only 5 VID pins,
+                          but we assume it is always safe to read 6 bits. */
+                       data->vid &= 0x3f;
                }
                data->last_updated = jiffies;
                data->valid = 1;
@@ -1193,8 +1449,9 @@ static void __exit sm_it87_exit(void)
 }
 
 
-MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
-MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
+MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, "
+             "Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver");
 module_param(update_vbat, bool, 0);
 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
 module_param(fix_pwm_polarity, bool, 0);
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
new file mode 100644 (file)
index 0000000..f58b64e
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * k8temp.c - Linux kernel module for hardware monitoring
+ *
+ * Copyright (C) 2006 Rudolf Marek <r.marek@sh.cvut.cz>
+ *
+ * Inspired from the w83785 and amd756 drivers.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/pci.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#define TEMP_FROM_REG(val)     (((((val) >> 16) & 0xff) - 49) * 1000)
+#define REG_TEMP       0xe4
+#define SEL_PLACE      0x40
+#define SEL_CORE       0x04
+
+struct k8temp_data {
+       struct class_device *class_dev;
+       struct mutex update_lock;
+       const char *name;
+       char valid;             /* zero until following fields are valid */
+       unsigned long last_updated;     /* in jiffies */
+
+       /* registers values */
+       u8 sensorsp;            /* sensor presence bits - SEL_CORE & SEL_PLACE */
+       u32 temp[2][2];         /* core, place */
+};
+
+static struct k8temp_data *k8temp_update_device(struct device *dev)
+{
+       struct k8temp_data *data = dev_get_drvdata(dev);
+       struct pci_dev *pdev = to_pci_dev(dev);
+       u8 tmp;
+
+       mutex_lock(&data->update_lock);
+
+       if (!data->valid
+           || time_after(jiffies, data->last_updated + HZ)) {
+               pci_read_config_byte(pdev, REG_TEMP, &tmp);
+               tmp &= ~(SEL_PLACE | SEL_CORE);         /* Select sensor 0, core0 */
+               pci_write_config_byte(pdev, REG_TEMP, tmp);
+               pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]);
+
+               if (data->sensorsp & SEL_PLACE) {
+                       tmp |= SEL_PLACE;       /* Select sensor 1, core0 */
+                       pci_write_config_byte(pdev, REG_TEMP, tmp);
+                       pci_read_config_dword(pdev, REG_TEMP,
+                                             &data->temp[0][1]);
+               }
+
+               if (data->sensorsp & SEL_CORE) {
+                       tmp &= ~SEL_PLACE;      /* Select sensor 0, core1 */
+                       tmp |= SEL_CORE;
+                       pci_write_config_byte(pdev, REG_TEMP, tmp);
+                       pci_read_config_dword(pdev, REG_TEMP,
+                                             &data->temp[1][0]);
+
+                       if (data->sensorsp & SEL_PLACE) {
+                               tmp |= SEL_PLACE;       /* Select sensor 1, core1 */
+                               pci_write_config_byte(pdev, REG_TEMP, tmp);
+                               pci_read_config_dword(pdev, REG_TEMP,
+                                                     &data->temp[1][1]);
+                       }
+               }
+
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       mutex_unlock(&data->update_lock);
+       return data;
+}
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+                        *devattr, char *buf)
+{
+       struct k8temp_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+
+static ssize_t show_temp(struct device *dev,
+                        struct device_attribute *devattr, char *buf)
+{
+       struct sensor_device_attribute_2 *attr =
+           to_sensor_dev_attr_2(devattr);
+       int core = attr->nr;
+       int place = attr->index;
+       struct k8temp_data *data = k8temp_update_device(dev);
+
+       return sprintf(buf, "%d\n",
+                      TEMP_FROM_REG(data->temp[core][place]));
+}
+
+/* core, place */
+
+static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1);
+static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static struct pci_device_id k8temp_ids[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
+       { 0 },
+};
+
+MODULE_DEVICE_TABLE(pci, k8temp_ids);
+
+static int __devinit k8temp_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *id)
+{
+       int err;
+       u8 scfg;
+       u32 temp;
+       struct k8temp_data *data;
+       u32 cpuid = cpuid_eax(1);
+
+       /* this feature should be available since SH-C0 core */
+       if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) {
+               err = -ENODEV;
+               goto exit;
+       }
+
+       if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       pci_read_config_byte(pdev, REG_TEMP, &scfg);
+       scfg &= ~(SEL_PLACE | SEL_CORE);                /* Select sensor 0, core0 */
+       pci_write_config_byte(pdev, REG_TEMP, scfg);
+       pci_read_config_byte(pdev, REG_TEMP, &scfg);
+
+       if (scfg & (SEL_PLACE | SEL_CORE)) {
+               dev_err(&pdev->dev, "Configuration bit(s) stuck at 1!\n");
+               err = -ENODEV;
+               goto exit_free;
+       }
+
+       scfg |= (SEL_PLACE | SEL_CORE);
+       pci_write_config_byte(pdev, REG_TEMP, scfg);
+
+       /* now we know if we can change core and/or sensor */
+       pci_read_config_byte(pdev, REG_TEMP, &data->sensorsp);
+
+       if (data->sensorsp & SEL_PLACE) {
+               scfg &= ~SEL_CORE;      /* Select sensor 1, core0 */
+               pci_write_config_byte(pdev, REG_TEMP, scfg);
+               pci_read_config_dword(pdev, REG_TEMP, &temp);
+               scfg |= SEL_CORE;       /* prepare for next selection */
+               if (!((temp >> 16) & 0xff))     /* if temp is 0 -49C is not likely */
+                       data->sensorsp &= ~SEL_PLACE;
+       }
+
+       if (data->sensorsp & SEL_CORE) {
+               scfg &= ~SEL_PLACE;     /* Select sensor 0, core1 */
+               pci_write_config_byte(pdev, REG_TEMP, scfg);
+               pci_read_config_dword(pdev, REG_TEMP, &temp);
+               if (!((temp >> 16) & 0xff))     /* if temp is 0 -49C is not likely */
+                       data->sensorsp &= ~SEL_CORE;
+       }
+
+       data->name = "k8temp";
+       mutex_init(&data->update_lock);
+       dev_set_drvdata(&pdev->dev, data);
+
+       /* Register sysfs hooks */
+       err = device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       if (err)
+               goto exit_remove;
+
+       /* sensor can be changed and reports something */
+       if (data->sensorsp & SEL_PLACE) {
+               err = device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_temp2_input.dev_attr);
+               if (err)
+                       goto exit_remove;
+       }
+
+       /* core can be changed and reports something */
+       if (data->sensorsp & SEL_CORE) {
+               err = device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_temp3_input.dev_attr);
+               if (err)
+                       goto exit_remove;
+               if (data->sensorsp & SEL_PLACE)
+                       err = device_create_file(&pdev->dev,
+                                          &sensor_dev_attr_temp4_input.
+                                          dev_attr);
+                       if (err)
+                               goto exit_remove;
+       }
+
+       err = device_create_file(&pdev->dev, &dev_attr_name);
+       if (err)
+               goto exit_remove;
+
+       data->class_dev = hwmon_device_register(&pdev->dev);
+
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
+       }
+
+       return 0;
+
+exit_remove:
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp4_input.dev_attr);
+       device_remove_file(&pdev->dev, &dev_attr_name);
+exit_free:
+       dev_set_drvdata(&pdev->dev, NULL);
+       kfree(data);
+exit:
+       return err;
+}
+
+static void __devexit k8temp_remove(struct pci_dev *pdev)
+{
+       struct k8temp_data *data = dev_get_drvdata(&pdev->dev);
+
+       hwmon_device_unregister(data->class_dev);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_input.dev_attr);
+       device_remove_file(&pdev->dev,
+                          &sensor_dev_attr_temp4_input.dev_attr);
+       device_remove_file(&pdev->dev, &dev_attr_name);
+       dev_set_drvdata(&pdev->dev, NULL);
+       kfree(data);
+}
+
+static struct pci_driver k8temp_driver = {
+       .name = "k8temp",
+       .id_table = k8temp_ids,
+       .probe = k8temp_probe,
+       .remove = __devexit_p(k8temp_remove),
+};
+
+static int __init k8temp_init(void)
+{
+       return pci_register_driver(&k8temp_driver);
+}
+
+static void __exit k8temp_exit(void)
+{
+       pci_unregister_driver(&k8temp_driver);
+}
+
+MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
+MODULE_DESCRIPTION("AMD K8 core temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(k8temp_init)
+module_exit(k8temp_exit)
index 071f0fc6adecef40ba8022cd93eacfa7951540d6..d69f3cf07122462faf33bab61232d86782dd98ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lm63.c - driver for the National Semiconductor LM63 temperature sensor
  *          with integrated fan control
- * Copyright (C) 2004-2005  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2004-2006  Jean Delvare <khali@linux-fr.org>
  * Based on the lm90 driver.
  *
  * The LM63 is a sensor chip made by National Semiconductor. It measures
@@ -46,6 +46,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /*
  * Addresses to scan
@@ -330,6 +331,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
        return sprintf(buf, "%u\n", data->alarms);
 }
 
+static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr,
+                         char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct lm63_data *data = lm63_update_device(dev);
+       int bitnr = attr->index;
+
+       return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
+}
+
 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
 static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
        set_fan, 1);
@@ -350,8 +361,52 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
 static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
        set_temp2_crit_hyst);
 
+/* Individual alarm files */
+static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
+/* Raw alarm file for compatibility */
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *lm63_attributes[] = {
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm1_enable.attr,
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit.dev_attr.attr,
+       &dev_attr_temp2_crit_hyst.attr,
+
+       &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group lm63_group = {
+       .attrs = lm63_attributes,
+};
+
+static struct attribute *lm63_attributes_fan1[] = {
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+
+       &sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group lm63_group_fan1 = {
+       .attrs = lm63_attributes_fan1,
+};
+
 /*
  * Real code
  */
@@ -438,37 +493,26 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
        lm63_init_client(new_client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj,
+                                     &lm63_group)))
                goto exit_detach;
+       if (data->config & 0x04) { /* tachometer enabled */
+               if ((err = sysfs_create_group(&new_client->dev.kobj,
+                                             &lm63_group_fan1)))
+                       goto exit_remove_files;
        }
 
-       if (data->config & 0x04) { /* tachometer enabled */
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_fan1_input.dev_attr);
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_fan1_min.dev_attr);
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
        }
-       device_create_file(&new_client->dev, &dev_attr_pwm1);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_min.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_max.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_crit.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
 
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
+       sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -518,6 +562,8 @@ static int lm63_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm63_group);
+       sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
 
        if ((err = i2c_detach_client(client)))
                return err;
index fc25b90ec24a5ec5d0cda40cd335ff0bc7e1aa24..7c65b8bb6d721498c9ac1e0f2dc968bb1b2f4744 100644 (file)
@@ -112,6 +112,18 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, lm75_detect);
 }
 
+static struct attribute *lm75_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm75_group = {
+       .attrs = lm75_attributes,
+};
+
 /* This function is called by i2c_probe */
 static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
 {
@@ -199,18 +211,19 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
        lm75_init_client(new_client);
        
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &lm75_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -223,6 +236,7 @@ static int lm75_detach_client(struct i2c_client *client)
 {
        struct lm75_data *data = i2c_get_clientdata(client);
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm75_group);
        i2c_detach_client(client);
        kfree(data);
        return 0;
index 459cc977380a33fc36dbae7bdb968734b1a85cd9..dd969f1e84154e6d754b63cfd8f013d09b3dc87e 100644 (file)
@@ -212,6 +212,23 @@ static int lm77_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, lm77_detect);
 }
 
+static struct attribute *lm77_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_crit.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_crit_hyst.attr,
+       &dev_attr_temp1_min_hyst.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_alarms.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm77_group = {
+       .attrs = lm77_attributes,
+};
+
 /* This function is called by i2c_probe */
 static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
 {
@@ -317,22 +334,19 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
        lm77_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &lm77_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -345,6 +359,7 @@ static int lm77_detach_client(struct i2c_client *client)
 {
        struct lm77_data *data = i2c_get_clientdata(client);
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm77_group);
        i2c_detach_client(client);
        kfree(data);
        return 0;
index fa1715b9a9967618a398006bc73ea9a4f6b316f4..ac1b746df6d0ad765b97bcb2fd77cb5bb99dabcb 100644 (file)
@@ -482,6 +482,50 @@ static int lm78_isa_attach_adapter(struct i2c_adapter *adapter)
        return lm78_detect(adapter, isa_address, -1);
 }
 
+static struct attribute *lm78_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in5_max.attr,
+       &dev_attr_in6_input.attr,
+       &dev_attr_in6_min.attr,
+       &dev_attr_in6_max.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan3_min.attr,
+       &dev_attr_fan3_div.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_cpu0_vid.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm78_group = {
+       .attrs = lm78_attributes,
+};
+
 /* This function is called by i2c_probe */
 static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
 {
@@ -616,50 +660,19 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group)))
+               goto ERROR3;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto ERROR3;
+               goto ERROR4;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in4_input);
-       device_create_file(&new_client->dev, &dev_attr_in4_min);
-       device_create_file(&new_client->dev, &dev_attr_in4_max);
-       device_create_file(&new_client->dev, &dev_attr_in5_input);
-       device_create_file(&new_client->dev, &dev_attr_in5_min);
-       device_create_file(&new_client->dev, &dev_attr_in5_max);
-       device_create_file(&new_client->dev, &dev_attr_in6_input);
-       device_create_file(&new_client->dev, &dev_attr_in6_min);
-       device_create_file(&new_client->dev, &dev_attr_in6_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_fan3_input);
-       device_create_file(&new_client->dev, &dev_attr_fan3_min);
-       device_create_file(&new_client->dev, &dev_attr_fan3_div);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-
        return 0;
 
+ERROR4:
+       sysfs_remove_group(&new_client->dev.kobj, &lm78_group);
 ERROR3:
        i2c_detach_client(new_client);
 ERROR2:
@@ -677,6 +690,7 @@ static int lm78_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm78_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index b4ccdfc0120305bc6f50e04542c0f953150def95..064516d824add6deca6527a1a7a0255884a19514 100644 (file)
@@ -394,6 +394,48 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, lm80_detect);
 }
 
+static struct attribute *lm80_attributes[] = {
+       &dev_attr_in0_min.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in6_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_max.attr,
+       &dev_attr_in5_max.attr,
+       &dev_attr_in6_max.attr,
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in6_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_div.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_temp1_crit.attr,
+       &dev_attr_temp1_crit_hyst.attr,
+       &dev_attr_alarms.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm80_group = {
+       .attrs = lm80_attributes,
+};
+
 static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
 {
        int i, cur;
@@ -452,48 +494,19 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
        data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group)))
+               goto error_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto error_detach;
+               goto error_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in4_min);
-       device_create_file(&new_client->dev, &dev_attr_in5_min);
-       device_create_file(&new_client->dev, &dev_attr_in6_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in4_max);
-       device_create_file(&new_client->dev, &dev_attr_in5_max);
-       device_create_file(&new_client->dev, &dev_attr_in6_max);
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in4_input);
-       device_create_file(&new_client->dev, &dev_attr_in5_input);
-       device_create_file(&new_client->dev, &dev_attr_in6_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
        return 0;
 
+error_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &lm80_group);
 error_detach:
        i2c_detach_client(new_client);
 error_free:
@@ -508,7 +521,7 @@ static int lm80_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
-
+       sysfs_remove_group(&client->dev.kobj, &lm80_group);
        if ((err = i2c_detach_client(client)))
                return err;
 
index 2137d7879df668f1f91e46d94a77ed8a2adca043..feb87b41e9865ab10750c9bf247797690ae6d67b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2005  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2006  Jean Delvare <khali@linux-fr.org>
  *
  * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
  * a sensor chip made by National Semiconductor. It reports up to four
@@ -40,6 +40,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /*
  * Addresses to scan
@@ -191,6 +192,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
        return sprintf(buf, "%d\n", data->alarms);
 }
 
+static ssize_t show_alarm(struct device *dev, struct device_attribute
+                         *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct lm83_data *data = lm83_update_device(dev);
+       int bitnr = attr->index;
+
+       return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
+}
+
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
@@ -208,8 +219,64 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp, NULL, 8);
 static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp,
        set_temp, 8);
 static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8);
+
+/* Individual alarm files */
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9);
+static SENSOR_DEVICE_ATTR(temp4_input_fault, S_IRUGO, show_alarm, NULL, 10);
+static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12);
+static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 13);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15);
+/* Raw alarm file for compatibility */
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *lm83_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit.dev_attr.attr,
+       &sensor_dev_attr_temp3_crit.dev_attr.attr,
+
+       &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp3_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group lm83_group = {
+       .attrs = lm83_attributes,
+};
+
+static struct attribute *lm83_attributes_opt[] = {
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp4_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp4_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit.dev_attr.attr,
+       &sensor_dev_attr_temp4_crit.dev_attr.attr,
+
+       &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp4_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group lm83_group_opt = {
+       .attrs = lm83_attributes_opt,
+};
+
 /*
  * Real code
  */
@@ -318,59 +385,32 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
                goto exit_free;
 
        /*
-        * Initialize the LM83 chip
-        * (Nothing to do for this one.)
-        */
-
-       /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
-               goto exit_detach;
-       }
-
-       /*
+        * Register sysfs hooks
         * The LM82 can only monitor one external diode which is
         * at the same register as the LM83 temp3 entry - so we
         * declare 1 and 3 common, and then 2 and 4 only for the LM83.
         */
 
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp3_input.dev_attr);
-
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp3_max.dev_attr);
-
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_crit.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp3_crit.dev_attr);
-
-       device_create_file(&new_client->dev, &dev_attr_alarms);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group)))
+               goto exit_detach;
 
        if (kind == lm83) {
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp2_input.dev_attr);
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp4_input.dev_attr);
-
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp2_max.dev_attr);
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp4_max.dev_attr);
-
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp2_crit.dev_attr);
-               device_create_file(&new_client->dev,
-                                  &sensor_dev_attr_temp4_crit.dev_attr);
+               if ((err = sysfs_create_group(&new_client->dev.kobj,
+                                             &lm83_group_opt)))
+                       goto exit_remove_files;
+       }
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
        }
 
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &lm83_group);
+       sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -385,6 +425,8 @@ static int lm83_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm83_group);
+       sysfs_remove_group(&client->dev.kobj, &lm83_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 342e9663119d45ef9d7c14a9ab240110ca554523..2c3293cf69d10303a3a17bde4fb06471a023cefa 100644 (file)
@@ -1025,6 +1025,89 @@ static int lm85_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, lm85_detect);
 }
 
+static struct attribute *lm85_attributes[] = {
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan4_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan3_min.attr,
+       &dev_attr_fan4_min.attr,
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_pwm3.attr,
+       &dev_attr_pwm1_enable.attr,
+       &dev_attr_pwm2_enable.attr,
+       &dev_attr_pwm3_enable.attr,
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp3_min.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_vrm.attr,
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_pwm1_auto_channels.attr,
+       &dev_attr_pwm2_auto_channels.attr,
+       &dev_attr_pwm3_auto_channels.attr,
+       &dev_attr_pwm1_auto_pwm_min.attr,
+       &dev_attr_pwm2_auto_pwm_min.attr,
+       &dev_attr_pwm3_auto_pwm_min.attr,
+       &dev_attr_pwm1_auto_pwm_minctl.attr,
+       &dev_attr_pwm2_auto_pwm_minctl.attr,
+       &dev_attr_pwm3_auto_pwm_minctl.attr,
+       &dev_attr_pwm1_auto_pwm_freq.attr,
+       &dev_attr_pwm2_auto_pwm_freq.attr,
+       &dev_attr_pwm3_auto_pwm_freq.attr,
+       &dev_attr_temp1_auto_temp_off.attr,
+       &dev_attr_temp2_auto_temp_off.attr,
+       &dev_attr_temp3_auto_temp_off.attr,
+       &dev_attr_temp1_auto_temp_min.attr,
+       &dev_attr_temp2_auto_temp_min.attr,
+       &dev_attr_temp3_auto_temp_min.attr,
+       &dev_attr_temp1_auto_temp_max.attr,
+       &dev_attr_temp2_auto_temp_max.attr,
+       &dev_attr_temp3_auto_temp_max.attr,
+       &dev_attr_temp1_auto_temp_crit.attr,
+       &dev_attr_temp2_auto_temp_crit.attr,
+       &dev_attr_temp3_auto_temp_crit.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm85_group = {
+       .attrs = lm85_attributes,
+};
+
+static struct attribute *lm85_attributes_opt[] = {
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm85_group_opt = {
+       .attrs = lm85_attributes_opt,
+};
+
 static int lm85_detect(struct i2c_adapter *adapter, int address,
                int kind)
 {
@@ -1163,87 +1246,33 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
        lm85_init_client(new_client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm85_group)))
                goto ERROR2;
-       }
-
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan3_input);
-       device_create_file(&new_client->dev, &dev_attr_fan4_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan3_min);
-       device_create_file(&new_client->dev, &dev_attr_fan4_min);
-       device_create_file(&new_client->dev, &dev_attr_pwm1);
-       device_create_file(&new_client->dev, &dev_attr_pwm2);
-       device_create_file(&new_client->dev, &dev_attr_pwm3);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp3_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp3_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp3_max);
-       device_create_file(&new_client->dev, &dev_attr_vrm);
-       device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_auto_channels);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_auto_channels);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_auto_channels);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_min);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_min);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_min);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_minctl);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_minctl);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_minctl);
-       device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_freq);
-       device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_freq);
-       device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_freq);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_off);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_off);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_off);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_min);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_max);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit);
 
        /* The ADT7463 has an optional VRM 10 mode where pin 21 is used
           as a sixth digital VID input rather than an analog input. */
        data->vid = lm85_read_value(new_client, LM85_REG_VID);
-       if (!(kind == adt7463 && (data->vid & 0x80))) {
-               device_create_file(&new_client->dev, &dev_attr_in4_input);
-               device_create_file(&new_client->dev, &dev_attr_in4_min);
-               device_create_file(&new_client->dev, &dev_attr_in4_max);
+       if (!(kind == adt7463 && (data->vid & 0x80)))
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in4_max)))
+                       goto ERROR3;
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR3;
        }
 
        return 0;
 
        /* Error out and cleanup code */
+    ERROR3:
+       sysfs_remove_group(&new_client->dev.kobj, &lm85_group);
+       sysfs_remove_group(&new_client->dev.kobj, &lm85_group_opt);
     ERROR2:
        i2c_detach_client(new_client);
     ERROR1:
@@ -1256,6 +1285,8 @@ static int lm85_detach_client(struct i2c_client *client)
 {
        struct lm85_data *data = i2c_get_clientdata(client);
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm85_group);
+       sysfs_remove_group(&client->dev.kobj, &lm85_group_opt);
        i2c_detach_client(client);
        kfree(data);
        return 0;
index e6c1b638c971dc68ef8fe4d21904e66b67fa3783..3ce825489e349c0c106646356397aa87eae69531 100644 (file)
@@ -542,6 +542,78 @@ static int lm87_attach_adapter(struct i2c_adapter *adapter)
        return i2c_probe(adapter, &addr_data, lm87_detect);
 }
 
+static struct attribute *lm87_attributes[] = {
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_crit.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp2_crit.attr,
+
+       &dev_attr_alarms.attr,
+       &dev_attr_aout_output.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm87_group = {
+       .attrs = lm87_attributes,
+};
+
+static struct attribute *lm87_attributes_opt[] = {
+       &dev_attr_in6_input.attr,
+       &dev_attr_in6_min.attr,
+       &dev_attr_in6_max.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+
+       &dev_attr_in7_input.attr,
+       &dev_attr_in7_min.attr,
+       &dev_attr_in7_max.attr,
+
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_temp3_min.attr,
+       &dev_attr_temp3_crit.attr,
+
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in5_max.attr,
+
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm87_group_opt = {
+       .attrs = lm87_attributes_opt,
+};
+
 /*
  * The following function does more than just detection. If detection
  * succeeds, it also registers the new chip.
@@ -609,77 +681,90 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
        data->in_scale[7] = 1875;
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group)))
                goto exit_detach;
-       }
-
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in4_input);
-       device_create_file(&new_client->dev, &dev_attr_in4_min);
-       device_create_file(&new_client->dev, &dev_attr_in4_max);
 
        if (data->channel & CHAN_NO_FAN(0)) {
-               device_create_file(&new_client->dev, &dev_attr_in6_input);
-               device_create_file(&new_client->dev, &dev_attr_in6_min);
-               device_create_file(&new_client->dev, &dev_attr_in6_max);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_max)))
+                       goto exit_remove;
        } else {
-               device_create_file(&new_client->dev, &dev_attr_fan1_input);
-               device_create_file(&new_client->dev, &dev_attr_fan1_min);
-               device_create_file(&new_client->dev, &dev_attr_fan1_div);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan1_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan1_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan1_div)))
+                       goto exit_remove;
        }
+
        if (data->channel & CHAN_NO_FAN(1)) {
-               device_create_file(&new_client->dev, &dev_attr_in7_input);
-               device_create_file(&new_client->dev, &dev_attr_in7_min);
-               device_create_file(&new_client->dev, &dev_attr_in7_max);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in7_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in7_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in7_max)))
+                       goto exit_remove;
        } else {
-               device_create_file(&new_client->dev, &dev_attr_fan2_input);
-               device_create_file(&new_client->dev, &dev_attr_fan2_min);
-               device_create_file(&new_client->dev, &dev_attr_fan2_div);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan2_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan2_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan2_div)))
+                       goto exit_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-
        if (data->channel & CHAN_TEMP3) {
-               device_create_file(&new_client->dev, &dev_attr_temp3_input);
-               device_create_file(&new_client->dev, &dev_attr_temp3_max);
-               device_create_file(&new_client->dev, &dev_attr_temp3_min);
-               device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_max))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_crit)))
+                       goto exit_remove;
        } else {
-               device_create_file(&new_client->dev, &dev_attr_in0_input);
-               device_create_file(&new_client->dev, &dev_attr_in0_min);
-               device_create_file(&new_client->dev, &dev_attr_in0_max);
-               device_create_file(&new_client->dev, &dev_attr_in5_input);
-               device_create_file(&new_client->dev, &dev_attr_in5_min);
-               device_create_file(&new_client->dev, &dev_attr_in5_max);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in0_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in0_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in0_max))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_max)))
+                       goto exit_remove;
        }
 
        if (!(data->channel & CHAN_NO_VID)) {
-               device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-               device_create_file(&new_client->dev, &dev_attr_vrm);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_cpu0_vid))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_vrm)))
+                       goto exit_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       device_create_file(&new_client->dev, &dev_attr_aout_output);
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
+       }
 
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &lm87_group);
+       sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -732,6 +817,8 @@ static int lm87_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm87_group);
+       sysfs_remove_group(&client->dev.kobj, &lm87_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
index d9eeaf7585bd3be3d171ba2d8f33a3b9393564e3..6882ce75feee99b5c2ab9f4f94b5f3a78820728a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2005  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2006  Jean Delvare <khali@linux-fr.org>
  *
  * Based on the lm83 driver. The LM90 is a sensor chip made by National
  * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -79,6 +79,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /*
  * Addresses to scan
@@ -327,6 +328,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
        return sprintf(buf, "%d\n", data->alarms);
 }
 
+static ssize_t show_alarm(struct device *dev, struct device_attribute
+                         *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct lm90_data *data = lm90_update_device(dev);
+       int bitnr = attr->index;
+
+       return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
+}
+
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
@@ -344,8 +355,45 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
 static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
        set_temphyst, 3);
 static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
+
+/* Individual alarm files */
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
+/* Raw alarm file for compatibility */
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *lm90_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_min.dev_attr.attr,
+       &sensor_dev_attr_temp2_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
+
+       &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group lm90_group = {
+       .attrs = lm90_attributes,
+};
+
 /* pec used for ADM1032 only */
 static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
                        char *buf)
@@ -569,39 +617,25 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
        lm90_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group)))
+               goto exit_detach;
+       if (new_client->flags & I2C_CLIENT_PEC) {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_pec)))
+                       goto exit_remove_files;
+       }
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_min.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_min.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_max.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_crit.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_crit.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_crit_hyst.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp2_crit_hyst.dev_attr);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
-       if (new_client->flags & I2C_CLIENT_PEC)
-               device_create_file(&new_client->dev, &dev_attr_pec);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &lm90_group);
+       device_remove_file(&new_client->dev, &dev_attr_pec);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -634,6 +668,8 @@ static int lm90_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm90_group);
+       device_remove_file(&client->dev, &dev_attr_pec);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 197f77226dc478a4d440700659d46d06da90e74d..30b536333f1469f537bd27799f5c5ada55d88323 100644 (file)
@@ -288,6 +288,23 @@ static int max6635_check(struct i2c_client *client)
        return 1;
 }
 
+static struct attribute *lm92_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_crit.attr,
+       &dev_attr_temp1_crit_hyst.attr,
+       &dev_attr_temp1_min.attr,
+       &dev_attr_temp1_min_hyst.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_alarms.attr,
+
+       NULL
+};
+
+static const struct attribute_group lm92_group = {
+       .attrs = lm92_attributes,
+};
+
 /* The following function does more than just detection. If detection
    succeeds, it also registers the new chip. */
 static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
@@ -359,23 +376,19 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
        lm92_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min);
-       device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
        return 0;
 
+exit_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &lm92_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -397,6 +410,7 @@ static int lm92_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &lm92_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index b4135b5971f4d67d25404532c75c9472132f4ff2..2f58f651f03a5c7af92d8322c3ff041a83cc12b1 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
                                        0x29, 0x2a, 0x2b,
@@ -172,6 +173,22 @@ static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2,
        set_temp_hyst2);
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *max1619_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_min.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_crit.attr,
+       &dev_attr_temp2_crit_hyst.attr,
+
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group max1619_group = {
+       .attrs = max1619_attributes,
+};
+
 /*
  * Real code
  */
@@ -273,22 +290,19 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
        max1619_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_min);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-       device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &max1619_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -318,6 +332,7 @@ static int max1619_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &max1619_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 236f9f29c624647dcea8e4eb9518be488cabcce7..3b8b81984ad4cf04ab3c0fdb91079654cbda519e 100644 (file)
@@ -328,6 +328,12 @@ static struct sensor_device_attribute fan_min[] = {
        SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2),
 };
 
+#define FAN_UNIT_ATTRS(X)      \
+       &fan_input[X].dev_attr.attr,    \
+       &fan_status[X].dev_attr.attr,   \
+       &fan_div[X].dev_attr.attr,      \
+       &fan_min[X].dev_attr.attr
+
 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -360,6 +366,19 @@ static struct sensor_device_attribute pwm[] = {
        SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2),
 };
 
+static struct attribute * pc8736x_fan_attr_array[] = {
+       FAN_UNIT_ATTRS(0),
+       FAN_UNIT_ATTRS(1),
+       FAN_UNIT_ATTRS(2),
+       &pwm[0].dev_attr.attr,
+       &pwm[1].dev_attr.attr,
+       &pwm[2].dev_attr.attr,
+       NULL
+};
+static const struct attribute_group pc8736x_fan_group = {
+       .attrs = pc8736x_fan_attr_array,
+};
+
 static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -472,6 +491,61 @@ static struct sensor_device_attribute in_max[] = {
        SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10),
 };
 
+#define VIN_UNIT_ATTRS(X) \
+       &in_input[X].dev_attr.attr,     \
+       &in_status[X].dev_attr.attr,    \
+       &in_min[X].dev_attr.attr,       \
+       &in_max[X].dev_attr.attr
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       return sprintf(buf, "%u\n", data->vrm);
+}
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct pc87360_data *data = i2c_get_clientdata(client);
+       data->vrm = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       return sprintf(buf, "%u\n", data->in_alarms);
+}
+static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
+
+static struct attribute *pc8736x_vin_attr_array[] = {
+       VIN_UNIT_ATTRS(0),
+       VIN_UNIT_ATTRS(1),
+       VIN_UNIT_ATTRS(2),
+       VIN_UNIT_ATTRS(3),
+       VIN_UNIT_ATTRS(4),
+       VIN_UNIT_ATTRS(5),
+       VIN_UNIT_ATTRS(6),
+       VIN_UNIT_ATTRS(7),
+       VIN_UNIT_ATTRS(8),
+       VIN_UNIT_ATTRS(9),
+       VIN_UNIT_ATTRS(10),
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       &dev_attr_alarms_in.attr,
+       NULL
+};
+static const struct attribute_group pc8736x_vin_group = {
+       .attrs = pc8736x_vin_attr_array,
+};
+
 static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -590,33 +664,22 @@ static struct sensor_device_attribute therm_crit[] = {
                    show_therm_crit, set_therm_crit, 2+11),
 };
 
-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct pc87360_data *data = pc87360_update_device(dev);
-       return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-
-static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct pc87360_data *data = pc87360_update_device(dev);
-       return sprintf(buf, "%u\n", data->vrm);
-}
-static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       struct pc87360_data *data = i2c_get_clientdata(client);
-       data->vrm = simple_strtoul(buf, NULL, 10);
-       return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-
-static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct pc87360_data *data = pc87360_update_device(dev);
-       return sprintf(buf, "%u\n", data->in_alarms);
-}
-static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
+#define THERM_UNIT_ATTRS(X) \
+       &therm_input[X].dev_attr.attr,  \
+       &therm_status[X].dev_attr.attr, \
+       &therm_min[X].dev_attr.attr,    \
+       &therm_max[X].dev_attr.attr,    \
+       &therm_crit[X].dev_attr.attr
+
+static struct attribute * pc8736x_therm_attr_array[] = {
+       THERM_UNIT_ATTRS(0),
+       THERM_UNIT_ATTRS(1),
+       THERM_UNIT_ATTRS(2),
+       NULL
+};
+static const struct attribute_group pc8736x_therm_group = {
+       .attrs = pc8736x_therm_attr_array,
+};
 
 static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf)
 {
@@ -736,6 +799,25 @@ static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *att
 }
 static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
 
+#define TEMP_UNIT_ATTRS(X) \
+       &temp_input[X].dev_attr.attr,   \
+       &temp_status[X].dev_attr.attr,  \
+       &temp_min[X].dev_attr.attr,     \
+       &temp_max[X].dev_attr.attr,     \
+       &temp_crit[X].dev_attr.attr
+
+static struct attribute * pc8736x_temp_attr_array[] = {
+       TEMP_UNIT_ATTRS(0),
+       TEMP_UNIT_ATTRS(1),
+       TEMP_UNIT_ATTRS(2),
+       /* include the few miscellaneous atts here */
+       &dev_attr_alarms_temp.attr,
+       NULL
+};
+static const struct attribute_group pc8736x_temp_group = {
+       .attrs = pc8736x_temp_attr_array,
+};
+
 /*
  * Device detection, registration and update
  */
@@ -936,60 +1018,69 @@ static int pc87360_detect(struct i2c_adapter *adapter)
                pc87360_init_client(client, use_thermistors);
        }
 
-       /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       /* Register all-or-nothing sysfs groups */
+
+       if (data->innr &&
+           (err = sysfs_create_group(&client->dev.kobj,
+                                     &pc8736x_vin_group)))
                goto ERROR3;
-       }
 
-       if (data->innr) {
-               for (i = 0; i < 11; i++) {
-                       device_create_file(dev, &in_input[i].dev_attr);
-                       device_create_file(dev, &in_min[i].dev_attr);
-                       device_create_file(dev, &in_max[i].dev_attr);
-                       device_create_file(dev, &in_status[i].dev_attr);
-               }
-               device_create_file(dev, &dev_attr_cpu0_vid);
-               device_create_file(dev, &dev_attr_vrm);
-               device_create_file(dev, &dev_attr_alarms_in);
-       }
+       if (data->innr == 14 &&
+           (err = sysfs_create_group(&client->dev.kobj,
+                                     &pc8736x_therm_group)))
+               goto ERROR3;
+
+       /* create device attr-files for varying sysfs groups */
 
        if (data->tempnr) {
                for (i = 0; i < data->tempnr; i++) {
-                       device_create_file(dev, &temp_input[i].dev_attr);
-                       device_create_file(dev, &temp_min[i].dev_attr);
-                       device_create_file(dev, &temp_max[i].dev_attr);
-                       device_create_file(dev, &temp_crit[i].dev_attr);
-                       device_create_file(dev, &temp_status[i].dev_attr);
-               }
-               device_create_file(dev, &dev_attr_alarms_temp);
-       }
-
-       if (data->innr == 14) {
-               for (i = 0; i < 3; i++) {
-                       device_create_file(dev, &therm_input[i].dev_attr);
-                       device_create_file(dev, &therm_min[i].dev_attr);
-                       device_create_file(dev, &therm_max[i].dev_attr);
-                       device_create_file(dev, &therm_crit[i].dev_attr);
-                       device_create_file(dev, &therm_status[i].dev_attr);
+                       if ((err = device_create_file(dev,
+                                       &temp_input[i].dev_attr))
+                           || (err = device_create_file(dev,
+                                       &temp_min[i].dev_attr))
+                           || (err = device_create_file(dev,
+                                       &temp_max[i].dev_attr))
+                           || (err = device_create_file(dev,
+                                       &temp_crit[i].dev_attr))
+                           || (err = device_create_file(dev,
+                                       &temp_status[i].dev_attr)))
+                               goto ERROR3;
                }
+               if ((err = device_create_file(dev, &dev_attr_alarms_temp)))
+                       goto ERROR3;
        }
 
        for (i = 0; i < data->fannr; i++) {
-               if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
-                       device_create_file(dev, &fan_input[i].dev_attr);
-                       device_create_file(dev, &fan_min[i].dev_attr);
-                       device_create_file(dev, &fan_div[i].dev_attr);
-                       device_create_file(dev, &fan_status[i].dev_attr);
-               }
-               if (FAN_CONFIG_CONTROL(data->fan_conf, i))
-                       device_create_file(dev, &pwm[i].dev_attr);
+               if (FAN_CONFIG_MONITOR(data->fan_conf, i)
+                   && ((err = device_create_file(dev,
+                                       &fan_input[i].dev_attr))
+                       || (err = device_create_file(dev,
+                                       &fan_min[i].dev_attr))
+                       || (err = device_create_file(dev,
+                                       &fan_div[i].dev_attr))
+                       || (err = device_create_file(dev,
+                                       &fan_status[i].dev_attr))))
+                       goto ERROR3;
+
+               if (FAN_CONFIG_CONTROL(data->fan_conf, i)
+                   && (err = device_create_file(dev, &pwm[i].dev_attr)))
+                       goto ERROR3;
        }
 
+       data->class_dev = hwmon_device_register(&client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR3;
+       }
        return 0;
 
 ERROR3:
+       /* can still remove groups whose members were added individually */
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group);
+
        i2c_detach_client(client);
 ERROR2:
        for (i = 0; i < 3; i++) {
@@ -1009,6 +1100,11 @@ static int pc87360_detach_client(struct i2c_client *client)
 
        hwmon_device_unregister(data->class_dev);
 
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group);
+       sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group);
+
        if ((i = i2c_detach_client(client)))
                return i;
 
index 3783af4195bd9452e758ac84e874fe132e4d1767..95a4b5d9eaf29820cdba79472de2f97ea482f269 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include <asm/io.h>
 
 
@@ -473,6 +474,50 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
        return sprintf(buf, "%d\n", data->alarms);
 }
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static struct attribute *sis5595_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group sis5595_group = {
+       .attrs = sis5595_attributes,
+};
+
+static struct attribute *sis5595_attributes_opt[] = {
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       NULL
+};
+
+static const struct attribute_group sis5595_group_opt = {
+       .attrs = sis5595_attributes_opt,
+};
  
 /* This is called when the module is loaded */
 static int sis5595_detect(struct i2c_adapter *adapter)
@@ -566,43 +611,37 @@ static int sis5595_detect(struct i2c_adapter *adapter)
        }
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &sis5595_group)))
+               goto exit_detach;
+       if (data->maxins == 4) {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_min))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_in4_max)))
+                       goto exit_remove_files;
+       } else {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp1_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp1_max))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_temp1_max_hyst)))
+                       goto exit_remove_files;
+       }
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       if (data->maxins == 4) {
-               device_create_file(&new_client->dev, &dev_attr_in4_input);
-               device_create_file(&new_client->dev, &dev_attr_in4_min);
-               device_create_file(&new_client->dev, &dev_attr_in4_max);
-       }
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-       if (data->maxins == 3) {
-               device_create_file(&new_client->dev, &dev_attr_temp1_input);
-               device_create_file(&new_client->dev, &dev_attr_temp1_max);
-               device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       }
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &sis5595_group);
+       sysfs_remove_group(&new_client->dev.kobj, &sis5595_group_opt);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -619,6 +658,8 @@ static int sis5595_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &sis5595_group);
+       sysfs_remove_group(&client->dev.kobj, &sis5595_group_opt);
 
        if ((err = i2c_detach_client(client)))
                return err;
index a85869393bab323f361a94b3daee02fb46bb599f..72b0e2d8650ca1df9b5297190e28837ba5296858 100644 (file)
@@ -176,9 +176,6 @@ sysfs_temp(2);
 sysfs_temp(3);
 sysfs_temp(4);
 
-#define device_create_file_temp(client, num) \
-       device_create_file(&client->dev, &dev_attr_temp##num##_input)
-
 /* FAN: 1 RPM/bit
    REG: count of 90kHz pulses / revolution */
 static int fan_from_reg(u16 reg)
@@ -205,8 +202,22 @@ sysfs_fan(2);
 sysfs_fan(3);
 sysfs_fan(4);
 
-#define device_create_file_fan(client, num) \
-       device_create_file(&client->dev, &dev_attr_fan##num##_input)
+static struct attribute *smsc47b397_attributes[] = {
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp4_input.attr,
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan4_input.attr,
+
+       NULL
+};
+
+static const struct attribute_group smsc47b397_group = {
+       .attrs = smsc47b397_attributes,
+};
 
 static int smsc47b397_detach_client(struct i2c_client *client)
 {
@@ -214,6 +225,7 @@ static int smsc47b397_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &smsc47b397_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
@@ -268,24 +280,19 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
        if ((err = i2c_attach_client(new_client)))
                goto error_free;
 
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &smsc47b397_group)))
+               goto error_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto error_detach;
+               goto error_remove;
        }
 
-       device_create_file_temp(new_client, 1);
-       device_create_file_temp(new_client, 2);
-       device_create_file_temp(new_client, 3);
-       device_create_file_temp(new_client, 4);
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       device_create_file_fan(new_client, 3);
-       device_create_file_fan(new_client, 4);
-
        return 0;
 
+error_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &smsc47b397_group);
 error_detach:
        i2c_detach_client(new_client);
 error_free:
index 6c81b843d8314b9ef6ee9a4df0003d7fbaa93ad4..47132fd26b1bf9a4f1948864fe95a34ecb5afdf2 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include <asm/io.h>
 
 /* Address is autodetected, there is no default value */
@@ -347,6 +348,30 @@ fan_present(2);
 
 static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
 
+/* Almost all sysfs files may or may not be created depending on the chip
+   setup so we create them individually. It is still convenient to define a
+   group to remove them all at once. */
+static struct attribute *smsc47m1_attributes[] = {
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm1_enable.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_pwm2_enable.attr,
+
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group smsc47m1_group = {
+       .attrs = smsc47m1_attributes,
+};
+
 static int __init smsc47m1_find(unsigned short *addr)
 {
        u8 val;
@@ -429,7 +454,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
        pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
               == 0x04;
        if (!(fan1 || fan2 || pwm1 || pwm2)) {
-               dev_warn(&new_client->dev, "Device is not configured, will not use\n");
+               dev_warn(&adapter->dev, "Device at 0x%x is not configured, "
+                        "will not use\n", new_client->addr);
                err = -ENODEV;
                goto error_free;
        }
@@ -446,46 +472,62 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
        smsc47m1_update_device(&new_client->dev, 1);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
-               goto error_detach;
-       }
-
        if (fan1) {
-               device_create_file(&new_client->dev, &dev_attr_fan1_input);
-               device_create_file(&new_client->dev, &dev_attr_fan1_min);
-               device_create_file(&new_client->dev, &dev_attr_fan1_div);
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan1_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan1_min))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan1_div)))
+                       goto error_remove_files;
        } else
                dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
                        "skipping\n");
 
        if (fan2) {
-               device_create_file(&new_client->dev, &dev_attr_fan2_input);
-               device_create_file(&new_client->dev, &dev_attr_fan2_min);
-               device_create_file(&new_client->dev, &dev_attr_fan2_div);
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan2_input))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan2_min))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_fan2_div)))
+                       goto error_remove_files;
        } else
                dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
                        "skipping\n");
 
        if (pwm1) {
-               device_create_file(&new_client->dev, &dev_attr_pwm1);
-               device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_pwm1))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_pwm1_enable)))
+                       goto error_remove_files;
        } else
                dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
                        "skipping\n");
        if (pwm2) {
-               device_create_file(&new_client->dev, &dev_attr_pwm2);
-               device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_pwm2))
+                || (err = device_create_file(&new_client->dev,
+                                             &dev_attr_pwm2_enable)))
+                       goto error_remove_files;
        } else
                dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
                        "skipping\n");
 
-       device_create_file(&new_client->dev, &dev_attr_alarms);
+       if ((err = device_create_file(&new_client->dev, &dev_attr_alarms)))
+               goto error_remove_files;
+
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto error_remove_files;
+       }
 
        return 0;
 
-error_detach:
+error_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group);
        i2c_detach_client(new_client);
 error_free:
        kfree(data);
@@ -500,6 +542,7 @@ static int smsc47m1_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &smsc47m1_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
index bdc4570acf9a868893c2de71709c51dd0d639a7e..a6833f4373950c8f46295cdb3b579945c7feb668 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
+#include <linux/sysfs.h>
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
@@ -370,6 +371,75 @@ static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200);
 static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400);
 static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800);
 
+static struct attribute *smsc47m192_attributes[] = {
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in0_alarm.dev_attr.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in1_alarm.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in2_alarm.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in3_alarm.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &sensor_dev_attr_in5_alarm.dev_attr.attr,
+       &sensor_dev_attr_in6_input.dev_attr.attr,
+       &sensor_dev_attr_in6_min.dev_attr.attr,
+       &sensor_dev_attr_in6_max.dev_attr.attr,
+       &sensor_dev_attr_in6_alarm.dev_attr.attr,
+       &sensor_dev_attr_in7_input.dev_attr.attr,
+       &sensor_dev_attr_in7_min.dev_attr.attr,
+       &sensor_dev_attr_in7_max.dev_attr.attr,
+       &sensor_dev_attr_in7_alarm.dev_attr.attr,
+
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_offset.dev_attr.attr,
+       &sensor_dev_attr_temp1_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_min.dev_attr.attr,
+       &sensor_dev_attr_temp2_offset.dev_attr.attr,
+       &sensor_dev_attr_temp2_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp2_input_fault.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_min.dev_attr.attr,
+       &sensor_dev_attr_temp3_offset.dev_attr.attr,
+       &sensor_dev_attr_temp3_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp3_input_fault.dev_attr.attr,
+
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       NULL
+};
+
+static const struct attribute_group smsc47m192_group = {
+       .attrs = smsc47m192_attributes,
+};
+
+static struct attribute *smsc47m192_attributes_in4[] = {
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in4_alarm.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group smsc47m192_group_in4 = {
+       .attrs = smsc47m192_attributes_in4,
+};
+
 /* This function is called when:
     * smsc47m192_driver is inserted (when this module is loaded), for each
       available adapter
@@ -471,80 +541,28 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
        smsc47m192_init_client(client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group)))
                goto exit_detach;
-       }
-
-       device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr);
 
        /* Pin 110 is either in4 (+12V) or VID4 */
        config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
        if (!(config & 0x20)) {
-               device_create_file(&client->dev,
-                                  &sensor_dev_attr_in4_input.dev_attr);
-               device_create_file(&client->dev,
-                                  &sensor_dev_attr_in4_min.dev_attr);
-               device_create_file(&client->dev,
-                                  &sensor_dev_attr_in4_max.dev_attr);
-               device_create_file(&client->dev,
-                                  &sensor_dev_attr_in4_alarm.dev_attr);
+               if ((err = sysfs_create_group(&client->dev.kobj,
+                                             &smsc47m192_group_in4)))
+                       goto exit_remove_files;
+       }
+
+       data->class_dev = hwmon_device_register(&client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
        }
-       device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr);
-       device_create_file(&client->dev,
-                          &sensor_dev_attr_temp1_offset.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr);
-       device_create_file(&client->dev,
-                          &sensor_dev_attr_temp2_offset.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr);
-       device_create_file(&client->dev,
-                          &sensor_dev_attr_temp2_input_fault.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr);
-       device_create_file(&client->dev,
-                          &sensor_dev_attr_temp3_offset.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr);
-       device_create_file(&client->dev,
-                          &sensor_dev_attr_temp3_input_fault.dev_attr);
-       device_create_file(&client->dev, &dev_attr_cpu0_vid);
-       device_create_file(&client->dev, &dev_attr_vrm);
 
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
+       sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
 exit_detach:
        i2c_detach_client(client);
 exit_free:
@@ -559,6 +577,8 @@ static int smsc47m192_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
+       sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 95ae056e5a94a8a8729ddc223ec771b6cb09fb73..f8acada0537a7894d6dd318558e3bc71ca1dd546 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 #include <asm/io.h>
 
 
@@ -570,6 +571,48 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
 }
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *via686a_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_max.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_temp2_max_hyst.attr,
+       &dev_attr_temp3_max_hyst.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group via686a_group = {
+       .attrs = via686a_attributes,
+};
+
 /* The driver. I choose to use type i2c_driver, as at is identical to both
    smbus_driver and isa_driver, and clients could be of either kind */
 static struct i2c_driver via686a_driver = {
@@ -650,46 +693,19 @@ static int via686a_detect(struct i2c_adapter *adapter)
        via686a_init_client(new_client);
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group)))
+               goto exit_detach;
+
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove_files;
        }
 
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
-       device_create_file(&new_client->dev, &dev_attr_in2_input);
-       device_create_file(&new_client->dev, &dev_attr_in3_input);
-       device_create_file(&new_client->dev, &dev_attr_in4_input);
-       device_create_file(&new_client->dev, &dev_attr_in0_min);
-       device_create_file(&new_client->dev, &dev_attr_in1_min);
-       device_create_file(&new_client->dev, &dev_attr_in2_min);
-       device_create_file(&new_client->dev, &dev_attr_in3_min);
-       device_create_file(&new_client->dev, &dev_attr_in4_min);
-       device_create_file(&new_client->dev, &dev_attr_in0_max);
-       device_create_file(&new_client->dev, &dev_attr_in1_max);
-       device_create_file(&new_client->dev, &dev_attr_in2_max);
-       device_create_file(&new_client->dev, &dev_attr_in3_max);
-       device_create_file(&new_client->dev, &dev_attr_in4_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_input);
-       device_create_file(&new_client->dev, &dev_attr_temp2_input);
-       device_create_file(&new_client->dev, &dev_attr_temp3_input);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max);
-       device_create_file(&new_client->dev, &dev_attr_temp3_max);
-       device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp2_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_temp3_max_hyst);
-       device_create_file(&new_client->dev, &dev_attr_fan1_input);
-       device_create_file(&new_client->dev, &dev_attr_fan2_input);
-       device_create_file(&new_client->dev, &dev_attr_fan1_min);
-       device_create_file(&new_client->dev, &dev_attr_fan2_min);
-       device_create_file(&new_client->dev, &dev_attr_fan1_div);
-       device_create_file(&new_client->dev, &dev_attr_fan2_div);
-       device_create_file(&new_client->dev, &dev_attr_alarms);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&new_client->dev.kobj, &via686a_group);
 exit_detach:
        i2c_detach_client(new_client);
 exit_free:
@@ -705,6 +721,7 @@ static int via686a_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       sysfs_remove_group(&client->dev.kobj, &via686a_group);
 
        if ((err = i2c_detach_client(client)))
                return err;
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
new file mode 100644 (file)
index 0000000..25cc560
--- /dev/null
@@ -0,0 +1,1355 @@
+/*
+ * vt1211.c - driver for the VIA VT1211 Super-I/O chip integrated hardware
+ *            monitoring features
+ * Copyright (C) 2006 Juerg Haefliger <juergh@gmail.com>
+ *
+ * This driver is based on the driver for kernel 2.4 by Mark D. Studebaker
+ * and its port to kernel 2.6 by Lars Ekman.
+ *
+ * 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/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <asm/io.h>
+
+static int uch_config = -1;
+module_param(uch_config, int, 0);
+MODULE_PARM_DESC(uch_config, "Initialize the universal channel configuration");
+
+static int int_mode = -1;
+module_param(int_mode, int, 0);
+MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode");
+
+static struct platform_device *pdev;
+
+#define DRVNAME "vt1211"
+
+/* ---------------------------------------------------------------------
+ * Registers
+ *
+ * The sensors are defined as follows.
+ *
+ * Sensor          Voltage Mode   Temp Mode   Notes (from the datasheet)
+ * --------        ------------   ---------   --------------------------
+ * Reading 1                      temp1       Intel thermal diode
+ * Reading 3                      temp2       Internal thermal diode
+ * UCH1/Reading2   in0            temp3       NTC type thermistor
+ * UCH2            in1            temp4       +2.5V
+ * UCH3            in2            temp5       VccP
+ * UCH4            in3            temp6       +5V
+ * UCH5            in4            temp7       +12V
+ * 3.3V            in5                        Internal VDD (+3.3V)
+ *
+ * --------------------------------------------------------------------- */
+
+/* Voltages (in) numbered 0-5 (ix) */
+#define VT1211_REG_IN(ix)              (0x21 + (ix))
+#define VT1211_REG_IN_MIN(ix)          ((ix) == 0 ? 0x3e : 0x2a + 2 * (ix))
+#define VT1211_REG_IN_MAX(ix)          ((ix) == 0 ? 0x3d : 0x29 + 2 * (ix))
+
+/* Temperatures (temp) numbered 0-6 (ix) */
+static u8 regtemp[]    = {0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
+static u8 regtempmax[] = {0x39, 0x1d, 0x3d, 0x2b, 0x2d, 0x2f, 0x31};
+static u8 regtemphyst[]        = {0x3a, 0x1e, 0x3e, 0x2c, 0x2e, 0x30, 0x32};
+
+/* Fans numbered 0-1 (ix) */
+#define VT1211_REG_FAN(ix)             (0x29 + (ix))
+#define VT1211_REG_FAN_MIN(ix)         (0x3b + (ix))
+#define VT1211_REG_FAN_DIV              0x47
+
+/* PWMs numbered 0-1 (ix) */
+/* Auto points numbered 0-3 (ap) */
+#define VT1211_REG_PWM(ix)             (0x60 + (ix))
+#define VT1211_REG_PWM_CLK              0x50
+#define VT1211_REG_PWM_CTL              0x51
+#define VT1211_REG_PWM_AUTO_TEMP(ap)   (0x55 - (ap))
+#define VT1211_REG_PWM_AUTO_PWM(ix, ap)        (0x58 + 2 * (ix) - (ap))
+
+/* Miscellaneous registers */
+#define VT1211_REG_CONFIG              0x40
+#define VT1211_REG_ALARM1              0x41
+#define VT1211_REG_ALARM2              0x42
+#define VT1211_REG_VID                 0x45
+#define VT1211_REG_UCH_CONFIG          0x4a
+#define VT1211_REG_TEMP1_CONFIG                0x4b
+#define VT1211_REG_TEMP2_CONFIG                0x4c
+
+/* In, temp & fan alarm bits */
+static const u8 bitalarmin[]   = {11, 0, 1, 3, 8, 2, 9};
+static const u8 bitalarmtemp[] = {4, 15, 11, 0, 1, 3, 8};
+static const u8 bitalarmfan[]  = {6, 7};
+
+/* ---------------------------------------------------------------------
+ * Data structures and manipulation thereof
+ * --------------------------------------------------------------------- */
+
+struct vt1211_data {
+       unsigned short addr;
+       const char *name;
+       struct class_device *class_dev;
+
+       struct mutex update_lock;
+       char valid;                     /* !=0 if following fields are valid */
+       unsigned long last_updated;     /* In jiffies */
+
+       /* Register values */
+       u8  in[6];
+       u8  in_max[6];
+       u8  in_min[6];
+       u8  temp[7];
+       u8  temp_max[7];
+       u8  temp_hyst[7];
+       u8  fan[2];
+       u8  fan_min[2];
+       u8  fan_div[2];
+       u8  fan_ctl;
+       u8  pwm[2];
+       u8  pwm_ctl[2];
+       u8  pwm_clk;
+       u8  pwm_auto_temp[4];
+       u8  pwm_auto_pwm[2][4];
+       u8  vid;                /* Read once at init time */
+       u8  vrm;
+       u8  uch_config;         /* Read once at init time */
+       u16 alarms;
+};
+
+/* ix = [0-5] */
+#define ISVOLT(ix, uch_config) ((ix) > 4 ? 1 : \
+                                !(((uch_config) >> ((ix) + 2)) & 1))
+
+/* ix = [0-6] */
+#define ISTEMP(ix, uch_config) ((ix) < 2 ? 1 : \
+                                ((uch_config) >> (ix)) & 1)
+
+/* in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the
+   driver according to the VT1211 BIOS porting guide */
+#define IN_FROM_REG(ix, reg)   ((reg) < 3 ? 0 : (ix) == 5 ? \
+                                (((reg) - 3) * 15882 + 479) / 958 : \
+                                (((reg) - 3) * 10000 + 479) / 958)
+#define IN_TO_REG(ix, val)     (SENSORS_LIMIT((ix) == 5 ? \
+                                ((val) * 958 + 7941) / 15882 + 3 : \
+                                ((val) * 958 + 5000) / 10000 + 3, 0, 255))
+
+/* temp1 (ix = 0) is an intel thermal diode which is scaled in user space.
+   temp2 (ix = 1) is the internal temp diode so it's scaled in the driver
+   according to some measurements that I took on an EPIA M10000.
+   temp3-7 are thermistor based so the driver returns the voltage measured at
+   the pin (range 0V - 2.2V). */
+#define TEMP_FROM_REG(ix, reg) ((ix) == 0 ? (reg) * 1000 : \
+                                (ix) == 1 ? (reg) < 51 ? 0 : \
+                                ((reg) - 51) * 1000 : \
+                                ((253 - (reg)) * 2200 + 105) / 210)
+#define TEMP_TO_REG(ix, val)   SENSORS_LIMIT( \
+                                ((ix) == 0 ? ((val) + 500) / 1000 : \
+                                 (ix) == 1 ? ((val) + 500) / 1000 + 51 : \
+                                 253 - ((val) * 210 + 1100) / 2200), 0, 255)
+
+#define DIV_FROM_REG(reg)      (1 << (reg))
+
+#define RPM_FROM_REG(reg, div) (((reg) == 0) || ((reg) == 255) ? 0 : \
+                                1310720 / (reg) / DIV_FROM_REG(div))
+#define RPM_TO_REG(val, div)   ((val) == 0 ? 255 : \
+                                SENSORS_LIMIT((1310720 / (val) / \
+                                DIV_FROM_REG(div)), 1, 254))
+
+/* ---------------------------------------------------------------------
+ * Super-I/O constants and functions
+ * --------------------------------------------------------------------- */
+
+/* Configuration & data index port registers */
+#define SIO_REG_CIP            0x2e
+#define SIO_REG_DIP            0x2f
+
+/* Configuration registers */
+#define SIO_VT1211_LDN         0x07    /* logical device number */
+#define SIO_VT1211_DEVID       0x20    /* device ID */
+#define SIO_VT1211_DEVREV      0x21    /* device revision */
+#define SIO_VT1211_ACTIVE      0x30    /* HW monitor active */
+#define SIO_VT1211_BADDR       0x60    /* base I/O address */
+#define SIO_VT1211_ID          0x3c    /* VT1211 device ID */
+
+/* VT1211 logical device numbers */
+#define SIO_VT1211_LDN_HWMON   0x0b    /* HW monitor */
+
+static inline void superio_outb(int reg, int val)
+{
+       outb(reg, SIO_REG_CIP);
+       outb(val, SIO_REG_DIP);
+}
+
+static inline int superio_inb(int reg)
+{
+       outb(reg, SIO_REG_CIP);
+       return inb(SIO_REG_DIP);
+}
+
+static inline void superio_select(int ldn)
+{
+       outb(SIO_VT1211_LDN, SIO_REG_CIP);
+       outb(ldn, SIO_REG_DIP);
+}
+
+static inline void superio_enter(void)
+{
+       outb(0x87, SIO_REG_CIP);
+       outb(0x87, SIO_REG_CIP);
+}
+
+static inline void superio_exit(void)
+{
+       outb(0xaa, SIO_REG_CIP);
+}
+
+/* ---------------------------------------------------------------------
+ * Device I/O access
+ * --------------------------------------------------------------------- */
+
+static inline u8 vt1211_read8(struct vt1211_data *data, u8 reg)
+{
+       return inb(data->addr + reg);
+}
+
+static inline void vt1211_write8(struct vt1211_data *data, u8 reg, u8 val)
+{
+       outb(val, data->addr + reg);
+}
+
+static struct vt1211_data *vt1211_update_device(struct device *dev)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       int ix, val;
+
+       mutex_lock(&data->update_lock);
+
+       /* registers cache is refreshed after 1 second */
+       if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+               /* read VID */
+               data->vid = vt1211_read8(data, VT1211_REG_VID) & 0x1f;
+
+               /* voltage (in) registers */
+               for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
+                       if (ISVOLT(ix, data->uch_config)) {
+                               data->in[ix] = vt1211_read8(data,
+                                               VT1211_REG_IN(ix));
+                               data->in_min[ix] = vt1211_read8(data,
+                                               VT1211_REG_IN_MIN(ix));
+                               data->in_max[ix] = vt1211_read8(data,
+                                               VT1211_REG_IN_MAX(ix));
+                       }
+               }
+
+               /* temp registers */
+               for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
+                       if (ISTEMP(ix, data->uch_config)) {
+                               data->temp[ix] = vt1211_read8(data,
+                                               regtemp[ix]);
+                               data->temp_max[ix] = vt1211_read8(data,
+                                               regtempmax[ix]);
+                               data->temp_hyst[ix] = vt1211_read8(data,
+                                               regtemphyst[ix]);
+                       }
+               }
+
+               /* fan & pwm registers */
+               for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) {
+                       data->fan[ix] = vt1211_read8(data,
+                                               VT1211_REG_FAN(ix));
+                       data->fan_min[ix] = vt1211_read8(data,
+                                               VT1211_REG_FAN_MIN(ix));
+                       data->pwm[ix] = vt1211_read8(data,
+                                               VT1211_REG_PWM(ix));
+               }
+               val = vt1211_read8(data, VT1211_REG_FAN_DIV);
+               data->fan_div[0] = (val >> 4) & 3;
+               data->fan_div[1] = (val >> 6) & 3;
+               data->fan_ctl = val & 0xf;
+
+               val = vt1211_read8(data, VT1211_REG_PWM_CTL);
+               data->pwm_ctl[0] = val & 0xf;
+               data->pwm_ctl[1] = (val >> 4) & 0xf;
+
+               data->pwm_clk = vt1211_read8(data, VT1211_REG_PWM_CLK);
+
+               /* pwm & temp auto point registers */
+               data->pwm_auto_pwm[0][1] = vt1211_read8(data,
+                                               VT1211_REG_PWM_AUTO_PWM(0, 1));
+               data->pwm_auto_pwm[0][2] = vt1211_read8(data,
+                                               VT1211_REG_PWM_AUTO_PWM(0, 2));
+               data->pwm_auto_pwm[1][1] = vt1211_read8(data,
+                                               VT1211_REG_PWM_AUTO_PWM(1, 1));
+               data->pwm_auto_pwm[1][2] = vt1211_read8(data,
+                                               VT1211_REG_PWM_AUTO_PWM(1, 2));
+               for (ix = 0; ix < ARRAY_SIZE(data->pwm_auto_temp); ix++) {
+                       data->pwm_auto_temp[ix] = vt1211_read8(data,
+                                               VT1211_REG_PWM_AUTO_TEMP(ix));
+               }
+
+               /* alarm registers */
+               data->alarms = (vt1211_read8(data, VT1211_REG_ALARM2) << 8) |
+                               vt1211_read8(data, VT1211_REG_ALARM1);
+
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       mutex_unlock(&data->update_lock);
+
+       return data;
+}
+
+/* ---------------------------------------------------------------------
+ * Voltage sysfs interfaces
+ * ix = [0-5]
+ * --------------------------------------------------------------------- */
+
+#define SHOW_IN_INPUT  0
+#define SHOW_SET_IN_MIN        1
+#define SHOW_SET_IN_MAX        2
+#define SHOW_IN_ALARM  3
+
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+                      char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       int res;
+
+       switch (fn) {
+       case SHOW_IN_INPUT:
+               res = IN_FROM_REG(ix, data->in[ix]);
+               break;
+       case SHOW_SET_IN_MIN:
+               res = IN_FROM_REG(ix, data->in_min[ix]);
+               break;
+       case SHOW_SET_IN_MAX:
+               res = IN_FROM_REG(ix, data->in_max[ix]);
+               break;
+       case SHOW_IN_ALARM:
+               res = (data->alarms >> bitalarmin[ix]) & 1;
+               break;
+       default:
+               res = 0;
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+       return sprintf(buf, "%d\n", res);
+}
+
+static ssize_t set_in(struct device *dev, struct device_attribute *attr,
+                     const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       switch (fn) {
+       case SHOW_SET_IN_MIN:
+               data->in_min[ix] = IN_TO_REG(ix, val);
+               vt1211_write8(data, VT1211_REG_IN_MIN(ix), data->in_min[ix]);
+               break;
+       case SHOW_SET_IN_MAX:
+               data->in_max[ix] = IN_TO_REG(ix, val);
+               vt1211_write8(data, VT1211_REG_IN_MAX(ix), data->in_max[ix]);
+               break;
+       default:
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+/* ---------------------------------------------------------------------
+ * Temperature sysfs interfaces
+ * ix = [0-6]
+ * --------------------------------------------------------------------- */
+
+#define SHOW_TEMP_INPUT                0
+#define SHOW_SET_TEMP_MAX      1
+#define SHOW_SET_TEMP_MAX_HYST 2
+#define SHOW_TEMP_ALARM                3
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       int res;
+
+       switch (fn) {
+       case SHOW_TEMP_INPUT:
+               res = TEMP_FROM_REG(ix, data->temp[ix]);
+               break;
+       case SHOW_SET_TEMP_MAX:
+               res = TEMP_FROM_REG(ix, data->temp_max[ix]);
+               break;
+       case SHOW_SET_TEMP_MAX_HYST:
+               res = TEMP_FROM_REG(ix, data->temp_hyst[ix]);
+               break;
+       case SHOW_TEMP_ALARM:
+               res = (data->alarms >> bitalarmtemp[ix]) & 1;
+               break;
+       default:
+               res = 0;
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+       return sprintf(buf, "%d\n", res);
+}
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       switch (fn) {
+       case SHOW_SET_TEMP_MAX:
+               data->temp_max[ix] = TEMP_TO_REG(ix, val);
+               vt1211_write8(data, regtempmax[ix],
+                             data->temp_max[ix]);
+               break;
+       case SHOW_SET_TEMP_MAX_HYST:
+               data->temp_hyst[ix] = TEMP_TO_REG(ix, val);
+               vt1211_write8(data, regtemphyst[ix],
+                             data->temp_hyst[ix]);
+               break;
+       default:
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+/* ---------------------------------------------------------------------
+ * Fan sysfs interfaces
+ * ix = [0-1]
+ * --------------------------------------------------------------------- */
+
+#define SHOW_FAN_INPUT         0
+#define SHOW_SET_FAN_MIN       1
+#define SHOW_SET_FAN_DIV       2
+#define SHOW_FAN_ALARM         3
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       int res;
+
+       switch (fn) {
+       case SHOW_FAN_INPUT:
+               res = RPM_FROM_REG(data->fan[ix], data->fan_div[ix]);
+               break;
+       case SHOW_SET_FAN_MIN:
+               res = RPM_FROM_REG(data->fan_min[ix], data->fan_div[ix]);
+               break;
+       case SHOW_SET_FAN_DIV:
+               res = DIV_FROM_REG(data->fan_div[ix]);
+               break;
+       case SHOW_FAN_ALARM:
+               res = (data->alarms >> bitalarmfan[ix]) & 1;
+               break;
+       default:
+               res = 0;
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+       return sprintf(buf, "%d\n", res);
+}
+
+static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+       int reg;
+
+       mutex_lock(&data->update_lock);
+
+       /* sync the data cache */
+       reg = vt1211_read8(data, VT1211_REG_FAN_DIV);
+       data->fan_div[0] = (reg >> 4) & 3;
+       data->fan_div[1] = (reg >> 6) & 3;
+       data->fan_ctl = reg & 0xf;
+
+       switch (fn) {
+       case SHOW_SET_FAN_MIN:
+               data->fan_min[ix] = RPM_TO_REG(val, data->fan_div[ix]);
+               vt1211_write8(data, VT1211_REG_FAN_MIN(ix),
+                             data->fan_min[ix]);
+               break;
+       case SHOW_SET_FAN_DIV:
+               switch (val) {
+                       case 1: data->fan_div[ix] = 0; break;
+                       case 2: data->fan_div[ix] = 1; break;
+                       case 4: data->fan_div[ix] = 2; break;
+                       case 8: data->fan_div[ix] = 3; break;
+                       default:
+                               count = -EINVAL;
+                               dev_warn(dev, "fan div value %ld not "
+                                        "supported. Choose one of 1, 2, "
+                                        "4, or 8.\n", val);
+                               goto EXIT;
+               }
+               vt1211_write8(data, VT1211_REG_FAN_DIV,
+                             ((data->fan_div[1] << 6) |
+                              (data->fan_div[0] << 4) |
+                               data->fan_ctl));
+               break;
+       default:
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+EXIT:
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/* ---------------------------------------------------------------------
+ * PWM sysfs interfaces
+ * ix = [0-1]
+ * --------------------------------------------------------------------- */
+
+#define SHOW_PWM                       0
+#define SHOW_SET_PWM_ENABLE            1
+#define SHOW_SET_PWM_FREQ              2
+#define SHOW_SET_PWM_AUTO_CHANNELS_TEMP        3
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       int res;
+
+       switch (fn) {
+       case SHOW_PWM:
+               res = data->pwm[ix];
+               break;
+       case SHOW_SET_PWM_ENABLE:
+               res = ((data->pwm_ctl[ix] >> 3) & 1) ? 2 : 0;
+               break;
+       case SHOW_SET_PWM_FREQ:
+               res = 90000 >> (data->pwm_clk & 7);
+               break;
+       case SHOW_SET_PWM_AUTO_CHANNELS_TEMP:
+               res = (data->pwm_ctl[ix] & 7) + 1;
+               break;
+       default:
+               res = 0;
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+       return sprintf(buf, "%d\n", res);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int fn = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+       int tmp, reg;
+
+       mutex_lock(&data->update_lock);
+
+       switch (fn) {
+       case SHOW_SET_PWM_ENABLE:
+               /* sync the data cache */
+               reg = vt1211_read8(data, VT1211_REG_FAN_DIV);
+               data->fan_div[0] = (reg >> 4) & 3;
+               data->fan_div[1] = (reg >> 6) & 3;
+               data->fan_ctl = reg & 0xf;
+               reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
+               data->pwm_ctl[0] = reg & 0xf;
+               data->pwm_ctl[1] = (reg >> 4) & 0xf;
+               switch (val) {
+               case 0:
+                       data->pwm_ctl[ix] &= 7;
+                       /* disable SmartGuardian if both PWM outputs are
+                        * disabled */
+                       if ((data->pwm_ctl[ix ^ 1] & 1) == 0) {
+                               data->fan_ctl &= 0xe;
+                       }
+                       break;
+               case 2:
+                       data->pwm_ctl[ix] |= 8;
+                       data->fan_ctl |= 1;
+                       break;
+               default:
+                       count = -EINVAL;
+                       dev_warn(dev, "pwm mode %ld not supported. "
+                                "Choose one of 0 or 2.\n", val);
+                       goto EXIT;
+               }
+               vt1211_write8(data, VT1211_REG_PWM_CTL,
+                             ((data->pwm_ctl[1] << 4) |
+                               data->pwm_ctl[0]));
+               vt1211_write8(data, VT1211_REG_FAN_DIV,
+                             ((data->fan_div[1] << 6) |
+                              (data->fan_div[0] << 4) |
+                               data->fan_ctl));
+               break;
+       case SHOW_SET_PWM_FREQ:
+               val = 135000 / SENSORS_LIMIT(val, 135000 >> 7, 135000);
+               /* calculate tmp = log2(val) */
+               tmp = 0;
+               for (val >>= 1; val > 0; val >>= 1) {
+                       tmp++;
+               }
+               /* sync the data cache */
+               reg = vt1211_read8(data, VT1211_REG_PWM_CLK);
+               data->pwm_clk = (reg & 0xf8) | tmp;
+               vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk);
+               break;
+       case SHOW_SET_PWM_AUTO_CHANNELS_TEMP:
+               if ((val < 1) || (val > 7)) {
+                       count = -EINVAL;
+                       dev_warn(dev, "temp channel %ld not supported. "
+                                "Choose a value between 1 and 7.\n", val);
+                       goto EXIT;
+               }
+               if (!ISTEMP(val - 1, data->uch_config)) {
+                       count = -EINVAL;
+                       dev_warn(dev, "temp channel %ld is not available.\n",
+                                val);
+                       goto EXIT;
+               }
+               /* sync the data cache */
+               reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
+               data->pwm_ctl[0] = reg & 0xf;
+               data->pwm_ctl[1] = (reg >> 4) & 0xf;
+               data->pwm_ctl[ix] = (data->pwm_ctl[ix] & 8) | (val - 1);
+               vt1211_write8(data, VT1211_REG_PWM_CTL,
+                             ((data->pwm_ctl[1] << 4) | data->pwm_ctl[0]));
+               break;
+       default:
+               dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
+       }
+
+EXIT:
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/* ---------------------------------------------------------------------
+ * PWM auto point definitions
+ * ix = [0-1]
+ * ap = [0-3]
+ * --------------------------------------------------------------------- */
+
+/*
+ * pwm[ix+1]_auto_point[ap+1]_temp mapping table:
+ * Note that there is only a single set of temp auto points that controls both
+ * PWM controllers. We still create 2 sets of sysfs files to make it look
+ * more consistent even though they map to the same registers.
+ *
+ * ix ap : description
+ * -------------------
+ * 0  0  : pwm1/2 off temperature        (pwm_auto_temp[0])
+ * 0  1  : pwm1/2 low speed temperature  (pwm_auto_temp[1])
+ * 0  2  : pwm1/2 high speed temperature (pwm_auto_temp[2])
+ * 0  3  : pwm1/2 full speed temperature (pwm_auto_temp[3])
+ * 1  0  : pwm1/2 off temperature        (pwm_auto_temp[0])
+ * 1  1  : pwm1/2 low speed temperature  (pwm_auto_temp[1])
+ * 1  2  : pwm1/2 high speed temperature (pwm_auto_temp[2])
+ * 1  3  : pwm1/2 full speed temperature (pwm_auto_temp[3])
+ */
+
+static ssize_t show_pwm_auto_point_temp(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int ap = sensor_attr_2->nr;
+
+       return sprintf(buf, "%d\n", TEMP_FROM_REG(data->pwm_ctl[ix] & 7,
+                      data->pwm_auto_temp[ap]));
+}
+
+static ssize_t set_pwm_auto_point_temp(struct device *dev,
+                                      struct device_attribute *attr,
+                                      const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int ap = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+       int reg;
+
+       mutex_lock(&data->update_lock);
+
+       /* sync the data cache */
+       reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
+       data->pwm_ctl[0] = reg & 0xf;
+       data->pwm_ctl[1] = (reg >> 4) & 0xf;
+
+       data->pwm_auto_temp[ap] = TEMP_TO_REG(data->pwm_ctl[ix] & 7, val);
+       vt1211_write8(data, VT1211_REG_PWM_AUTO_TEMP(ap),
+                     data->pwm_auto_temp[ap]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+/*
+ * pwm[ix+1]_auto_point[ap+1]_pwm mapping table:
+ * Note that the PWM auto points 0 & 3 are hard-wired in the VT1211 and can't
+ * be changed.
+ *
+ * ix ap : description
+ * -------------------
+ * 0  0  : pwm1 off                   (pwm_auto_pwm[0][0], hard-wired to 0)
+ * 0  1  : pwm1 low speed duty cycle  (pwm_auto_pwm[0][1])
+ * 0  2  : pwm1 high speed duty cycle (pwm_auto_pwm[0][2])
+ * 0  3  : pwm1 full speed            (pwm_auto_pwm[0][3], hard-wired to 255)
+ * 1  0  : pwm2 off                   (pwm_auto_pwm[1][0], hard-wired to 0)
+ * 1  1  : pwm2 low speed duty cycle  (pwm_auto_pwm[1][1])
+ * 1  2  : pwm2 high speed duty cycle (pwm_auto_pwm[1][2])
+ * 1  3  : pwm2 full speed            (pwm_auto_pwm[1][3], hard-wired to 255)
+*/
+
+static ssize_t show_pwm_auto_point_pwm(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int ap = sensor_attr_2->nr;
+
+       return sprintf(buf, "%d\n", data->pwm_auto_pwm[ix][ap]);
+}
+
+static ssize_t set_pwm_auto_point_pwm(struct device *dev,
+                                     struct device_attribute *attr,
+                                     const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *sensor_attr_2 =
+                                               to_sensor_dev_attr_2(attr);
+       int ix = sensor_attr_2->index;
+       int ap = sensor_attr_2->nr;
+       long val = simple_strtol(buf, NULL, 10);
+
+       if ((val < 0) || (val > 255)) {
+               dev_err(dev, "pwm value %ld is out of range. "
+                       "Choose a value between 0 and 255." , val);
+               return -EINVAL;
+       }
+
+       mutex_lock(&data->update_lock);
+       data->pwm_auto_pwm[ix][ap] = val;
+       vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap),
+                     data->pwm_auto_pwm[ix][ap]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+/* ---------------------------------------------------------------------
+ * Miscellaneous sysfs interfaces (VRM, VID, name, and (legacy) alarms)
+ * --------------------------------------------------------------------- */
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t count)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+       long val = simple_strtol(buf, NULL, 10);
+
+       data->vrm = val;
+
+       return count;
+}
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+
+static ssize_t show_name(struct device *dev,
+                        struct device_attribute *attr, char *buf)
+{
+       struct vt1211_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+static ssize_t show_alarms(struct device *dev,
+                          struct device_attribute *attr, char *buf)
+{
+       struct vt1211_data *data = vt1211_update_device(dev);
+
+       return sprintf(buf, "%d\n", data->alarms);
+}
+
+/* ---------------------------------------------------------------------
+ * Device attribute structs
+ * --------------------------------------------------------------------- */
+
+#define SENSOR_ATTR_IN_INPUT(ix) \
+       SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \
+               show_in, NULL, SHOW_IN_INPUT, ix)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_in_input[] = {
+       SENSOR_ATTR_IN_INPUT(0),
+       SENSOR_ATTR_IN_INPUT(1),
+       SENSOR_ATTR_IN_INPUT(2),
+       SENSOR_ATTR_IN_INPUT(3),
+       SENSOR_ATTR_IN_INPUT(4),
+       SENSOR_ATTR_IN_INPUT(5),
+};
+
+#define SENSOR_ATTR_IN_MIN(ix) \
+       SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \
+               show_in, set_in, SHOW_SET_IN_MIN, ix)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_in_min[] = {
+       SENSOR_ATTR_IN_MIN(0),
+       SENSOR_ATTR_IN_MIN(1),
+       SENSOR_ATTR_IN_MIN(2),
+       SENSOR_ATTR_IN_MIN(3),
+       SENSOR_ATTR_IN_MIN(4),
+       SENSOR_ATTR_IN_MIN(5),
+};
+
+#define SENSOR_ATTR_IN_MAX(ix) \
+       SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \
+               show_in, set_in, SHOW_SET_IN_MAX, ix)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_in_max[] = {
+       SENSOR_ATTR_IN_MAX(0),
+       SENSOR_ATTR_IN_MAX(1),
+       SENSOR_ATTR_IN_MAX(2),
+       SENSOR_ATTR_IN_MAX(3),
+       SENSOR_ATTR_IN_MAX(4),
+       SENSOR_ATTR_IN_MAX(5),
+};
+
+#define SENSOR_ATTR_IN_ALARM(ix) \
+       SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \
+               show_in, NULL, SHOW_IN_ALARM, ix)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_in_alarm[] = {
+       SENSOR_ATTR_IN_ALARM(0),
+       SENSOR_ATTR_IN_ALARM(1),
+       SENSOR_ATTR_IN_ALARM(2),
+       SENSOR_ATTR_IN_ALARM(3),
+       SENSOR_ATTR_IN_ALARM(4),
+       SENSOR_ATTR_IN_ALARM(5),
+};
+
+#define SENSOR_ATTR_TEMP_INPUT(ix) \
+       SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \
+               show_temp, NULL, SHOW_TEMP_INPUT, ix-1)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_temp_input[] = {
+       SENSOR_ATTR_TEMP_INPUT(1),
+       SENSOR_ATTR_TEMP_INPUT(2),
+       SENSOR_ATTR_TEMP_INPUT(3),
+       SENSOR_ATTR_TEMP_INPUT(4),
+       SENSOR_ATTR_TEMP_INPUT(5),
+       SENSOR_ATTR_TEMP_INPUT(6),
+       SENSOR_ATTR_TEMP_INPUT(7),
+};
+
+#define SENSOR_ATTR_TEMP_MAX(ix) \
+       SENSOR_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \
+               show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_temp_max[] = {
+       SENSOR_ATTR_TEMP_MAX(1),
+       SENSOR_ATTR_TEMP_MAX(2),
+       SENSOR_ATTR_TEMP_MAX(3),
+       SENSOR_ATTR_TEMP_MAX(4),
+       SENSOR_ATTR_TEMP_MAX(5),
+       SENSOR_ATTR_TEMP_MAX(6),
+       SENSOR_ATTR_TEMP_MAX(7),
+};
+
+#define SENSOR_ATTR_TEMP_MAX_HYST(ix) \
+       SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \
+               show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_temp_max_hyst[] = {
+       SENSOR_ATTR_TEMP_MAX_HYST(1),
+       SENSOR_ATTR_TEMP_MAX_HYST(2),
+       SENSOR_ATTR_TEMP_MAX_HYST(3),
+       SENSOR_ATTR_TEMP_MAX_HYST(4),
+       SENSOR_ATTR_TEMP_MAX_HYST(5),
+       SENSOR_ATTR_TEMP_MAX_HYST(6),
+       SENSOR_ATTR_TEMP_MAX_HYST(7),
+};
+
+#define SENSOR_ATTR_TEMP_ALARM(ix) \
+       SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \
+               show_temp, NULL, SHOW_TEMP_ALARM, ix-1)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_temp_alarm[] = {
+       SENSOR_ATTR_TEMP_ALARM(1),
+       SENSOR_ATTR_TEMP_ALARM(2),
+       SENSOR_ATTR_TEMP_ALARM(3),
+       SENSOR_ATTR_TEMP_ALARM(4),
+       SENSOR_ATTR_TEMP_ALARM(5),
+       SENSOR_ATTR_TEMP_ALARM(6),
+       SENSOR_ATTR_TEMP_ALARM(7),
+};
+
+#define SENSOR_ATTR_FAN(ix) \
+       SENSOR_ATTR_2(fan##ix##_input, S_IRUGO, \
+               show_fan, NULL, SHOW_FAN_INPUT, ix-1), \
+       SENSOR_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
+               show_fan, set_fan, SHOW_SET_FAN_MIN, ix-1), \
+       SENSOR_ATTR_2(fan##ix##_div, S_IRUGO | S_IWUSR, \
+               show_fan, set_fan, SHOW_SET_FAN_DIV, ix-1), \
+       SENSOR_ATTR_2(fan##ix##_alarm, S_IRUGO, \
+               show_fan, NULL, SHOW_FAN_ALARM, ix-1)
+
+#define SENSOR_ATTR_PWM(ix) \
+       SENSOR_ATTR_2(pwm##ix, S_IRUGO, \
+               show_pwm, NULL, SHOW_PWM, ix-1), \
+       SENSOR_ATTR_2(pwm##ix##_enable, S_IRUGO | S_IWUSR, \
+               show_pwm, set_pwm, SHOW_SET_PWM_ENABLE, ix-1), \
+       SENSOR_ATTR_2(pwm##ix##_auto_channels_temp, S_IRUGO | S_IWUSR, \
+               show_pwm, set_pwm, SHOW_SET_PWM_AUTO_CHANNELS_TEMP, ix-1)
+
+#define SENSOR_ATTR_PWM_FREQ(ix) \
+       SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \
+               show_pwm, set_pwm, SHOW_SET_PWM_FREQ, ix-1)
+
+#define SENSOR_ATTR_PWM_FREQ_RO(ix) \
+       SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO, \
+               show_pwm, NULL, SHOW_SET_PWM_FREQ, ix-1)
+
+#define SENSOR_ATTR_PWM_AUTO_POINT_TEMP(ix, ap) \
+       SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO | S_IWUSR, \
+               show_pwm_auto_point_temp, set_pwm_auto_point_temp, \
+               ap-1, ix-1)
+
+#define SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(ix, ap) \
+       SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO, \
+               show_pwm_auto_point_temp, NULL, \
+               ap-1, ix-1)
+
+#define SENSOR_ATTR_PWM_AUTO_POINT_PWM(ix, ap) \
+       SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO | S_IWUSR, \
+               show_pwm_auto_point_pwm, set_pwm_auto_point_pwm, \
+               ap-1, ix-1)
+
+#define SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(ix, ap) \
+       SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO, \
+               show_pwm_auto_point_pwm, NULL, \
+               ap-1, ix-1)
+
+static struct sensor_device_attribute_2 vt1211_sysfs_fan_pwm[] = {
+       SENSOR_ATTR_FAN(1),
+       SENSOR_ATTR_FAN(2),
+       SENSOR_ATTR_PWM(1),
+       SENSOR_ATTR_PWM(2),
+       SENSOR_ATTR_PWM_FREQ(1),
+       SENSOR_ATTR_PWM_FREQ_RO(2),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 1),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 2),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 3),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 4),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 1),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 2),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 3),
+       SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 4),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 1),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 2),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 3),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 4),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 1),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 2),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 3),
+       SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 4),
+};
+
+static struct device_attribute vt1211_sysfs_misc[] = {
+       __ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm),
+       __ATTR(cpu0_vid, S_IRUGO, show_vid, NULL),
+       __ATTR(name, S_IRUGO, show_name, NULL),
+       __ATTR(alarms, S_IRUGO, show_alarms, NULL),
+};
+
+/* ---------------------------------------------------------------------
+ * Device registration and initialization
+ * --------------------------------------------------------------------- */
+
+static void __devinit vt1211_init_device(struct vt1211_data *data)
+{
+       /* set VRM */
+       data->vrm = vid_which_vrm();
+
+       /* Read (and initialize) UCH config */
+       data->uch_config = vt1211_read8(data, VT1211_REG_UCH_CONFIG);
+       if (uch_config > -1) {
+               data->uch_config = (data->uch_config & 0x83) |
+                                  (uch_config << 2);
+               vt1211_write8(data, VT1211_REG_UCH_CONFIG, data->uch_config);
+       }
+
+       /* Initialize the interrupt mode (if request at module load time).
+        * The VT1211 implements 3 different modes for clearing interrupts:
+        * 0: Clear INT when status register is read. Regenerate INT as long
+        *    as temp stays above hysteresis limit.
+        * 1: Clear INT when status register is read. DON'T regenerate INT
+        *    until temp falls below hysteresis limit and exceeds hot limit
+        *    again.
+        * 2: Clear INT when temp falls below max limit.
+        *
+        * The driver only allows to force mode 0 since that's the only one
+        * that makes sense for 'sensors' */
+       if (int_mode == 0) {
+               vt1211_write8(data, VT1211_REG_TEMP1_CONFIG, 0);
+               vt1211_write8(data, VT1211_REG_TEMP2_CONFIG, 0);
+       }
+
+       /* Fill in some hard wired values into our data struct */
+       data->pwm_auto_pwm[0][3] = 255;
+       data->pwm_auto_pwm[1][3] = 255;
+}
+
+static void vt1211_remove_sysfs(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) {
+               device_remove_file(dev,
+                       &vt1211_sysfs_in_input[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_in_min[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_in_max[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_in_alarm[i].dev_attr);
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) {
+               device_remove_file(dev,
+                       &vt1211_sysfs_temp_input[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_temp_max[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_temp_max_hyst[i].dev_attr);
+               device_remove_file(dev,
+                       &vt1211_sysfs_temp_alarm[i].dev_attr);
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
+               device_remove_file(dev,
+                       &vt1211_sysfs_fan_pwm[i].dev_attr);
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) {
+               device_remove_file(dev, &vt1211_sysfs_misc[i]);
+       }
+}
+
+static int __devinit vt1211_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct vt1211_data *data;
+       struct resource *res;
+       int i, err;
+
+       if (!(data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               dev_err(dev, "Out of memory\n");
+               goto EXIT;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       data->addr = res->start;
+       data->name = DRVNAME;
+       mutex_init(&data->update_lock);
+
+       platform_set_drvdata(pdev, data);
+
+       /* Initialize the VT1211 chip */
+       vt1211_init_device(data);
+
+       /* Create sysfs interface files */
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) {
+               if (ISVOLT(i, data->uch_config)) {
+                       if ((err = device_create_file(dev,
+                               &vt1211_sysfs_in_input[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_in_min[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_in_max[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_in_alarm[i].dev_attr))) {
+                               goto EXIT_DEV_REMOVE;
+                       }
+               }
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) {
+               if (ISTEMP(i, data->uch_config)) {
+                       if ((err = device_create_file(dev,
+                               &vt1211_sysfs_temp_input[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_temp_max[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_temp_max_hyst[i].dev_attr)) ||
+                           (err = device_create_file(dev,
+                               &vt1211_sysfs_temp_alarm[i].dev_attr))) {
+                               goto EXIT_DEV_REMOVE;
+                       }
+               }
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
+               err = device_create_file(dev,
+                       &vt1211_sysfs_fan_pwm[i].dev_attr);
+               if (err) {
+                       goto EXIT_DEV_REMOVE;
+               }
+       }
+       for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) {
+               err = device_create_file(dev,
+                      &vt1211_sysfs_misc[i]);
+               if (err) {
+                       goto EXIT_DEV_REMOVE;
+               }
+       }
+
+       /* Register device */
+       data->class_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               dev_err(dev, "Class registration failed (%d)\n", err);
+               goto EXIT_DEV_REMOVE_SILENT;
+       }
+
+       return 0;
+
+EXIT_DEV_REMOVE:
+       dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
+EXIT_DEV_REMOVE_SILENT:
+       vt1211_remove_sysfs(pdev);
+       platform_set_drvdata(pdev, NULL);
+       kfree(data);
+EXIT:
+       return err;
+}
+
+static int __devexit vt1211_remove(struct platform_device *pdev)
+{
+       struct vt1211_data *data = platform_get_drvdata(pdev);
+
+       hwmon_device_unregister(data->class_dev);
+       vt1211_remove_sysfs(pdev);
+       platform_set_drvdata(pdev, NULL);
+       kfree(data);
+
+       return 0;
+}
+
+static struct platform_driver vt1211_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name  = DRVNAME,
+       },
+       .probe  = vt1211_probe,
+       .remove = __devexit_p(vt1211_remove),
+};
+
+static int __init vt1211_device_add(unsigned short address)
+{
+       struct resource res = {
+               .start  = address,
+               .end    = address + 0x7f,
+               .flags  = IORESOURCE_IO,
+       };
+       int err;
+
+       pdev = platform_device_alloc(DRVNAME, address);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed (%d)\n",
+                      err);
+               goto EXIT;
+       }
+
+       res.name = pdev->name;
+       err = platform_device_add_resources(pdev, &res, 1);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device resource addition failed "
+                      "(%d)\n", err);
+               goto EXIT_DEV_PUT;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto EXIT_DEV_PUT;
+       }
+
+       return 0;
+
+EXIT_DEV_PUT:
+       platform_device_put(pdev);
+EXIT:
+       return err;
+}
+
+static int __init vt1211_find(unsigned short *address)
+{
+       int err = -ENODEV;
+
+       superio_enter();
+
+       if (superio_inb(SIO_VT1211_DEVID) != SIO_VT1211_ID) {
+               goto EXIT;
+       }
+
+       superio_select(SIO_VT1211_LDN_HWMON);
+
+       if ((superio_inb(SIO_VT1211_ACTIVE) & 1) == 0) {
+               printk(KERN_WARNING DRVNAME ": HW monitor is disabled, "
+                      "skipping\n");
+               goto EXIT;
+       }
+
+       *address = ((superio_inb(SIO_VT1211_BADDR) << 8) |
+                   (superio_inb(SIO_VT1211_BADDR + 1))) & 0xff00;
+       if (*address == 0) {
+               printk(KERN_WARNING DRVNAME ": Base address is not set, "
+                      "skipping\n");
+               goto EXIT;
+       }
+
+       err = 0;
+       printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, "
+              "revision %u\n", *address, superio_inb(SIO_VT1211_DEVREV));
+
+EXIT:
+       superio_exit();
+       return err;
+}
+
+static int __init vt1211_init(void)
+{
+       int err;
+       unsigned short address = 0;
+
+       err = vt1211_find(&address);
+       if (err) {
+               goto EXIT;
+       }
+
+       if ((uch_config < -1) || (uch_config > 31)) {
+               err = -EINVAL;
+               printk(KERN_WARNING DRVNAME ": Invalid UCH configuration %d. "
+                      "Choose a value between 0 and 31.\n", uch_config);
+         goto EXIT;
+       }
+
+       if ((int_mode < -1) || (int_mode > 0)) {
+               err = -EINVAL;
+               printk(KERN_WARNING DRVNAME ": Invalid interrupt mode %d. "
+                      "Only mode 0 is supported.\n", int_mode);
+         goto EXIT;
+       }
+
+       err = platform_driver_register(&vt1211_driver);
+       if (err) {
+               goto EXIT;
+       }
+
+       /* Sets global pdev as a side effect */
+       err = vt1211_device_add(address);
+       if (err) {
+               goto EXIT_DRV_UNREGISTER;
+       }
+
+       return 0;
+
+EXIT_DRV_UNREGISTER:
+       platform_driver_unregister(&vt1211_driver);
+EXIT:
+       return err;
+}
+
+static void __exit vt1211_exit(void)
+{
+       platform_device_unregister(pdev);
+       platform_driver_unregister(&vt1211_driver);
+}
+
+MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>");
+MODULE_DESCRIPTION("VT1211 sensors");
+MODULE_LICENSE("GPL");
+
+module_init(vt1211_init);
+module_exit(vt1211_exit);
index 236ccf0e915d70917b248a9f67f23e227fe44e1a..93f93d4fb8aec2126e86131e9077703c4e1e171d 100644 (file)
@@ -451,37 +451,6 @@ define_temperature_sysfs(4);
 define_temperature_sysfs(5);
 define_temperature_sysfs(6);
 
-#define CFG_INFO_TEMP(id)      { &sensor_dev_attr_temp##id##_input.dev_attr, \
-                               &sensor_dev_attr_temp##id##_max_hyst.dev_attr, \
-                               &sensor_dev_attr_temp##id##_max.dev_attr }
-#define CFG_INFO_VOLT(id)      { &sensor_dev_attr_in##id##_input.dev_attr, \
-                               &sensor_dev_attr_in##id##_min.dev_attr, \
-                               &sensor_dev_attr_in##id##_max.dev_attr }
-
-struct str_device_attr_table {
-       struct device_attribute *input;
-       struct device_attribute *min;
-       struct device_attribute *max;
-};
-
-static struct str_device_attr_table cfg_info_temp[] = {
-       { &dev_attr_temp1_input, &dev_attr_temp1_max_hyst, &dev_attr_temp1_max },
-       CFG_INFO_TEMP(2),
-       CFG_INFO_TEMP(3),
-       CFG_INFO_TEMP(4),
-       CFG_INFO_TEMP(5),
-       CFG_INFO_TEMP(6)
-};
-
-static struct str_device_attr_table cfg_info_volt[] = {
-       CFG_INFO_VOLT(0),
-       CFG_INFO_VOLT(1),
-       CFG_INFO_VOLT(2),
-       CFG_INFO_VOLT(3),
-       CFG_INFO_VOLT(4),
-       { &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max }
-};
-
 /* Fans */
 static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
                char *buf)
@@ -585,6 +554,107 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static struct attribute *vt8231_attributes_temps[6][4] = {
+       {
+               &dev_attr_temp1_input.attr,
+               &dev_attr_temp1_max_hyst.attr,
+               &dev_attr_temp1_max.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_temp2_input.dev_attr.attr,
+               &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
+               &sensor_dev_attr_temp2_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_temp3_input.dev_attr.attr,
+               &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
+               &sensor_dev_attr_temp3_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_temp4_input.dev_attr.attr,
+               &sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
+               &sensor_dev_attr_temp4_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_temp5_input.dev_attr.attr,
+               &sensor_dev_attr_temp5_max_hyst.dev_attr.attr,
+               &sensor_dev_attr_temp5_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_temp6_input.dev_attr.attr,
+               &sensor_dev_attr_temp6_max_hyst.dev_attr.attr,
+               &sensor_dev_attr_temp6_max.dev_attr.attr,
+               NULL
+       }
+};
+
+static const struct attribute_group vt8231_group_temps[6] = {
+       { .attrs = vt8231_attributes_temps[0] },
+       { .attrs = vt8231_attributes_temps[1] },
+       { .attrs = vt8231_attributes_temps[2] },
+       { .attrs = vt8231_attributes_temps[3] },
+       { .attrs = vt8231_attributes_temps[4] },
+       { .attrs = vt8231_attributes_temps[5] },
+};
+
+static struct attribute *vt8231_attributes_volts[6][4] = {
+       {
+               &sensor_dev_attr_in0_input.dev_attr.attr,
+               &sensor_dev_attr_in0_min.dev_attr.attr,
+               &sensor_dev_attr_in0_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_in1_input.dev_attr.attr,
+               &sensor_dev_attr_in1_min.dev_attr.attr,
+               &sensor_dev_attr_in1_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_in2_input.dev_attr.attr,
+               &sensor_dev_attr_in2_min.dev_attr.attr,
+               &sensor_dev_attr_in2_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_in3_input.dev_attr.attr,
+               &sensor_dev_attr_in3_min.dev_attr.attr,
+               &sensor_dev_attr_in3_max.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_in4_input.dev_attr.attr,
+               &sensor_dev_attr_in4_min.dev_attr.attr,
+               &sensor_dev_attr_in4_max.dev_attr.attr,
+               NULL
+       }, {
+               &dev_attr_in5_input.attr,
+               &dev_attr_in5_min.attr,
+               &dev_attr_in5_max.attr,
+               NULL
+       }
+};
+
+static const struct attribute_group vt8231_group_volts[6] = {
+       { .attrs = vt8231_attributes_volts[0] },
+       { .attrs = vt8231_attributes_volts[1] },
+       { .attrs = vt8231_attributes_volts[2] },
+       { .attrs = vt8231_attributes_volts[3] },
+       { .attrs = vt8231_attributes_volts[4] },
+       { .attrs = vt8231_attributes_volts[5] },
+};
+
+static struct attribute *vt8231_attributes[] = {
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       NULL
+};
+
+static const struct attribute_group vt8231_group = {
+       .attrs = vt8231_attributes,
+};
+
 static struct i2c_driver vt8231_driver = {
        .driver = {
                .owner  = THIS_MODULE,
@@ -671,43 +741,43 @@ int vt8231_detect(struct i2c_adapter *adapter)
        vt8231_init_client(client);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&client->dev.kobj, &vt8231_group)))
                goto exit_detach;
-       }
 
        /* Must update device information to find out the config field */
        data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG);
 
-       for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) {
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) {
                if (ISTEMP(i, data->uch_config)) {
-                       device_create_file(&client->dev,
-                                          cfg_info_temp[i].input);
-                       device_create_file(&client->dev, cfg_info_temp[i].max);
-                       device_create_file(&client->dev, cfg_info_temp[i].min);
+                       if ((err = sysfs_create_group(&client->dev.kobj,
+                                       &vt8231_group_temps[i])))
+                               goto exit_remove_files;
                }
        }
 
-       for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) {
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) {
                if (ISVOLT(i, data->uch_config)) {
-                       device_create_file(&client->dev,
-                                          cfg_info_volt[i].input);
-                       device_create_file(&client->dev, cfg_info_volt[i].max);
-                       device_create_file(&client->dev, cfg_info_volt[i].min);
+                       if ((err = sysfs_create_group(&client->dev.kobj,
+                                       &vt8231_group_volts[i])))
+                               goto exit_remove_files;
                }
        }
 
-       device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr);
-       device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr);
-
-       device_create_file(&client->dev, &dev_attr_alarms);
+       data->class_dev = hwmon_device_register(&client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
+       }
        return 0;
 
+exit_remove_files:
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++)
+               sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]);
+
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++)
+               sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]);
+
+       sysfs_remove_group(&client->dev.kobj, &vt8231_group);
 exit_detach:
        i2c_detach_client(client);
 exit_free:
@@ -720,10 +790,18 @@ exit_release:
 static int vt8231_detach_client(struct i2c_client *client)
 {
        struct vt8231_data *data = i2c_get_clientdata(client);
-       int err;
+       int err, i;
 
        hwmon_device_unregister(data->class_dev);
 
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++)
+               sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]);
+
+       for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++)
+               sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]);
+
+       sysfs_remove_group(&client->dev.kobj, &vt8231_group);
+
        if ((err = i2c_detach_client(client))) {
                return err;
        }
index b21d6b9d7eac730ede45e89fbd67b871cddcb30d..833faa275ffaed22b8eb5caa57172a965595ca7a 100644 (file)
@@ -2,6 +2,9 @@
     w83627ehf - Driver for the hardware monitoring functionality of
                 the Winbond W83627EHF Super-I/O chip
     Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2006  Yuan Mu (Winbond),
+                        Rudolf Marek <r.marek@sh.cvut.cz>
+                        David Hubbard <david.c.hubbard@gmail.com>
 
     Shamelessly ripped from the w83627hf driver
     Copyright (C) 2003  Mark Studebaker
@@ -29,8 +32,8 @@
 
     Supports the following chips:
 
-    Chip        #vin    #fan    #pwm    #temp   chip_id man_id
-    w83627ehf   10      5       -       3       0x88    0x5ca3
+    Chip        #vin    #fan    #pwm    #temp   chip_id    man_id
+    w83627ehf   10      5       4       3       0x88,0xa1  0x5ca3
 */
 
 #include <linux/module.h>
@@ -145,10 +148,44 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 };
 #define W83627EHF_REG_ALARM2           0x45A
 #define W83627EHF_REG_ALARM3           0x45B
 
+/* SmartFan registers */
+/* DC or PWM output fan configuration */
+static const u8 W83627EHF_REG_PWM_ENABLE[] = {
+       0x04,                   /* SYS FAN0 output mode and PWM mode */
+       0x04,                   /* CPU FAN0 output mode and PWM mode */
+       0x12,                   /* AUX FAN mode */
+       0x62,                   /* CPU fan1 mode */
+};
+
+static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 };
+static const u8 W83627EHF_PWM_ENABLE_SHIFT[] = { 2, 4, 1, 4 };
+
+/* FAN Duty Cycle, be used to control */
+static const u8 W83627EHF_REG_PWM[] = { 0x01, 0x03, 0x11, 0x61 };
+static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 };
+static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 };
+
+
+/* Advanced Fan control, some values are common for all fans */
+static const u8 W83627EHF_REG_FAN_MIN_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 };
+static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0C, 0x0D, 0x17, 0x66 };
+
 /*
  * Conversions
  */
 
+/* 1 is PWM mode, output in ms */
+static inline unsigned int step_time_from_reg(u8 reg, u8 mode)
+{
+       return mode ? 100 * reg : 400 * reg;
+}
+
+static inline u8 step_time_to_reg(unsigned int msec, u8 mode)
+{
+       return SENSORS_LIMIT((mode ? (msec + 50) / 100 :
+                                               (msec + 200) / 400), 1, 255);
+}
+
 static inline unsigned int
 fan_from_reg(u8 reg, unsigned int div)
 {
@@ -170,12 +207,12 @@ temp1_from_reg(s8 reg)
 }
 
 static inline s8
-temp1_to_reg(int temp)
+temp1_to_reg(int temp, int min, int max)
 {
-       if (temp <= -128000)
-               return -128;
-       if (temp >= 127000)
-               return 127;
+       if (temp <= min)
+               return min / 1000;
+       if (temp >= max)
+               return max / 1000;
        if (temp < 0)
                return (temp - 500) / 1000;
        return (temp + 500) / 1000;
@@ -223,6 +260,16 @@ struct w83627ehf_data {
        s16 temp_max[2];
        s16 temp_max_hyst[2];
        u32 alarms;
+
+       u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
+       u8 pwm_enable[4]; /* 1->manual
+                            2->thermal cruise (also called SmartFan I) */
+       u8 pwm[4];
+       u8 target_temp[4];
+       u8 tolerance[4];
+
+       u8 fan_min_output[4]; /* minimum fan speed */
+       u8 fan_stop_time[4];
 };
 
 static inline int is_word_sized(u16 reg)
@@ -349,6 +396,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct w83627ehf_data *data = i2c_get_clientdata(client);
+       int pwmcfg = 0, tolerance = 0; /* shut up the compiler */
        int i;
 
        mutex_lock(&data->update_lock);
@@ -416,6 +464,34 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
                        }
                }
 
+               for (i = 0; i < 4; i++) {
+                       /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */
+                       if (i != 1) {
+                               pwmcfg = w83627ehf_read_value(client,
+                                               W83627EHF_REG_PWM_ENABLE[i]);
+                               tolerance = w83627ehf_read_value(client,
+                                               W83627EHF_REG_TOLERANCE[i]);
+                       }
+                       data->pwm_mode[i] =
+                               ((pwmcfg >> W83627EHF_PWM_MODE_SHIFT[i]) & 1)
+                               ? 0 : 1;
+                       data->pwm_enable[i] =
+                                       ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i])
+                                               & 3) + 1;
+                       data->pwm[i] = w83627ehf_read_value(client,
+                                               W83627EHF_REG_PWM[i]);
+                       data->fan_min_output[i] = w83627ehf_read_value(client,
+                                               W83627EHF_REG_FAN_MIN_OUTPUT[i]);
+                       data->fan_stop_time[i] = w83627ehf_read_value(client,
+                                               W83627EHF_REG_FAN_STOP_TIME[i]);
+                       data->target_temp[i] =
+                               w83627ehf_read_value(client,
+                                       W83627EHF_REG_TARGET[i]) &
+                                       (data->pwm_mode[i] == 1 ? 0x7f : 0xff);
+                       data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0))
+                                                                       & 0x0f;
+               }
+
                /* Measured temperatures and limits */
                data->temp1 = w83627ehf_read_value(client,
                              W83627EHF_REG_TEMP1);
@@ -546,14 +622,6 @@ static struct sensor_device_attribute sda_in_max[] = {
        SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
 };
 
-static void device_create_file_in(struct device *dev, int i)
-{
-       device_create_file(dev, &sda_in_input[i].dev_attr);
-       device_create_file(dev, &sda_in_alarm[i].dev_attr);
-       device_create_file(dev, &sda_in_min[i].dev_attr);
-       device_create_file(dev, &sda_in_max[i].dev_attr);
-}
-
 #define show_fan_reg(reg) \
 static ssize_t \
 show_##reg(struct device *dev, struct device_attribute *attr, \
@@ -681,14 +749,6 @@ static struct sensor_device_attribute sda_fan_div[] = {
        SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
 };
 
-static void device_create_file_fan(struct device *dev, int i)
-{
-       device_create_file(dev, &sda_fan_input[i].dev_attr);
-       device_create_file(dev, &sda_fan_alarm[i].dev_attr);
-       device_create_file(dev, &sda_fan_div[i].dev_attr);
-       device_create_file(dev, &sda_fan_min[i].dev_attr);
-}
-
 #define show_temp1_reg(reg) \
 static ssize_t \
 show_##reg(struct device *dev, struct device_attribute *attr, \
@@ -711,7 +771,7 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
        u32 val = simple_strtoul(buf, NULL, 10); \
  \
        mutex_lock(&data->update_lock); \
-       data->temp1_##reg = temp1_to_reg(val); \
+       data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \
        w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \
                              data->temp1_##reg); \
        mutex_unlock(&data->update_lock); \
@@ -777,10 +837,309 @@ static struct sensor_device_attribute sda_temp[] = {
        SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
 };
 
+#define show_pwm_reg(reg) \
+static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
+                               char *buf) \
+{ \
+       struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       return sprintf(buf, "%d\n", data->reg[nr]); \
+}
+
+show_pwm_reg(pwm_mode)
+show_pwm_reg(pwm_enable)
+show_pwm_reg(pwm)
+
+static ssize_t
+store_pwm_mode(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83627ehf_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       u32 val = simple_strtoul(buf, NULL, 10);
+       u16 reg;
+
+       if (val > 1)
+               return -EINVAL;
+       mutex_lock(&data->update_lock);
+       reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]);
+       data->pwm_mode[nr] = val;
+       reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]);
+       if (!val)
+               reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr];
+       w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+store_pwm(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83627ehf_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255);
+
+       mutex_lock(&data->update_lock);
+       data->pwm[nr] = val;
+       w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+store_pwm_enable(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83627ehf_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       u32 val = simple_strtoul(buf, NULL, 10);
+       u16 reg;
+
+       if (!val || (val > 2))  /* only modes 1 and 2 are supported */
+               return -EINVAL;
+       mutex_lock(&data->update_lock);
+       reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]);
+       data->pwm_enable[nr] = val;
+       reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]);
+       reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr];
+       w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+
+#define show_tol_temp(reg) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+                               char *buf) \
+{ \
+       struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       return sprintf(buf, "%d\n", temp1_from_reg(data->reg[nr])); \
+}
+
+show_tol_temp(tolerance)
+show_tol_temp(target_temp)
+
+static ssize_t
+store_target_temp(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83627ehf_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000);
+
+       mutex_lock(&data->update_lock);
+       data->target_temp[nr] = val;
+       w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+store_tolerance(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83627ehf_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       int nr = sensor_attr->index;
+       u16 reg;
+       /* Limit the temp to 0C - 15C */
+       u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000);
+
+       mutex_lock(&data->update_lock);
+       reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]);
+       data->tolerance[nr] = val;
+       if (nr == 1)
+               reg = (reg & 0x0f) | (val << 4);
+       else
+               reg = (reg & 0xf0) | val;
+       w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static struct sensor_device_attribute sda_pwm[] = {
+       SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
+       SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
+       SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
+       SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3),
+};
+
+static struct sensor_device_attribute sda_pwm_mode[] = {
+       SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+                   store_pwm_mode, 0),
+       SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+                   store_pwm_mode, 1),
+       SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+                   store_pwm_mode, 2),
+       SENSOR_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+                   store_pwm_mode, 3),
+};
+
+static struct sensor_device_attribute sda_pwm_enable[] = {
+       SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+                   store_pwm_enable, 0),
+       SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+                   store_pwm_enable, 1),
+       SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+                   store_pwm_enable, 2),
+       SENSOR_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+                   store_pwm_enable, 3),
+};
+
+static struct sensor_device_attribute sda_target_temp[] = {
+       SENSOR_ATTR(pwm1_target, S_IWUSR | S_IRUGO, show_target_temp,
+                   store_target_temp, 0),
+       SENSOR_ATTR(pwm2_target, S_IWUSR | S_IRUGO, show_target_temp,
+                   store_target_temp, 1),
+       SENSOR_ATTR(pwm3_target, S_IWUSR | S_IRUGO, show_target_temp,
+                   store_target_temp, 2),
+       SENSOR_ATTR(pwm4_target, S_IWUSR | S_IRUGO, show_target_temp,
+                   store_target_temp, 3),
+};
+
+static struct sensor_device_attribute sda_tolerance[] = {
+       SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+                   store_tolerance, 0),
+       SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+                   store_tolerance, 1),
+       SENSOR_ATTR(pwm3_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+                   store_tolerance, 2),
+       SENSOR_ATTR(pwm4_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+                   store_tolerance, 3),
+};
+
+/* Smart Fan registers */
+
+#define fan_functions(reg, REG) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+                      char *buf) \
+{ \
+       struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       return sprintf(buf, "%d\n", data->reg[nr]); \
+}\
+static ssize_t \
+store_##reg(struct device *dev, struct device_attribute *attr, \
+                           const char *buf, size_t count) \
+{\
+       struct i2c_client *client = to_i2c_client(dev); \
+       struct w83627ehf_data *data = i2c_get_clientdata(client); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \
+       mutex_lock(&data->update_lock); \
+       data->reg[nr] = val; \
+       w83627ehf_write_value(client, W83627EHF_REG_##REG[nr],  val); \
+       mutex_unlock(&data->update_lock); \
+       return count; \
+}
+
+fan_functions(fan_min_output, FAN_MIN_OUTPUT)
+
+#define fan_time_functions(reg, REG) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+                               char *buf) \
+{ \
+       struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       return sprintf(buf, "%d\n", \
+                       step_time_from_reg(data->reg[nr], data->pwm_mode[nr])); \
+} \
+\
+static ssize_t \
+store_##reg(struct device *dev, struct device_attribute *attr, \
+                       const char *buf, size_t count) \
+{ \
+       struct i2c_client *client = to_i2c_client(dev); \
+       struct w83627ehf_data *data = i2c_get_clientdata(client); \
+       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+       int nr = sensor_attr->index; \
+       u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \
+                                       data->pwm_mode[nr]); \
+       mutex_lock(&data->update_lock); \
+       data->reg[nr] = val; \
+       w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \
+       mutex_unlock(&data->update_lock); \
+       return count; \
+} \
+
+fan_time_functions(fan_stop_time, FAN_STOP_TIME)
+
+
+static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
+       SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+                   store_fan_stop_time, 3),
+       SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+                   store_fan_min_output, 3),
+};
+
+static struct sensor_device_attribute sda_sf3_arrays[] = {
+       SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+                   store_fan_stop_time, 0),
+       SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+                   store_fan_stop_time, 1),
+       SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+                   store_fan_stop_time, 2),
+       SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+                   store_fan_min_output, 0),
+       SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+                   store_fan_min_output, 1),
+       SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+                   store_fan_min_output, 2),
+};
+
 /*
  * Driver and client management
  */
 
+static void w83627ehf_device_remove_files(struct device *dev)
+{
+       /* some entries in the following arrays may not have been used in
+        * device_create_file(), but device_remove_file() will ignore them */
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
+               device_remove_file(dev, &sda_sf3_arrays[i].dev_attr);
+       for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
+               device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
+       for (i = 0; i < 10; i++) {
+               device_remove_file(dev, &sda_in_input[i].dev_attr);
+               device_remove_file(dev, &sda_in_alarm[i].dev_attr);
+               device_remove_file(dev, &sda_in_min[i].dev_attr);
+               device_remove_file(dev, &sda_in_max[i].dev_attr);
+       }
+       for (i = 0; i < 5; i++) {
+               device_remove_file(dev, &sda_fan_input[i].dev_attr);
+               device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
+               device_remove_file(dev, &sda_fan_div[i].dev_attr);
+               device_remove_file(dev, &sda_fan_min[i].dev_attr);
+       }
+       for (i = 0; i < 4; i++) {
+               device_remove_file(dev, &sda_pwm[i].dev_attr);
+               device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
+               device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
+               device_remove_file(dev, &sda_target_temp[i].dev_attr);
+               device_remove_file(dev, &sda_tolerance[i].dev_attr);
+       }
+       for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
+               device_remove_file(dev, &sda_temp[i].dev_attr);
+}
+
 static struct i2c_driver w83627ehf_driver;
 
 static void w83627ehf_init_client(struct i2c_client *client)
@@ -810,6 +1169,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
        struct i2c_client *client;
        struct w83627ehf_data *data;
        struct device *dev;
+       u8 fan4pin, fan5pin;
        int i, err = 0;
 
        if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
@@ -848,35 +1208,87 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
                data->fan_min[i] = w83627ehf_read_value(client,
                                   W83627EHF_REG_FAN_MIN[i]);
 
+       /* fan4 and fan5 share some pins with the GPIO and serial flash */
+
+       superio_enter();
+       fan5pin = superio_inb(0x24) & 0x2;
+       fan4pin = superio_inb(0x29) & 0x6;
+       superio_exit();
+
        /* It looks like fan4 and fan5 pins can be alternatively used
           as fan on/off switches */
+
        data->has_fan = 0x07; /* fan1, fan2 and fan3 */
        i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
-       if (i & (1 << 2))
+       if ((i & (1 << 2)) && (!fan4pin))
                data->has_fan |= (1 << 3);
-       if (i & (1 << 0))
+       if ((i & (1 << 0)) && (!fan5pin))
                data->has_fan |= (1 << 4);
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
-               goto exit_detach;
-       }
+       for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
+               if ((err = device_create_file(dev,
+                       &sda_sf3_arrays[i].dev_attr)))
+                       goto exit_remove;
+
+       /* if fan4 is enabled create the sf3 files for it */
+       if (data->has_fan & (1 << 3))
+               for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
+                       if ((err = device_create_file(dev,
+                               &sda_sf3_arrays_fan4[i].dev_attr)))
+                               goto exit_remove;
+               }
 
        for (i = 0; i < 10; i++)
-               device_create_file_in(dev, i);
+               if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
+                       || (err = device_create_file(dev,
+                               &sda_in_alarm[i].dev_attr))
+                       || (err = device_create_file(dev,
+                               &sda_in_min[i].dev_attr))
+                       || (err = device_create_file(dev,
+                               &sda_in_max[i].dev_attr)))
+                       goto exit_remove;
 
        for (i = 0; i < 5; i++) {
-               if (data->has_fan & (1 << i))
-                       device_create_file_fan(dev, i);
+               if (data->has_fan & (1 << i)) {
+                       if ((err = device_create_file(dev,
+                                       &sda_fan_input[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_fan_alarm[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_fan_div[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_fan_min[i].dev_attr)))
+                               goto exit_remove;
+                       if (i < 4 && /* w83627ehf only has 4 pwm */
+                               ((err = device_create_file(dev,
+                                       &sda_pwm[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_pwm_mode[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_pwm_enable[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_target_temp[i].dev_attr))
+                               || (err = device_create_file(dev,
+                                       &sda_tolerance[i].dev_attr))))
+                               goto exit_remove;
+               }
        }
+
        for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
-               device_create_file(dev, &sda_temp[i].dev_attr);
+               if ((err = device_create_file(dev, &sda_temp[i].dev_attr)))
+                       goto exit_remove;
+
+       data->class_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
+       }
 
        return 0;
 
-exit_detach:
+exit_remove:
+       w83627ehf_device_remove_files(dev);
        i2c_detach_client(client);
 exit_free:
        kfree(data);
@@ -892,6 +1304,7 @@ static int w83627ehf_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
+       w83627ehf_device_remove_files(&client->dev);
 
        if ((err = i2c_detach_client(client)))
                return err;
index 30295028ea99238ea89e0d59b40fa580018c5cc6..dfdc29c77123a7e0530984f5251f229f000a9f89 100644 (file)
@@ -512,13 +512,6 @@ static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
        show_regs_in_max0, store_regs_in_max0);
 
-#define device_create_file_in(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
 #define show_fan_reg(reg) \
 static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
 { \
@@ -576,12 +569,6 @@ sysfs_fan_min_offset(2);
 sysfs_fan_offset(3);
 sysfs_fan_min_offset(3);
 
-#define device_create_file_fan(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-} while (0)
-
 #define show_temp_reg(reg) \
 static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
 { \
@@ -656,13 +643,6 @@ sysfs_temp_offsets(1);
 sysfs_temp_offsets(2);
 sysfs_temp_offsets(3);
 
-#define device_create_file_temp(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
-} while (0)
-
 static ssize_t
 show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -670,8 +650,6 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
 
 static ssize_t
 show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
@@ -692,8 +670,6 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf
        return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm)
 
 static ssize_t
 show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
@@ -702,8 +678,6 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%ld\n", (long) data->alarms);
 }
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms)
 
 #define show_beep_reg(REG, reg) \
 static ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
@@ -766,12 +740,6 @@ static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \
 sysfs_beep(ENABLE, enable);
 sysfs_beep(MASK, mask);
 
-#define device_create_file_beep(client) \
-do { \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask); \
-} while (0)
-
 static ssize_t
 show_fan_div_reg(struct device *dev, char *buf, int nr)
 {
@@ -837,11 +805,6 @@ sysfs_fan_div(1);
 sysfs_fan_div(2);
 sysfs_fan_div(3);
 
-#define device_create_file_fan_div(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
 static ssize_t
 show_pwm_reg(struct device *dev, char *buf, int nr)
 {
@@ -896,11 +859,6 @@ sysfs_pwm(1);
 sysfs_pwm(2);
 sysfs_pwm(3);
 
-#define device_create_file_pwm(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset); \
-} while (0)
-
 static ssize_t
 show_sensor_reg(struct device *dev, char *buf, int nr)
 {
@@ -972,12 +930,6 @@ sysfs_sensor(1);
 sysfs_sensor(2);
 sysfs_sensor(3);
 
-#define device_create_file_sensor(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
-} while (0)
-
-
 static int __init w83627hf_find(int sioaddr, unsigned short *addr)
 {
        u16 val;
@@ -1009,6 +961,85 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr)
        return 0;
 }
 
+static struct attribute *w83627hf_attributes[] = {
+       &dev_attr_in0_input.attr,
+       &dev_attr_in0_min.attr,
+       &dev_attr_in0_max.attr,
+       &dev_attr_in2_input.attr,
+       &dev_attr_in2_min.attr,
+       &dev_attr_in2_max.attr,
+       &dev_attr_in3_input.attr,
+       &dev_attr_in3_min.attr,
+       &dev_attr_in3_max.attr,
+       &dev_attr_in4_input.attr,
+       &dev_attr_in4_min.attr,
+       &dev_attr_in4_max.attr,
+       &dev_attr_in7_input.attr,
+       &dev_attr_in7_min.attr,
+       &dev_attr_in7_max.attr,
+       &dev_attr_in8_input.attr,
+       &dev_attr_in8_min.attr,
+       &dev_attr_in8_max.attr,
+
+       &dev_attr_fan1_input.attr,
+       &dev_attr_fan1_min.attr,
+       &dev_attr_fan1_div.attr,
+       &dev_attr_fan2_input.attr,
+       &dev_attr_fan2_min.attr,
+       &dev_attr_fan2_div.attr,
+
+       &dev_attr_temp1_input.attr,
+       &dev_attr_temp1_max.attr,
+       &dev_attr_temp1_max_hyst.attr,
+       &dev_attr_temp1_type.attr,
+       &dev_attr_temp2_input.attr,
+       &dev_attr_temp2_max.attr,
+       &dev_attr_temp2_max_hyst.attr,
+       &dev_attr_temp2_type.attr,
+
+       &dev_attr_alarms.attr,
+       &dev_attr_beep_enable.attr,
+       &dev_attr_beep_mask.attr,
+
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm2.attr,
+
+       NULL
+};
+
+static const struct attribute_group w83627hf_group = {
+       .attrs = w83627hf_attributes,
+};
+
+static struct attribute *w83627hf_attributes_opt[] = {
+       &dev_attr_in1_input.attr,
+       &dev_attr_in1_min.attr,
+       &dev_attr_in1_max.attr,
+       &dev_attr_in5_input.attr,
+       &dev_attr_in5_min.attr,
+       &dev_attr_in5_max.attr,
+       &dev_attr_in6_input.attr,
+       &dev_attr_in6_min.attr,
+       &dev_attr_in6_max.attr,
+
+       &dev_attr_fan3_input.attr,
+       &dev_attr_fan3_min.attr,
+       &dev_attr_fan3_div.attr,
+
+       &dev_attr_temp3_input.attr,
+       &dev_attr_temp3_max.attr,
+       &dev_attr_temp3_max_hyst.attr,
+       &dev_attr_temp3_type.attr,
+
+       &dev_attr_pwm3.attr,
+
+       NULL
+};
+
+static const struct attribute_group w83627hf_group_opt = {
+       .attrs = w83627hf_attributes_opt,
+};
+
 static int w83627hf_detect(struct i2c_adapter *adapter)
 {
        int val, kind;
@@ -1108,62 +1139,72 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
        data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2));
        data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
 
-       /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       /* Register common device attributes */
+       if ((err = sysfs_create_group(&new_client->dev.kobj, &w83627hf_group)))
                goto ERROR3;
-       }
-
-       device_create_file_in(new_client, 0);
-       if (kind != w83697hf)
-               device_create_file_in(new_client, 1);
-       device_create_file_in(new_client, 2);
-       device_create_file_in(new_client, 3);
-       device_create_file_in(new_client, 4);
-       if (kind == w83627hf || kind == w83697hf) {
-               device_create_file_in(new_client, 5);
-               device_create_file_in(new_client, 6);
-       }
-       device_create_file_in(new_client, 7);
-       device_create_file_in(new_client, 8);
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       if (kind != w83697hf)
-               device_create_file_fan(new_client, 3);
-
-       device_create_file_temp(new_client, 1);
-       device_create_file_temp(new_client, 2);
-       if (kind != w83697hf)
-               device_create_file_temp(new_client, 3);
 
-       if (kind != w83697hf && data->vid != 0xff) {
-               device_create_file_vid(new_client);
-               device_create_file_vrm(new_client);
-       }
+       /* Register chip-specific device attributes */
+       if (kind == w83627hf || kind == w83697hf)
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in5_max))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in6_max)))
+                       goto ERROR4;
 
-       device_create_file_fan_div(new_client, 1);
-       device_create_file_fan_div(new_client, 2);
        if (kind != w83697hf)
-               device_create_file_fan_div(new_client, 3);
-
-       device_create_file_alarms(new_client);
-
-       device_create_file_beep(new_client);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_in1_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in1_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_in1_max))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan3_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan3_min))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_fan3_div))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_input))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_max))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_max_hyst))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_temp3_type)))
+                       goto ERROR4;
+
+       if (kind != w83697hf && data->vid != 0xff)
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_cpu0_vid))
+                || (err = device_create_file(&new_client->dev,
+                                       &dev_attr_vrm)))
+                       goto ERROR4;
 
-       device_create_file_pwm(new_client, 1);
-       device_create_file_pwm(new_client, 2);
        if (kind == w83627thf || kind == w83637hf || kind == w83687thf)
-               device_create_file_pwm(new_client, 3);
+               if ((err = device_create_file(&new_client->dev,
+                                       &dev_attr_pwm3)))
+                       goto ERROR4;
 
-       device_create_file_sensor(new_client, 1);
-       device_create_file_sensor(new_client, 2);
-       if (kind != w83697hf)
-               device_create_file_sensor(new_client, 3);
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR4;
+       }
 
        return 0;
 
+      ERROR4:
+       sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group);
+       sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group_opt);
       ERROR3:
        i2c_detach_client(new_client);
       ERROR2:
@@ -1181,6 +1222,9 @@ static int w83627hf_detach_client(struct i2c_client *client)
 
        hwmon_device_unregister(data->class_dev);
 
+       sysfs_remove_group(&client->dev.kobj, &w83627hf_group);
+       sysfs_remove_group(&client->dev.kobj, &w83627hf_group_opt);
+
        if ((err = i2c_detach_client(client)))
                return err;
 
index 95221b14e13a511749982ae13071932cda5fbe27..a4584ec69842fba9910d234fc6c80bb58b2a357f 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/i2c-isa.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <asm/io.h>
@@ -360,13 +361,6 @@ sysfs_in_offsets(6);
 sysfs_in_offsets(7);
 sysfs_in_offsets(8);
 
-#define device_create_file_in(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
 #define show_fan_reg(reg) \
 static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
 { \
@@ -421,12 +415,6 @@ sysfs_fan_min_offset(2);
 sysfs_fan_offset(3);
 sysfs_fan_min_offset(3);
 
-#define device_create_file_fan(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-} while (0)
-
 #define show_temp_reg(reg) \
 static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
 { \
@@ -497,13 +485,6 @@ sysfs_temp_offsets(1);
 sysfs_temp_offsets(2);
 sysfs_temp_offsets(3);
 
-#define device_create_file_temp(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
-} while (0)
-
 static ssize_t
 show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -511,10 +492,8 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
 }
 
-static
-DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid);
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+
 static ssize_t
 show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -535,10 +514,8 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf
        return count;
 }
 
-static
-DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm);
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+
 static ssize_t
 show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -546,10 +523,8 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%u\n", data->alarms);
 }
 
-static
-DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+
 static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct w83781d_data *data = w83781d_update_device(dev);
@@ -615,12 +590,6 @@ static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_re
 sysfs_beep(ENABLE, enable);
 sysfs_beep(MASK, mask);
 
-#define device_create_file_beep(client) \
-do { \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask); \
-} while (0)
-
 static ssize_t
 show_fan_div_reg(struct device *dev, char *buf, int nr)
 {
@@ -686,11 +655,6 @@ sysfs_fan_div(1);
 sysfs_fan_div(2);
 sysfs_fan_div(3);
 
-#define device_create_file_fan_div(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
 static ssize_t
 show_pwm_reg(struct device *dev, char *buf, int nr)
 {
@@ -787,16 +751,6 @@ sysfs_pwmenable(2);                /* only PWM2 can be enabled/disabled */
 sysfs_pwm(3);
 sysfs_pwm(4);
 
-#define device_create_file_pwm(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset); \
-} while (0)
-
-#define device_create_file_pwmenable(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \
-} while (0)
-
 static ssize_t
 show_sensor_reg(struct device *dev, char *buf, int nr)
 {
@@ -865,11 +819,6 @@ sysfs_sensor(1);
 sysfs_sensor(2);
 sysfs_sensor(3);
 
-#define device_create_file_sensor(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
-} while (0)
-
 /* This function is called when:
      * w83781d_driver is inserted (when this module is loaded), for each
        available adapter
@@ -994,11 +943,69 @@ ERROR_SC_0:
        return err;
 }
 
+#define IN_UNIT_ATTRS(X)                       \
+       &dev_attr_in##X##_input.attr,           \
+       &dev_attr_in##X##_min.attr,             \
+       &dev_attr_in##X##_max.attr
+
+#define FAN_UNIT_ATTRS(X)                      \
+       &dev_attr_fan##X##_input.attr,          \
+       &dev_attr_fan##X##_min.attr,            \
+       &dev_attr_fan##X##_div.attr
+
+#define TEMP_UNIT_ATTRS(X)                     \
+       &dev_attr_temp##X##_input.attr,         \
+       &dev_attr_temp##X##_max.attr,           \
+       &dev_attr_temp##X##_max_hyst.attr
+
+static struct attribute* w83781d_attributes[] = {
+       IN_UNIT_ATTRS(0),
+       IN_UNIT_ATTRS(2),
+       IN_UNIT_ATTRS(3),
+       IN_UNIT_ATTRS(4),
+       IN_UNIT_ATTRS(5),
+       IN_UNIT_ATTRS(6),
+       FAN_UNIT_ATTRS(1),
+       FAN_UNIT_ATTRS(2),
+       FAN_UNIT_ATTRS(3),
+       TEMP_UNIT_ATTRS(1),
+       TEMP_UNIT_ATTRS(2),
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_beep_mask.attr,
+       &dev_attr_beep_enable.attr,
+       NULL
+};
+static const struct attribute_group w83781d_group = {
+       .attrs = w83781d_attributes,
+};
+
+static struct attribute *w83781d_attributes_opt[] = {
+       IN_UNIT_ATTRS(1),
+       IN_UNIT_ATTRS(7),
+       IN_UNIT_ATTRS(8),
+       TEMP_UNIT_ATTRS(3),
+       &dev_attr_pwm1.attr,
+       &dev_attr_pwm2.attr,
+       &dev_attr_pwm2_enable.attr,
+       &dev_attr_pwm3.attr,
+       &dev_attr_pwm4.attr,
+       &dev_attr_temp1_type.attr,
+       &dev_attr_temp2_type.attr,
+       &dev_attr_temp3_type.attr,
+       NULL
+};
+static const struct attribute_group w83781d_group_opt = {
+       .attrs = w83781d_attributes_opt,
+};
+
 static int
 w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
 {
        int i = 0, val1 = 0, val2;
-       struct i2c_client *new_client;
+       struct i2c_client *client;
+       struct device *dev;
        struct w83781d_data *data;
        int err;
        const char *client_name = "";
@@ -1075,13 +1082,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                goto ERROR1;
        }
 
-       new_client = &data->client;
-       i2c_set_clientdata(new_client, data);
-       new_client->addr = address;
+       client = &data->client;
+       i2c_set_clientdata(client, data);
+       client->addr = address;
        mutex_init(&data->lock);
-       new_client->adapter = adapter;
-       new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver;
-       new_client->flags = 0;
+       client->adapter = adapter;
+       client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver;
+       client->flags = 0;
+       dev = &client->dev;
 
        /* Now, we do the remaining detection. */
 
@@ -1090,20 +1098,18 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
           force_*=... parameter, and the Winbond will be reset to the right
           bank. */
        if (kind < 0) {
-               if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) {
-                       dev_dbg(&new_client->dev, "Detection failed at step "
-                               "3\n");
+               if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) {
+                       dev_dbg(dev, "Detection failed at step 3\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
-               val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
-               val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
+               val1 = w83781d_read_value(client, W83781D_REG_BANK);
+               val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN);
                /* Check for Winbond or Asus ID if in bank 0 */
                if ((!(val1 & 0x07)) &&
                    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
                     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
-                       dev_dbg(&new_client->dev, "Detection failed at step "
-                               "4\n");
+                       dev_dbg(dev, "Detection failed at step 4\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
@@ -1112,9 +1118,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
                                  ((val1 & 0x80) && (val2 == 0x5c)))) {
                        if (w83781d_read_value
-                           (new_client, W83781D_REG_I2C_ADDR) != address) {
-                               dev_dbg(&new_client->dev, "Detection failed "
-                                       "at step 5\n");
+                           (client, W83781D_REG_I2C_ADDR) != address) {
+                               dev_dbg(dev, "Detection failed at step 5\n");
                                err = -ENODEV;
                                goto ERROR2;
                        }
@@ -1123,27 +1128,26 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
 
        /* We have either had a force parameter, or we have already detected the
           Winbond. Put it now into bank 0 and Vendor ID High Byte */
-       w83781d_write_value(new_client, W83781D_REG_BANK,
-                           (w83781d_read_value(new_client,
-                                               W83781D_REG_BANK) & 0x78) |
-                           0x80);
+       w83781d_write_value(client, W83781D_REG_BANK,
+                           (w83781d_read_value(client, W83781D_REG_BANK)
+                            & 0x78) | 0x80);
 
        /* Determine the chip type. */
        if (kind <= 0) {
                /* get vendor ID */
-               val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
+               val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN);
                if (val2 == 0x5c)
                        vendid = winbond;
                else if (val2 == 0x12)
                        vendid = asus;
                else {
-                       dev_dbg(&new_client->dev, "Chip was made by neither "
+                       dev_dbg(dev, "Chip was made by neither "
                                "Winbond nor Asus?\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
 
-               val1 = w83781d_read_value(new_client, W83781D_REG_WCHIPID);
+               val1 = w83781d_read_value(client, W83781D_REG_WCHIPID);
                if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
                        kind = w83781d;
                else if (val1 == 0x30 && vendid == winbond)
@@ -1157,7 +1161,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                        kind = as99127f;
                else {
                        if (kind == 0)
-                               dev_warn(&new_client->dev, "Ignoring 'force' "
+                               dev_warn(dev, "Ignoring 'force' "
                                         "parameter for unknown chip at "
                                         "adapter %d, address 0x%02x\n",
                                         i2c_adapter_id(adapter), address);
@@ -1179,20 +1183,20 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        /* Fill in the remaining client fields and put into the global list */
-       strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+       strlcpy(client->name, client_name, I2C_NAME_SIZE);
        data->type = kind;
 
        data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Tell the I2C layer a new client has arrived */
-       if ((err = i2c_attach_client(new_client)))
+       if ((err = i2c_attach_client(client)))
                goto ERROR2;
 
        /* attach secondary i2c lm75-like clients */
        if (!is_isa) {
                if ((err = w83781d_detect_subclients(adapter, address,
-                               kind, new_client)))
+                               kind, client)))
                        goto ERROR3;
        } else {
                data->lm75[0] = NULL;
@@ -1200,11 +1204,11 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        /* Initialize the chip */
-       w83781d_init_client(new_client);
+       w83781d_init_client(client);
 
        /* A few vars need to be filled upon startup */
        for (i = 1; i <= 3; i++) {
-               data->fan_min[i - 1] = w83781d_read_value(new_client,
+               data->fan_min[i - 1] = w83781d_read_value(client,
                                        W83781D_REG_FAN_MIN(i));
        }
        if (kind != w83781d && kind != as99127f)
@@ -1212,65 +1216,68 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                        data->pwmenable[i] = 1;
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(&new_client->dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&dev->kobj, &w83781d_group)))
                goto ERROR4;
-       }
 
-       device_create_file_in(new_client, 0);
-       if (kind != w83783s)
-               device_create_file_in(new_client, 1);
-       device_create_file_in(new_client, 2);
-       device_create_file_in(new_client, 3);
-       device_create_file_in(new_client, 4);
-       device_create_file_in(new_client, 5);
-       device_create_file_in(new_client, 6);
+       if (kind != w83783s) {
+               if ((err = device_create_file(dev, &dev_attr_in1_input))
+                   || (err = device_create_file(dev, &dev_attr_in1_min))
+                   || (err = device_create_file(dev, &dev_attr_in1_max)))
+                       goto ERROR4;
+       }
        if (kind != as99127f && kind != w83781d && kind != w83783s) {
-               device_create_file_in(new_client, 7);
-               device_create_file_in(new_client, 8);
+               if ((err = device_create_file(dev, &dev_attr_in7_input))
+                   || (err = device_create_file(dev, &dev_attr_in7_min))
+                   || (err = device_create_file(dev, &dev_attr_in7_max))
+                   || (err = device_create_file(dev, &dev_attr_in8_input))
+                   || (err = device_create_file(dev, &dev_attr_in8_min))
+                   || (err = device_create_file(dev, &dev_attr_in8_max)))
+                       goto ERROR4;
+       }
+       if (kind != w83783s) {
+               if ((err = device_create_file(dev, &dev_attr_temp3_input))
+                   || (err = device_create_file(dev, &dev_attr_temp3_max))
+                   || (err = device_create_file(dev,
+                                                &dev_attr_temp3_max_hyst)))
+                       goto ERROR4;
        }
-
-       device_create_file_fan(new_client, 1);
-       device_create_file_fan(new_client, 2);
-       device_create_file_fan(new_client, 3);
-
-       device_create_file_temp(new_client, 1);
-       device_create_file_temp(new_client, 2);
-       if (kind != w83783s)
-               device_create_file_temp(new_client, 3);
-
-       device_create_file_vid(new_client);
-       device_create_file_vrm(new_client);
-
-       device_create_file_fan_div(new_client, 1);
-       device_create_file_fan_div(new_client, 2);
-       device_create_file_fan_div(new_client, 3);
-
-       device_create_file_alarms(new_client);
-
-       device_create_file_beep(new_client);
 
        if (kind != w83781d && kind != as99127f) {
-               device_create_file_pwm(new_client, 1);
-               device_create_file_pwm(new_client, 2);
-               device_create_file_pwmenable(new_client, 2);
+               if ((err = device_create_file(dev, &dev_attr_pwm1))
+                   || (err = device_create_file(dev, &dev_attr_pwm2))
+                   || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
+                       goto ERROR4;
        }
        if (kind == w83782d && !is_isa) {
-               device_create_file_pwm(new_client, 3);
-               device_create_file_pwm(new_client, 4);
+               if ((err = device_create_file(dev, &dev_attr_pwm3))
+                   || (err = device_create_file(dev, &dev_attr_pwm4)))
+                       goto ERROR4;
        }
 
        if (kind != as99127f && kind != w83781d) {
-               device_create_file_sensor(new_client, 1);
-               device_create_file_sensor(new_client, 2);
-               if (kind != w83783s)
-                       device_create_file_sensor(new_client, 3);
+               if ((err = device_create_file(dev, &dev_attr_temp1_type))
+                   || (err = device_create_file(dev,
+                                                &dev_attr_temp2_type)))
+                       goto ERROR4;
+               if (kind != w83783s) {
+                       if ((err = device_create_file(dev,
+                                                     &dev_attr_temp3_type)))
+                               goto ERROR4;
+               }
+       }
+
+       data->class_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR4;
        }
 
        return 0;
 
 ERROR4:
+       sysfs_remove_group(&dev->kobj, &w83781d_group);
+       sysfs_remove_group(&dev->kobj, &w83781d_group_opt);
+
        if (data->lm75[1]) {
                i2c_detach_client(data->lm75[1]);
                kfree(data->lm75[1]);
@@ -1280,7 +1287,7 @@ ERROR4:
                kfree(data->lm75[0]);
        }
 ERROR3:
-       i2c_detach_client(new_client);
+       i2c_detach_client(client);
 ERROR2:
        kfree(data);
 ERROR1:
@@ -1297,9 +1304,11 @@ w83781d_detach_client(struct i2c_client *client)
        int err;
 
        /* main client */
-       if (data)
+       if (data) {
                hwmon_device_unregister(data->class_dev);
-
+               sysfs_remove_group(&client->dev.kobj, &w83781d_group);
+               sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt);
+       }
        if (i2c_is_isa_client(client))
                release_region(client->addr, W83781D_EXTENT);
 
index eec43abd57fb1e59801d311c95357efac86b2265..d965d074cd61c8ee3c3335dd850acc266f456106 100644 (file)
@@ -27,9 +27,9 @@
 
     The w83791d chip appears to be part way between the 83781d and the
     83792d. Thus, this file is derived from both the w83792d.c and
-    w83781d.c files, but its output is more along the lines of the
-    83781d (which means there are no changes to the user-mode sensors
-    program which treats the 83791d as an 83781d).
+    w83781d.c files.
+
+    The w83791g chip is the same as the w83791d but lead-free.
 */
 
 #include <linux/config.h>
@@ -1172,6 +1172,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
                        (w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) +
                        (w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16);
 
+               /* Extract global beep enable flag */
                data->beep_enable =
                        (data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01;
 
index 7576ec9426a35b0e733d08f5552058aa67e9cd73..4e108262576fa9bcf7887b94a21225d14d013d50 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/sysfs.h>
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
@@ -381,41 +382,6 @@ static ssize_t store_in_##reg (struct device *dev, \
 store_in_reg(MIN, min);
 store_in_reg(MAX, max);
 
-static struct sensor_device_attribute sda_in_input[] = {
-       SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
-       SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
-       SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
-       SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
-       SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
-       SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
-       SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
-       SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
-       SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
-};
-static struct sensor_device_attribute sda_in_min[] = {
-       SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
-       SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
-       SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
-       SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
-       SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
-       SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
-       SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
-       SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
-       SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
-};
-static struct sensor_device_attribute sda_in_max[] = {
-       SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
-       SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
-       SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
-       SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
-       SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
-       SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
-       SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
-       SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
-       SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
-};
-
-
 #define show_fan_reg(reg) \
 static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
                        char *buf) \
@@ -499,35 +465,6 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute sda_fan_input[] = {
-       SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1),
-       SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2),
-       SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3),
-       SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4),
-       SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5),
-       SENSOR_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6),
-       SENSOR_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7),
-};
-static struct sensor_device_attribute sda_fan_min[] = {
-       SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 1),
-       SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 2),
-       SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3),
-       SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 4),
-       SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 5),
-       SENSOR_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 6),
-       SENSOR_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 7),
-};
-static struct sensor_device_attribute sda_fan_div[] = {
-       SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 1),
-       SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 2),
-       SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 3),
-       SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 4),
-       SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 5),
-       SENSOR_ATTR(fan6_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 6),
-       SENSOR_ATTR(fan7_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 7),
-};
-
-
 /* read/write the temperature1, includes measured value and limits */
 
 static ssize_t show_temp1(struct device *dev, struct device_attribute *attr,
@@ -595,24 +532,6 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute_2 sda_temp_input[] = {
-       SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0),
-       SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0),
-       SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0),
-};
-
-static struct sensor_device_attribute_2 sda_temp_max[] = {
-       SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 1),
-       SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 2),
-       SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 2),
-};
-
-static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
-       SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 2),
-       SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 4),
-       SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 4),
-};
-
 /* get reatime status of all sensors items: voltage, temp, fan */
 static ssize_t
 show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
@@ -621,9 +540,6 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
        return sprintf(buf, "%d\n", data->alarms);
 }
 
-static
-DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-
 static ssize_t
 show_pwm(struct device *dev, struct device_attribute *attr,
                char *buf)
@@ -715,21 +631,6 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute sda_pwm[] = {
-       SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
-       SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
-       SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
-};
-static struct sensor_device_attribute sda_pwm_enable[] = {
-       SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
-                   show_pwmenable, store_pwmenable, 1),
-       SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
-                   show_pwmenable, store_pwmenable, 2),
-       SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
-                   show_pwmenable, store_pwmenable, 3),
-};
-
-
 static ssize_t
 show_pwm_mode(struct device *dev, struct device_attribute *attr,
                        char *buf)
@@ -767,16 +668,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute sda_pwm_mode[] = {
-       SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO,
-                   show_pwm_mode, store_pwm_mode, 0),
-       SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO,
-                   show_pwm_mode, store_pwm_mode, 1),
-       SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO,
-                   show_pwm_mode, store_pwm_mode, 2),
-};
-
-
 static ssize_t
 show_regs_chassis(struct device *dev, struct device_attribute *attr,
                        char *buf)
@@ -785,8 +676,6 @@ show_regs_chassis(struct device *dev, struct device_attribute *attr,
        return sprintf(buf, "%d\n", data->chassis);
 }
 
-static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
-
 static ssize_t
 show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -815,9 +704,6 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
-               show_chassis_clear, store_chassis_clear);
-
 /* For Smart Fan I / Thermal Cruise */
 static ssize_t
 show_thermal_cruise(struct device *dev, struct device_attribute *attr,
@@ -853,15 +739,6 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute sda_thermal_cruise[] = {
-       SENSOR_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO,
-                   show_thermal_cruise, store_thermal_cruise, 1),
-       SENSOR_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO,
-                   show_thermal_cruise, store_thermal_cruise, 2),
-       SENSOR_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO,
-                   show_thermal_cruise, store_thermal_cruise, 3),
-};
-
 /* For Smart Fan I/Thermal Cruise and Smart Fan II */
 static ssize_t
 show_tolerance(struct device *dev, struct device_attribute *attr,
@@ -901,15 +778,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute sda_tolerance[] = {
-       SENSOR_ATTR(tolerance1, S_IWUSR | S_IRUGO,
-                   show_tolerance, store_tolerance, 1),
-       SENSOR_ATTR(tolerance2, S_IWUSR | S_IRUGO,
-                   show_tolerance, store_tolerance, 2),
-       SENSOR_ATTR(tolerance3, S_IWUSR | S_IRUGO,
-                   show_tolerance, store_tolerance, 3),
-};
-
 /* For Smart Fan II */
 static ssize_t
 show_sf2_point(struct device *dev, struct device_attribute *attr,
@@ -946,36 +814,6 @@ store_sf2_point(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute_2 sda_sf2_point[] = {
-       SENSOR_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 1, 1),
-       SENSOR_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 2, 1),
-       SENSOR_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 3, 1),
-       SENSOR_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 4, 1),
-
-       SENSOR_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 1, 2),
-       SENSOR_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 2, 2),
-       SENSOR_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 3, 2),
-       SENSOR_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 4, 2),
-
-       SENSOR_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 1, 3),
-       SENSOR_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 2, 3),
-       SENSOR_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 3, 3),
-       SENSOR_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_point, store_sf2_point, 4, 3),
-};
-
-
 static ssize_t
 show_sf2_level(struct device *dev, struct device_attribute *attr,
                char *buf)
@@ -1016,29 +854,6 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static struct sensor_device_attribute_2 sda_sf2_level[] = {
-       SENSOR_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 1, 1),
-       SENSOR_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 2, 1),
-       SENSOR_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 3, 1),
-
-       SENSOR_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 1, 2),
-       SENSOR_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 2, 2),
-       SENSOR_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 3, 2),
-
-       SENSOR_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 1, 3),
-       SENSOR_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 2, 3),
-       SENSOR_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR,
-                     show_sf2_level, store_sf2_level, 3, 3),
-};
-
 /* This function is called when:
      * w83792d_driver is inserted (when this module is loaded), for each
        available adapter
@@ -1139,12 +954,297 @@ ERROR_SC_0:
        return err;
 }
 
-static void device_create_file_fan(struct device *dev, int i)
-{
-       device_create_file(dev, &sda_fan_input[i].dev_attr);
-       device_create_file(dev, &sda_fan_div[i].dev_attr);
-       device_create_file(dev, &sda_fan_min[i].dev_attr);
-}
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8);
+static SENSOR_DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 0);
+static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 1);
+static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 2);
+static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 3);
+static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 4);
+static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 5);
+static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 6);
+static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 7);
+static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO,
+                       show_in_min, store_in_min, 8);
+static SENSOR_DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 0);
+static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 1);
+static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 2);
+static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 3);
+static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 4);
+static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 5);
+static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 6);
+static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 7);
+static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO,
+                       show_in_max, store_in_max, 8);
+static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
+                       show_temp1, store_temp1, 0, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23,
+                       store_temp23, 0, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23,
+                       store_temp23, 1, 2);
+static SENSOR_DEVICE_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR,
+                       show_temp1, store_temp1, 0, 2);
+static SENSOR_DEVICE_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR,
+                       show_temp23, store_temp23, 0, 4);
+static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR,
+                       show_temp23, store_temp23, 1, 4);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
+static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
+                       show_chassis_clear, store_chassis_clear);
+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+                       show_pwmenable, store_pwmenable, 1);
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
+                       show_pwmenable, store_pwmenable, 2);
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
+                       show_pwmenable, store_pwmenable, 3);
+static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO,
+                       show_pwm_mode, store_pwm_mode, 0);
+static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO,
+                       show_pwm_mode, store_pwm_mode, 1);
+static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO,
+                       show_pwm_mode, store_pwm_mode, 2);
+static SENSOR_DEVICE_ATTR(tolerance1, S_IWUSR | S_IRUGO,
+                       show_tolerance, store_tolerance, 1);
+static SENSOR_DEVICE_ATTR(tolerance2, S_IWUSR | S_IRUGO,
+                       show_tolerance, store_tolerance, 2);
+static SENSOR_DEVICE_ATTR(tolerance3, S_IWUSR | S_IRUGO,
+                       show_tolerance, store_tolerance, 3);
+static SENSOR_DEVICE_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO,
+                       show_thermal_cruise, store_thermal_cruise, 1);
+static SENSOR_DEVICE_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO,
+                       show_thermal_cruise, store_thermal_cruise, 2);
+static SENSOR_DEVICE_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO,
+                       show_thermal_cruise, store_thermal_cruise, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 1, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 2, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 3, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 4, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 1, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 2, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 3, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 4, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 1, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 2, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 3, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_point, store_sf2_point, 4, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 1, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 2, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 3, 1);
+static SENSOR_DEVICE_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 1, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 2, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 3, 2);
+static SENSOR_DEVICE_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 1, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 2, 3);
+static SENSOR_DEVICE_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR,
+                       show_sf2_level, store_sf2_level, 3, 3);
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 3);
+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 4);
+static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 5);
+static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 6);
+static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
+                       show_fan_min, store_fan_min, 7);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 1);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 2);
+static SENSOR_DEVICE_ATTR(fan3_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 3);
+static SENSOR_DEVICE_ATTR(fan4_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 4);
+static SENSOR_DEVICE_ATTR(fan5_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 5);
+static SENSOR_DEVICE_ATTR(fan6_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 6);
+static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO,
+                       show_fan_div, store_fan_div, 7);
+
+static struct attribute *w83792d_attributes_fan[4][4] = {
+       {
+               &sensor_dev_attr_fan4_input.dev_attr.attr,
+               &sensor_dev_attr_fan4_min.dev_attr.attr,
+               &sensor_dev_attr_fan4_div.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan5_input.dev_attr.attr,
+               &sensor_dev_attr_fan5_min.dev_attr.attr,
+               &sensor_dev_attr_fan5_div.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan6_input.dev_attr.attr,
+               &sensor_dev_attr_fan6_min.dev_attr.attr,
+               &sensor_dev_attr_fan6_div.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan7_input.dev_attr.attr,
+               &sensor_dev_attr_fan7_min.dev_attr.attr,
+               &sensor_dev_attr_fan7_div.dev_attr.attr,
+               NULL
+       }
+};
+
+static const struct attribute_group w83792d_group_fan[4] = {
+       { .attrs = w83792d_attributes_fan[0] },
+       { .attrs = w83792d_attributes_fan[1] },
+       { .attrs = w83792d_attributes_fan[2] },
+       { .attrs = w83792d_attributes_fan[3] },
+};
+
+static struct attribute *w83792d_attributes[] = {
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
+       &sensor_dev_attr_in1_input.dev_attr.attr,
+       &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in1_min.dev_attr.attr,
+       &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in2_min.dev_attr.attr,
+       &sensor_dev_attr_in3_input.dev_attr.attr,
+       &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in3_min.dev_attr.attr,
+       &sensor_dev_attr_in4_input.dev_attr.attr,
+       &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in4_min.dev_attr.attr,
+       &sensor_dev_attr_in5_input.dev_attr.attr,
+       &sensor_dev_attr_in5_max.dev_attr.attr,
+       &sensor_dev_attr_in5_min.dev_attr.attr,
+       &sensor_dev_attr_in6_input.dev_attr.attr,
+       &sensor_dev_attr_in6_max.dev_attr.attr,
+       &sensor_dev_attr_in6_min.dev_attr.attr,
+       &sensor_dev_attr_in7_input.dev_attr.attr,
+       &sensor_dev_attr_in7_max.dev_attr.attr,
+       &sensor_dev_attr_in7_min.dev_attr.attr,
+       &sensor_dev_attr_in8_input.dev_attr.attr,
+       &sensor_dev_attr_in8_max.dev_attr.attr,
+       &sensor_dev_attr_in8_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_max.dev_attr.attr,
+       &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_max.dev_attr.attr,
+       &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_pwm1.dev_attr.attr,
+       &sensor_dev_attr_pwm1_mode.dev_attr.attr,
+       &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm2.dev_attr.attr,
+       &sensor_dev_attr_pwm2_mode.dev_attr.attr,
+       &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm3.dev_attr.attr,
+       &sensor_dev_attr_pwm3_mode.dev_attr.attr,
+       &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_chassis.attr,
+       &dev_attr_chassis_clear.attr,
+       &sensor_dev_attr_tolerance1.dev_attr.attr,
+       &sensor_dev_attr_thermal_cruise1.dev_attr.attr,
+       &sensor_dev_attr_tolerance2.dev_attr.attr,
+       &sensor_dev_attr_thermal_cruise2.dev_attr.attr,
+       &sensor_dev_attr_tolerance3.dev_attr.attr,
+       &sensor_dev_attr_thermal_cruise3.dev_attr.attr,
+       &sensor_dev_attr_sf2_point1_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_point2_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_point3_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_point4_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_point1_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_point2_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_point3_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_point4_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_point1_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_point2_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_point3_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_point4_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_level1_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_level2_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_level3_fan1.dev_attr.attr,
+       &sensor_dev_attr_sf2_level1_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_level2_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_level3_fan2.dev_attr.attr,
+       &sensor_dev_attr_sf2_level1_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_level2_fan3.dev_attr.attr,
+       &sensor_dev_attr_sf2_level3_fan3.dev_attr.attr,
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &sensor_dev_attr_fan3_input.dev_attr.attr,
+       &sensor_dev_attr_fan3_min.dev_attr.attr,
+       &sensor_dev_attr_fan3_div.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group w83792d_group = {
+       .attrs = w83792d_attributes,
+};
 
 static int
 w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
@@ -1268,59 +1368,46 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        /* Register sysfs hooks */
-       data->class_dev = hwmon_device_register(dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       if ((err = sysfs_create_group(&dev->kobj, &w83792d_group)))
                goto ERROR3;
-       }
-       for (i = 0; i < 9; i++) {
-               device_create_file(dev, &sda_in_input[i].dev_attr);
-               device_create_file(dev, &sda_in_max[i].dev_attr);
-               device_create_file(dev, &sda_in_min[i].dev_attr);
-       }
-       for (i = 0; i < 3; i++)
-               device_create_file_fan(dev, i);
 
        /* Read GPIO enable register to check if pins for fan 4,5 are used as
           GPIO */
        val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN);
+
        if (!(val1 & 0x40))
-               device_create_file_fan(dev, 3);
+               if ((err = sysfs_create_group(&dev->kobj,
+                                             &w83792d_group_fan[0])))
+                       goto exit_remove_files;
+
        if (!(val1 & 0x20))
-               device_create_file_fan(dev, 4);
+               if ((err = sysfs_create_group(&dev->kobj,
+                                             &w83792d_group_fan[1])))
+                       goto exit_remove_files;
 
        val1 = w83792d_read_value(client, W83792D_REG_PIN);
        if (val1 & 0x40)
-               device_create_file_fan(dev, 5);
+               if ((err = sysfs_create_group(&dev->kobj,
+                                             &w83792d_group_fan[2])))
+                       goto exit_remove_files;
+
        if (val1 & 0x04)
-               device_create_file_fan(dev, 6);
-
-       for (i = 0; i < 3; i++) {
-               device_create_file(dev, &sda_temp_input[i].dev_attr);
-               device_create_file(dev, &sda_temp_max[i].dev_attr);
-               device_create_file(dev, &sda_temp_max_hyst[i].dev_attr);
-               device_create_file(dev, &sda_thermal_cruise[i].dev_attr);
-               device_create_file(dev, &sda_tolerance[i].dev_attr);
-       }
+               if ((err = sysfs_create_group(&dev->kobj,
+                                             &w83792d_group_fan[3])))
+                       goto exit_remove_files;
 
-       for (i = 0; i < ARRAY_SIZE(sda_pwm); i++) {
-               device_create_file(dev, &sda_pwm[i].dev_attr);
-               device_create_file(dev, &sda_pwm_enable[i].dev_attr);
-               device_create_file(dev, &sda_pwm_mode[i].dev_attr);
+       data->class_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove_files;
        }
 
-       device_create_file(dev, &dev_attr_alarms);
-       device_create_file(dev, &dev_attr_chassis);
-       device_create_file(dev, &dev_attr_chassis_clear);
-
-       for (i = 0; i < ARRAY_SIZE(sda_sf2_point); i++)
-               device_create_file(dev, &sda_sf2_point[i].dev_attr);
-
-       for (i = 0; i < ARRAY_SIZE(sda_sf2_level); i++)
-               device_create_file(dev, &sda_sf2_level[i].dev_attr);
-
        return 0;
 
+exit_remove_files:
+       sysfs_remove_group(&dev->kobj, &w83792d_group);
+       for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
+               sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]);
 ERROR3:
        if (data->lm75[0] != NULL) {
                i2c_detach_client(data->lm75[0]);
@@ -1342,11 +1429,16 @@ static int
 w83792d_detach_client(struct i2c_client *client)
 {
        struct w83792d_data *data = i2c_get_clientdata(client);
-       int err;
+       int err, i;
 
        /* main client */
-       if (data)
+       if (data) {
                hwmon_device_unregister(data->class_dev);
+               sysfs_remove_group(&client->dev.kobj, &w83792d_group);
+               for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
+                       sysfs_remove_group(&client->dev.kobj,
+                                          &w83792d_group_fan[i]);
+       }
 
        if ((err = i2c_detach_client(client)))
                return err;
index 3f2bac125fb19b8a346c19fde04d6ceded5704e9..a3fcace412f0c41099f243e7349b07932515d84d 100644 (file)
@@ -236,21 +236,30 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
         * Nothing yet, assume it is already started.
         */
 
+       err = device_create_file(&new_client->dev,
+                                &sensor_dev_attr_temp1_input.dev_attr);
+       if (err)
+               goto exit_remove;
+
+       err = device_create_file(&new_client->dev,
+                                &sensor_dev_attr_temp1_max.dev_attr);
+       if (err)
+               goto exit_remove;
+
        /* Register sysfs hooks */
        data->class_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto exit_detach;
+               goto exit_remove;
        }
 
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_create_file(&new_client->dev,
-                          &sensor_dev_attr_temp1_max.dev_attr);
-
        return 0;
 
-exit_detach:
+exit_remove:
+       device_remove_file(&new_client->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_remove_file(&new_client->dev,
+                          &sensor_dev_attr_temp1_max.dev_attr);
        i2c_detach_client(new_client);
 exit_free:
        kfree(data);
@@ -264,7 +273,10 @@ static int w83l785ts_detach_client(struct i2c_client *client)
        int err;
 
        hwmon_device_unregister(data->class_dev);
-
+       device_remove_file(&client->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_remove_file(&client->dev,
+                          &sensor_dev_attr_temp1_max.dev_attr);
        if ((err = i2c_detach_client(client)))
                return err;
 
index 9e56c3989d680e7f022614989f7ec17b4661d00c..0d9667921f618494f1dba82f5b1674ff18bf1c4c 100644 (file)
@@ -196,7 +196,7 @@ config I2C_IBM_IIC
 
 config I2C_IOP3XX
        tristate "Intel IOP3xx and IXP4xx on-chip I2C interface"
-       depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C
+       depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX) && I2C
        help
          Say Y here if you want to use the IIC bus controller on
          the Intel IOP3xx I/O Processors or IXP4xx Network Processors.
index 8e413150af37d1c11e8a647fbe6719132176e3da..4436c89be58eb838c6b05dba1ecffecbc8fb18b0 100644 (file)
@@ -82,14 +82,16 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
 
        /* 
         * Every time unit enable is asserted, GPOD needs to be cleared
-        * on IOP321 to avoid data corruption on the bus.
+        * on IOP3XX to avoid data corruption on the bus.
         */
-#ifdef CONFIG_ARCH_IOP321
-#define IOP321_GPOD_I2C0    0x00c0  /* clear these bits to enable ch0 */
-#define IOP321_GPOD_I2C1    0x0030  /* clear these bits to enable ch1 */
-
-       *IOP321_GPOD &= (iop3xx_adap->id == 0) ? ~IOP321_GPOD_I2C0 : 
-               ~IOP321_GPOD_I2C1;
+#ifdef CONFIG_PLAT_IOP
+       if (iop3xx_adap->id == 0) {
+               gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
+               gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
+       } else {
+               gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW);
+               gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW);
+       }
 #endif
        /* NB SR bits not same position as CR IE bits :-( */
        iop3xx_adap->SR_enabled = 
index 8f2b1f0deb813b6876fa233c525094ea522e1cf7..0ca599d3b4029851ddf022bab424759824060ec2 100644 (file)
@@ -210,8 +210,8 @@ static int __init i2c_sibyte_init(void)
 
 static void __exit i2c_sibyte_exit(void)
 {
-       i2c_del_bus(&sibyte_board_adapter[0]);
-       i2c_del_bus(&sibyte_board_adapter[1]);
+       i2c_del_adapter(&sibyte_board_adapter[0]);
+       i2c_del_adapter(&sibyte_board_adapter[1]);
 }
 
 module_init(i2c_sibyte_init);
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..69d627bd537a8cb7ca1095a7915291995c9dfbc6 100644 (file)
@@ -4,6 +4,8 @@
 # Andre Hedrick <andre@linux-ide.org>
 #
 
+if BLOCK
+
 menu "ATA/ATAPI/MFM/RLL support"
 
 config IDE
@@ -1082,3 +1084,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..c3546fe9af63dbc718447523d116ed75ede19083 100644 (file)
@@ -205,7 +205,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);
 
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..38479a29d3e10a4e07236c0466fc0b81b4ba4a3b 100644 (file)
@@ -59,7 +59,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
 {
        int ret = 1;
 
-       BUG_ON(!(rq->flags & REQ_STARTED));
+       BUG_ON(!blk_rq_started(rq));
 
        /*
         * if failfast is set on a request, override number of sectors and
@@ -141,7 +141,7 @@ enum {
 
 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;
@@ -164,7 +164,7 @@ 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));
@@ -244,7 +244,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 +366,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 +376,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 +390,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 +421,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 +587,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 +638,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 +808,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 +844,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 +866,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 +892,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 +933,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 +980,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 +1013,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 +1264,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;
@@ -1670,7 +1670,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 +1710,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 +1717,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 +1726,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 +1735,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 1feff23487d44f515574809e153744a615c7ad26..850ef63cc986ba695ba643f5b13483c49a430a6c 100644 (file)
@@ -456,13 +456,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 7067ab997927d5515f32f2b09c8a48af1cc34cdf..2ebc3760f261dc7ed15f819f0c50492cb87bdca4 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;
        }
@@ -2768,12 +2768,12 @@ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq)
        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..2b1a1389c31880b16d492f8145ddfe5ac96acd90 100644 (file)
@@ -1217,9 +1217,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 +1238,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;
 
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 a574de5f083572933ce68c5898ccae7192d5218c..d55b938b1aebeb83bc7d60e3016e7e2b28fdc40b 100644 (file)
@@ -318,6 +318,20 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
        hwif->drives[0].autodma = hwif->autodma;
 }
 
+static void __devinit init_hwif_sb600_legacy(ide_hwif_t *hwif)
+{
+
+       hwif->atapi_dma = 1;
+       hwif->ultra_mask = 0x7f;
+       hwif->mwdma_mask = 0x07;
+       hwif->swdma_mask = 0x07;
+
+       if (!noautodma)
+               hwif->autodma = 1;
+       hwif->drives[0].autodma = hwif->autodma;
+       hwif->drives[1].autodma = hwif->autodma;
+}
+
 static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
        {       /* 0 */
                .name           = "ATIIXP",
@@ -326,6 +340,12 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
                .autodma        = AUTODMA,
                .enablebits     = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
                .bootable       = ON_BOARD,
+       },{     /* 1 */
+               .name           = "ATI SB600 SATA Legacy IDE",
+               .init_hwif      = init_hwif_sb600_legacy,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = ON_BOARD,
        }
 };
 
@@ -348,6 +368,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
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 9cbf09e2052f87d5845b41a3d348f129f7f5250d..60d3fbdd216c72833958cca3b51db16e3cd3d722 100644 (file)
@@ -86,7 +86,7 @@ EXPORT_SYMBOL(rdma_copy_addr);
 int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
 {
        struct net_device *dev;
-       u32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+       __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
        int ret;
 
        dev = ip_dev_find(ip);
@@ -239,7 +239,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
 {
        struct net_device *dev;
        u32 src_ip = src_in->sin_addr.s_addr;
-       u32 dst_ip = dst_in->sin_addr.s_addr;
+       __be32 dst_ip = dst_in->sin_addr.s_addr;
        int ret;
 
        dev = ip_dev_find(dst_ip);
index 08f46c83a3a43c92d796a76557293bfa37074256..3aae4978e1cbc574eb4e816b2fdb74cc18c7dd55 100644 (file)
@@ -197,7 +197,7 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
                        "resource=%x, qp_state=%s\n",
                        __FUNCTION__,
                        to_event_str(event_id),
-                       be64_to_cpu(wr->ae.ae_generic.user_context),
+                       (unsigned long long) be64_to_cpu(wr->ae.ae_generic.user_context),
                        be32_to_cpu(wr->ae.ae_generic.resource_type),
                        be32_to_cpu(wr->ae.ae_generic.resource),
                        to_qp_state_str(be32_to_cpu(wr->ae.ae_generic.qp_state)));
index 1d2529992c0c954018faea5090ada7d1597d67ce..028a60bbfca9ce2db18fb7506a8c84649d4e20a6 100644 (file)
@@ -115,7 +115,7 @@ u16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head,
                            ((unsigned long) &(head->shared_ptr[mqsp]) -
                             (unsigned long) head);
                pr_debug("%s addr %p dma_addr %llx\n", __FUNCTION__,
-                        &(head->shared_ptr[mqsp]), (u64)*dma_addr);
+                        &(head->shared_ptr[mqsp]), (unsigned long long) *dma_addr);
                return &(head->shared_ptr[mqsp]);
        }
        return NULL;
index 485254efdd1e57fc02af3ecb53ed618f56a8baf1..75b93e9b88100638a10c3d59b77e51a59ad420be 100644 (file)
@@ -302,7 +302,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
        vq_req = vq_req_alloc(c2dev);
        if (!vq_req) {
                err = -ENOMEM;
-               goto bail1;
+               goto bail0;
        }
        vq_req->qp = qp;
        vq_req->cm_id = cm_id;
@@ -311,7 +311,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
        wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL);
        if (!wr) {
                err = -ENOMEM;
-               goto bail2;
+               goto bail1;
        }
 
        /* Build the WR */
@@ -331,7 +331,7 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
        /* Validate private_data length */
        if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) {
                err = -EINVAL;
-               goto bail2;
+               goto bail1;
        }
 
        if (iw_param->private_data) {
@@ -348,19 +348,19 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
        err = vq_send_wr(c2dev, (union c2wr *) wr);
        if (err) {
                vq_req_put(c2dev, vq_req);
-               goto bail2;
+               goto bail1;
        }
 
        /* Wait for reply from adapter */
        err = vq_wait_for_reply(c2dev, vq_req);
        if (err)
-               goto bail2;
+               goto bail1;
 
        /* Check that reply is present */
        reply = (struct c2wr_cr_accept_rep *) (unsigned long) vq_req->reply_msg;
        if (!reply) {
                err = -ENOMEM;
-               goto bail2;
+               goto bail1;
        }
 
        err = c2_errno(reply);
@@ -368,9 +368,8 @@ int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
 
        if (!err)
                c2_set_qp_state(qp, C2_QP_STATE_RTS);
- bail2:
-       kfree(wr);
  bail1:
+       kfree(wr);
        vq_req_free(c2dev, vq_req);
  bail0:
        if (err) {
index dd6af551108bc111a87c4bb0cbd8ebd449007a6e..da98d9f714295062d7e46c5ccd9e03b6e9a93bb2 100644 (file)
@@ -390,14 +390,18 @@ static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
        }
 
        mr = kmalloc(sizeof(*mr), GFP_KERNEL);
-       if (!mr)
+       if (!mr) {
+               vfree(page_list);
                return ERR_PTR(-ENOMEM);
+       }
 
        mr->pd = to_c2pd(ib_pd);
        pr_debug("%s - page shift %d, pbl_depth %d, total_len %u, "
                "*iova_start %llx, first pa %llx, last pa %llx\n",
                __FUNCTION__, page_shift, pbl_depth, total_len,
-               *iova_start, page_list[0], page_list[pbl_depth-1]);
+               (unsigned long long) *iova_start,
+               (unsigned long long) page_list[0],
+               (unsigned long long) page_list[pbl_depth-1]);
        err = c2_nsmr_register_phys_kern(to_c2dev(ib_pd->device), page_list,
                                         (1 << page_shift), pbl_depth,
                                         total_len, 0, iova_start,
index f49a32b7a8f6472545a2594f5c888232142f6d63..e37c5688c2146c969a609cc9a913d01319b86700 100644 (file)
@@ -527,7 +527,7 @@ int c2_rnic_init(struct c2_dev *c2dev)
                                                DMA_FROM_DEVICE);
        pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma);
        pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages,
-                (u64)c2dev->rep_vq.host_dma);
+                (unsigned long long) c2dev->rep_vq.host_dma);
        c2_mq_rep_init(&c2dev->rep_vq,
                   1,
                   qsize,
@@ -550,7 +550,7 @@ int c2_rnic_init(struct c2_dev *c2dev)
                                                DMA_FROM_DEVICE);
        pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma);
        pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages,
-                (u64)c2dev->rep_vq.host_dma);
+                (unsigned long long) c2dev->rep_vq.host_dma);
        c2_mq_rep_init(&c2dev->aeq,
                       2,
                       qsize,
index f577905e3acaafc3d624c04a00dca92b6f08be35..54139d3981812a2ffdc78166d2dcf7722ea29b91 100644 (file)
@@ -141,8 +141,9 @@ struct infinipath_stats {
         * packets if ipath not configured, etc.)
         */
        __u64 sps_krdrops;
+       __u64 sps_txeparity; /* PIO buffer parity error, recovered */
        /* pad for future growth */
-       __u64 __sps_pad[46];
+       __u64 __sps_pad[45];
 };
 
 /*
@@ -185,6 +186,9 @@ typedef enum _ipath_ureg {
 #define IPATH_RUNTIME_PCIE     0x2
 #define IPATH_RUNTIME_FORCE_WC_ORDER   0x4
 #define IPATH_RUNTIME_RCVHDR_COPY      0x8
+#define IPATH_RUNTIME_MASTER   0x10
+#define IPATH_RUNTIME_PBC_REWRITE 0x20
+#define IPATH_RUNTIME_LOOSE_DMA_ALIGN 0x40
 
 /*
  * This structure is returned by ipath_userinit() immediately after
@@ -202,7 +206,8 @@ struct ipath_base_info {
        /* version of software, for feature checking. */
        __u32 spi_sw_version;
        /* InfiniPath port assigned, goes into sent packets */
-       __u32 spi_port;
+       __u16 spi_port;
+       __u16 spi_subport;
        /*
         * IB MTU, packets IB data must be less than this.
         * The MTU is in bytes, and will be a multiple of 4 bytes.
@@ -218,7 +223,7 @@ struct ipath_base_info {
        __u32 spi_tidcnt;
        /* size of the TID Eager list in infinipath, in entries */
        __u32 spi_tidegrcnt;
-       /* size of a single receive header queue entry. */
+       /* size of a single receive header queue entry in words. */
        __u32 spi_rcvhdrent_size;
        /*
         * Count of receive header queue entries allocated.
@@ -310,6 +315,12 @@ struct ipath_base_info {
        __u32 spi_filler_for_align;
        /* address of readonly memory copy of the rcvhdrq tail register. */
        __u64 spi_rcvhdr_tailaddr;
+
+       /* shared memory pages for subports if IPATH_RUNTIME_MASTER is set */
+       __u64 spi_subport_uregbase;
+       __u64 spi_subport_rcvegrbuf;
+       __u64 spi_subport_rcvhdr_base;
+
 } __attribute__ ((aligned(8)));
 
 
@@ -328,12 +339,12 @@ struct ipath_base_info {
 
 /*
  * Minor version differences are always compatible
- * a within a major version, however if if user software is larger
+ * a within a major version, however if user software is larger
  * than driver software, some new features and/or structure fields
  * may not be implemented; the user code must deal with this if it
- * cares, or it must abort after initialization reports the difference
+ * cares, or it must abort after initialization reports the difference.
  */
-#define IPATH_USER_SWMINOR 2
+#define IPATH_USER_SWMINOR 3
 
 #define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR)
 
@@ -379,7 +390,16 @@ struct ipath_user_info {
         */
        __u32 spu_rcvhdrsize;
 
-       __u64 spu_unused; /* kept for compatible layout */
+       /*
+        * If two or more processes wish to share a port, each process
+        * must set the spu_subport_cnt and spu_subport_id to the same
+        * values.  The only restriction on the spu_subport_id is that
+        * it be unique for a given node.
+        */
+       __u16 spu_subport_cnt;
+       __u16 spu_subport_id;
+
+       __u32 spu_unused; /* kept for compatible layout */
 
        /*
         * address of struct base_info to write to
@@ -392,19 +412,25 @@ struct ipath_user_info {
 
 #define IPATH_CMD_MIN          16
 
-#define IPATH_CMD_USER_INIT    16      /* set up userspace */
+#define __IPATH_CMD_USER_INIT  16      /* old set up userspace (for old user code) */
 #define IPATH_CMD_PORT_INFO    17      /* find out what resources we got */
 #define IPATH_CMD_RECV_CTRL    18      /* control receipt of packets */
 #define IPATH_CMD_TID_UPDATE   19      /* update expected TID entries */
 #define IPATH_CMD_TID_FREE     20      /* free expected TID entries */
 #define IPATH_CMD_SET_PART_KEY 21      /* add partition key */
+#define IPATH_CMD_SLAVE_INFO   22      /* return info on slave processes */
+#define IPATH_CMD_ASSIGN_PORT  23      /* allocate HCA and port */
+#define IPATH_CMD_USER_INIT    24      /* set up userspace */
 
-#define IPATH_CMD_MAX          21
+#define IPATH_CMD_MAX          24
 
 struct ipath_port_info {
        __u32 num_active;       /* number of active units */
        __u32 unit;             /* unit (chip) assigned to caller */
-       __u32 port;             /* port on unit assigned to caller */
+       __u16 port;             /* port on unit assigned to caller */
+       __u16 subport;          /* subport on unit assigned to caller */
+       __u16 num_ports;        /* number of ports available on unit */
+       __u16 num_subports;     /* number of subport slaves opened on port */
 };
 
 struct ipath_tid_info {
@@ -435,6 +461,8 @@ struct ipath_cmd {
                __u32 recv_ctrl;
                /* partition key to set */
                __u16 part_key;
+               /* user address of __u32 bitmask of active slaves */
+               __u64 slave_mask_addr;
        } cmd;
 };
 
@@ -596,6 +624,10 @@ struct infinipath_counters {
 
 /* K_PktFlags bits */
 #define INFINIPATH_KPF_INTR 0x1
+#define INFINIPATH_KPF_SUBPORT_MASK 0x3
+#define INFINIPATH_KPF_SUBPORT_SHIFT 1
+
+#define INFINIPATH_MAX_SUBPORT 4
 
 /* SendPIO per-buffer control */
 #define INFINIPATH_SP_TEST    0x40
@@ -610,7 +642,7 @@ struct ipath_header {
        /*
         * Version - 4 bits, Port - 4 bits, TID - 10 bits and Offset -
         * 14 bits before ECO change ~28 Dec 03.  After that, Vers 4,
-        * Port 3, TID 11, offset 14.
+        * Port 4, TID 11, offset 13.
         */
        __le32 ver_port_tid_offset;
        __le16 chksum;
index 049221bc590e0eda2c2c743eca6da06af88a0259..87462e0cb4d2f5e95bf41f12b9ec9910429eb24e 100644 (file)
@@ -46,7 +46,7 @@
  */
 void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
 {
-       struct ipath_cq_wc *wc = cq->queue;
+       struct ipath_cq_wc *wc;
        unsigned long flags;
        u32 head;
        u32 next;
@@ -57,6 +57,7 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
         * Note that the head pointer might be writable by user processes.
         * Take care to verify it is a sane value.
         */
+       wc = cq->queue;
        head = wc->head;
        if (head >= (unsigned) cq->ibcq.cqe) {
                head = cq->ibcq.cqe;
@@ -109,21 +110,27 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
 int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
 {
        struct ipath_cq *cq = to_icq(ibcq);
-       struct ipath_cq_wc *wc = cq->queue;
+       struct ipath_cq_wc *wc;
        unsigned long flags;
        int npolled;
+       u32 tail;
 
        spin_lock_irqsave(&cq->lock, flags);
 
+       wc = cq->queue;
+       tail = wc->tail;
+       if (tail > (u32) cq->ibcq.cqe)
+               tail = (u32) cq->ibcq.cqe;
        for (npolled = 0; npolled < num_entries; ++npolled, ++entry) {
-               if (wc->tail == wc->head)
+               if (tail == wc->head)
                        break;
-               *entry = wc->queue[wc->tail];
-               if (wc->tail >= cq->ibcq.cqe)
-                       wc->tail = 0;
+               *entry = wc->queue[tail];
+               if (tail >= cq->ibcq.cqe)
+                       tail = 0;
                else
-                       wc->tail++;
+                       tail++;
        }
+       wc->tail = tail;
 
        spin_unlock_irqrestore(&cq->lock, flags);
 
@@ -177,11 +184,6 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
                goto done;
        }
 
-       if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
-               ret = ERR_PTR(-ENOMEM);
-               goto done;
-       }
-
        /* Allocate the completion queue structure. */
        cq = kmalloc(sizeof(*cq), GFP_KERNEL);
        if (!cq) {
@@ -237,6 +239,16 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
        } else
                cq->ip = NULL;
 
+       spin_lock(&dev->n_cqs_lock);
+       if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
+               spin_unlock(&dev->n_cqs_lock);
+               ret = ERR_PTR(-ENOMEM);
+               goto bail_wc;
+       }
+
+       dev->n_cqs_allocated++;
+       spin_unlock(&dev->n_cqs_lock);
+
        /*
         * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe.
         * The number of entries should be >= the number requested or return
@@ -253,7 +265,6 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
 
        ret = &cq->ibcq;
 
-       dev->n_cqs_allocated++;
        goto done;
 
 bail_wc:
@@ -280,7 +291,9 @@ int ipath_destroy_cq(struct ib_cq *ibcq)
        struct ipath_cq *cq = to_icq(ibcq);
 
        tasklet_kill(&cq->comptask);
+       spin_lock(&dev->n_cqs_lock);
        dev->n_cqs_allocated--;
+       spin_unlock(&dev->n_cqs_lock);
        if (cq->ip)
                kref_put(&cq->ip->ref, ipath_release_mmap_info);
        else
@@ -316,10 +329,16 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
        return 0;
 }
 
+/**
+ * ipath_resize_cq - change the size of the CQ
+ * @ibcq: the completion queue
+ *
+ * Returns 0 for success.
+ */
 int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
 {
        struct ipath_cq *cq = to_icq(ibcq);
-       struct ipath_cq_wc *old_wc = cq->queue;
+       struct ipath_cq_wc *old_wc;
        struct ipath_cq_wc *wc;
        u32 head, tail, n;
        int ret;
@@ -355,6 +374,7 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
         * Make sure head and tail are sane since they
         * might be user writable.
         */
+       old_wc = cq->queue;
        head = old_wc->head;
        if (head > (u32) cq->ibcq.cqe)
                head = (u32) cq->ibcq.cqe;
index 2108466c7e337169649c4a64e0f9157995a9aca7..12cefa658f3ba888f808c79b902f9fb018fb380c 100644 (file)
@@ -95,16 +95,6 @@ const char *ipath_ibcstatus_str[] = {
        "RecovIdle",
 };
 
-/*
- * These variables are initialized in the chip-specific files
- * but are defined here.
- */
-u16 ipath_gpio_sda_num, ipath_gpio_scl_num;
-u64 ipath_gpio_sda, ipath_gpio_scl;
-u64 infinipath_i_bitsextant;
-ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
-u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask;
-
 static void __devexit ipath_remove_one(struct pci_dev *);
 static int __devinit ipath_init_one(struct pci_dev *,
                                    const struct pci_device_id *);
@@ -527,28 +517,146 @@ bail:
        return ret;
 }
 
+static void __devexit cleanup_device(struct ipath_devdata *dd)
+{
+       int port;
+
+       ipath_shutdown_device(dd);
+
+       if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
+               /* can't do anything more with chip; needs re-init */
+               *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
+               if (dd->ipath_kregbase) {
+                       /*
+                        * if we haven't already cleaned up before these are
+                        * to ensure any register reads/writes "fail" until
+                        * re-init
+                        */
+                       dd->ipath_kregbase = NULL;
+                       dd->ipath_uregbase = 0;
+                       dd->ipath_sregbase = 0;
+                       dd->ipath_cregbase = 0;
+                       dd->ipath_kregsize = 0;
+               }
+               ipath_disable_wc(dd);
+       }
+
+       if (dd->ipath_pioavailregs_dma) {
+               dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
+                                 (void *) dd->ipath_pioavailregs_dma,
+                                 dd->ipath_pioavailregs_phys);
+               dd->ipath_pioavailregs_dma = NULL;
+       }
+       if (dd->ipath_dummy_hdrq) {
+               dma_free_coherent(&dd->pcidev->dev,
+                       dd->ipath_pd[0]->port_rcvhdrq_size,
+                       dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
+               dd->ipath_dummy_hdrq = NULL;
+       }
+
+       if (dd->ipath_pageshadow) {
+               struct page **tmpp = dd->ipath_pageshadow;
+               dma_addr_t *tmpd = dd->ipath_physshadow;
+               int i, cnt = 0;
+
+               ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
+                          "locked\n");
+               for (port = 0; port < dd->ipath_cfgports; port++) {
+                       int port_tidbase = port * dd->ipath_rcvtidcnt;
+                       int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
+                       for (i = port_tidbase; i < maxtid; i++) {
+                               if (!tmpp[i])
+                                       continue;
+                               pci_unmap_page(dd->pcidev, tmpd[i],
+                                       PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                               ipath_release_user_pages(&tmpp[i], 1);
+                               tmpp[i] = NULL;
+                               cnt++;
+                       }
+               }
+               if (cnt) {
+                       ipath_stats.sps_pageunlocks += cnt;
+                       ipath_cdbg(VERBOSE, "There were still %u expTID "
+                                  "entries locked\n", cnt);
+               }
+               if (ipath_stats.sps_pagelocks ||
+                   ipath_stats.sps_pageunlocks)
+                       ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
+                                  "unlocked via ipath_m{un}lock\n",
+                                  (unsigned long long)
+                                  ipath_stats.sps_pagelocks,
+                                  (unsigned long long)
+                                  ipath_stats.sps_pageunlocks);
+
+               ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
+                          dd->ipath_pageshadow);
+               vfree(dd->ipath_pageshadow);
+               dd->ipath_pageshadow = NULL;
+       }
+
+       /*
+        * free any resources still in use (usually just kernel ports)
+        * at unload; we do for portcnt, not cfgports, because cfgports
+        * could have changed while we were loaded.
+        */
+       for (port = 0; port < dd->ipath_portcnt; port++) {
+               struct ipath_portdata *pd = dd->ipath_pd[port];
+               dd->ipath_pd[port] = NULL;
+               ipath_free_pddata(dd, pd);
+       }
+       kfree(dd->ipath_pd);
+       /*
+        * debuggability, in case some cleanup path tries to use it
+        * after this
+        */
+       dd->ipath_pd = NULL;
+}
+
 static void __devexit ipath_remove_one(struct pci_dev *pdev)
 {
-       struct ipath_devdata *dd;
+       struct ipath_devdata *dd = pci_get_drvdata(pdev);
 
-       ipath_cdbg(VERBOSE, "removing, pdev=%p\n", pdev);
-       if (!pdev)
-               return;
+       ipath_cdbg(VERBOSE, "removing, pdev=%p, dd=%p\n", pdev, dd);
+
+       if (dd->verbs_dev)
+               ipath_unregister_ib_device(dd->verbs_dev);
 
-       dd = pci_get_drvdata(pdev);
-       ipath_unregister_ib_device(dd->verbs_dev);
        ipath_diag_remove(dd);
        ipath_user_remove(dd);
        ipathfs_remove_device(dd);
        ipath_device_remove_group(&pdev->dev, dd);
+
        ipath_cdbg(VERBOSE, "Releasing pci memory regions, dd %p, "
                   "unit %u\n", dd, (u32) dd->ipath_unit);
-       if (dd->ipath_kregbase) {
-               ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n",
-                          dd->ipath_kregbase);
-               iounmap((volatile void __iomem *) dd->ipath_kregbase);
-               dd->ipath_kregbase = NULL;
-       }
+
+       cleanup_device(dd);
+
+       /*
+        * turn off rcv, send, and interrupts for all ports, all drivers
+        * should also hard reset the chip here?
+        * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
+        * for all versions of the driver, if they were allocated
+        */
+       if (pdev->irq) {
+               ipath_cdbg(VERBOSE,
+                          "unit %u free_irq of irq %x\n",
+                          dd->ipath_unit, pdev->irq);
+               free_irq(pdev->irq, dd);
+       } else
+               ipath_dbg("irq is 0, not doing free_irq "
+                         "for unit %u\n", dd->ipath_unit);
+       /*
+        * we check for NULL here, because it's outside
+        * the kregbase check, and we need to call it
+        * after the free_irq.  Thus it's possible that
+        * the function pointers were never initialized.
+        */
+       if (dd->ipath_f_cleanup)
+               /* clean up chip-specific stuff */
+               dd->ipath_f_cleanup(dd);
+
+       ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n", dd->ipath_kregbase);
+       iounmap((volatile void __iomem *) dd->ipath_kregbase);
        pci_release_regions(pdev);
        ipath_cdbg(VERBOSE, "calling pci_disable_device\n");
        pci_disable_device(pdev);
@@ -760,8 +868,8 @@ static void get_rhf_errstring(u32 err, char *msg, size_t len)
 static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum,
                                     int err)
 {
-       return dd->ipath_port0_skbs ?
-               (void *)dd->ipath_port0_skbs[bufnum]->data : NULL;
+       return dd->ipath_port0_skbinfo ?
+               (void *) dd->ipath_port0_skbinfo[bufnum].skb->data : NULL;
 }
 
 /**
@@ -783,31 +891,34 @@ struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd,
         */
 
        /*
-        * We need 4 extra bytes for unaligned transfer copying
+        * We need 2 extra bytes for ipath_ether data sent in the
+        * key header.  In order to keep everything dword aligned,
+        * we'll reserve 4 bytes.
         */
+       len = dd->ipath_ibmaxlen + 4;
+
        if (dd->ipath_flags & IPATH_4BYTE_TID) {
-               /* we need a 4KB multiple alignment, and there is no way
+               /* We need a 2KB multiple alignment, and there is no way
                 * to do it except to allocate extra and then skb_reserve
                 * enough to bring it up to the right alignment.
                 */
-               len = dd->ipath_ibmaxlen + 4 + (1 << 11) - 1;
+               len += 2047;
        }
-       else
-               len = dd->ipath_ibmaxlen + 4;
+
        skb = __dev_alloc_skb(len, gfp_mask);
        if (!skb) {
                ipath_dev_err(dd, "Failed to allocate skbuff, length %u\n",
                              len);
                goto bail;
        }
+
+       skb_reserve(skb, 4);
+
        if (dd->ipath_flags & IPATH_4BYTE_TID) {
-               u32 una = ((1 << 11) - 1) & (unsigned long)(skb->data + 4);
+               u32 una = (unsigned long)skb->data & 2047;
                if (una)
-                       skb_reserve(skb, 4 + (1 << 11) - una);
-               else
-                       skb_reserve(skb, 4);
-       } else
-               skb_reserve(skb, 4);
+                       skb_reserve(skb, 2048 - una);
+       }
 
 bail:
        return skb;
@@ -1326,6 +1437,9 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
                                      "for port %u rcvhdrqtailaddr failed\n",
                                      pd->port_port);
                        ret = -ENOMEM;
+                       dma_free_coherent(&dd->pcidev->dev, amt,
+                                         pd->port_rcvhdrq, pd->port_rcvhdrq_phys);
+                       pd->port_rcvhdrq = NULL;
                        goto bail;
                }
                pd->port_rcvhdrqtailaddr_phys = phys_hdrqtail;
@@ -1347,12 +1461,13 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
                ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; "
                           "hdrtailaddr@%p %llx physical\n",
                           pd->port_port, pd->port_rcvhdrq,
-                          pd->port_rcvhdrq_phys, pd->port_rcvhdrtail_kvaddr,
-                          (unsigned long long)pd->port_rcvhdrqtailaddr_phys);
+                          (unsigned long long) pd->port_rcvhdrq_phys,
+                          pd->port_rcvhdrtail_kvaddr, (unsigned long long)
+                          pd->port_rcvhdrqtailaddr_phys);
 
        /* clear for security and sanity on each use */
        memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size);
-       memset((void *)pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE);
+       memset(pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE);
 
        /*
         * tell chip each time we init it, even if we are re-using previous
@@ -1805,7 +1920,7 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd)
                pd->port_rcvhdrq = NULL;
                if (pd->port_rcvhdrtail_kvaddr) {
                        dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
-                                        (void *)pd->port_rcvhdrtail_kvaddr,
+                                        pd->port_rcvhdrtail_kvaddr,
                                         pd->port_rcvhdrqtailaddr_phys);
                        pd->port_rcvhdrtail_kvaddr = NULL;
                }
@@ -1824,24 +1939,32 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd)
                        dma_free_coherent(&dd->pcidev->dev, size,
                                base, pd->port_rcvegrbuf_phys[e]);
                }
-               vfree(pd->port_rcvegrbuf);
+               kfree(pd->port_rcvegrbuf);
                pd->port_rcvegrbuf = NULL;
-               vfree(pd->port_rcvegrbuf_phys);
+               kfree(pd->port_rcvegrbuf_phys);
                pd->port_rcvegrbuf_phys = NULL;
                pd->port_rcvegrbuf_chunks = 0;
-       } else if (pd->port_port == 0 && dd->ipath_port0_skbs) {
+       } else if (pd->port_port == 0 && dd->ipath_port0_skbinfo) {
                unsigned e;
-               struct sk_buff **skbs = dd->ipath_port0_skbs;
+               struct ipath_skbinfo *skbinfo = dd->ipath_port0_skbinfo;
 
-               dd->ipath_port0_skbs = NULL;
-               ipath_cdbg(VERBOSE, "free closed port %d ipath_port0_skbs "
-                          "@ %p\n", pd->port_port, skbs);
+               dd->ipath_port0_skbinfo = NULL;
+               ipath_cdbg(VERBOSE, "free closed port %d "
+                          "ipath_port0_skbinfo @ %p\n", pd->port_port,
+                          skbinfo);
                for (e = 0; e < dd->ipath_rcvegrcnt; e++)
-                       if (skbs[e])
-                               dev_kfree_skb(skbs[e]);
-               vfree(skbs);
+               if (skbinfo[e].skb) {
+                       pci_unmap_single(dd->pcidev, skbinfo[e].phys,
+                                        dd->ipath_ibmaxlen,
+                                        PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb(skbinfo[e].skb);
+               }
+               vfree(skbinfo);
        }
        kfree(pd->port_tid_pg_list);
+       vfree(pd->subport_uregbase);
+       vfree(pd->subport_rcvegrbuf);
+       vfree(pd->subport_rcvhdr_base);
        kfree(pd);
 }
 
@@ -1907,150 +2030,12 @@ bail:
        return ret;
 }
 
-static void cleanup_device(struct ipath_devdata *dd)
-{
-       int port;
-
-       ipath_shutdown_device(dd);
-
-       if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
-               /* can't do anything more with chip; needs re-init */
-               *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
-               if (dd->ipath_kregbase) {
-                       /*
-                        * if we haven't already cleaned up before these are
-                        * to ensure any register reads/writes "fail" until
-                        * re-init
-                        */
-                       dd->ipath_kregbase = NULL;
-                       dd->ipath_uregbase = 0;
-                       dd->ipath_sregbase = 0;
-                       dd->ipath_cregbase = 0;
-                       dd->ipath_kregsize = 0;
-               }
-               ipath_disable_wc(dd);
-       }
-
-       if (dd->ipath_pioavailregs_dma) {
-               dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
-                                 (void *) dd->ipath_pioavailregs_dma,
-                                 dd->ipath_pioavailregs_phys);
-               dd->ipath_pioavailregs_dma = NULL;
-       }
-       if (dd->ipath_dummy_hdrq) {
-               dma_free_coherent(&dd->pcidev->dev,
-                       dd->ipath_pd[0]->port_rcvhdrq_size,
-                       dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
-               dd->ipath_dummy_hdrq = NULL;
-       }
-
-       if (dd->ipath_pageshadow) {
-               struct page **tmpp = dd->ipath_pageshadow;
-               int i, cnt = 0;
-
-               ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
-                          "locked\n");
-               for (port = 0; port < dd->ipath_cfgports; port++) {
-                       int port_tidbase = port * dd->ipath_rcvtidcnt;
-                       int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
-                       for (i = port_tidbase; i < maxtid; i++) {
-                               if (!tmpp[i])
-                                       continue;
-                               ipath_release_user_pages(&tmpp[i], 1);
-                               tmpp[i] = NULL;
-                               cnt++;
-                       }
-               }
-               if (cnt) {
-                       ipath_stats.sps_pageunlocks += cnt;
-                       ipath_cdbg(VERBOSE, "There were still %u expTID "
-                                  "entries locked\n", cnt);
-               }
-               if (ipath_stats.sps_pagelocks ||
-                   ipath_stats.sps_pageunlocks)
-                       ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
-                                  "unlocked via ipath_m{un}lock\n",
-                                  (unsigned long long)
-                                  ipath_stats.sps_pagelocks,
-                                  (unsigned long long)
-                                  ipath_stats.sps_pageunlocks);
-
-               ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
-                          dd->ipath_pageshadow);
-               vfree(dd->ipath_pageshadow);
-               dd->ipath_pageshadow = NULL;
-       }
-
-       /*
-        * free any resources still in use (usually just kernel ports)
-        * at unload; we do for portcnt, not cfgports, because cfgports
-        * could have changed while we were loaded.
-        */
-       for (port = 0; port < dd->ipath_portcnt; port++) {
-               struct ipath_portdata *pd = dd->ipath_pd[port];
-               dd->ipath_pd[port] = NULL;
-               ipath_free_pddata(dd, pd);
-       }
-       kfree(dd->ipath_pd);
-       /*
-        * debuggability, in case some cleanup path tries to use it
-        * after this
-        */
-       dd->ipath_pd = NULL;
-}
-
 static void __exit infinipath_cleanup(void)
 {
-       struct ipath_devdata *dd, *tmp;
-       unsigned long flags;
-
-       ipath_diagpkt_remove();
-
        ipath_exit_ipathfs();
 
        ipath_driver_remove_group(&ipath_driver.driver);
 
-       spin_lock_irqsave(&ipath_devs_lock, flags);
-
-       /*
-        * turn off rcv, send, and interrupts for all ports, all drivers
-        * should also hard reset the chip here?
-        * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
-        * for all versions of the driver, if they were allocated
-        */
-       list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
-               spin_unlock_irqrestore(&ipath_devs_lock, flags);
-
-               if (dd->ipath_kregbase)
-                       cleanup_device(dd);
-
-               if (dd->pcidev) {
-                       if (dd->pcidev->irq) {
-                               ipath_cdbg(VERBOSE,
-                                          "unit %u free_irq of irq %x\n",
-                                          dd->ipath_unit, dd->pcidev->irq);
-                               free_irq(dd->pcidev->irq, dd);
-                       } else
-                               ipath_dbg("irq is 0, not doing free_irq "
-                                         "for unit %u\n", dd->ipath_unit);
-
-                       /*
-                        * we check for NULL here, because it's outside
-                        * the kregbase check, and we need to call it
-                        * after the free_irq.  Thus it's possible that
-                        * the function pointers were never initialized.
-                        */
-                       if (dd->ipath_f_cleanup)
-                               /* clean up chip-specific stuff */
-                               dd->ipath_f_cleanup(dd);
-
-                       dd->pcidev = NULL;
-               }
-               spin_lock_irqsave(&ipath_devs_lock, flags);
-       }
-
-       spin_unlock_irqrestore(&ipath_devs_lock, flags);
-
        ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
        pci_unregister_driver(&ipath_driver);
 
index 3313356ab93aa13d1c6b3fe4bb60d543f21402fc..a4019a6b75602c760ef5774ed2216cd33b9d6576 100644 (file)
@@ -100,9 +100,9 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
        gpioval = &dd->ipath_gpio_out;
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        if (line == i2c_line_scl)
-               mask = ipath_gpio_scl;
+               mask = dd->ipath_gpio_scl;
        else
-               mask = ipath_gpio_sda;
+               mask = dd->ipath_gpio_sda;
 
        if (new_line_state == i2c_line_high)
                /* tri-state the output rather than force high */
@@ -119,12 +119,12 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
                write_val = 0x0UL;
 
        if (line == i2c_line_scl) {
-               write_val <<= ipath_gpio_scl_num;
-               *gpioval = *gpioval & ~(1UL << ipath_gpio_scl_num);
+               write_val <<= dd->ipath_gpio_scl_num;
+               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_scl_num);
                *gpioval |= write_val;
        } else {
-               write_val <<= ipath_gpio_sda_num;
-               *gpioval = *gpioval & ~(1UL << ipath_gpio_sda_num);
+               write_val <<= dd->ipath_gpio_sda_num;
+               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_sda_num);
                *gpioval |= write_val;
        }
        ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval);
@@ -157,9 +157,9 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        /* config line to be an input */
        if (line == i2c_line_scl)
-               mask = ipath_gpio_scl;
+               mask = dd->ipath_gpio_scl;
        else
-               mask = ipath_gpio_sda;
+               mask = dd->ipath_gpio_sda;
        write_val = read_val & ~mask;
        ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
@@ -187,6 +187,7 @@ bail:
 static void i2c_wait_for_writes(struct ipath_devdata *dd)
 {
        (void)ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch);
+       rmb();
 }
 
 static void scl_out(struct ipath_devdata *dd, u8 bit)
index 29930e22318e5a09f78349fe4c8d9e052db9aa62..a9ddc6911f66f89478740c9b994f66038236c692 100644 (file)
 #include "ipath_kernel.h"
 #include "ipath_common.h"
 
+/*
+ * mmap64 doesn't allow all 64 bits for 32-bit applications
+ * so only use the low 43 bits.
+ */
+#define MMAP64_MASK    0x7FFFFFFFFFFUL
+
 static int ipath_open(struct inode *, struct file *);
 static int ipath_close(struct inode *, struct file *);
 static ssize_t ipath_write(struct file *, const char __user *, size_t,
@@ -57,18 +63,35 @@ static struct file_operations ipath_file_ops = {
        .mmap = ipath_mmap
 };
 
-static int ipath_get_base_info(struct ipath_portdata *pd,
+static int ipath_get_base_info(struct file *fp,
                               void __user *ubase, size_t ubase_size)
 {
+       struct ipath_portdata *pd = port_fp(fp);
        int ret = 0;
        struct ipath_base_info *kinfo = NULL;
        struct ipath_devdata *dd = pd->port_dd;
+       unsigned subport_cnt;
+       int shared, master;
+       size_t sz;
+
+       subport_cnt = pd->port_subport_cnt;
+       if (!subport_cnt) {
+               shared = 0;
+               master = 0;
+               subport_cnt = 1;
+       } else {
+               shared = 1;
+               master = !subport_fp(fp);
+       }
 
-       if (ubase_size < sizeof(*kinfo)) {
+       sz = sizeof(*kinfo);
+       /* If port sharing is not requested, allow the old size structure */
+       if (!shared)
+               sz -= 3 * sizeof(u64);
+       if (ubase_size < sz) {
                ipath_cdbg(PROC,
-                          "Base size %lu, need %lu (version mismatch?)\n",
-                          (unsigned long) ubase_size,
-                          (unsigned long) sizeof(*kinfo));
+                          "Base size %zu, need %zu (version mismatch?)\n",
+                          ubase_size, sz);
                ret = -EINVAL;
                goto bail;
        }
@@ -95,7 +118,9 @@ static int ipath_get_base_info(struct ipath_portdata *pd,
        kinfo->spi_rcv_egrperchunk = pd->port_rcvegrbufs_perchunk;
        kinfo->spi_rcv_egrchunksize = kinfo->spi_rcv_egrbuftotlen /
                pd->port_rcvegrbuf_chunks;
-       kinfo->spi_tidcnt = dd->ipath_rcvtidcnt;
+       kinfo->spi_tidcnt = dd->ipath_rcvtidcnt / subport_cnt;
+       if (master)
+               kinfo->spi_tidcnt += dd->ipath_rcvtidcnt % subport_cnt;
        /*
         * for this use, may be ipath_cfgports summed over all chips that
         * are are configured and present
@@ -118,31 +143,75 @@ static int ipath_get_base_info(struct ipath_portdata *pd,
         * page_address() macro worked, but in 2.6.11, even that returns the
         * full 64 bit address (upper bits all 1's).  So far, using the
         * physical addresses (or chip offsets, for chip mapping) works, but
-        * no doubt some future kernel release will chang that, and we'll be
-        * on to yet another method of dealing with this
+        * no doubt some future kernel release will change that, and we'll be
+        * on to yet another method of dealing with this.
         */
        kinfo->spi_rcvhdr_base = (u64) pd->port_rcvhdrq_phys;
-       kinfo->spi_rcvhdr_tailaddr = (u64)pd->port_rcvhdrqtailaddr_phys;
+       kinfo->spi_rcvhdr_tailaddr = (u64) pd->port_rcvhdrqtailaddr_phys;
        kinfo->spi_rcv_egrbufs = (u64) pd->port_rcvegr_phys;
        kinfo->spi_pioavailaddr = (u64) dd->ipath_pioavailregs_phys;
        kinfo->spi_status = (u64) kinfo->spi_pioavailaddr +
                (void *) dd->ipath_statusp -
                (void *) dd->ipath_pioavailregs_dma;
-       kinfo->spi_piobufbase = (u64) pd->port_piobufs;
-       kinfo->__spi_uregbase =
-               dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+       if (!shared) {
+               kinfo->spi_piocnt = dd->ipath_pbufsport;
+               kinfo->spi_piobufbase = (u64) pd->port_piobufs;
+               kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
+                       dd->ipath_palign * pd->port_port;
+       } else if (master) {
+               kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) +
+                                   (dd->ipath_pbufsport % subport_cnt);
+               /* Master's PIO buffers are after all the slave's */
+               kinfo->spi_piobufbase = (u64) pd->port_piobufs +
+                       dd->ipath_palign *
+                       (dd->ipath_pbufsport - kinfo->spi_piocnt);
+               kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
+                       dd->ipath_palign * pd->port_port;
+       } else {
+               unsigned slave = subport_fp(fp) - 1;
+
+               kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt;
+               kinfo->spi_piobufbase = (u64) pd->port_piobufs +
+                       dd->ipath_palign * kinfo->spi_piocnt * slave;
+               kinfo->__spi_uregbase = ((u64) pd->subport_uregbase +
+                       PAGE_SIZE * slave) & MMAP64_MASK;
 
-       kinfo->spi_pioindex = dd->ipath_pbufsport * (pd->port_port - 1);
-       kinfo->spi_piocnt = dd->ipath_pbufsport;
+               kinfo->spi_rcvhdr_base = ((u64) pd->subport_rcvhdr_base +
+                       pd->port_rcvhdrq_size * slave) & MMAP64_MASK;
+               kinfo->spi_rcvhdr_tailaddr =
+                       (u64) pd->port_rcvhdrqtailaddr_phys & MMAP64_MASK;
+               kinfo->spi_rcv_egrbufs = ((u64) pd->subport_rcvegrbuf +
+                       dd->ipath_rcvegrcnt * dd->ipath_rcvegrbufsize * slave) &
+                       MMAP64_MASK;
+       }
+
+       kinfo->spi_pioindex = (kinfo->spi_piobufbase - dd->ipath_piobufbase) /
+               dd->ipath_palign;
        kinfo->spi_pioalign = dd->ipath_palign;
 
        kinfo->spi_qpair = IPATH_KD_QP;
        kinfo->spi_piosize = dd->ipath_ibmaxlen;
        kinfo->spi_mtu = dd->ipath_ibmaxlen;    /* maxlen, not ibmtu */
        kinfo->spi_port = pd->port_port;
+       kinfo->spi_subport = subport_fp(fp);
        kinfo->spi_sw_version = IPATH_KERN_SWVERSION;
        kinfo->spi_hw_version = dd->ipath_revision;
 
+       if (master) {
+               kinfo->spi_runtime_flags |= IPATH_RUNTIME_MASTER;
+               kinfo->spi_subport_uregbase =
+                       (u64) pd->subport_uregbase & MMAP64_MASK;
+               kinfo->spi_subport_rcvegrbuf =
+                       (u64) pd->subport_rcvegrbuf & MMAP64_MASK;
+               kinfo->spi_subport_rcvhdr_base =
+                       (u64) pd->subport_rcvhdr_base & MMAP64_MASK;
+               ipath_cdbg(PROC, "port %u flags %x %llx %llx %llx\n",
+                       kinfo->spi_port, kinfo->spi_runtime_flags,
+                       (unsigned long long) kinfo->spi_subport_uregbase,
+                       (unsigned long long) kinfo->spi_subport_rcvegrbuf,
+                       (unsigned long long) kinfo->spi_subport_rcvhdr_base);
+       }
+
        if (copy_to_user(ubase, kinfo, sizeof(*kinfo)))
                ret = -EFAULT;
 
@@ -154,6 +223,7 @@ bail:
 /**
  * ipath_tid_update - update a port TID
  * @pd: the port
+ * @fp: the ipath device file
  * @ti: the TID information
  *
  * The new implementation as of Oct 2004 is that the driver assigns
@@ -176,11 +246,11 @@ bail:
  * virtually contiguous pages, that should change to improve
  * performance.
  */
-static int ipath_tid_update(struct ipath_portdata *pd,
+static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
                            const struct ipath_tid_info *ti)
 {
        int ret = 0, ntids;
-       u32 tid, porttid, cnt, i, tidcnt;
+       u32 tid, porttid, cnt, i, tidcnt, tidoff;
        u16 *tidlist;
        struct ipath_devdata *dd = pd->port_dd;
        u64 physaddr;
@@ -188,6 +258,7 @@ static int ipath_tid_update(struct ipath_portdata *pd,
        u64 __iomem *tidbase;
        unsigned long tidmap[8];
        struct page **pagep = NULL;
+       unsigned subport = subport_fp(fp);
 
        if (!dd->ipath_pageshadow) {
                ret = -ENOMEM;
@@ -204,20 +275,34 @@ static int ipath_tid_update(struct ipath_portdata *pd,
                ret = -EFAULT;
                goto done;
        }
-       tidcnt = dd->ipath_rcvtidcnt;
-       if (cnt >= tidcnt) {
+       porttid = pd->port_port * dd->ipath_rcvtidcnt;
+       if (!pd->port_subport_cnt) {
+               tidcnt = dd->ipath_rcvtidcnt;
+               tid = pd->port_tidcursor;
+               tidoff = 0;
+       } else if (!subport) {
+               tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
+                        (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
+               tidoff = dd->ipath_rcvtidcnt - tidcnt;
+               porttid += tidoff;
+               tid = tidcursor_fp(fp);
+       } else {
+               tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
+               tidoff = tidcnt * (subport - 1);
+               porttid += tidoff;
+               tid = tidcursor_fp(fp);
+       }
+       if (cnt > tidcnt) {
                /* make sure it all fits in port_tid_pg_list */
                dev_info(&dd->pcidev->dev, "Process tried to allocate %u "
                         "TIDs, only trying max (%u)\n", cnt, tidcnt);
                cnt = tidcnt;
        }
-       pagep = (struct page **)pd->port_tid_pg_list;
-       tidlist = (u16 *) (&pagep[cnt]);
+       pagep = &((struct page **) pd->port_tid_pg_list)[tidoff];
+       tidlist = &((u16 *) &pagep[dd->ipath_rcvtidcnt])[tidoff];
 
        memset(tidmap, 0, sizeof(tidmap));
-       tid = pd->port_tidcursor;
        /* before decrement; chip actual # */
-       porttid = pd->port_port * tidcnt;
        ntids = tidcnt;
        tidbase = (u64 __iomem *) (((char __iomem *) dd->ipath_kregbase) +
                                   dd->ipath_rcvtidbase +
@@ -274,16 +359,19 @@ static int ipath_tid_update(struct ipath_portdata *pd,
                        ret = -ENOMEM;
                        break;
                }
-               tidlist[i] = tid;
+               tidlist[i] = tid + tidoff;
                ipath_cdbg(VERBOSE, "Updating idx %u to TID %u, "
-                          "vaddr %lx\n", i, tid, vaddr);
+                          "vaddr %lx\n", i, tid + tidoff, vaddr);
                /* we "know" system pages and TID pages are same size */
                dd->ipath_pageshadow[porttid + tid] = pagep[i];
+               dd->ipath_physshadow[porttid + tid] = ipath_map_page(
+                       dd->pcidev, pagep[i], 0, PAGE_SIZE,
+                       PCI_DMA_FROMDEVICE);
                /*
                 * don't need atomic or it's overhead
                 */
                __set_bit(tid, tidmap);
-               physaddr = page_to_phys(pagep[i]);
+               physaddr = dd->ipath_physshadow[porttid + tid];
                ipath_stats.sps_pagelocks++;
                ipath_cdbg(VERBOSE,
                           "TID %u, vaddr %lx, physaddr %llx pgp %p\n",
@@ -317,6 +405,9 @@ static int ipath_tid_update(struct ipath_portdata *pd,
                                           tid);
                                dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
                                                    dd->ipath_tidinvalid);
+                               pci_unmap_page(dd->pcidev,
+                                       dd->ipath_physshadow[porttid + tid],
+                                       PAGE_SIZE, PCI_DMA_FROMDEVICE);
                                dd->ipath_pageshadow[porttid + tid] = NULL;
                                ipath_stats.sps_pageunlocks++;
                        }
@@ -341,7 +432,10 @@ static int ipath_tid_update(struct ipath_portdata *pd,
                }
                if (tid == tidcnt)
                        tid = 0;
-               pd->port_tidcursor = tid;
+               if (!pd->port_subport_cnt)
+                       pd->port_tidcursor = tid;
+               else
+                       tidcursor_fp(fp) = tid;
        }
 
 done:
@@ -354,6 +448,7 @@ done:
 /**
  * ipath_tid_free - free a port TID
  * @pd: the port
+ * @subport: the subport
  * @ti: the TID info
  *
  * right now we are unlocking one page at a time, but since
@@ -367,7 +462,7 @@ done:
  * they pass in to us.
  */
 
-static int ipath_tid_free(struct ipath_portdata *pd,
+static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
                          const struct ipath_tid_info *ti)
 {
        int ret = 0;
@@ -388,11 +483,20 @@ static int ipath_tid_free(struct ipath_portdata *pd,
        }
 
        porttid = pd->port_port * dd->ipath_rcvtidcnt;
+       if (!pd->port_subport_cnt)
+               tidcnt = dd->ipath_rcvtidcnt;
+       else if (!subport) {
+               tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
+                        (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
+               porttid += dd->ipath_rcvtidcnt - tidcnt;
+       } else {
+               tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
+               porttid += tidcnt * (subport - 1);
+       }
        tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) +
                                   dd->ipath_rcvtidbase +
                                   porttid * sizeof(*tidbase));
 
-       tidcnt = dd->ipath_rcvtidcnt;
        limit = sizeof(tidmap) * BITS_PER_BYTE;
        if (limit > tidcnt)
                /* just in case size changes in future */
@@ -417,6 +521,9 @@ static int ipath_tid_free(struct ipath_portdata *pd,
                                   pd->port_pid, tid);
                        dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
                                            dd->ipath_tidinvalid);
+                       pci_unmap_page(dd->pcidev,
+                               dd->ipath_physshadow[porttid + tid],
+                               PAGE_SIZE, PCI_DMA_FROMDEVICE);
                        ipath_release_user_pages(
                                &dd->ipath_pageshadow[porttid + tid], 1);
                        dd->ipath_pageshadow[porttid + tid] = NULL;
@@ -581,20 +688,24 @@ bail:
 /**
  * ipath_manage_rcvq - manage a port's receive queue
  * @pd: the port
+ * @subport: the subport
  * @start_stop: action to carry out
  *
  * start_stop == 0 disables receive on the port, for use in queue
  * overflow conditions.  start_stop==1 re-enables, to be used to
  * re-init the software copy of the head register
  */
-static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
+static int ipath_manage_rcvq(struct ipath_portdata *pd, unsigned subport,
+                            int start_stop)
 {
        struct ipath_devdata *dd = pd->port_dd;
        u64 tval;
 
-       ipath_cdbg(PROC, "%sabling rcv for unit %u port %u\n",
+       ipath_cdbg(PROC, "%sabling rcv for unit %u port %u:%u\n",
                   start_stop ? "en" : "dis", dd->ipath_unit,
-                  pd->port_port);
+                  pd->port_port, subport);
+       if (subport)
+               goto bail;
        /* atomically clear receive enable port. */
        if (start_stop) {
                /*
@@ -609,7 +720,7 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
                 * updated and correct itself, even in the face of software
                 * bugs.
                 */
-               *pd->port_rcvhdrtail_kvaddr = 0;
+               *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0;
                set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
                        &dd->ipath_rcvctrl);
        } else
@@ -630,6 +741,7 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop)
                tval = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port);
        }
        /* always; new head should be equal to new tail; see above */
+bail:
        return 0;
 }
 
@@ -687,6 +799,36 @@ static void ipath_clean_part_key(struct ipath_portdata *pd,
        }
 }
 
+/*
+ * Initialize the port data with the receive buffer sizes
+ * so this can be done while the master port is locked.
+ * Otherwise, there is a race with a slave opening the port
+ * and seeing these fields uninitialized.
+ */
+static void init_user_egr_sizes(struct ipath_portdata *pd)
+{
+       struct ipath_devdata *dd = pd->port_dd;
+       unsigned egrperchunk, egrcnt, size;
+
+       /*
+        * to avoid wasting a lot of memory, we allocate 32KB chunks of
+        * physically contiguous memory, advance through it until used up
+        * and then allocate more.  Of course, we need memory to store those
+        * extra pointers, now.  Started out with 256KB, but under heavy
+        * memory pressure (creating large files and then copying them over
+        * NFS while doing lots of MPI jobs), we hit some allocation
+        * failures, even though we can sleep...  (2.6.10) Still get
+        * failures at 64K.  32K is the lowest we can go without wasting
+        * additional memory.
+        */
+       size = 0x8000;
+       egrperchunk = size / dd->ipath_rcvegrbufsize;
+       egrcnt = dd->ipath_rcvegrcnt;
+       pd->port_rcvegrbuf_chunks = (egrcnt + egrperchunk - 1) / egrperchunk;
+       pd->port_rcvegrbufs_perchunk = egrperchunk;
+       pd->port_rcvegrbuf_size = size;
+}
+
 /**
  * ipath_create_user_egr - allocate eager TID buffers
  * @pd: the port to allocate TID buffers for
@@ -702,7 +844,7 @@ static void ipath_clean_part_key(struct ipath_portdata *pd,
 static int ipath_create_user_egr(struct ipath_portdata *pd)
 {
        struct ipath_devdata *dd = pd->port_dd;
-       unsigned e, egrcnt, alloced, egrperchunk, chunk, egrsize, egroff;
+       unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
        size_t size;
        int ret;
        gfp_t gfp_flags;
@@ -722,31 +864,18 @@ static int ipath_create_user_egr(struct ipath_portdata *pd)
        ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid "
                   "offset %x, egrsize %u\n", egrcnt, egroff, egrsize);
 
-       /*
-        * to avoid wasting a lot of memory, we allocate 32KB chunks of
-        * physically contiguous memory, advance through it until used up
-        * and then allocate more.  Of course, we need memory to store those
-        * extra pointers, now.  Started out with 256KB, but under heavy
-        * memory pressure (creating large files and then copying them over
-        * NFS while doing lots of MPI jobs), we hit some allocation
-        * failures, even though we can sleep...  (2.6.10) Still get
-        * failures at 64K.  32K is the lowest we can go without wasting
-        * additional memory.
-        */
-       size = 0x8000;
-       alloced = ALIGN(egrsize * egrcnt, size);
-       egrperchunk = size / egrsize;
-       chunk = (egrcnt + egrperchunk - 1) / egrperchunk;
-       pd->port_rcvegrbuf_chunks = chunk;
-       pd->port_rcvegrbufs_perchunk = egrperchunk;
-       pd->port_rcvegrbuf_size = size;
-       pd->port_rcvegrbuf = vmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]));
+       chunk = pd->port_rcvegrbuf_chunks;
+       egrperchunk = pd->port_rcvegrbufs_perchunk;
+       size = pd->port_rcvegrbuf_size;
+       pd->port_rcvegrbuf = kmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]),
+                                    GFP_KERNEL);
        if (!pd->port_rcvegrbuf) {
                ret = -ENOMEM;
                goto bail;
        }
        pd->port_rcvegrbuf_phys =
-               vmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]));
+               kmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]),
+                       GFP_KERNEL);
        if (!pd->port_rcvegrbuf_phys) {
                ret = -ENOMEM;
                goto bail_rcvegrbuf;
@@ -791,105 +920,23 @@ bail_rcvegrbuf_phys:
                                  pd->port_rcvegrbuf_phys[e]);
 
        }
-       vfree(pd->port_rcvegrbuf_phys);
+       kfree(pd->port_rcvegrbuf_phys);
        pd->port_rcvegrbuf_phys = NULL;
 bail_rcvegrbuf:
-       vfree(pd->port_rcvegrbuf);
+       kfree(pd->port_rcvegrbuf);
        pd->port_rcvegrbuf = NULL;
 bail:
        return ret;
 }
 
-static int ipath_do_user_init(struct ipath_portdata *pd,
-                             const struct ipath_user_info *uinfo)
-{
-       int ret = 0;
-       struct ipath_devdata *dd = pd->port_dd;
-       u32 head32;
-
-       /* for now, if major version is different, bail */
-       if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) {
-               dev_info(&dd->pcidev->dev,
-                        "User major version %d not same as driver "
-                        "major %d\n", uinfo->spu_userversion >> 16,
-                        IPATH_USER_SWMAJOR);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR)
-               ipath_dbg("User minor version %d not same as driver "
-                         "minor %d\n", uinfo->spu_userversion & 0xffff,
-                         IPATH_USER_SWMINOR);
-
-       if (uinfo->spu_rcvhdrsize) {
-               ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize);
-               if (ret)
-                       goto done;
-       }
-
-       /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
-
-       /* for right now, kernel piobufs are at end, so port 1 is at 0 */
-       pd->port_piobufs = dd->ipath_piobufbase +
-               dd->ipath_pbufsport * (pd->port_port -
-                                      1) * dd->ipath_palign;
-       ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
-                  pd->port_port, pd->port_piobufs);
-
-       /*
-        * Now allocate the rcvhdr Q and eager TIDs; skip the TID
-        * array for time being.  If pd->port_port > chip-supported,
-        * we need to do extra stuff here to handle by handling overflow
-        * through port 0, someday
-        */
-       ret = ipath_create_rcvhdrq(dd, pd);
-       if (!ret)
-               ret = ipath_create_user_egr(pd);
-       if (ret)
-               goto done;
-
-       /*
-        * set the eager head register for this port to the current values
-        * of the tail pointers, since we don't know if they were
-        * updated on last use of the port.
-        */
-       head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port);
-       ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port);
-       dd->ipath_lastegrheads[pd->port_port] = -1;
-       dd->ipath_lastrcvhdrqtails[pd->port_port] = -1;
-       ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n",
-               pd->port_port, head32);
-       pd->port_tidcursor = 0; /* start at beginning after open */
-       /*
-        * now enable the port; the tail registers will be written to memory
-        * by the chip as soon as it sees the write to
-        * dd->ipath_kregs->kr_rcvctrl.  The update only happens on
-        * transition from 0 to 1, so clear it first, then set it as part of
-        * enabling the port.  This will (very briefly) affect any other
-        * open ports, but it shouldn't be long enough to be an issue.
-        * We explictly set the in-memory copy to 0 beforehand, so we don't
-        * have to wait to be sure the DMA update has happened.
-        */
-       *pd->port_rcvhdrtail_kvaddr = 0ULL;
-       set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
-               &dd->ipath_rcvctrl);
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
-                        dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD);
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
-                        dd->ipath_rcvctrl);
-done:
-       return ret;
-}
-
 
 /* common code for the mappings on dma_alloc_coherent mem */
 static int ipath_mmap_mem(struct vm_area_struct *vma,
-                            struct ipath_portdata *pd, unsigned len,
-                            int write_ok, dma_addr_t addr, char *what)
+       struct ipath_portdata *pd, unsigned len, int write_ok,
+       void *kvaddr, char *what)
 {
        struct ipath_devdata *dd = pd->port_dd;
-       unsigned pfn = (unsigned long)addr >> PAGE_SHIFT;
+       unsigned long pfn;
        int ret;
 
        if ((vma->vm_end - vma->vm_start) > len) {
@@ -912,17 +959,17 @@ static int ipath_mmap_mem(struct vm_area_struct *vma,
                vma->vm_flags &= ~VM_MAYWRITE;
        }
 
+       pfn = virt_to_phys(kvaddr) >> PAGE_SHIFT;
        ret = remap_pfn_range(vma, vma->vm_start, pfn,
                              len, vma->vm_page_prot);
        if (ret)
-               dev_info(&dd->pcidev->dev,
-                        "%s port%u mmap of %lx, %x bytes r%c failed: %d\n",
-                        what, pd->port_port, (unsigned long)addr, len,
-                        write_ok?'w':'o', ret);
+               dev_info(&dd->pcidev->dev, "%s port%u mmap of %lx, %x "
+                        "bytes r%c failed: %d\n", what, pd->port_port,
+                        pfn, len, write_ok?'w':'o', ret);
        else
-               ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes r%c\n",
-                       what, pd->port_port, (unsigned long)addr, len,
-                        write_ok?'w':'o');
+               ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes "
+                          "r%c\n", what, pd->port_port, pfn, len,
+                          write_ok?'w':'o');
 bail:
        return ret;
 }
@@ -957,7 +1004,8 @@ static int mmap_ureg(struct vm_area_struct *vma, struct ipath_devdata *dd,
 
 static int mmap_piobufs(struct vm_area_struct *vma,
                        struct ipath_devdata *dd,
-                       struct ipath_portdata *pd)
+                       struct ipath_portdata *pd,
+                       unsigned piobufs, unsigned piocnt)
 {
        unsigned long phys;
        int ret;
@@ -968,16 +1016,15 @@ static int mmap_piobufs(struct vm_area_struct *vma,
         * process data, and catches users who might try to read the i/o
         * space due to a bug.
         */
-       if ((vma->vm_end - vma->vm_start) >
-           (dd->ipath_pbufsport * dd->ipath_palign)) {
+       if ((vma->vm_end - vma->vm_start) > (piocnt * dd->ipath_palign)) {
                dev_info(&dd->pcidev->dev, "FAIL mmap piobufs: "
                         "reqlen %lx > PAGE\n",
                         vma->vm_end - vma->vm_start);
-               ret = -EFAULT;
+               ret = -EINVAL;
                goto bail;
        }
 
-       phys = dd->ipath_physaddr + pd->port_piobufs;
+       phys = dd->ipath_physaddr + piobufs;
 
        /*
         * Don't mark this as non-cached, or we don't get the
@@ -1011,7 +1058,7 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
        struct ipath_devdata *dd = pd->port_dd;
        unsigned long start, size;
        size_t total_size, i;
-       dma_addr_t *phys;
+       unsigned long pfn;
        int ret;
 
        size = pd->port_rcvegrbuf_size;
@@ -1021,7 +1068,7 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
                         "reqlen %lx > actual %lx\n",
                         vma->vm_end - vma->vm_start,
                         (unsigned long) total_size);
-               ret = -EFAULT;
+               ret = -EINVAL;
                goto bail;
        }
 
@@ -1035,11 +1082,11 @@ static int mmap_rcvegrbufs(struct vm_area_struct *vma,
        vma->vm_flags &= ~VM_MAYWRITE;
 
        start = vma->vm_start;
-       phys = pd->port_rcvegrbuf_phys;
 
        for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) {
-               ret = remap_pfn_range(vma, start, phys[i] >> PAGE_SHIFT,
-                                     size, vma->vm_page_prot);
+               pfn = virt_to_phys(pd->port_rcvegrbuf[i]) >> PAGE_SHIFT;
+               ret = remap_pfn_range(vma, start, pfn, size,
+                                     vma->vm_page_prot);
                if (ret < 0)
                        goto bail;
        }
@@ -1049,6 +1096,122 @@ bail:
        return ret;
 }
 
+/*
+ * ipath_file_vma_nopage - handle a VMA page fault.
+ */
+static struct page *ipath_file_vma_nopage(struct vm_area_struct *vma,
+                                         unsigned long address, int *type)
+{
+       unsigned long offset = address - vma->vm_start;
+       struct page *page = NOPAGE_SIGBUS;
+       void *pageptr;
+
+       /*
+        * Convert the vmalloc address into a struct page.
+        */
+       pageptr = (void *)(offset + (vma->vm_pgoff << PAGE_SHIFT));
+       page = vmalloc_to_page(pageptr);
+       if (!page)
+               goto out;
+
+       /* Increment the reference count. */
+       get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
+out:
+       return page;
+}
+
+static struct vm_operations_struct ipath_file_vm_ops = {
+       .nopage = ipath_file_vma_nopage,
+};
+
+static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
+                      struct ipath_portdata *pd, unsigned subport)
+{
+       unsigned long len;
+       struct ipath_devdata *dd;
+       void *addr;
+       size_t size;
+       int ret;
+
+       /* If the port is not shared, all addresses should be physical */
+       if (!pd->port_subport_cnt) {
+               ret = -EINVAL;
+               goto bail;
+       }
+
+       dd = pd->port_dd;
+       size = pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size;
+
+       /*
+        * Master has all the slave uregbase, rcvhdrq, and
+        * rcvegrbufs mmapped.
+        */
+       if (subport == 0) {
+               unsigned num_slaves = pd->port_subport_cnt - 1;
+
+               if (pgaddr == ((u64) pd->subport_uregbase & MMAP64_MASK)) {
+                       addr = pd->subport_uregbase;
+                       size = PAGE_SIZE * num_slaves;
+               } else if (pgaddr == ((u64) pd->subport_rcvhdr_base &
+                                     MMAP64_MASK)) {
+                       addr = pd->subport_rcvhdr_base;
+                       size = pd->port_rcvhdrq_size * num_slaves;
+               } else if (pgaddr == ((u64) pd->subport_rcvegrbuf &
+                                     MMAP64_MASK)) {
+                       addr = pd->subport_rcvegrbuf;
+                       size *= num_slaves;
+               } else {
+                       ret = -EINVAL;
+                       goto bail;
+               }
+       } else if (pgaddr == (((u64) pd->subport_uregbase +
+                              PAGE_SIZE * (subport - 1)) & MMAP64_MASK)) {
+               addr = pd->subport_uregbase + PAGE_SIZE * (subport - 1);
+               size = PAGE_SIZE;
+       } else if (pgaddr == (((u64) pd->subport_rcvhdr_base +
+                              pd->port_rcvhdrq_size * (subport - 1)) &
+                             MMAP64_MASK)) {
+               addr = pd->subport_rcvhdr_base +
+                       pd->port_rcvhdrq_size * (subport - 1);
+               size = pd->port_rcvhdrq_size;
+       } else if (pgaddr == (((u64) pd->subport_rcvegrbuf +
+                              size * (subport - 1)) & MMAP64_MASK)) {
+               addr = pd->subport_rcvegrbuf + size * (subport - 1);
+               /* rcvegrbufs are read-only on the slave */
+               if (vma->vm_flags & VM_WRITE) {
+                       dev_info(&dd->pcidev->dev,
+                                "Can't map eager buffers as "
+                                "writable (flags=%lx)\n", vma->vm_flags);
+                       ret = -EPERM;
+                       goto bail;
+               }
+               /*
+                * Don't allow permission to later change to writeable
+                * with mprotect.
+                */
+               vma->vm_flags &= ~VM_MAYWRITE;
+       } else {
+               ret = -EINVAL;
+               goto bail;
+       }
+       len = vma->vm_end - vma->vm_start;
+       if (len > size) {
+               ipath_cdbg(MM, "FAIL: reqlen %lx > %zx\n", len, size);
+               ret = -EINVAL;
+               goto bail;
+       }
+
+       vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
+       vma->vm_ops = &ipath_file_vm_ops;
+       vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+       ret = 0;
+
+bail:
+       return ret;
+}
+
 /**
  * ipath_mmap - mmap various structures into user space
  * @fp: the file pointer
@@ -1064,73 +1227,99 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
        struct ipath_portdata *pd;
        struct ipath_devdata *dd;
        u64 pgaddr, ureg;
+       unsigned piobufs, piocnt;
        int ret;
 
        pd = port_fp(fp);
+       if (!pd) {
+               ret = -EINVAL;
+               goto bail;
+       }
        dd = pd->port_dd;
 
        /*
         * This is the ipath_do_user_init() code, mapping the shared buffers
         * into the user process. The address referred to by vm_pgoff is the
-        * virtual, not physical, address; we only do one mmap for each
-        * space mapped.
+        * file offset passed via mmap().  For shared ports, this is the
+        * kernel vmalloc() address of the pages to share with the master.
+        * For non-shared or master ports, this is a physical address.
+        * We only do one mmap for each space mapped.
         */
        pgaddr = vma->vm_pgoff << PAGE_SHIFT;
 
        /*
-        * Must fit in 40 bits for our hardware; some checked elsewhere,
-        * but we'll be paranoid.  Check for 0 is mostly in case one of the
-        * allocations failed, but user called mmap anyway.   We want to catch
-        * that before it can match.
+        * Check for 0 in case one of the allocations failed, but user
+        * called mmap anyway.
         */
-       if (!pgaddr || pgaddr >= (1ULL<<40))  {
-               ipath_dev_err(dd, "Bad phys addr %llx, start %lx, end %lx\n",
-                       (unsigned long long)pgaddr, vma->vm_start, vma->vm_end);
-               return -EINVAL;
+       if (!pgaddr)  {
+               ret = -EINVAL;
+               goto bail;
        }
 
-       /* just the offset of the port user registers, not physical addr */
-       ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
-
-       ipath_cdbg(MM, "ushare: pgaddr %llx vm_start=%lx, vmlen %lx\n",
+       ipath_cdbg(MM, "pgaddr %llx vm_start=%lx len %lx port %u:%u:%u\n",
                   (unsigned long long) pgaddr, vma->vm_start,
-                  vma->vm_end - vma->vm_start);
+                  vma->vm_end - vma->vm_start, dd->ipath_unit,
+                  pd->port_port, subport_fp(fp));
 
-       if (vma->vm_start & (PAGE_SIZE-1)) {
-               ipath_dev_err(dd,
-                       "vm_start not aligned: %lx, end=%lx phys %lx\n",
-                       vma->vm_start, vma->vm_end, (unsigned long)pgaddr);
-               ret = -EINVAL;
+       /*
+        * Physical addresses must fit in 40 bits for our hardware.
+        * Check for kernel virtual addresses first, anything else must
+        * match a HW or memory address.
+        */
+       if (pgaddr >= (1ULL<<40)) {
+               ret = mmap_kvaddr(vma, pgaddr, pd, subport_fp(fp));
+               goto bail;
        }
-       else if (pgaddr == ureg)
+
+       if (!pd->port_subport_cnt) {
+               /* port is not shared */
+               ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+               piocnt = dd->ipath_pbufsport;
+               piobufs = pd->port_piobufs;
+       } else if (!subport_fp(fp)) {
+               /* caller is the master */
+               ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port;
+               piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) +
+                        (dd->ipath_pbufsport % pd->port_subport_cnt);
+               piobufs = pd->port_piobufs +
+                       dd->ipath_palign * (dd->ipath_pbufsport - piocnt);
+       } else {
+               unsigned slave = subport_fp(fp) - 1;
+
+               /* caller is a slave */
+               ureg = 0;
+               piocnt = dd->ipath_pbufsport / pd->port_subport_cnt;
+               piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave;
+       }
+
+       if (pgaddr == ureg)
                ret = mmap_ureg(vma, dd, ureg);
-       else if (pgaddr == pd->port_piobufs)
-               ret = mmap_piobufs(vma, dd, pd);
-       else if (pgaddr == (u64) pd->port_rcvegr_phys)
+       else if (pgaddr == piobufs)
+               ret = mmap_piobufs(vma, dd, pd, piobufs, piocnt);
+       else if (pgaddr == dd->ipath_pioavailregs_phys)
+               /* in-memory copy of pioavail registers */
+               ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
+                                    (void *) dd->ipath_pioavailregs_dma,
+                                    "pioavail registers");
+       else if (subport_fp(fp))
+               /* Subports don't mmap the physical receive buffers */
+               ret = -EINVAL;
+       else if (pgaddr == pd->port_rcvegr_phys)
                ret = mmap_rcvegrbufs(vma, pd);
-       else if (pgaddr == (u64) pd->port_rcvhdrq_phys) {
+       else if (pgaddr == (u64) pd->port_rcvhdrq_phys)
                /*
                 * The rcvhdrq itself; readonly except on HT (so have
                 * to allow writable mapping), multiple pages, contiguous
                 * from an i/o perspective.
                 */
-               unsigned total_size =
-                       ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize
-                          * sizeof(u32), PAGE_SIZE);
-               ret = ipath_mmap_mem(vma, pd, total_size, 1,
-                                    pd->port_rcvhdrq_phys,
+               ret = ipath_mmap_mem(vma, pd, pd->port_rcvhdrq_size, 1,
+                                    pd->port_rcvhdrq,
                                     "rcvhdrq");
-       }
-       else if (pgaddr == (u64)pd->port_rcvhdrqtailaddr_phys)
+       else if (pgaddr == (u64) pd->port_rcvhdrqtailaddr_phys)
                /* in-memory copy of rcvhdrq tail register */
                ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
-                                    pd->port_rcvhdrqtailaddr_phys,
+                                    pd->port_rcvhdrtail_kvaddr,
                                     "rcvhdrq tail");
-       else if (pgaddr == dd->ipath_pioavailregs_phys)
-               /* in-memory copy of pioavail registers */
-               ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
-                                    dd->ipath_pioavailregs_phys,
-                                    "pioavail registers");
        else
                ret = -EINVAL;
 
@@ -1138,9 +1327,10 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
 
        if (ret < 0)
                dev_info(&dd->pcidev->dev,
-                        "Failure %d on addr %lx, off %lx\n",
-                        -ret, vma->vm_start, vma->vm_pgoff);
-
+                        "Failure %d on off %llx len %lx\n",
+                        -ret, (unsigned long long)pgaddr,
+                        vma->vm_end - vma->vm_start);
+bail:
        return ret;
 }
 
@@ -1154,6 +1344,8 @@ static unsigned int ipath_poll(struct file *fp,
        struct ipath_devdata *dd;
 
        pd = port_fp(fp);
+       if (!pd)
+               goto bail;
        dd = pd->port_dd;
 
        bit = pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT;
@@ -1176,7 +1368,7 @@ static unsigned int ipath_poll(struct file *fp,
 
        if (tail == head) {
                set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
-               if(dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
+               if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
                        (void)ipath_write_ureg(dd, ur_rcvhdrhead,
                                               dd->ipath_rhdrhead_intr_off
                                               | head, pd->port_port);
@@ -1200,18 +1392,80 @@ static unsigned int ipath_poll(struct file *fp,
        ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
                         dd->ipath_rcvctrl);
 
+bail:
        return pollflag;
 }
 
+static int init_subports(struct ipath_devdata *dd,
+                        struct ipath_portdata *pd,
+                        const struct ipath_user_info *uinfo)
+{
+       int ret = 0;
+       unsigned num_slaves;
+       size_t size;
+
+       /* Old user binaries don't know about subports */
+       if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR)
+               goto bail;
+       /*
+        * If the user is requesting zero or one port,
+        * skip the subport allocation.
+        */
+       if (uinfo->spu_subport_cnt <= 1)
+               goto bail;
+       if (uinfo->spu_subport_cnt > 4) {
+               ret = -EINVAL;
+               goto bail;
+       }
+
+       num_slaves = uinfo->spu_subport_cnt - 1;
+       pd->subport_uregbase = vmalloc(PAGE_SIZE * num_slaves);
+       if (!pd->subport_uregbase) {
+               ret = -ENOMEM;
+               goto bail;
+       }
+       /* Note: pd->port_rcvhdrq_size isn't initialized yet. */
+       size = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize *
+                    sizeof(u32), PAGE_SIZE) * num_slaves;
+       pd->subport_rcvhdr_base = vmalloc(size);
+       if (!pd->subport_rcvhdr_base) {
+               ret = -ENOMEM;
+               goto bail_ureg;
+       }
+
+       pd->subport_rcvegrbuf = vmalloc(pd->port_rcvegrbuf_chunks *
+                                       pd->port_rcvegrbuf_size *
+                                       num_slaves);
+       if (!pd->subport_rcvegrbuf) {
+               ret = -ENOMEM;
+               goto bail_rhdr;
+       }
+
+       pd->port_subport_cnt = uinfo->spu_subport_cnt;
+       pd->port_subport_id = uinfo->spu_subport_id;
+       pd->active_slaves = 1;
+       goto bail;
+
+bail_rhdr:
+       vfree(pd->subport_rcvhdr_base);
+bail_ureg:
+       vfree(pd->subport_uregbase);
+       pd->subport_uregbase = NULL;
+bail:
+       return ret;
+}
+
 static int try_alloc_port(struct ipath_devdata *dd, int port,
-                         struct file *fp)
+                         struct file *fp,
+                         const struct ipath_user_info *uinfo)
 {
+       struct ipath_portdata *pd;
        int ret;
 
-       if (!dd->ipath_pd[port]) {
-               void *p, *ptmp;
+       if (!(pd = dd->ipath_pd[port])) {
+               void *ptmp;
 
-               p = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL);
+               pd = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL);
 
                /*
                 * Allocate memory for use in ipath_tid_update() just once
@@ -1221,34 +1475,36 @@ static int try_alloc_port(struct ipath_devdata *dd, int port,
                ptmp = kmalloc(dd->ipath_rcvtidcnt * sizeof(u16) +
                               dd->ipath_rcvtidcnt * sizeof(struct page **),
                               GFP_KERNEL);
-               if (!p || !ptmp) {
+               if (!pd || !ptmp) {
                        ipath_dev_err(dd, "Unable to allocate portdata "
                                      "memory, failing open\n");
                        ret = -ENOMEM;
-                       kfree(p);
+                       kfree(pd);
                        kfree(ptmp);
                        goto bail;
                }
-               dd->ipath_pd[port] = p;
+               dd->ipath_pd[port] = pd;
                dd->ipath_pd[port]->port_port = port;
                dd->ipath_pd[port]->port_dd = dd;
                dd->ipath_pd[port]->port_tid_pg_list = ptmp;
                init_waitqueue_head(&dd->ipath_pd[port]->port_wait);
        }
-       if (!dd->ipath_pd[port]->port_cnt) {
-               dd->ipath_pd[port]->port_cnt = 1;
-               fp->private_data = (void *) dd->ipath_pd[port];
+       if (!pd->port_cnt) {
+               pd->userversion = uinfo->spu_userversion;
+               init_user_egr_sizes(pd);
+               if ((ret = init_subports(dd, pd, uinfo)) != 0)
+                       goto bail;
                ipath_cdbg(PROC, "%s[%u] opened unit:port %u:%u\n",
                           current->comm, current->pid, dd->ipath_unit,
                           port);
-               dd->ipath_pd[port]->port_pid = current->pid;
-               strncpy(dd->ipath_pd[port]->port_comm, current->comm,
-                       sizeof(dd->ipath_pd[port]->port_comm));
+               pd->port_cnt = 1;
+               port_fp(fp) = pd;
+               pd->port_pid = current->pid;
+               strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
                ipath_stats.sps_ports++;
                ret = 0;
-               goto bail;
-       }
-       ret = -EBUSY;
+       } else
+               ret = -EBUSY;
 
 bail:
        return ret;
@@ -1264,7 +1520,8 @@ static inline int usable(struct ipath_devdata *dd)
                                     | IPATH_LINKUNK));
 }
 
-static int find_free_port(int unit, struct file *fp)
+static int find_free_port(int unit, struct file *fp,
+                         const struct ipath_user_info *uinfo)
 {
        struct ipath_devdata *dd = ipath_lookup(unit);
        int ret, i;
@@ -1279,8 +1536,8 @@ static int find_free_port(int unit, struct file *fp)
                goto bail;
        }
 
-       for (i = 0; i < dd->ipath_cfgports; i++) {
-               ret = try_alloc_port(dd, i, fp);
+       for (i = 1; i < dd->ipath_cfgports; i++) {
+               ret = try_alloc_port(dd, i, fp, uinfo);
                if (ret != -EBUSY)
                        goto bail;
        }
@@ -1290,13 +1547,14 @@ bail:
        return ret;
 }
 
-static int find_best_unit(struct file *fp)
+static int find_best_unit(struct file *fp,
+                         const struct ipath_user_info *uinfo)
 {
        int ret = 0, i, prefunit = -1, devmax;
        int maxofallports, npresent, nup;
        int ndev;
 
-       (void) ipath_count_units(&npresent, &nup, &maxofallports);
+       devmax = ipath_count_units(&npresent, &nup, &maxofallports);
 
        /*
         * This code is present to allow a knowledgeable person to
@@ -1343,8 +1601,6 @@ static int find_best_unit(struct file *fp)
 
        if (prefunit != -1)
                devmax = prefunit + 1;
-       else
-               devmax = ipath_count_units(NULL, NULL, NULL);
 recheck:
        for (i = 1; i < maxofallports; i++) {
                for (ndev = prefunit != -1 ? prefunit : 0; ndev < devmax;
@@ -1359,7 +1615,7 @@ recheck:
                                 * next.
                                 */
                                continue;
-                       ret = try_alloc_port(dd, i, fp);
+                       ret = try_alloc_port(dd, i, fp, uinfo);
                        if (!ret)
                                goto done;
                }
@@ -1395,22 +1651,183 @@ done:
        return ret;
 }
 
+static int find_shared_port(struct file *fp,
+                           const struct ipath_user_info *uinfo)
+{
+       int devmax, ndev, i;
+       int ret = 0;
+
+       devmax = ipath_count_units(NULL, NULL, NULL);
+
+       for (ndev = 0; ndev < devmax; ndev++) {
+               struct ipath_devdata *dd = ipath_lookup(ndev);
+
+               if (!dd)
+                       continue;
+               for (i = 1; i < dd->ipath_cfgports; i++) {
+                       struct ipath_portdata *pd = dd->ipath_pd[i];
+
+                       /* Skip ports which are not yet open */
+                       if (!pd || !pd->port_cnt)
+                               continue;
+                       /* Skip port if it doesn't match the requested one */
+                       if (pd->port_subport_id != uinfo->spu_subport_id)
+                               continue;
+                       /* Verify the sharing process matches the master */
+                       if (pd->port_subport_cnt != uinfo->spu_subport_cnt ||
+                           pd->userversion != uinfo->spu_userversion ||
+                           pd->port_cnt >= pd->port_subport_cnt) {
+                               ret = -EINVAL;
+                               goto done;
+                       }
+                       port_fp(fp) = pd;
+                       subport_fp(fp) = pd->port_cnt++;
+                       tidcursor_fp(fp) = 0;
+                       pd->active_slaves |= 1 << subport_fp(fp);
+                       ipath_cdbg(PROC,
+                                  "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
+                                  current->comm, current->pid,
+                                  subport_fp(fp),
+                                  pd->port_comm, pd->port_pid,
+                                  dd->ipath_unit, pd->port_port);
+                       ret = 1;
+                       goto done;
+               }
+       }
+
+done:
+       return ret;
+}
+
 static int ipath_open(struct inode *in, struct file *fp)
 {
-       int ret, user_minor;
+       /* The real work is performed later in ipath_assign_port() */
+       fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
+       return fp->private_data ? 0 : -ENOMEM;
+}
+
+
+/* Get port early, so can set affinity prior to memory allocation */
+static int ipath_assign_port(struct file *fp,
+                             const struct ipath_user_info *uinfo)
+{
+       int ret;
+       int i_minor;
+       unsigned swminor;
+
+       /* Check to be sure we haven't already initialized this file */
+       if (port_fp(fp)) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       /* for now, if major version is different, bail */
+       if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) {
+               ipath_dbg("User major version %d not same as driver "
+                         "major %d\n", uinfo->spu_userversion >> 16,
+                         IPATH_USER_SWMAJOR);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       swminor = uinfo->spu_userversion & 0xffff;
+       if (swminor != IPATH_USER_SWMINOR)
+               ipath_dbg("User minor version %d not same as driver "
+                         "minor %d\n", swminor, IPATH_USER_SWMINOR);
 
        mutex_lock(&ipath_mutex);
 
-       user_minor = iminor(in) - IPATH_USER_MINOR_BASE;
+       if (swminor == IPATH_USER_SWMINOR && uinfo->spu_subport_cnt &&
+           (ret = find_shared_port(fp, uinfo))) {
+               mutex_unlock(&ipath_mutex);
+               if (ret > 0)
+                       ret = 0;
+               goto done;
+       }
+
+       i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE;
        ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
-                  (long)in->i_rdev, user_minor);
+                  (long)fp->f_dentry->d_inode->i_rdev, i_minor);
 
-       if (user_minor)
-               ret = find_free_port(user_minor - 1, fp);
+       if (i_minor)
+               ret = find_free_port(i_minor - 1, fp, uinfo);
        else
-               ret = find_best_unit(fp);
+               ret = find_best_unit(fp, uinfo);
 
        mutex_unlock(&ipath_mutex);
+
+done:
+       return ret;
+}
+
+
+static int ipath_do_user_init(struct file *fp,
+                             const struct ipath_user_info *uinfo)
+{
+       int ret;
+       struct ipath_portdata *pd;
+       struct ipath_devdata *dd;
+       u32 head32;
+
+       pd = port_fp(fp);
+       dd = pd->port_dd;
+
+       if (uinfo->spu_rcvhdrsize) {
+               ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize);
+               if (ret)
+                       goto done;
+       }
+
+       /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
+
+       /* for right now, kernel piobufs are at end, so port 1 is at 0 */
+       pd->port_piobufs = dd->ipath_piobufbase +
+               dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign;
+       ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
+                  pd->port_port, pd->port_piobufs);
+
+       /*
+        * Now allocate the rcvhdr Q and eager TIDs; skip the TID
+        * array for time being.  If pd->port_port > chip-supported,
+        * we need to do extra stuff here to handle by handling overflow
+        * through port 0, someday
+        */
+       ret = ipath_create_rcvhdrq(dd, pd);
+       if (!ret)
+               ret = ipath_create_user_egr(pd);
+       if (ret)
+               goto done;
+
+       /*
+        * set the eager head register for this port to the current values
+        * of the tail pointers, since we don't know if they were
+        * updated on last use of the port.
+        */
+       head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port);
+       ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port);
+       dd->ipath_lastegrheads[pd->port_port] = -1;
+       dd->ipath_lastrcvhdrqtails[pd->port_port] = -1;
+       ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n",
+               pd->port_port, head32);
+       pd->port_tidcursor = 0; /* start at beginning after open */
+       /*
+        * now enable the port; the tail registers will be written to memory
+        * by the chip as soon as it sees the write to
+        * dd->ipath_kregs->kr_rcvctrl.  The update only happens on
+        * transition from 0 to 1, so clear it first, then set it as part of
+        * enabling the port.  This will (very briefly) affect any other
+        * open ports, but it shouldn't be long enough to be an issue.
+        * We explictly set the in-memory copy to 0 beforehand, so we don't
+        * have to wait to be sure the DMA update has happened.
+        */
+       *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0ULL;
+       set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port,
+               &dd->ipath_rcvctrl);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
+                        dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
+                        dd->ipath_rcvctrl);
+done:
        return ret;
 }
 
@@ -1433,6 +1850,8 @@ static void unlock_expected_tids(struct ipath_portdata *pd)
                if (!dd->ipath_pageshadow[i])
                        continue;
 
+               pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i],
+                       PAGE_SIZE, PCI_DMA_FROMDEVICE);
                ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i],
                                                  1);
                dd->ipath_pageshadow[i] = NULL;
@@ -1453,6 +1872,7 @@ static void unlock_expected_tids(struct ipath_portdata *pd)
 static int ipath_close(struct inode *in, struct file *fp)
 {
        int ret = 0;
+       struct ipath_filedata *fd;
        struct ipath_portdata *pd;
        struct ipath_devdata *dd;
        unsigned port;
@@ -1462,9 +1882,24 @@ static int ipath_close(struct inode *in, struct file *fp)
 
        mutex_lock(&ipath_mutex);
 
-       pd = port_fp(fp);
-       port = pd->port_port;
+       fd = (struct ipath_filedata *) fp->private_data;
        fp->private_data = NULL;
+       pd = fd->pd;
+       if (!pd) {
+               mutex_unlock(&ipath_mutex);
+               goto bail;
+       }
+       if (--pd->port_cnt) {
+               /*
+                * XXX If the master closes the port before the slave(s),
+                * revoke the mmap for the eager receive queue so
+                * the slave(s) don't wait for receive data forever.
+                */
+               pd->active_slaves &= ~(1 << fd->subport);
+               mutex_unlock(&ipath_mutex);
+               goto bail;
+       }
+       port = pd->port_port;
        dd = pd->port_dd;
 
        if (pd->port_hdrqfull) {
@@ -1503,8 +1938,6 @@ static int ipath_close(struct inode *in, struct file *fp)
 
                /* clean up the pkeys for this port user */
                ipath_clean_part_key(pd, dd);
-
-
                /*
                 * be paranoid, and never write 0's to these, just use an
                 * unused part of the port 0 tail page.  Of course,
@@ -1523,39 +1956,49 @@ static int ipath_close(struct inode *in, struct file *fp)
                i = dd->ipath_pbufsport * (port - 1);
                ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport);
 
+               dd->ipath_f_clear_tids(dd, pd->port_port);
+
                if (dd->ipath_pageshadow)
                        unlock_expected_tids(pd);
                ipath_stats.sps_ports--;
                ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
                           pd->port_comm, pd->port_pid,
                           dd->ipath_unit, port);
-
-               dd->ipath_f_clear_tids(dd, pd->port_port);
        }
 
-       pd->port_cnt = 0;
        pd->port_pid = 0;
-
        dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */
        mutex_unlock(&ipath_mutex);
        ipath_free_pddata(dd, pd); /* after releasing the mutex */
 
+bail:
+       kfree(fd);
        return ret;
 }
 
-static int ipath_port_info(struct ipath_portdata *pd,
+static int ipath_port_info(struct ipath_portdata *pd, u16 subport,
                           struct ipath_port_info __user *uinfo)
 {
        struct ipath_port_info info;
        int nup;
        int ret;
+       size_t sz;
 
        (void) ipath_count_units(NULL, &nup, NULL);
        info.num_active = nup;
        info.unit = pd->port_dd->ipath_unit;
        info.port = pd->port_port;
+       info.subport = subport;
+       /* Don't return new fields if old library opened the port. */
+       if ((pd->userversion & 0xffff) == IPATH_USER_SWMINOR) {
+               /* Number of user ports available for this device. */
+               info.num_ports = pd->port_dd->ipath_cfgports - 1;
+               info.num_subports = pd->port_subport_cnt;
+               sz = sizeof(info);
+       } else
+               sz = sizeof(info) - 2 * sizeof(u16);
 
-       if (copy_to_user(uinfo, &info, sizeof(info))) {
+       if (copy_to_user(uinfo, &info, sz)) {
                ret = -EFAULT;
                goto bail;
        }
@@ -1565,6 +2008,16 @@ bail:
        return ret;
 }
 
+static int ipath_get_slave_info(struct ipath_portdata *pd,
+                               void __user *slave_mask_addr)
+{
+       int ret = 0;
+
+       if (copy_to_user(slave_mask_addr, &pd->active_slaves, sizeof(u32)))
+               ret = -EFAULT;
+       return ret;
+}
+
 static ssize_t ipath_write(struct file *fp, const char __user *data,
                           size_t count, loff_t *off)
 {
@@ -1591,6 +2044,8 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
        consumed = sizeof(cmd.type);
 
        switch (cmd.type) {
+       case IPATH_CMD_ASSIGN_PORT:
+       case __IPATH_CMD_USER_INIT:
        case IPATH_CMD_USER_INIT:
                copy = sizeof(cmd.cmd.user_info);
                dest = &cmd.cmd.user_info;
@@ -1617,6 +2072,11 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
                dest = &cmd.cmd.part_key;
                src = &ucmd->cmd.part_key;
                break;
+       case IPATH_CMD_SLAVE_INFO:
+               copy = sizeof(cmd.cmd.slave_mask_addr);
+               dest = &cmd.cmd.slave_mask_addr;
+               src = &ucmd->cmd.slave_mask_addr;
+               break;
        default:
                ret = -EINVAL;
                goto bail;
@@ -1634,34 +2094,55 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
 
        consumed += copy;
        pd = port_fp(fp);
+       if (!pd && cmd.type != __IPATH_CMD_USER_INIT &&
+               cmd.type != IPATH_CMD_ASSIGN_PORT) {
+               ret = -EINVAL;
+               goto bail;
+       }
 
        switch (cmd.type) {
+       case IPATH_CMD_ASSIGN_PORT:
+               ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+               if (ret)
+                       goto bail;
+               break;
+       case __IPATH_CMD_USER_INIT:
+               /* backwards compatibility, get port first */
+               ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+               if (ret)
+                       goto bail;
+               /* and fall through to current version. */
        case IPATH_CMD_USER_INIT:
-               ret = ipath_do_user_init(pd, &cmd.cmd.user_info);
-               if (ret < 0)
+               ret = ipath_do_user_init(fp, &cmd.cmd.user_info);
+               if (ret)
                        goto bail;
                ret = ipath_get_base_info(
-                       pd, (void __user *) (unsigned long)
+                       fp, (void __user *) (unsigned long)
                        cmd.cmd.user_info.spu_base_info,
                        cmd.cmd.user_info.spu_base_info_size);
                break;
        case IPATH_CMD_RECV_CTRL:
-               ret = ipath_manage_rcvq(pd, cmd.cmd.recv_ctrl);
+               ret = ipath_manage_rcvq(pd, subport_fp(fp), cmd.cmd.recv_ctrl);
                break;
        case IPATH_CMD_PORT_INFO:
-               ret = ipath_port_info(pd,
+               ret = ipath_port_info(pd, subport_fp(fp),
                                      (struct ipath_port_info __user *)
                                      (unsigned long) cmd.cmd.port_info);
                break;
        case IPATH_CMD_TID_UPDATE:
-               ret = ipath_tid_update(pd, &cmd.cmd.tid_info);
+               ret = ipath_tid_update(pd, fp, &cmd.cmd.tid_info);
                break;
        case IPATH_CMD_TID_FREE:
-               ret = ipath_tid_free(pd, &cmd.cmd.tid_info);
+               ret = ipath_tid_free(pd, subport_fp(fp), &cmd.cmd.tid_info);
                break;
        case IPATH_CMD_SET_PART_KEY:
                ret = ipath_set_part_key(pd, cmd.cmd.part_key);
                break;
+       case IPATH_CMD_SLAVE_INFO:
+               ret = ipath_get_slave_info(pd,
+                                          (void __user *) (unsigned long)
+                                          cmd.cmd.slave_mask_addr);
+               break;
        }
 
        if (ret >= 0)
@@ -1858,4 +2339,3 @@ void ipath_user_remove(struct ipath_devdata *dd)
 bail:
        return;
 }
-
index c8a8af0fe47175abfe6c2f07aa36df9d0a07d2a5..a507d0b5be6c9c8bf31e2b4a3b22ed27a1e705c1 100644 (file)
@@ -356,19 +356,16 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
 
        pos = *ppos;
 
-       if ( pos < 0) {
+       if (pos != 0) {
                ret = -EINVAL;
                goto bail;
        }
 
-       if (pos >= sizeof(struct ipath_flash)) {
-               ret = 0;
+       if (count != sizeof(struct ipath_flash)) {
+               ret = -EINVAL;
                goto bail;
        }
 
-       if (count > sizeof(struct ipath_flash) - pos)
-               count = sizeof(struct ipath_flash) - pos;
-
        tmp = kmalloc(count, GFP_KERNEL);
        if (!tmp) {
                ret = -ENOMEM;
index 5c9b509e40e449c24645c72b1418057a5b0d9c00..9e4e8d4c6e2035769ddef2a080a1f7163bef8678 100644 (file)
@@ -252,8 +252,8 @@ static const struct ipath_cregs ipath_ht_cregs = {
 };
 
 /* kr_intstatus, kr_intclear, kr_intmask bits */
-#define INFINIPATH_I_RCVURG_MASK 0x1FF
-#define INFINIPATH_I_RCVAVAIL_MASK 0x1FF
+#define INFINIPATH_I_RCVURG_MASK ((1U<<9)-1)
+#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<9)-1)
 
 /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */
 #define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0
@@ -338,7 +338,7 @@ static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs,
        if (crcbits) {
                u16 ctrl0, ctrl1;
                snprintf(bitsmsg, sizeof bitsmsg,
-                        "[HT%s lane %s CRC (%llx); ignore till reload]",
+                        "[HT%s lane %s CRC (%llx); powercycle to completely clear]",
                         !(crcbits & _IPATH_HTLINK1_CRCBITS) ?
                         "0 (A)" : (!(crcbits & _IPATH_HTLINK0_CRCBITS)
                                    ? "1 (B)" : "0+1 (A+B)"),
@@ -389,17 +389,28 @@ static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs,
                                     _IPATH_HTLINK1_CRCBITS)));
 }
 
+/* 6110 specific hardware errors... */
+static const struct ipath_hwerror_msgs ipath_6110_hwerror_msgs[] = {
+       INFINIPATH_HWE_MSG(HTCBUSIREQPARITYERR, "HTC Ireq Parity"),
+       INFINIPATH_HWE_MSG(HTCBUSTREQPARITYERR, "HTC Treq Parity"),
+       INFINIPATH_HWE_MSG(HTCBUSTRESPPARITYERR, "HTC Tresp Parity"),
+       INFINIPATH_HWE_MSG(HTCMISCERR5, "HT core Misc5"),
+       INFINIPATH_HWE_MSG(HTCMISCERR6, "HT core Misc6"),
+       INFINIPATH_HWE_MSG(HTCMISCERR7, "HT core Misc7"),
+       INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"),
+       INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"),
+};
+
 /**
- * ipath_ht_handle_hwerrors - display hardware errors
+ * ipath_ht_handle_hwerrors - display hardware errors.
  * @dd: the infinipath device
  * @msg: the output buffer
  * @msgl: the size of the output buffer
  *
- * Use same msg buffer as regular errors to avoid
- * excessive stack use.  Most hardware errors are catastrophic, but for
- * right now, we'll print them and continue.
- * We reuse the same message buffer as ipath_handle_errors() to avoid
- * excessive stack usage.
+ * Use same msg buffer as regular errors to avoid excessive stack
+ * use.  Most hardware errors are catastrophic, but for right now,
+ * we'll print them and continue.  We reuse the same message buffer as
+ * ipath_handle_errors() to avoid excessive stack usage.
  */
 static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                                     size_t msgl)
@@ -440,19 +451,49 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
         * make sure we get this much out, unless told to be quiet,
         * or it's occurred within the last 5 seconds
         */
-       if ((hwerrs & ~dd->ipath_lasthwerror) ||
+       if ((hwerrs & ~(dd->ipath_lasthwerror |
+                       ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                         INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                       << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) ||
            (ipath_debug & __IPATH_VERBDBG))
                dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx "
                         "(cleared)\n", (unsigned long long) hwerrs);
        dd->ipath_lasthwerror |= hwerrs;
 
-       if (hwerrs & ~infinipath_hwe_bitsextant)
+       if (hwerrs & ~dd->ipath_hwe_bitsextant)
                ipath_dev_err(dd, "hwerror interrupt with unknown errors "
                              "%llx set\n", (unsigned long long)
-                             (hwerrs & ~infinipath_hwe_bitsextant));
+                             (hwerrs & ~dd->ipath_hwe_bitsextant));
 
        ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
        if (ctrl & INFINIPATH_C_FREEZEMODE) {
+               /*
+                * parity errors in send memory are recoverable,
+                * just cancel the send (if indicated in * sendbuffererror),
+                * count the occurrence, unfreeze (if no other handled
+                * hardware error bits are set), and continue. They can
+                * occur if a processor speculative read is done to the PIO
+                * buffer while we are sending a packet, for example.
+                */
+               if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                              INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                             << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
+                       ipath_stats.sps_txeparity++;
+                       ipath_dbg("Recovering from TXE parity error (%llu), "
+                                 "hwerrstatus=%llx\n",
+                                 (unsigned long long) ipath_stats.sps_txeparity,
+                                 (unsigned long long) hwerrs);
+                       ipath_disarm_senderrbufs(dd);
+                       hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                                    INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                                   << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
+                       if (!hwerrs) { /* else leave in freeze mode */
+                               ipath_write_kreg(dd,
+                                                dd->ipath_kregs->kr_control,
+                                                dd->ipath_control);
+                               return;
+                       }
+               }
                if (hwerrs) {
                        /*
                         * if any set that we aren't ignoring; only
@@ -499,44 +540,16 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                         bits);
                strlcat(msg, bitsmsg, msgl);
        }
-       if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK
-                     << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) {
-               bits = (u32) ((hwerrs >>
-                              INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) &
-                             INFINIPATH_HWE_RXEMEMPARITYERR_MASK);
-               snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ",
-                        bits);
-               strlcat(msg, bitsmsg, msgl);
-       }
-       if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK
-                     << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
-               bits = (u32) ((hwerrs >>
-                              INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) &
-                             INFINIPATH_HWE_TXEMEMPARITYERR_MASK);
-               snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ",
-                        bits);
-               strlcat(msg, bitsmsg, msgl);
-       }
-       if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR)
-               strlcat(msg, "[IB2IPATH Parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR)
-               strlcat(msg, "[IPATH2IB Parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_HTCBUSIREQPARITYERR)
-               strlcat(msg, "[HTC Ireq Parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_HTCBUSTREQPARITYERR)
-               strlcat(msg, "[HTC Treq Parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_HTCBUSTRESPPARITYERR)
-               strlcat(msg, "[HTC Tresp Parity]", msgl);
+
+       ipath_format_hwerrors(hwerrs,
+                             ipath_6110_hwerror_msgs,
+                             sizeof(ipath_6110_hwerror_msgs) /
+                             sizeof(ipath_6110_hwerror_msgs[0]),
+                             msg, msgl);
 
        if (hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS))
                hwerr_crcbits(dd, hwerrs, msg, msgl);
 
-       if (hwerrs & INFINIPATH_HWE_HTCMISCERR5)
-               strlcat(msg, "[HT core Misc5]", msgl);
-       if (hwerrs & INFINIPATH_HWE_HTCMISCERR6)
-               strlcat(msg, "[HT core Misc6]", msgl);
-       if (hwerrs & INFINIPATH_HWE_HTCMISCERR7)
-               strlcat(msg, "[HT core Misc7]", msgl);
        if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) {
                strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]",
                        msgl);
@@ -573,11 +586,6 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                                 dd->ipath_hwerrmask);
        }
 
-       if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR)
-               strlcat(msg, "[Rx Dsync]", msgl);
-       if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED)
-               strlcat(msg, "[SerDes PLL]", msgl);
-
        ipath_dev_err(dd, "%s hardware error\n", msg);
        if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg)
                /*
@@ -1080,21 +1088,21 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
        ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
 }
 
-static void ipath_init_ht_variables(void)
+static void ipath_init_ht_variables(struct ipath_devdata *dd)
 {
-       ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
-       ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
-       ipath_gpio_sda = IPATH_GPIO_SDA;
-       ipath_gpio_scl = IPATH_GPIO_SCL;
+       dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
+       dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
+       dd->ipath_gpio_sda = IPATH_GPIO_SDA;
+       dd->ipath_gpio_scl = IPATH_GPIO_SCL;
 
-       infinipath_i_bitsextant =
+       dd->ipath_i_bitsextant =
                (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) |
                (INFINIPATH_I_RCVAVAIL_MASK <<
                 INFINIPATH_I_RCVAVAIL_SHIFT) |
                INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT |
                INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO;
 
-       infinipath_e_bitsextant =
+       dd->ipath_e_bitsextant =
                INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC |
                INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN |
                INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN |
@@ -1112,7 +1120,7 @@ static void ipath_init_ht_variables(void)
                INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET |
                INFINIPATH_E_HARDWARE;
 
-       infinipath_hwe_bitsextant =
+       dd->ipath_hwe_bitsextant =
                (INFINIPATH_HWE_HTCMEMPARITYERR_MASK <<
                 INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT) |
                (INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
@@ -1141,8 +1149,8 @@ static void ipath_init_ht_variables(void)
                INFINIPATH_HWE_IBCBUSTOSPCPARITYERR |
                INFINIPATH_HWE_IBCBUSFRSPCPARITYERR;
 
-       infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
-       infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+       dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
+       dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
 }
 
 /**
@@ -1607,5 +1615,5 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd)
         * do very early init that is needed before ipath_f_bus is
         * called
         */
-       ipath_init_ht_variables();
+       ipath_init_ht_variables(dd);
 }
index d86516d23df618ef369fb183a061a8f761228754..a72ab9de386a4e0e0d92ae04afa0cba1f7b8f3f7 100644 (file)
@@ -263,8 +263,8 @@ static const struct ipath_cregs ipath_pe_cregs = {
 };
 
 /* kr_intstatus, kr_intclear, kr_intmask bits */
-#define INFINIPATH_I_RCVURG_MASK 0x1F
-#define INFINIPATH_I_RCVAVAIL_MASK 0x1F
+#define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1)
+#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1)
 
 /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */
 #define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK  0x000000000000003fULL
@@ -294,6 +294,33 @@ static const struct ipath_cregs ipath_pe_cregs = {
 #define IPATH_GPIO_SCL (1ULL << \
        (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
 
+/*
+ * Rev2 silicon allows suppressing check for ArmLaunch errors.
+ * this can speed up short packet sends on systems that do
+ * not guaranteee write-order.
+ */
+#define INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR (1ULL<<63)
+
+/* 6120 specific hardware errors... */
+static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = {
+       INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"),
+       INFINIPATH_HWE_MSG(PCIECPLTIMEOUT, "PCIe completion timeout"),
+       /*
+        * In practice, it's unlikely wthat we'll see PCIe PLL, or bus
+        * parity or memory parity error failures, because most likely we
+        * won't be able to talk to the core of the chip.  Nonetheless, we
+        * might see them, if they are in parts of the PCIe core that aren't
+        * essential.
+        */
+       INFINIPATH_HWE_MSG(PCIE1PLLFAILED, "PCIePLL1"),
+       INFINIPATH_HWE_MSG(PCIE0PLLFAILED, "PCIePLL0"),
+       INFINIPATH_HWE_MSG(PCIEBUSPARITYXTLH, "PCIe XTLH core parity"),
+       INFINIPATH_HWE_MSG(PCIEBUSPARITYXADM, "PCIe ADM TX core parity"),
+       INFINIPATH_HWE_MSG(PCIEBUSPARITYRADM, "PCIe ADM RX core parity"),
+       INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"),
+       INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"),
+};
+
 /**
  * ipath_pe_handle_hwerrors - display hardware errors.
  * @dd: the infinipath device
@@ -343,19 +370,49 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
         * make sure we get this much out, unless told to be quiet,
         * or it's occurred within the last 5 seconds
         */
-       if ((hwerrs & ~dd->ipath_lasthwerror) ||
+       if ((hwerrs & ~(dd->ipath_lasthwerror |
+                       ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                         INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                        << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) ||
            (ipath_debug & __IPATH_VERBDBG))
                dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx "
                         "(cleared)\n", (unsigned long long) hwerrs);
        dd->ipath_lasthwerror |= hwerrs;
 
-       if (hwerrs & ~infinipath_hwe_bitsextant)
+       if (hwerrs & ~dd->ipath_hwe_bitsextant)
                ipath_dev_err(dd, "hwerror interrupt with unknown errors "
                              "%llx set\n", (unsigned long long)
-                             (hwerrs & ~infinipath_hwe_bitsextant));
+                             (hwerrs & ~dd->ipath_hwe_bitsextant));
 
        ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
        if (ctrl & INFINIPATH_C_FREEZEMODE) {
+               /*
+                * parity errors in send memory are recoverable,
+                * just cancel the send (if indicated in * sendbuffererror),
+                * count the occurrence, unfreeze (if no other handled
+                * hardware error bits are set), and continue. They can
+                * occur if a processor speculative read is done to the PIO
+                * buffer while we are sending a packet, for example.
+                */
+               if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                              INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                             << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
+                       ipath_stats.sps_txeparity++;
+                       ipath_dbg("Recovering from TXE parity error (%llu), "
+                                 "hwerrstatus=%llx\n",
+                                 (unsigned long long) ipath_stats.sps_txeparity,
+                                 (unsigned long long) hwerrs);
+                       ipath_disarm_senderrbufs(dd);
+                       hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
+                                    INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
+                                   << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
+                       if (!hwerrs) { /* else leave in freeze mode */
+                               ipath_write_kreg(dd,
+                                                dd->ipath_kregs->kr_control,
+                                                dd->ipath_control);
+                           return;
+                       }
+               }
                if (hwerrs) {
                        /*
                         * if any set that we aren't ignoring only make the
@@ -379,9 +436,8 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                } else {
                        ipath_dbg("Clearing freezemode on ignored hardware "
                                  "error\n");
-                       ctrl &= ~INFINIPATH_C_FREEZEMODE;
                        ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
-                                        ctrl);
+                                        dd->ipath_control);
                }
        }
 
@@ -396,24 +452,13 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
                                 dd->ipath_hwerrmask);
        }
-       if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK
-                     << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) {
-               bits = (u32) ((hwerrs >>
-                              INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) &
-                             INFINIPATH_HWE_RXEMEMPARITYERR_MASK);
-               snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ",
-                        bits);
-               strlcat(msg, bitsmsg, msgl);
-       }
-       if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK
-                     << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) {
-               bits = (u32) ((hwerrs >>
-                              INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) &
-                             INFINIPATH_HWE_TXEMEMPARITYERR_MASK);
-               snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ",
-                        bits);
-               strlcat(msg, bitsmsg, msgl);
-       }
+
+       ipath_format_hwerrors(hwerrs,
+                             ipath_6120_hwerror_msgs,
+                             sizeof(ipath_6120_hwerror_msgs)/
+                             sizeof(ipath_6120_hwerror_msgs[0]),
+                             msg, msgl);
+
        if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK
                      << INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) {
                bits = (u32) ((hwerrs >>
@@ -423,10 +468,6 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                         "[PCIe Mem Parity Errs %x] ", bits);
                strlcat(msg, bitsmsg, msgl);
        }
-       if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR)
-               strlcat(msg, "[IB2IPATH Parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR)
-               strlcat(msg, "[IPATH2IB Parity]", msgl);
 
 #define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP |       \
                         INFINIPATH_HWE_COREPLL_RFSLIP )
@@ -452,34 +493,6 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                                 dd->ipath_hwerrmask);
        }
 
-       if (hwerrs & INFINIPATH_HWE_PCIEPOISONEDTLP)
-               strlcat(msg, "[PCIe Poisoned TLP]", msgl);
-       if (hwerrs & INFINIPATH_HWE_PCIECPLTIMEOUT)
-               strlcat(msg, "[PCIe completion timeout]", msgl);
-
-       /*
-        * In practice, it's unlikely wthat we'll see PCIe PLL, or bus
-        * parity or memory parity error failures, because most likely we
-        * won't be able to talk to the core of the chip.  Nonetheless, we
-        * might see them, if they are in parts of the PCIe core that aren't
-        * essential.
-        */
-       if (hwerrs & INFINIPATH_HWE_PCIE1PLLFAILED)
-               strlcat(msg, "[PCIePLL1]", msgl);
-       if (hwerrs & INFINIPATH_HWE_PCIE0PLLFAILED)
-               strlcat(msg, "[PCIePLL0]", msgl);
-       if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXTLH)
-               strlcat(msg, "[PCIe XTLH core parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXADM)
-               strlcat(msg, "[PCIe ADM TX core parity]", msgl);
-       if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYRADM)
-               strlcat(msg, "[PCIe ADM RX core parity]", msgl);
-
-       if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR)
-               strlcat(msg, "[Rx Dsync]", msgl);
-       if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED)
-               strlcat(msg, "[SerDes PLL]", msgl);
-
        ipath_dev_err(dd, "%s hardware error\n", msg);
        if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) {
                /*
@@ -525,6 +538,9 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
        case 5:
                n = "InfiniPath_QMH7140";
                break;
+       case 6:
+               n = "InfiniPath_QLE7142";
+               break;
        default:
                ipath_dev_err(dd,
                              "Don't yet know about board with ID %u\n",
@@ -571,9 +587,12 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
        if (!dd->ipath_boardrev)        // no PLL for Emulator
                val &= ~INFINIPATH_HWE_SERDESPLLFAILED;
 
-       /* workaround bug 9460 in internal interface bus parity checking */
-       val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
-
+       if (dd->ipath_minrev < 2) {
+               /* workaround bug 9460 in internal interface bus parity
+                * checking. Fixed (HW bug 9490) in Rev2.
+                */
+               val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
+       }
        dd->ipath_hwerrmask = val;
 }
 
@@ -583,8 +602,8 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
  */
 static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
 {
-       u64 val, tmp, config1;
-       int ret = 0, change = 0;
+       u64 val, tmp, config1, prev_val;
+       int ret = 0;
 
        ipath_dbg("Trying to bringup serdes\n");
 
@@ -641,6 +660,7 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
        val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
 
        val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
+       prev_val = val;
        if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) &
             INFINIPATH_XGXS_MDIOADDR_MASK) != 3) {
                val &=
@@ -648,11 +668,9 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
                          INFINIPATH_XGXS_MDIOADDR_SHIFT);
                /* MDIO address 3 */
                val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT;
-               change = 1;
        }
        if (val & INFINIPATH_XGXS_RESET) {
                val &= ~INFINIPATH_XGXS_RESET;
-               change = 1;
        }
        if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
             INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
@@ -661,9 +679,19 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
                         INFINIPATH_XGXS_RX_POL_SHIFT);
                val |= dd->ipath_rx_pol_inv <<
                        INFINIPATH_XGXS_RX_POL_SHIFT;
-               change = 1;
        }
-       if (change)
+       if (dd->ipath_minrev >= 2) {
+               /* Rev 2. can tolerate multiple writes to PBC, and
+                * allowing them can provide lower latency on some
+                * CPUs, but this feature is off by default, only
+                * turned on by setting D63 of XGXSconfig reg.
+                * May want to make this conditional more
+                * fine-grained in future. This is not exactly
+                * related to XGXS, but where the bit ended up.
+                */
+               val |= INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR;
+       }
+       if (val != prev_val)
                ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
 
        val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
@@ -717,9 +745,25 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
        ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
 }
 
-/* this is not yet needed on this chip, so just return 0. */
 static int ipath_pe_intconfig(struct ipath_devdata *dd)
 {
+       u64 val;
+       u32 chiprev;
+
+       /*
+        * If the chip supports added error indication via GPIO pins,
+        * enable interrupts on those bits so the interrupt routine
+        * can count the events. Also set flag so interrupt routine
+        * can know they are expected.
+        */
+       chiprev = dd->ipath_revision >> INFINIPATH_R_CHIPREVMINOR_SHIFT;
+       if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) {
+               /* Rev2+ reports extra errors via internal GPIO pins */
+               dd->ipath_flags |= IPATH_GPIO_ERRINTRS;
+               val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+               val |= IPATH_GPIO_ERRINTR_MASK;
+               ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
+       }
        return 0;
 }
 
@@ -853,21 +897,23 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd,
        return 0;
 }
 
-static void ipath_init_pe_variables(void)
+static void ipath_init_pe_variables(struct ipath_devdata *dd)
 {
        /*
         * bits for selecting i2c direction and values,
         * used for I2C serial flash
         */
-       ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
-       ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
-       ipath_gpio_sda = IPATH_GPIO_SDA;
-       ipath_gpio_scl = IPATH_GPIO_SCL;
+       dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
+       dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
+       dd->ipath_gpio_sda = IPATH_GPIO_SDA;
+       dd->ipath_gpio_scl = IPATH_GPIO_SCL;
 
        /* variables for sanity checking interrupt and errors */
-       infinipath_hwe_bitsextant =
+       dd->ipath_hwe_bitsextant =
                (INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
                 INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) |
+               (INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
+                INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) |
                (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK <<
                 INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) |
                INFINIPATH_HWE_PCIE1PLLFAILED |
@@ -883,13 +929,13 @@ static void ipath_init_pe_variables(void)
                INFINIPATH_HWE_SERDESPLLFAILED |
                INFINIPATH_HWE_IBCBUSTOSPCPARITYERR |
                INFINIPATH_HWE_IBCBUSFRSPCPARITYERR;
-       infinipath_i_bitsextant =
+       dd->ipath_i_bitsextant =
                (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) |
                (INFINIPATH_I_RCVAVAIL_MASK <<
                 INFINIPATH_I_RCVAVAIL_SHIFT) |
                INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT |
                INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO;
-       infinipath_e_bitsextant =
+       dd->ipath_e_bitsextant =
                INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC |
                INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN |
                INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN |
@@ -907,8 +953,8 @@ static void ipath_init_pe_variables(void)
                INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET |
                INFINIPATH_E_HARDWARE;
 
-       infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
-       infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+       dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
+       dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
 }
 
 /* setup the MSI stuff again after a reset.  I'd like to just call
@@ -1082,6 +1128,45 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
        mmiowb();
        spin_unlock_irqrestore(&dd->ipath_tid_lock, flags);
 }
+/**
+ * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher
+ * @dd: the infinipath device
+ * @tidptr: pointer to the expected TID (in chip) to udpate
+ * @tidtype: 0 for eager, 1 for expected
+ * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
+ *
+ * This exists as a separate routine to allow for selection of the
+ * appropriate "flavor". The static calls in cleanup just use the
+ * revision-agnostic form, as they are not performance critical.
+ */
+static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
+                            u32 type, unsigned long pa)
+{
+       u32 __iomem *tidp32 = (u32 __iomem *)tidptr;
+
+       if (pa != dd->ipath_tidinvalid) {
+               if (pa & ((1U << 11) - 1)) {
+                       dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
+                                "not 2KB aligned!\n", pa);
+                       return;
+               }
+               pa >>= 11;
+               /* paranoia check */
+               if (pa & (7<<29))
+                       ipath_dev_err(dd,
+                                     "BUG: Physical page address 0x%lx "
+                                     "has bits set in 31-29\n", pa);
+
+               if (type == 0)
+                       pa |= dd->ipath_tidtemplate;
+               else /* for now, always full 4KB page */
+                       pa |= 2 << 29;
+       }
+       if (dd->ipath_kregbase)
+               writel(pa, tidp32);
+       mmiowb();
+}
+
 
 /**
  * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager
@@ -1203,7 +1288,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
 
 /**
  * ipath_init_pe_get_base_info - set chip-specific flags for user code
- * @dd: the infinipath device
+ * @pd: the infinipath port
  * @kbase: ipath_base_info pointer
  *
  * We set the PCIE flag because the lower bandwidth on PCIe vs
@@ -1212,6 +1297,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
 static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
 {
        struct ipath_base_info *kinfo = kbase;
+       struct ipath_devdata *dd;
 
        if (ipath_unordered_wc()) {
                kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER;
@@ -1220,8 +1306,20 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
        else
                ipath_cdbg(PROC, "Not Intel processor, WC ordered\n");
 
-       kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
+       if (pd == NULL)
+               goto done;
 
+       dd = pd->port_dd;
+
+       if (dd != NULL && dd->ipath_minrev >= 2) {
+               ipath_cdbg(PROC, "IBA6120 Rev2, allow multiple PBC write\n");
+               kinfo->spi_runtime_flags |= IPATH_RUNTIME_PBC_REWRITE;
+               ipath_cdbg(PROC, "IBA6120 Rev2, allow loose DMA alignment\n");
+               kinfo->spi_runtime_flags |= IPATH_RUNTIME_LOOSE_DMA_ALIGN;
+       }
+
+done:
+       kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
        return 0;
 }
 
@@ -1244,7 +1342,10 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
        dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes;
        dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes;
        dd->ipath_f_clear_tids = ipath_pe_clear_tids;
-       dd->ipath_f_put_tid = ipath_pe_put_tid;
+       if (dd->ipath_minrev >= 2)
+               dd->ipath_f_put_tid = ipath_pe_put_tid_2;
+       else
+               dd->ipath_f_put_tid = ipath_pe_put_tid;
        dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
        dd->ipath_f_setextled = ipath_setup_pe_setextled;
        dd->ipath_f_get_base_info = ipath_pe_get_base_info;
@@ -1259,6 +1360,6 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
        dd->ipath_kregs = &ipath_pe_kregs;
        dd->ipath_cregs = &ipath_pe_cregs;
 
-       ipath_init_pe_variables();
+       ipath_init_pe_variables(dd);
 }
 
index 44669dc2e22d1c502ce95503a19ed8f2f0fdb8ce..d819cca524cd9ac2260e24ee438ac131a9273eb0 100644 (file)
@@ -88,13 +88,13 @@ MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver");
 static int create_port0_egr(struct ipath_devdata *dd)
 {
        unsigned e, egrcnt;
-       struct sk_buff **skbs;
+       struct ipath_skbinfo *skbinfo;
        int ret;
 
        egrcnt = dd->ipath_rcvegrcnt;
 
-       skbs = vmalloc(sizeof(*dd->ipath_port0_skbs) * egrcnt);
-       if (skbs == NULL) {
+       skbinfo = vmalloc(sizeof(*dd->ipath_port0_skbinfo) * egrcnt);
+       if (skbinfo == NULL) {
                ipath_dev_err(dd, "allocation error for eager TID "
                              "skb array\n");
                ret = -ENOMEM;
@@ -109,13 +109,13 @@ static int create_port0_egr(struct ipath_devdata *dd)
                 * 4 bytes so that the data buffer stays word aligned.
                 * See ipath_kreceive() for more details.
                 */
-               skbs[e] = ipath_alloc_skb(dd, GFP_KERNEL);
-               if (!skbs[e]) {
+               skbinfo[e].skb = ipath_alloc_skb(dd, GFP_KERNEL);
+               if (!skbinfo[e].skb) {
                        ipath_dev_err(dd, "SKB allocation error for "
                                      "eager TID %u\n", e);
                        while (e != 0)
-                               dev_kfree_skb(skbs[--e]);
-                       vfree(skbs);
+                               dev_kfree_skb(skbinfo[--e].skb);
+                       vfree(skbinfo);
                        ret = -ENOMEM;
                        goto bail;
                }
@@ -124,14 +124,17 @@ static int create_port0_egr(struct ipath_devdata *dd)
         * After loop above, so we can test non-NULL to see if ready
         * to use at receive, etc.
         */
-       dd->ipath_port0_skbs = skbs;
+       dd->ipath_port0_skbinfo = skbinfo;
 
        for (e = 0; e < egrcnt; e++) {
-               unsigned long phys =
-                       virt_to_phys(dd->ipath_port0_skbs[e]->data);
+               dd->ipath_port0_skbinfo[e].phys =
+                 ipath_map_single(dd->pcidev,
+                                  dd->ipath_port0_skbinfo[e].skb->data,
+                                  dd->ipath_ibmaxlen, PCI_DMA_FROMDEVICE);
                dd->ipath_f_put_tid(dd, e + (u64 __iomem *)
                                    ((char __iomem *) dd->ipath_kregbase +
-                                    dd->ipath_rcvegrbase), 0, phys);
+                                    dd->ipath_rcvegrbase), 0,
+                                   dd->ipath_port0_skbinfo[e].phys);
        }
 
        ret = 0;
@@ -432,16 +435,33 @@ done:
  */
 static void init_shadow_tids(struct ipath_devdata *dd)
 {
-       dd->ipath_pageshadow = (struct page **)
-               vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+       struct page **pages;
+       dma_addr_t *addrs;
+
+       pages = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
                        sizeof(struct page *));
-       if (!dd->ipath_pageshadow)
+       if (!pages) {
                ipath_dev_err(dd, "failed to allocate shadow page * "
                              "array, no expected sends!\n");
-       else
-               memset(dd->ipath_pageshadow, 0,
-                      dd->ipath_cfgports * dd->ipath_rcvtidcnt *
-                      sizeof(struct page *));
+               dd->ipath_pageshadow = NULL;
+               return;
+       }
+
+       addrs = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+                       sizeof(dma_addr_t));
+       if (!addrs) {
+               ipath_dev_err(dd, "failed to allocate shadow dma handle "
+                             "array, no expected sends!\n");
+               vfree(dd->ipath_pageshadow);
+               dd->ipath_pageshadow = NULL;
+               return;
+       }
+
+       memset(pages, 0, dd->ipath_cfgports * dd->ipath_rcvtidcnt *
+              sizeof(struct page *));
+
+       dd->ipath_pageshadow = pages;
+       dd->ipath_physshadow = addrs;
 }
 
 static void enable_chip(struct ipath_devdata *dd,
index 49bf7bb15b04b2628f52bf10df0b0366c574a3b7..6bee53ce5f334a84352847ce014c9a3d2502f322 100644 (file)
 #include "ipath_verbs.h"
 #include "ipath_common.h"
 
+/*
+ * Called when we might have an error that is specific to a particular
+ * PIO buffer, and may need to cancel that buffer, so it can be re-used.
+ */
+void ipath_disarm_senderrbufs(struct ipath_devdata *dd)
+{
+       u32 piobcnt;
+       unsigned long sbuf[4];
+       /*
+        * it's possible that sendbuffererror could have bits set; might
+        * have already done this as a result of hardware error handling
+        */
+       piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
+       /* read these before writing errorclear */
+       sbuf[0] = ipath_read_kreg64(
+               dd, dd->ipath_kregs->kr_sendbuffererror);
+       sbuf[1] = ipath_read_kreg64(
+               dd, dd->ipath_kregs->kr_sendbuffererror + 1);
+       if (piobcnt > 128) {
+               sbuf[2] = ipath_read_kreg64(
+                       dd, dd->ipath_kregs->kr_sendbuffererror + 2);
+               sbuf[3] = ipath_read_kreg64(
+                       dd, dd->ipath_kregs->kr_sendbuffererror + 3);
+       }
+
+       if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
+               int i;
+               if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) {
+                       __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
+                                         "SendbufErrs %lx %lx", sbuf[0],
+                                         sbuf[1]);
+                       if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128)
+                               printk(" %lx %lx ", sbuf[2], sbuf[3]);
+                       printk("\n");
+               }
+
+               for (i = 0; i < piobcnt; i++)
+                       if (test_bit(i, sbuf))
+                               ipath_disarm_piobufs(dd, i, 1);
+               dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */
+       }
+}
+
+
 /* These are all rcv-related errors which we want to count for stats */
 #define E_SUM_PKTERRS \
        (INFINIPATH_E_RHDRLEN | INFINIPATH_E_RBADTID | \
 
 static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
 {
-       unsigned long sbuf[4];
        u64 ignore_this_time = 0;
-       u32 piobcnt;
 
-       /* if possible that sendbuffererror could be valid */
-       piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
-       /* read these before writing errorclear */
-       sbuf[0] = ipath_read_kreg64(
-               dd, dd->ipath_kregs->kr_sendbuffererror);
-       sbuf[1] = ipath_read_kreg64(
-               dd, dd->ipath_kregs->kr_sendbuffererror + 1);
-       if (piobcnt > 128) {
-               sbuf[2] = ipath_read_kreg64(
-                       dd, dd->ipath_kregs->kr_sendbuffererror + 2);
-               sbuf[3] = ipath_read_kreg64(
-                       dd, dd->ipath_kregs->kr_sendbuffererror + 3);
-       }
-
-       if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
-               int i;
-
-               ipath_cdbg(PKT, "SendbufErrs %lx %lx ", sbuf[0], sbuf[1]);
-               if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128)
-                       printk("%lx %lx ", sbuf[2], sbuf[3]);
-               for (i = 0; i < piobcnt; i++) {
-                       if (test_bit(i, sbuf)) {
-                               u32 __iomem *piobuf;
-                               if (i < dd->ipath_piobcnt2k)
-                                       piobuf = (u32 __iomem *)
-                                               (dd->ipath_pio2kbase +
-                                                i * dd->ipath_palign);
-                               else
-                                       piobuf = (u32 __iomem *)
-                                               (dd->ipath_pio4kbase +
-                                                (i - dd->ipath_piobcnt2k) *
-                                                dd->ipath_4kalign);
-
-                               ipath_cdbg(PKT,
-                                          "PIObuf[%u] @%p pbc is %x; ",
-                                          i, piobuf, readl(piobuf));
-
-                               ipath_disarm_piobufs(dd, i, 1);
-                       }
-               }
-               if (ipath_debug & __IPATH_PKTDBG)
-                       printk("\n");
-       }
+       ipath_disarm_senderrbufs(dd);
        if ((errs & E_SUM_LINK_PKTERRS) &&
            !(dd->ipath_flags & IPATH_LINKACTIVE)) {
                /*
@@ -132,6 +132,82 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
        return ignore_this_time;
 }
 
+/* generic hw error messages... */
+#define INFINIPATH_HWE_TXEMEMPARITYERR_MSG(a) \
+       { \
+               .mask = ( INFINIPATH_HWE_TXEMEMPARITYERR_##a <<    \
+                         INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT ),   \
+               .msg = "TXE " #a " Memory Parity"            \
+       }
+#define INFINIPATH_HWE_RXEMEMPARITYERR_MSG(a) \
+       { \
+               .mask = ( INFINIPATH_HWE_RXEMEMPARITYERR_##a <<    \
+                         INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT ),   \
+               .msg = "RXE " #a " Memory Parity"            \
+       }
+
+static const struct ipath_hwerror_msgs ipath_generic_hwerror_msgs[] = {
+       INFINIPATH_HWE_MSG(IBCBUSFRSPCPARITYERR, "IPATH2IB Parity"),
+       INFINIPATH_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2IPATH Parity"),
+
+       INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOBUF),
+       INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOPBC),
+       INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOLAUNCHFIFO),
+
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(RCVBUF),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(LOOKUPQ),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EAGERTID),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EXPTID),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(FLAGBUF),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(DATAINFO),
+       INFINIPATH_HWE_RXEMEMPARITYERR_MSG(HDRINFO),
+};
+
+/**
+ * ipath_format_hwmsg - format a single hwerror message
+ * @msg message buffer
+ * @msgl length of message buffer
+ * @hwmsg message to add to message buffer
+ */
+static void ipath_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
+{
+       strlcat(msg, "[", msgl);
+       strlcat(msg, hwmsg, msgl);
+       strlcat(msg, "]", msgl);
+}
+
+/**
+ * ipath_format_hwerrors - format hardware error messages for display
+ * @hwerrs hardware errors bit vector
+ * @hwerrmsgs hardware error descriptions
+ * @nhwerrmsgs number of hwerrmsgs
+ * @msg message buffer
+ * @msgl message buffer length
+ */
+void ipath_format_hwerrors(u64 hwerrs,
+                          const struct ipath_hwerror_msgs *hwerrmsgs,
+                          size_t nhwerrmsgs,
+                          char *msg, size_t msgl)
+{
+       int i;
+       const int glen =
+           sizeof(ipath_generic_hwerror_msgs) /
+           sizeof(ipath_generic_hwerror_msgs[0]);
+
+       for (i=0; i<glen; i++) {
+               if (hwerrs & ipath_generic_hwerror_msgs[i].mask) {
+                       ipath_format_hwmsg(msg, msgl,
+                                          ipath_generic_hwerror_msgs[i].msg);
+               }
+       }
+
+       for (i=0; i<nhwerrmsgs; i++) {
+               if (hwerrs & hwerrmsgs[i].mask) {
+                       ipath_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
+               }
+       }
+}
+
 /* return the strings for the most common link states */
 static char *ib_linkstate(u32 linkstate)
 {
@@ -404,10 +480,10 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
                dd->ipath_f_handle_hwerrors(dd, msg, sizeof msg);
        }
 
-       if (!noprint && (errs & ~infinipath_e_bitsextant))
+       if (!noprint && (errs & ~dd->ipath_e_bitsextant))
                ipath_dev_err(dd, "error interrupt with unknown errors "
                              "%llx set\n", (unsigned long long)
-                             (errs & ~infinipath_e_bitsextant));
+                             (errs & ~dd->ipath_e_bitsextant));
 
        if (errs & E_SUM_ERRS)
                ignore_this_time = handle_e_sum_errs(dd, errs);
@@ -478,6 +554,14 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
                        ~(INFINIPATH_E_HARDWARE |
                          INFINIPATH_E_IBSTATUSCHANGED);
        }
+
+       /* likely due to cancel, so suppress */
+       if ((errs & (INFINIPATH_E_SPKTLEN | INFINIPATH_E_SPIOARMLAUNCH)) &&
+               dd->ipath_lastcancel > jiffies) {
+               ipath_dbg("Suppressed armlaunch/spktlen after error send cancel\n");
+               errs &= ~(INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SPKTLEN);
+       }
+
        if (!errs)
                return 0;
 
@@ -529,7 +613,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
                                 * don't report same point multiple times,
                                 * except kernel
                                 */
-                               tl = (u32) * pd->port_rcvhdrtail_kvaddr;
+                               tl = *(u64 *) pd->port_rcvhdrtail_kvaddr;
                                if (tl == dd->ipath_lastrcvhdrqtails[i])
                                        continue;
                                hd = ipath_read_ureg32(dd, ur_rcvhdrhead,
@@ -729,9 +813,9 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
        int rcvdint = 0;
 
        portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) &
-                infinipath_i_rcvavail_mask)
+                dd->ipath_i_rcvavail_mask)
                | ((istat >> INFINIPATH_I_RCVURG_SHIFT) &
-                  infinipath_i_rcvurg_mask);
+                  dd->ipath_i_rcvurg_mask);
        for (i = 1; i < dd->ipath_cfgports; i++) {
                struct ipath_portdata *pd = dd->ipath_pd[i];
                if (portr & (1 << i) && pd && pd->port_cnt &&
@@ -808,7 +892,7 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
        if (oldhead != curtail) {
                if (dd->ipath_flags & IPATH_GPIO_INTR) {
                        ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
-                                        (u64) (1 << 2));
+                                        (u64) (1 << IPATH_GPIO_PORT0_BIT));
                        istat = port0rbits | INFINIPATH_I_GPIO;
                }
                else
@@ -838,10 +922,10 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
        if (unexpected)
                unexpected = 0;
 
-       if (unlikely(istat & ~infinipath_i_bitsextant))
+       if (unlikely(istat & ~dd->ipath_i_bitsextant))
                ipath_dev_err(dd,
                              "interrupt with unknown interrupts %x set\n",
-                             istat & (u32) ~ infinipath_i_bitsextant);
+                             istat & (u32) ~ dd->ipath_i_bitsextant);
        else
                ipath_cdbg(VERBOSE, "intr stat=0x%x\n", istat);
 
@@ -867,26 +951,80 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
 
        if (istat & INFINIPATH_I_GPIO) {
                /*
-                * Packets are available in the port 0 rcv queue.
-                * Eventually this needs to be generalized to check
-                * IPATH_GPIO_INTR, and the specific GPIO bit, if
-                * GPIO interrupts are used for anything else.
+                * GPIO interrupts fall in two broad classes:
+                * GPIO_2 indicates (on some HT4xx boards) that a packet
+                *        has arrived for Port 0. Checking for this
+                *        is controlled by flag IPATH_GPIO_INTR.
+                * GPIO_3..5 on IBA6120 Rev2 chips indicate errors
+                *        that we need to count. Checking for this
+                *        is controlled by flag IPATH_GPIO_ERRINTRS.
                 */
-               if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) {
-                       u32 gpiostatus;
-                       gpiostatus = ipath_read_kreg32(
-                               dd, dd->ipath_kregs->kr_gpio_status);
-                       ipath_dbg("Unexpected GPIO interrupt bits %x\n",
-                                 gpiostatus);
-                       ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
-                                        gpiostatus);
+               u32 gpiostatus;
+               u32 to_clear = 0;
+
+               gpiostatus = ipath_read_kreg32(
+                       dd, dd->ipath_kregs->kr_gpio_status);
+               /* First the error-counter case.
+                */
+               if ((gpiostatus & IPATH_GPIO_ERRINTR_MASK) &&
+                   (dd->ipath_flags & IPATH_GPIO_ERRINTRS)) {
+                       /* want to clear the bits we see asserted. */
+                       to_clear |= (gpiostatus & IPATH_GPIO_ERRINTR_MASK);
+
+                       /*
+                        * Count appropriately, clear bits out of our copy,
+                        * as they have been "handled".
+                        */
+                       if (gpiostatus & (1 << IPATH_GPIO_RXUVL_BIT)) {
+                               ipath_dbg("FlowCtl on UnsupVL\n");
+                               dd->ipath_rxfc_unsupvl_errs++;
+                       }
+                       if (gpiostatus & (1 << IPATH_GPIO_OVRUN_BIT)) {
+                               ipath_dbg("Overrun Threshold exceeded\n");
+                               dd->ipath_overrun_thresh_errs++;
+                       }
+                       if (gpiostatus & (1 << IPATH_GPIO_LLI_BIT)) {
+                               ipath_dbg("Local Link Integrity error\n");
+                               dd->ipath_lli_errs++;
+                       }
+                       gpiostatus &= ~IPATH_GPIO_ERRINTR_MASK;
                }
-               else {
-                       /* Clear GPIO status bit 2 */
-                       ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
-                                       (u64) (1 << 2));
+               /* Now the Port0 Receive case */
+               if ((gpiostatus & (1 << IPATH_GPIO_PORT0_BIT)) &&
+                   (dd->ipath_flags & IPATH_GPIO_INTR)) {
+                       /*
+                        * GPIO status bit 2 is set, and we expected it.
+                        * clear it and indicate in p0bits.
+                        * This probably only happens if a Port0 pkt
+                        * arrives at _just_ the wrong time, and we
+                        * handle that by seting chk0rcv;
+                        */
+                       to_clear |= (1 << IPATH_GPIO_PORT0_BIT);
+                       gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT);
                        chk0rcv = 1;
                }
+               if (unlikely(gpiostatus)) {
+                       /*
+                        * Some unexpected bits remain. If they could have
+                        * caused the interrupt, complain and clear.
+                        * MEA: this is almost certainly non-ideal.
+                        * we should look into auto-disable of unexpected
+                        * GPIO interrupts, possibly on a "three strikes"
+                        * basis.
+                        */
+                       u32 mask;
+                       mask = ipath_read_kreg32(
+                               dd, dd->ipath_kregs->kr_gpio_mask);
+                       if (mask & gpiostatus) {
+                               ipath_dbg("Unexpected GPIO IRQ bits %x\n",
+                                 gpiostatus & mask);
+                               to_clear |= (gpiostatus & mask);
+                       }
+               }
+               if (to_clear) {
+                       ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
+                                       (u64) to_clear);
+               }
        }
        chk0rcv |= istat & port0rbits;
 
@@ -911,9 +1049,9 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
                istat &= ~port0rbits;
        }
 
-       if (istat & ((infinipath_i_rcvavail_mask <<
+       if (istat & ((dd->ipath_i_rcvavail_mask <<
                      INFINIPATH_I_RCVAVAIL_SHIFT)
-                    | (infinipath_i_rcvurg_mask <<
+                    | (dd->ipath_i_rcvurg_mask <<
                        INFINIPATH_I_RCVURG_SHIFT)))
                handle_urcv(dd, istat);
 
index a8a56276ff1dbe6dd591a8756f8f0171a8d24063..d7540b71b451b624dd580deb7c074a61c61dbe6f 100644 (file)
@@ -39,6 +39,8 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 
 #include "ipath_common.h"
@@ -62,7 +64,7 @@ struct ipath_portdata {
        /* rcvhdrq base, needs mmap before useful */
        void *port_rcvhdrq;
        /* kernel virtual address where hdrqtail is updated */
-       volatile __le64 *port_rcvhdrtail_kvaddr;
+       void *port_rcvhdrtail_kvaddr;
        /*
         * temp buffer for expected send setup, allocated at open, instead
         * of each setup call
@@ -79,8 +81,8 @@ struct ipath_portdata {
        dma_addr_t port_rcvhdrq_phys;
        dma_addr_t port_rcvhdrqtailaddr_phys;
        /*
-        * number of opens on this instance (0 or 1; ignoring forks, dup,
-        * etc. for now)
+        * number of opens (including slave subports) on this instance
+        * (ignoring forks, dup, etc. for now)
         */
        int port_cnt;
        /*
@@ -89,6 +91,10 @@ struct ipath_portdata {
         */
        /* instead of calculating it */
        unsigned port_port;
+       /* non-zero if port is being shared. */
+       u16 port_subport_cnt;
+       /* non-zero if port is being shared. */
+       u16 port_subport_id;
        /* chip offset of PIO buffers for this port */
        u32 port_piobufs;
        /* how many alloc_pages() chunks in port_rcvegrbuf_pages */
@@ -121,6 +127,16 @@ struct ipath_portdata {
        u16 port_pkeys[4];
        /* so file ops can get at unit */
        struct ipath_devdata *port_dd;
+       /* A page of memory for rcvhdrhead, rcvegrhead, rcvegrtail * N */
+       void *subport_uregbase;
+       /* An array of pages for the eager receive buffers * N */
+       void *subport_rcvegrbuf;
+       /* An array of pages for the eager header queue entries * N */
+       void *subport_rcvhdr_base;
+       /* The version of the library which opened this port */
+       u32 userversion;
+       /* Bitmask of active slaves */
+       u32 active_slaves;
 };
 
 struct sk_buff;
@@ -132,6 +148,11 @@ struct _ipath_layer {
        void *l_arg;
 };
 
+struct ipath_skbinfo {
+       struct sk_buff *skb;
+       dma_addr_t phys;
+};
+
 struct ipath_devdata {
        struct list_head ipath_list;
 
@@ -154,7 +175,7 @@ struct ipath_devdata {
        /* ipath_cfgports pointers */
        struct ipath_portdata **ipath_pd;
        /* sk_buffs used by port 0 eager receive queue */
-       struct sk_buff **ipath_port0_skbs;
+       struct ipath_skbinfo *ipath_port0_skbinfo;
        /* kvirt address of 1st 2k pio buffer */
        void __iomem *ipath_pio2kbase;
        /* kvirt address of 1st 4k pio buffer */
@@ -315,12 +336,16 @@ struct ipath_devdata {
        u8 ipath_ht_slave_off;
        /* for write combining settings */
        unsigned long ipath_wc_cookie;
+       unsigned long ipath_wc_base;
+       unsigned long ipath_wc_len;
        /* ref count for each pkey */
        atomic_t ipath_pkeyrefs[4];
        /* shadow copy of all exptids physaddr; used only by funcsim */
        u64 *ipath_tidsimshadow;
        /* shadow copy of struct page *'s for exp tid pages */
        struct page **ipath_pageshadow;
+       /* shadow copy of dma handles for exp tid pages */
+       dma_addr_t *ipath_physshadow;
        /* lock to workaround chip bug 9437 */
        spinlock_t ipath_tid_lock;
 
@@ -402,6 +427,9 @@ struct ipath_devdata {
        unsigned long ipath_rcvctrl;
        /* shadow kr_sendctrl */
        unsigned long ipath_sendctrl;
+       /* ports waiting for PIOavail intr */
+       unsigned long ipath_portpiowait;
+       unsigned long ipath_lastcancel; /* to not count armlaunch after cancel */
 
        /* value we put in kr_rcvhdrcnt */
        u32 ipath_rcvhdrcnt;
@@ -465,8 +493,6 @@ struct ipath_devdata {
        u32 ipath_htwidth;
        /* HT speed (200,400,800,1000) from HT config */
        u32 ipath_htspeed;
-       /* ports waiting for PIOavail intr */
-       unsigned long ipath_portpiowait;
        /*
         * number of sequential ibcstatus change for polling active/quiet
         * (i.e., link not coming up).
@@ -510,8 +536,47 @@ struct ipath_devdata {
        u32 ipath_lli_counter;
        /* local link integrity errors */
        u32 ipath_lli_errors;
+       /*
+        * Above counts only cases where _successive_ LocalLinkIntegrity
+        * errors were seen in the receive headers of kern-packets.
+        * Below are the three (monotonically increasing) counters
+        * maintained via GPIO interrupts on iba6120-rev2.
+        */
+       u32 ipath_rxfc_unsupvl_errs;
+       u32 ipath_overrun_thresh_errs;
+       u32 ipath_lli_errs;
+
+       /*
+        * Not all devices managed by a driver instance are the same
+        * type, so these fields must be per-device.
+        */
+       u64 ipath_i_bitsextant;
+       ipath_err_t ipath_e_bitsextant;
+       ipath_err_t ipath_hwe_bitsextant;
+
+       /*
+        * Below should be computable from number of ports,
+        * since they are never modified.
+        */
+       u32 ipath_i_rcvavail_mask;
+       u32 ipath_i_rcvurg_mask;
+
+       /*
+        * Register bits for selecting i2c direction and values, used for
+        * I2C serial flash.
+        */
+       u16 ipath_gpio_sda_num;
+       u16 ipath_gpio_scl_num;
+       u64 ipath_gpio_sda;
+       u64 ipath_gpio_scl;
 };
 
+/* Private data for file operations */
+struct ipath_filedata {
+       struct ipath_portdata *pd;
+       unsigned subport;
+       unsigned tidcursor;
+};
 extern struct list_head ipath_dev_list;
 extern spinlock_t ipath_devs_lock;
 extern struct ipath_devdata *ipath_lookup(int unit);
@@ -521,6 +586,7 @@ int ipath_enable_wc(struct ipath_devdata *dd);
 void ipath_disable_wc(struct ipath_devdata *dd);
 int ipath_count_units(int *npresentp, int *nupp, u32 *maxportsp);
 void ipath_shutdown_device(struct ipath_devdata *);
+void ipath_disarm_senderrbufs(struct ipath_devdata *);
 
 struct file_operations;
 int ipath_cdev_init(int minor, char *name, struct file_operations *fops,
@@ -572,7 +638,11 @@ int ipath_set_lid(struct ipath_devdata *, u32, u8);
 int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
 
 /* for use in system calls, where we want to know device type, etc. */
-#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data)
+#define port_fp(fp) ((struct ipath_filedata *)(fp)->private_data)->pd
+#define subport_fp(fp) \
+       ((struct ipath_filedata *)(fp)->private_data)->subport
+#define tidcursor_fp(fp) \
+       ((struct ipath_filedata *)(fp)->private_data)->tidcursor
 
 /*
  * values for ipath_flags
@@ -612,6 +682,15 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
                /* can miss port0 rx interrupts */
 #define IPATH_POLL_RX_INTR  0x40000
 #define IPATH_DISABLED      0x80000 /* administratively disabled */
+               /* Use GPIO interrupts for new counters */
+#define IPATH_GPIO_ERRINTRS 0x100000
+
+/* Bits in GPIO for the added interrupts */
+#define IPATH_GPIO_PORT0_BIT 2
+#define IPATH_GPIO_RXUVL_BIT 3
+#define IPATH_GPIO_OVRUN_BIT 4
+#define IPATH_GPIO_LLI_BIT 5
+#define IPATH_GPIO_ERRINTR_MASK 0x38
 
 /* portdata flag bit offsets */
                /* waiting for a packet to arrive */
@@ -798,6 +877,13 @@ void ipath_exit_ipathfs(void);
 int ipathfs_add_device(struct ipath_devdata *);
 int ipathfs_remove_device(struct ipath_devdata *);
 
+/*
+ * dma_addr wrappers - all 0's invalid for hw
+ */
+dma_addr_t ipath_map_page(struct pci_dev *, struct page *, unsigned long,
+                         size_t, int);
+dma_addr_t ipath_map_single(struct pci_dev *, void *, size_t, int);
+
 /*
  * Flush write combining store buffers (if present) and perform a write
  * barrier.
@@ -855,4 +941,20 @@ extern struct mutex ipath_mutex;
 
 #endif /* _IPATH_DEBUGGING */
 
+/*
+ * this is used for formatting hw error messages...
+ */
+struct ipath_hwerror_msgs {
+       u64 mask;
+       const char *msg;
+};
+
+#define INFINIPATH_HWE_MSG(a, b) { .mask = INFINIPATH_HWE_##a, .msg = b }
+
+/* in ipath_intr.c... */
+void ipath_format_hwerrors(u64 hwerrs,
+                          const struct ipath_hwerror_msgs *hwerrmsgs,
+                          size_t nhwerrmsgs,
+                          char *msg, size_t lmsg);
+
 #endif                         /* _IPATH_KERNEL_H */
index ba1b93226caa4472ca67fa1d5dade05ee271b53a..9a6cbd05adcde9e19f7d75032163b8362d6ca77c 100644 (file)
@@ -118,9 +118,10 @@ void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey)
  * Check the IB SGE for validity and initialize our internal version
  * of it.
  */
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
+int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
                  struct ib_sge *sge, int acc)
 {
+       struct ipath_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
        struct ipath_mregion *mr;
        unsigned n, m;
        size_t off;
@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
                goto bail;
        }
        mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
-       if (unlikely(mr == NULL || mr->lkey != sge->lkey)) {
+       if (unlikely(mr == NULL || mr->lkey != sge->lkey ||
+                    qp->ibqp.pd != mr->pd)) {
                ret = 0;
                goto bail;
        }
@@ -188,9 +190,10 @@ bail:
  *
  * Return 1 if successful, otherwise 0.
  */
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
+int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
                  u32 len, u64 vaddr, u32 rkey, int acc)
 {
+       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        struct ipath_lkey_table *rkt = &dev->lk_table;
        struct ipath_sge *sge = &ss->sge;
        struct ipath_mregion *mr;
@@ -214,7 +217,8 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
        }
 
        mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
-       if (unlikely(mr == NULL || mr->lkey != rkey)) {
+       if (unlikely(mr == NULL || mr->lkey != rkey ||
+                    qp->ibqp.pd != mr->pd)) {
                ret = 0;
                goto bail;
        }
index 72d1db89db8f6d3393154eb542c0b47a39208714..25908b02fbe578f57fd6ee7128ea0c9b22169f32 100644 (file)
@@ -87,7 +87,8 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp,
        struct ipath_devdata *dd = to_idev(ibdev)->dd;
        u32 vendor, majrev, minrev;
 
-       if (smp->attr_mod)
+       /* GUID 0 is illegal */
+       if (smp->attr_mod || (dd->ipath_guid == 0))
                smp->status |= IB_SMP_INVALID_FIELD;
 
        nip->base_version = 1;
@@ -131,10 +132,15 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp,
         * We only support one GUID for now.  If this changes, the
         * portinfo.guid_cap field needs to be updated too.
         */
-       if (startgx == 0)
-               /* The first is a copy of the read-only HW GUID. */
-               *p = to_idev(ibdev)->dd->ipath_guid;
-       else
+       if (startgx == 0) {
+               __be64 g = to_idev(ibdev)->dd->ipath_guid;
+               if (g == 0)
+                       /* GUID 0 is illegal */
+                       smp->status |= IB_SMP_INVALID_FIELD;
+               else
+                       /* The first is a copy of the read-only HW GUID. */
+                       *p = g;
+       } else
                smp->status |= IB_SMP_INVALID_FIELD;
 
        return reply(smp);
index b36f6fb3e37a76f16ae370aa1e6ee163227b7df6..a0673c1eef716bb59655df6d55ab334626e00b9f 100644 (file)
@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
                goto bail;
        }
 
+       mr->mr.pd = pd;
        mr->mr.user_base = *iova_start;
        mr->mr.iova = *iova_start;
        mr->mr.length = 0;
@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
                goto bail;
        }
 
+       mr->mr.pd = pd;
        mr->mr.user_base = region->user_base;
        mr->mr.iova = region->virt_base;
        mr->mr.length = region->length;
@@ -289,6 +291,7 @@ struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
         * Resources are allocated but no valid mapping (RKEY can't be
         * used).
         */
+       fmr->mr.pd = pd;
        fmr->mr.user_base = 0;
        fmr->mr.iova = 0;
        fmr->mr.length = 0;
index 224b0f40767f0ef6b08a8aa8e451fcad419c6d87..46c1c89bf6ae2748dd5779ddca0c24a44e271af6 100644 (file)
@@ -335,6 +335,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
        qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
        qp->r_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
        qp->r_nak_state = 0;
+       qp->r_wrid_valid = 0;
        qp->s_rnr_timeout = 0;
        qp->s_head = 0;
        qp->s_tail = 0;
@@ -342,6 +343,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
        qp->s_last = 0;
        qp->s_ssn = 1;
        qp->s_lsn = 0;
+       qp->s_wait_credit = 0;
        if (qp->r_rq.wq) {
                qp->r_rq.wq->head = 0;
                qp->r_rq.wq->tail = 0;
@@ -352,12 +354,13 @@ static void ipath_reset_qp(struct ipath_qp *qp)
 /**
  * ipath_error_qp - put a QP into an error state
  * @qp: the QP to put into an error state
+ * @err: the receive completion error to signal if a RWQE is active
  *
  * Flushes both send and receive work queues.
  * QP s_lock should be held and interrupts disabled.
  */
 
-void ipath_error_qp(struct ipath_qp *qp)
+void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
 {
        struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        struct ib_wc wc;
@@ -373,7 +376,6 @@ void ipath_error_qp(struct ipath_qp *qp)
                list_del_init(&qp->piowait);
        spin_unlock(&dev->pending_lock);
 
-       wc.status = IB_WC_WR_FLUSH_ERR;
        wc.vendor_err = 0;
        wc.byte_len = 0;
        wc.imm_data = 0;
@@ -385,6 +387,12 @@ void ipath_error_qp(struct ipath_qp *qp)
        wc.sl = 0;
        wc.dlid_path_bits = 0;
        wc.port_num = 0;
+       if (qp->r_wrid_valid) {
+               qp->r_wrid_valid = 0;
+               wc.status = err;
+               ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+       }
+       wc.status = IB_WC_WR_FLUSH_ERR;
 
        while (qp->s_last != qp->s_head) {
                struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
@@ -501,7 +509,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                break;
 
        case IB_QPS_ERR:
-               ipath_error_qp(qp);
+               ipath_error_qp(qp, IB_WC_GENERAL_ERR);
                break;
 
        default:
@@ -516,7 +524,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                qp->remote_qpn = attr->dest_qp_num;
 
        if (attr_mask & IB_QP_SQ_PSN) {
-               qp->s_next_psn = attr->sq_psn;
+               qp->s_psn = qp->s_next_psn = attr->sq_psn;
                qp->s_last_psn = qp->s_next_psn - 1;
        }
 
index a08654042c03411db35b26c54acaf5105e4015cb..a504cf67f27274b2f8cd622884a09e519f7e410e 100644 (file)
@@ -201,6 +201,18 @@ int ipath_make_rc_req(struct ipath_qp *qp,
            qp->s_rnr_timeout)
                goto done;
 
+       /* Limit the number of packets sent without an ACK. */
+       if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) {
+               qp->s_wait_credit = 1;
+               dev->n_rc_stalls++;
+               spin_lock(&dev->pending_lock);
+               if (list_empty(&qp->timerwait))
+                       list_add_tail(&qp->timerwait,
+                                     &dev->pending[dev->pending_index]);
+               spin_unlock(&dev->pending_lock);
+               goto done;
+       }
+
        /* header size in 32-bit words LRH+BTH = (8+12)/4. */
        hwords = 5;
        bth0 = 0;
@@ -221,7 +233,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                        /* Check if send work queue is empty. */
                        if (qp->s_tail == qp->s_head)
                                goto done;
-                       qp->s_psn = wqe->psn = qp->s_next_psn;
+                       wqe->psn = qp->s_next_psn;
                        newreq = 1;
                }
                /*
@@ -393,12 +405,6 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                ss = &qp->s_sge;
                len = qp->s_len;
                if (len > pmtu) {
-                       /*
-                        * Request an ACK every 1/2 MB to avoid retransmit
-                        * timeouts.
-                        */
-                       if (((wqe->length - len) % (512 * 1024)) == 0)
-                               bth2 |= 1 << 31;
                        len = pmtu;
                        break;
                }
@@ -435,12 +441,6 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                ss = &qp->s_sge;
                len = qp->s_len;
                if (len > pmtu) {
-                       /*
-                        * Request an ACK every 1/2 MB to avoid retransmit
-                        * timeouts.
-                        */
-                       if (((wqe->length - len) % (512 * 1024)) == 0)
-                               bth2 |= 1 << 31;
                        len = pmtu;
                        break;
                }
@@ -498,6 +498,8 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                 */
                goto done;
        }
+       if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT - 1) >= 0)
+               bth2 |= 1 << 31;        /* Request ACK. */
        qp->s_len -= len;
        qp->s_hdrwords = hwords;
        qp->s_cur_sge = ss;
@@ -737,6 +739,15 @@ bail:
        return;
 }
 
+static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
+{
+       if (qp->s_wait_credit) {
+               qp->s_wait_credit = 0;
+               tasklet_hi_schedule(&qp->s_task);
+       }
+       qp->s_last_psn = psn;
+}
+
 /**
  * do_rc_ack - process an incoming RC ACK
  * @qp: the QP the ACK came in on
@@ -805,7 +816,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                         * The last valid PSN seen is the previous
                         * request's.
                         */
-                       qp->s_last_psn = wqe->psn - 1;
+                       update_last_psn(qp, wqe->psn - 1);
                        /* Retry this request. */
                        ipath_restart_rc(qp, wqe->psn, &wc);
                        /*
@@ -864,7 +875,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                ipath_get_credit(qp, aeth);
                qp->s_rnr_retry = qp->s_rnr_retry_cnt;
                qp->s_retry = qp->s_retry_cnt;
-               qp->s_last_psn = psn;
+               update_last_psn(qp, psn);
                ret = 1;
                goto bail;
 
@@ -883,7 +894,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                        goto bail;
 
                /* The last valid PSN is the previous PSN. */
-               qp->s_last_psn = psn - 1;
+               update_last_psn(qp, psn - 1);
 
                dev->n_rc_resends += (int)qp->s_psn - (int)psn;
 
@@ -898,7 +909,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
        case 3:         /* NAK */
                /* The last valid PSN seen is the previous request's. */
                if (qp->s_last != qp->s_tail)
-                       qp->s_last_psn = wqe->psn - 1;
+                       update_last_psn(qp, wqe->psn - 1);
                switch ((aeth >> IPATH_AETH_CREDIT_SHIFT) &
                        IPATH_AETH_CREDIT_MASK) {
                case 0: /* PSN sequence error */
@@ -1071,7 +1082,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                 * since we don't want s_sge modified.
                 */
                qp->s_len -= pmtu;
-               qp->s_last_psn = psn;
+               update_last_psn(qp, psn);
                spin_unlock_irqrestore(&qp->s_lock, flags);
                ipath_copy_sge(&qp->s_sge, data, pmtu);
                goto bail;
@@ -1223,7 +1234,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
                         * Address range must be a subset of the original
                         * request and start on pmtu boundaries.
                         */
-                       ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
+                       ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
                                           qp->s_rdma_len, vaddr, rkey,
                                           IB_ACCESS_REMOTE_READ);
                        if (unlikely(!ok)) {
@@ -1282,6 +1293,14 @@ done:
        return 1;
 }
 
+static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
+{
+       spin_lock_irq(&qp->s_lock);
+       qp->state = IB_QPS_ERR;
+       ipath_error_qp(qp, err);
+       spin_unlock_irq(&qp->s_lock);
+}
+
 /**
  * ipath_rc_rcv - process an incoming RC packet
  * @dev: the device this packet came in on
@@ -1309,6 +1328,10 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
        struct ib_reth *reth;
        int header_in_data;
 
+       /* Validate the SLID. See Ch. 9.6.1.5 */
+       if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
+               goto done;
+
        /* Check for GRH */
        if (!has_grh) {
                ohdr = &hdr->u.oth;
@@ -1370,8 +1393,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                 */
                if (qp->r_ack_state >= OP(COMPARE_SWAP))
                        goto send_ack;
-               /* XXX Flush WQEs */
-               qp->state = IB_QPS_ERR;
+               ipath_rc_error(qp, IB_WC_REM_INV_REQ_ERR);
                qp->r_ack_state = OP(SEND_ONLY);
                qp->r_nak_state = IB_NAK_INVALID_REQUEST;
                qp->r_ack_psn = qp->r_psn;
@@ -1477,9 +1499,9 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        goto nack_inv;
                ipath_copy_sge(&qp->r_sge, data, tlen);
                qp->r_msn++;
-               if (opcode == OP(RDMA_WRITE_LAST) ||
-                   opcode == OP(RDMA_WRITE_ONLY))
+               if (!qp->r_wrid_valid)
                        break;
+               qp->r_wrid_valid = 0;
                wc.wr_id = qp->r_wr_id;
                wc.status = IB_WC_SUCCESS;
                wc.opcode = IB_WC_RECV;
@@ -1517,7 +1539,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        int ok;
 
                        /* Check rkey & NAK */
-                       ok = ipath_rkey_ok(dev, &qp->r_sge,
+                       ok = ipath_rkey_ok(qp, &qp->r_sge,
                                           qp->r_len, vaddr, rkey,
                                           IB_ACCESS_REMOTE_WRITE);
                        if (unlikely(!ok))
@@ -1559,7 +1581,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        int ok;
 
                        /* Check rkey & NAK */
-                       ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
+                       ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
                                           qp->s_rdma_len, vaddr, rkey,
                                           IB_ACCESS_REMOTE_READ);
                        if (unlikely(!ok)) {
@@ -1618,7 +1640,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        goto nack_inv;
                rkey = be32_to_cpu(ateth->rkey);
                /* Check rkey & NAK */
-               if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge,
+               if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
                                            sizeof(u64), vaddr, rkey,
                                            IB_ACCESS_REMOTE_ATOMIC)))
                        goto nack_acc;
@@ -1670,8 +1692,7 @@ nack_acc:
         * is pending though.
         */
        if (qp->r_ack_state < OP(COMPARE_SWAP)) {
-               /* XXX Flush WQEs */
-               qp->state = IB_QPS_ERR;
+               ipath_rc_error(qp, IB_WC_REM_ACCESS_ERR);
                qp->r_ack_state = OP(RDMA_WRITE_ONLY);
                qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
                qp->r_ack_psn = qp->r_psn;
index 6e23b3d632b820eac22febb91b0aab7d0269982a..dffc76016d3c23c3a0680f89d5dbd11d223a3a57 100644 (file)
 #define INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT 40
 #define INFINIPATH_HWE_RXEMEMPARITYERR_MASK 0x7FULL
 #define INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT 44
-#define INFINIPATH_HWE_RXDSYNCMEMPARITYERR  0x0000000400000000ULL
-#define INFINIPATH_HWE_MEMBISTFAILED        0x0040000000000000ULL
 #define INFINIPATH_HWE_IBCBUSTOSPCPARITYERR 0x4000000000000000ULL
 #define INFINIPATH_HWE_IBCBUSFRSPCPARITYERR 0x8000000000000000ULL
+/* txe mem parity errors (shift by INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) */
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF  0x1ULL
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC  0x2ULL
+#define INFINIPATH_HWE_TXEMEMPARITYERR_PIOLAUNCHFIFO 0x4ULL
+/* rxe mem parity errors (shift by INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) */
+#define INFINIPATH_HWE_RXEMEMPARITYERR_RCVBUF   0x01ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_LOOKUPQ  0x02ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_EAGERTID 0x04ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_EXPTID   0x08ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_FLAGBUF  0x10ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_DATAINFO 0x20ULL
+#define INFINIPATH_HWE_RXEMEMPARITYERR_HDRINFO  0x40ULL
+/* waldo specific -- find the rest in ipath_6110.c */
+#define INFINIPATH_HWE_RXDSYNCMEMPARITYERR  0x0000000400000000ULL
+/* monty specific -- find the rest in ipath_6120.c */
+#define INFINIPATH_HWE_MEMBISTFAILED   0x0040000000000000ULL
 
 /* kr_hwdiagctrl bits */
 #define INFINIPATH_DC_FORCETXEMEMPARITYERR_MASK 0xFULL
 
 /* combination link status states that we use with some frequency */
 #define IPATH_IBSTATE_MASK ((INFINIPATH_IBCS_LINKTRAININGSTATE_MASK \
-               << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \
+               << INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | \
                (INFINIPATH_IBCS_LINKSTATE_MASK \
-               <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT))
+               <<INFINIPATH_IBCS_LINKSTATE_SHIFT))
 #define IPATH_IBSTATE_INIT ((INFINIPATH_IBCS_L_STATE_INIT \
                << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \
                (INFINIPATH_IBCS_LT_STATE_LINKUP \
 
 typedef u64 ipath_err_t;
 
+/* The following change with the type of device, so
+ * need to be part of the ipath_devdata struct, or
+ * we could have problems plugging in devices of
+ * different types (e.g. one HT, one PCIE)
+ * in one system, to be managed by one driver.
+ * On the other hand, this file is may also be included
+ * by other code, so leave the declarations here
+ * temporarily. Minor footprint issue if common-model
+ * linker used, none if C89+ linker used.
+ */
+
 /* mask of defined bits for various registers */
 extern u64 infinipath_i_bitsextant;
 extern ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
@@ -309,13 +334,6 @@ extern ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant;
 /* masks that are different in various chips, or only exist in some chips */
 extern u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask;
 
-/*
- * register bits for selecting i2c direction and values, used for I2C serial
- * flash
- */
-extern u16 ipath_gpio_sda_num, ipath_gpio_scl_num;
-extern u64 ipath_gpio_sda, ipath_gpio_scl;
-
 /*
  * These are the infinipath general register numbers (not offsets).
  * The kernel registers are used directly, those beyond the kernel
index 5c1da2d25e03e6c16ff4572ff59e88de613be0f5..f7530512045d0f0e7584424e020e1e5169909a29 100644 (file)
@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
 
 static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
 {
-       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        int user = to_ipd(qp->ibqp.pd)->user;
        int i, j, ret;
        struct ib_wc wc;
@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
                        continue;
                /* Check LKEY */
                if ((user && wqe->sg_list[i].lkey == 0) ||
-                   !ipath_lkey_ok(&dev->lk_table,
-                                  &qp->r_sg_list[j], &wqe->sg_list[i],
+                   !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
                                   IB_ACCESS_LOCAL_WRITE))
                        goto bad_lkey;
                qp->r_len += wqe->sg_list[i].length;
@@ -231,6 +229,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
                }
        }
        spin_unlock_irqrestore(&rq->lock, flags);
+       qp->r_wrid_valid = 1;
 
 bail:
        return ret;
@@ -326,7 +325,7 @@ again:
        case IB_WR_RDMA_WRITE:
                if (wqe->length == 0)
                        break;
-               if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length,
+               if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_WRITE))) {
@@ -350,7 +349,7 @@ again:
                break;
 
        case IB_WR_RDMA_READ:
-               if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length,
+               if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_READ)))
@@ -365,7 +364,7 @@ again:
 
        case IB_WR_ATOMIC_CMP_AND_SWP:
        case IB_WR_ATOMIC_FETCH_AND_ADD:
-               if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64),
+               if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
                                            IB_ACCESS_REMOTE_ATOMIC)))
@@ -575,8 +574,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
                }
                if (wr->sg_list[i].length == 0)
                        continue;
-               if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table,
-                                  &wqe->sg_list[j], &wr->sg_list[i],
+               if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
                                   acc)) {
                        spin_unlock_irqrestore(&qp->s_lock, flags);
                        ret = -EINVAL;
index 941e866d9517ba84edb6078db94565f5090f2429..94033503400ca9f5f9d1ef617e799c9dd7ddb62f 100644 (file)
@@ -104,11 +104,6 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
        u32 sz;
        struct ib_srq *ret;
 
-       if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
-               ret = ERR_PTR(-ENOMEM);
-               goto done;
-       }
-
        if (srq_init_attr->attr.max_wr == 0) {
                ret = ERR_PTR(-EINVAL);
                goto done;
@@ -180,10 +175,17 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
        spin_lock_init(&srq->rq.lock);
        srq->rq.wq->head = 0;
        srq->rq.wq->tail = 0;
-       srq->rq.max_sge = srq_init_attr->attr.max_sge;
        srq->limit = srq_init_attr->attr.srq_limit;
 
-       dev->n_srqs_allocated++;
+       spin_lock(&dev->n_srqs_lock);
+       if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
+               spin_unlock(&dev->n_srqs_lock);
+               ret = ERR_PTR(-ENOMEM);
+               goto bail_wq;
+       }
+
+       dev->n_srqs_allocated++;
+       spin_unlock(&dev->n_srqs_lock);
 
        ret = &srq->ibsrq;
        goto done;
@@ -351,8 +353,13 @@ int ipath_destroy_srq(struct ib_srq *ibsrq)
        struct ipath_srq *srq = to_isrq(ibsrq);
        struct ipath_ibdev *dev = to_idev(ibsrq->device);
 
+       spin_lock(&dev->n_srqs_lock);
        dev->n_srqs_allocated--;
-       vfree(srq->rq.wq);
+       spin_unlock(&dev->n_srqs_lock);
+       if (srq->ip)
+               kref_put(&srq->ip->ref, ipath_release_mmap_info);
+       else
+               vfree(srq->rq.wq);
        kfree(srq);
 
        return 0;
index e299148c4b68ec4ae793f0805a339d3c75bbb081..182de34f9f476f84d1c289992bf61b4ff21f6cc1 100644 (file)
@@ -257,7 +257,7 @@ static ssize_t store_guid(struct device *dev,
        struct ipath_devdata *dd = dev_get_drvdata(dev);
        ssize_t ret;
        unsigned short guid[8];
-       __be64 nguid;
+       __be64 new_guid;
        u8 *ng;
        int i;
 
@@ -266,7 +266,7 @@ static ssize_t store_guid(struct device *dev,
                   &guid[4], &guid[5], &guid[6], &guid[7]) != 8)
                goto invalid;
 
-       ng = (u8 *) &nguid;
+       ng = (u8 *) &new_guid;
 
        for (i = 0; i < 8; i++) {
                if (guid[i] > 0xff)
@@ -274,7 +274,10 @@ static ssize_t store_guid(struct device *dev,
                ng[i] = guid[i];
        }
 
-       dd->ipath_guid = nguid;
+       if (new_guid == 0)
+               goto invalid;
+
+       dd->ipath_guid = new_guid;
        dd->ipath_nguid = 1;
 
        ret = strlen(buf);
@@ -297,6 +300,16 @@ static ssize_t show_nguid(struct device *dev,
        return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_nguid);
 }
 
+static ssize_t show_nports(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       struct ipath_devdata *dd = dev_get_drvdata(dev);
+
+       /* Return the number of user ports available. */
+       return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_cfgports - 1);
+}
+
 static ssize_t show_serial(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
@@ -608,6 +621,7 @@ static DEVICE_ATTR(mlid, S_IWUSR | S_IRUGO, show_mlid, store_mlid);
 static DEVICE_ATTR(mtu, S_IWUSR | S_IRUGO, show_mtu, store_mtu);
 static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, show_enabled, store_enabled);
 static DEVICE_ATTR(nguid, S_IRUGO, show_nguid, NULL);
+static DEVICE_ATTR(nports, S_IRUGO, show_nports, NULL);
 static DEVICE_ATTR(reset, S_IWUSR, NULL, store_reset);
 static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
@@ -623,6 +637,7 @@ static struct attribute *dev_attributes[] = {
        &dev_attr_mlid.attr,
        &dev_attr_mtu.attr,
        &dev_attr_nguid.attr,
+       &dev_attr_nports.attr,
        &dev_attr_serial.attr,
        &dev_attr_status.attr,
        &dev_attr_status_str.attr,
index 0fd3cded16baffab97b78934c990ae5a0944f194..e636cfd67a821f74349c48d1f64f80d3bc9e94ab 100644 (file)
@@ -246,6 +246,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
        struct ib_reth *reth;
        int header_in_data;
 
+       /* Validate the SLID. See Ch. 9.6.1.5 */
+       if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
+               goto done;
+
        /* Check for GRH */
        if (!has_grh) {
                ohdr = &hdr->u.oth;
@@ -440,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        int ok;
 
                        /* Check rkey */
-                       ok = ipath_rkey_ok(dev, &qp->r_sge, qp->r_len,
+                       ok = ipath_rkey_ok(qp, &qp->r_sge, qp->r_len,
                                           vaddr, rkey,
                                           IB_ACCESS_REMOTE_WRITE);
                        if (unlikely(!ok)) {
index 6991d1d74e3cebab1ed461108b384e37cd746848..49f1102af8b36635427459aa52faeb76b2e2afd0 100644 (file)
@@ -39,7 +39,6 @@
 static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
                    u32 *lengthp, struct ipath_sge_state *ss)
 {
-       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        int user = to_ipd(qp->ibqp.pd)->user;
        int i, j, ret;
        struct ib_wc wc;
@@ -50,8 +49,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
                        continue;
                /* Check LKEY */
                if ((user && wqe->sg_list[i].lkey == 0) ||
-                   !ipath_lkey_ok(&dev->lk_table,
-                                  j ? &ss->sg_list[j - 1] : &ss->sge,
+                   !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge,
                                   &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
                        goto bad_lkey;
                *lengthp += wqe->sg_list[i].length;
@@ -343,7 +341,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
 
                if (wr->sg_list[i].length == 0)
                        continue;
-               if (!ipath_lkey_ok(&dev->lk_table, ss.num_sge ?
+               if (!ipath_lkey_ok(qp, ss.num_sge ?
                                   sg_list + ss.num_sge - 1 : &ss.sge,
                                   &wr->sg_list[i], 0)) {
                        ret = -EINVAL;
index e32fca9faf80360ced178df98a67516b78dd4bff..413754b1d8a254d6fb26111dfe743a74d13ddcfc 100644 (file)
@@ -89,6 +89,62 @@ bail:
        return ret;
 }
 
+/**
+ * ipath_map_page - a safety wrapper around pci_map_page()
+ *
+ * A dma_addr of all 0's is interpreted by the chip as "disabled".
+ * Unfortunately, it can also be a valid dma_addr returned on some
+ * architectures.
+ *
+ * The powerpc iommu assigns dma_addrs in ascending order, so we don't
+ * have to bother with retries or mapping a dummy page to insure we
+ * don't just get the same mapping again.
+ *
+ * I'm sure we won't be so lucky with other iommu's, so FIXME.
+ */
+dma_addr_t ipath_map_page(struct pci_dev *hwdev, struct page *page,
+       unsigned long offset, size_t size, int direction)
+{
+       dma_addr_t phys;
+
+       phys = pci_map_page(hwdev, page, offset, size, direction);
+
+       if (phys == 0) {
+               pci_unmap_page(hwdev, phys, size, direction);
+               phys = pci_map_page(hwdev, page, offset, size, direction);
+               /*
+                * FIXME: If we get 0 again, we should keep this page,
+                * map another, then free the 0 page.
+                */
+       }
+
+       return phys;
+}
+
+/**
+ * ipath_map_single - a safety wrapper around pci_map_single()
+ *
+ * Same idea as ipath_map_page().
+ */
+dma_addr_t ipath_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
+       int direction)
+{
+       dma_addr_t phys;
+
+       phys = pci_map_single(hwdev, ptr, size, direction);
+
+       if (phys == 0) {
+               pci_unmap_single(hwdev, phys, size, direction);
+               phys = pci_map_single(hwdev, ptr, size, direction);
+               /*
+                * FIXME: If we get 0 again, we should keep this page,
+                * map another, then free the 0 page.
+                */
+       }
+
+       return phys;
+}
+
 /**
  * ipath_get_user_pages - lock user pages into memory
  * @start_page: the start page
index b8381c5e72bd689d7790ec043467f6d0c2d0afb0..42eaed88c281b2a194641c6231abc80bafa45893 100644 (file)
@@ -898,7 +898,8 @@ int ipath_get_counters(struct ipath_devdata *dd,
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) +
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) +
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) +
-               ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt);
+               ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt) +
+               dd->ipath_rxfc_unsupvl_errs;
        cntrs->port_rcv_remphys_errors =
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt);
        cntrs->port_xmit_discards =
@@ -911,8 +912,10 @@ int ipath_get_counters(struct ipath_devdata *dd,
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
        cntrs->port_rcv_packets =
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
-       cntrs->local_link_integrity_errors = dd->ipath_lli_errors;
-       cntrs->excessive_buffer_overrun_errors = 0; /* XXX */
+       cntrs->local_link_integrity_errors =
+               (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ?
+               dd->ipath_lli_errs : dd->ipath_lli_errors;
+       cntrs->excessive_buffer_overrun_errors = dd->ipath_overrun_thresh_errs;
 
        ret = 0;
 
@@ -1199,6 +1202,7 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
        struct ipath_ah *ah;
        struct ib_ah *ret;
        struct ipath_ibdev *dev = to_idev(pd->device);
+       unsigned long flags;
 
        /* A multicast address requires a GRH (see ch. 8.4.1). */
        if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
@@ -1225,16 +1229,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
                goto bail;
        }
 
-       spin_lock(&dev->n_ahs_lock);
+       spin_lock_irqsave(&dev->n_ahs_lock, flags);
        if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
-               spin_unlock(&dev->n_ahs_lock);
+               spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
                kfree(ah);
                ret = ERR_PTR(-ENOMEM);
                goto bail;
        }
 
        dev->n_ahs_allocated++;
-       spin_unlock(&dev->n_ahs_lock);
+       spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
 
        /* ib_create_ah() will initialize ah->ibah. */
        ah->attr = *ah_attr;
@@ -1255,10 +1259,11 @@ static int ipath_destroy_ah(struct ib_ah *ibah)
 {
        struct ipath_ibdev *dev = to_idev(ibah->device);
        struct ipath_ah *ah = to_iah(ibah);
+       unsigned long flags;
 
-       spin_lock(&dev->n_ahs_lock);
+       spin_lock_irqsave(&dev->n_ahs_lock, flags);
        dev->n_ahs_allocated--;
-       spin_unlock(&dev->n_ahs_lock);
+       spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
 
        kfree(ah);
 
@@ -1380,11 +1385,13 @@ static int enable_timer(struct ipath_devdata *dd)
         * processing.
         */
        if (dd->ipath_flags & IPATH_GPIO_INTR) {
+               u64 val;
                ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
                                 0x2074076542310ULL);
                /* Enable GPIO bit 2 interrupt */
-               ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
-                                (u64) (1 << 2));
+               val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+               val |= (u64) (1 << IPATH_GPIO_PORT0_BIT);
+               ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
        }
 
        init_timer(&dd->verbs_timer);
@@ -1399,8 +1406,17 @@ static int enable_timer(struct ipath_devdata *dd)
 static int disable_timer(struct ipath_devdata *dd)
 {
        /* Disable GPIO bit 2 interrupt */
-       if (dd->ipath_flags & IPATH_GPIO_INTR)
-               ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0);
+       if (dd->ipath_flags & IPATH_GPIO_INTR) {
+                u64 val;
+                /* Disable GPIO bit 2 interrupt */
+                val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
+                val &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT));
+                ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
+               /*
+                * We might want to undo changes to debugportselect,
+                * but how?
+                */
+       }
 
        del_timer_sync(&dd->verbs_timer);
 
@@ -1683,6 +1699,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf)
                      "RC OTH NAKs %d\n"
                      "RC timeouts %d\n"
                      "RC RDMA dup %d\n"
+                     "RC stalls   %d\n"
                      "piobuf wait %d\n"
                      "no piobuf   %d\n"
                      "PKT drops   %d\n"
@@ -1690,7 +1707,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf)
                      dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
                      dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
                      dev->n_other_naks, dev->n_timeouts,
-                     dev->n_rdma_dup_busy, dev->n_piowait,
+                     dev->n_rdma_dup_busy, dev->n_rc_stalls, dev->n_piowait,
                      dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs);
        for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
                const struct ipath_opcode_stats *si = &dev->opstats[i];
index 09bbb3f9a2176f495b1bafa2602da95f5b6faed9..8039f6e5f0c8b447b9a6161ac06dd50dbe11c418 100644 (file)
@@ -220,6 +220,7 @@ struct ipath_segarray {
 };
 
 struct ipath_mregion {
+       struct ib_pd *pd;       /* shares refcnt of ibmr.pd */
        u64 user_base;          /* User's address for this region */
        u64 iova;               /* IB start address of this region */
        size_t length;
@@ -364,12 +365,14 @@ struct ipath_qp {
        u8 r_min_rnr_timer;     /* retry timeout value for RNR NAKs */
        u8 r_reuse_sge;         /* for UC receive errors */
        u8 r_sge_inx;           /* current index into sg_list */
+       u8 r_wrid_valid;        /* r_wrid set but CQ entry not yet made */
        u8 qp_access_flags;
        u8 s_max_sge;           /* size of s_wq->sg_list */
        u8 s_retry_cnt;         /* number of times to retry */
        u8 s_rnr_retry_cnt;
        u8 s_retry;             /* requester retry counter */
        u8 s_rnr_retry;         /* requester RNR retry counter */
+       u8 s_wait_credit;       /* limit number of unacked packets sent */
        u8 s_pkey_index;        /* PKEY index to use */
        u8 timeout;             /* Timeout for this QP */
        enum ib_mtu path_mtu;
@@ -393,6 +396,8 @@ struct ipath_qp {
 #define IPATH_S_BUSY           0
 #define IPATH_S_SIGNAL_REQ_WR  1
 
+#define IPATH_PSN_CREDIT       2048
+
 /*
  * Since struct ipath_swqe is not a fixed size, we can't simply index into
  * struct ipath_qp.s_wq.  This function does the array index computation.
@@ -521,6 +526,7 @@ struct ipath_ibdev {
        u32 n_rnr_naks;
        u32 n_other_naks;
        u32 n_timeouts;
+       u32 n_rc_stalls;
        u32 n_pkt_drops;
        u32 n_vl15_dropped;
        u32 n_wqe_errs;
@@ -634,6 +640,8 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
 
 int ipath_destroy_qp(struct ib_qp *ibqp);
 
+void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err);
+
 int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                    int attr_mask, struct ib_udata *udata);
 
@@ -653,12 +661,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
 
 void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
 
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
-                 u32 len, u64 vaddr, u32 rkey, int acc);
-
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
-                 struct ib_sge *sge, int acc);
-
 void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length);
 
 void ipath_skip_sge(struct ipath_sge_state *ss, u32 length);
@@ -683,10 +685,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt,
 
 void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey);
 
-int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
+int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
                  struct ib_sge *sge, int acc);
 
-int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
+int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
                  u32 len, u64 vaddr, u32 rkey, int acc);
 
 int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
index 036fde662aa9bd759e697521876073ec2d64e786..0095bb70f34e7bbe1f0257ef13402e69865a8e83 100644 (file)
 #include "ipath_kernel.h"
 
 /**
- * ipath_unordered_wc - indicate whether write combining is ordered
+ * ipath_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: infinipath device
  *
- * PowerPC systems (at least those in the 970 processor family)
- * write partially filled store buffers in address order, but will write
- * completely filled store buffers in "random" order, and therefore must
- * have serialization for correctness with current InfiniPath chips.
+ * Nothing to do on PowerPC, so just return without error.
+ */
+int ipath_enable_wc(struct ipath_devdata *dd)
+{
+       return 0;
+}
+
+/**
+ * ipath_unordered_wc - indicate whether write combining is unordered
  *
+ * Because our performance depends on our ability to do write
+ * combining mmio writes in the most efficient way, we need to
+ * know if we are on a processor that may reorder stores when
+ * write combining.
  */
 int ipath_unordered_wc(void)
 {
index f8f9e2e8cbdd6217642076ff7842ed0b9036427b..04696e62da878ac3322d483bec9d62afbd3c7164 100644 (file)
@@ -123,6 +123,8 @@ int ipath_enable_wc(struct ipath_devdata *dd)
                        ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, "
                                   "cookie is %d\n", cookie);
                        dd->ipath_wc_cookie = cookie;
+                       dd->ipath_wc_base = (unsigned long) pioaddr;
+                       dd->ipath_wc_len = (unsigned long) piolen;
                }
        }
 
@@ -136,9 +138,16 @@ int ipath_enable_wc(struct ipath_devdata *dd)
 void ipath_disable_wc(struct ipath_devdata *dd)
 {
        if (dd->ipath_wc_cookie) {
+               int r;
                ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n");
-               mtrr_del(dd->ipath_wc_cookie, 0, 0);
-               dd->ipath_wc_cookie = 0;
+               r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base,
+                            dd->ipath_wc_len);
+               if (r < 0)
+                       dev_info(&dd->pcidev->dev,
+                                "mtrr_del(%lx, %lx, %lx) failed: %d\n",
+                                dd->ipath_wc_cookie, dd->ipath_wc_base,
+                                dd->ipath_wc_len, r);
+               dd->ipath_wc_cookie = 0; /* even on failure */
        }
 }
 
index 365a1b5f19e044f8c427b8f34440b3e93c3a6171..aecbb9083f0c06c770dfb20aba8c1068c9629e1f 100644 (file)
@@ -1,11 +1,12 @@
 config INFINIBAND_ISER
-       tristate "ISCSI RDMA Protocol"
+       tristate "iSCSI Extensions for RDMA (iSER)"
        depends on INFINIBAND && SCSI && INET
        select SCSI_ISCSI_ATTRS
        ---help---
-         Support for the ISCSI RDMA Protocol over InfiniBand.  This
-         allows you to access storage devices that speak ISER/ISCSI
-         over InfiniBand.
+         Support for the iSCSI Extensions for RDMA (iSER) Protocol
+          over InfiniBand. This allows you to access storage devices
+          that speak iSCSI over iSER over InfiniBand.
 
-         The ISER protocol is defined by IETF.
-         See <http://www.ietf.org/>.
+         The iSER protocol is defined by IETF.
+         See <http://www.ietf.org/internet-drafts/draft-ietf-ips-iser-05.txt>
+         and <http://www.infinibandta.org/members/spec/iser_annex_060418.pdf>
index 2a14fe2e3226c7a2cb987ba4979ae0fb2ee186bb..eb6f98d822899bcf71ab05ffd376a835dcc3e89f 100644 (file)
@@ -317,6 +317,8 @@ iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn)
        struct iscsi_iser_conn *iser_conn = conn->dd_data;
 
        iscsi_conn_teardown(cls_conn);
+       if (iser_conn->ib_conn)
+               iser_conn->ib_conn->iser_conn = NULL;
        kfree(iser_conn);
 }
 
index 2cf9ae0def1cfb827f883992198af29d5a8b6ba1..9c53916f28c24d89a8d8e6bbd8616cfe62783423 100644 (file)
@@ -192,7 +192,7 @@ struct iser_regd_buf {
 
 struct iser_dto {
        struct iscsi_iser_cmd_task *ctask;
-       struct iscsi_iser_conn     *conn;
+       struct iser_conn *ib_conn;
        int                        notify_enable;
 
        /* vector of registered buffers */
@@ -355,4 +355,11 @@ int  iser_post_send(struct iser_desc *tx_desc);
 
 int iser_conn_state_comp(struct iser_conn *ib_conn,
                         enum iser_ib_conn_state comp);
+
+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+                           struct iser_data_buf       *data,
+                           enum   iser_data_dir       iser_dir,
+                           enum   dma_data_direction  dma_dir);
+
+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask);
 #endif
index ccf56f6f7236a076be2c81c769a9bcf9f2f21a1e..9b3d79c796c8e1e9defbac5d3936d7f6fa44d9cc 100644 (file)
@@ -66,42 +66,6 @@ static void iser_dto_add_regd_buff(struct iser_dto *dto,
        dto->regd_vector_len++;
 }
 
-static int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
-                                 struct iser_data_buf       *data,
-                                 enum   iser_data_dir       iser_dir,
-                                 enum   dma_data_direction  dma_dir)
-{
-       struct device *dma_device;
-
-       iser_ctask->dir[iser_dir] = 1;
-       dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
-       data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
-       if (data->dma_nents == 0) {
-               iser_err("dma_map_sg failed!!!\n");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
-{
-       struct device  *dma_device;
-       struct iser_data_buf *data;
-
-       dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
-       if (iser_ctask->dir[ISER_DIR_IN]) {
-               data = &iser_ctask->data[ISER_DIR_IN];
-               dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
-       }
-
-       if (iser_ctask->dir[ISER_DIR_OUT]) {
-               data = &iser_ctask->data[ISER_DIR_OUT];
-               dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
-       }
-}
-
 /* Register user buffer memory and initialize passive rdma
  *  dto descriptor. Total data size is stored in
  *  iser_ctask->data[ISER_DIR_IN].data_len
@@ -249,7 +213,7 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
        }
 
        recv_dto = &rx_desc->dto;
-       recv_dto->conn          = iser_conn;
+       recv_dto->ib_conn = iser_conn->ib_conn;
        recv_dto->regd_vector_len = 0;
 
        regd_hdr = &rx_desc->hdr_regd_buf;
@@ -296,7 +260,7 @@ static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
        regd_hdr->virt_addr  = tx_desc; /* == &tx_desc->iser_header */
        regd_hdr->data_size  = ISER_TOTAL_HEADERS_LEN;
 
-       send_dto->conn          = iser_conn;
+       send_dto->ib_conn         = iser_conn->ib_conn;
        send_dto->notify_enable   = 1;
        send_dto->regd_vector_len = 0;
 
@@ -588,7 +552,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
                         unsigned long dto_xfer_len)
 {
        struct iser_dto        *dto = &rx_desc->dto;
-       struct iscsi_iser_conn *conn = dto->conn;
+       struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
        struct iscsi_session *session = conn->iscsi_conn->session;
        struct iscsi_cmd_task *ctask;
        struct iscsi_iser_cmd_task *iser_ctask;
@@ -641,7 +605,8 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
 void iser_snd_completion(struct iser_desc *tx_desc)
 {
        struct iser_dto        *dto = &tx_desc->dto;
-       struct iscsi_iser_conn *iser_conn = dto->conn;
+       struct iser_conn       *ib_conn = dto->ib_conn;
+       struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
        struct iscsi_conn      *conn = iser_conn->iscsi_conn;
        struct iscsi_mgmt_task *mtask;
 
@@ -652,7 +617,7 @@ void iser_snd_completion(struct iser_desc *tx_desc)
        if (tx_desc->type == ISCSI_TX_DATAOUT)
                kmem_cache_free(ig.desc_cache, tx_desc);
 
-       atomic_dec(&iser_conn->ib_conn->post_send_buf_count);
+       atomic_dec(&ib_conn->post_send_buf_count);
 
        write_lock(conn->recv_lock);
        if (conn->suspend_tx) {
@@ -698,14 +663,19 @@ void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
 void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
 {
        int deferred;
+       int is_rdma_aligned = 1;
 
        /* if we were reading, copy back to unaligned sglist,
         * anyway dma_unmap and free the copy
         */
-       if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL)
+       if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
+               is_rdma_aligned = 0;
                iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
-       if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL)
+       }
+       if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
+               is_rdma_aligned = 0;
                iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+       }
 
        if (iser_ctask->dir[ISER_DIR_IN]) {
                deferred = iser_regd_buff_release
@@ -725,7 +695,9 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
                }
        }
 
-       iser_dma_unmap_task_data(iser_ctask);
+       /* if the data was unaligned, it was already unmapped and then copied */
+       if (is_rdma_aligned)
+               iser_dma_unmap_task_data(iser_ctask);
 }
 
 void iser_dto_buffs_release(struct iser_dto *dto)
index d0b03f4265811c04f70d5d2a33acdaa9dacf8a56..0606744c3f84407b63986f7e15c097cca77a992b 100644 (file)
@@ -369,6 +369,44 @@ static void iser_page_vec_build(struct iser_data_buf *data,
        }
 }
 
+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+                           struct iser_data_buf       *data,
+                           enum   iser_data_dir       iser_dir,
+                           enum   dma_data_direction  dma_dir)
+{
+       struct device *dma_device;
+
+       iser_ctask->dir[iser_dir] = 1;
+       dma_device =
+               iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+       data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
+       if (data->dma_nents == 0) {
+               iser_err("dma_map_sg failed!!!\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
+{
+       struct device  *dma_device;
+       struct iser_data_buf *data;
+
+       dma_device =
+               iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+       if (iser_ctask->dir[ISER_DIR_IN]) {
+               data = &iser_ctask->data[ISER_DIR_IN];
+               dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
+       }
+
+       if (iser_ctask->dir[ISER_DIR_OUT]) {
+               data = &iser_ctask->data[ISER_DIR_OUT];
+               dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
+       }
+}
+
 /**
  * iser_reg_rdma_mem - Registers memory intended for RDMA,
  * obtaining rkey and va
@@ -394,6 +432,10 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
                iser_err("rdma alignment violation %d/%d aligned\n",
                         aligned_len, mem->size);
                iser_data_buf_dump(mem);
+
+               /* unmap the command data before accessing it */
+               iser_dma_unmap_task_data(iser_ctask);
+
                /* allocate copy buf, if we are writing, copy the */
                /* unaligned scatterlist, dma map the copy        */
                if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0)
index ecdca7fc1e4cf0466f58bd6d89b4153891b71e0b..18a0000349965dc03438ecf641358c18efdbdf18 100644 (file)
@@ -571,6 +571,8 @@ void iser_conn_release(struct iser_conn *ib_conn)
        /* on EVENT_ADDR_ERROR there's no device yet for this conn */
        if (device != NULL)
                iser_device_try_release(device);
+       if (ib_conn->iser_conn)
+               ib_conn->iser_conn->ib_conn = NULL;
        kfree(ib_conn);
 }
 
@@ -694,7 +696,7 @@ int iser_post_recv(struct iser_desc *rx_desc)
        struct iser_dto   *recv_dto = &rx_desc->dto;
 
        /* Retrieve conn */
-       ib_conn = recv_dto->conn->ib_conn;
+       ib_conn = recv_dto->ib_conn;
 
        iser_dto_to_iov(recv_dto, iov, 2);
 
@@ -727,7 +729,7 @@ int iser_post_send(struct iser_desc *tx_desc)
        struct iser_conn  *ib_conn;
        struct iser_dto   *dto = &tx_desc->dto;
 
-       ib_conn = dto->conn->ib_conn;
+       ib_conn = dto->ib_conn;
 
        iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
 
@@ -774,7 +776,7 @@ static void iser_comp_error_worker(void *data)
 static void iser_handle_comp_error(struct iser_desc *desc)
 {
        struct iser_dto  *dto     = &desc->dto;
-       struct iser_conn *ib_conn = dto->conn->ib_conn;
+       struct iser_conn *ib_conn = dto->ib_conn;
 
        iser_dto_buffs_release(dto);
 
index a9dda56f62c412a8af7b4be41edb94abe847b361..83eac3a66bc801d11f11d6f1535f3894b9950f18 100644 (file)
@@ -183,4 +183,13 @@ config KEYBOARD_HIL
          This driver implements support for HIL-keyboards attached
          to your machine, so normally you should say Y here.
 
+config KEYBOARD_OMAP
+       tristate "TI OMAP keypad support"
+       depends on (ARCH_OMAP1 || ARCH_OMAP2)
+       help
+         Say Y here if you want to use the OMAP keypad.
+
+         To compile this driver as a module, choose M here: the
+         module will be called omap-keypad.
+
 endif
index 2708167ba17585c062a74d7d7e5ac7946da99ad2..b265391f1f10a226e6054d3496cb296f3deeafc7 100644 (file)
@@ -15,4 +15,5 @@ obj-$(CONFIG_KEYBOARD_CORGI)          += corgikbd.o
 obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)         += hilkbd.o
+obj-$(CONFIG_KEYBOARD_OMAP)             += omap-keypad.o
 
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
new file mode 100644 (file)
index 0000000..d436287
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * linux/drivers/input/keyboard/omap-keypad.c
+ *
+ * OMAP Keypad Driver
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ *
+ * Added support for H2 & H3 Keypad
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/menelaus.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/mux.h>
+
+#undef NEW_BOARD_LEARNING_MODE
+
+static void omap_kp_tasklet(unsigned long);
+static void omap_kp_timer(unsigned long);
+
+static unsigned char keypad_state[8];
+static DEFINE_MUTEX(kp_enable_mutex);
+static int kp_enable = 1;
+static int kp_cur_group = -1;
+
+struct omap_kp {
+       struct input_dev *input;
+       struct timer_list timer;
+       int irq;
+       unsigned int rows;
+       unsigned int cols;
+       unsigned long delay;
+       unsigned int debounce;
+};
+
+DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
+
+static int *keymap;
+static unsigned int *row_gpios;
+static unsigned int *col_gpios;
+
+#ifdef CONFIG_ARCH_OMAP2
+static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
+{
+       int col;
+       for (col = 0; col < omap_kp->cols; col++) {
+               if (value & (1 << col))
+                       omap_set_gpio_dataout(col_gpios[col], 1);
+               else
+                       omap_set_gpio_dataout(col_gpios[col], 0);
+       }
+}
+
+static u8 get_row_gpio_val(struct omap_kp *omap_kp)
+{
+       int row;
+       u8 value = 0;
+
+       for (row = 0; row < omap_kp->rows; row++) {
+               if (omap_get_gpio_datain(row_gpios[row]))
+                       value |= (1 << row);
+       }
+       return value;
+}
+#else
+#define                set_col_gpio_val(x, y)  do {} while (0)
+#define                get_row_gpio_val(x)     0
+#endif
+
+static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
+                                    struct pt_regs *regs)
+{
+       struct omap_kp *omap_kp = dev_id;
+
+       /* disable keyboard interrupt and schedule for handling */
+       if (cpu_is_omap24xx()) {
+               int i;
+               for (i = 0; i < omap_kp->rows; i++)
+                       disable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+       } else
+               /* disable keyboard interrupt and schedule for handling */
+               omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+       tasklet_schedule(&kp_tasklet);
+
+       return IRQ_HANDLED;
+}
+
+static void omap_kp_timer(unsigned long data)
+{
+       tasklet_schedule(&kp_tasklet);
+}
+
+static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
+{
+       int col = 0;
+
+       /* read the keypad status */
+       if (cpu_is_omap24xx()) {
+               int i;
+               for (i = 0; i < omap_kp->rows; i++)
+                       disable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+
+               /* read the keypad status */
+               for (col = 0; col < omap_kp->cols; col++) {
+                       set_col_gpio_val(omap_kp, ~(1 << col));
+                       state[col] = ~(get_row_gpio_val(omap_kp)) & 0x3f;
+               }
+               set_col_gpio_val(omap_kp, 0);
+
+       } else {
+               /* disable keyboard interrupt and schedule for handling */
+               omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+               /* read the keypad status */
+               omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+               for (col = 0; col < omap_kp->cols; col++) {
+                       omap_writew(~(1 << col) & 0xff,
+                                   OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+
+                       udelay(omap_kp->delay);
+
+                       state[col] = ~omap_readw(OMAP_MPUIO_BASE +
+                                                OMAP_MPUIO_KBR_LATCH) & 0xff;
+               }
+               omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+               udelay(2);
+       }
+}
+
+static inline int omap_kp_find_key(int col, int row)
+{
+       int i, key;
+
+       key = KEY(col, row, 0);
+       for (i = 0; keymap[i] != 0; i++)
+               if ((keymap[i] & 0xff000000) == key)
+                       return keymap[i] & 0x00ffffff;
+       return -1;
+}
+
+static void omap_kp_tasklet(unsigned long data)
+{
+       struct omap_kp *omap_kp_data = (struct omap_kp *) data;
+       unsigned char new_state[8], changed, key_down = 0;
+       int col, row;
+       int spurious = 0;
+
+       /* check for any changes */
+       omap_kp_scan_keypad(omap_kp_data, new_state);
+
+       /* check for changes and print those */
+       for (col = 0; col < omap_kp_data->cols; col++) {
+               changed = new_state[col] ^ keypad_state[col];
+               key_down |= new_state[col];
+               if (changed == 0)
+                       continue;
+
+               for (row = 0; row < omap_kp_data->rows; row++) {
+                       int key;
+                       if (!(changed & (1 << row)))
+                               continue;
+#ifdef NEW_BOARD_LEARNING_MODE
+                       printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col,
+                              row, (new_state[col] & (1 << row)) ?
+                              "pressed" : "released");
+#else
+                       key = omap_kp_find_key(col, row);
+                       if (key < 0) {
+                               printk(KERN_WARNING
+                                     "omap-keypad: Spurious key event %d-%d\n",
+                                      col, row);
+                               /* We scan again after a couple of seconds */
+                               spurious = 1;
+                               continue;
+                       }
+
+                       if (!(kp_cur_group == (key & GROUP_MASK) ||
+                             kp_cur_group == -1))
+                               continue;
+
+                       kp_cur_group = key & GROUP_MASK;
+                       input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
+                                        new_state[col] & (1 << row));
+#endif
+               }
+       }
+       memcpy(keypad_state, new_state, sizeof(keypad_state));
+
+       if (key_down) {
+                int delay = HZ / 20;
+               /* some key is pressed - keep irq disabled and use timer
+                * to poll the keypad */
+               if (spurious)
+                       delay = 2 * HZ;
+               mod_timer(&omap_kp_data->timer, jiffies + delay);
+       } else {
+               /* enable interrupts */
+               if (cpu_is_omap24xx()) {
+                       int i;
+                       for (i = 0; i < omap_kp_data->rows; i++)
+                               enable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
+               } else {
+                       omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+                       kp_cur_group = -1;
+               }
+       }
+}
+
+static ssize_t omap_kp_enable_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%u\n", kp_enable);
+}
+
+static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr,
+                                   const char *buf, size_t count)
+{
+       int state;
+
+       if (sscanf(buf, "%u", &state) != 1)
+               return -EINVAL;
+
+       if ((state != 1) && (state != 0))
+               return -EINVAL;
+
+       mutex_lock(&kp_enable_mutex);
+       if (state != kp_enable) {
+               if (state)
+                       enable_irq(INT_KEYBOARD);
+               else
+                       disable_irq(INT_KEYBOARD);
+               kp_enable = state;
+       }
+       mutex_unlock(&kp_enable_mutex);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, omap_kp_enable_show, omap_kp_enable_store);
+
+#ifdef CONFIG_PM
+static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
+{
+       /* Nothing yet */
+
+       return 0;
+}
+
+static int omap_kp_resume(struct platform_device *dev)
+{
+       /* Nothing yet */
+
+       return 0;
+}
+#else
+#define omap_kp_suspend        NULL
+#define omap_kp_resume NULL
+#endif
+
+static int __init omap_kp_probe(struct platform_device *pdev)
+{
+       struct omap_kp *omap_kp;
+       struct input_dev *input_dev;
+       struct omap_kp_platform_data *pdata =  pdev->dev.platform_data;
+       int i, col_idx, row_idx, irq_idx, ret;
+
+       if (!pdata->rows || !pdata->cols || !pdata->keymap) {
+               printk(KERN_ERR "No rows, cols or keymap from pdata\n");
+               return -EINVAL;
+       }
+
+       omap_kp = kzalloc(sizeof(struct omap_kp), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!omap_kp || !input_dev) {
+               kfree(omap_kp);
+               input_free_device(input_dev);
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(pdev, omap_kp);
+
+       omap_kp->input = input_dev;
+
+       /* Disable the interrupt for the MPUIO keyboard */
+       if (!cpu_is_omap24xx())
+               omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+
+       keymap = pdata->keymap;
+
+       if (pdata->rep)
+               set_bit(EV_REP, input_dev->evbit);
+
+       if (pdata->delay)
+               omap_kp->delay = pdata->delay;
+
+       if (pdata->row_gpios && pdata->col_gpios) {
+               row_gpios = pdata->row_gpios;
+               col_gpios = pdata->col_gpios;
+       }
+
+       omap_kp->rows = pdata->rows;
+       omap_kp->cols = pdata->cols;
+
+       if (cpu_is_omap24xx()) {
+               /* Cols: outputs */
+               for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
+                       if (omap_request_gpio(col_gpios[col_idx]) < 0) {
+                               printk(KERN_ERR "Failed to request"
+                                      "GPIO%d for keypad\n",
+                                      col_gpios[col_idx]);
+                               goto err1;
+                       }
+                       omap_set_gpio_direction(col_gpios[col_idx], 0);
+               }
+               /* Rows: inputs */
+               for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
+                       if (omap_request_gpio(row_gpios[row_idx]) < 0) {
+                               printk(KERN_ERR "Failed to request"
+                                      "GPIO%d for keypad\n",
+                                      row_gpios[row_idx]);
+                               goto err2;
+                       }
+                       omap_set_gpio_direction(row_gpios[row_idx], 1);
+               }
+       }
+
+       setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);
+
+       /* get the irq and init timer*/
+       tasklet_enable(&kp_tasklet);
+       kp_tasklet.data = (unsigned long) omap_kp;
+
+       ret = device_create_file(&pdev->dev, &dev_attr_enable);
+       if (ret < 0)
+               goto err2;
+
+       /* setup input device */
+       set_bit(EV_KEY, input_dev->evbit);
+       for (i = 0; keymap[i] != 0; i++)
+               set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
+       input_dev->name = "omap-keypad";
+       input_dev->phys = "omap-keypad/input0";
+       input_dev->cdev.dev = &pdev->dev;
+       input_dev->private = omap_kp;
+
+       input_dev->id.bustype = BUS_HOST;
+       input_dev->id.vendor = 0x0001;
+       input_dev->id.product = 0x0001;
+       input_dev->id.version = 0x0100;
+
+       input_dev->keycode = keymap;
+       input_dev->keycodesize = sizeof(unsigned int);
+       input_dev->keycodemax = pdata->keymapsize;
+
+       ret = input_register_device(omap_kp->input);
+       if (ret < 0) {
+               printk(KERN_ERR "Unable to register omap-keypad input device\n");
+               goto err3;
+       }
+
+       if (pdata->dbounce)
+               omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
+
+       /* scan current status and enable interrupt */
+       omap_kp_scan_keypad(omap_kp, keypad_state);
+       if (!cpu_is_omap24xx()) {
+               omap_kp->irq = platform_get_irq(pdev, 0);
+               if (omap_kp->irq >= 0) {
+                       if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
+                                       "omap-keypad", omap_kp) < 0)
+                               goto err4;
+               }
+               omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+       } else {
+               for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
+                       if (request_irq(OMAP_GPIO_IRQ(row_gpios[irq_idx]),
+                                       omap_kp_interrupt,
+                                       IRQF_TRIGGER_FALLING,
+                                       "omap-keypad", omap_kp) < 0)
+                               goto err5;
+               }
+       }
+       return 0;
+err5:
+       for (i = irq_idx-1; i >=0; i--)
+               free_irq(row_gpios[i], 0);
+err4:
+       input_unregister_device(omap_kp->input);
+       input_dev = NULL;
+err3:
+       device_remove_file(&pdev->dev, &dev_attr_enable);
+err2:
+       for (i = row_idx-1; i >=0; i--)
+               omap_free_gpio(row_gpios[i]);
+err1:
+       for (i = col_idx-1; i >=0; i--)
+               omap_free_gpio(col_gpios[i]);
+
+       kfree(omap_kp);
+       input_free_device(input_dev);
+
+       return -EINVAL;
+}
+
+static int omap_kp_remove(struct platform_device *pdev)
+{
+       struct omap_kp *omap_kp = platform_get_drvdata(pdev);
+
+       /* disable keypad interrupt handling */
+       tasklet_disable(&kp_tasklet);
+       if (cpu_is_omap24xx()) {
+               int i;
+               for (i = 0; i < omap_kp->cols; i++)
+                       omap_free_gpio(col_gpios[i]);
+               for (i = 0; i < omap_kp->rows; i++) {
+                       omap_free_gpio(row_gpios[i]);
+                       free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
+               }
+       } else {
+               omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+               free_irq(omap_kp->irq, 0);
+       }
+
+       del_timer_sync(&omap_kp->timer);
+       tasklet_kill(&kp_tasklet);
+
+       /* unregister everything */
+       input_unregister_device(omap_kp->input);
+
+       kfree(omap_kp);
+
+       return 0;
+}
+
+static struct platform_driver omap_kp_driver = {
+       .probe          = omap_kp_probe,
+       .remove         = omap_kp_remove,
+       .suspend        = omap_kp_suspend,
+       .resume         = omap_kp_resume,
+       .driver         = {
+               .name   = "omap-keypad",
+       },
+};
+
+static int __devinit omap_kp_init(void)
+{
+       printk(KERN_INFO "OMAP Keypad Driver\n");
+       return platform_driver_register(&omap_kp_driver);
+}
+
+static void __exit omap_kp_exit(void)
+{
+       platform_driver_unregister(&omap_kp_driver);
+}
+
+module_init(omap_kp_init);
+module_exit(omap_kp_exit);
+
+MODULE_AUTHOR("Timo Teräs");
+MODULE_DESCRIPTION("OMAP Keypad Driver");
+MODULE_LICENSE("GPL");
index 43da8ae1b2ada35d4b2f2bf51ef9a4f2a37f74a5..1f8d6ae66b41e47ac2be94ef6d44d25ffdc72b7b 100644 (file)
@@ -1614,8 +1614,8 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
        struct sk_buff *skb;
        unsigned char *p;
        struct in_device *in_dev = NULL;
-       u32 addr = 0;           /* local ipv4 address */
-       u32 mask = 0;           /* local netmask */
+       __be32 addr = 0;                /* local ipv4 address */
+       __be32 mask = 0;                /* local netmask */
 
        if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) {
                /* take primary(first) address of interface */
index 713c4a8aa77dc347af774edc6ddf2f11fe58176b..45ba3d45bcb8a8387461883ae050aa308213a812 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/leds.h>
 #include <linux/err.h>
 #include <asm/io.h>
+#include <linux/nsc_gpio.h>
 #include <linux/scx200_gpio.h>
 
 #define DRVNAME "net48xx-led"
@@ -26,10 +27,7 @@ static struct platform_device *pdev;
 static void net48xx_error_led_set(struct led_classdev *led_cdev,
                enum led_brightness value)
 {
-       if (value)
-               scx200_gpio_set_high(NET48XX_ERROR_LED_GPIO);
-       else
-               scx200_gpio_set_low(NET48XX_ERROR_LED_GPIO);
+       scx200_gpio_ops.gpio_set(NET48XX_ERROR_LED_GPIO, value ? 1 : 0);
 }
 
 static struct led_classdev net48xx_error_led = {
@@ -81,7 +79,8 @@ static int __init net48xx_led_init(void)
 {
        int ret;
 
-       if (!scx200_gpio_present()) {
+       /* small hack, but scx200_gpio doesn't set .dev if the probe fails */
+       if (!scx200_gpio_ops.dev) {
                ret = -ENODEV;
                goto out;
        }
index a82f313d9dc97681a8d7220d25d1faa5de6eceb0..6c29fe727c0f4ea7ee30d1daac58dc5efc309fc6 100644 (file)
@@ -16,7 +16,7 @@
 #define MAX_PMU_LEVEL 0xFF
 
 static struct backlight_properties pmu_backlight_data;
-static spinlock_t pmu_backlight_lock;
+static DEFINE_SPINLOCK(pmu_backlight_lock);
 static int sleeping;
 static u8 bl_curve[FB_BACKLIGHT_LEVELS];
 
index aceb61d9fbc8dcbc377610ac0f95e4f6b5d1c40f..83f79de7174beea3859afa905fe31b73a2bb50e4 100644 (file)
@@ -397,12 +397,7 @@ static int wf_sat_detach(struct i2c_client *client)
 
 static int __init sat_sensors_init(void)
 {
-       int err;
-
-       err = i2c_add_driver(&wf_sat_driver);
-       if (err < 0)
-               return err;
-       return 0;
+       return i2c_add_driver(&wf_sat_driver);
 }
 
 static void __exit sat_sensors_exit(void)
index bf869ed03eed33c9b61c7c4c46d78e621b0e1b0e..6dd31a291d8436af9821d0b465866208daec3cd5 100644 (file)
@@ -2,6 +2,8 @@
 # Block device driver configuration
 #
 
+if BLOCK
+
 menu "Multi-device support (RAID and LVM)"
 
 config MD
@@ -251,3 +253,4 @@ config DM_MULTIPATH_EMC
 
 endmenu
 
+endif
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 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 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 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 02776814443e24df9218fed9b703542e6d66c614..82938ad6ddbd8282752af18c91dcdf37e33b392a 100644 (file)
@@ -58,6 +58,7 @@ static int adcsync;
 static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
 {
        struct input_dev *idev = ts->idev;
+
        input_report_abs(idev, ABS_X, x);
        input_report_abs(idev, ABS_Y, y);
        input_report_abs(idev, ABS_PRESSURE, pressure);
@@ -67,6 +68,7 @@ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x
 static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
 {
        struct input_dev *idev = ts->idev;
+
        input_report_abs(idev, ABS_PRESSURE, 0);
        input_sync(idev);
 }
@@ -189,6 +191,7 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
 static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
 {
        unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+
        if (machine_is_collie())
                return (!(val & (UCB_TS_CR_TSPX_LOW)));
        else
@@ -291,6 +294,7 @@ static int ucb1x00_thread(void *_ts)
 static void ucb1x00_ts_irq(int idx, void *id)
 {
        struct ucb1x00_ts *ts = id;
+
        ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
        wake_up(&ts->irq_wait);
 }
@@ -372,36 +376,43 @@ static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
 static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
 {
        struct ucb1x00_ts *ts;
+       struct input_dev *idev;
+       int err;
 
        ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
-       if (!ts)
-               return -ENOMEM;
-
-       ts->idev = input_allocate_device();
-       if (!ts->idev) {
-               kfree(ts);
-               return -ENOMEM;
+       idev = input_allocate_device();
+       if (!ts || !idev) {
+               err = -ENOMEM;
+               goto fail;
        }
 
        ts->ucb = dev->ucb;
+       ts->idev = idev;
        ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
 
-       ts->idev->private = ts;
-       ts->idev->name       = "Touchscreen panel";
-       ts->idev->id.product = ts->ucb->id;
-       ts->idev->open       = ucb1x00_ts_open;
-       ts->idev->close      = ucb1x00_ts_close;
+       idev->private    = ts;
+       idev->name       = "Touchscreen panel";
+       idev->id.product = ts->ucb->id;
+       idev->open       = ucb1x00_ts_open;
+       idev->close      = ucb1x00_ts_close;
 
-       __set_bit(EV_ABS, ts->idev->evbit);
-       __set_bit(ABS_X, ts->idev->absbit);
-       __set_bit(ABS_Y, ts->idev->absbit);
-       __set_bit(ABS_PRESSURE, ts->idev->absbit);
+       __set_bit(EV_ABS, idev->evbit);
+       __set_bit(ABS_X, idev->absbit);
+       __set_bit(ABS_Y, idev->absbit);
+       __set_bit(ABS_PRESSURE, idev->absbit);
 
-       input_register_device(ts->idev);
+       err = input_register_device(idev);
+       if (err)
+               goto fail;
 
        dev->priv = ts;
 
        return 0;
+
+ fail:
+       input_free_device(idev);
+       kfree(ts);
+       return err;
 }
 
 static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
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 6b7638b84290c0e91d4bc03e2be7328ee0388c64..cb142a66098cf1d30f520207e295d13c5f7c6bdf 100644 (file)
@@ -822,6 +822,7 @@ static int at91_mci_probe(struct platform_device *pdev)
        mmc->f_min = 375000;
        mmc->f_max = 25000000;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+       mmc->caps = MMC_CAP_BYTEBLOCK;
 
        host = mmc_priv(mmc);
        host->mmc = mmc;
@@ -850,7 +851,7 @@ static int at91_mci_probe(struct platform_device *pdev)
        /*
         * Allocate the MCI interrupt
         */
-       ret = request_irq(AT91_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host);
+       ret = request_irq(AT91RM9200_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host);
        if (ret) {
                printk(KERN_ERR "Failed to request MCI interrupt\n");
                clk_disable(mci_clk);
@@ -906,7 +907,7 @@ static int at91_mci_remove(struct platform_device *pdev)
 
        mmc_remove_host(mmc);
        at91_mci_disable();
-       free_irq(AT91_ID_MCI, host);
+       free_irq(AT91RM9200_ID_MCI, host);
        mmc_free_host(mmc);
 
        clk_disable(mci_clk);                           /* Disable the peripheral clock */
index fb6565b98f32af75a0d4a5c25547b43b87a55f7f..1b79dd271aae37ce9e9d8c8d59b98683ca4fb543 100644 (file)
@@ -956,7 +956,7 @@ static int imxmci_probe(struct platform_device *pdev)
        mmc->f_min = 150000;
        mmc->f_max = CLK_RATE/2;
        mmc->ocr_avail = MMC_VDD_32_33;
-       mmc->caps |= MMC_CAP_4_BIT_DATA;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK;
 
        /* MMC core transfer sizes tunable parameters */
        mmc->max_hw_segs = 64;
index 74eaaee66de0e59532ba5655fddac5aaeea5ba08..5b9caa7978d34311839840243e38921255f6da4b 100644 (file)
@@ -996,7 +996,6 @@ static void mmc_read_scrs(struct mmc_host *host)
 
                mmc_set_data_timeout(&data, card, 0);
 
-               data.blksz_bits = 3;
                data.blksz = 1 << 3;
                data.blocks = 1;
                data.flags = MMC_DATA_READ;
index a0e0dad1b41944de1a59ab9b4c1c6e01c1ed42e7..db0e8ad439a5f6c8e09f873bf5734d9bc51df217 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
+#include <linux/mmc/host.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -165,6 +166,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
        do {
                struct mmc_blk_request brq;
                struct mmc_command cmd;
+               u32 readcmd, writecmd;
 
                memset(&brq, 0, sizeof(struct mmc_blk_request));
                brq.mrq.cmd = &brq.cmd;
@@ -172,7 +174,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
                brq.cmd.arg = req->sector << 9;
                brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-               brq.data.blksz_bits = md->block_bits;
                brq.data.blksz = 1 << md->block_bits;
                brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
                brq.stop.opcode = MMC_STOP_TRANSMISSION;
@@ -181,20 +182,31 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
                mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
 
-               if (rq_data_dir(req) == READ) {
-                       brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
-                       brq.data.flags |= MMC_DATA_READ;
-               } else {
-                       brq.cmd.opcode = MMC_WRITE_BLOCK;
-                       brq.data.flags |= MMC_DATA_WRITE;
+               /*
+                * If the host doesn't support multiple block writes, force
+                * block writes to single block.
+                */
+               if (rq_data_dir(req) != READ &&
+                   !(card->host->caps & MMC_CAP_MULTIWRITE))
                        brq.data.blocks = 1;
-               }
 
                if (brq.data.blocks > 1) {
                        brq.data.flags |= MMC_DATA_MULTI;
                        brq.mrq.stop = &brq.stop;
+                       readcmd = MMC_READ_MULTIPLE_BLOCK;
+                       writecmd = MMC_WRITE_MULTIPLE_BLOCK;
                } else {
                        brq.mrq.stop = NULL;
+                       readcmd = MMC_READ_SINGLE_BLOCK;
+                       writecmd = MMC_WRITE_BLOCK;
+               }
+
+               if (rq_data_dir(req) == READ) {
+                       brq.cmd.opcode = readcmd;
+                       brq.data.flags |= MMC_DATA_READ;
+               } else {
+                       brq.cmd.opcode = writecmd;
+                       brq.data.flags |= MMC_DATA_WRITE;
                }
 
                brq.data.sg = mq->sg;
@@ -219,27 +231,29 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        goto cmd_err;
                }
 
-               do {
-                       int err;
-
-                       cmd.opcode = MMC_SEND_STATUS;
-                       cmd.arg = card->rca << 16;
-                       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-                       err = mmc_wait_for_cmd(card->host, &cmd, 5);
-                       if (err) {
-                               printk(KERN_ERR "%s: error %d requesting status\n",
-                                      req->rq_disk->disk_name, err);
-                               goto cmd_err;
-                       }
-               } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
+               if (rq_data_dir(req) != READ) {
+                       do {
+                               int err;
+
+                               cmd.opcode = MMC_SEND_STATUS;
+                               cmd.arg = card->rca << 16;
+                               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+                               err = mmc_wait_for_cmd(card->host, &cmd, 5);
+                               if (err) {
+                                       printk(KERN_ERR "%s: error %d requesting status\n",
+                                              req->rq_disk->disk_name, err);
+                                       goto cmd_err;
+                               }
+                       } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
 
 #if 0
-               if (cmd.resp[0] & ~0x00000900)
-                       printk(KERN_ERR "%s: status = %08x\n",
-                              req->rq_disk->disk_name, cmd.resp[0]);
-               if (mmc_decode_status(cmd.resp))
-                       goto cmd_err;
+                       if (cmd.resp[0] & ~0x00000900)
+                               printk(KERN_ERR "%s: status = %08x\n",
+                                      req->rq_disk->disk_name, cmd.resp[0]);
+                       if (mmc_decode_status(cmd.resp))
+                               goto cmd_err;
 #endif
+               }
 
                /*
                 * A block was successfully transferred.
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 1886562abdd40100956cc50b12962bd91bf484d3..2b5a0cc9ea56392efc4a82e040ab67fe66ce1617 100644 (file)
@@ -69,12 +69,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        unsigned int datactrl, timeout, irqmask;
        unsigned long long clks;
        void __iomem *base;
+       int blksz_bits;
 
        DBG(host, "blksz %04x blks %04x flags %08x\n",
-           1 << data->blksz_bits, data->blocks, data->flags);
+           data->blksz, data->blocks, data->flags);
 
        host->data = data;
-       host->size = data->blocks << data->blksz_bits;
+       host->size = data->blksz;
        host->data_xfered = 0;
 
        mmci_init_sg(host, data);
@@ -88,7 +89,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        writel(timeout, base + MMCIDATATIMER);
        writel(host->size, base + MMCIDATALENGTH);
 
-       datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
+       blksz_bits = ffs(data->blksz) - 1;
+       BUG_ON(1 << blksz_bits != data->blksz);
+
+       datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
        if (data->flags & MMC_DATA_READ) {
                datactrl |= MCI_DPSM_DIRECTION;
                irqmask = MCI_RXFIFOHALFFULLMASK;
@@ -145,7 +149,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
              unsigned int status)
 {
        if (status & MCI_DATABLOCKEND) {
-               host->data_xfered += 1 << data->blksz_bits;
+               host->data_xfered += data->blksz;
        }
        if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
                if (status & MCI_DATACRCFAIL)
@@ -505,6 +509,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
        mmc->f_min = (host->mclk + 511) / 512;
        mmc->f_max = min(host->mclk, fmax);
        mmc->ocr_avail = plat->ocr_mask;
+       mmc->caps = MMC_CAP_MULTIWRITE;
 
        /*
         * We can do SGIO
index ddf06b32c159912f6b4213364c4f0bc294fd49d4..52c9e52e6b781126ece1830f84e329293365ed1d 100644 (file)
@@ -1034,13 +1034,14 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
        host->irq = pdev->resource[1].start;
        host->base = (void __iomem*)IO_ADDRESS(r->start);
 
-       if (minfo->wire4)
-                mmc->caps |= MMC_CAP_4_BIT_DATA;
-
        mmc->ops = &mmc_omap_ops;
        mmc->f_min = 400000;
        mmc->f_max = 24000000;
        mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+       mmc->caps = MMC_CAP_BYTEBLOCK;
+
+       if (minfo->wire4)
+                mmc->caps |= MMC_CAP_4_BIT_DATA;
 
        /* Use scatterlist DMA to reduce per-transfer costs.
         * NOTE max_seg_size assumption that small blocks aren't
index 4e21b3b9d330e4abf9834c22951cb18f8062828d..fdfc3838dd796ee1d37ed9d50039e4cc05ccf331 100644 (file)
@@ -1262,7 +1262,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
        mmc->ops = &sdhci_ops;
        mmc->f_min = host->max_clk / 256;
        mmc->f_max = host->max_clk;
-       mmc->caps = MMC_CAP_4_BIT_DATA;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
 
        mmc->ocr_avail = 0;
        if (caps & SDHCI_CAN_VDD_330)
index c351c6d1a18a11ee8ed712c77248b4337c5729d5..6435a6822ad34106abc05a0d47996b4af1170e1d 100644 (file)
@@ -1323,7 +1323,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
        mmc->f_min = 375000;
        mmc->f_max = 24000000;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->caps = MMC_CAP_4_BIT_DATA;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
 
        spin_lock_init(&host->lock);
 
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 458d3c8ae1eee3904fa34cbd414d44e6a28633b3..6baf5fe142305cfa1131a0be93a838e3e803a9a4 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))
index 5b6b05ed8f3c90553d5b9d710e39d4da54edb74d..9d34056147ad5c4c026b74e58a59ffc99cb1ec62 100644 (file)
@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
         *      Slow phase with lock held.
         */
 
-       disable_irq_nosync_lockdep(dev->irq);
+       disable_irq_nosync_lockdep_irqsave(dev->irq, &flags);
 
        spin_lock(&ei_local->page_lock);
 
@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                outb_p(ENISR_ALL, e8390_base + EN0_IMR);
                spin_unlock(&ei_local->page_lock);
-               enable_irq_lockdep(dev->irq);
+               enable_irq_lockdep_irqrestore(dev->irq, &flags);
                ei_local->stat.tx_errors++;
                return 1;
        }
@@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 
        spin_unlock(&ei_local->page_lock);
-       enable_irq_lockdep(dev->irq);
+       enable_irq_lockdep_irqrestore(dev->irq, &flags);
 
        dev_kfree_skb (skb);
        ei_local->stat.tx_bytes += send_length;
index 63154774c257be95f733aef42320439aec55cd92..ff8a8c0a26d5ce33c227ab5b75cabc63472c3649 100644 (file)
@@ -24,6 +24,9 @@ config NETDEVICES
 
          If unsure, say Y.
 
+# All the following symbols are dependent on NETDEVICES - do not repeat
+# that for each of the symbols.
+if NETDEVICES
 
 config IFB
        tristate "Intermediate Functional Block support"
@@ -2852,6 +2855,8 @@ config NETCONSOLE
        If you want to log kernel messages over the network, enable this.
        See <file:Documentation/networking/netconsole.txt> for details.
 
+endif #NETDEVICES
+
 config NETPOLL
        def_bool NETCONSOLE
 
index 7f7dd450226a8f853224a987302a21b2bf24acc2..b98592a8bac8034fb899c6b7f6c452be1b1bb68e 100644 (file)
@@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Create the Extended DDP header */
        ddp = (struct ddpehdr *)skb->data;
-        ddp->deh_len = skb->len;
-        ddp->deh_hops = 1;
-        ddp->deh_pad = 0;
+        ddp->deh_len_hops = htons(skb->len + (1<<10));
         ddp->deh_sum = 0;
 
        /*
@@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
         ddp->deh_sport = 72;
 
         *((__u8 *)(ddp+1)) = 22;               /* ddp type = IP */
-        *((__u16 *)ddp)=ntohs(*((__u16 *)ddp));        /* fix up length field */
 
         skb->protocol = htons(ETH_P_ATALK);     /* Protocol has changed */
 
index 95b28aa01f4fa9bcb22b9172ee53c32045dac134..3ecf2cc53a7ca2305f76b96ef754b2acb3505bce 100644 (file)
@@ -947,7 +947,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
                return -ENOMEM;
 
        dev->base_addr = AT91_VA_BASE_EMAC;
-       dev->irq = AT91_ID_EMAC;
+       dev->irq = AT91RM9200_ID_EMAC;
        SET_MODULE_OWNER(dev);
 
        /* Install the interrupt handler */
index 7fcf015021ecf9986950f22cacbb2a6432845c07..6b4edb63c4c485faaf029164bc6b32ea99c9a982 100644 (file)
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.4.44"
-#define DRV_MODULE_RELDATE     "August 10, 2006"
+#define DRV_MODULE_VERSION     "1.4.45"
+#define DRV_MODULE_RELDATE     "September 29, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -5805,6 +5805,34 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                bp->cmd_ticks_int = bp->cmd_ticks;
        }
 
+       /* Disable MSI on 5706 if AMD 8132 bridge is found.
+        *
+        * MSI is defined to be 32-bit write.  The 5706 does 64-bit MSI writes
+        * with byte enables disabled on the unused 32-bit word.  This is legal
+        * but causes problems on the AMD 8132 which will eventually stop
+        * responding after a while.
+        *
+        * AMD believes this incompatibility is unique to the 5706, and
+        * prefers to locally disable MSI rather than globally disabling it
+        * using pci_msi_quirk.
+        */
+       if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) {
+               struct pci_dev *amd_8132 = NULL;
+
+               while ((amd_8132 = pci_get_device(PCI_VENDOR_ID_AMD,
+                                                 PCI_DEVICE_ID_AMD_8132_BRIDGE,
+                                                 amd_8132))) {
+                       u8 rev;
+
+                       pci_read_config_byte(amd_8132, PCI_REVISION_ID, &rev);
+                       if (rev >= 0x10 && rev <= 0x13) {
+                               disable_msi = 1;
+                               pci_dev_put(amd_8132);
+                               break;
+                       }
+               }
+       }
+
        bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
        bp->req_line_speed = 0;
        if (bp->phy_flags & PHY_SERDES_FLAG) {
index 0fb5f653d3cebe4b41acdc4759d1934eb745542e..c0bbddae4ec41ef998d38f17a0a0c4ec8bd28a54 100644 (file)
@@ -2252,7 +2252,7 @@ static u32 bond_glean_dev_ip(struct net_device *dev)
 {
        struct in_device *idev;
        struct in_ifaddr *ifa;
-       u32 addr = 0;
+       __be32 addr = 0;
 
        if (!dev)
                return 0;
index 22ac2df1aeb0c513e0d4822cafe5e938d56826c6..e17a1449ee105366dcb0caccc703216edd7ee537 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/8xx_immap.h>
 #include <asm/pgtable.h>
@@ -37,7 +38,6 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/commproc.h>
-#include <asm/dma-mapping.h>
 
 #include "fec_8xx.h"
 
index 95022c005f75cb3497f269476b00657e87b4c493..92590d8fc24b4ee39b9e7bf7175132d5fa5a9002 100644 (file)
@@ -6,11 +6,10 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/phy.h>
+#include <linux/dma-mapping.h>
 
 #include <linux/fs_enet_pd.h>
 
-#include <asm/dma-mapping.h>
-
 #ifdef CONFIG_CPM1
 #include <asm/commproc.h>
 
index e9e6d99a9add263619e2278f756b59ab29709aa4..7c8ccc09b60126a448a70c1ef4e3f77975a1f434 100644 (file)
@@ -287,6 +287,7 @@ comment "FIR device drivers"
 config USB_IRDA
        tristate "IrDA USB dongles"
        depends on IRDA && USB
+       select FW_LOADER
        ---help---
          Say Y here if you want to build support for the USB IrDA FIR Dongle
          device driver.  To compile it as a module, choose M here: the module
index cb62f2a9676aeb7d46395c162aed054939f93de5..7185a4ee3c1e4bf6070840964c93355bcdcad7c7 100644 (file)
@@ -110,7 +110,7 @@ static nsc_chip_t chips[] = {
        { "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8, 
          nsc_ircc_probe_338, nsc_ircc_init_338 },
        /* Contributed by Steffen Pingel - IBM X40 */
-       { "PC8738x", { 0x164e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff,
+       { "PC8738x", { 0x164e, 0x4e, 0x2e }, 0x20, 0xf4, 0xff,
          nsc_ircc_probe_39x, nsc_ircc_init_39x },
        /* Contributed by Jan Frey - IBM A30/A31 */
        { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, 
index 2eff45bedc7cbc28a0f819fe44e43feece707bfe..22358ff68c4c7d2fe200a0e5517efb21600a9802 100644 (file)
@@ -2354,6 +2354,26 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
 #define PCIID_VENDOR_INTEL 0x8086
 #define PCIID_VENDOR_ALI 0x10b9
 static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {
+       /*
+        * Subsystems needing entries:
+        * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family
+        * 0x10b9:0x1533 0x0e11:0x005a Compaq nc4000 family
+        * 0x8086:0x24cc 0x0e11:0x002a HP nx9000 family
+        */
+       {
+               /* Guessed entry */
+               .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
+               .device = 0x24cc,
+               .subvendor = 0x103c,
+               .subdevice = 0x08bc,
+               .sir_io = 0x02f8,
+               .fir_io = 0x0130,
+               .fir_irq = 0x05,
+               .fir_dma = 0x03,
+               .cfg_base = 0x004e,
+               .preconfigure = preconfigure_through_82801,
+               .name = "HP nx5000 family",
+       },
        {
                .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
                .device = 0x24cc,
@@ -2366,7 +2386,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
                .fir_dma = 0x03,
                .cfg_base = 0x004e,
                .preconfigure = preconfigure_through_82801,
-               .name = "HP nc8000",
+               .name = "HP nc8000 family",
        },
        {
                .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
@@ -2379,7 +2399,21 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
                .fir_dma = 0x03,
                .cfg_base = 0x004e,
                .preconfigure = preconfigure_through_82801,
-               .name = "HP nc6000",
+               .name = "HP nc6000 family",
+       },
+       {
+               .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */
+               .device = 0x24cc,
+               .subvendor = 0x0e11,
+               .subdevice = 0x0860,
+               /* I assume these are the same for x1000 as for the others */
+               .sir_io = 0x02e8,
+               .fir_io = 0x02f8,
+               .fir_irq = 0x07,
+               .fir_dma = 0x03,
+               .cfg_base = 0x002e,
+               .preconfigure = preconfigure_through_82801,
+               .name = "Compaq x1000 family",
        },
        {
                /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */
index d61b208b52a215d4825a72cd3929f57263c8f6d9..12103c93f7efb4622da065c77c9f184bdd76c10f 100644 (file)
@@ -149,8 +149,6 @@ enum StirFifoCtlMask {
        FIFOCTL_DIR = 0x10,
        FIFOCTL_CLR = 0x08,
        FIFOCTL_EMPTY = 0x04,
-       FIFOCTL_RXERR = 0x02,
-       FIFOCTL_TXERR = 0x01,
 };
 
 enum StirDiagMask {
@@ -615,19 +613,6 @@ static int fifo_txwait(struct stir_cb *stir, int space)
 
                pr_debug("fifo status 0x%lx count %lu\n", status, count);
 
-               /* error when receive/transmit fifo gets confused */
-               if (status & FIFOCTL_RXERR) {
-                       stir->stats.rx_fifo_errors++;
-                       stir->stats.rx_errors++;
-                       break;
-               }
-
-               if (status & FIFOCTL_TXERR) {
-                       stir->stats.tx_fifo_errors++;
-                       stir->stats.tx_errors++;
-                       break;
-               }
-
                /* is fifo receiving already, or empty */
                if (!(status & FIFOCTL_DIR)
                    || (status & FIFOCTL_EMPTY))
index 79b85f327500c4e553bccf2c69007d2e22e89468..d916e1257c471d8df1c14e172f9a25963a2c00b8 100644 (file)
@@ -1223,8 +1223,13 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase)
 
        IRDA_DEBUG(2, "%s(): len=%x\n", __FUNCTION__, len);
 
+       if ((len - 4) < 2) {
+               self->stats.rx_dropped++;
+               return FALSE;
+       }
+
        skb = dev_alloc_skb(len + 1);
-       if ((skb == NULL) || ((len - 4) < 2)) {
+       if (skb == NULL) {
                self->stats.rx_dropped++;
                return FALSE;
        }
index f429b19bf620edddfeb955077504cb67c20d4e1f..4178b4b1d2df544a5b7c20fe90a0c0b02727ddcf 100644 (file)
@@ -161,15 +161,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
        return(0);
 }
 
+static struct net_device_stats loopback_stats;
+
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
-       struct net_device_stats *stats = dev->priv;
+       struct net_device_stats *stats = &loopback_stats;
        int i;
 
-       if (!stats) {
-               return NULL;
-       }
-
        memset(stats, 0, sizeof(struct net_device_stats));
 
        for_each_possible_cpu(i) {
@@ -185,19 +183,28 @@ static struct net_device_stats *get_stats(struct net_device *dev)
        return stats;
 }
 
-static u32 loopback_get_link(struct net_device *dev)
+static u32 always_on(struct net_device *dev)
 {
        return 1;
 }
 
 static const struct ethtool_ops loopback_ethtool_ops = {
-       .get_link               = loopback_get_link,
+       .get_link               = always_on,
        .get_tso                = ethtool_op_get_tso,
        .set_tso                = ethtool_op_set_tso,
+       .get_tx_csum            = always_on,
+       .get_sg                 = always_on,
+       .get_rx_csum            = always_on,
 };
 
+/*
+ * The loopback device is special. There is only one instance and
+ * it is statically allocated. Don't do this for other devices.
+ */
 struct net_device loopback_dev = {
        .name                   = "lo",
+       .get_stats              = &get_stats,
+       .priv                   = &loopback_stats,
        .mtu                    = (16 * 1024) + 20 + 20 + 12,
        .hard_start_xmit        = loopback_xmit,
        .hard_header            = eth_header,
@@ -221,16 +228,6 @@ struct net_device loopback_dev = {
 /* Setup and register the loopback device. */
 int __init loopback_init(void)
 {
-       struct net_device_stats *stats;
-
-       /* Can survive without statistics */
-       stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-       if (stats) {
-               memset(stats, 0, sizeof(struct net_device_stats));
-               loopback_dev.priv = stats;
-               loopback_dev.get_stats = &get_stats;
-       }
-
        return register_netdev(&loopback_dev);
 };
 
index 5666ed998142475420fbd3f0a5e220a98f1afb6e..0adee733b76121126c4cbfcf0cbed8f9aadbc087 100644 (file)
@@ -600,6 +600,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
                po->chan.hdrlen = (sizeof(struct pppoe_hdr) +
                                   dev->hard_header_len);
 
+               po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr);
                po->chan.private = sk;
                po->chan.ops = &pppoe_chan_ops;
 
index c660e33f43a2e35bbc7723ced259629bd740936f..fedd1a37bc3e71fa631ea9ebb39b97d1e0cf6e15 100644 (file)
@@ -195,6 +195,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define        SMC_IRQ_FLAGS (( \
                   machine_is_omap_h2() \
                || machine_is_omap_h3() \
+               || machine_is_omap_h4() \
                || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
        ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
 
index aaf45b907a786aaa9028e60fcf6d38668653ad6d..c25ba273b74596b9727d00d695b1083229efdf36 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.65"
-#define DRV_MODULE_RELDATE     "August 07, 2006"
+#define DRV_MODULE_VERSION     "3.66"
+#define DRV_MODULE_RELDATE     "September 23, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -173,6 +173,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)},
@@ -187,6 +188,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5756)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)},
@@ -197,6 +199,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -424,6 +428,16 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
                readl(mbox);
 }
 
+static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off)
+{
+       return (readl(tp->regs + off + GRCMBOX_BASE));
+}
+
+static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val)
+{
+       writel(val, tp->regs + off + GRCMBOX_BASE);
+}
+
 #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
 #define tw32_mailbox_f(reg, val)       tw32_mailbox_flush(tp, (reg), (val))
 #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
@@ -439,6 +453,10 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
 {
        unsigned long flags;
 
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+           (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC))
+               return;
+
        spin_lock_irqsave(&tp->indirect_lock, flags);
        if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
                pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
@@ -460,6 +478,12 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 {
        unsigned long flags;
 
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+           (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) {
+               *val = 0;
+               return;
+       }
+
        spin_lock_irqsave(&tp->indirect_lock, flags);
        if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
                pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
@@ -489,6 +513,9 @@ static inline void tg3_cond_int(struct tg3 *tp)
        if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
            (tp->hw_status->status & SD_STATUS_UPDATED))
                tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+       else
+               tw32(HOSTCC_MODE, tp->coalesce_mode |
+                    (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
 }
 
 static void tg3_enable_ints(struct tg3 *tp)
@@ -654,6 +681,10 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
        unsigned int loops;
        int ret;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
+           (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL))
+               return 0;
+
        if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
                tw32_f(MAC_MI_MODE,
                     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
@@ -1004,6 +1035,24 @@ out:
                                 phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 phy_reg;
+
+               /* adjust output voltage */
+               tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
+
+               if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) {
+                       u32 phy_reg2;
+
+                       tg3_writephy(tp, MII_TG3_EPHY_TEST,
+                                    phy_reg | MII_TG3_EPHY_SHADOW_EN);
+                       /* Enable auto-MDIX */
+                       if (!tg3_readphy(tp, 0x10, &phy_reg2))
+                               tg3_writephy(tp, 0x10, phy_reg2 | 0x4000);
+                       tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg);
+               }
+       }
+
        tg3_phy_set_wirespeed(tp);
        return 0;
 }
@@ -1117,6 +1166,15 @@ static void tg3_nvram_unlock(struct tg3 *);
 
 static void tg3_power_down_phy(struct tg3 *tp)
 {
+       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+               return;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+               tg3_writephy(tp, MII_TG3_EXT_CTRL,
+                            MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+       }
+
        /* The PHY should not be powered down on some chips because
         * of bugs.
         */
@@ -1199,7 +1257,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                tg3_setup_phy(tp, 0);
        }
 
-       if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 val;
+
+               val = tr32(GRC_VCPU_EXT_CTRL);
+               tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
+       } else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
                int i;
                u32 val;
 
@@ -1223,7 +1286,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
                        udelay(40);
 
-                       mac_mode = MAC_MODE_PORT_MODE_MII;
+                       if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+                               mac_mode = MAC_MODE_PORT_MODE_GMII;
+                       else
+                               mac_mode = MAC_MODE_PORT_MODE_MII;
 
                        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
                            !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
@@ -1301,15 +1367,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        }
 
        if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
-           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
-               /* Turn off the PHY */
-               if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
-                       tg3_writephy(tp, MII_TG3_EXT_CTRL,
-                                    MII_TG3_EXT_CTRL_FORCE_LED_OFF);
-                       tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
-                       tg3_power_down_phy(tp);
-               }
-       }
+           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+               tg3_power_down_phy(tp);
 
        tg3_frob_aux_power(tp);
 
@@ -1467,6 +1526,13 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
                break;
 
        default:
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+                       *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
+                                SPEED_10;
+                       *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
+                                 DUPLEX_HALF;
+                       break;
+               }
                *speed = SPEED_INVALID;
                *duplex = DUPLEX_INVALID;
                break;
@@ -1749,7 +1815,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 
        if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
                tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
-       else
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
                tg3_writephy(tp, MII_TG3_IMASK, ~0);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2406,24 +2472,27 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
        expected_sg_dig_ctrl |= (1 << 12);
 
        if (sg_dig_ctrl != expected_sg_dig_ctrl) {
+               if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
+                   tp->serdes_counter &&
+                   ((mac_status & (MAC_STATUS_PCS_SYNCED |
+                                   MAC_STATUS_RCVD_CFG)) ==
+                    MAC_STATUS_PCS_SYNCED)) {
+                       tp->serdes_counter--;
+                       current_link_up = 1;
+                       goto out;
+               }
+restart_autoneg:
                if (workaround)
                        tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
                tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30));
                udelay(5);
                tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
 
-               tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
+               tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+               tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
        } else if (mac_status & (MAC_STATUS_PCS_SYNCED |
                                 MAC_STATUS_SIGNAL_DET)) {
-               int i;
-
-               /* Giver time to negotiate (~200ms) */
-               for (i = 0; i < 40000; i++) {
-                       sg_dig_status = tr32(SG_DIG_STATUS);
-                       if (sg_dig_status & (0x3))
-                               break;
-                       udelay(5);
-               }
+               sg_dig_status = tr32(SG_DIG_STATUS);
                mac_status = tr32(MAC_STATUS);
 
                if ((sg_dig_status & (1 << 1)) &&
@@ -2439,10 +2508,11 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
 
                        tg3_setup_flow_control(tp, local_adv, remote_adv);
                        current_link_up = 1;
-                       tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+                       tp->serdes_counter = 0;
+                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
                } else if (!(sg_dig_status & (1 << 1))) {
-                       if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED)
-                               tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+                       if (tp->serdes_counter)
+                               tp->serdes_counter--;
                        else {
                                if (workaround) {
                                        u32 val = serdes_cfg;
@@ -2466,9 +2536,17 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
                                    !(mac_status & MAC_STATUS_RCVD_CFG)) {
                                        tg3_setup_flow_control(tp, 0, 0);
                                        current_link_up = 1;
-                               }
+                                       tp->tg3_flags2 |=
+                                               TG3_FLG2_PARALLEL_DETECT;
+                                       tp->serdes_counter =
+                                               SERDES_PARALLEL_DET_TIMEOUT;
+                               } else
+                                       goto restart_autoneg;
                        }
                }
+       } else {
+               tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+               tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
        }
 
 out:
@@ -2599,14 +2677,16 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
                                    MAC_STATUS_CFG_CHANGED));
                udelay(5);
                if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED |
-                                        MAC_STATUS_CFG_CHANGED)) == 0)
+                                        MAC_STATUS_CFG_CHANGED |
+                                        MAC_STATUS_LNKSTATE_CHANGED)) == 0)
                        break;
        }
 
        mac_status = tr32(MAC_STATUS);
        if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) {
                current_link_up = 0;
-               if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+               if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+                   tp->serdes_counter == 0) {
                        tw32_f(MAC_MODE, (tp->mac_mode |
                                          MAC_MODE_SEND_CONFIGS));
                        udelay(1);
@@ -2711,7 +2791,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                        tg3_writephy(tp, MII_BMCR, bmcr);
 
                        tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
-                       tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
+                       tp->serdes_counter = SERDES_AN_TIMEOUT_5714S;
                        tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
 
                        return err;
@@ -2816,9 +2896,9 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
 
 static void tg3_serdes_parallel_detect(struct tg3 *tp)
 {
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) {
+       if (tp->serdes_counter) {
                /* Give autoneg time to complete. */
-               tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+               tp->serdes_counter--;
                return;
        }
        if (!netif_carrier_ok(tp->dev) &&
@@ -3535,8 +3615,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
 
        if ((sblk->status & SD_STATUS_UPDATED) ||
            !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-               tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-                            0x00000001);
+               tg3_disable_ints(tp);
                return IRQ_RETVAL(1);
        }
        return IRQ_RETVAL(0);
@@ -4644,6 +4723,44 @@ static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
        }
 }
 
+static int tg3_poll_fw(struct tg3 *tp)
+{
+       int i;
+       u32 val;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               for (i = 0; i < 400; i++) {
+                       if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE)
+                               return 0;
+                       udelay(10);
+               }
+               return -ENODEV;
+       }
+
+       /* Wait for firmware initialization to complete. */
+       for (i = 0; i < 100000; i++) {
+               tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
+               if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+                       break;
+               udelay(10);
+       }
+
+       /* Chip might not be fitted with firmware.  Some Sun onboard
+        * parts are configured like that.  So don't signal the timeout
+        * of the above loop as an error, but do report the lack of
+        * running firmware once.
+        */
+       if (i >= 100000 &&
+           !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
+               tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
+
+               printk(KERN_INFO PFX "%s: No firmware running.\n",
+                      tp->dev->name);
+       }
+
+       return 0;
+}
+
 static void tg3_stop_fw(struct tg3 *);
 
 /* tp->lock is held. */
@@ -4651,7 +4768,7 @@ static int tg3_chip_reset(struct tg3 *tp)
 {
        u32 val;
        void (*write_op)(struct tg3 *, u32, u32);
-       int i;
+       int err;
 
        tg3_nvram_lock(tp);
 
@@ -4688,6 +4805,12 @@ static int tg3_chip_reset(struct tg3 *tp)
                }
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               tw32(VCPU_STATUS, tr32(VCPU_STATUS) | VCPU_STATUS_DRV_RESET);
+               tw32(GRC_VCPU_EXT_CTRL,
+                    tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU);
+       }
+
        if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
                val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
        tw32(GRC_MISC_CFG, val);
@@ -4811,26 +4934,9 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32_f(MAC_MODE, 0);
        udelay(40);
 
-       /* Wait for firmware initialization to complete. */
-       for (i = 0; i < 100000; i++) {
-               tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
-               if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
-                       break;
-               udelay(10);
-       }
-
-       /* Chip might not be fitted with firmare.  Some Sun onboard
-        * parts are configured like that.  So don't signal the timeout
-        * of the above loop as an error, but do report the lack of
-        * running firmware once.
-        */
-       if (i >= 100000 &&
-           !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
-               tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
-
-               printk(KERN_INFO PFX "%s: No firmware running.\n",
-                      tp->dev->name);
-       }
+       err = tg3_poll_fw(tp);
+       if (err)
+               return err;
 
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
            tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
@@ -5036,6 +5142,12 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
        BUG_ON(offset == TX_CPU_BASE &&
            (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 val = tr32(GRC_VCPU_EXT_CTRL);
+
+               tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
+               return 0;
+       }
        if (offset == RX_CPU_BASE) {
                for (i = 0; i < 10000; i++) {
                        tw32(offset + CPU_STATE, 0xffffffff);
@@ -6040,6 +6152,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                val = 1;
        else if (val > tp->rx_std_max_post)
                val = tp->rx_std_max_post;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
+                       tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
+
+               if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
+                       val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
+       }
 
        tw32(RCVBDI_STD_THRESH, val);
 
@@ -6460,7 +6579,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (err)
                return err;
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
                u32 tmp;
 
                /* Clear CRC stats. */
@@ -6660,12 +6780,14 @@ static void tg3_timer(unsigned long __opaque)
                                need_setup = 1;
                        }
                        if (need_setup) {
-                               tw32_f(MAC_MODE,
-                                    (tp->mac_mode &
-                                     ~MAC_MODE_PORT_MODE_MASK));
-                               udelay(40);
-                               tw32_f(MAC_MODE, tp->mac_mode);
-                               udelay(40);
+                               if (!tp->serdes_counter) {
+                                       tw32_f(MAC_MODE,
+                                            (tp->mac_mode &
+                                             ~MAC_MODE_PORT_MODE_MASK));
+                                       udelay(40);
+                                       tw32_f(MAC_MODE, tp->mac_mode);
+                                       udelay(40);
+                               }
                                tg3_setup_phy(tp, 0);
                        }
                } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
@@ -6674,13 +6796,29 @@ static void tg3_timer(unsigned long __opaque)
                tp->timer_counter = tp->timer_multiplier;
        }
 
-       /* Heartbeat is only sent once every 2 seconds.  */
+       /* Heartbeat is only sent once every 2 seconds.
+        *
+        * The heartbeat is to tell the ASF firmware that the host
+        * driver is still alive.  In the event that the OS crashes,
+        * ASF needs to reset the hardware to free up the FIFO space
+        * that may be filled with rx packets destined for the host.
+        * If the FIFO is full, ASF will no longer function properly.
+        *
+        * Unintended resets have been reported on real time kernels
+        * where the timer doesn't run on time.  Netpoll will also have
+        * same problem.
+        *
+        * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware
+        * to check the ring condition when the heartbeat is expiring
+        * before doing the reset.  This will prevent most unintended
+        * resets.
+        */
        if (!--tp->asf_counter) {
                if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
                        u32 val;
 
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
-                                     FWCMD_NICDRV_ALIVE2);
+                                     FWCMD_NICDRV_ALIVE3);
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
@@ -6721,8 +6859,7 @@ static int tg3_request_irq(struct tg3 *tp)
 static int tg3_test_interrupt(struct tg3 *tp)
 {
        struct net_device *dev = tp->dev;
-       int err, i;
-       u32 int_mbox = 0;
+       int err, i, intr_ok = 0;
 
        if (!netif_running(dev))
                return -ENODEV;
@@ -6743,10 +6880,18 @@ static int tg3_test_interrupt(struct tg3 *tp)
               HOSTCC_MODE_NOW);
 
        for (i = 0; i < 5; i++) {
+               u32 int_mbox, misc_host_ctrl;
+
                int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
                                        TG3_64BIT_REG_LOW);
-               if (int_mbox != 0)
+               misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
+
+               if ((int_mbox != 0) ||
+                   (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) {
+                       intr_ok = 1;
                        break;
+               }
+
                msleep(10);
        }
 
@@ -6759,7 +6904,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
        if (err)
                return err;
 
-       if (int_mbox != 0)
+       if (intr_ok)
                return 0;
 
        return -EIO;
@@ -6936,9 +7081,10 @@ static int tg3_open(struct net_device *dev)
 
                if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
                        if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
-                               u32 val = tr32(0x7c04);
+                               u32 val = tr32(PCIE_TRANSACTION_CFG);
 
-                               tw32(0x7c04, val | (1 << 29));
+                               tw32(PCIE_TRANSACTION_CFG,
+                                    val | PCIE_TRANS_CFG_1SHOT_MSI);
                        }
                }
        }
@@ -7857,7 +8003,7 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EINVAL;
        if ((wol->wolopts & WAKE_MAGIC) &&
-           tp->tg3_flags2 & TG3_FLG2_PHY_SERDES &&
+           tp->tg3_flags2 & TG3_FLG2_ANY_SERDES &&
            !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
                return -EINVAL;
 
@@ -7893,7 +8039,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
                        return -EINVAL;
                return 0;
        }
-       if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) {
+       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
+           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
                if (value)
                        dev->features |= NETIF_F_TSO6;
                else
@@ -8147,6 +8294,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
 
 #define NVRAM_TEST_SIZE 0x100
 #define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
+#define NVRAM_SELFBOOT_HW_SIZE 0x20
+#define NVRAM_SELFBOOT_DATA_SIZE 0x1c
 
 static int tg3_test_nvram(struct tg3 *tp)
 {
@@ -8158,12 +8307,14 @@ static int tg3_test_nvram(struct tg3 *tp)
 
        if (magic == TG3_EEPROM_MAGIC)
                size = NVRAM_TEST_SIZE;
-       else if ((magic & 0xff000000) == 0xa5000000) {
+       else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) {
                if ((magic & 0xe00000) == 0x200000)
                        size = NVRAM_SELFBOOT_FORMAT1_SIZE;
                else
                        return 0;
-       } else
+       } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+               size = NVRAM_SELFBOOT_HW_SIZE;
+       else
                return -EIO;
 
        buf = kmalloc(size, GFP_KERNEL);
@@ -8182,7 +8333,8 @@ static int tg3_test_nvram(struct tg3 *tp)
                goto out;
 
        /* Selfboot format */
-       if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) {
+       if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) ==
+           TG3_EEPROM_MAGIC_FW) {
                u8 *buf8 = (u8 *) buf, csum8 = 0;
 
                for (i = 0; i < size; i++)
@@ -8197,6 +8349,51 @@ static int tg3_test_nvram(struct tg3 *tp)
                goto out;
        }
 
+       if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) ==
+           TG3_EEPROM_MAGIC_HW) {
+               u8 data[NVRAM_SELFBOOT_DATA_SIZE];
+               u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+               u8 *buf8 = (u8 *) buf;
+               int j, k;
+
+               /* Separate the parity bits and the data bytes.  */
+               for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) {
+                       if ((i == 0) || (i == 8)) {
+                               int l;
+                               u8 msk;
+
+                               for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1)
+                                       parity[k++] = buf8[i] & msk;
+                               i++;
+                       }
+                       else if (i == 16) {
+                               int l;
+                               u8 msk;
+
+                               for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1)
+                                       parity[k++] = buf8[i] & msk;
+                               i++;
+
+                               for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1)
+                                       parity[k++] = buf8[i] & msk;
+                               i++;
+                       }
+                       data[j++] = buf8[i];
+               }
+
+               err = -EIO;
+               for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) {
+                       u8 hw8 = hweight8(data[i]);
+
+                       if ((hw8 & 0x1) && parity[i])
+                               goto out;
+                       else if (!(hw8 & 0x1) && !parity[i])
+                               goto out;
+               }
+               err = 0;
+               goto out;
+       }
+
        /* Bootstrap checksum at offset 0x10 */
        csum = calc_crc((unsigned char *) buf, 0x10);
        if(csum != cpu_to_le32(buf[0x10/4]))
@@ -8243,7 +8440,7 @@ static int tg3_test_link(struct tg3 *tp)
 /* Only test the commonly used registers */
 static int tg3_test_registers(struct tg3 *tp)
 {
-       int i, is_5705;
+       int i, is_5705, is_5750;
        u32 offset, read_mask, write_mask, val, save_val, read_val;
        static struct {
                u16 offset;
@@ -8251,6 +8448,7 @@ static int tg3_test_registers(struct tg3 *tp)
 #define TG3_FL_5705    0x1
 #define TG3_FL_NOT_5705        0x2
 #define TG3_FL_NOT_5788        0x4
+#define TG3_FL_NOT_5750        0x8
                u32 read_mask;
                u32 write_mask;
        } reg_tbl[] = {
@@ -8361,9 +8559,9 @@ static int tg3_test_registers(struct tg3 *tp)
                        0xffffffff, 0x00000000 },
 
                /* Buffer Manager Control Registers. */
-               { BUFMGR_MB_POOL_ADDR, 0x0000,
+               { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750,
                        0x00000000, 0x007fff80 },
-               { BUFMGR_MB_POOL_SIZE, 0x0000,
+               { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750,
                        0x00000000, 0x007fffff },
                { BUFMGR_MB_RDMA_LOW_WATER, 0x0000,
                        0x00000000, 0x0000003f },
@@ -8389,10 +8587,12 @@ static int tg3_test_registers(struct tg3 *tp)
                { 0xffff, 0x0000, 0x00000000, 0x00000000 },
        };
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+       is_5705 = is_5750 = 0;
+       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
                is_5705 = 1;
-       else
-               is_5705 = 0;
+               if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+                       is_5750 = 1;
+       }
 
        for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
                if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705))
@@ -8405,6 +8605,9 @@ static int tg3_test_registers(struct tg3 *tp)
                    (reg_tbl[i].flags & TG3_FL_NOT_5788))
                        continue;
 
+               if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750))
+                       continue;
+
                offset = (u32) reg_tbl[i].offset;
                read_mask = reg_tbl[i].read_mask;
                write_mask = reg_tbl[i].write_mask;
@@ -8496,6 +8699,13 @@ static int tg3_test_memory(struct tg3 *tp)
                { 0x00008000, 0x02000},
                { 0x00010000, 0x0c000},
                { 0xffffffff, 0x00000}
+       }, mem_tbl_5906[] = {
+               { 0x00000200, 0x00008},
+               { 0x00004000, 0x00400},
+               { 0x00006000, 0x00400},
+               { 0x00008000, 0x01000},
+               { 0x00010000, 0x01000},
+               { 0xffffffff, 0x00000}
        };
        struct mem_entry *mem_tbl;
        int err = 0;
@@ -8505,6 +8715,8 @@ static int tg3_test_memory(struct tg3 *tp)
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                        mem_tbl = mem_tbl_5755;
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                       mem_tbl = mem_tbl_5906;
                else
                        mem_tbl = mem_tbl_5705;
        } else
@@ -8541,13 +8753,41 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        return 0;
 
                mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
-                          MAC_MODE_PORT_MODE_GMII;
+                          MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY;
+               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+                       mac_mode |= MAC_MODE_PORT_MODE_MII;
+               else
+                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
                tw32(MAC_MODE, mac_mode);
        } else if (loopback_mode == TG3_PHY_LOOPBACK) {
-               tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
-                                          BMCR_SPEED1000);
+               u32 val;
+
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+                       u32 phytest;
+
+                       if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) {
+                               u32 phy;
+
+                               tg3_writephy(tp, MII_TG3_EPHY_TEST,
+                                            phytest | MII_TG3_EPHY_SHADOW_EN);
+                               if (!tg3_readphy(tp, 0x1b, &phy))
+                                       tg3_writephy(tp, 0x1b, phy & ~0x20);
+                               if (!tg3_readphy(tp, 0x10, &phy))
+                                       tg3_writephy(tp, 0x10, phy & ~0x4000);
+                               tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
+                       }
+               }
+               val = BMCR_LOOPBACK | BMCR_FULLDPLX;
+               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+                       val |= BMCR_SPEED100;
+               else
+                       val |= BMCR_SPEED1000;
+
+               tg3_writephy(tp, MII_BMCR, val);
                udelay(40);
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                       tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
+
                /* reset to prevent losing 1st rx packet intermittently */
                if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
                        tw32_f(MAC_RX_MODE, RX_MODE_RESET);
@@ -8555,7 +8795,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        tw32_f(MAC_RX_MODE, tp->rx_mode);
                }
                mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
+                          MAC_MODE_LINK_POLARITY;
+               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+                       mac_mode |= MAC_MODE_PORT_MODE_MII;
+               else
+                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
                if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
                        mac_mode &= ~MAC_MODE_LINK_POLARITY;
                        tg3_writephy(tp, MII_TG3_EXT_CTRL,
@@ -8604,7 +8848,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 
        udelay(10);
 
-       for (i = 0; i < 10; i++) {
+       /* 250 usec to allow enough time on some 10/100 Mbps devices.  */
+       for (i = 0; i < 25; i++) {
                tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
                       HOSTCC_MODE_NOW);
 
@@ -8956,7 +9201,9 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
        if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
                return;
 
-       if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000))
+       if ((magic != TG3_EEPROM_MAGIC) &&
+           ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
+           ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
                return;
 
        /*
@@ -9194,6 +9441,13 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
        }
 }
 
+static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
+{
+       tp->nvram_jedecnum = JEDEC_ATMEL;
+       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+       tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+}
+
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
@@ -9230,6 +9484,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
                        tg3_get_5755_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                        tg3_get_5787_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                       tg3_get_5906_nvram_info(tp);
                else
                        tg3_get_nvram_info(tp);
 
@@ -9703,6 +9959,12 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        /* Assume an onboard device by default.  */
        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM))
+                       tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+               return;
+       }
+
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
                u32 nic_cfg, led_cfg;
@@ -10034,7 +10296,10 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
        }
 
 out_not_found:
-       strcpy(tp->board_part_number, "none");
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               strcpy(tp->board_part_number, "BCM95906");
+       else
+               strcpy(tp->board_part_number, "none");
 }
 
 static void __devinit tg3_read_fw_ver(struct tg3 *tp)
@@ -10236,6 +10501,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
 
@@ -10245,7 +10511,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
                } else {
@@ -10262,7 +10529,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
                tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
 
        if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
@@ -10392,6 +10660,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                pci_cmd &= ~PCI_COMMAND_MEMORY;
                pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
        }
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               tp->read32_mbox = tg3_read32_mbox_5906;
+               tp->write32_mbox = tg3_write32_mbox_5906;
+               tp->write32_tx_mbox = tg3_write32_mbox_5906;
+               tp->write32_rx_mbox = tg3_write32_mbox_5906;
+       }
 
        if (tp->write32 == tg3_write_indirect_reg32 ||
            ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
@@ -10463,6 +10737,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) ||
            (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
                tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
 
@@ -10476,7 +10751,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
                        tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
-               else
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
 
@@ -10566,7 +10841,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
            (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
             (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
-             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)))
+             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
        err = tg3_phy_probe(tp);
@@ -10617,7 +10893,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
         * straddle the 4GB address boundary in some cases.
         */
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->dev->hard_start_xmit = tg3_start_xmit;
        else
                tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
@@ -10698,6 +10975,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
                else
                        tg3_nvram_unlock(tp);
        }
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               mac_offset = 0x10;
 
        /* First try to get it from MAC address mailbox. */
        tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
@@ -11181,6 +11460,12 @@ static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
                        DEFAULT_MB_MACRX_LOW_WATER_5705;
                tp->bufmgr_config.mbuf_high_water =
                        DEFAULT_MB_HIGH_WATER_5705;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+                       tp->bufmgr_config.mbuf_mac_rx_low_water =
+                               DEFAULT_MB_MACRX_LOW_WATER_5906;
+                       tp->bufmgr_config.mbuf_high_water =
+                               DEFAULT_MB_HIGH_WATER_5906;
+               }
 
                tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
                        DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780;
@@ -11224,6 +11509,8 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case PHY_ID_BCM5780:    return "5780";
        case PHY_ID_BCM5755:    return "5755";
        case PHY_ID_BCM5787:    return "5787";
+       case PHY_ID_BCM5756:    return "5722/5756";
+       case PHY_ID_BCM5906:    return "5906";
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
@@ -11526,7 +11813,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         */
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                dev->features |= NETIF_F_TSO;
-               if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
+                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
                        dev->features |= NETIF_F_TSO6;
        }
 
index 3ecf356cfb082e17cc17875aec9eaf0c7e5b3cbb..92f53000bce69f2895dad2183ac37013de7e58cb 100644 (file)
@@ -24,6 +24,8 @@
 
 #define RX_COPY_THRESHOLD              256
 
+#define TG3_RX_INTERNAL_RING_SZ_5906   32
+
 #define RX_STD_MAX_SIZE                        1536
 #define RX_STD_MAX_SIZE_5705           512
 #define RX_JUMBO_MAX_SIZE              0xdeadbeef /* XXX */
 #define  CHIPREV_ID_5752_A0_HW          0x5000
 #define  CHIPREV_ID_5752_A0             0x6000
 #define  CHIPREV_ID_5752_A1             0x6001
+#define  CHIPREV_ID_5906_A1             0xc001
 #define  GET_ASIC_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700                         0x07
 #define   ASIC_REV_5701                         0x00
 #define   ASIC_REV_5714                         0x09
 #define   ASIC_REV_5755                         0x0a
 #define   ASIC_REV_5787                         0x0b
+#define   ASIC_REV_5906                         0x0c
 #define  GET_CHIP_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX               0x70
 #define   CHIPREV_5700_BX               0x71
 #define  SNDDATAI_SCTRL_FORCE_ZERO      0x00000010
 #define SNDDATAI_STATSENAB             0x00000c0c
 #define SNDDATAI_STATSINCMASK          0x00000c10
-/* 0xc14 --> 0xc80 unused */
+#define ISO_PKT_TX                     0x00000c20
+/* 0xc24 --> 0xc80 unused */
 #define SNDDATAI_COS_CNT_0             0x00000c80
 #define SNDDATAI_COS_CNT_1             0x00000c84
 #define SNDDATAI_COS_CNT_2             0x00000c88
 #define BUFMGR_MB_MACRX_LOW_WATER      0x00004414
 #define  DEFAULT_MB_MACRX_LOW_WATER      0x00000020
 #define  DEFAULT_MB_MACRX_LOW_WATER_5705  0x00000010
+#define  DEFAULT_MB_MACRX_LOW_WATER_5906  0x00000004
 #define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
 #define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b
 #define BUFMGR_MB_HIGH_WATER           0x00004418
 #define  DEFAULT_MB_HIGH_WATER          0x00000060
 #define  DEFAULT_MB_HIGH_WATER_5705     0x00000060
+#define  DEFAULT_MB_HIGH_WATER_5906     0x00000010
 #define  DEFAULT_MB_HIGH_WATER_JUMBO    0x0000017c
 #define  DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096
 #define BUFMGR_RX_MB_ALLOC_REQ         0x0000441c
 #define TX_CPU_STATE                   0x00005404
 #define TX_CPU_PGMCTR                  0x0000541c
 
+#define VCPU_STATUS                    0x00005100
+#define  VCPU_STATUS_INIT_DONE          0x04000000
+#define  VCPU_STATUS_DRV_RESET          0x08000000
+
 /* Mailboxes */
+#define GRCMBOX_BASE                   0x00005600
 #define GRCMBOX_INTERRUPT_0            0x00005800 /* 64-bit */
 #define GRCMBOX_INTERRUPT_1            0x00005808 /* 64-bit */
 #define GRCMBOX_INTERRUPT_2            0x00005810 /* 64-bit */
 #define GRC_EEPROM_CTRL                        0x00006840
 #define GRC_MDI_CTRL                   0x00006844
 #define GRC_SEEPROM_DELAY              0x00006848
-/* 0x684c --> 0x6c00 unused */
+/* 0x684c --> 0x6890 unused */
+#define GRC_VCPU_EXT_CTRL              0x00006890
+#define GRC_VCPU_EXT_CTRL_HALT_CPU      0x00400000
+#define GRC_VCPU_EXT_CTRL_DISABLE_WOL   0x20000000
 #define GRC_FASTBOOT_PC                        0x00006894      /* 5752, 5755, 5787 */
 
 /* 0x6c00 --> 0x7000 unused */
 #define NVRAM_WRITE1                   0x00007028
 /* 0x702c --> 0x7400 unused */
 
-/* 0x7400 --> 0x8000 unused */
+/* 0x7400 --> 0x7c00 unused */
+#define PCIE_TRANSACTION_CFG           0x00007c04
+#define PCIE_TRANS_CFG_1SHOT_MSI        0x20000000
+#define PCIE_TRANS_CFG_LOM              0x00000020
+
 
 #define TG3_EEPROM_MAGIC               0x669955aa
+#define TG3_EEPROM_MAGIC_FW            0xa5000000
+#define TG3_EEPROM_MAGIC_FW_MSK                0xff000000
+#define TG3_EEPROM_MAGIC_HW            0xabcd
+#define TG3_EEPROM_MAGIC_HW_MSK                0xffff
 
 /* 32K Window into NIC internal memory */
 #define NIC_SRAM_WIN_BASE              0x00008000
 #define  FWCMD_NICDRV_FIX_DMAR          0x00000005
 #define  FWCMD_NICDRV_FIX_DMAW          0x00000006
 #define  FWCMD_NICDRV_ALIVE2            0x0000000d
+#define  FWCMD_NICDRV_ALIVE3            0x0000000e
 #define NIC_SRAM_FW_CMD_LEN_MBOX       0x00000b7c
 #define NIC_SRAM_FW_CMD_DATA_MBOX      0x00000b80
 #define NIC_SRAM_FW_ASF_STATUS_MBOX    0x00000c00
 #define MII_TG3_DSP_RW_PORT            0x15 /* DSP coefficient read/write port */
 
 #define MII_TG3_DSP_ADDRESS            0x17 /* DSP address register */
+#define MII_TG3_EPHY_PTEST             0x17 /* 5906 PHY register */
 
 #define MII_TG3_AUX_CTRL               0x18 /* auxilliary control register */
 
 #define MII_TG3_AUX_STAT_100FULL       0x0500
 #define MII_TG3_AUX_STAT_1000HALF      0x0600
 #define MII_TG3_AUX_STAT_1000FULL      0x0700
+#define MII_TG3_AUX_STAT_100           0x0008
+#define MII_TG3_AUX_STAT_FULL          0x0001
 
 #define MII_TG3_ISTAT                  0x1a /* IRQ status register */
 #define MII_TG3_IMASK                  0x1b /* IRQ mask register */
 #define MII_TG3_INT_DUPLEXCHG          0x0008
 #define MII_TG3_INT_ANEG_PAGE_RX       0x0400
 
+#define MII_TG3_EPHY_TEST              0x1f /* 5906 PHY register */
+#define MII_TG3_EPHY_SHADOW_EN         0x80
+
 /* There are two ways to manage the TX descriptors on the tigon3.
  * Either the descriptors are in host DMA'able memory, or they
  * exist only in the cards on-chip SRAM.  All 16 send bds are under
@@ -2203,7 +2233,6 @@ struct tg3 {
 #define TG3_FLG2_PCI_EXPRESS           0x00000200
 #define TG3_FLG2_ASF_NEW_HANDSHAKE     0x00000400
 #define TG3_FLG2_HW_AUTONEG            0x00000800
-#define TG3_FLG2_PHY_JUST_INITTED      0x00001000
 #define TG3_FLG2_PHY_SERDES            0x00002000
 #define TG3_FLG2_CAPACITIVE_COUPLING   0x00004000
 #define TG3_FLG2_FLASH                 0x00008000
@@ -2236,6 +2265,12 @@ struct tg3 {
        u16                             asf_counter;
        u16                             asf_multiplier;
 
+       /* 1 second counter for transient serdes link events */
+       u32                             serdes_counter;
+#define SERDES_AN_TIMEOUT_5704S                2
+#define SERDES_PARALLEL_DET_TIMEOUT    1
+#define SERDES_AN_TIMEOUT_5714S                1
+
        struct tg3_link_config          link_config;
        struct tg3_bufmgr_config        bufmgr_config;
 
@@ -2276,6 +2311,8 @@ struct tg3 {
 #define PHY_ID_BCM5780                 0x60008350
 #define PHY_ID_BCM5755                 0xbc050cc0
 #define PHY_ID_BCM5787                 0xbc050ce0
+#define PHY_ID_BCM5756                 0xbc050ed0
+#define PHY_ID_BCM5906                 0xdc00ac40
 #define PHY_ID_BCM8002                 0x60010140
 #define PHY_ID_INVALID                 0xffffffff
 #define PHY_ID_REV_MASK                        0x0000000f
@@ -2302,7 +2339,8 @@ struct tg3 {
         (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
         (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
         (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
-        (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002)
+        (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \
+        (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM8002)
 
        struct tg3_hw_stats             *hw_stats;
        dma_addr_t                      stats_mapping;
index 7ec2b2f9b7eec6750c7906ff7f281b23bb530fe5..b0bc5ddcf1b11df483912a33160ce074c75ffa5c 100644 (file)
@@ -161,7 +161,7 @@ static int cisco_rx(struct sk_buff *skb)
        struct hdlc_header *data = (struct hdlc_header*)skb->data;
        struct cisco_packet *cisco_data;
        struct in_device *in_dev;
-       u32 addr, mask;
+       __be32 addr, mask;
 
        if (skb->len < sizeof(struct hdlc_header))
                goto rx_error;
index c13b459a013789a62c1d7ade07739833791c9752..218f7b574ab3082012f2b4ec3a03262ffab98f9c 100644 (file)
@@ -469,7 +469,7 @@ static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb)
        struct net_device *dev = sp->pp_if;
        int len = skb->len;
        u8 *p, opt[6];
-       u32 rmagic;
+       u32 rmagic = 0;
 
        if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
                if (sp->pp_flags & PP_DEBUG)
@@ -763,7 +763,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
                {
                struct in_device *in_dev;
                struct in_ifaddr *ifa;
-               u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
+               __be32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
 #ifdef CONFIG_INET
                rcu_read_lock();
                if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
index ccaf28e8db0a28f529bf412b977b2546e14d266f..337c692f6fd66e98ba057cc46fc38b9a7e5fdad0 100644 (file)
@@ -1342,7 +1342,7 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
         * 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
         */
        if (haddr.c[0] == 0xFF) {
-               u32 brd = 0;
+               __be32 brd = 0;
                struct in_device *in_dev;
 
                rcu_read_lock();
@@ -1406,7 +1406,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
        int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
        int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
            && !doreset;
-       u32 addr, brd;
+       __be32 addr, brd;
 
        /*
         * 1. If we have a packet, encapsulate it and put it in the buffer
index 98b83a85c60e2d462fe92e4e39de2e6f0e977945..78c0a269a2ba3e24200b0c13e72a70c99b978141 100644 (file)
@@ -374,6 +374,7 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
        return;
 }
 
+#ifdef CONFIG_PM
 static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
 {
        struct parport_serial_private *priv = pci_get_drvdata(dev);
@@ -407,14 +408,17 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
 
        return 0;
 }
+#endif
 
 static struct pci_driver parport_serial_pci_driver = {
        .name           = "parport_serial",
        .id_table       = parport_serial_pci_tbl,
        .probe          = parport_serial_pci_probe,
        .remove         = __devexit_p(parport_serial_pci_remove),
+#ifdef CONFIG_PM
        .suspend        = parport_serial_pci_suspend,
        .resume         = parport_serial_pci_resume,
+#endif
 };
 
 
index 33a7b720539b081a8fabea5da18b06613565741d..62c804af9fbe473a5f20816d8f5fbaad3a1ff785 100644 (file)
@@ -27,7 +27,7 @@ config RTC_HCTOSYS
        help
          If you say yes here, the system time will be set using
          the value read from the specified RTC device. This is useful
-         in order to avoid unnecessary fschk runs.
+         in order to avoid unnecessary fsck runs.
 
 config RTC_HCTOSYS_DEVICE
        string "The RTC to read the time from"
index 0964d1dba92519e6fe3ab799f2c04bb4ae26db40..25589061f9310d6555d729205b09490982c19132 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
 
 #define RS5C348_REG_SECS       0
 #define RS5C348_REG_MINS       1
@@ -175,8 +175,15 @@ static int __devinit rs5c348_probe(struct spi_device *spi)
                goto kfree_exit;
        if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
                u8 buf[2];
+               struct rtc_time tm;
                if (ret & RS5C348_BIT_VDET)
                        dev_warn(&spi->dev, "voltage-low detected.\n");
+               if (ret & RS5C348_BIT_XSTP)
+                       dev_warn(&spi->dev, "oscillator-stop detected.\n");
+               rtc_time_to_tm(0, &tm); /* 1970/1/1 */
+               ret = rs5c348_rtc_set_time(&spi->dev, &tm);
+               if (ret < 0)
+                       goto kfree_exit;
                buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
                buf[1] = 0;
                ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
index 929d6fff6152a642b929d8854e515d3f8152bc1d..b250c53545033cba2a019ee4e5973bf1bac04551 100644 (file)
@@ -1,4 +1,4 @@
-if S390
+if S390 && BLOCK
 
 comment "S/390 block device drivers"
        depends on S390
index 23fa0b289173e84098c48411ac10287db517e8e1..222a8a71a5e8b439dd11df7e31ee389270a1dab9 100644 (file)
@@ -63,44 +63,26 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
  * and function code cmd.
  * In case of an exception return 3. Otherwise return result of bitwise OR of
  * resulting condition code and DIAG return code. */
-static __inline__ int
-dia250(void *iob, int cmd)
+static inline int dia250(void *iob, int cmd)
 {
+       register unsigned long reg0 asm ("0") = (unsigned long) iob;
        typedef union {
                struct dasd_diag_init_io init_io;
                struct dasd_diag_rw_io rw_io;
        } addr_type;
        int rc;
 
-       __asm__ __volatile__(
-#ifdef CONFIG_64BIT
-               "       lghi    %0,3\n"
-               "       lgr     0,%3\n"
-               "       diag    0,%2,0x250\n"
-               "0:     ipm     %0\n"
-               "       srl     %0,28\n"
-               "       or      %0,1\n"
-               "1:\n"
-               ".section __ex_table,\"a\"\n"
-               "       .align 8\n"
-               "       .quad  0b,1b\n"
-               ".previous\n"
-#else
-               "       lhi     %0,3\n"
-               "       lr      0,%3\n"
+       rc = 3;
+       asm volatile(
                "       diag    0,%2,0x250\n"
                "0:     ipm     %0\n"
                "       srl     %0,28\n"
                "       or      %0,1\n"
                "1:\n"
-               ".section __ex_table,\"a\"\n"
-               "       .align 4\n"
-               "       .long 0b,1b\n"
-               ".previous\n"
-#endif
-               : "=&d" (rc), "=m" (*(addr_type *) iob)
-               : "d" (cmd), "d" (iob), "m" (*(addr_type *) iob)
-               : "0", "1", "cc");
+               EX_TABLE(0b,1b)
+               : "+d" (rc), "=m" (*(addr_type *) iob)
+               : "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob)
+               : "1", "cc");
        return rc;
 }
 
@@ -547,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 cab2c736683a089672f5d5283926353d5d66605b..a04d9120cef0111970cb4980235781a0f76a8a2c 100644 (file)
@@ -89,28 +89,15 @@ MODULE_LICENSE("GPL");
  */
 static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
 {
-       int cc;
+       int cc = 2;     /* return unused cc 2 if pgin traps */
 
-       __asm__ __volatile__ (
-               "   lhi   %0,2\n"  /* return unused cc 2 if pgin traps */
-               "   .insn rre,0xb22e0000,%1,%2\n"  /* pgin %1,%2 */
-                "0: ipm   %0\n"
-               "   srl   %0,28\n"
+       asm volatile(
+               "       .insn   rre,0xb22e0000,%1,%2\n"  /* pgin %1,%2 */
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
                "1:\n"
-#ifndef CONFIG_64BIT
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-               "   .long  0b,1b\n"
-               ".previous"
-#else
-                ".section __ex_table,\"a\"\n"
-                "   .align 8\n"
-                "   .quad 0b,1b\n"
-                ".previous"
-#endif
-               : "=&d" (cc) 
-               : "a" (__pa(page_addr)), "a" (xpage_index) 
-               : "cc" );
+               EX_TABLE(0b,1b)
+               : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc");
        if (cc == 3)
                return -ENXIO;
        if (cc == 2) {
@@ -137,28 +124,15 @@ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
  */
 static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
 {
-       int cc;
+       int cc = 2;     /* return unused cc 2 if pgin traps */
 
-       __asm__ __volatile__ (
-               "   lhi   %0,2\n"  /* return unused cc 2 if pgout traps */
-               "   .insn rre,0xb22f0000,%1,%2\n"  /* pgout %1,%2 */
-                "0: ipm   %0\n"
-               "   srl   %0,28\n"
+       asm volatile(
+               "       .insn   rre,0xb22f0000,%1,%2\n"  /* pgout %1,%2 */
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
                "1:\n"
-#ifndef CONFIG_64BIT
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-               "   .long  0b,1b\n"
-               ".previous"
-#else
-                ".section __ex_table,\"a\"\n"
-                "   .align 8\n"
-                "   .quad 0b,1b\n"
-                ".previous"
-#endif
-               : "=&d" (cc) 
-               : "a" (__pa(page_addr)), "a" (xpage_index) 
-               : "cc" );
+               EX_TABLE(0b,1b)
+               : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc");
        if (cc == 3)
                return -ENXIO;
        if (cc == 2) {
index ef004d089712bc8a0420e204fc3d597fbfb05343..b4557fa30858038103825a70ae43402062dce96d 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
-#include <asm/cpcmd.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
 
index 985d1613baaa59235d5c6a6edcb76e91f5fa9b0c..31e335751d6d5a3788aee3676c2cfb5e4d123a18 100644 (file)
@@ -100,13 +100,12 @@ service_call(sclp_cmdw_t command, void *sccb)
 {
        int cc;
 
-       __asm__ __volatile__(
-               "   .insn rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=&d" (cc)
-               : "d" (command), "a" (__pa(sccb))
-               : "cc", "memory" );
+       asm volatile(
+               "       .insn   rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
+               : "cc", "memory");
        if (cc == 3)
                return -EIO;
        if (cc == 2)
@@ -360,16 +359,6 @@ sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
        sclp_process_queue();
 }
 
-/* Return current Time-Of-Day clock. */
-static inline u64
-sclp_get_clock(void)
-{
-       u64 result;
-
-       asm volatile ("STCK 0(%1)" : "=m" (result) : "a" (&(result)) : "cc");
-       return result;
-}
-
 /* Convert interval in jiffies to TOD ticks. */
 static inline u64
 sclp_tod_from_jiffies(unsigned long jiffies)
@@ -382,7 +371,6 @@ sclp_tod_from_jiffies(unsigned long jiffies)
 void
 sclp_sync_wait(void)
 {
-       unsigned long psw_mask;
        unsigned long flags;
        unsigned long cr0, cr0_sync;
        u64 timeout;
@@ -392,7 +380,7 @@ sclp_sync_wait(void)
        timeout = 0;
        if (timer_pending(&sclp_request_timer)) {
                /* Get timeout TOD value */
-               timeout = sclp_get_clock() +
+               timeout = get_clock() +
                          sclp_tod_from_jiffies(sclp_request_timer.expires -
                                                jiffies);
        }
@@ -406,13 +394,12 @@ sclp_sync_wait(void)
        cr0_sync |= 0x00000200;
        cr0_sync &= 0xFFFFF3AC;
        __ctl_load(cr0_sync, 0, 0);
-       asm volatile ("STOSM 0(%1),0x01"
-                     : "=m" (psw_mask) : "a" (&psw_mask) : "memory");
+       __raw_local_irq_stosm(0x01);
        /* Loop until driver state indicates finished request */
        while (sclp_running_state != sclp_running_state_idle) {
                /* Check for expired request timer */
                if (timer_pending(&sclp_request_timer) &&
-                   sclp_get_clock() > timeout &&
+                   get_clock() > timeout &&
                    del_timer(&sclp_request_timer))
                        sclp_request_timer.function(sclp_request_timer.data);
                barrier();
index 29718042c6c9a669da34d828e046fb636a6f64d1..06e2eeec8473dca2e3ff3c79ae5fab78014eac0c 100644 (file)
@@ -698,7 +698,6 @@ tty3270_alloc_view(void)
        if (!tp->freemem_pages)
                goto out_tp;
        INIT_LIST_HEAD(&tp->freemem);
-       init_timer(&tp->timer);
        for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
                tp->freemem_pages[pages] = (void *)
                        __get_free_pages(GFP_KERNEL|GFP_DMA, 0);
index 807320a41fa40f5ab1ed0b426e9831d2bb109b97..4b868f72fe89efd4a3befcf73bfdd5ef85e34ac2 100644 (file)
@@ -54,48 +54,20 @@ enum vmwdt_func {
 static int __diag288(enum vmwdt_func func, unsigned int timeout,
                            char *cmd, size_t len)
 {
-       register unsigned long __func asm("2");
-       register unsigned long __timeout asm("3");
-       register unsigned long __cmdp asm("4");
-       register unsigned long __cmdl asm("5");
+       register unsigned long __func asm("2") = func;
+       register unsigned long __timeout asm("3") = timeout;
+       register unsigned long __cmdp asm("4") = virt_to_phys(cmd);
+       register unsigned long __cmdl asm("5") = len;
        int err;
 
-       __func = func;
-       __timeout = timeout;
-       __cmdp = virt_to_phys(cmd);
-       __cmdl = len;
-       err = 0;
-       asm volatile (
-#ifdef CONFIG_64BIT
-                      "diag %2,%4,0x288\n"
-               "1:     \n"
-               ".section .fixup,\"ax\"\n"
-               "2:     lghi %0,%1\n"
-               "       jg 1b\n"
-               ".previous\n"
-               ".section __ex_table,\"a\"\n"
-               "       .align 8\n"
-               "       .quad 1b,2b\n"
-               ".previous\n"
-#else
-                      "diag %2,%4,0x288\n"
-               "1:     \n"
-               ".section .fixup,\"ax\"\n"
-               "2:     lhi %0,%1\n"
-               "       bras 1,3f\n"
-               "       .long 1b\n"
-               "3:     l 1,0(1)\n"
-               "       br 1\n"
-               ".previous\n"
-               ".section __ex_table,\"a\"\n"
-               "       .align 4\n"
-               "       .long 1b,2b\n"
-               ".previous\n"
-#endif
-               : "+&d"(err)
-               : "i"(-EINVAL), "d"(__func), "d"(__timeout),
-                 "d"(__cmdp), "d"(__cmdl)
-               : "1", "cc");
+       err = -EINVAL;
+       asm volatile(
+               "       diag    %1,%3,0x288\n"
+               "0:     la      %0,0\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "=d" (err) : "d"(__func), "d"(__timeout),
+                 "d"(__cmdp), "d"(__cmdl), "0" (-EINVAL) : "1", "cc");
        return err;
 }
 
index 438db483035d033a85013e184fcef818a75dcfd2..1398367b5f68ef14f3591f9daf53e582475557b9 100644 (file)
@@ -42,18 +42,15 @@ diag210(struct diag210 * addr)
        spin_lock_irqsave(&diag210_lock, flags);
        diag210_tmp = *addr;
 
-       asm volatile (
-               "   lhi   %0,-1\n"
-               "   sam31\n"
-               "   diag  %1,0,0x210\n"
-               "0: ipm   %0\n"
-               "   srl   %0,28\n"
-               "1: sam64\n"
-               ".section __ex_table,\"a\"\n"
-               "    .align 8\n"
-               "    .quad 0b,1b\n"
-               ".previous"
-               : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" );
+       asm volatile(
+               "       lhi     %0,-1\n"
+               "       sam31\n"
+               "       diag    %1,0,0x210\n"
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
+               "1:     sam64\n"
+               EX_TABLE(0b,1b)
+               : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory");
 
        *addr = diag210_tmp;
        spin_unlock_irqrestore(&diag210_lock, flags);
@@ -66,17 +63,14 @@ diag210(struct diag210 * addr)
 {
        int ccode;
 
-       asm volatile (
-               "   lhi   %0,-1\n"
-               "   diag  %1,0,0x210\n"
-               "0: ipm   %0\n"
-               "   srl   %0,28\n"
+       asm volatile(
+               "       lhi     %0,-1\n"
+               "       diag    %1,0,0x210\n"
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
                "1:\n"
-               ".section __ex_table,\"a\"\n"
-               "    .align 4\n"
-               "    .long 0b,1b\n"
-               ".previous"
-               : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory" );
+               EX_TABLE(0b,1b)
+               : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory");
 
        return ccode;
 }
index 95a9462f9a911ccc74faea8b9a39235f4b6cebc3..ad6d829400691826659cf3de58ff35f0fa8eed98 100644 (file)
@@ -25,106 +25,74 @@ struct tpi_info {
 static inline int stsch(struct subchannel_id schid,
                            volatile struct schib *addr)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   stsch 0(%2)\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid), "a" (addr), "m" (*addr)
-               : "cc", "1" );
+       asm volatile(
+               "       stsch   0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int stsch_err(struct subchannel_id schid,
                                volatile struct schib *addr)
 {
-       int ccode;
+       register struct subchannel_id reg1 asm ("1") = schid;
+       int ccode = -EIO;
 
-       __asm__ __volatile__(
-               "    lhi  %0,%3\n"
-               "    lr   1,%1\n"
-               "    stsch 0(%2)\n"
-               "0:  ipm  %0\n"
-               "    srl  %0,28\n"
+       asm volatile(
+               "       stsch   0(%2)\n"
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
                "1:\n"
-#ifdef CONFIG_64BIT
-               ".section __ex_table,\"a\"\n"
-               "   .align 8\n"
-               "   .quad 0b,1b\n"
-               ".previous"
-#else
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-               "   .long 0b,1b\n"
-               ".previous"
-#endif
-               : "=&d" (ccode)
-               : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
-               : "cc", "1" );
+               EX_TABLE(0b,1b)
+               : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int msch(struct subchannel_id schid,
                           volatile struct schib *addr)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   msch  0(%2)\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid), "a" (addr), "m" (*addr)
-               : "cc", "1" );
+       asm volatile(
+               "       msch    0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int msch_err(struct subchannel_id schid,
                               volatile struct schib *addr)
 {
-       int ccode;
+       register struct subchannel_id reg1 asm ("1") = schid;
+       int ccode = -EIO;
 
-       __asm__ __volatile__(
-               "    lhi  %0,%3\n"
-               "    lr   1,%1\n"
-               "    msch 0(%2)\n"
-               "0:  ipm  %0\n"
-               "    srl  %0,28\n"
+       asm volatile(
+               "       msch    0(%2)\n"
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
                "1:\n"
-#ifdef CONFIG_64BIT
-               ".section __ex_table,\"a\"\n"
-               "   .align 8\n"
-               "   .quad 0b,1b\n"
-               ".previous"
-#else
-               ".section __ex_table,\"a\"\n"
-               "   .align 4\n"
-               "   .long 0b,1b\n"
-               ".previous"
-#endif
-               : "=&d" (ccode)
-               : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
-               : "cc", "1" );
+               EX_TABLE(0b,1b)
+               : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int tsch(struct subchannel_id schid,
                           volatile struct irb *addr)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   tsch  0(%2)\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid), "a" (addr), "m" (*addr)
-               : "cc", "1" );
+       asm volatile(
+               "       tsch    0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
@@ -132,89 +100,77 @@ static inline int tpi( volatile struct tpi_info *addr)
 {
        int ccode;
 
-       __asm__ __volatile__(
-               "   tpi   0(%1)\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "a" (addr), "m" (*addr)
-               : "cc", "1" );
+       asm volatile(
+               "       tpi     0(%1)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int ssch(struct subchannel_id schid,
                           volatile struct orb *addr)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   ssch  0(%2)\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid), "a" (addr), "m" (*addr)
-               : "cc", "1" );
+       asm volatile(
+               "       ssch    0(%2)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
        return ccode;
 }
 
 static inline int rsch(struct subchannel_id schid)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   rsch\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid)
-               : "cc", "1" );
+       asm volatile(
+               "       rsch\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1) : "cc");
        return ccode;
 }
 
 static inline int csch(struct subchannel_id schid)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   csch\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid)
-               : "cc", "1" );
+       asm volatile(
+               "       csch\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1) : "cc");
        return ccode;
 }
 
 static inline int hsch(struct subchannel_id schid)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   hsch\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid)
-               : "cc", "1" );
+       asm volatile(
+               "       hsch\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1) : "cc");
        return ccode;
 }
 
 static inline int xsch(struct subchannel_id schid)
 {
+       register struct subchannel_id reg1 asm ("1") = schid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   .insn rre,0xb2760000,%1,0\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (schid)
-               : "cc", "1" );
+       asm volatile(
+               "       .insn   rre,0xb2760000,%1,0\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1) : "cc");
        return ccode;
 }
 
@@ -223,41 +179,27 @@ static inline int chsc(void *chsc_area)
        typedef struct { char _[4096]; } addr_type;
        int cc;
 
-       __asm__ __volatile__ (
-               ".insn  rre,0xb25f0000,%2,0     \n\t"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
+       asm volatile(
+               "       .insn   rre,0xb25f0000,%2,0\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
                : "=d" (cc), "=m" (*(addr_type *) chsc_area)
                : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
-               : "cc" );
-
+               : "cc");
        return cc;
 }
 
-static inline int iac( void)
-{
-       int ccode;
-
-       __asm__ __volatile__(
-               "   iac   1\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode) : : "cc", "1" );
-       return ccode;
-}
-
 static inline int rchp(int chpid)
 {
+       register unsigned int reg1 asm ("1") = chpid;
        int ccode;
 
-       __asm__ __volatile__(
-               "   lr    1,%1\n"
-               "   rchp\n"
-               "   ipm   %0\n"
-               "   srl   %0,28"
-               : "=d" (ccode)
-               : "d" (chpid)
-               : "cc", "1" );
+       asm volatile(
+               "       lr      1,%1\n"
+               "       rchp\n"
+               "       ipm     %0\n"
+               "       srl     %0,28"
+               : "=d" (ccode) : "d" (reg1) : "cc");
        return ccode;
 }
 
index 124569362f0220caaf9634ec36d8aeb725b63519..49bb9e371c327e50266ebd4caf42662fd3b54d03 100644 (file)
@@ -274,12 +274,11 @@ do_sqbs(unsigned long sch, unsigned char state, int queue,
        register unsigned long _sch asm ("1") = sch;
        unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
 
-       asm volatile (
-              " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t"
-              : "+d" (_ccq), "+d" (_queuestart)
-              : "d" ((unsigned long)state), "d" (_sch)
-              : "memory", "cc"
-       );
+       asm volatile(
+              "        .insn   rsy,0xeb000000008A,%1,0,0(%2)"
+              : "+d" (_ccq), "+d" (_queuestart)
+              : "d" ((unsigned long)state), "d" (_sch)
+              : "memory", "cc");
        *count = _ccq & 0xff;
        *start = _queuestart & 0xff;
 
@@ -299,12 +298,11 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue,
        unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
        unsigned long _state = 0;
 
-       asm volatile (
-             " .insn rrf,0xB99c0000,%1,%2,0,0  \n\t"
-             : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
-             : "d" (_sch)
-             : "memory", "cc"
-       );
+       asm volatile(
+               "       .insn   rrf,0xB99c0000,%1,%2,0,0"
+               : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
+               : "d" (_sch)
+               : "memory", "cc" );
        *count = _ccq & 0xff;
        *start = _queuestart & 0xff;
        *state = _state & 0xff;
@@ -319,69 +317,35 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue,
 static inline int
 do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
 {
+       register unsigned long reg0 asm ("0") = 2;
+       register struct subchannel_id reg1 asm ("1") = schid;
+       register unsigned long reg2 asm ("2") = mask1;
+       register unsigned long reg3 asm ("3") = mask2;
        int cc;
 
-#ifndef CONFIG_64BIT
-       asm volatile (
-               "lhi    0,2     \n\t"
-               "lr     1,%1    \n\t"
-               "lr     2,%2    \n\t"
-               "lr     3,%3    \n\t"
-               "siga   0       \n\t"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
+       asm volatile(
+               "       siga    0\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
                : "=d" (cc)
-               : "d" (schid), "d" (mask1), "d" (mask2)
-               : "cc", "0", "1", "2", "3"
-               );
-#else /* CONFIG_64BIT */
-       asm volatile (
-               "lghi   0,2     \n\t"
-               "llgfr  1,%1    \n\t"
-               "llgfr  2,%2    \n\t"
-               "llgfr  3,%3    \n\t"
-               "siga   0       \n\t"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
-               : "=d" (cc)
-               : "d" (schid), "d" (mask1), "d" (mask2)
-               : "cc", "0", "1", "2", "3"
-               );
-#endif /* CONFIG_64BIT */
+               : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc");
        return cc;
 }
 
 static inline int
 do_siga_input(struct subchannel_id schid, unsigned int mask)
 {
+       register unsigned long reg0 asm ("0") = 1;
+       register struct subchannel_id reg1 asm ("1") = schid;
+       register unsigned long reg2 asm ("2") = mask;
        int cc;
 
-#ifndef CONFIG_64BIT
-       asm volatile (
-               "lhi    0,1     \n\t"
-               "lr     1,%1    \n\t"
-               "lr     2,%2    \n\t"
-               "siga   0       \n\t"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
-               : "=d" (cc)
-               : "d" (schid), "d" (mask)
-               : "cc", "0", "1", "2", "memory"
-               );
-#else /* CONFIG_64BIT */
-       asm volatile (
-               "lghi   0,1     \n\t"
-               "llgfr  1,%1    \n\t"
-               "llgfr  2,%2    \n\t"
-               "siga   0       \n\t"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
+       asm volatile(
+               "       siga    0\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
                : "=d" (cc)
-               : "d" (schid), "d" (mask)
-               : "cc", "0", "1", "2", "memory"
-               );
-#endif /* CONFIG_64BIT */
-       
+               : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory");
        return cc;
 }
 
@@ -389,93 +353,35 @@ static inline int
 do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
               unsigned int fc)
 {
+       register unsigned long __fc asm("0") = fc;
+       register unsigned long __schid asm("1") = schid;
+       register unsigned long __mask asm("2") = mask;
        int cc;
-       __u32 busy_bit;
-
-#ifndef CONFIG_64BIT
-       asm volatile (
-               "lhi    0,0     \n\t"
-               "lr     1,%2    \n\t"
-               "lr     2,%3    \n\t"
-               "siga   0       \n\t"
-               "0:"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
-               "srl    0,31    \n\t"
-               "lr     %1,0    \n\t"
-               "1:     \n\t"
-               ".section .fixup,\"ax\"\n\t"
-               "2:     \n\t"
-               "lhi    %0,%4   \n\t"
-               "bras   1,3f    \n\t"
-               ".long 1b       \n\t"
-               "3:     \n\t"
-               "l      1,0(1)  \n\t"
-               "br     1       \n\t"
-               ".previous      \n\t"
-               ".section __ex_table,\"a\"\n\t"
-               ".align 4       \n\t"
-               ".long  0b,2b   \n\t"
-               ".previous      \n\t"
-               : "=d" (cc), "=d" (busy_bit)
-               : "d" (schid), "d" (mask),
-               "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
-               : "cc", "0", "1", "2", "memory"
-               );
-#else /* CONFIG_64BIT */
-       asm volatile (
-               "llgfr  0,%5    \n\t"
-                "lgr    1,%2    \n\t"
-               "llgfr  2,%3    \n\t"
-               "siga   0       \n\t"
-               "0:"
-               "ipm    %0      \n\t"
-               "srl    %0,28   \n\t"
-               "srl    0,31    \n\t"
-               "llgfr  %1,0    \n\t"
-               "1:     \n\t"
-               ".section .fixup,\"ax\"\n\t"
-               "lghi   %0,%4   \n\t"
-               "jg     1b      \n\t"
-               ".previous\n\t"
-               ".section __ex_table,\"a\"\n\t"
-               ".align 8       \n\t"
-               ".quad  0b,1b   \n\t"
-               ".previous      \n\t"
-               : "=d" (cc), "=d" (busy_bit)
-               : "d" (schid), "d" (mask),
-               "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
-               : "cc", "0", "1", "2", "memory"
-               );
-#endif /* CONFIG_64BIT */
-       
-       (*bb) = busy_bit;
+
+       asm volatile(
+               "       siga    0\n"
+               "0:     ipm     %0\n"
+               "       srl     %0,28\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask)
+               : "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
+               : "cc", "memory");
+       (*bb) = ((unsigned int) __fc) >> 31;
        return cc;
 }
 
 static inline unsigned long
 do_clear_global_summary(void)
 {
-
-       unsigned long time;
-
-#ifndef CONFIG_64BIT
-       asm volatile (
-               "lhi    1,3     \n\t"
-               ".insn  rre,0xb2650000,2,0      \n\t"
-               "lr     %0,3    \n\t"
-               : "=d" (time) : : "cc", "1", "2", "3"
-               );
-#else /* CONFIG_64BIT */
-       asm volatile (
-               "lghi   1,3     \n\t"
-               ".insn  rre,0xb2650000,2,0      \n\t"
-               "lgr    %0,3    \n\t"
-               : "=d" (time) : : "cc", "1", "2", "3"
-               );
-#endif /* CONFIG_64BIT */
-       
-       return time;
+       register unsigned long __fn asm("1") = 3;
+       register unsigned long __tmp asm("2");
+       register unsigned long __time asm("3");
+
+       asm volatile(
+               "       .insn   rre,0xb2650000,2,0"
+               : "+d" (__fn), "=d" (__tmp), "=d" (__time));
+       return __time;
 }
        
 /*
index 821dde86e240c611a32a3cf6c576db73f39c182f..809dd8d7f47ab034510e88ccf06dfcb39ddf3e15 100644 (file)
@@ -534,19 +534,15 @@ iucv_add_handler (handler *new)
  *
  * Returns: return code from CP's IUCV call
  */
-static __inline__ ulong
-b2f0(__u32 code, void *parm)
+static inline ulong b2f0(__u32 code, void *parm)
 {
+       register unsigned long reg0 asm ("0");
+       register unsigned long reg1 asm ("1");
        iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));
 
-       asm volatile (
-               "LRA   1,0(%1)\n\t"
-               "LR    0,%0\n\t"
-               ".long 0xb2f01000"
-               :
-               : "d" (code), "a" (parm)
-               : "0", "1"
-               );
+       reg0 = code;
+       reg1 = virt_to_phys(parm);
+       asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1));
 
        iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));
 
@@ -1248,6 +1244,8 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
 static int
 iucv_query_generic(int want_maxconn)
 {
+       register unsigned long reg0 asm ("0");
+       register unsigned long reg1 asm ("1");
        iparml_purge *parm = (iparml_purge *)grab_param();
        int bufsize, maxconn;
        int ccode;
@@ -1256,18 +1254,15 @@ iucv_query_generic(int want_maxconn)
         * Call b2f0 and store R0 (max buffer size),
         * R1 (max connections) and CC.
         */
-       asm volatile (
-               "LRA   1,0(%4)\n\t"
-               "LR    0,%3\n\t"
-               ".long 0xb2f01000\n\t"
-               "IPM   %0\n\t"
-               "SRL   %0,28\n\t"
-               "ST    0,%1\n\t"
-               "ST    1,%2\n\t"
-               : "=d" (ccode), "=m" (bufsize), "=m" (maxconn)
-               : "d" (QUERY), "a" (parm)
-               : "0", "1", "cc"
-               );
+       reg0 = QUERY;
+       reg1 = virt_to_phys(parm);
+       asm volatile(
+               "       .long   0xb2f01000\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
+       bufsize = reg0;
+       maxconn = reg1;
        release_param(parm);
 
        if (ccode)
index 5613b4564fa2967f3b78a37fff49c87e621301be..8364d5475ac7fa5a8d2898f3a65d4d70a57b3066 100644 (file)
@@ -8067,7 +8067,7 @@ qeth_arp_constructor(struct neighbour *neigh)
        neigh->parms = neigh_parms_clone(parms);
        rcu_read_unlock();
 
-       neigh->type = inet_addr_type(*(u32 *) neigh->primary_key);
+       neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
        neigh->nud_state = NUD_NOARP;
        neigh->ops = arp_direct_ops;
        neigh->output = neigh->ops->queue_xmit;
index a914129a4da9862ba3f58d2269b14a58df7e3271..479364d0332a062c2424fbf16728464fb3c29b7a 100644 (file)
@@ -253,11 +253,12 @@ s390_revalidate_registers(struct mci *mci)
                kill_task = 1;
 
 #ifndef CONFIG_64BIT
-       asm volatile("ld 0,0(%0)\n"
-                    "ld 2,8(%0)\n"
-                    "ld 4,16(%0)\n"
-                    "ld 6,24(%0)"
-                    : : "a" (&S390_lowcore.floating_pt_save_area));
+       asm volatile(
+               "       ld      0,0(%0)\n"
+               "       ld      2,8(%0)\n"
+               "       ld      4,16(%0)\n"
+               "       ld      6,24(%0)"
+               : : "a" (&S390_lowcore.floating_pt_save_area));
 #endif
 
        if (MACHINE_HAS_IEEE) {
@@ -274,37 +275,36 @@ s390_revalidate_registers(struct mci *mci)
                         * Floating point control register can't be restored.
                         * Task will be terminated.
                         */
-                       asm volatile ("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
+                       asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
                        kill_task = 1;
 
-               }
-               else
-                       asm volatile (
-                               "lfpc 0(%0)"
-                               : : "a" (fpt_creg_save_area));
-
-               asm volatile("ld  0,0(%0)\n"
-                            "ld  1,8(%0)\n"
-                            "ld  2,16(%0)\n"
-                            "ld  3,24(%0)\n"
-                            "ld  4,32(%0)\n"
-                            "ld  5,40(%0)\n"
-                            "ld  6,48(%0)\n"
-                            "ld  7,56(%0)\n"
-                            "ld  8,64(%0)\n"
-                            "ld  9,72(%0)\n"
-                            "ld 10,80(%0)\n"
-                            "ld 11,88(%0)\n"
-                            "ld 12,96(%0)\n"
-                            "ld 13,104(%0)\n"
-                            "ld 14,112(%0)\n"
-                            "ld 15,120(%0)\n"
-                            : : "a" (fpt_save_area));
+               } else
+                       asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
+
+               asm volatile(
+                       "       ld      0,0(%0)\n"
+                       "       ld      1,8(%0)\n"
+                       "       ld      2,16(%0)\n"
+                       "       ld      3,24(%0)\n"
+                       "       ld      4,32(%0)\n"
+                       "       ld      5,40(%0)\n"
+                       "       ld      6,48(%0)\n"
+                       "       ld      7,56(%0)\n"
+                       "       ld      8,64(%0)\n"
+                       "       ld      9,72(%0)\n"
+                       "       ld      10,80(%0)\n"
+                       "       ld      11,88(%0)\n"
+                       "       ld      12,96(%0)\n"
+                       "       ld      13,104(%0)\n"
+                       "       ld      14,112(%0)\n"
+                       "       ld      15,120(%0)\n"
+                       : : "a" (fpt_save_area));
        }
 
        /* Revalidate access registers */
-       asm volatile("lam 0,15,0(%0)"
-                    : : "a" (&S390_lowcore.access_regs_save_area));
+       asm volatile(
+               "       lam     0,15,0(%0)"
+               : : "a" (&S390_lowcore.access_regs_save_area));
        if (!mci->ar)
                /*
                 * Access registers have unknown contents.
@@ -321,11 +321,13 @@ s390_revalidate_registers(struct mci *mci)
                s390_handle_damage("invalid control registers.");
        else
 #ifdef CONFIG_64BIT
-               asm volatile("lctlg 0,15,0(%0)"
-                            : : "a" (&S390_lowcore.cregs_save_area));
+               asm volatile(
+                       "       lctlg   0,15,0(%0)"
+                       : : "a" (&S390_lowcore.cregs_save_area));
 #else
-               asm volatile("lctl 0,15,0(%0)"
-                            : : "a" (&S390_lowcore.cregs_save_area));
+               asm volatile(
+                       "       lctl    0,15,0(%0)"
+                       : : "a" (&S390_lowcore.cregs_save_area));
 #endif
 
        /*
@@ -339,20 +341,23 @@ s390_revalidate_registers(struct mci *mci)
         * old contents (should be zero) otherwise set it to zero.
         */
        if (!mci->pr)
-               asm volatile("sr 0,0\n"
-                            "sckpf"
-                            : : : "0", "cc");
+               asm volatile(
+                       "       sr      0,0\n"
+                       "       sckpf"
+                       : : : "0", "cc");
        else
                asm volatile(
-                       "l 0,0(%0)\n"
-                       "sckpf"
-                       : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc");
+                       "       l       0,0(%0)\n"
+                       "       sckpf"
+                       : : "a" (&S390_lowcore.tod_progreg_save_area)
+                       : "0", "cc");
 #endif
 
        /* Revalidate clock comparator register */
-       asm volatile ("stck 0(%1)\n"
-                     "sckc 0(%1)"
-                     : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+       asm volatile(
+               "       stck    0(%1)\n"
+               "       sckc    0(%1)"
+               : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
 
        /* Check if old PSW is valid */
        if (!mci->wp)
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 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 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 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 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 261eaa4429532cd9303a7dcf5cbfe0bda9985a65..d926272a40db59ed23a956078e90b58a640f0e84 100644 (file)
@@ -295,7 +295,7 @@ config SERIAL_AMBA_PL011_CONSOLE
          Even if you say Y here, the currently visible framebuffer console
          (/dev/tty0) will still be used as the system console by default, but
          you can alter that using a kernel command line option such as
-         "console=ttyAM0". (Try "man bootparam" or see the documentation of
+         "console=ttyAMA0". (Try "man bootparam" or see the documentation of
          your boot loader (lilo or loadlin) about how to pass options to the
          kernel at boot time.)
 
index 54c6b2adf7b73c57a2023768a8e11b6cc545bd9e..bf4bf103e5a0aff82476cc45a399d6b1b1f35aff 100644 (file)
@@ -139,7 +139,7 @@ static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
                 * AT91RM9200 Errata #39: RTS0 is not internally connected to PA21.
                 *  We need to drive the pin manually.
                 */
-               if (port->mapbase == AT91_BASE_US0) {
+               if (port->mapbase == AT91RM9200_BASE_US0) {
                        if (mctrl & TIOCM_RTS)
                                at91_set_gpio_value(AT91_PIN_PA21, 0);
                        else
index d34f336d53d80db4fdebd4016e8f9dedb077c770..0da3ebfff82dc55cc4750640ae7f92530f63562d 100644 (file)
@@ -1270,7 +1270,7 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
 }
 #endif
 
-static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
+static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
 {
        struct zilog_channel __iomem *channel;
        unsigned long flags;
index b10463244413c276846bbdcaebe58a0026ba4cbd..113e484c763eb23093bb0ffa08f28a12f8b8bff0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/device.h>
 #include <linux/usb.h>
+#include <linux/workqueue.h>
 #include "hcd.h"
 #include "usb.h"
 
@@ -302,11 +303,11 @@ int usb_driver_claim_interface(struct usb_driver *driver,
        dev->driver = &driver->drvwrap.driver;
        usb_set_intfdata(iface, priv);
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        iface->condition = USB_INTERFACE_BOUND;
        mark_active(iface);
        iface->pm_usage_cnt = !(driver->supports_autosuspend);
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
 
        /* if interface was already added, bind now; else let
         * the future device_add() bind it, bypassing probe()
@@ -355,11 +356,11 @@ void usb_driver_release_interface(struct usb_driver *driver,
        dev->driver = NULL;
        usb_set_intfdata(iface, NULL);
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        iface->condition = USB_INTERFACE_UNBOUND;
        mark_quiesced(iface);
        iface->needs_remote_wakeup = 0;
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
 }
 EXPORT_SYMBOL(usb_driver_release_interface);
 
@@ -788,7 +789,7 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
 
 #ifdef CONFIG_PM
 
-/* Caller has locked udev->pm_mutex */
+/* Caller has locked udev's pm_mutex */
 static int suspend_device(struct usb_device *udev, pm_message_t msg)
 {
        struct usb_device_driver        *udriver;
@@ -815,7 +816,7 @@ done:
        return status;
 }
 
-/* Caller has locked udev->pm_mutex */
+/* Caller has locked udev's pm_mutex */
 static int resume_device(struct usb_device *udev)
 {
        struct usb_device_driver        *udriver;
@@ -841,7 +842,7 @@ done:
        return status;
 }
 
-/* Caller has locked intf's usb_device's pm_mutex */
+/* Caller has locked intf's usb_device's pm mutex */
 static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
 {
        struct usb_driver       *driver;
@@ -1063,7 +1064,7 @@ int usb_resume_both(struct usb_device *udev)
        /* Propagate the resume up the tree, if necessary */
        if (udev->state == USB_STATE_SUSPENDED) {
                if (parent) {
-                       mutex_lock_nested(&parent->pm_mutex, parent->level);
+                       usb_pm_lock(parent);
                        parent->auto_pm = 1;
                        status = usb_resume_both(parent);
                } else {
@@ -1078,7 +1079,7 @@ int usb_resume_both(struct usb_device *udev)
                if (status == 0)
                        status = resume_device(udev);
                if (parent)
-                       mutex_unlock(&parent->pm_mutex);
+                       usb_pm_unlock(parent);
        } else {
 
                /* Needed only for setting udev->dev.power.power_state.event
@@ -1103,8 +1104,8 @@ int usb_resume_both(struct usb_device *udev)
 
 /**
  * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces
- * @udev - the usb_device to autosuspend
- * @dec_usage_cnt - flag to decrement @udev's PM-usage counter
+ * @udev: the usb_device to autosuspend
+ * @dec_usage_cnt: flag to decrement @udev's PM-usage counter
  *
  * This routine should be called when a core subsystem is finished using
  * @udev and wants to allow it to autosuspend.  Examples would be when
@@ -1128,20 +1129,20 @@ int usb_resume_both(struct usb_device *udev)
  */
 void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt)
 {
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        udev->pm_usage_cnt -= dec_usage_cnt;
        if (udev->pm_usage_cnt <= 0)
-               schedule_delayed_work(&udev->autosuspend,
+               queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
                                USB_AUTOSUSPEND_DELAY);
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
        // dev_dbg(&udev->dev, "%s: cnt %d\n",
        //              __FUNCTION__, udev->pm_usage_cnt);
 }
 
 /**
  * usb_autoresume_device - immediately autoresume a USB device and its interfaces
- * @udev - the usb_device to autoresume
- * @inc_usage_cnt - flag to increment @udev's PM-usage counter
+ * @udev: the usb_device to autoresume
+ * @inc_usage_cnt: flag to increment @udev's PM-usage counter
  *
  * This routine should be called when a core subsystem wants to use @udev
  * and needs to guarantee that it is not suspended.  In addition, the
@@ -1167,13 +1168,13 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt)
 {
        int     status;
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        udev->pm_usage_cnt += inc_usage_cnt;
        udev->auto_pm = 1;
        status = usb_resume_both(udev);
        if (status != 0)
                udev->pm_usage_cnt -= inc_usage_cnt;
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
        // dev_dbg(&udev->dev, "%s: status %d cnt %d\n",
        //              __FUNCTION__, status, udev->pm_usage_cnt);
        return status;
@@ -1181,7 +1182,7 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt)
 
 /**
  * usb_autopm_put_interface - decrement a USB interface's PM-usage counter
- * @intf - the usb_interface whose counter should be decremented
+ * @intf: the usb_interface whose counter should be decremented
  *
  * This routine should be called by an interface driver when it is
  * finished using @intf and wants to allow it to autosuspend.  A typical
@@ -1214,13 +1215,13 @@ void usb_autopm_put_interface(struct usb_interface *intf)
 {
        struct usb_device       *udev = interface_to_usbdev(intf);
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
-       if (intf->condition != USB_INTERFACE_UNBOUND) {
-               if (--intf->pm_usage_cnt <= 0)
-                       schedule_delayed_work(&udev->autosuspend,
-                                       USB_AUTOSUSPEND_DELAY);
+       usb_pm_lock(udev);
+       if (intf->condition != USB_INTERFACE_UNBOUND &&
+                       --intf->pm_usage_cnt <= 0) {
+               queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
+                               USB_AUTOSUSPEND_DELAY);
        }
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
        // dev_dbg(&intf->dev, "%s: cnt %d\n",
        //              __FUNCTION__, intf->pm_usage_cnt);
 }
@@ -1228,7 +1229,7 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
 
 /**
  * usb_autopm_get_interface - increment a USB interface's PM-usage counter
- * @intf - the usb_interface whose counter should be incremented
+ * @intf: the usb_interface whose counter should be incremented
  *
  * This routine should be called by an interface driver when it wants to
  * use @intf and needs to guarantee that it is not suspended.  In addition,
@@ -1262,7 +1263,7 @@ int usb_autopm_get_interface(struct usb_interface *intf)
        struct usb_device       *udev = interface_to_usbdev(intf);
        int                     status;
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        if (intf->condition == USB_INTERFACE_UNBOUND)
                status = -ENODEV;
        else {
@@ -1272,7 +1273,7 @@ int usb_autopm_get_interface(struct usb_interface *intf)
                if (status != 0)
                        --intf->pm_usage_cnt;
        }
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
        // dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
        //              __FUNCTION__, status, intf->pm_usage_cnt);
        return status;
@@ -1288,10 +1289,10 @@ static int usb_suspend(struct device *dev, pm_message_t message)
        if (is_usb_device(dev)) {
                struct usb_device *udev = to_usb_device(dev);
 
-               mutex_lock_nested(&udev->pm_mutex, udev->level);
+               usb_pm_lock(udev);
                udev->auto_pm = 0;
                status = usb_suspend_both(udev, message);
-               mutex_unlock(&udev->pm_mutex);
+               usb_pm_unlock(udev);
        } else
                status = 0;
        return status;
@@ -1304,10 +1305,10 @@ static int usb_resume(struct device *dev)
        if (is_usb_device(dev)) {
                struct usb_device *udev = to_usb_device(dev);
 
-               mutex_lock_nested(&udev->pm_mutex, udev->level);
+               usb_pm_lock(udev);
                udev->auto_pm = 0;
                status = usb_resume_both(udev);
-               mutex_unlock(&udev->pm_mutex);
+               usb_pm_unlock(udev);
 
                /* Rebind drivers that had no suspend method? */
        } else
index e86f6295708555ea7cd76df5030831f58946f7f3..37f9f5e7425d1b5e1a518302fa36cad686989c25 100644 (file)
@@ -345,7 +345,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
        struct usb_ctrlrequest *cmd;
        u16             typeReq, wValue, wIndex, wLength;
        u8              *ubuf = urb->transfer_buffer;
-       u8              tbuf [sizeof (struct usb_hub_descriptor)];
+       u8              tbuf [sizeof (struct usb_hub_descriptor)]
+               __attribute__((aligned(4)));
        const u8        *bufp = tbuf;
        int             len = 0;
        int             patch_wakeup = 0;
@@ -835,8 +836,7 @@ void usb_enable_root_hub_irq (struct usb_bus *bus)
        struct usb_hcd *hcd;
 
        hcd = container_of (bus, struct usb_hcd, self);
-       if (hcd->driver->hub_irq_enable && !hcd->poll_rh &&
-                       hcd->state != HC_STATE_HALT)
+       if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
                hcd->driver->hub_irq_enable (hcd);
 }
 
index 2a8cb3c2b19ca51db6f6aa521cebaca9a84bd58c..7676690a0386aedc56242def77c874825714b13b 100644 (file)
@@ -1779,7 +1779,7 @@ static int remote_wakeup(struct usb_device *udev)
         * to the parent hub! */
 
        usb_lock_device(udev);
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        if (udev->state == USB_STATE_SUSPENDED) {
                dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
                /* TRSMRCY = 10 msec */
@@ -1788,7 +1788,7 @@ static int remote_wakeup(struct usb_device *udev)
                if (status == 0)
                        udev->dev.power.power_state.event = PM_EVENT_ON;
        }
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
 
        if (status == 0)
                usb_autoresume_device(udev, 0);
index 60ef4ef0101ae727567ec07bdd82d5b73cbf102e..e4df9edf1bc02bcfaa65f96f74730cb37f1e65bd 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 
 #include <asm/io.h>
 #include <asm/scatterlist.h>
@@ -47,6 +48,8 @@ const char *usbcore_name = "usbcore";
 
 static int nousb;      /* Disable USB when built into kernel image */
 
+struct workqueue_struct *ksuspend_usb_wq;      /* For autosuspend */
+
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -170,9 +173,9 @@ static void usb_release_dev(struct device *dev)
 
        udev = to_usb_device(dev);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_USB_SUSPEND
        cancel_delayed_work(&udev->autosuspend);
-       flush_scheduled_work();
+       flush_workqueue(ksuspend_usb_wq);
 #endif
        usb_destroy_configuration(udev);
        usb_put_hcd(bus_to_hcd(udev->bus));
@@ -184,17 +187,44 @@ static void usb_release_dev(struct device *dev)
 
 #ifdef CONFIG_PM
 
+static int ksuspend_usb_init(void)
+{
+       ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
+       if (!ksuspend_usb_wq)
+               return -ENOMEM;
+       return 0;
+}
+
+static void ksuspend_usb_cleanup(void)
+{
+       destroy_workqueue(ksuspend_usb_wq);
+}
+
+#else
+
+#define ksuspend_usb_init()    0
+#define ksuspend_usb_cleanup() do {} while (0)
+
+#endif
+
+#ifdef CONFIG_USB_SUSPEND
+
 /* usb_autosuspend_work - callback routine to autosuspend a USB device */
 static void usb_autosuspend_work(void *_udev)
 {
        struct usb_device       *udev = _udev;
 
-       mutex_lock_nested(&udev->pm_mutex, udev->level);
+       usb_pm_lock(udev);
        udev->auto_pm = 1;
        usb_suspend_both(udev, PMSG_SUSPEND);
-       mutex_unlock(&udev->pm_mutex);
+       usb_pm_unlock(udev);
 }
 
+#else
+
+static void usb_autosuspend_work(void *_udev)
+{}
+
 #endif
 
 /**
@@ -976,9 +1006,12 @@ static int __init usb_init(void)
                return 0;
        }
 
+       retval = ksuspend_usb_init();
+       if (retval)
+               goto out;
        retval = bus_register(&usb_bus_type);
        if (retval) 
-               goto out;
+               goto bus_register_failed;
        retval = usb_host_init();
        if (retval)
                goto host_init_failed;
@@ -1014,6 +1047,8 @@ major_init_failed:
        usb_host_cleanup();
 host_init_failed:
        bus_unregister(&usb_bus_type);
+bus_register_failed:
+       ksuspend_usb_cleanup();
 out:
        return retval;
 }
@@ -1035,6 +1070,7 @@ static void __exit usb_exit(void)
        usb_hub_cleanup();
        usb_host_cleanup();
        bus_unregister(&usb_bus_type);
+       ksuspend_usb_cleanup();
 }
 
 subsys_initcall(usb_init);
index 0c09ecced6e19721be1155623499d85cbec44d1d..f69df137ec0ec91aac813342ee3a3e0e564a6fae 100644 (file)
@@ -36,6 +36,16 @@ extern int usb_resume_both(struct usb_device *udev);
 extern int usb_port_suspend(struct usb_device *dev);
 extern int usb_port_resume(struct usb_device *dev);
 
+static inline void usb_pm_lock(struct usb_device *udev)
+{
+       mutex_lock_nested(&udev->pm_mutex, udev->level);
+}
+
+static inline void usb_pm_unlock(struct usb_device *udev)
+{
+       mutex_unlock(&udev->pm_mutex);
+}
+
 #else
 
 #define usb_suspend_both(udev, msg)    0
@@ -45,6 +55,8 @@ static inline int usb_resume_both(struct usb_device *udev)
 }
 #define usb_port_suspend(dev)          0
 #define usb_port_resume(dev)           0
+static inline void usb_pm_lock(struct usb_device *udev) {}
+static inline void usb_pm_unlock(struct usb_device *udev) {}
 
 #endif
 
@@ -58,10 +70,15 @@ extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt);
 #else
 
 #define usb_autosuspend_device(udev, dec_busy_cnt)     do {} while (0)
-#define usb_autoresume_device(udev, inc_busy_cnt)      0
+static inline int usb_autoresume_device(struct usb_device *udev,
+               int inc_busy_cnt)
+{
+       return 0;
+}
 
 #endif
 
+extern struct workqueue_struct *ksuspend_usb_wq;
 extern struct bus_type usb_bus_type;
 extern struct usb_device_driver usb_generic_driver;
 
index d00958a01cfbc2fc0b0d551348a7c127c819da13..77beba485a8430e343eddffdd7f91e223ef7a712 100644 (file)
@@ -1658,7 +1658,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
+       if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) {
                DBG("someone's using UDC memory\n");
                return -EBUSY;
        }
@@ -1720,7 +1720,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
 fail1:
        device_unregister(&udc->gadget.dev);
 fail0:
-       release_mem_region(AT91_BASE_UDP, SZ_16K);
+       release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
        DBG("%s probe failed, %d\n", driver_name, retval);
        return retval;
 }
@@ -1742,7 +1742,7 @@ static int __devexit at91udc_remove(struct platform_device *pdev)
                free_irq(udc->board.vbus_pin, udc);
        free_irq(udc->udp_irq, udc);
        device_unregister(&udc->gadget.dev);
-       release_mem_region(AT91_BASE_UDP, SZ_16K);
+       release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
 
        clk_put(udc->iclk);
        clk_put(udc->fclk);
index fdab97a27c08bdbd152cc013dc3de9091fef3fa7..4d2946e540cf9462538db8b51274fd5a40621ffe 100644 (file)
@@ -816,15 +816,14 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
        dum->gadget.dev.driver = &driver->driver;
        dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
                        driver->driver.name);
-       if ((retval = driver->bind (&dum->gadget)) != 0) {
-               dum->driver = NULL;
-               dum->gadget.dev.driver = NULL;
-               return retval;
-       }
+       if ((retval = driver->bind (&dum->gadget)) != 0)
+               goto err_bind_gadget;
 
        driver->driver.bus = dum->gadget.dev.parent->bus;
-       driver_register (&driver->driver);
-       device_bind_driver (&dum->gadget.dev);
+       if ((retval = driver_register (&driver->driver)) != 0)
+               goto err_register;
+       if ((retval = device_bind_driver (&dum->gadget.dev)) != 0)
+               goto err_bind_driver;
 
        /* khubd will enumerate this in a while */
        spin_lock_irq (&dum->lock);
@@ -834,6 +833,19 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
 
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
+
+err_bind_driver:
+       driver_unregister (&driver->driver);
+err_register:
+       driver->unbind (&dum->gadget);
+       spin_lock_irq (&dum->lock);
+       dum->pullup = 0;
+       set_link_state (dum);
+       spin_unlock_irq (&dum->lock);
+err_bind_gadget:
+       dum->driver = NULL;
+       dum->gadget.dev.driver = NULL;
+       return retval;
 }
 EXPORT_SYMBOL (usb_gadget_register_driver);
 
@@ -916,7 +928,9 @@ static int dummy_udc_probe (struct platform_device *pdev)
        usb_get_hcd (dummy_to_hcd (dum));
 
        platform_set_drvdata (pdev, dum);
-       device_create_file (&dum->gadget.dev, &dev_attr_function);
+       rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
+       if (rc < 0)
+               device_unregister (&dum->gadget.dev);
        return rc;
 }
 
@@ -1864,8 +1878,7 @@ static int dummy_start (struct usb_hcd *hcd)
 #endif
 
        /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
-       device_create_file (dummy_dev(dum), &dev_attr_urbs);
-       return 0;
+       return device_create_file (dummy_dev(dum), &dev_attr_urbs);
 }
 
 static void dummy_stop (struct usb_hcd *hcd)
index 8d7f1e84cd7b048eadc36df840c383ff7c7bfab8..c83d3b6c68f2121dd574ff92fd3c30a4b9670791 100644 (file)
@@ -567,6 +567,7 @@ struct lun {
        unsigned int    ro : 1;
        unsigned int    prevent_medium_removal : 1;
        unsigned int    registered : 1;
+       unsigned int    info_valid : 1;
 
        u32             sense_data;
        u32             sense_data_info;
@@ -1656,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg)
                        curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        bh->inreq->length = 0;
                        bh->state = BUF_STATE_FULL;
                        break;
@@ -1691,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg)
                if (nread < amount) {
                        curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
 
@@ -1785,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg)
                                curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                                curlun->sense_data_info = usb_offset >> 9;
+                               curlun->info_valid = 1;
                                continue;
                        }
                        amount -= (amount & 511);
@@ -1827,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg)
                        if (bh->outreq->status != 0) {
                                curlun->sense_data = SS_COMMUNICATION_FAILURE;
                                curlun->sense_data_info = file_offset >> 9;
+                               curlun->info_valid = 1;
                                break;
                        }
 
@@ -1868,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg)
                        if (nwritten < amount) {
                                curlun->sense_data = SS_WRITE_ERROR;
                                curlun->sense_data_info = file_offset >> 9;
+                               curlun->info_valid = 1;
                                break;
                        }
 
@@ -2010,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg)
                        curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
 
@@ -2036,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg)
                if (nread == 0) {
                        curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
                file_offset += nread;
@@ -2079,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        struct lun      *curlun = fsg->curlun;
        u8              *buf = (u8 *) bh->buf;
        u32             sd, sdinfo;
+       int             valid;
 
        /*
         * From the SCSI-2 spec., section 7.9 (Unit attention condition):
@@ -2106,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                fsg->bad_lun_okay = 1;
                sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
                sdinfo = 0;
+               valid = 0;
        } else {
                sd = curlun->sense_data;
                sdinfo = curlun->sense_data_info;
+               valid = curlun->info_valid << 7;
                curlun->sense_data = SS_NO_SENSE;
                curlun->sense_data_info = 0;
+               curlun->info_valid = 0;
        }
 
        memset(buf, 0, 18);
-       buf[0] = 0x80 | 0x70;                   // Valid, current error
+       buf[0] = valid | 0x70;                  // Valid, current error
        buf[2] = SK(sd);
        put_be32(&buf[3], sdinfo);              // Sense information
        buf[7] = 18 - 8;                        // Additional sense length
@@ -2703,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->sense_data_info = 0;
+                       curlun->info_valid = 0;
                }
        } else {
                fsg->curlun = curlun = NULL;
@@ -3332,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg)
                        curlun->sense_data = curlun->unit_attention_data =
                                        SS_NO_SENSE;
                        curlun->sense_data_info = 0;
+                       curlun->info_valid = 0;
                }
                fsg->state = FSG_STATE_IDLE;
        }
@@ -3873,21 +3887,26 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
                curlun->ro = mod_data.ro[i];
+               curlun->dev.release = lun_release;
                curlun->dev.parent = &gadget->dev;
                curlun->dev.driver = &fsg_driver.driver;
                dev_set_drvdata(&curlun->dev, fsg);
                snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
                                "%s-lun%d", gadget->dev.bus_id, i);
 
-               if ((rc = device_register(&curlun->dev)) != 0)
+               if ((rc = device_register(&curlun->dev)) != 0) {
                        INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
-               else {
-                       curlun->registered = 1;
-                       curlun->dev.release = lun_release;
-                       device_create_file(&curlun->dev, &dev_attr_ro);
-                       device_create_file(&curlun->dev, &dev_attr_file);
-                       kref_get(&fsg->ref);
+                       goto out;
+               }
+               if ((rc = device_create_file(&curlun->dev,
+                                       &dev_attr_ro)) != 0 ||
+                               (rc = device_create_file(&curlun->dev,
+                                       &dev_attr_file)) != 0) {
+                       device_unregister(&curlun->dev);
+                       goto out;
                }
+               curlun->registered = 1;
+               kref_get(&fsg->ref);
 
                if (mod_data.file[i] && *mod_data.file[i]) {
                        if ((rc = open_backing_file(curlun,
index 1027aa04583d28e1a3d373e0499d55a4e5f59cbe..d1d68c4022519bf8aedcdb075193ded74c07dc44 100644 (file)
@@ -715,17 +715,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
                return IRQ_NOTMINE;
        }
 
-       /* NOTE:  vendors didn't always make the same implementation
-        * choices for RHSC.  Sometimes it triggers on an edge (like
-        * setting and maybe clearing a port status change bit); and
-        * it's level-triggered on other silicon, active until khubd
-        * clears all active port status change bits.  Poll by timer
-        * til it's fully debounced and the difference won't matter.
-        */
        if (ints & OHCI_INTR_RHSC) {
                ohci_vdbg (ohci, "rhsc\n");
-               ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrdisable);
-               hcd->poll_rh = 1;
                ohci->next_statechange = jiffies + STATECHANGE_DELAY;
                ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus);
                usb_hcd_poll_rh_status(hcd);
@@ -743,13 +734,18 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
        if (ints & OHCI_INTR_RD) {
                ohci_vdbg (ohci, "resume detect\n");
                ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
-               if (hcd->state != HC_STATE_QUIESCING)
+               hcd->poll_rh = 1;
+               if (ohci->autostop) {
+                       spin_lock (&ohci->lock);
+                       ohci_rh_resume (ohci);
+                       spin_unlock (&ohci->lock);
+               } else
                        usb_hcd_resume_root_hub(hcd);
        }
 
        if (ints & OHCI_INTR_WDH) {
                if (HC_IS_RUNNING(hcd->state))
-                       ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable);  
+                       ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable);
                spin_lock (&ohci->lock);
                dl_done_list (ohci, ptregs);
                spin_unlock (&ohci->lock);
index 0b899339cac807e58c98a3377e8b3fbae0bab2f1..ec75774abeac581eabb0a57b6de6fb30e4594a92 100644 (file)
@@ -44,27 +44,17 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
        ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
 }
 
-#ifdef CONFIG_PM
-
 #define OHCI_SCHED_ENABLES \
        (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
 
 static void dl_done_list (struct ohci_hcd *, struct pt_regs *);
 static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *);
-static int ohci_restart (struct ohci_hcd *ohci);
 
-static int ohci_bus_suspend (struct usb_hcd *hcd)
+static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
+__releases(ohci->lock)
+__acquires(ohci->lock)
 {
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
        int                     status = 0;
-       unsigned long           flags;
-
-       spin_lock_irqsave (&ohci->lock, flags);
-
-       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
-               spin_unlock_irqrestore (&ohci->lock, flags);
-               return -ESHUTDOWN;
-       }
 
        ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
        switch (ohci->hc_control & OHCI_CTRL_HCFS) {
@@ -80,15 +70,16 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
                ohci_dbg (ohci, "needs reinit!\n");
                goto done;
        case OHCI_USB_SUSPEND:
-               ohci_dbg (ohci, "already suspended\n");
-               goto done;
+               if (!ohci->autostop) {
+                       ohci_dbg (ohci, "already suspended\n");
+                       goto done;
+               }
        }
-       ohci_dbg (ohci, "suspend root hub\n");
+       ohci_dbg (ohci, "%s root hub\n",
+                       autostop ? "auto-stop" : "suspend");
 
        /* First stop any processing */
-       if (ohci->hc_control & OHCI_SCHED_ENABLES) {
-               int             limit;
-
+       if (!autostop && (ohci->hc_control & OHCI_SCHED_ENABLES)) {
                ohci->hc_control &= ~OHCI_SCHED_ENABLES;
                ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
                ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
@@ -98,27 +89,22 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
                 * then the last WDH could take 6+ msec
                 */
                ohci_dbg (ohci, "stopping schedules ...\n");
-               limit = 2000;
-               while (limit > 0) {
-                       udelay (250);
-                       limit =- 250;
-                       if (ohci_readl (ohci, &ohci->regs->intrstatus)
-                                       & OHCI_INTR_SF)
-                               break;
-               }
-               dl_done_list (ohci, NULL);
-               mdelay (7);
+               ohci->autostop = 0;
+               spin_unlock_irq (&ohci->lock);
+               msleep (8);
+               spin_lock_irq (&ohci->lock);
        }
        dl_done_list (ohci, NULL);
        finish_unlinks (ohci, ohci_frame_no(ohci), NULL);
-       ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
-                       &ohci->regs->intrstatus);
 
        /* maybe resume can wake root hub */
-       if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev))
+       if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) ||
+                       autostop)
                ohci->hc_control |= OHCI_CTRL_RWE;
-       else
+       else {
+               ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
                ohci->hc_control &= ~OHCI_CTRL_RWE;
+       }
 
        /* Suspend hub ... this is the "global (to this bus) suspend" mode,
         * which doesn't imply ports will first be individually suspended.
@@ -129,13 +115,12 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
        (void) ohci_readl (ohci, &ohci->regs->control);
 
        /* no resumes until devices finish suspending */
-       ohci->next_statechange = jiffies + msecs_to_jiffies (5);
-
-       /* no timer polling */
-       hcd->poll_rh = 0;
+       if (!autostop) {
+               ohci->next_statechange = jiffies + msecs_to_jiffies (5);
+               ohci->autostop = 0;
+       }
 
 done:
-       spin_unlock_irqrestore (&ohci->lock, flags);
        return status;
 }
 
@@ -147,25 +132,19 @@ static inline struct ed *find_head (struct ed *ed)
        return ed;
 }
 
+static int ohci_restart (struct ohci_hcd *ohci);
+
 /* caller has locked the root hub */
-static int ohci_bus_resume (struct usb_hcd *hcd)
+static int ohci_rh_resume (struct ohci_hcd *ohci)
+__releases(ohci->lock)
+__acquires(ohci->lock)
 {
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
+       struct usb_hcd          *hcd = ohci_to_hcd (ohci);
        u32                     temp, enables;
        int                     status = -EINPROGRESS;
-       unsigned long           flags;
-
-       if (time_before (jiffies, ohci->next_statechange))
-               msleep(5);
-
-       spin_lock_irqsave (&ohci->lock, flags);
-
-       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
-               spin_unlock_irqrestore (&ohci->lock, flags);
-               return -ESHUTDOWN;
-       }
-
+       int                     autostopped = ohci->autostop;
 
+       ohci->autostop = 0;
        ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
 
        if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
@@ -185,7 +164,8 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
                ohci->hc_control |= OHCI_USB_RESUME;
                ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
                (void) ohci_readl (ohci, &ohci->regs->control);
-               ohci_dbg (ohci, "resume root hub\n");
+               ohci_dbg (ohci, "%s root hub\n",
+                               autostopped ? "auto-start" : "resume");
                break;
        case OHCI_USB_RESUME:
                /* HCFS changes sometime after INTR_RD */
@@ -200,16 +180,24 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
                ohci_dbg (ohci, "lost power\n");
                status = -EBUSY;
        }
-       spin_unlock_irqrestore (&ohci->lock, flags);
+#ifdef CONFIG_PM
        if (status == -EBUSY) {
-               (void) ohci_init (ohci);
-               return ohci_restart (ohci);
+               if (!autostopped) {
+                       spin_unlock_irq (&ohci->lock);
+                       (void) ohci_init (ohci);
+                       status = ohci_restart (ohci);
+                       spin_lock_irq (&ohci->lock);
+               }
+               return status;
        }
+#endif
        if (status != -EINPROGRESS)
                return status;
+       if (autostopped)
+               goto skip_resume;
+       spin_unlock_irq (&ohci->lock);
 
        temp = ohci->num_ports;
-       enables = 0;
        while (temp--) {
                u32 stat = ohci_readl (ohci,
                                       &ohci->regs->roothub.portstatus [temp]);
@@ -242,17 +230,21 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
        /* Sometimes PCI D3 suspend trashes frame timings ... */
        periodic_reinit (ohci);
 
+       /* the following code is executed with ohci->lock held and
+        * irqs disabled if and only if autostopped is true
+        */
+
+skip_resume:
        /* interrupts might have been disabled */
        ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
        if (ohci->ed_rm_list)
                ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
-       ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
-                       &ohci->regs->intrstatus);
 
        /* Then re-enable operations */
        ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
        (void) ohci_readl (ohci, &ohci->regs->control);
-       msleep (3);
+       if (!autostopped)
+               msleep (3);
 
        temp = ohci->hc_control;
        temp &= OHCI_CTRL_RWC;
@@ -262,7 +254,11 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
        (void) ohci_readl (ohci, &ohci->regs->control);
 
        /* TRSMRCY */
-       msleep (10);
+       if (!autostopped) {
+               msleep (10);
+               spin_lock_irq (&ohci->lock);
+       }
+       /* now ohci->lock is always held and irqs are always disabled */
 
        /* keep it alive for more than ~5x suspend + resume costs */
        ohci->next_statechange = jiffies + STATECHANGE_DELAY;
@@ -299,6 +295,45 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
        return 0;
 }
 
+#ifdef CONFIG_PM
+
+static int ohci_bus_suspend (struct usb_hcd *hcd)
+{
+       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
+       int                     rc;
+
+       spin_lock_irq (&ohci->lock);
+
+       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
+               rc = -ESHUTDOWN;
+       else
+               rc = ohci_rh_suspend (ohci, 0);
+       spin_unlock_irq (&ohci->lock);
+       return rc;
+}
+
+static int ohci_bus_resume (struct usb_hcd *hcd)
+{
+       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
+       int                     rc;
+
+       if (time_before (jiffies, ohci->next_statechange))
+               msleep(5);
+
+       spin_lock_irq (&ohci->lock);
+
+       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
+               rc = -ESHUTDOWN;
+       else
+               rc = ohci_rh_resume (ohci);
+       spin_unlock_irq (&ohci->lock);
+
+       /* poll until we know a device is connected or we autostop */
+       if (rc == 0)
+               usb_hcd_poll_rh_status(hcd);
+       return rc;
+}
+
 #endif /* CONFIG_PM */
 
 /*-------------------------------------------------------------------------*/
@@ -310,21 +345,11 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
        int             i, changed = 0, length = 1;
-       int             can_suspend;
+       int             any_connected = 0, rhsc_enabled = 1;
        unsigned long   flags;
 
-       can_suspend = device_may_wakeup(&hcd->self.root_hub->dev);
        spin_lock_irqsave (&ohci->lock, flags);
 
-       /* handle autosuspended root:  finish resuming before
-        * letting khubd or root hub timer see state changes.
-        */
-       if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
-                    || !HC_IS_RUNNING(hcd->state))) {
-               can_suspend = 0;
-               goto done;
-       }
-
        /* undocumented erratum seen on at least rev D */
        if ((ohci->flags & OHCI_QUIRK_AMD756)
                        && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) {
@@ -348,9 +373,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
        for (i = 0; i < ohci->num_ports; i++) {
                u32     status = roothub_portstatus (ohci, i);
 
-               /* can't autosuspend with active ports */
-               if ((status & RH_PS_PES) && !(status & RH_PS_PSS))
-                       can_suspend = 0;
+               /* can't autostop if ports are connected */
+               any_connected |= (status & RH_PS_CCS);
 
                if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
                                | RH_PS_OCIC | RH_PS_PRSC)) {
@@ -359,49 +383,73 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
                            buf [0] |= 1 << (i + 1);
                        else
                            buf [1] |= 1 << (i - 7);
-                       continue;
                }
        }
 
-       /* after root hub changes, stop polling after debouncing
-        * for a while and maybe kicking in autosuspend
+       /* NOTE:  vendors didn't always make the same implementation
+        * choices for RHSC.  Sometimes it triggers on an edge (like
+        * setting and maybe clearing a port status change bit); and
+        * it's level-triggered on other silicon, active until khubd
+        * clears all active port status change bits.  If it's still
+        * set (level-triggered) we must disable it and rely on
+        * polling until khubd re-enables it.
         */
-       if (changed) {
-               ohci->next_statechange = jiffies + STATECHANGE_DELAY;
-               can_suspend = 0;
-       } else if (time_before (jiffies, ohci->next_statechange)) {
-               can_suspend = 0;
-       } else {
-#ifdef CONFIG_PM
-               can_suspend = can_suspend
-                       && !ohci->ed_rm_list
-                       && ((OHCI_CTRL_HCFS | OHCI_SCHED_ENABLES)
-                                       & ohci->hc_control)
-                               == OHCI_USB_OPER;
-#endif
-               if (hcd->uses_new_polling) {
+       if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) {
+               ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
+               (void) ohci_readl (ohci, &ohci->regs->intrdisable);
+               rhsc_enabled = 0;
+       }
+       hcd->poll_rh = 1;
+
+       /* carry out appropriate state changes */
+       switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+
+       case OHCI_USB_OPER:
+               /* keep on polling until we know a device is connected
+                * and RHSC is enabled */
+               if (!ohci->autostop) {
+                       if (any_connected) {
+                               if (rhsc_enabled)
+                                       hcd->poll_rh = 0;
+                       } else {
+                               ohci->autostop = 1;
+                               ohci->next_statechange = jiffies + HZ;
+                       }
+
+               /* if no devices have been attached for one second, autostop */
+               } else {
+                       if (changed || any_connected) {
+                               ohci->autostop = 0;
+                               ohci->next_statechange = jiffies +
+                                               STATECHANGE_DELAY;
+                       } else if (time_after_eq (jiffies,
+                                               ohci->next_statechange)
+                                       && !ohci->ed_rm_list
+                                       && !(ohci->hc_control &
+                                               OHCI_SCHED_ENABLES)) {
+                               ohci_rh_suspend (ohci, 1);
+                       }
+               }
+               break;
+
+       /* if there is a port change, autostart or ask to be resumed */
+       case OHCI_USB_SUSPEND:
+       case OHCI_USB_RESUME:
+               if (changed) {
+                       if (ohci->autostop)
+                               ohci_rh_resume (ohci);
+                       else
+                               usb_hcd_resume_root_hub (hcd);
+               } else {
+                       /* everything is idle, no need for polling */
                        hcd->poll_rh = 0;
-                       /* use INTR_RHSC iff INTR_RD won't apply */
-                       if (!can_suspend)
-                               ohci_writel (ohci, OHCI_INTR_RHSC,
-                                               &ohci->regs->intrenable);
                }
+               break;
        }
 
 done:
        spin_unlock_irqrestore (&ohci->lock, flags);
 
-#ifdef CONFIG_PM
-       /* save power by autosuspending idle root hubs;
-        * INTR_RD wakes us when there's work
-        */
-       if (can_suspend && usb_trylock_device (hcd->self.root_hub) == 0) {
-               ohci_vdbg (ohci, "autosuspend\n");
-               (void) ohci_bus_suspend (hcd);
-               usb_unlock_device (hcd->self.root_hub);
-       }
-#endif
-
        return changed ? length : 0;
 }
 
@@ -572,9 +620,6 @@ static int ohci_hub_control (
                        break;
                case USB_PORT_FEAT_SUSPEND:
                        temp = RH_PS_POCI;
-                       if ((ohci->hc_control & OHCI_CTRL_HCFS)
-                                       != OHCI_USB_OPER)
-                               usb_hcd_resume_root_hub(hcd);
                        break;
                case USB_PORT_FEAT_C_SUSPEND:
                        temp = RH_PS_PSSC;
index 3732db7d68eb58ed193130ff47f9aea20fc910e6..874418552789154ee73a72064e6265c299d1edbe 100644 (file)
@@ -73,13 +73,14 @@ ohci_pci_start (struct usb_hcd *hcd)
                else if (pdev->vendor == PCI_VENDOR_ID_NS) {
                        struct pci_dev  *b;
 
-                       b  = pci_find_slot (pdev->bus->number,
+                       b  = pci_get_slot (pdev->bus,
                                        PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
                        if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
                                        && b->vendor == PCI_VENDOR_ID_NS) {
                                ohci->flags |= OHCI_QUIRK_SUPERIO;
                                ohci_dbg (ohci, "Using NSC SuperIO setup\n");
                        }
+                       pci_dev_put(b);
                }
 
                /* Check for Compaq's ZFMicro chipset, which needs short 
index 93fdc3c353416dd46269532156130f2645547a85..a2f42a2f47c6f440165fb05be038dae041668167 100644 (file)
@@ -388,6 +388,7 @@ struct ohci_hcd {
        u32                     hc_control;     /* copy of hc control reg */
        unsigned long           next_statechange;       /* suspend/resume */
        u32                     fminterval;             /* saved register */
+       unsigned                autostop:1;     /* rh auto stopping/stopped */
 
        unsigned long           flags;          /* for HC bugs */
 #define        OHCI_QUIRK_AMD756       0x01                    /* erratum #4 */
index b2bafc37c414968f91e02df4e96ed2b93527f6d0..5f861331932a670affdb9769f8ef32571b957269 100644 (file)
@@ -225,7 +225,7 @@ static inline void mts_debug_dump(struct mts_desc* desc) {
 }
 
 
-static inline void mts_show_command(Scsi_Cmnd *srb)
+static inline void mts_show_command(struct scsi_cmnd *srb)
 {
        char *what = NULL;
 
@@ -309,7 +309,7 @@ static inline void mts_show_command(Scsi_Cmnd *srb)
 
 #else
 
-static inline void mts_show_command(Scsi_Cmnd * dummy)
+static inline void mts_show_command(struct scsi_cmnd * dummy)
 {
 }
 
@@ -338,7 +338,7 @@ static int mts_slave_configure (struct scsi_device *s)
        return 0;
 }
 
-static int mts_scsi_abort (Scsi_Cmnd *srb)
+static int mts_scsi_abort(struct scsi_cmnd *srb)
 {
        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 
@@ -349,7 +349,7 @@ static int mts_scsi_abort (Scsi_Cmnd *srb)
        return FAILED;
 }
 
-static int mts_scsi_host_reset (Scsi_Cmnd *srb)
+static int mts_scsi_host_reset(struct scsi_cmnd *srb)
 {
        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
        int result, rc;
@@ -366,8 +366,8 @@ static int mts_scsi_host_reset (Scsi_Cmnd *srb)
        return result ? FAILED : SUCCESS;
 }
 
-static
-int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback );
+static int
+mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback);
 
 static void mts_transfer_cleanup( struct urb *transfer );
 static void mts_do_sg(struct urb * transfer, struct pt_regs *regs);
@@ -537,7 +537,7 @@ static const unsigned char mts_direction[256/8] = {
 #define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1)
 
 static void
-mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc )
+mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 {
        int pipe;
        struct scatterlist * sg;
@@ -588,8 +588,8 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc )
 }
 
 
-static
-int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
+static int
+mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 {
        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
        int err = 0;
index 926d4bdc6746cb48b7352fe1d338f9e111d426c0..d5d62a93905885900ed64ca6596da41f55ea5942 100644 (file)
@@ -8,14 +8,14 @@
  *
  */
 
-typedef void (*mts_scsi_cmnd_callback)(Scsi_Cmnd *);
+typedef void (*mts_scsi_cmnd_callback)(struct scsi_cmnd *);
 
 
 struct mts_transfer_context
 {
        struct mts_desc* instance;
        mts_scsi_cmnd_callback final_callback;
-       Scsi_Cmnd *srb;
+       struct scsi_cmnd *srb;
        
        void* data;
        unsigned data_length;
index 2a3e9e9b4b3dc73b2b7d0e801506e21b8040d1a9..81b1ea01a172e40e32790a64d6602f653b0e9171 100644 (file)
@@ -1600,6 +1600,9 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_ALCOR            0x058f
 #define USB_DEVICE_ID_ALCOR_USBRS232   0x9720
 
+#define USB_VENDOR_ID_SUN              0x0430
+#define USB_DEVICE_ID_RARITAN_KVM_DONGLE       0xcdab
+
 /*
  * Alphabetically sorted blacklist by quirk type.
  */
@@ -1729,6 +1732,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
index 9a8d137d39f91d75dd9273ba16ef13adfbf6ffa6..78e419904abf361d3463abc625d29fe6c7b32ae3 100644 (file)
@@ -44,20 +44,25 @@ struct driver_interfacekit {
        int inputs;
        int outputs;
        int has_lcd;
+       int amnesiac;
 };
-#define ifkit(_sensors, _inputs, _outputs, _lcd)                       \
-static struct driver_interfacekit ph_##_sensors##_inputs##_outputs = { \
+
+#define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac)            \
+{                                                                      \
        .sensors        = _sensors,                                     \
        .inputs         = _inputs,                                      \
        .outputs        = _outputs,                                     \
        .has_lcd        = _lcd,                                         \
+       .amnesiac       = _amnesiac                                     \
 };
-ifkit(0, 0, 4, 0);
-ifkit(8, 8, 8, 0);
-ifkit(0, 4, 7, 1);
-ifkit(8, 8, 4, 0);
-ifkit(0, 8, 8, 1);
-ifkit(0, 16, 16, 0);
+
+static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0);
+static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1);
+static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0);
+static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0);
+static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0);
+static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0);
+static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0);
 
 static unsigned long device_no;
 
@@ -77,6 +82,7 @@ struct interfacekit {
        dma_addr_t data_dma;
 
        struct work_struct do_notify;
+       struct work_struct do_resubmit;
        unsigned long input_events;
        unsigned long sensor_events;
 };
@@ -84,8 +90,10 @@ struct interfacekit {
 static struct usb_device_id id_table[] = {
        {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004),
                .driver_info = (kernel_ulong_t)&ph_004},
-       {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888),
-               .driver_info = (kernel_ulong_t)&ph_888},
+       {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814),
+               .driver_info = (kernel_ulong_t)&ph_888o},
+       {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff),
+               .driver_info = (kernel_ulong_t)&ph_888n},
        {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047),
                .driver_info = (kernel_ulong_t)&ph_047},
        {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
@@ -98,16 +106,11 @@ static struct usb_device_id id_table[] = {
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static int change_outputs(struct interfacekit *kit, int output_num, int enable)
+static int set_outputs(struct interfacekit *kit)
 {
        u8 *buffer;
        int retval;
 
-       if (enable)
-               set_bit(output_num, &kit->outputs);
-       else
-               clear_bit(output_num, &kit->outputs);
-
        buffer = kzalloc(4, GFP_KERNEL);
        if (!buffer) {
                dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
@@ -127,6 +130,9 @@ static int change_outputs(struct interfacekit *kit, int output_num, int enable)
                                retval);
        kfree(buffer);
 
+       if (kit->ifkit->amnesiac)
+               schedule_delayed_work(&kit->do_resubmit, HZ / 2);
+
        return retval < 0 ? retval : 0;
 }
 
@@ -399,19 +405,29 @@ static void do_notify(void *data)
        }
 }
 
+static void do_resubmit(void *data)
+{
+       set_outputs(data);
+}
+
 #define show_set_output(value)         \
 static ssize_t set_output##value(struct device *dev,                   \
                                        struct device_attribute *attr,  \
                                        const char *buf, size_t count)  \
 {                                                                      \
        struct interfacekit *kit = dev_get_drvdata(dev);                \
-       int enabled;                                                    \
+       int enable                                                    \
        int retval;                                                     \
                                                                        \
-       if (sscanf(buf, "%d", &enabled) < 1)                            \
+       if (sscanf(buf, "%d", &enable) < 1)                             \
                return -EINVAL;                                         \
                                                                        \
-       retval = change_outputs(kit, value - 1, enabled);               \
+       if (enable)                                                     \
+               set_bit(value - 1, &kit->outputs);                      \
+       else                                                            \
+               clear_bit(value - 1, &kit->outputs);                    \
+                                                                       \
+       retval = set_outputs(kit);                                      \
                                                                        \
        return retval ? retval : count;                                 \
 }                                                                      \
@@ -560,6 +576,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
        kit->udev = usb_get_dev(dev);
        kit->intf = intf;
        INIT_WORK(&kit->do_notify, do_notify, kit);
+       INIT_WORK(&kit->do_resubmit, do_resubmit, kit);
        usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
                        maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
                        interfacekit_irq, kit, endpoint->bInterval);
@@ -663,6 +680,7 @@ static void interfacekit_disconnect(struct usb_interface *interface)
        usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
 
        cancel_delayed_work(&kit->do_notify);
+       cancel_delayed_work(&kit->do_resubmit);
 
        for (i=0; i<kit->ifkit->outputs; i++)
                device_remove_file(kit->dev, &dev_output_attrs[i]);
index 9b97aa6384c795681de6830fc8a6d824a2c41411..9c0eacf7055c1d65169ad536fc4d21450da74eae 100644 (file)
@@ -1455,6 +1455,10 @@ static const struct usb_device_id        products [] = {
        // DLink DUB-E100 H/W Ver B1
        USB_DEVICE (0x07d1, 0x3c05),
        .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // DLink DUB-E100 H/W Ver B1 Alternate
+       USB_DEVICE (0x2001, 0x3c05),
+       .driver_info = (unsigned long) &ax88772_info,
 }, {
        // Linksys USB1000
        USB_DEVICE (0x1737, 0x0039),
index def3bb8e22901509bf35b618d14fb3402f8a2f43..544d41fe9b9261fb5ad2740e3ecba447cd662bf1 100644 (file)
@@ -165,6 +165,7 @@ static struct usb_device_id usb_klsi_table[] = {
        { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
        { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
        { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
+       { USB_DEVICE(0x1668, 0x0323) }, /* Actiontec USB Ethernet */
        { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */
        {} /* Null terminator */
 };
index b8e25af13f023ed8e5c9c6b115f05b28a2ce45c2..918cf5a77c08208f99e89aeede993397413d2129 100644 (file)
@@ -45,7 +45,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.6.13 (2005/11/13)"
+#define DRIVER_VERSION "v0.6.14 (2006/09/27)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -339,7 +339,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
        }
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
 
        return ret;
 }
@@ -376,7 +376,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
 
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
        return -ETIMEDOUT;
 }
 
@@ -413,7 +413,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
 
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
        return -ETIMEDOUT;
 }
 
@@ -461,7 +461,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
                return ret;
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
        return -ETIMEDOUT;
 }
 #endif                         /* PEGASUS_WRITE_EEPROM */
@@ -481,8 +481,12 @@ static void set_ethernet_addr(pegasus_t * pegasus)
 {
        __u8 node_id[6];
 
-       get_node_id(pegasus, node_id);
-       set_registers(pegasus, EthID, sizeof (node_id), node_id);
+       if (pegasus->features & PEGASUS_II) {
+               get_registers(pegasus, 0x10, sizeof(node_id), node_id);
+       } else {
+               get_node_id(pegasus, node_id);
+               set_registers(pegasus, EthID, sizeof (node_id), node_id);
+       }
        memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
 }
 
index 6286aba86fae2340beaed87c5f2a970050053939..d954ec34b018504b0cde6706030e3a29fac46ea9 100644 (file)
@@ -214,14 +214,14 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
                return (0);
        }
 
-       spin_lock(&port->lock);
+       spin_lock_bh(&port->lock);
        if (port->write_urb_busy) {
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
        port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       spin_unlock_bh(&port->lock);
 
        spin_lock_irqsave(&priv->lock, flags);
 
index 1f7b72553f3729c01208553a370acc78cfbfdba4..e774a27c6c9857bf9677d166f55f5d55e6271866 100644 (file)
@@ -344,6 +344,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) },
+       { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2106_PID) },
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) },
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) },
        { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) },
@@ -507,6 +508,9 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
        { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 77299996f7ee045cc5d73c330f97b5b5774f0470..f0edb87d2dd51c7831fa661be827758fffe6999e 100644 (file)
 #define SEALEVEL_2102_PID      0x2102  /* SeaLINK+485 (2102) */
 #define SEALEVEL_2103_PID      0x2103  /* SeaLINK+232I (2103) */
 #define SEALEVEL_2104_PID      0x2104  /* SeaLINK+485I (2104) */
+#define SEALEVEL_2106_PID      0x9020  /* SeaLINK+422 (2106) */
 #define SEALEVEL_2201_1_PID    0x2211  /* SeaPORT+2/232 (2201) Port 1 */
 #define SEALEVEL_2201_2_PID    0x2221  /* SeaPORT+2/232 (2201) Port 2 */
 #define SEALEVEL_2202_1_PID    0x2212  /* SeaPORT+2/485 (2202) Port 1 */
  */
 #define FTDI_GAMMA_SCOUT_PID           0xD678  /* Gamma Scout online */
 
+/*
+ * Tactrix OpenPort (ECU) devices.
+ * OpenPort 1.3M submitted by Donour Sizemore.
+ * OpenPort 1.3S and 1.3U submitted by Ian Abbott.
+ */
+#define FTDI_TACTRIX_OPENPORT_13M_PID  0xCC48  /* OpenPort 1.3 Mitsubishi */
+#define FTDI_TACTRIX_OPENPORT_13S_PID  0xCC49  /* OpenPort 1.3 Subaru */
+#define FTDI_TACTRIX_OPENPORT_13U_PID  0xCC4A  /* OpenPort 1.3 Universal */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 17271355639397be219a44c2e3c4fe75f13bd7f2..21cbaa0fb96b998e99084ac3bc3ed6db1ac2f3dc 100644 (file)
@@ -175,14 +175,14 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               spin_lock(&port->lock);
+               spin_lock_bh(&port->lock);
                if (port->write_urb_busy) {
-                       spin_unlock(&port->lock);
+                       spin_unlock_bh(&port->lock);
                        dbg("%s - already writing", __FUNCTION__);
                        return 0;
                }
                port->write_urb_busy = 1;
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
 
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
index bfc6998cd16f41128b6f10c059952213a33b3c30..cbc725a6c58eb15aa606f6e40a37b6e3404493bf 100644 (file)
@@ -479,6 +479,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */
+       { USB_DEVICE(0x0BB4, 0x0BCE) }, /* "High Tech Computer Corp" */
        { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
        { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
        { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
index 87306cb6f9f5a065c6ead79b10e60b77b76a6f2a..812bc213a963349643b0e974cdf8b47629b57fef 100644 (file)
@@ -394,14 +394,14 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int
                return 0;
        }
 
-       spin_lock(&port->lock);
+       spin_lock_bh(&port->lock);
        if (port->write_urb_busy) {
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
        port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       spin_unlock_bh(&port->lock);
 
        count = min(count, port->bulk_out_size);
        memcpy(port->bulk_out_buffer, buf, count);
index 1738b0b6a376dd90e41a1fadf8a3486eff6f0fac..1b348df388ed2586a2ce0937c3f4af9e3b61c934 100644 (file)
@@ -342,14 +342,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        if (count == 0)
                return 0;
 
-       spin_lock(&port->lock);
+       spin_lock_bh(&port->lock);
        if (port->write_urb_busy) {
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
        port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       spin_unlock_bh(&port->lock);
 
        transfer_buffer = port->write_urb->transfer_buffer;
        transfer_size = min(count, port->bulk_out_size - 1);
index 49b8dc039d1fef8f68aca71fee6efdb02082f458..59e777f1e8fdd3502eafab416be7d84bdc15d7ee 100644 (file)
@@ -518,13 +518,13 @@ static int keyspan_pda_write(struct usb_serial_port *port,
           the TX urb is in-flight (wait until it completes)
           the device is full (wait until it says there is room)
        */
-       spin_lock(&port->lock);
+       spin_lock_bh(&port->lock);
        if (port->write_urb_busy || priv->tx_throttled) {
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
                return 0;
        }
        port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       spin_unlock_bh(&port->lock);
 
        /* At this point the URB is in our control, nobody else can submit it
           again (the only sudden transition was the one from EINPROGRESS to
index e49f40913c27550e0c121c8d01bdf8ef909d0ae7..a764ff4e326cfb2c6695af4e226b9389a3a5e866 100644 (file)
@@ -256,14 +256,14 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
                return (0);
        }
 
-       spin_lock(&wport->lock);
+       spin_lock_bh(&wport->lock);
        if (wport->write_urb_busy) {
-               spin_unlock(&wport->lock);
+               spin_unlock_bh(&wport->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
        wport->write_urb_busy = 1;
-       spin_unlock(&wport->lock);
+       spin_unlock_bh(&wport->lock);
 
        count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
index 1036d436ed231116e7283ea94c59a056f1206e7d..9c18173e33fb90710fdda8e3161625eb2cde0e19 100644 (file)
@@ -82,6 +82,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
        { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
        { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index 762cc290ef5869df049629c196b4e59f2f845926..65a5039665e71d31610d5d73645321dd6389b0f0 100644 (file)
@@ -93,3 +93,7 @@
 /* Alcor Micro Corp. USB 2.0 TO RS-232 */
 #define ALCOR_VENDOR_ID                0x058F
 #define ALCOR_PRODUCT_ID       0x9720
+
+/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
+#define HUAWEI_VENDOR_ID       0x12d1
+#define HUAWEI_PRODUCT_ID      0x1001
index 789771ecdb11013a168ffc5fa0157474ab4538dc..1e07dfad68535b54a80a8860f9fc8b71e1f6f615 100644 (file)
@@ -298,14 +298,14 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
                dbg ("%s - write request of 0 bytes", __FUNCTION__);
                return (0);
        }
-       spin_lock(&port->lock);
+       spin_lock_bh(&port->lock);
        if (port->write_urb_busy) {
-               spin_unlock(&port->lock);
+               spin_unlock_bh(&port->lock);
                dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
        port->write_urb_busy = 1;
-       spin_unlock(&port->lock);
+       spin_unlock_bh(&port->lock);
 
        packet_length = port->bulk_out_size;    // get max packetsize
 
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 40bf159f7d5469b3440b9988a5ab50da1ff13447..c9a8d50106d1a3bef5b9f1359baad58d015f1725 100644 (file)
@@ -152,6 +152,13 @@ UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
 
+/* Reported by Jon Hart <Jon.Hart@web.de> */
+UNUSUAL_DEV(  0x0421, 0x0434, 0x0100, 0x0100,
+               "Nokia",
+               "E60",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
+
 /* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
  * Einar Th. Einarsson <einarthered@gmail.com> */
 UNUSUAL_DEV(  0x0421, 0x0444, 0x0100, 0x0100,
@@ -1277,6 +1284,13 @@ UNUSUAL_DEV(  0x0fce, 0xe031, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Jan Mate <mate@fiit.stuba.sk> */
+UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
+               "Sony Ericsson",
+               "P990i",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
  * Entry is needed only for the initializer function override.
index 702eb933cf88bc9414ccbcb85e74de2dcfc18b08..e0ef3328942c44ff0eb09f249388aca98cc1cbcf 100644 (file)
@@ -825,30 +825,48 @@ config FB_I810_I2C
        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
index caf1eca199b0041fa526afe23ae6f10393443a52..628571c63bacc4905517c5563a7fc0fa7848c564 100644 (file)
@@ -33,19 +33,19 @@ static unsigned long locomolcd_flags;
 
 static void locomolcd_on(int comadj)
 {
-       locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 1);
+       locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
        mdelay(2);
 
-       locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 1);
+       locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
        mdelay(2);
 
        locomo_m62332_senddata(locomolcd_dev, comadj, 0);
        mdelay(5);
 
-       locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 1);
+       locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
        mdelay(10);
 
        /* TFTCRST | CPSOUT=0 | CPSEN */
@@ -58,8 +58,8 @@ static void locomolcd_on(int comadj)
        locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
        mdelay(10);
 
-       locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 1);
+       locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
 }
 
 static void locomolcd_off(int comadj)
@@ -68,16 +68,16 @@ static void locomolcd_off(int comadj)
        locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
        mdelay(1);
 
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
        mdelay(110);
 
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
        mdelay(700);
 
        /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
        locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0);
-       locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
+       locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
 }
 
 void locomolcd_power(int on)
@@ -167,14 +167,14 @@ static int locomolcd_resume(struct locomo_dev *dev)
 #define locomolcd_resume       NULL
 #endif
 
-static int locomolcd_probe(struct locomo_dev *dev)
+static int locomolcd_probe(struct locomo_dev *ldev)
 {
        unsigned long flags;
 
        local_irq_save(flags);
-       locomolcd_dev = dev;
+       locomolcd_dev = ldev;
 
-       locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0);
+       locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
 
        /* the poodle_lcd_power function is called for the first time
         * from fs_initcall, which is before locomo is activated.
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 22f7ccd58d38725f7c23f5064c3ace5047aba97f..0f628041e3f7660c75fb846985b4124ba571cffe 100644 (file)
@@ -460,8 +460,10 @@ static int __init init_v9fs(void)
 
        ret = v9fs_mux_global_init();
        if (!ret)
-               ret = register_filesystem(&v9fs_fs_type);
-
+               return ret;
+       ret = register_filesystem(&v9fs_fs_type);
+       if (!ret)
+               v9fs_mux_global_exit();
        return ret;
 }
 
index d311198bba439d812421331e7aea06a5046aa176..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"
 
@@ -881,6 +889,19 @@ config TMPFS
 
          See <file:Documentation/filesystems/tmpfs.txt> for details.
 
+config TMPFS_POSIX_ACL
+       bool "Tmpfs POSIX Access Control Lists"
+       depends on TMPFS
+       select GENERIC_ACL
+       help
+         POSIX Access Control Lists (ACLs) support permissions for users and
+         groups beyond the owner/group/world scheme.
+
+         To learn more about Access Control Lists, visit the POSIX ACLs for
+         Linux website <http://acl.bestbits.at/>.
+
+         If you don't know what Access Control Lists are, say N.
+
 config HUGETLBFS
        bool "HugeTLB file system support"
        depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
@@ -926,7 +947,7 @@ menu "Miscellaneous filesystems"
 
 config ADFS_FS
        tristate "ADFS file system support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        help
          The Acorn Disc Filing System is the standard file system of the
          RiscOS operating system which runs on Acorn's ARM-based Risc PC
@@ -954,7 +975,7 @@ config ADFS_FS_RW
 
 config AFFS_FS
        tristate "Amiga FFS file system support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        help
          The Fast File System (FFS) is the common file system used on hard
          disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20).  Say Y
@@ -976,7 +997,7 @@ config AFFS_FS
 
 config HFS_FS
        tristate "Apple Macintosh file system support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        select NLS
        help
          If you say Y here, you will be able to mount Macintosh-formatted
@@ -989,6 +1010,7 @@ config HFS_FS
 
 config HFSPLUS_FS
        tristate "Apple Extended HFS file system support"
+       depends on BLOCK
        select NLS
        select NLS_UTF8
        help
@@ -1002,7 +1024,7 @@ config HFSPLUS_FS
 
 config BEFS_FS
        tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        select NLS
        help
          The BeOS File System (BeFS) is the native file system of Be, Inc's
@@ -1029,7 +1051,7 @@ config BEFS_DEBUG
 
 config BFS_FS
        tristate "BFS file system support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        help
          Boot File System (BFS) is a file system used under SCO UnixWare to
          allow the bootloader access to the kernel image and other important
@@ -1051,7 +1073,7 @@ config BFS_FS
 
 config EFS_FS
        tristate "EFS file system support (read only) (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on BLOCK && EXPERIMENTAL
        help
          EFS is an older file system used for non-ISO9660 CD-ROMs and hard
          disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
@@ -1066,7 +1088,7 @@ config EFS_FS
 
 config JFFS_FS
        tristate "Journalling Flash File System (JFFS) support"
-       depends on MTD
+       depends on MTD && BLOCK
        help
          JFFS is the Journaling Flash File System developed by Axis
          Communications in Sweden, aimed at providing a crash/powerdown-safe
@@ -1251,6 +1273,7 @@ endchoice
 
 config CRAMFS
        tristate "Compressed ROM file system support (cramfs)"
+       depends on BLOCK
        select ZLIB_INFLATE
        help
          Saying Y here includes support for CramFs (Compressed ROM File
@@ -1270,6 +1293,7 @@ config CRAMFS
 
 config VXFS_FS
        tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
+       depends on BLOCK
        help
          FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
          file system format.  VERITAS VxFS(TM) is the standard file system
@@ -1287,6 +1311,7 @@ config VXFS_FS
 
 config HPFS_FS
        tristate "OS/2 HPFS file system support"
+       depends on BLOCK
        help
          OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
          is the file system used for organizing files on OS/2 hard disk
@@ -1303,6 +1328,7 @@ config HPFS_FS
 
 config QNX4FS_FS
        tristate "QNX4 file system support (read only)"
+       depends on BLOCK
        help
          This is the file system used by the real-time operating systems
          QNX 4 and QNX 6 (the latter is also called QNX RTP).
@@ -1330,6 +1356,7 @@ config QNX4FS_RW
 
 config SYSV_FS
        tristate "System V/Xenix/V7/Coherent file system support"
+       depends on BLOCK
        help
          SCO, Xenix and Coherent are commercial Unix systems for Intel
          machines, and Version 7 was used on the DEC PDP-11. Saying Y
@@ -1368,6 +1395,7 @@ config SYSV_FS
 
 config UFS_FS
        tristate "UFS file system support (read only)"
+       depends on BLOCK
        help
          BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
          OpenBSD and NeXTstep) use a file system called UFS. Some System V
@@ -1940,13 +1968,19 @@ config 9P_FS
 
          If unsure, say N.
 
+config GENERIC_ACL
+       bool
+       select FS_POSIX_ACL
+
 endmenu
 
+if BLOCK
 menu "Partition Types"
 
 source "fs/partitions/Kconfig"
 
 endmenu
+endif
 
 source "fs/nls/Kconfig"
 
index 89135428a539184580b2b0305ec46f6e7d5bfa86..a503e6ce0f329944fd658e1e049662ab8d27f3cb 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
+
+ifeq ($(CONFIG_BLOCK),y)
+obj-y +=       buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o
+else
+obj-y +=       no-block.o
+endif
 
 obj-$(CONFIG_INOTIFY)          += inotify.o
 obj-$(CONFIG_INOTIFY_USER)     += inotify_user.o
@@ -35,6 +41,7 @@ obj-$(CONFIG_BINFMT_FLAT)     += binfmt_flat.o
 obj-$(CONFIG_FS_MBCACHE)       += mbcache.o
 obj-$(CONFIG_FS_POSIX_ACL)     += posix_acl.o xattr_acl.o
 obj-$(CONFIG_NFS_COMMON)       += nfs_common/
+obj-$(CONFIG_GENERIC_ACL)      += generic_acl.o
 
 obj-$(CONFIG_QUOTA)            += dquot.o
 obj-$(CONFIG_QFMT_V1)          += quota_v1.o
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 101d21b6c03715b45ead510a2abccb706f23d209..86463ec9ccb496cea5907ec1de2075c982d4849d 100644 (file)
@@ -775,6 +775,7 @@ static int afs_proc_cell_servers_release(struct inode *inode,
  * first item
  */
 static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos)
+       __acquires(m->private->sv_lock)
 {
        struct list_head *_p;
        struct afs_cell *cell = m->private;
@@ -823,6 +824,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v,
  * clean up after reading from the cells list
  */
 static void afs_proc_cell_servers_stop(struct seq_file *p, void *v)
+       __releases(p->private->sv_lock)
 {
        struct afs_cell *cell = p->private;
 
index 27e17f96cada446d0858405493b46203fd0d57c3..563ef9d7da9ffa858ad754217861f4e2292b30ea 100644 (file)
@@ -281,9 +281,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
 
                DPRINTK("mount done status=%d", status);
 
-               if (status && dentry->d_inode)
-                       return status; /* Try to get the kernel to invalidate this dentry */
-
                /* Turn this into a real negative dentry? */
                if (status == -ENOENT) {
                        spin_lock(&dentry->d_lock);
@@ -359,7 +356,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
         * don't try to mount it again.
         */
        spin_lock(&dcache_lock);
-       if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
+       if (!d_mountpoint(dentry) && __simple_empty(dentry)) {
                spin_unlock(&dcache_lock);
 
                status = try_to_fill_dentry(dentry, 0);
@@ -540,6 +537,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
                            return ERR_PTR(-ERESTARTNOINTR);
                        }
                }
+               spin_lock(&dentry->d_lock);
+               dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+               spin_unlock(&dentry->d_lock);
        }
 
        /*
index f312103434d4594fcd8d532c90bb8b4cf4698289..517e111bb7ef4acbb94f95fb560cb4c2734f4d5b 100644 (file)
@@ -278,6 +278,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                return -ENOEXEC;
        }
 
+       /*
+        * Requires a mmap handler. This prevents people from using a.out
+        * as part of an exploit attack against /proc-related vulnerabilities.
+        */
+       if (!bprm->file->f_op || !bprm->file->f_op->mmap)
+               return -ENOEXEC;
+
        fd_offset = N_TXTOFF(ex);
 
        /* Check initial limits. This avoids letting people circumvent
@@ -476,6 +483,13 @@ static int load_aout_library(struct file *file)
                goto out;
        }
 
+       /*
+        * Requires a mmap handler. This prevents people from using a.out
+        * as part of an exploit attack against /proc-related vulnerabilities.
+        */
+       if (!file->f_op || !file->f_op->mmap)
+               goto out;
+
        if (N_FLAGS(ex))
                goto out;
 
index dfd8cfb7fb5dcd213ab74c41474c81e06a69f8e1..bad52433de69dc01cc836292938607fa02628e20 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
@@ -1038,10 +1037,8 @@ out_free_interp:
 out_free_file:
        sys_close(elf_exec_fileno);
 out_free_fh:
-       if (files) {
-               put_files_struct(current->files);
-               current->files = files;
-       }
+       if (files)
+               reset_files_struct(current, files);
 out_free_ph:
        kfree(elf_phdata);
        goto out;
@@ -1481,20 +1478,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
 
        if (signr) {
                struct elf_thread_status *tmp;
-               read_lock(&tasklist_lock);
+               rcu_read_lock();
                do_each_thread(g,p)
                        if (current->mm == p->mm && current != p) {
                                tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
                                if (!tmp) {
-                                       read_unlock(&tasklist_lock);
+                                       rcu_read_unlock();
                                        goto cleanup;
                                }
-                               INIT_LIST_HEAD(&tmp->list);
                                tmp->thread = p;
                                list_add(&tmp->list, &thread_list);
                        }
                while_each_thread(g,p);
-               read_unlock(&tasklist_lock);
+               rcu_read_unlock();
                list_for_each(t, &thread_list) {
                        struct elf_thread_status *tmp;
                        int sz;
index 2f336582922940ffb9160d664f39acff70fe3ad1..f86d5c9ce5ebda5eaf4c94fbd441dd770a24b9c4 100644 (file)
@@ -1597,20 +1597,19 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
 
        if (signr) {
                struct elf_thread_status *tmp;
-               read_lock(&tasklist_lock);
+               rcu_read_lock();
                do_each_thread(g,p)
                        if (current->mm == p->mm && current != p) {
                                tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
                                if (!tmp) {
-                                       read_unlock(&tasklist_lock);
+                                       rcu_read_unlock();
                                        goto cleanup;
                                }
-                               INIT_LIST_HEAD(&tmp->list);
                                tmp->thread = p;
                                list_add(&tmp->list, &thread_list);
                        }
                while_each_thread(g,p);
-               read_unlock(&tasklist_lock);
+               rcu_read_unlock();
                list_for_each(t, &thread_list) {
                        struct elf_thread_status *tmp;
                        int sz;
index 66ba137f86618b25044a2beeb2a73a6f1dc81865..1713c48fef5494e5e8ef361a83b5795ecaae4ce9 100644 (file)
@@ -215,10 +215,8 @@ _error:
        bprm->interp_flags = 0;
        bprm->interp_data = 0;
 _unshare:
-       if (files) {
-               put_files_struct(current->files);
-               current->files = files;
-       }
+       if (files)
+               reset_files_struct(current, files);
        goto _ret;
 }
 
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 045f98854f14ab91c71cc6a61a9cafb1716a53c4..0c361ea7e5a6e13811da039c8e235b0acb670340 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;
@@ -543,11 +545,11 @@ static struct kobject *bdev_get_holder(struct block_device *bdev)
                return kobject_get(bdev->bd_disk->holder_dir);
 }
 
-static void add_symlink(struct kobject *from, struct kobject *to)
+static int add_symlink(struct kobject *from, struct kobject *to)
 {
        if (!from || !to)
-               return;
-       sysfs_create_link(from, to, kobject_name(to));
+               return 0;
+       return sysfs_create_link(from, to, kobject_name(to));
 }
 
 static void del_symlink(struct kobject *from, struct kobject *to)
@@ -648,30 +650,38 @@ static void free_bd_holder(struct bd_holder *bo)
  * If there is no matching entry with @bo in @bdev->bd_holder_list,
  * add @bo to the list, create symlinks.
  *
- * Returns 1 if @bo was added to the list.
- * Returns 0 if @bo wasn't used by any reason and should be freed.
+ * Returns 0 if symlinks are created or already there.
+ * Returns -ve if something fails and @bo can be freed.
  */
 static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
 {
        struct bd_holder *tmp;
+       int ret;
 
        if (!bo)
-               return 0;
+               return -EINVAL;
 
        list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
                if (tmp->sdir == bo->sdir) {
                        tmp->count++;
+                       /* We've already done what we need to do here. */
+                       free_bd_holder(bo);
                        return 0;
                }
        }
 
        if (!bd_holder_grab_dirs(bdev, bo))
-               return 0;
+               return -EBUSY;
 
-       add_symlink(bo->sdir, bo->sdev);
-       add_symlink(bo->hdir, bo->hdev);
-       list_add_tail(&bo->list, &bdev->bd_holder_list);
-       return 1;
+       ret = add_symlink(bo->sdir, bo->sdev);
+       if (ret == 0) {
+               ret = add_symlink(bo->hdir, bo->hdev);
+               if (ret)
+                       del_symlink(bo->sdir, bo->sdev);
+       }
+       if (ret == 0)
+               list_add_tail(&bo->list, &bdev->bd_holder_list);
+       return ret;
 }
 
 /**
@@ -741,7 +751,9 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
 
        mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
        res = bd_claim(bdev, holder);
-       if (res || !add_bd_holder(bdev, bo))
+       if (res == 0)
+               res = add_bd_holder(bdev, bo);
+       if (res)
                free_bd_holder(bo);
        mutex_unlock(&bdev->bd_mutex);
 
@@ -1021,7 +1033,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
                                rescan_partitions(bdev->bd_disk, bdev);
                } else {
                        mutex_lock_nested(&bdev->bd_contains->bd_mutex,
-                                         BD_MUTEX_PARTITION);
+                                         BD_MUTEX_WHOLE);
                        bdev->bd_contains->bd_part_count++;
                        mutex_unlock(&bdev->bd_contains->bd_mutex);
                }
@@ -1303,3 +1315,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 0009346d827f52ad2da3c24bdbb6485d5cdfa6dd..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
@@ -128,13 +129,31 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
 
        for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
                if ((*cp)->major > major ||
-                   ((*cp)->major == major && (*cp)->baseminor >= baseminor))
+                   ((*cp)->major == major &&
+                    (((*cp)->baseminor >= baseminor) ||
+                     ((*cp)->baseminor + (*cp)->minorct > baseminor))))
                        break;
-       if (*cp && (*cp)->major == major &&
-           (*cp)->baseminor < baseminor + minorct) {
-               ret = -EBUSY;
-               goto out;
+
+       /* Check for overlapping minor ranges.  */
+       if (*cp && (*cp)->major == major) {
+               int old_min = (*cp)->baseminor;
+               int old_max = (*cp)->baseminor + (*cp)->minorct - 1;
+               int new_min = baseminor;
+               int new_max = baseminor + minorct - 1;
+
+               /* New driver overlaps from the left.  */
+               if (new_max >= old_min && new_max <= old_max) {
+                       ret = -EBUSY;
+                       goto out;
+               }
+
+               /* New driver overlaps from the right.  */
+               if (new_min <= old_max && new_min >= old_min) {
+                       ret = -EBUSY;
+                       goto out;
+               }
        }
+
        cd->next = *cp;
        *cp = cd;
        mutex_unlock(&chrdevs_lock);
@@ -165,6 +184,15 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
        return cd;
 }
 
+/**
+ * register_chrdev_region() - register a range of device numbers
+ * @from: the first in the desired range of device numbers; must include
+ *        the major number.
+ * @count: the number of consecutive device numbers required
+ * @name: the name of the device or driver.
+ *
+ * Return value is zero on success, a negative error code on failure.
+ */
 int register_chrdev_region(dev_t from, unsigned count, const char *name)
 {
        struct char_device_struct *cd;
@@ -190,6 +218,17 @@ fail:
        return PTR_ERR(cd);
 }
 
+/**
+ * alloc_chrdev_region() - register a range of char device numbers
+ * @dev: output parameter for first assigned number
+ * @baseminor: first of the requested range of minor numbers
+ * @count: the number of minor numbers required
+ * @name: the name of the associated device or driver
+ *
+ * Allocates a range of char device numbers.  The major number will be
+ * chosen dynamically, and returned (along with the first minor number)
+ * in @dev.  Returns zero or a negative error code.
+ */
 int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
                        const char *name)
 {
@@ -259,6 +298,15 @@ out2:
        return err;
 }
 
+/**
+ * unregister_chrdev_region() - return a range of device numbers
+ * @from: the first in the range of numbers to unregister
+ * @count: the number of device numbers to unregister
+ *
+ * This function will unregister a range of @count device numbers,
+ * starting with @from.  The caller should normally be the one who
+ * allocated those numbers in the first place...
+ */
 void unregister_chrdev_region(dev_t from, unsigned count)
 {
        dev_t to = from + count;
@@ -396,6 +444,16 @@ static int exact_lock(dev_t dev, void *data)
        return cdev_get(p) ? 0 : -1;
 }
 
+/**
+ * cdev_add() - add a char device to the system
+ * @p: the cdev structure for the device
+ * @dev: the first device number for which this device is responsible
+ * @count: the number of consecutive minor numbers corresponding to this
+ *         device
+ *
+ * cdev_add() adds the device represented by @p to the system, making it
+ * live immediately.  A negative error code is returned on failure.
+ */
 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
 {
        p->dev = dev;
@@ -408,6 +466,13 @@ static void cdev_unmap(dev_t dev, unsigned count)
        kobj_unmap(cdev_map, dev, count);
 }
 
+/**
+ * cdev_del() - remove a cdev from the system
+ * @p: the cdev structure to be removed
+ *
+ * cdev_del() removes @p from the system, possibly freeing the structure
+ * itself.
+ */
 void cdev_del(struct cdev *p)
 {
        cdev_unmap(p->dev, p->count);
@@ -436,6 +501,11 @@ static struct kobj_type ktype_cdev_dynamic = {
        .release        = cdev_dynamic_release,
 };
 
+/**
+ * cdev_alloc() - allocate a cdev structure
+ *
+ * Allocates and returns a cdev structure, or NULL on failure.
+ */
 struct cdev *cdev_alloc(void)
 {
        struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
@@ -447,6 +517,14 @@ struct cdev *cdev_alloc(void)
        return p;
 }
 
+/**
+ * cdev_init() - initialize a cdev structure
+ * @cdev: the structure to initialize
+ * @fops: the file_operations for this device
+ *
+ * Initializes @cdev, remembering @fops, making it ready to add to the
+ * system with cdev_add().
+ */
 void cdev_init(struct cdev *cdev, const struct file_operations *fops)
 {
        memset(cdev, 0, sizeof *cdev);
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..05f874c7441bbd388087dd0be9a1197628144373 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>
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 ce982f6e8c80270be3fd23f8f9553c486626986e..122b4e3992b54b322d40ef84814c95048ca00472 100644 (file)
 #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;
 
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+
 int compat_printk(const char *fmt, ...)
 {
        va_list ap;
@@ -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"
index 4063a939697768d990faa971a4488efe21f80dcb..64b34533edea67e2ed28f0c85fa406d3135de23c 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>
@@ -60,7 +56,6 @@
 #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/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 +155,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 +645,7 @@ out:
 }
 #endif
 
+#ifdef CONFIG_BLOCK
 struct hd_geometry32 {
        unsigned char heads;
        unsigned char sectors;
@@ -918,6 +870,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 +994,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 +1167,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 +1495,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 +1530,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 +1558,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 +1579,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 +1904,7 @@ out:
        kfree(karg);
        return err;
 }
+#endif
 
 struct mtd_oob_buf32 {
        u_int32_t start;
@@ -2052,61 +1946,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 +2011,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
         }
         return ret;
 }
+#endif /* CONFIG_BLOCK */
 
 struct serial_struct32 {
         compat_int_t    type;
@@ -2777,6 +2618,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 +2644,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 +2664,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 +2693,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)
index ad96b69907156c5e79879da38a4d928a47fa8b8e..a624c3ec81892870545cd80bea3f22c91069c2ab 100644 (file)
@@ -543,8 +543,15 @@ static struct file_system_type cramfs_fs_type = {
 
 static int __init init_cramfs_fs(void)
 {
-       cramfs_uncompress_init();
-       return register_filesystem(&cramfs_fs_type);
+       int rv;
+
+       rv = cramfs_uncompress_init();
+       if (rv < 0)
+               return rv;
+       rv = register_filesystem(&cramfs_fs_type);
+       if (rv < 0)
+               cramfs_uncompress_exit();
+       return rv;
 }
 
 static void __exit exit_cramfs_fs(void)
index 8def89f2c4383b052490eeba366241adc07ccaa8..fc3ccb74626ffb3a581da4049c703242352dedfa 100644 (file)
@@ -68,11 +68,10 @@ int cramfs_uncompress_init(void)
        return 0;
 }
 
-int cramfs_uncompress_exit(void)
+void cramfs_uncompress_exit(void)
 {
        if (!--initialized) {
                zlib_inflateEnd(&stream);
                vfree(stream.workspace);
        }
-       return 0;
 }
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 0122a279106a9dd4a0475557901471be5c428546..9af789567e513b4575c9066711b8b6f595c949c7 100644 (file)
@@ -834,6 +834,9 @@ static void print_warning(struct dquot *dquot, const char warntype)
        if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
                return;
 
+       mutex_lock(&tty_mutex);
+       if (!current->signal->tty)
+               goto out_lock;
        tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
        if (warntype == ISOFTWARN || warntype == BSOFTWARN)
                tty_write_message(current->signal->tty, ": warning, ");
@@ -861,6 +864,8 @@ static void print_warning(struct dquot *dquot, const char warntype)
                        break;
        }
        tty_write_message(current->signal->tty, msg);
+out_lock:
+       mutex_unlock(&tty_mutex);
 }
 
 static inline void flush_warnings(struct dquot **dquots, char *warntype)
index 97df6e0aeaeed58db0f63ab746883ee87c7c1985..a8efe35176b025626e4e49732ec49a1843862250 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -898,8 +898,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        return 0;
 
 mmap_failed:
-       put_files_struct(current->files);
-       current->files = files;
+       reset_files_struct(current, files);
 out:
        return retval;
 }
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..e8bbed9dd2680d094b550228694fe66136b7ea80 100644 (file)
@@ -46,6 +46,9 @@ const struct file_operations ext2_file_operations = {
        .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,
@@ -63,6 +66,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 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..74ff20f9d09b927f982c0f5331f7b339286a1ad3 100644 (file)
@@ -114,6 +114,9 @@ const struct file_operations ext3_file_operations = {
        .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..235e77b52ea59b2610c2ed5cf4af464f4cd12359 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)
index 698b85bb1dd45855a709635eb6239a4c9bbef0d6..3e50a41662834834538886e5cd0aa4d48d0c3b08 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,
@@ -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 1ee25232e6af3dd4cee629fdeba312f769cd8d02..d50fc47169c1aba4b4388677dfabfd4f53b11933 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
+#include <linux/blkdev.h>
 
 int fat_generic_ioctl(struct inode *inode, struct file *filp,
                      unsigned int cmd, unsigned long arg)
@@ -112,6 +113,16 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
        }
 }
 
+static int fat_file_release(struct inode *inode, struct file *filp)
+{
+       if ((filp->f_mode & FMODE_WRITE) &&
+            MSDOS_SB(inode->i_sb)->options.flush) {
+               fat_flush_inodes(inode->i_sb, inode, NULL);
+               blk_congestion_wait(WRITE, HZ/10);
+       }
+       return 0;
+}
+
 const struct file_operations fat_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
@@ -121,6 +132,7 @@ const struct file_operations fat_file_operations = {
        .aio_read       = generic_file_aio_read,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
+       .release        = fat_file_release,
        .ioctl          = fat_generic_ioctl,
        .fsync          = file_fsync,
        .sendfile       = generic_file_sendfile,
@@ -289,6 +301,7 @@ void fat_truncate(struct inode *inode)
        lock_kernel();
        fat_free(inode, nr_clusters);
        unlock_kernel();
+       fat_flush_inodes(inode->i_sb, inode, NULL);
 }
 
 struct inode_operations fat_file_inode_operations = {
index ab96ae82375305ae295447bbef39a1728894eae0..045738032a83d5f4579208881d17088a65326e5a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/vfs.h>
 #include <linux/parser.h>
 #include <linux/uio.h>
+#include <linux/writeback.h>
 #include <asm/unaligned.h>
 
 #ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -853,7 +854,7 @@ enum {
        Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
        Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
        Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
-       Opt_obsolate, Opt_err,
+       Opt_obsolate, Opt_flush, Opt_err,
 };
 
 static match_table_t fat_tokens = {
@@ -885,7 +886,8 @@ static match_table_t fat_tokens = {
        {Opt_obsolate, "cvf_format=%20s"},
        {Opt_obsolate, "cvf_options=%100s"},
        {Opt_obsolate, "posix"},
-       {Opt_err, NULL}
+       {Opt_flush, "flush"},
+       {Opt_err, NULL},
 };
 static match_table_t msdos_tokens = {
        {Opt_nodots, "nodots"},
@@ -1026,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
                                return 0;
                        opts->codepage = option;
                        break;
+               case Opt_flush:
+                       opts->flush = 1;
+                       break;
 
                /* msdos specific */
                case Opt_dots:
@@ -1425,6 +1430,56 @@ out_fail:
 
 EXPORT_SYMBOL_GPL(fat_fill_super);
 
+/*
+ * helper function for fat_flush_inodes.  This writes both the inode
+ * and the file data blocks, waiting for in flight data blocks before
+ * the start of the call.  It does not wait for any io started
+ * during the call
+ */
+static int writeback_inode(struct inode *inode)
+{
+
+       int ret;
+       struct address_space *mapping = inode->i_mapping;
+       struct writeback_control wbc = {
+              .sync_mode = WB_SYNC_NONE,
+             .nr_to_write = 0,
+       };
+       /* if we used WB_SYNC_ALL, sync_inode waits for the io for the
+       * inode to finish.  So WB_SYNC_NONE is sent down to sync_inode
+       * and filemap_fdatawrite is used for the data blocks
+       */
+       ret = sync_inode(inode, &wbc);
+       if (!ret)
+              ret = filemap_fdatawrite(mapping);
+       return ret;
+}
+
+/*
+ * write data and metadata corresponding to i1 and i2.  The io is
+ * started but we do not wait for any of it to finish.
+ *
+ * filemap_flush is used for the block device, so if there is a dirty
+ * page for a block already in flight, we will not wait and start the
+ * io over again
+ */
+int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2)
+{
+       int ret = 0;
+       if (!MSDOS_SB(sb)->options.flush)
+               return 0;
+       if (i1)
+               ret = writeback_inode(i1);
+       if (!ret && i2)
+               ret = writeback_inode(i2);
+       if (!ret && sb) {
+               struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+               ret = filemap_flush(mapping);
+       }
+       return ret;
+}
+EXPORT_SYMBOL_GPL(fat_flush_inodes);
+
 static int __init init_fat_fs(void)
 {
        int err;
index 8d3bfca7714bf35e9e982caa761bb5c549909bc6..8e81775c5dc818bd3b9d66e3fd895524294f5c78 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -288,71 +288,63 @@ out:
 }
 
 /*
- * Expands the file descriptor table - it will allocate a new fdtable and
- * both fd array and fdset. It is expected to be called with the
- * files_lock held.
+ * Expand the file descriptor table.
+ * This function will allocate a new fdtable and both fd array and fdset, of
+ * the given size.
+ * Return <0 error code on error; 1 on successful completion.
+ * The files->file_lock should be held on entry, and will be held on exit.
  */
 static int expand_fdtable(struct files_struct *files, int nr)
        __releases(files->file_lock)
        __acquires(files->file_lock)
 {
-       int error = 0;
-       struct fdtable *fdt;
-       struct fdtable *nfdt = NULL;
+       struct fdtable *new_fdt, *cur_fdt;
 
        spin_unlock(&files->file_lock);
-       nfdt = alloc_fdtable(nr);
-       if (!nfdt) {
-               error = -ENOMEM;
-               spin_lock(&files->file_lock);
-               goto out;
-       }
-
+       new_fdt = alloc_fdtable(nr);
        spin_lock(&files->file_lock);
-       fdt = files_fdtable(files);
+       if (!new_fdt)
+               return -ENOMEM;
        /*
-        * Check again since another task may have expanded the
-        * fd table while we dropped the lock
+        * Check again since another task may have expanded the fd table while
+        * we dropped the lock
         */
-       if (nr >= fdt->max_fds || nr >= fdt->max_fdset) {
-               copy_fdtable(nfdt, fdt);
+       cur_fdt = files_fdtable(files);
+       if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) {
+               /* Continue as planned */
+               copy_fdtable(new_fdt, cur_fdt);
+               rcu_assign_pointer(files->fdt, new_fdt);
+               free_fdtable(cur_fdt);
        } else {
-               /* Somebody expanded while we dropped file_lock */
-               spin_unlock(&files->file_lock);
-               __free_fdtable(nfdt);
-               spin_lock(&files->file_lock);
-               goto out;
+               /* Somebody else expanded, so undo our attempt */
+               __free_fdtable(new_fdt);
        }
-       rcu_assign_pointer(files->fdt, nfdt);
-       free_fdtable(fdt);
-out:
-       return error;
+       return 1;
 }
 
 /*
  * Expand files.
- * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked.
- * Should be called with the files->file_lock spinlock held for write.
+ * This function will expand the file structures, if the requested size exceeds
+ * the current capacity and there is room for expansion.
+ * Return <0 error code on error; 0 when nothing done; 1 when files were
+ * expanded and execution may have blocked.
+ * The files->file_lock should be held on entry, and will be held on exit.
  */
 int expand_files(struct files_struct *files, int nr)
 {
-       int err, expand = 0;
        struct fdtable *fdt;
 
        fdt = files_fdtable(files);
-       if (nr >= fdt->max_fdset || nr >= fdt->max_fds) {
-               if (fdt->max_fdset >= NR_OPEN ||
-                       fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) {
-                       err = -EMFILE;
-                       goto out;
-               }
-               expand = 1;
-               if ((err = expand_fdtable(files, nr)))
-                       goto out;
-       }
-       err = expand;
-out:
-       return err;
+       /* Do we need to expand? */
+       if (nr < fdt->max_fdset && nr < fdt->max_fds)
+               return 0;
+       /* Can we expand? */
+       if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN ||
+           nr >= NR_OPEN)
+               return -EMFILE;
+
+       /* All good, so we try */
+       return expand_fdtable(files, nr);
 }
 
 static void __devinit fdtable_defer_list_init(int cpu)
index 9f1072836c8ea5c940c916d8236365a26c78da84..e3fa77c6ed56dce64e3fe68892022edaa85d0e56 100644 (file)
@@ -69,8 +69,6 @@ int register_filesystem(struct file_system_type * fs)
        int res = 0;
        struct file_system_type ** p;
 
-       if (!fs)
-               return -EINVAL;
        if (fs->next)
                return -EBUSY;
        INIT_LIST_HEAD(&fs->fs_supers);
index b74b791fc23ba6e4b905e2312518ddde0073ba16..ac28b0835ffc611a0236f3ba745744ba1ca05390 100644 (file)
@@ -260,12 +260,17 @@ static struct file_system_type vxfs_fs_type = {
 static int __init
 vxfs_init(void)
 {
+       int rv;
+
        vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
                        sizeof(struct vxfs_inode_info), 0, 
                        SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL);
-       if (vxfs_inode_cachep)
-               return register_filesystem(&vxfs_fs_type);
-       return -ENOMEM;
+       if (!vxfs_inode_cachep)
+               return -ENOMEM;
+       rv = register_filesystem(&vxfs_fs_type);
+       if (rv < 0)
+               kmem_cache_destroy(vxfs_inode_cachep);
+       return rv;
 }
 
 static void __exit
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 1e2006caf15842b2c2beffe11968f3cc6311f16f..4fc557c40cc0c0bf8f158a7793d508f9ccb23111 100644 (file)
@@ -212,6 +212,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
  * Called with fc->lock, unlocks it
  */
 static void request_end(struct fuse_conn *fc, struct fuse_req *req)
+       __releases(fc->lock)
 {
        void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
        req->end = NULL;
@@ -640,6 +641,7 @@ static void request_wait(struct fuse_conn *fc)
  */
 static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
                               const struct iovec *iov, unsigned long nr_segs)
+       __releases(fc->lock)
 {
        struct fuse_copy_state cs;
        struct fuse_in_header ih;
index 409ce6a7cca4ccd2e53f46693a5e4301bef87245..f85b2a282f130e2f0d4a5dc4d4bcfc61ed99b2f7 100644 (file)
@@ -776,7 +776,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
                if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
                        return -EACCES;
 
-               if (nd && (nd->flags & LOOKUP_ACCESS))
+               if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
                        return fuse_access(inode, mask);
                return 0;
        }
index cb7cadb0b7901906e2dfd47bd5f3aac3b3578fb7..7d0a9aee01f248ef70bb1796a013fca8dda571af 100644 (file)
@@ -251,6 +251,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
        memset(&outarg, 0, sizeof(outarg));
        req->in.numargs = 0;
        req->in.h.opcode = FUSE_STATFS;
+       req->in.h.nodeid = get_node_id(dentry->d_inode);
        req->out.numargs = 1;
        req->out.args[0].size =
                fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
new file mode 100644 (file)
index 0000000..9ccb789
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/generic_acl.h>
+
+/**
+ * generic_acl_list  -  Generic xattr_handler->list() operation
+ * @ops:       Filesystem specific getacl and setacl callbacks
+ */
+size_t
+generic_acl_list(struct inode *inode, struct generic_acl_operations *ops,
+                int type, char *list, size_t list_size)
+{
+       struct posix_acl *acl;
+       const char *name;
+       size_t size;
+
+       acl = ops->getacl(inode, type);
+       if (!acl)
+               return 0;
+       posix_acl_release(acl);
+
+       switch(type) {
+               case ACL_TYPE_ACCESS:
+                       name = POSIX_ACL_XATTR_ACCESS;
+                       break;
+
+               case ACL_TYPE_DEFAULT:
+                       name = POSIX_ACL_XATTR_DEFAULT;
+                       break;
+
+               default:
+                       return 0;
+       }
+       size = strlen(name) + 1;
+       if (list && size <= list_size)
+               memcpy(list, name, size);
+       return size;
+}
+
+/**
+ * generic_acl_get  -  Generic xattr_handler->get() operation
+ * @ops:       Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_get(struct inode *inode, struct generic_acl_operations *ops,
+               int type, void *buffer, size_t size)
+{
+       struct posix_acl *acl;
+       int error;
+
+       acl = ops->getacl(inode, type);
+       if (!acl)
+               return -ENODATA;
+       error = posix_acl_to_xattr(acl, buffer, size);
+       posix_acl_release(acl);
+
+       return error;
+}
+
+/**
+ * generic_acl_set  -  Generic xattr_handler->set() operation
+ * @ops:       Filesystem specific getacl and setacl callbacks
+ */
+int
+generic_acl_set(struct inode *inode, struct generic_acl_operations *ops,
+               int type, const void *value, size_t size)
+{
+       struct posix_acl *acl = NULL;
+       int error;
+
+       if (S_ISLNK(inode->i_mode))
+               return -EOPNOTSUPP;
+       if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
+               return -EPERM;
+       if (value) {
+               acl = posix_acl_from_xattr(value, size);
+               if (IS_ERR(acl))
+                       return PTR_ERR(acl);
+       }
+       if (acl) {
+               mode_t mode;
+
+               error = posix_acl_valid(acl);
+               if (error)
+                       goto failed;
+               switch(type) {
+                       case ACL_TYPE_ACCESS:
+                               mode = inode->i_mode;
+                               error = posix_acl_equiv_mode(acl, &mode);
+                               if (error < 0)
+                                       goto failed;
+                               inode->i_mode = mode;
+                               if (error == 0) {
+                                       posix_acl_release(acl);
+                                       acl = NULL;
+                               }
+                               break;
+
+                       case ACL_TYPE_DEFAULT:
+                               if (!S_ISDIR(inode->i_mode)) {
+                                       error = -EINVAL;
+                                       goto failed;
+                               }
+                               break;
+               }
+       }
+       ops->setacl(inode, type, acl);
+       error = 0;
+failed:
+       posix_acl_release(acl);
+       return error;
+}
+
+/**
+ * generic_acl_init  -  Take care of acl inheritance at @inode create time
+ * @ops:       Filesystem specific getacl and setacl callbacks
+ *
+ * Files created inside a directory with a default ACL inherit the
+ * directory's default ACL.
+ */
+int
+generic_acl_init(struct inode *inode, struct inode *dir,
+                struct generic_acl_operations *ops)
+{
+       struct posix_acl *acl = NULL;
+       mode_t mode = inode->i_mode;
+       int error;
+
+       inode->i_mode = mode & ~current->fs->umask;
+       if (!S_ISLNK(inode->i_mode))
+               acl = ops->getacl(dir, ACL_TYPE_DEFAULT);
+       if (acl) {
+               struct posix_acl *clone;
+
+               if (S_ISDIR(inode->i_mode)) {
+                       clone = posix_acl_clone(acl, GFP_KERNEL);
+                       error = -ENOMEM;
+                       if (!clone)
+                               goto cleanup;
+                       ops->setacl(inode, ACL_TYPE_DEFAULT, clone);
+                       posix_acl_release(clone);
+               }
+               clone = posix_acl_clone(acl, GFP_KERNEL);
+               error = -ENOMEM;
+               if (!clone)
+                       goto cleanup;
+               error = posix_acl_create_masq(clone, &mode);
+               if (error >= 0) {
+                       inode->i_mode = mode;
+                       if (error > 0)
+                               ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+               }
+               posix_acl_release(clone);
+       }
+       error = 0;
+
+cleanup:
+       posix_acl_release(acl);
+       return error;
+}
+
+/**
+ * generic_acl_chmod  -  change the access acl of @inode upon chmod()
+ * @ops:       FIlesystem specific getacl and setacl callbacks
+ *
+ * A chmod also changes the permissions of the owner, group/mask, and
+ * other ACL entries.
+ */
+int
+generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops)
+{
+       struct posix_acl *acl, *clone;
+       int error = 0;
+
+       if (S_ISLNK(inode->i_mode))
+               return -EOPNOTSUPP;
+       acl = ops->getacl(inode, ACL_TYPE_ACCESS);
+       if (acl) {
+               clone = posix_acl_clone(acl, GFP_KERNEL);
+               posix_acl_release(acl);
+               if (!clone)
+                       return -ENOMEM;
+               error = posix_acl_chmod_masq(clone, inode->i_mode);
+               if (!error)
+                       ops->setacl(inode, ACL_TYPE_ACCESS, clone);
+               posix_acl_release(clone);
+       }
+       return error;
+}
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 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 e025a31b4c64a9f2584e7e2f5e095aae3d8a353c..f5b8f329aca6d3e3c3b102cc50b1ee55c2663362 100644 (file)
@@ -229,7 +229,7 @@ static void hugetlbfs_delete_inode(struct inode *inode)
        clear_inode(inode);
 }
 
-static void hugetlbfs_forget_inode(struct inode *inode)
+static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
 {
        struct super_block *sb = inode->i_sb;
 
index f5c04dd9ae8ae54ba32ebfd4c8cba3bb4001f219..ada7643104e14dee4bcc8a5dc5bd87b7398aad5f 100644 (file)
@@ -133,7 +133,6 @@ static struct inode *alloc_inode(struct super_block *sb)
                inode->i_bdev = NULL;
                inode->i_cdev = NULL;
                inode->i_rdev = 0;
-               inode->i_security = NULL;
                inode->dirtied_when = 0;
                if (security_inode_alloc(inode)) {
                        if (inode->i_sb->s_op->destroy_inode)
@@ -363,27 +362,6 @@ int invalidate_inodes(struct super_block * sb)
 }
 
 EXPORT_SYMBOL(invalidate_inodes);
-int __invalidate_device(struct block_device *bdev)
-{
-       struct super_block *sb = get_super(bdev);
-       int res = 0;
-
-       if (sb) {
-               /*
-                * no need to lock the super, get_super holds the
-                * read mutex so the filesystem cannot go away
-                * under us (->put_super runs with the write lock
-                * hold).
-                */
-               shrink_dcache_sb(sb);
-               res = invalidate_inodes(sb);
-               drop_super(sb);
-       }
-       invalidate_bdev(bdev, 0);
-       return res;
-}
-EXPORT_SYMBOL(__invalidate_device);
 
 static int can_unuse(struct inode *inode)
 {
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 4527692f432b1b262f74bc42027326628e06b5ee..c34b862cdbf204cf5e7124408659f89108289a82 100644 (file)
@@ -960,30 +960,30 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
                        goto abort;
                }
                
-               if (nextblk) {
-                       while (b_off >= (offset + sect_size)) {
-                               struct inode *ninode;
-                               
-                               offset += sect_size;
-                               if (nextblk == 0)
-                                       goto abort;
-                               ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
-                               if (!ninode)
-                                       goto abort;
-                               firstext  = ISOFS_I(ninode)->i_first_extent;
-                               sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
-                               nextblk   = ISOFS_I(ninode)->i_next_section_block;
-                               nextoff   = ISOFS_I(ninode)->i_next_section_offset;
-                               iput(ninode);
-                               
-                               if (++section > 100) {
-                                       printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
-                                       printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
-                                              "nextblk=%lu nextoff=%lu\n",
-                                              iblock, firstext, (unsigned) sect_size,
-                                              nextblk, nextoff);
-                                       goto abort;
-                               }
+               /* On the last section, nextblk == 0, section size is likely to
+                * exceed sect_size by a partial block, and access beyond the
+                * end of the file will reach beyond the section size, too.
+                */
+               while (nextblk && (b_off >= (offset + sect_size))) {
+                       struct inode *ninode;
+
+                       offset += sect_size;
+                       ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
+                       if (!ninode)
+                               goto abort;
+                       firstext  = ISOFS_I(ninode)->i_first_extent;
+                       sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
+                       nextblk   = ISOFS_I(ninode)->i_next_section_block;
+                       nextoff   = ISOFS_I(ninode)->i_next_section_offset;
+                       iput(ninode);
+
+                       if (++section > 100) {
+                               printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
+                               printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
+                                      "nextblk=%lu nextoff=%lu\n",
+                                      iblock, firstext, (unsigned) sect_size,
+                                      nextblk, nextoff);
+                               goto abort;
                        }
                }
                
index 2fc66c3e66818830904603d2023b4bd4422963ed..7af6099c911c2cbb584932f822788b5e92ab4d9f 100644 (file)
@@ -715,18 +715,8 @@ journal_t * journal_init_dev(struct block_device *bdev,
        if (!journal)
                return NULL;
 
-       journal->j_dev = bdev;
-       journal->j_fs_dev = fs_dev;
-       journal->j_blk_offset = start;
-       journal->j_maxlen = len;
-       journal->j_blocksize = blocksize;
-
-       bh = __getblk(journal->j_dev, start, journal->j_blocksize);
-       J_ASSERT(bh != NULL);
-       journal->j_sb_buffer = bh;
-       journal->j_superblock = (journal_superblock_t *)bh->b_data;
-
        /* journal descriptor can store up to n blocks -bzzz */
+       journal->j_blocksize = blocksize;
        n = journal->j_blocksize / sizeof(journal_block_tag_t);
        journal->j_wbufsize = n;
        journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
@@ -736,6 +726,15 @@ journal_t * journal_init_dev(struct block_device *bdev,
                kfree(journal);
                journal = NULL;
        }
+       journal->j_dev = bdev;
+       journal->j_fs_dev = fs_dev;
+       journal->j_blk_offset = start;
+       journal->j_maxlen = len;
+
+       bh = __getblk(journal->j_dev, start, journal->j_blocksize);
+       J_ASSERT(bh != NULL);
+       journal->j_sb_buffer = bh;
+       journal->j_superblock = (journal_superblock_t *)bh->b_data;
 
        return journal;
 }
index 445eed6ce5dc6d0c9196aab99b68d0e53cad1a67..11563fe2a52bed60eafe259d92ae3aedbfa64e98 100644 (file)
@@ -46,7 +46,7 @@ static int scan_revoke_records(journal_t *, struct buffer_head *,
 #ifdef __KERNEL__
 
 /* Release readahead buffers after use */
-void journal_brelse_array(struct buffer_head *b[], int n)
+static void journal_brelse_array(struct buffer_head *b[], int n)
 {
        while (--n >= 0)
                brelse (b[n]);
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 8db5afb7b0a7dec0cc8c6bf372c2445050f54b1f..3793aaa145776971a19fbbbb9b61934634f80731 100644 (file)
@@ -317,17 +317,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 int simple_readpage(struct file *file, struct page *page)
 {
-       void *kaddr;
-
-       if (PageUptodate(page))
-               goto out;
-
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr, 0, PAGE_CACHE_SIZE);
-       kunmap_atomic(kaddr, KM_USER0);
+       clear_highpage(page);
        flush_dcache_page(page);
        SetPageUptodate(page);
-out:
        unlock_page(page);
        return 0;
 }
index e4fde1ab22cdb0a5af105cdea66cccf9473ac08e..0ff71256e65b4fb0d3a9fc4352c0a8c9b4b5e365 100644 (file)
@@ -160,6 +160,7 @@ __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
 
 static void
 __mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
+       __releases(mb_cache_spinlock)
 {
        /* Wake up all processes queuing for this cache entry. */
        if (ce->e_queued)
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 9e44158a7540d3c41e6324c89ea78ebfa68c016b..d220165d49180fc53c6b66401e439ac2b9d36113 100644 (file)
@@ -280,7 +280,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
                        struct nameidata *nd)
 {
        struct super_block *sb = dir->i_sb;
-       struct inode *inode;
+       struct inode *inode = NULL;
        struct fat_slot_info sinfo;
        struct timespec ts;
        unsigned char msdos_name[MSDOS_NAME];
@@ -316,6 +316,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
        d_instantiate(dentry, inode);
 out:
        unlock_kernel();
+       if (!err)
+               err = fat_flush_inodes(sb, dir, inode);
        return err;
 }
 
@@ -348,6 +350,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
        fat_detach(inode);
 out:
        unlock_kernel();
+       if (!err)
+               err = fat_flush_inodes(inode->i_sb, dir, inode);
 
        return err;
 }
@@ -401,6 +405,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        d_instantiate(dentry, inode);
 
        unlock_kernel();
+       fat_flush_inodes(sb, dir, inode);
        return 0;
 
 out_free:
@@ -430,6 +435,8 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
        fat_detach(inode);
 out:
        unlock_kernel();
+       if (!err)
+               err = fat_flush_inodes(inode->i_sb, dir, inode);
 
        return err;
 }
@@ -635,6 +642,8 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
                              new_dir, new_msdos_name, new_dentry, is_hid);
 out:
        unlock_kernel();
+       if (!err)
+               err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir);
        return err;
 }
 
index 808e4ea2bb9413a446743fbcdf10caae8d0baf2f..2892e68d3a8647981e5aa7caf3c53e708584d4bf 100644 (file)
@@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *);
 static __always_inline int
 walk_init_root(const char *name, struct nameidata *nd)
 {
-       read_lock(&current->fs->lock);
-       if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-               nd->mnt = mntget(current->fs->altrootmnt);
-               nd->dentry = dget(current->fs->altroot);
-               read_unlock(&current->fs->lock);
+       struct fs_struct *fs = current->fs;
+
+       read_lock(&fs->lock);
+       if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
+               nd->mnt = mntget(fs->altrootmnt);
+               nd->dentry = dget(fs->altroot);
+               read_unlock(&fs->lock);
                if (__emul_lookup_dentry(name,nd))
                        return 0;
-               read_lock(&current->fs->lock);
+               read_lock(&fs->lock);
        }
-       nd->mnt = mntget(current->fs->rootmnt);
-       nd->dentry = dget(current->fs->root);
-       read_unlock(&current->fs->lock);
+       nd->mnt = mntget(fs->rootmnt);
+       nd->dentry = dget(fs->root);
+       read_unlock(&fs->lock);
        return 1;
 }
 
@@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
 
 static __always_inline void follow_dotdot(struct nameidata *nd)
 {
+       struct fs_struct *fs = current->fs;
+
        while(1) {
                struct vfsmount *parent;
                struct dentry *old = nd->dentry;
 
-                read_lock(&current->fs->lock);
-               if (nd->dentry == current->fs->root &&
-                   nd->mnt == current->fs->rootmnt) {
-                        read_unlock(&current->fs->lock);
+                read_lock(&fs->lock);
+               if (nd->dentry == fs->root &&
+                   nd->mnt == fs->rootmnt) {
+                        read_unlock(&fs->lock);
                        break;
                }
-                read_unlock(&current->fs->lock);
+                read_unlock(&fs->lock);
                spin_lock(&dcache_lock);
                if (nd->dentry != nd->mnt->mnt_root) {
                        nd->dentry = dget(nd->dentry->d_parent);
@@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
                struct vfsmount *old_mnt = nd->mnt;
                struct qstr last = nd->last;
                int last_type = nd->last_type;
+               struct fs_struct *fs = current->fs;
+
                /*
-                * NAME was not found in alternate root or it's a directory.  Try to find
-                * it in the normal root:
+                * NAME was not found in alternate root or it's a directory.
+                * Try to find it in the normal root:
                 */
                nd->last_type = LAST_ROOT;
-               read_lock(&current->fs->lock);
-               nd->mnt = mntget(current->fs->rootmnt);
-               nd->dentry = dget(current->fs->root);
-               read_unlock(&current->fs->lock);
+               read_lock(&fs->lock);
+               nd->mnt = mntget(fs->rootmnt);
+               nd->dentry = dget(fs->root);
+               read_unlock(&fs->lock);
                if (path_walk(name, nd) == 0) {
                        if (nd->dentry->d_inode) {
                                dput(old_dentry);
@@ -1074,6 +1080,7 @@ void set_fs_altroot(void)
        struct vfsmount *mnt = NULL, *oldmnt;
        struct dentry *dentry = NULL, *olddentry;
        int err;
+       struct fs_struct *fs = current->fs;
 
        if (!emul)
                goto set_it;
@@ -1083,12 +1090,12 @@ void set_fs_altroot(void)
                dentry = nd.dentry;
        }
 set_it:
-       write_lock(&current->fs->lock);
-       oldmnt = current->fs->altrootmnt;
-       olddentry = current->fs->altroot;
-       current->fs->altrootmnt = mnt;
-       current->fs->altroot = dentry;
-       write_unlock(&current->fs->lock);
+       write_lock(&fs->lock);
+       oldmnt = fs->altrootmnt;
+       olddentry = fs->altroot;
+       fs->altrootmnt = mnt;
+       fs->altroot = dentry;
+       write_unlock(&fs->lock);
        if (olddentry) {
                dput(olddentry);
                mntput(oldmnt);
@@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name,
        int retval = 0;
        int fput_needed;
        struct file *file;
+       struct fs_struct *fs = current->fs;
 
        nd->last_type = LAST_ROOT; /* if there are only slashes... */
        nd->flags = flags;
        nd->depth = 0;
 
        if (*name=='/') {
-               read_lock(&current->fs->lock);
-               if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-                       nd->mnt = mntget(current->fs->altrootmnt);
-                       nd->dentry = dget(current->fs->altroot);
-                       read_unlock(&current->fs->lock);
+               read_lock(&fs->lock);
+               if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
+                       nd->mnt = mntget(fs->altrootmnt);
+                       nd->dentry = dget(fs->altroot);
+                       read_unlock(&fs->lock);
                        if (__emul_lookup_dentry(name,nd))
                                goto out; /* found in altroot */
-                       read_lock(&current->fs->lock);
+                       read_lock(&fs->lock);
                }
-               nd->mnt = mntget(current->fs->rootmnt);
-               nd->dentry = dget(current->fs->root);
-               read_unlock(&current->fs->lock);
+               nd->mnt = mntget(fs->rootmnt);
+               nd->dentry = dget(fs->root);
+               read_unlock(&fs->lock);
        } else if (dfd == AT_FDCWD) {
-               read_lock(&current->fs->lock);
-               nd->mnt = mntget(current->fs->pwdmnt);
-               nd->dentry = dget(current->fs->pwd);
-               read_unlock(&current->fs->lock);
+               read_lock(&fs->lock);
+               nd->mnt = mntget(fs->pwdmnt);
+               nd->dentry = dget(fs->pwd);
+               read_unlock(&fs->lock);
        } else {
                struct dentry *dentry;
 
index 36d180858136fb46e256fcc6550baf7ea6c2dbed..66d921e14feebaa532bed7e6a041ba08e5057a8c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/quotaops.h>
 #include <linux/acct.h>
 #include <linux/capability.h>
 #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);
 
@@ -1813,6 +1813,7 @@ void __init mnt_init(unsigned long mempages)
        struct list_head *d;
        unsigned int nr_hash;
        int i;
+       int err;
 
        init_rwsem(&namespace_sem);
 
@@ -1853,8 +1854,14 @@ void __init mnt_init(unsigned long mempages)
                d++;
                i--;
        } while (i);
-       sysfs_init();
-       subsystem_register(&fs_subsys);
+       err = sysfs_init();
+       if (err)
+               printk(KERN_WARNING "%s: sysfs_init error: %d\n",
+                       __FUNCTION__, err);
+       err = subsystem_register(&fs_subsys);
+       if (err)
+               printk(KERN_WARNING "%s: subsystem_register error: %d\n",
+                       __FUNCTION__, err);
        init_rootfs();
        init_mount_tree();
 }
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>
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 303f06d2a7b92e8e001489cf2b1db17bdae6bd0c..304c1c7814cbacfec0695e8714c5557ea8ee0e9b 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -546,7 +546,8 @@ asmlinkage long sys_chdir(const char __user * filename)
        struct nameidata nd;
        int error;
 
-       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
+       error = __user_walk(filename,
+                           LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
        if (error)
                goto out;
 
@@ -1172,6 +1173,7 @@ asmlinkage long sys_close(unsigned int fd)
        struct file * filp;
        struct files_struct *files = current->files;
        struct fdtable *fdt;
+       int retval;
 
        spin_lock(&files->file_lock);
        fdt = files_fdtable(files);
@@ -1184,7 +1186,16 @@ asmlinkage long sys_close(unsigned int fd)
        FD_CLR(fd, fdt->close_on_exec);
        __put_unused_fd(files, fd);
        spin_unlock(&files->file_lock);
-       return filp_close(filp, files);
+       retval = filp_close(filp, files);
+
+       /* can't restart close syscall because file table entry was cleared */
+       if (unlikely(retval == -ERESTARTSYS ||
+                    retval == -ERESTARTNOINTR ||
+                    retval == -ERESTARTNOHAND ||
+                    retval == -ERESTART_RESTARTBLOCK))
+               retval = -EINTR;
+
+       return retval;
 
 out_unlock:
        spin_unlock(&files->file_lock);
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 8f12587c3129731fcd92392b41f8c86a9be3c646..4f8df71e49d330038614c4f81a300f477b6f9a95 100644 (file)
@@ -58,6 +58,31 @@ msdos_magic_present(unsigned char *p)
        return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2);
 }
 
+/* Value is EBCDIC 'IBMA' */
+#define AIX_LABEL_MAGIC1       0xC9
+#define AIX_LABEL_MAGIC2       0xC2
+#define AIX_LABEL_MAGIC3       0xD4
+#define AIX_LABEL_MAGIC4       0xC1
+static int aix_magic_present(unsigned char *p, struct block_device *bdev)
+{
+       Sector sect;
+       unsigned char *d;
+       int ret = 0;
+
+       if (p[0] != AIX_LABEL_MAGIC1 &&
+               p[1] != AIX_LABEL_MAGIC2 &&
+               p[2] != AIX_LABEL_MAGIC3 &&
+               p[3] != AIX_LABEL_MAGIC4)
+               return 0;
+       d = read_dev_sector(bdev, 7, &sect);
+       if (d) {
+               if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M')
+                       ret = 1;
+               put_dev_sector(sect);
+       };
+       return ret;
+}
+
 /*
  * Create devices for each logical partition in an extended partition.
  * The logical partitions form a linked list, with each entry being
@@ -393,6 +418,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                return 0;
        }
 
+       if (aix_magic_present(data, bdev)) {
+               put_dev_sector(sect);
+               printk( " [AIX]");
+               return 0;
+       }
+
        /*
         * Now that the 55aa signature is present, this is probably
         * either the boot sector of a FAT filesystem or a DOS-type
index 0b615d62a159b16eb8da4a593b52f4a469f46cc4..c0e554971df01dbac80e057bde18b94e6648faa9 100644 (file)
@@ -347,6 +347,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        sigemptyset(&sigign);
        sigemptyset(&sigcatch);
        cutime = cstime = utime = stime = cputime_zero;
+
+       mutex_lock(&tty_mutex);
        read_lock(&tasklist_lock);
        if (task->sighand) {
                spin_lock_irq(&task->sighand->siglock);
@@ -388,6 +390,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        }
        ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
        read_unlock(&tasklist_lock);
+       mutex_unlock(&tty_mutex);
 
        if (!whole || num_threads<2)
                wchan = get_wchan(task);
index fe8d55fb17cc37da251cfd524dfc14dfb1711c72..89c20d9d50bfbf09c77aca8ca921885bb7eb0084 100644 (file)
@@ -797,7 +797,7 @@ out_no_task:
 static ssize_t mem_write(struct file * file, const char * buf,
                         size_t count, loff_t *ppos)
 {
-       int copied = 0;
+       int copied;
        char *page;
        struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
        unsigned long dst = *ppos;
@@ -814,6 +814,7 @@ static ssize_t mem_write(struct file * file, const char * buf,
        if (!page)
                goto out;
 
+       copied = 0;
        while (count > 0) {
                int this_len, retval;
 
index 3ceff385727273269018a6e4780a97a6bd234cc6..1294eda4acaeefc5739bd4ad267a7fca2dd679dd 100644 (file)
@@ -100,7 +100,7 @@ static int notesize(struct memelfnote *en)
        int sz;
 
        sz = sizeof(struct elf_note);
-       sz += roundup(strlen(en->name), 4);
+       sz += roundup((strlen(en->name) + 1), 4);
        sz += roundup(en->datasz, 4);
 
        return sz;
@@ -116,7 +116,7 @@ static char *storenote(struct memelfnote *men, char *bufp)
 
 #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
 
-       en.n_namesz = strlen(men->name);
+       en.n_namesz = strlen(men->name) + 1;
        en.n_descsz = men->datasz;
        en.n_type = men->type;
 
index 5bbd60896050545759f4aa603e12cfee9cd63295..66bc425f2f3db467344dd81c841442c5806b985e 100644 (file)
@@ -277,12 +277,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 +358,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 +382,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 +700,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 +714,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 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 3a59309f3ca90d9c0a96a834abb7255ecf92de2c..0eb7ac08048471ac4f34a81cd50c1b4ccc32e81d 100644 (file)
@@ -28,7 +28,7 @@ endif
 # will work around it. If any other architecture displays this behavior,
 # add it here.
 ifeq ($(CONFIG_PPC32),y)
-EXTRA_CFLAGS := -O1
+EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0400, -O1)
 endif
 
 TAGS:
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 1627edd50810b94df2f4003479092022c9952d9d..3e08f7161a3ddafa86440d11865eedf09053ab49 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>
@@ -130,7 +131,7 @@ static int reiserfs_sync_file(struct file *p_s_filp,
        reiserfs_write_lock(p_s_inode->i_sb);
        barrier_done = reiserfs_commit_for_inode(p_s_inode);
        reiserfs_write_unlock(p_s_inode->i_sb);
-       if (barrier_done != 1)
+       if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb))
                blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
        if (barrier_done < 0)
                return barrier_done;
@@ -1568,6 +1569,9 @@ const struct file_operations reiserfs_file_operations = {
        .read = generic_file_read,
        .write = reiserfs_file_write,
        .ioctl = reiserfs_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = reiserfs_compat_ioctl,
+#endif
        .mmap = generic_file_mmap,
        .release = reiserfs_file_release,
        .fsync = reiserfs_sync_file,
index 8810fda0da469aa14ebf69ea51aeaedb2686e0f5..7e5a2f5ebeb0fc19e120a5d9f29c00c37b89624f 100644 (file)
@@ -1127,9 +1127,9 @@ static void init_inode(struct inode *inode, struct path *path)
        REISERFS_I(inode)->i_prealloc_count = 0;
        REISERFS_I(inode)->i_trans_id = 0;
        REISERFS_I(inode)->i_jl = NULL;
-       REISERFS_I(inode)->i_acl_access = NULL;
-       REISERFS_I(inode)->i_acl_default = NULL;
-       init_rwsem(&REISERFS_I(inode)->xattr_sem);
+       reiserfs_init_acl_access(inode);
+       reiserfs_init_acl_default(inode);
+       reiserfs_init_xattr_rwsem(inode);
 
        if (stat_data_v1(ih)) {
                struct stat_data_v1 *sd =
@@ -1834,9 +1834,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        REISERFS_I(inode)->i_attrs =
            REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
        sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
-       REISERFS_I(inode)->i_acl_access = NULL;
-       REISERFS_I(inode)->i_acl_default = NULL;
-       init_rwsem(&REISERFS_I(inode)->xattr_sem);
+       reiserfs_init_acl_access(inode);
+       reiserfs_init_acl_default(inode);
+       reiserfs_init_xattr_rwsem(inode);
 
        if (old_format_only(sb))
                make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET,
@@ -1974,11 +1974,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
         * iput doesn't deadlock in reiserfs_delete_xattrs. The locking
         * code really needs to be reworked, but this will take care of it
         * for now. -jeffm */
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
        if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) {
                reiserfs_write_unlock_xattrs(dir->i_sb);
                iput(inode);
                reiserfs_write_lock_xattrs(dir->i_sb);
        } else
+#endif
                iput(inode);
        return err;
 }
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 9b3672d69367251b6109c6550c5e8e7f81986634..e6b5ccf23f152178eb2981423ae3218f1abab6c0 100644 (file)
@@ -1186,6 +1186,21 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct
        return NULL;
 }
 
+static int newer_jl_done(struct reiserfs_journal_cnode *cn)
+{
+       struct super_block *sb = cn->sb;
+       b_blocknr_t blocknr = cn->blocknr;
+
+       cn = cn->hprev;
+       while (cn) {
+               if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist &&
+                   atomic_read(&cn->jlist->j_commit_left) != 0)
+                                   return 0;
+               cn = cn->hprev;
+       }
+       return 1;
+}
+
 static void remove_journal_hash(struct super_block *,
                                struct reiserfs_journal_cnode **,
                                struct reiserfs_journal_list *, unsigned long,
@@ -1604,6 +1619,31 @@ static int flush_journal_list(struct super_block *s,
        return err;
 }
 
+static int test_transaction(struct super_block *s,
+                            struct reiserfs_journal_list *jl)
+{
+       struct reiserfs_journal_cnode *cn;
+
+       if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0)
+               return 1;
+
+       cn = jl->j_realblock;
+       while (cn) {
+               /* if the blocknr == 0, this has been cleared from the hash,
+                ** skip it
+                */
+               if (cn->blocknr == 0) {
+                       goto next;
+               }
+               if (cn->bh && !newer_jl_done(cn))
+                       return 0;
+             next:
+               cn = cn->next;
+               cond_resched();
+       }
+       return 0;
+}
+
 static int write_one_transaction(struct super_block *s,
                                 struct reiserfs_journal_list *jl,
                                 struct buffer_chunk *chunk)
@@ -3433,16 +3473,6 @@ static void flush_async_commits(void *p)
                flush_commit_list(p_s_sb, jl, 1);
        }
        unlock_kernel();
-       /*
-        * this is a little racey, but there's no harm in missing
-        * the filemap_fdata_write
-        */
-       if (!atomic_read(&journal->j_async_throttle)
-           && !reiserfs_is_journal_aborted(journal)) {
-               atomic_inc(&journal->j_async_throttle);
-               filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
-               atomic_dec(&journal->j_async_throttle);
-       }
 }
 
 /*
@@ -3844,7 +3874,9 @@ static void flush_old_journal_lists(struct super_block *s)
                entry = journal->j_journal_list.next;
                jl = JOURNAL_LIST_ENTRY(entry);
                /* this check should always be run, to send old lists to disk */
-               if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
+               if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) &&
+                   atomic_read(&jl->j_commit_left) == 0 &&
+                   test_transaction(s, jl)) {
                        flush_used_journal_lists(s, jl);
                } else {
                        break;
index b40d4d64d598b83ce47b578ed487a7f282178605..80fc3b32802f827d6fe1bf8e9e919321d3f9e6d0 100644 (file)
@@ -510,8 +510,10 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
            SLAB_CTOR_CONSTRUCTOR) {
                INIT_LIST_HEAD(&ei->i_prealloc_list);
                inode_init_once(&ei->vfs_inode);
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
                ei->i_acl_access = NULL;
                ei->i_acl_default = NULL;
+#endif
        }
 }
 
@@ -560,6 +562,7 @@ static void reiserfs_dirty_inode(struct inode *inode)
        reiserfs_write_unlock(inode->i_sb);
 }
 
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
 static void reiserfs_clear_inode(struct inode *inode)
 {
        struct posix_acl *acl;
@@ -574,6 +577,9 @@ static void reiserfs_clear_inode(struct inode *inode)
                posix_acl_release(acl);
        REISERFS_I(inode)->i_acl_default = NULL;
 }
+#else
+#define reiserfs_clear_inode NULL
+#endif
 
 #ifdef CONFIG_QUOTA
 static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
index 33b72ba0f86f45790bd7661053266cd8336c9757..dcbc1112b7ec214c063eaf5786bb17d5f208e6b0 100644 (file)
@@ -658,8 +658,6 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
        unsigned int i;
        struct poll_list *head;
        struct poll_list *walk;
-       struct fdtable *fdt;
-       int max_fdset;
        /* Allocate small arguments on the stack to save memory and be
           faster - use long to make sure the buffer is aligned properly
           on 64 bit archs to avoid unaligned access */
@@ -667,11 +665,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
        struct poll_list *stack_pp = NULL;
 
        /* Do a sanity check on nfds ... */
-       rcu_read_lock();
-       fdt = files_fdtable(current->files);
-       max_fdset = fdt->max_fdset;
-       rcu_read_unlock();
-       if (nfds > max_fdset && nfds > OPEN_MAX)
+       if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
                return -EINVAL;
 
        poll_initwait(&table);
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 5c4c94d5495e42588c9aef5a9fe4271d54f1da24..aec99ddbe53f726a526d4cd0b02abb9f55179e0b 100644 (file)
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(deactivate_super);
  *     success, 0 if we had failed (superblock contents was already dead or
  *     dying when grab_super() had been called).
  */
-static int grab_super(struct super_block *s)
+static int grab_super(struct super_block *s) __releases(sb_lock)
 {
        s->s_count++;
        spin_unlock(&sb_lock);
@@ -220,6 +220,37 @@ static int grab_super(struct super_block *s)
        return 0;
 }
 
+/*
+ * Write out and wait upon all dirty data associated with this
+ * superblock.  Filesystem data as well as the underlying block
+ * device.  Takes the superblock lock.  Requires a second blkdev
+ * flush by the caller to complete the operation.
+ */
+void __fsync_super(struct super_block *sb)
+{
+       sync_inodes_sb(sb, 0);
+       DQUOT_SYNC(sb);
+       lock_super(sb);
+       if (sb->s_dirt && sb->s_op->write_super)
+               sb->s_op->write_super(sb);
+       unlock_super(sb);
+       if (sb->s_op->sync_fs)
+               sb->s_op->sync_fs(sb, 1);
+       sync_blockdev(sb->s_bdev);
+       sync_inodes_sb(sb, 1);
+}
+
+/*
+ * Write out and wait upon all dirty data associated with this
+ * superblock.  Filesystem data as well as the underlying block
+ * device.  Takes the superblock lock.
+ */
+int fsync_super(struct super_block *sb)
+{
+       __fsync_super(sb);
+       return sync_blockdev(sb->s_bdev);
+}
+
 /**
  *     generic_shutdown_super  -       common helper for ->kill_sb()
  *     @sb: superblock to kill
@@ -540,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
 {
        int retval;
        
+#ifdef CONFIG_BLOCK
        if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev))
                return -EACCES;
+#endif
        if (flags & MS_RDONLY)
                acct_auto_close(sb);
        shrink_dcache_sb(sb);
@@ -661,6 +694,7 @@ void kill_litter_super(struct super_block *sb)
 
 EXPORT_SYMBOL(kill_litter_super);
 
+#ifdef CONFIG_BLOCK
 static int set_bdev_super(struct super_block *s, void *data)
 {
        s->s_bdev = data;
@@ -756,6 +790,7 @@ void kill_block_super(struct super_block *sb)
 }
 
 EXPORT_SYMBOL(kill_block_super);
+#endif
 
 int get_sb_nodev(struct file_system_type *fs_type,
        int flags, void *data,
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 5dd356cbbda607de674b825d40ecf0c72fce490b..1d3b5d2070e5474cbf2b212b457166487e32fbde 100644 (file)
@@ -1621,6 +1621,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
+       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY)
+               printk("UDF-fs: Partition marked readonly; forcing readonly mount\n");
+               sb->s_flags |= MS_RDONLY;
+
        if ( udf_find_fileset(sb, &fileset, &rootdir) )
        {
                printk("UDF-fs: No fileset found\n");
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 9e7f85986d0de3d766a6cc5ee783bb7cd5a9bdb9..291948d5085a08ebac04c8f725c152d80a392805 100644 (file)
@@ -30,7 +30,6 @@ ifeq ($(CONFIG_XFS_TRACE),y)
        EXTRA_CFLAGS += -DXFS_BLI_TRACE
        EXTRA_CFLAGS += -DXFS_BMAP_TRACE
        EXTRA_CFLAGS += -DXFS_BMBT_TRACE
-       EXTRA_CFLAGS += -DXFS_DIR_TRACE
        EXTRA_CFLAGS += -DXFS_DIR2_TRACE
        EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
        EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
index aba7fcf881a217d209d7c0c89fb9a573156e21ba..d59737589815c8048c00d432867606a719d0fa31 100644 (file)
@@ -34,6 +34,14 @@ kmem_alloc(size_t size, unsigned int __nocast flags)
        gfp_t   lflags = kmem_flags_convert(flags);
        void    *ptr;
 
+#ifdef DEBUG
+       if (unlikely(!(flags & KM_LARGE) && (size > PAGE_SIZE))) {
+               printk(KERN_WARNING "Large %s attempt, size=%ld\n",
+                       __FUNCTION__, (long)size);
+               dump_stack();
+       }
+#endif
+
        do {
                if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
                        ptr = kmalloc(size, lflags);
@@ -60,6 +68,27 @@ kmem_zalloc(size_t size, unsigned int __nocast flags)
        return ptr;
 }
 
+void *
+kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize,
+                  unsigned int __nocast flags)
+{
+       void            *ptr;
+       size_t          kmsize = maxsize;
+       unsigned int    kmflags = (flags & ~KM_SLEEP) | KM_NOSLEEP;
+
+       while (!(ptr = kmem_zalloc(kmsize, kmflags))) {
+               if ((kmsize <= minsize) && (flags & KM_NOSLEEP))
+                       break;
+               if ((kmsize >>= 1) <= minsize) {
+                       kmsize = minsize;
+                       kmflags = flags;
+               }
+       }
+       if (ptr)
+               *size = kmsize;
+       return ptr;
+}
+
 void
 kmem_free(void *ptr, size_t size)
 {
index 0e8293c5a32fb9ac8c00d9481627f7d20580dfae..9ebabdf7829c3a5c5dc2fe08caefde56fb8dfe2c 100644 (file)
@@ -30,6 +30,7 @@
 #define KM_NOSLEEP     0x0002u
 #define KM_NOFS                0x0004u
 #define KM_MAYFAIL     0x0008u
+#define KM_LARGE       0x0010u
 
 /*
  * We use a special process flag to avoid recursive callbacks into
@@ -41,7 +42,7 @@ kmem_flags_convert(unsigned int __nocast flags)
 {
        gfp_t   lflags;
 
-       BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL));
+       BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL|KM_LARGE));
 
        if (flags & KM_NOSLEEP) {
                lflags = GFP_ATOMIC | __GFP_NOWARN;
@@ -54,8 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags)
 }
 
 extern void *kmem_alloc(size_t, unsigned int __nocast);
-extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
 extern void *kmem_zalloc(size_t, unsigned int __nocast);
+extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast);
+extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
 extern void  kmem_free(void *, size_t);
 
 /*
index b25090094cca73d97a350b141f12114327fc3405..2009e6d922ce5161304813b82a7ea7ca47c2351a 100644 (file)
@@ -29,8 +29,6 @@
 
 typedef struct semaphore sema_t;
 
-#define init_sema(sp, val, c, d)       sema_init(sp, val)
-#define initsema(sp, val)              sema_init(sp, val)
 #define initnsema(sp, val, name)       sema_init(sp, val)
 #define psema(sp, b)                   down(sp)
 #define vsema(sp)                      up(sp)
index 9a8ad481b0086e72b69d9643d3df70e936880ecb..351a8f454bd1adfdcffb91e8299324da77a8878c 100644 (file)
@@ -53,8 +53,6 @@ static inline void _sv_wait(sv_t *sv, spinlock_t *lock, int state,
        remove_wait_queue(&sv->waiters, &wait);
 }
 
-#define init_sv(sv,type,name,flag) \
-       init_waitqueue_head(&(sv)->waiters)
 #define sv_init(sv,flag,name) \
        init_waitqueue_head(&(sv)->waiters)
 #define sv_destroy(sv) \
index 34dcb43a7837d8d9b602ba23199c8f6bbe429400..09360cf1e1f277cb5b35233aa4ef0d81edcaa38d 100644 (file)
@@ -71,7 +71,7 @@ xfs_page_trace(
        int             tag,
        struct inode    *inode,
        struct page     *page,
-       int             mask)
+       unsigned long   pgoff)
 {
        xfs_inode_t     *ip;
        bhv_vnode_t     *vp = vn_from_inode(inode);
@@ -91,7 +91,7 @@ xfs_page_trace(
                (void *)ip,
                (void *)inode,
                (void *)page,
-               (void *)((unsigned long)mask),
+               (void *)pgoff,
                (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
                (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
                (void *)((unsigned long)((isize >> 32) & 0xffffffff)),
@@ -105,7 +105,7 @@ xfs_page_trace(
                (void *)NULL);
 }
 #else
-#define xfs_page_trace(tag, inode, page, mask)
+#define xfs_page_trace(tag, inode, page, pgoff)
 #endif
 
 /*
@@ -1197,7 +1197,7 @@ xfs_vm_releasepage(
                .nr_to_write = 1,
        };
 
-       xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask);
+       xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0);
 
        if (!page_has_buffers(page))
                return 0;
@@ -1356,7 +1356,6 @@ xfs_end_io_direct(
                ioend->io_size = size;
                xfs_finish_ioend(ioend);
        } else {
-               ASSERT(size >= 0);
                xfs_destroy_ioend(ioend);
        }
 
index 2af528dcfb0428ca93f2a5dced879e400682b876..9bbadafdcb00285a8644a350a0ef033c7889f139 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -318,8 +318,12 @@ xfs_buf_free(
                if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
                        free_address(bp->b_addr - bp->b_offset);
 
-               for (i = 0; i < bp->b_page_count; i++)
-                       page_cache_release(bp->b_pages[i]);
+               for (i = 0; i < bp->b_page_count; i++) {
+                       struct page     *page = bp->b_pages[i];
+
+                       ASSERT(!PagePrivate(page));
+                       page_cache_release(page);
+               }
                _xfs_buf_free_pages(bp);
        } else if (bp->b_flags & _XBF_KMEM_ALLOC) {
                 /*
@@ -400,6 +404,7 @@ _xfs_buf_lookup_pages(
                nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset);
                size -= nbytes;
 
+               ASSERT(!PagePrivate(page));
                if (!PageUptodate(page)) {
                        page_count--;
                        if (blocksize >= PAGE_CACHE_SIZE) {
@@ -768,7 +773,7 @@ xfs_buf_get_noaddr(
        _xfs_buf_initialize(bp, target, 0, len, 0);
 
  try_again:
-       data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);
+       data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
        if (unlikely(data == NULL))
                goto fail_free_buf;
 
@@ -1117,10 +1122,10 @@ xfs_buf_bio_end_io(
        do {
                struct page     *page = bvec->bv_page;
 
+               ASSERT(!PagePrivate(page));
                if (unlikely(bp->b_error)) {
                        if (bp->b_flags & XBF_READ)
                                ClearPageUptodate(page);
-                       SetPageError(page);
                } else if (blocksize >= PAGE_CACHE_SIZE) {
                        SetPageUptodate(page);
                } else if (!PagePrivate(page) &&
@@ -1156,16 +1161,16 @@ _xfs_buf_ioapply(
        total_nr_pages = bp->b_page_count;
        map_i = 0;
 
-       if (bp->b_flags & _XBF_RUN_QUEUES) {
-               bp->b_flags &= ~_XBF_RUN_QUEUES;
-               rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC;
-       } else {
-               rw = (bp->b_flags & XBF_READ) ? READ : WRITE;
-       }
-
        if (bp->b_flags & XBF_ORDERED) {
                ASSERT(!(bp->b_flags & XBF_READ));
                rw = WRITE_BARRIER;
+       } else if (bp->b_flags & _XBF_RUN_QUEUES) {
+               ASSERT(!(bp->b_flags & XBF_READ_AHEAD));
+               bp->b_flags &= ~_XBF_RUN_QUEUES;
+               rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC;
+       } else {
+               rw = (bp->b_flags & XBF_WRITE) ? WRITE :
+                    (bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
        }
 
        /* Special code path for reading a sub page size buffer in --
@@ -1681,6 +1686,7 @@ xfsbufd(
        xfs_buf_t               *bp, *n;
        struct list_head        *dwq = &target->bt_delwrite_queue;
        spinlock_t              *dwlk = &target->bt_delwrite_lock;
+       int                     count;
 
        current->flags |= PF_MEMALLOC;
 
@@ -1696,6 +1702,7 @@ xfsbufd(
                schedule_timeout_interruptible(
                        xfs_buf_timer_centisecs * msecs_to_jiffies(10));
 
+               count = 0;
                age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
                spin_lock(dwlk);
                list_for_each_entry_safe(bp, n, dwq, b_list) {
@@ -1711,9 +1718,11 @@ xfsbufd(
                                        break;
                                }
 
-                               bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+                               bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|
+                                                _XBF_RUN_QUEUES);
                                bp->b_flags |= XBF_WRITE;
-                               list_move(&bp->b_list, &tmp);
+                               list_move_tail(&bp->b_list, &tmp);
+                               count++;
                        }
                }
                spin_unlock(dwlk);
@@ -1724,12 +1733,12 @@ xfsbufd(
 
                        list_del_init(&bp->b_list);
                        xfs_buf_iostrategy(bp);
-
-                       blk_run_address_space(target->bt_mapping);
                }
 
                if (as_list_len > 0)
                        purge_addresses();
+               if (count)
+                       blk_run_address_space(target->bt_mapping);
 
                clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
        } while (!kthread_should_stop());
@@ -1767,7 +1776,7 @@ xfs_flush_buftarg(
                        continue;
                }
 
-               list_move(&bp->b_list, &tmp);
+               list_move_tail(&bp->b_list, &tmp);
        }
        spin_unlock(dwlk);
 
@@ -1776,7 +1785,7 @@ xfs_flush_buftarg(
         */
        list_for_each_entry_safe(bp, n, &tmp, b_list) {
                xfs_buf_lock(bp);
-               bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+               bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES);
                bp->b_flags |= XBF_WRITE;
                if (wait)
                        bp->b_flags &= ~XBF_ASYNC;
@@ -1786,6 +1795,9 @@ xfs_flush_buftarg(
                xfs_buf_iostrategy(bp);
        }
 
+       if (wait)
+               blk_run_address_space(target->bt_mapping);
+
        /*
         * Remaining list items must be flushed before returning
         */
@@ -1797,9 +1809,6 @@ xfs_flush_buftarg(
                xfs_buf_relse(bp);
        }
 
-       if (wait)
-               blk_run_address_space(target->bt_mapping);
-
        return pincount;
 }
 
index 7858703ed84cf42130de0bf5444eac74111c4c82..9dd235cb01070623795c7e880c58636465ae17b6 100644 (file)
@@ -298,11 +298,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
 #define XFS_BUF_UNWRITE(bp)    ((bp)->b_flags &= ~XBF_WRITE)
 #define XFS_BUF_ISWRITE(bp)    ((bp)->b_flags & XBF_WRITE)
 
-#define XFS_BUF_ISUNINITIAL(bp)        (0)
-#define XFS_BUF_UNUNINITIAL(bp)        (0)
-
-#define XFS_BUF_BP_ISMAPPED(bp)        (1)
-
 #define XFS_BUF_IODONE_FUNC(bp)                        ((bp)->b_iodone)
 #define XFS_BUF_SET_IODONE_FUNC(bp, func)      ((bp)->b_iodone = (func))
 #define XFS_BUF_CLR_IODONE_FUNC(bp)            ((bp)->b_iodone = NULL)
@@ -393,8 +388,6 @@ static inline int XFS_bwrite(xfs_buf_t *bp)
        return error;
 }
 
-#define XFS_bdwrite(bp)                xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC)
-
 static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
 {
        bp->b_strat = xfs_bdstrat_cb;
index 6c162c3dde7efb44ee4f1abbb430591974244b82..ed3a5e1b4b6777490a7d8c6738a1959a15796543 100644 (file)
@@ -34,7 +34,7 @@ xfs_param_t xfs_params = {
        .restrict_chown = {     0,              1,              1       },
        .sgid_inherit   = {     0,              0,              1       },
        .symlink_mode   = {     0,              0,              1       },
-       .panic_mask     = {     0,              0,              127     },
+       .panic_mask     = {     0,              0,              255     },
        .error_level    = {     0,              3,              11      },
        .syncd_timer    = {     1*100,          30*100,         7200*100},
        .stats_clear    = {     0,              0,              1       },
index 6e52a5dd38d86333cd50ede6dfbe4a9c74e9c2f1..a74f854d91e6afe1d86ba2da278a733a5afa48e5 100644 (file)
@@ -653,7 +653,7 @@ xfs_attrmulti_by_handle(
 STATIC int
 xfs_ioc_space(
        bhv_desc_t              *bdp,
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        struct file             *filp,
        int                     flags,
        unsigned int            cmd,
@@ -735,7 +735,7 @@ xfs_ioctl(
                    !capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
-               return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg);
+               return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg);
 
        case XFS_IOC_DIOINFO: {
                struct dioattr  da;
@@ -763,6 +763,8 @@ xfs_ioctl(
                return xfs_ioc_fsgeometry(mp, arg);
 
        case XFS_IOC_GETVERSION:
+               return put_user(inode->i_generation, (int __user *)arg);
+
        case XFS_IOC_GETXFLAGS:
        case XFS_IOC_SETXFLAGS:
        case XFS_IOC_FSGETXATTR:
@@ -957,7 +959,7 @@ xfs_ioctl(
 STATIC int
 xfs_ioc_space(
        bhv_desc_t              *bdp,
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        struct file             *filp,
        int                     ioflags,
        unsigned int            cmd,
@@ -967,13 +969,13 @@ xfs_ioc_space(
        int                     attr_flags = 0;
        int                     error;
 
-       if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+       if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
                return -XFS_ERROR(EPERM);
 
        if (!(filp->f_mode & FMODE_WRITE))
                return -XFS_ERROR(EBADF);
 
-       if (!VN_ISREG(vp))
+       if (!S_ISREG(inode->i_mode))
                return -XFS_ERROR(EINVAL);
 
        if (copy_from_user(&bf, arg, sizeof(bf)))
@@ -1264,13 +1266,6 @@ xfs_ioc_xattr(
                break;
        }
 
-       case XFS_IOC_GETVERSION: {
-               flags = vn_to_inode(vp)->i_generation;
-               if (copy_to_user(arg, &flags, sizeof(flags)))
-                       error = -EFAULT;
-               break;
-       }
-
        default:
                error = -ENOTTY;
                break;
index 22e3b714f62973a62817f1ee7262c72c387a152a..3ba814ae3bba536c2eaeb99e2e530ffc4239e7b1 100644 (file)
@@ -623,12 +623,27 @@ xfs_vn_getattr(
 {
        struct inode    *inode = dentry->d_inode;
        bhv_vnode_t     *vp = vn_from_inode(inode);
-       int             error = 0;
+       bhv_vattr_t     vattr = { .va_mask = XFS_AT_STAT };
+       int             error;
 
-       if (unlikely(vp->v_flag & VMODIFIED))
-               error = vn_revalidate(vp);
-       if (!error)
-               generic_fillattr(inode, stat);
+       error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL);
+       if (likely(!error)) {
+               stat->size = i_size_read(inode);
+               stat->dev = inode->i_sb->s_dev;
+               stat->rdev = (vattr.va_rdev == 0) ? 0 :
+                               MKDEV(sysv_major(vattr.va_rdev) & 0x1ff,
+                                     sysv_minor(vattr.va_rdev));
+               stat->mode = vattr.va_mode;
+               stat->nlink = vattr.va_nlink;
+               stat->uid = vattr.va_uid;
+               stat->gid = vattr.va_gid;
+               stat->ino = vattr.va_nodeid;
+               stat->atime = vattr.va_atime;
+               stat->mtime = vattr.va_mtime;
+               stat->ctime = vattr.va_ctime;
+               stat->blocks = vattr.va_nblocks;
+               stat->blksize = vattr.va_blocksize;
+       }
        return -error;
 }
 
index a13f75c1a936a7f2c0b3ab1d74fc75fc2a146b51..2b0e0018738a09ab31a19b89152b63ac8e804053 100644 (file)
@@ -148,11 +148,7 @@ BUFFER_FNS(PrivateStart, unwritten);
                (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
 
 #define NBPP           PAGE_SIZE
-#define DPPSHFT                (PAGE_SHIFT - 9)
 #define NDPP           (1 << (PAGE_SHIFT - 9))
-#define dtop(DD)       (((DD) + NDPP - 1) >> DPPSHFT)
-#define dtopt(DD)      ((DD) >> DPPSHFT)
-#define dpoff(DD)      ((DD) & (NDPP-1))
 
 #define NBBY           8               /* number of bits per byte */
 #define        NBPC            PAGE_SIZE       /* Number of bytes per click */
@@ -172,8 +168,6 @@ BUFFER_FNS(PrivateStart, unwritten);
 #define        btoct(x)        ((__psunsigned_t)(x)>>BPCSHIFT)
 #define        btoc64(x)       (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
 #define        btoct64(x)      ((__uint64_t)(x)>>BPCSHIFT)
-#define        io_btoc(x)      (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT)
-#define        io_btoct(x)     ((__psunsigned_t)(x)>>IO_BPCSHIFT)
 
 /* off_t bytes to clicks */
 #define offtoc(x)       (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
@@ -186,7 +180,6 @@ BUFFER_FNS(PrivateStart, unwritten);
 #define        ctob(x)         ((__psunsigned_t)(x)<<BPCSHIFT)
 #define btoct(x)        ((__psunsigned_t)(x)>>BPCSHIFT)
 #define        ctob64(x)       ((__uint64_t)(x)<<BPCSHIFT)
-#define        io_ctob(x)      ((__psunsigned_t)(x)<<IO_BPCSHIFT)
 
 /* bytes to clicks */
 #define btoc(x)         (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
@@ -339,4 +332,11 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
        return(x * y);
 }
 
+static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
+{
+       x += y - 1;
+       do_div(x, y);
+       return x;
+}
+
 #endif /* __XFS_LINUX__ */
index ee788b1cb3641a355219183f9217037d04df2a94..55992b40353cad97de4dd7b20dd9a009bd3d5b63 100644 (file)
@@ -270,12 +270,12 @@ xfs_read(
                }
        }
 
-       if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
-               bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
-                                               -1, FI_REMAPF_LOCKED);
-
-       if (unlikely(ioflags & IO_ISDIRECT))
+       if (unlikely(ioflags & IO_ISDIRECT)) {
+               if (VN_CACHED(vp))
+                       bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
+                                                -1, FI_REMAPF_LOCKED);
                mutex_unlock(&inode->i_mutex);
+       }
 
        xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
                                (void *)iovp, segs, *offset, ioflags);
index 9df9ed37d219fb7269932d72208d4961101c17d6..38c4d128a8c0c8675f05f6672fefd3f058dd85c2 100644 (file)
@@ -227,7 +227,9 @@ xfs_initialize_vnode(
                xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
                xfs_set_inodeops(inode);
 
+               spin_lock(&ip->i_flags_lock);
                ip->i_flags &= ~XFS_INEW;
+               spin_unlock(&ip->i_flags_lock);
                barrier();
 
                unlock_new_inode(inode);
index 91fc2c4b3353f1f4ea96ed51de25ade3f4304f76..da255bdf526036995fcb50340c96f89aff8f81e6 100644 (file)
@@ -79,7 +79,7 @@ typedef enum {
 #define VFS_RDONLY             0x0001  /* read-only vfs */
 #define VFS_GRPID              0x0002  /* group-ID assigned from directory */
 #define VFS_DMI                        0x0004  /* filesystem has the DMI enabled */
-#define VFS_UMOUNT             0x0008  /* unmount in progress */
+/* ---- VFS_UMOUNT ----                0x0008  -- unneeded, fixed via kthread APIs */
 #define VFS_32BITINODES                0x0010  /* do not use inums above 32 bits */
 #define VFS_END                        0x0010  /* max flag */
 
index c42b3221b20cb95a0a1303b2d6c51a4aff071148..515f5fdea57a0af1317bf4d03827685dfbd2fb00 100644 (file)
@@ -85,8 +85,6 @@ typedef enum {
 #define VN_BHV_HEAD(vp)                        ((bhv_head_t *)(&((vp)->v_bh)))
 #define vn_bhv_head_init(bhp,name)     bhv_head_init(bhp,name)
 #define vn_bhv_remove(bhp,bdp)         bhv_remove(bhp,bdp)
-#define vn_bhv_lookup(bhp,ops)         bhv_lookup(bhp,ops)
-#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
 
 /*
  * Vnode to Linux inode mapping.
index 5b2dcc58b24430105bcca1860d7a589e811a3228..33ad5af386e03ed21cfee5b747341af6e5fd8d3e 100644 (file)
@@ -381,18 +381,6 @@ xfs_qm_dquot_logitem_unlock(
 }
 
 
-/*
- * The transaction with the dquot locked has aborted.  The dquot
- * must not be dirty within the transaction.  We simply unlock just
- * as if the transaction had been cancelled.
- */
-STATIC void
-xfs_qm_dquot_logitem_abort(
-       xfs_dq_logitem_t    *ql)
-{
-       xfs_qm_dquot_logitem_unlock(ql);
-}
-
 /*
  * this needs to stamp an lsn into the dquot, I think.
  * rpc's that look at user dquot's would then have to
@@ -426,7 +414,6 @@ STATIC struct xfs_item_ops xfs_dquot_item_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_qm_dquot_logitem_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_abort,
        .iop_pushbuf    = (void(*)(xfs_log_item_t*))
                                        xfs_qm_dquot_logitem_pushbuf,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
@@ -558,17 +545,6 @@ xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
        return (lsn);
 }
 
-/*
- * The transaction of which this QUOTAOFF is a part has been aborted.
- * Just clean up after ourselves.
- * Shouldn't this never happen in the case of qoffend logitems? XXX
- */
-STATIC void
-xfs_qm_qoff_logitem_abort(xfs_qoff_logitem_t *qf)
-{
-       kmem_free(qf, sizeof(xfs_qoff_logitem_t));
-}
-
 /*
  * There isn't much you can do to push on an quotaoff item.  It is simply
  * stuck waiting for the log to be flushed to disk.
@@ -644,7 +620,6 @@ STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_qm_qoffend_logitem_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
        .iop_pushbuf    = NULL,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_qm_qoffend_logitem_committing
@@ -667,7 +642,6 @@ STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_qm_qoff_logitem_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
        .iop_pushbuf    = NULL,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_qm_qoff_logitem_committing
index e23e45535c48219855daa75be9aa60d2f977c790..7c6a3a50379e2a543fac68acf60774909fc9097c 100644 (file)
@@ -112,17 +112,17 @@ xfs_Gqm_init(void)
 {
        xfs_dqhash_t    *udqhash, *gdqhash;
        xfs_qm_t        *xqm;
-       uint            i, hsize, flags = KM_SLEEP | KM_MAYFAIL;
+       size_t          hsize;
+       uint            i;
 
        /*
         * Initialize the dquot hash tables.
         */
-       hsize = XFS_QM_HASHSIZE_HIGH;
-       while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) {
-               if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW)
-                       flags = KM_SLEEP;
-       }
-       gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP);
+       udqhash = kmem_zalloc_greedy(&hsize,
+                                    XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH,
+                                    KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+       gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE);
+       hsize /= sizeof(xfs_dqhash_t);
        ndquot = hsize << 8;
 
        xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
index 4568deb6da867dcae2c446d034b8dbe5dba95fb3..689407de0a20684ad71513fca7873712ac50648d 100644 (file)
@@ -55,12 +55,6 @@ extern kmem_zone_t   *qm_dqtrxzone;
 #define XFS_QM_HASHSIZE_LOW            (NBPP / sizeof(xfs_dqhash_t))
 #define XFS_QM_HASHSIZE_HIGH           ((NBPP * 4) / sizeof(xfs_dqhash_t))
 
-/*
- * We output a cmn_err when quotachecking a quota file with more than
- * this many fsbs.
- */
-#define XFS_QM_BIG_QCHECK_NBLKS                500
-
 /*
  * This defines the unit of allocation of dquots.
  * Currently, it is just one file system block, and a 4K blk contains 30
index b7ddd04aae327b1cd6f7c4df66844879de765fca..a8b85e2be9d5cf34d10ecaa332d4b9257a82efd1 100644 (file)
@@ -75,7 +75,6 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
 
 #define xfs_qm_freelist_lock(qm)       XQMLCK(&((qm)->qm_dqfreelist))
 #define xfs_qm_freelist_unlock(qm)     XQMUNLCK(&((qm)->qm_dqfreelist))
-#define XFS_QM_IS_FREELIST_LOCKED(qm)  XQMISLCKD(&((qm)->qm_dqfreelist))
 
 /*
  * Hash into a bucket in the dquot hash table, based on <mp, id>.
@@ -170,6 +169,5 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
 #define DQFLAGTO_TYPESTR(d)    (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
                                 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
                                 (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
-#define DQFLAGTO_DIRTYSTR(d)   (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
 
 #endif /* __XFS_QUOTA_PRIV_H__ */
index addf5a7ea06c40f879d40d1e8117c15cf01e21c5..5cf2e86caa7198653b37f086bf02335d2599fad6 100644 (file)
@@ -75,7 +75,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep)
                                                            sleep);
        } else {
                ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
-                                                           sleep);
+                                                           sleep | KM_LARGE);
        }
 
        if (ktep == NULL) {
index dc2361dd740aedbc3ee1695e30ef50094a6b8f6d..9ece7f87ec5b29b62d28e2cb756a88028240c7b1 100644 (file)
@@ -150,7 +150,7 @@ typedef struct xfs_agi {
 #define        XFS_BUF_TO_AGFL(bp)     ((xfs_agfl_t *)XFS_BUF_PTR(bp))
 
 typedef struct xfs_agfl {
-       xfs_agblock_t   agfl_bno[1];    /* actually XFS_AGFL_SIZE(mp) */
+       __be32          agfl_bno[1];    /* actually XFS_AGFL_SIZE(mp) */
 } xfs_agfl_t;
 
 /*
index d2bbcd882a69578174110f3655e4aadf190a52f4..e80dda3437d196345b0d19cded4cac518b4e0eda 100644 (file)
@@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small(
        /*
         * Can't allocate from the freelist for some reason.
         */
-       else
+       else {
+               fbno = NULLAGBLOCK;
                flen = 0;
+       }
        /*
         * Can't do the allocation, give up.
         */
@@ -2021,7 +2023,7 @@ xfs_alloc_get_freelist(
        /*
         * Get the block number and update the data structures.
         */
-       bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT);
+       bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
        be32_add(&agf->agf_flfirst, 1);
        xfs_trans_brelse(tp, agflbp);
        if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
@@ -2108,7 +2110,7 @@ xfs_alloc_put_freelist(
 {
        xfs_agf_t               *agf;   /* a.g. freespace structure */
        xfs_agfl_t              *agfl;  /* a.g. free block array */
-       xfs_agblock_t           *blockp;/* pointer to array entry */
+       __be32                  *blockp;/* pointer to array entry */
        int                     error;
 #ifdef XFS_ALLOC_TRACE
        static char             fname[] = "xfs_alloc_put_freelist";
@@ -2132,7 +2134,7 @@ xfs_alloc_put_freelist(
        pag->pagf_flcount++;
        ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
        blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
-       INT_SET(*blockp, ARCH_CONVERT, bno);
+       *blockp = cpu_to_be32(bno);
        TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
        xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
        xfs_trans_log_buf(tp, agflbp,
index 7446556e8021092cecbba838bf9fa9214cf2ed01..74cadf95d4e84de19879cbcfea33e6d41433f9fb 100644 (file)
@@ -92,6 +92,7 @@ xfs_alloc_delrec(
        xfs_alloc_key_t         *rkp;   /* right block key pointer */
        xfs_alloc_ptr_t         *rpp;   /* right block address pointer */
        int                     rrecs=0;        /* number of records in right block */
+       int                     numrecs;
        xfs_alloc_rec_t         *rrp;   /* right block record pointer */
        xfs_btree_cur_t         *tcur;  /* temporary btree cursor */
 
@@ -115,7 +116,8 @@ xfs_alloc_delrec(
        /*
         * Fail if we're off the end of the block.
         */
-       if (ptr > be16_to_cpu(block->bb_numrecs)) {
+       numrecs = be16_to_cpu(block->bb_numrecs);
+       if (ptr > numrecs) {
                *stat = 0;
                return 0;
        }
@@ -129,18 +131,18 @@ xfs_alloc_delrec(
                lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
                lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
 #ifdef DEBUG
-               for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) {
+               for (i = ptr; i < numrecs; i++) {
                        if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
                                return error;
                }
 #endif
-               if (ptr < be16_to_cpu(block->bb_numrecs)) {
+               if (ptr < numrecs) {
                        memmove(&lkp[ptr - 1], &lkp[ptr],
-                               (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp));
+                               (numrecs - ptr) * sizeof(*lkp));
                        memmove(&lpp[ptr - 1], &lpp[ptr],
-                               (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp));
-                       xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
-                       xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
+                               (numrecs - ptr) * sizeof(*lpp));
+                       xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1);
+                       xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1);
                }
        }
        /*
@@ -149,10 +151,10 @@ xfs_alloc_delrec(
         */
        else {
                lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
-               if (ptr < be16_to_cpu(block->bb_numrecs)) {
+               if (ptr < numrecs) {
                        memmove(&lrp[ptr - 1], &lrp[ptr],
-                               (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp));
-                       xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
+                               (numrecs - ptr) * sizeof(*lrp));
+                       xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1);
                }
                /*
                 * If it's the first record in the block, we'll need a key
@@ -167,7 +169,8 @@ xfs_alloc_delrec(
        /*
         * Decrement and log the number of entries in the block.
         */
-       be16_add(&block->bb_numrecs, -1);
+       numrecs--;
+       block->bb_numrecs = cpu_to_be16(numrecs);
        xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
        /*
         * See if the longest free extent in the allocation group was
@@ -181,14 +184,14 @@ xfs_alloc_delrec(
        if (level == 0 &&
            cur->bc_btnum == XFS_BTNUM_CNT &&
            be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
-           ptr > be16_to_cpu(block->bb_numrecs)) {
-               ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1);
+           ptr > numrecs) {
+               ASSERT(ptr == numrecs + 1);
                /*
                 * There are still records in the block.  Grab the size
                 * from the last one.
                 */
-               if (be16_to_cpu(block->bb_numrecs)) {
-                       rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur);
+               if (numrecs) {
+                       rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur);
                        agf->agf_longest = rrp->ar_blockcount;
                }
                /*
@@ -211,7 +214,7 @@ xfs_alloc_delrec(
                 * and it's NOT the leaf level,
                 * then we can get rid of this level.
                 */
-               if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) {
+               if (numrecs == 1 && level > 0) {
                        /*
                         * lpp is still set to the first pointer in the block.
                         * Make it the new root of the btree.
@@ -267,7 +270,7 @@ xfs_alloc_delrec(
         * If the number of records remaining in the block is at least
         * the minimum, we're done.
         */
-       if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
+       if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
                if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
                        return error;
                *stat = 1;
@@ -419,19 +422,21 @@ xfs_alloc_delrec(
         * See if we can join with the left neighbor block.
         */
        if (lbno != NULLAGBLOCK &&
-           lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+           lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
                /*
                 * Set "right" to be the starting block,
                 * "left" to be the left neighbor.
                 */
                rbno = bno;
                right = block;
+               rrecs = be16_to_cpu(right->bb_numrecs);
                rbp = bp;
                if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
                                cur->bc_private.a.agno, lbno, 0, &lbp,
                                XFS_ALLOC_BTREE_REF)))
                        return error;
                left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
+               lrecs = be16_to_cpu(left->bb_numrecs);
                if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
                        return error;
        }
@@ -439,20 +444,21 @@ xfs_alloc_delrec(
         * If that won't work, see if we can join with the right neighbor block.
         */
        else if (rbno != NULLAGBLOCK &&
-                rrecs + be16_to_cpu(block->bb_numrecs) <=
-                 XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+                rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
                /*
                 * Set "left" to be the starting block,
                 * "right" to be the right neighbor.
                 */
                lbno = bno;
                left = block;
+               lrecs = be16_to_cpu(left->bb_numrecs);
                lbp = bp;
                if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
                                cur->bc_private.a.agno, rbno, 0, &rbp,
                                XFS_ALLOC_BTREE_REF)))
                        return error;
                right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
+               rrecs = be16_to_cpu(right->bb_numrecs);
                if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
                        return error;
        }
@@ -474,34 +480,28 @@ xfs_alloc_delrec(
                /*
                 * It's a non-leaf.  Move keys and pointers.
                 */
-               lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
-               lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
+               lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur);
+               lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur);
                rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
                rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
 #ifdef DEBUG
-               for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+               for (i = 0; i < rrecs; i++) {
                        if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
                                return error;
                }
 #endif
-               memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp));
-               memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp));
-               xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
-                                  be16_to_cpu(left->bb_numrecs) +
-                                  be16_to_cpu(right->bb_numrecs));
-               xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
-                                  be16_to_cpu(left->bb_numrecs) +
-                                  be16_to_cpu(right->bb_numrecs));
+               memcpy(lkp, rkp, rrecs * sizeof(*lkp));
+               memcpy(lpp, rpp, rrecs * sizeof(*lpp));
+               xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
+               xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
        } else {
                /*
                 * It's a leaf.  Move records.
                 */
-               lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
+               lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur);
                rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
-               memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp));
-               xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
-                                  be16_to_cpu(left->bb_numrecs) +
-                                  be16_to_cpu(right->bb_numrecs));
+               memcpy(lrp, rrp, rrecs * sizeof(*lrp));
+               xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
        }
        /*
         * If we joined with the left neighbor, set the buffer in the
@@ -509,7 +509,7 @@ xfs_alloc_delrec(
         */
        if (bp != lbp) {
                xfs_btree_setbuf(cur, level, lbp);
-               cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs);
+               cur->bc_ptrs[level] += lrecs;
        }
        /*
         * If we joined with the right neighbor and there's a level above
@@ -521,7 +521,8 @@ xfs_alloc_delrec(
        /*
         * Fix up the number of records in the surviving block.
         */
-       be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs));
+       lrecs += rrecs;
+       left->bb_numrecs = cpu_to_be16(lrecs);
        /*
         * Fix up the right block pointer in the surviving block, and log it.
         */
@@ -608,6 +609,7 @@ xfs_alloc_insrec(
        xfs_btree_cur_t         *ncur;  /* new cursor to be used at next lvl */
        xfs_alloc_key_t         nkey;   /* new key value, from split */
        xfs_alloc_rec_t         nrec;   /* new record value, for caller */
+       int                     numrecs;
        int                     optr;   /* old ptr value */
        xfs_alloc_ptr_t         *pp;    /* pointer to btree addresses */
        int                     ptr;    /* index in btree block for this rec */
@@ -653,13 +655,14 @@ xfs_alloc_insrec(
         */
        bp = cur->bc_bufs[level];
        block = XFS_BUF_TO_ALLOC_BLOCK(bp);
+       numrecs = be16_to_cpu(block->bb_numrecs);
 #ifdef DEBUG
        if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
                return error;
        /*
         * Check that the new entry is being inserted in the right place.
         */
-       if (ptr <= be16_to_cpu(block->bb_numrecs)) {
+       if (ptr <= numrecs) {
                if (level == 0) {
                        rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
                        xfs_btree_check_rec(cur->bc_btnum, recp, rp);
@@ -670,12 +673,12 @@ xfs_alloc_insrec(
        }
 #endif
        nbno = NULLAGBLOCK;
-       ncur = (xfs_btree_cur_t *)0;
+       ncur = NULL;
        /*
         * If the block is full, we can't insert the new entry until we
         * make the block un-full.
         */
-       if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+       if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
                /*
                 * First, try shifting an entry to the right neighbor.
                 */
@@ -729,6 +732,7 @@ xfs_alloc_insrec(
         * At this point we know there's room for our new entry in the block
         * we're pointing at.
         */
+       numrecs = be16_to_cpu(block->bb_numrecs);
        if (level > 0) {
                /*
                 * It's a non-leaf entry.  Make a hole for the new data
@@ -737,15 +741,15 @@ xfs_alloc_insrec(
                kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
                pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
 #ifdef DEBUG
-               for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) {
+               for (i = numrecs; i >= ptr; i--) {
                        if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
                                return error;
                }
 #endif
                memmove(&kp[ptr], &kp[ptr - 1],
-                       (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp));
+                       (numrecs - ptr + 1) * sizeof(*kp));
                memmove(&pp[ptr], &pp[ptr - 1],
-                       (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp));
+                       (numrecs - ptr + 1) * sizeof(*pp));
 #ifdef DEBUG
                if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
                        return error;
@@ -755,11 +759,12 @@ xfs_alloc_insrec(
                 */
                kp[ptr - 1] = key;
                pp[ptr - 1] = cpu_to_be32(*bnop);
-               be16_add(&block->bb_numrecs, 1);
-               xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
-               xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
+               numrecs++;
+               block->bb_numrecs = cpu_to_be16(numrecs);
+               xfs_alloc_log_keys(cur, bp, ptr, numrecs);
+               xfs_alloc_log_ptrs(cur, bp, ptr, numrecs);
 #ifdef DEBUG
-               if (ptr < be16_to_cpu(block->bb_numrecs))
+               if (ptr < numrecs)
                        xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
                                kp + ptr);
 #endif
@@ -769,16 +774,17 @@ xfs_alloc_insrec(
                 */
                rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
                memmove(&rp[ptr], &rp[ptr - 1],
-                       (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp));
+                       (numrecs - ptr + 1) * sizeof(*rp));
                /*
                 * Now stuff the new record in, bump numrecs
                 * and log the new data.
                 */
-               rp[ptr - 1] = *recp; /* INT_: struct copy */
-               be16_add(&block->bb_numrecs, 1);
-               xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
+               rp[ptr - 1] = *recp;
+               numrecs++;
+               block->bb_numrecs = cpu_to_be16(numrecs);
+               xfs_alloc_log_recs(cur, bp, ptr, numrecs);
 #ifdef DEBUG
-               if (ptr < be16_to_cpu(block->bb_numrecs))
+               if (ptr < numrecs)
                        xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
                                rp + ptr);
 #endif
@@ -819,8 +825,8 @@ xfs_alloc_insrec(
         */
        *bnop = nbno;
        if (nbno != NULLAGBLOCK) {
-               *recp = nrec; /* INT_: struct copy */
-               *curp = ncur; /* INT_: struct copy */
+               *recp = nrec;
+               *curp = ncur;
        }
        *stat = 1;
        return 0;
@@ -981,7 +987,7 @@ xfs_alloc_lookup(
                 */
                bp = cur->bc_bufs[level];
                if (bp && XFS_BUF_ADDR(bp) != d)
-                       bp = (xfs_buf_t *)0;
+                       bp = NULL;
                if (!bp) {
                        /*
                         * Need to get a new buffer.  Read it, then
@@ -1229,7 +1235,7 @@ xfs_alloc_lshift(
                if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
                        return error;
 #endif
-               *lpp = *rpp; /* INT_: copy */
+               *lpp = *rpp;
                xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
                xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
        }
@@ -1406,8 +1412,8 @@ xfs_alloc_newroot(
 
                kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
                if (be16_to_cpu(left->bb_level) > 0) {
-                       kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */
-                       kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */
+                       kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur);
+                       kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);
                } else {
                        xfs_alloc_rec_t *rp;    /* btree record pointer */
 
@@ -1527,8 +1533,8 @@ xfs_alloc_rshift(
                if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
                        return error;
 #endif
-               *rkp = *lkp; /* INT_: copy */
-               *rpp = *lpp; /* INT_: copy */
+               *rkp = *lkp;
+               *rpp = *lpp;
                xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
                xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
                xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
@@ -2044,7 +2050,7 @@ xfs_alloc_insert(
        nbno = NULLAGBLOCK;
        nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
        nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
-       ncur = (xfs_btree_cur_t *)0;
+       ncur = NULL;
        pcur = cur;
        /*
         * Loop going up the tree, starting at the leaf level.
@@ -2076,7 +2082,7 @@ xfs_alloc_insert(
                 */
                if (ncur) {
                        pcur = ncur;
-                       ncur = (xfs_btree_cur_t *)0;
+                       ncur = NULL;
                }
        } while (nbno != NULLAGBLOCK);
        *stat = i;
index 1a210104327547b77768e6fd6cd58f7618bac090..9ada7bdbae5219a0803aac3b8c5f55a8d2f095c1 100644 (file)
@@ -91,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
 /*
  * Routines to manipulate out-of-line attribute values.
  */
-STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args);
 STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
 STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
 
@@ -180,7 +179,7 @@ xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
        return(error);
 }
 
-STATIC int
+int
 xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
                 char *value, int valuelen, int flags)
 {
@@ -440,7 +439,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
  * Generic handler routine to remove a name from an attribute list.
  * Transitions attribute list from Btree to shortform as necessary.
  */
-STATIC int
+int
 xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
 {
        xfs_da_args_t   args;
@@ -591,6 +590,110 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
        return xfs_attr_remove_int(dp, name, namelen, flags);
 }
 
+int                                                            /* error */
+xfs_attr_list_int(xfs_attr_list_context_t *context)
+{
+       int error;
+       xfs_inode_t *dp = context->dp;
+
+       /*
+        * Decide on what work routines to call based on the inode size.
+        */
+       if (XFS_IFORK_Q(dp) == 0 ||
+           (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
+            dp->i_d.di_anextents == 0)) {
+               error = 0;
+       } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
+               error = xfs_attr_shortform_list(context);
+       } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
+               error = xfs_attr_leaf_list(context);
+       } else {
+               error = xfs_attr_node_list(context);
+       }
+       return error;
+}
+
+#define        ATTR_ENTBASESIZE                /* minimum bytes used by an attr */ \
+       (((struct attrlist_ent *) 0)->a_name - (char *) 0)
+#define        ATTR_ENTSIZE(namelen)           /* actual bytes used by an attr */ \
+       ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
+        & ~(sizeof(u_int32_t)-1))
+
+/*
+ * Format an attribute and copy it out to the user's buffer.
+ * Take care to check values and protect against them changing later,
+ * we may be reading them directly out of a user buffer.
+ */
+/*ARGSUSED*/
+STATIC int
+xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp,
+                    char *name, int namelen,
+                    int valuelen, char *value)
+{
+       attrlist_ent_t *aep;
+       int arraytop;
+
+       ASSERT(!(context->flags & ATTR_KERNOVAL));
+       ASSERT(context->count >= 0);
+       ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
+       ASSERT(context->firstu >= sizeof(*context->alist));
+       ASSERT(context->firstu <= context->bufsize);
+
+       arraytop = sizeof(*context->alist) +
+                       context->count * sizeof(context->alist->al_offset[0]);
+       context->firstu -= ATTR_ENTSIZE(namelen);
+       if (context->firstu < arraytop) {
+               xfs_attr_trace_l_c("buffer full", context);
+               context->alist->al_more = 1;
+               context->seen_enough = 1;
+               return 1;
+       }
+
+       aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
+       aep->a_valuelen = valuelen;
+       memcpy(aep->a_name, name, namelen);
+       aep->a_name[ namelen ] = 0;
+       context->alist->al_offset[ context->count++ ] = context->firstu;
+       context->alist->al_count = context->count;
+       xfs_attr_trace_l_c("add", context);
+       return 0;
+}
+
+STATIC int
+xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp,
+                    char *name, int namelen,
+                    int valuelen, char *value)
+{
+       char *offset;
+       int arraytop;
+
+       ASSERT(context->count >= 0);
+
+       arraytop = context->count + namesp->attr_namelen + namelen + 1;
+       if (arraytop > context->firstu) {
+               context->count = -1;    /* insufficient space */
+               return 1;
+       }
+       offset = (char *)context->alist + context->count;
+       strncpy(offset, namesp->attr_name, namesp->attr_namelen);
+       offset += namesp->attr_namelen;
+       strncpy(offset, name, namelen);                 /* real name */
+       offset += namelen;
+       *offset = '\0';
+       context->count += namesp->attr_namelen + namelen + 1;
+       return 0;
+}
+
+/*ARGSUSED*/
+STATIC int
+xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
+                    char *name, int namelen,
+                    int valuelen, char *value)
+{
+       context->count += namesp->attr_namelen + namelen + 1;
+       return 0;
+}
+
 /*
  * Generate a list of extended attribute names and optionally
  * also value lengths.  Positive return value follows the XFS
@@ -615,13 +718,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
                return(XFS_ERROR(EINVAL));
        if ((cursor->initted == 0) &&
            (cursor->hashval || cursor->blkno || cursor->offset))
-               return(XFS_ERROR(EINVAL));
+               return XFS_ERROR(EINVAL);
 
        /*
         * Check for a properly aligned buffer.
         */
        if (((long)buffer) & (sizeof(int)-1))
-               return(XFS_ERROR(EFAULT));
+               return XFS_ERROR(EFAULT);
        if (flags & ATTR_KERNOVAL)
                bufsize = 0;
 
@@ -634,53 +737,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
        context.dupcnt = 0;
        context.resynch = 1;
        context.flags = flags;
-       if (!(flags & ATTR_KERNAMELS)) {
+       context.seen_enough = 0;
+       context.alist = (attrlist_t *)buffer;
+       context.put_value = 0;
+
+       if (flags & ATTR_KERNAMELS) {
+               context.bufsize = bufsize;
+               context.firstu = context.bufsize;
+               if (flags & ATTR_KERNOVAL)
+                       context.put_listent = xfs_attr_kern_list_sizes;
+               else
+                       context.put_listent = xfs_attr_kern_list;
+       } else {
                context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
                context.firstu = context.bufsize;
-               context.alist = (attrlist_t *)buffer;
                context.alist->al_count = 0;
                context.alist->al_more = 0;
                context.alist->al_offset[0] = context.bufsize;
-       }
-       else {
-               context.bufsize = bufsize;
-               context.firstu = context.bufsize;
-               context.alist = (attrlist_t *)buffer;
+               context.put_listent = xfs_attr_put_listent;
        }
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
-               return (EIO);
+               return EIO;
 
        xfs_ilock(dp, XFS_ILOCK_SHARED);
-       /*
-        * Decide on what work routines to call based on the inode size.
-        */
        xfs_attr_trace_l_c("syscall start", &context);
-       if (XFS_IFORK_Q(dp) == 0 ||
-           (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
-            dp->i_d.di_anextents == 0)) {
-               error = 0;
-       } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
-               error = xfs_attr_shortform_list(&context);
-       } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
-               error = xfs_attr_leaf_list(&context);
-       } else {
-               error = xfs_attr_node_list(&context);
-       }
+
+       error = xfs_attr_list_int(&context);
+
        xfs_iunlock(dp, XFS_ILOCK_SHARED);
        xfs_attr_trace_l_c("syscall end", &context);
 
-       if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) {
-               ASSERT(error >= 0);
-       }
-       else {  /* must return negated buffer size or the error */
+       if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) {
+               /* must return negated buffer size or the error */
                if (context.count < 0)
                        error = XFS_ERROR(ERANGE);
                else
                        error = -context.count;
-       }
+       } else
+               ASSERT(error >= 0);
 
-       return(error);
+       return error;
 }
 
 int                                                            /* error */
@@ -1122,19 +1219,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
        context->cursor->blkno = 0;
        error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
        if (error)
-               return(error);
+               return XFS_ERROR(error);
        ASSERT(bp != NULL);
        leaf = bp->data;
        if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
                XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
                                     context->dp->i_mount, leaf);
                xfs_da_brelse(NULL, bp);
-               return(XFS_ERROR(EFSCORRUPTED));
+               return XFS_ERROR(EFSCORRUPTED);
        }
 
-       (void)xfs_attr_leaf_list_int(bp, context);
+       error = xfs_attr_leaf_list_int(bp, context);
        xfs_da_brelse(NULL, bp);
-       return(0);
+       return XFS_ERROR(error);
 }
 
 
@@ -1858,8 +1955,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
                        return(XFS_ERROR(EFSCORRUPTED));
                }
                error = xfs_attr_leaf_list_int(bp, context);
-               if (error || !leaf->hdr.info.forw)
-                       break;  /* not really an error, buffer full or EOF */
+               if (error) {
+                       xfs_da_brelse(NULL, bp);
+                       return error;
+               }
+               if (context->seen_enough || leaf->hdr.info.forw == 0)
+                       break;
                cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
                xfs_da_brelse(NULL, bp);
                error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
@@ -1886,7 +1987,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
  * Read the value associated with an attribute from the out-of-line buffer
  * that we stored it in.
  */
-STATIC int
+int
 xfs_attr_rmtval_get(xfs_da_args_t *args)
 {
        xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
index 981633f6c077cb96128bbe730b3deb7809f16bc4..783977d3ea7192cdd8109aac8f7b05895964b6dd 100644 (file)
@@ -37,6 +37,7 @@
 
 struct cred;
 struct bhv_vnode;
+struct xfs_attr_list_context;
 
 typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
 typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
@@ -160,13 +161,16 @@ struct xfs_da_args;
  */
 int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
 int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
+int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int);
 int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
-int xfs_attr_list(bhv_desc_t *, char *, int, int,
-                        struct attrlist_cursor_kern *, struct cred *);
+int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int);
+int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *);
+int xfs_attr_list_int(struct xfs_attr_list_context *);
 int xfs_attr_inactive(struct xfs_inode *dp);
 
 int xfs_attr_shortform_getvalue(struct xfs_da_args *);
 int xfs_attr_fetch(struct xfs_inode *, const char *, int,
                        char *, int *, int, struct cred *);
+int xfs_attr_rmtval_get(struct xfs_da_args *args);
 
 #endif /* __XFS_ATTR_H__ */
index 9455051f01208e61ae7d32cf9ab2cbad858d5fe7..9719bbef122ce355c20894a51d424e4b264be933 100644 (file)
@@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
                                         int dst_start, int move_count,
                                         xfs_mount_t *mp);
 STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
-STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
-                            attrnames_t *, char *name, int namelen,
-                            int valuelen);
+
+/*========================================================================
+ * Namespace helper routines
+ *========================================================================*/
+
+STATIC inline attrnames_t *
+xfs_attr_flags_namesp(int flags)
+{
+       return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
+                 ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
+}
+
+/*
+ * If namespace bits don't match return 0.
+ * If all match then return 1.
+ */
+STATIC inline int
+xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
+{
+       return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
+}
+
+/*
+ * If namespace bits don't match and we don't have an override for it
+ * then return 0.
+ * If all match or are overridable then return 1.
+ */
+STATIC inline int
+xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
+{
+       if (((arg_flags & ATTR_SECURE) == 0) !=
+           ((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
+           !(arg_flags & ATTR_KERNORMALS))
+               return 0;
+       if (((arg_flags & ATTR_ROOT) == 0) !=
+           ((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
+           !(arg_flags & ATTR_KERNROOTLS))
+               return 0;
+       return 1;
+}
 
 
 /*========================================================================
@@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
                        continue;
                if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
                        continue;
-               if (((args->flags & ATTR_SECURE) != 0) !=
-                   ((sfe->flags & XFS_ATTR_SECURE) != 0))
-                       continue;
-               if (((args->flags & ATTR_ROOT) != 0) !=
-                   ((sfe->flags & XFS_ATTR_ROOT) != 0))
+               if (!xfs_attr_namesp_match(args->flags, sfe->flags))
                        continue;
                ASSERT(0);
 #endif
@@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
 
        sfe->namelen = args->namelen;
        sfe->valuelen = args->valuelen;
-       sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
-                       ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
+       sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
        memcpy(sfe->nameval, args->name, args->namelen);
        memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
        sf->hdr.count++;
@@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
                        continue;
                if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
                        continue;
-               if (((args->flags & ATTR_SECURE) != 0) !=
-                   ((sfe->flags & XFS_ATTR_SECURE) != 0))
-                       continue;
-               if (((args->flags & ATTR_ROOT) != 0) !=
-                   ((sfe->flags & XFS_ATTR_ROOT) != 0))
+               if (!xfs_attr_namesp_match(args->flags, sfe->flags))
                        continue;
                break;
        }
@@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
                        continue;
                if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
                        continue;
-               if (((args->flags & ATTR_SECURE) != 0) !=
-                   ((sfe->flags & XFS_ATTR_SECURE) != 0))
-                       continue;
-               if (((args->flags & ATTR_ROOT) != 0) !=
-                   ((sfe->flags & XFS_ATTR_ROOT) != 0))
+               if (!xfs_attr_namesp_match(args->flags, sfe->flags))
                        continue;
                return(XFS_ERROR(EEXIST));
        }
@@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
                        continue;
                if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
                        continue;
-               if (((args->flags & ATTR_SECURE) != 0) !=
-                   ((sfe->flags & XFS_ATTR_SECURE) != 0))
-                       continue;
-               if (((args->flags & ATTR_ROOT) != 0) !=
-                   ((sfe->flags & XFS_ATTR_ROOT) != 0))
+               if (!xfs_attr_namesp_match(args->flags, sfe->flags))
                        continue;
                if (args->flags & ATTR_KERNOVAL) {
                        args->valuelen = sfe->valuelen;
@@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
                nargs.valuelen = sfe->valuelen;
                nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
                                                sfe->namelen);
-               nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
-                               ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
+               nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
                error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
                ASSERT(error == ENOATTR);
                error = xfs_attr_leaf_add(bp, &nargs);
@@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b)
        }
 }
 
+
+#define XFS_ISRESET_CURSOR(cursor) \
+       (!((cursor)->initted) && !((cursor)->hashval) && \
+        !((cursor)->blkno) && !((cursor)->offset))
 /*
  * Copy out entries of shortform attribute lists for attr_list().
  * Shortform attribute lists are not stored in hashval sorted order.
@@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
        xfs_attr_sf_entry_t *sfe;
        xfs_inode_t *dp;
        int sbsize, nsbuf, count, i;
+       int error;
 
        ASSERT(context != NULL);
        dp = context->dp;
@@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
        xfs_attr_trace_l_c("sf start", context);
 
        /*
-        * If the buffer is large enough, do not bother with sorting.
+        * If the buffer is large enough and the cursor is at the start,
+        * do not bother with sorting since we will return everything in
+        * one buffer and another call using the cursor won't need to be
+        * made.
         * Note the generous fudge factor of 16 overhead bytes per entry.
+        * If bufsize is zero then put_listent must be a search function
+        * and can just scan through what we have.
         */
-       if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) {
+       if (context->bufsize == 0 ||
+           (XFS_ISRESET_CURSOR(cursor) &&
+             (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
                for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
                        attrnames_t     *namesp;
 
-                       if (((context->flags & ATTR_SECURE) != 0) !=
-                           ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
-                           !(context->flags & ATTR_KERNORMALS)) {
-                               sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
-                               continue;
-                       }
-                       if (((context->flags & ATTR_ROOT) != 0) !=
-                           ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
-                           !(context->flags & ATTR_KERNROOTLS)) {
+                       if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
                                sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
                                continue;
                        }
-                       namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure:
-                               ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
-                                 &attr_user);
-                       if (context->flags & ATTR_KERNOVAL) {
-                               ASSERT(context->flags & ATTR_KERNAMELS);
-                               context->count += namesp->attr_namelen +
-                                       sfe->namelen + 1;
-                       }
-                       else {
-                               if (xfs_attr_put_listent(context, namesp,
-                                                  (char *)sfe->nameval,
-                                                  (int)sfe->namelen,
-                                                  (int)sfe->valuelen))
-                                       break;
-                       }
+                       namesp = xfs_attr_flags_namesp(sfe->flags);
+                       error = context->put_listent(context,
+                                          namesp,
+                                          (char *)sfe->nameval,
+                                          (int)sfe->namelen,
+                                          (int)sfe->valuelen,
+                                          (char*)&sfe->nameval[sfe->namelen]);
+
+                       /*
+                        * Either search callback finished early or
+                        * didn't fit it all in the buffer after all.
+                        */
+                       if (context->seen_enough)
+                               break;
+
+                       if (error)
+                               return error;
                        sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
                }
                xfs_attr_trace_l_c("sf big-gulp", context);
                return(0);
        }
 
+       /* do no more for a search callback */
+       if (context->bufsize == 0)
+               return 0;
+
        /*
         * It didn't all fit, so we have to sort everything on hashval.
         */
@@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
                        kmem_free(sbuf, sbsize);
                        return XFS_ERROR(EFSCORRUPTED);
                }
-               if (((context->flags & ATTR_SECURE) != 0) !=
-                   ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
-                   !(context->flags & ATTR_KERNORMALS)) {
-                       sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
-                       continue;
-               }
-               if (((context->flags & ATTR_ROOT) != 0) !=
-                   ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
-                   !(context->flags & ATTR_KERNROOTLS)) {
+               if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
                        sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
                        continue;
                }
@@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
        for ( ; i < nsbuf; i++, sbp++) {
                attrnames_t     *namesp;
 
-               namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
-                       ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
-                         &attr_user);
+               namesp = xfs_attr_flags_namesp(sbp->flags);
 
                if (cursor->hashval != sbp->hash) {
                        cursor->hashval = sbp->hash;
                        cursor->offset = 0;
                }
-               if (context->flags & ATTR_KERNOVAL) {
-                       ASSERT(context->flags & ATTR_KERNAMELS);
-                       context->count += namesp->attr_namelen +
-                                               sbp->namelen + 1;
-               } else {
-                       if (xfs_attr_put_listent(context, namesp,
-                                       sbp->name, sbp->namelen,
-                                       sbp->valuelen))
-                               break;
-               }
+               error = context->put_listent(context,
+                                       namesp,
+                                       sbp->name,
+                                       sbp->namelen,
+                                       sbp->valuelen,
+                                       &sbp->name[sbp->namelen]);
+               if (error)
+                       return error;
+               if (context->seen_enough)
+                       break;
                cursor->offset++;
        }
 
@@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
                nargs.value = (char *)&name_loc->nameval[nargs.namelen];
                nargs.valuelen = be16_to_cpu(name_loc->valuelen);
                nargs.hashval = be32_to_cpu(entry->hashval);
-               nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
-                             ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
+               nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
                xfs_attr_shortform_add(&nargs, forkoff);
        }
        error = 0;
@@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
                                     be16_to_cpu(map->size));
        entry->hashval = cpu_to_be32(args->hashval);
        entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
-       entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
-                       ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
+       entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
        if (args->rename) {
                entry->flags |= XFS_ATTR_INCOMPLETE;
                if ((args->blkno2 == args->blkno) &&
@@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
                else
                        break;
        }
-       ASSERT((probe >= 0) && 
+       ASSERT((probe >= 0) &&
               (!leaf->hdr.count
               || (probe < be16_to_cpu(leaf->hdr.count))));
        ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
@@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
                        name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe);
                        if (name_loc->namelen != args->namelen)
                                continue;
-                       if (memcmp(args->name, (char *)name_loc->nameval,
-                                            args->namelen) != 0)
+                       if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0)
                                continue;
-                       if (((args->flags & ATTR_SECURE) != 0) !=
-                           ((entry->flags & XFS_ATTR_SECURE) != 0))
-                               continue;
-                       if (((args->flags & ATTR_ROOT) != 0) !=
-                           ((entry->flags & XFS_ATTR_ROOT) != 0))
+                       if (!xfs_attr_namesp_match(args->flags, entry->flags))
                                continue;
                        args->index = probe;
                        return(XFS_ERROR(EEXIST));
@@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
                        if (memcmp(args->name, (char *)name_rmt->name,
                                             args->namelen) != 0)
                                continue;
-                       if (((args->flags & ATTR_SECURE) != 0) !=
-                           ((entry->flags & XFS_ATTR_SECURE) != 0))
-                               continue;
-                       if (((args->flags & ATTR_ROOT) != 0) !=
-                           ((entry->flags & XFS_ATTR_ROOT) != 0))
+                       if (!xfs_attr_namesp_match(args->flags, entry->flags))
                                continue;
                        args->index = probe;
                        args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
@@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
        attrlist_cursor_kern_t *cursor;
        xfs_attr_leafblock_t *leaf;
        xfs_attr_leaf_entry_t *entry;
-       xfs_attr_leaf_name_local_t *name_loc;
-       xfs_attr_leaf_name_remote_t *name_rmt;
        int retval, i;
 
        ASSERT(bp != NULL);
@@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
         * We have found our place, start copying out the new attributes.
         */
        retval = 0;
-       for (  ; (i < be16_to_cpu(leaf->hdr.count))
-            && (retval == 0); entry++, i++) {
-               attrnames_t     *namesp;
+       for (  ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
+               attrnames_t *namesp;
 
                if (be32_to_cpu(entry->hashval) != cursor->hashval) {
                        cursor->hashval = be32_to_cpu(entry->hashval);
@@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
 
                if (entry->flags & XFS_ATTR_INCOMPLETE)
                        continue;               /* skip incomplete entries */
-               if (((context->flags & ATTR_SECURE) != 0) !=
-                   ((entry->flags & XFS_ATTR_SECURE) != 0) &&
-                   !(context->flags & ATTR_KERNORMALS))
-                       continue;               /* skip non-matching entries */
-               if (((context->flags & ATTR_ROOT) != 0) !=
-                   ((entry->flags & XFS_ATTR_ROOT) != 0) &&
-                   !(context->flags & ATTR_KERNROOTLS))
-                       continue;               /* skip non-matching entries */
-
-               namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
-                       ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
-                         &attr_user);
+               if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
+                       continue;
+
+               namesp = xfs_attr_flags_namesp(entry->flags);
 
                if (entry->flags & XFS_ATTR_LOCAL) {
-                       name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
-                       if (context->flags & ATTR_KERNOVAL) {
-                               ASSERT(context->flags & ATTR_KERNAMELS);
-                               context->count += namesp->attr_namelen +
-                                               (int)name_loc->namelen + 1;
-                       } else {
-                               retval = xfs_attr_put_listent(context, namesp,
-                                       (char *)name_loc->nameval,
-                                       (int)name_loc->namelen,
-                                       be16_to_cpu(name_loc->valuelen));
-                       }
+                       xfs_attr_leaf_name_local_t *name_loc =
+                               XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
+
+                       retval = context->put_listent(context,
+                                               namesp,
+                                               (char *)name_loc->nameval,
+                                               (int)name_loc->namelen,
+                                               be16_to_cpu(name_loc->valuelen),
+                                               (char *)&name_loc->nameval[name_loc->namelen]);
+                       if (retval)
+                               return retval;
                } else {
-                       name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
-                       if (context->flags & ATTR_KERNOVAL) {
-                               ASSERT(context->flags & ATTR_KERNAMELS);
-                               context->count += namesp->attr_namelen +
-                                               (int)name_rmt->namelen + 1;
-                       } else {
-                               retval = xfs_attr_put_listent(context, namesp,
-                                       (char *)name_rmt->name,
-                                       (int)name_rmt->namelen,
-                                       be32_to_cpu(name_rmt->valuelen));
+                       xfs_attr_leaf_name_remote_t *name_rmt =
+                               XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
+
+                       int valuelen = be32_to_cpu(name_rmt->valuelen);
+
+                       if (context->put_value) {
+                               xfs_da_args_t args;
+
+                               memset((char *)&args, 0, sizeof(args));
+                               args.dp = context->dp;
+                               args.whichfork = XFS_ATTR_FORK;
+                               args.valuelen = valuelen;
+                               args.value = kmem_alloc(valuelen, KM_SLEEP);
+                               args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
+                               args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen);
+                               retval = xfs_attr_rmtval_get(&args);
+                               if (retval)
+                                       return retval;
+                               retval = context->put_listent(context,
+                                               namesp,
+                                               (char *)name_rmt->name,
+                                               (int)name_rmt->namelen,
+                                               valuelen,
+                                               (char*)args.value);
+                               kmem_free(args.value, valuelen);
                        }
+                       else {
+                               retval = context->put_listent(context,
+                                               namesp,
+                                               (char *)name_rmt->name,
+                                               (int)name_rmt->namelen,
+                                               valuelen,
+                                               NULL);
+                       }
+                       if (retval)
+                               return retval;
                }
-               if (retval == 0) {
-                       cursor->offset++;
-               }
+               if (context->seen_enough)
+                       break;
+               cursor->offset++;
        }
        xfs_attr_trace_l_cl("blk end", context, leaf);
        return(retval);
 }
 
-#define        ATTR_ENTBASESIZE                /* minimum bytes used by an attr */ \
-       (((struct attrlist_ent *) 0)->a_name - (char *) 0)
-#define        ATTR_ENTSIZE(namelen)           /* actual bytes used by an attr */ \
-       ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
-        & ~(sizeof(u_int32_t)-1))
-
-/*
- * Format an attribute and copy it out to the user's buffer.
- * Take care to check values and protect against them changing later,
- * we may be reading them directly out of a user buffer.
- */
-/*ARGSUSED*/
-STATIC int
-xfs_attr_put_listent(xfs_attr_list_context_t *context,
-                    attrnames_t *namesp, char *name, int namelen, int valuelen)
-{
-       attrlist_ent_t *aep;
-       int arraytop;
-
-       ASSERT(!(context->flags & ATTR_KERNOVAL));
-       if (context->flags & ATTR_KERNAMELS) {
-               char *offset;
-
-               ASSERT(context->count >= 0);
-
-               arraytop = context->count + namesp->attr_namelen + namelen + 1;
-               if (arraytop > context->firstu) {
-                       context->count = -1;    /* insufficient space */
-                       return(1);
-               }
-               offset = (char *)context->alist + context->count;
-               strncpy(offset, namesp->attr_name, namesp->attr_namelen);
-               offset += namesp->attr_namelen;
-               strncpy(offset, name, namelen);                 /* real name */
-               offset += namelen;
-               *offset = '\0';
-               context->count += namesp->attr_namelen + namelen + 1;
-               return(0);
-       }
-
-       ASSERT(context->count >= 0);
-       ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
-       ASSERT(context->firstu >= sizeof(*context->alist));
-       ASSERT(context->firstu <= context->bufsize);
-
-       arraytop = sizeof(*context->alist) +
-                       context->count * sizeof(context->alist->al_offset[0]);
-       context->firstu -= ATTR_ENTSIZE(namelen);
-       if (context->firstu < arraytop) {
-               xfs_attr_trace_l_c("buffer full", context);
-               context->alist->al_more = 1;
-               return(1);
-       }
-
-       aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
-       aep->a_valuelen = valuelen;
-       memcpy(aep->a_name, name, namelen);
-       aep->a_name[ namelen ] = 0;
-       context->alist->al_offset[ context->count++ ] = context->firstu;
-       context->alist->al_count = context->count;
-       xfs_attr_trace_l_c("add", context);
-       return(0);
-}
 
 /*========================================================================
  * Manage the INCOMPLETE flag in a leaf entry
index 51c3ee156b2fdf787399710ce5b280007ff0655c..040f732ce1e22a22e513bd3afca283c1d432e167 100644 (file)
@@ -129,6 +129,19 @@ typedef struct xfs_attr_leafblock {
 #define XFS_ATTR_SECURE                (1 << XFS_ATTR_SECURE_BIT)
 #define XFS_ATTR_INCOMPLETE    (1 << XFS_ATTR_INCOMPLETE_BIT)
 
+/*
+ * Conversion macros for converting namespace bits from argument flags
+ * to ondisk flags.
+ */
+#define XFS_ATTR_NSP_ARGS_MASK         (ATTR_ROOT | ATTR_SECURE)
+#define XFS_ATTR_NSP_ONDISK_MASK       (XFS_ATTR_ROOT | XFS_ATTR_SECURE)
+#define XFS_ATTR_NSP_ONDISK(flags)     ((flags) & XFS_ATTR_NSP_ONDISK_MASK)
+#define XFS_ATTR_NSP_ARGS(flags)       ((flags) & XFS_ATTR_NSP_ARGS_MASK)
+#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\
+                                        ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0))
+#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\
+                                        ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0))
+
 /*
  * Alignment for namelist and valuelist entries (since they are mixed
  * there can be only one alignment value)
@@ -196,16 +209,26 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize)
  * Structure used to pass context around among the routines.
  *========================================================================*/
 
+
+struct xfs_attr_list_context;
+
+typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *,
+                                     char *, int, int, char *);
+
 typedef struct xfs_attr_list_context {
-       struct xfs_inode                *dp;    /* inode */
-       struct attrlist_cursor_kern     *cursor;/* position in list */
-       struct attrlist                 *alist; /* output buffer */
-       int                             count;  /* num used entries */
-       int                             dupcnt; /* count dup hashvals seen */
-       int                             bufsize;/* total buffer size */
-       int                             firstu; /* first used byte in buffer */
-       int                             flags;  /* from VOP call */
-       int                             resynch;/* T/F: resynch with cursor */
+       struct xfs_inode                *dp;            /* inode */
+       struct attrlist_cursor_kern     *cursor;        /* position in list */
+       struct attrlist                 *alist;         /* output buffer */
+       int                             seen_enough;    /* T/F: seen enough of list? */
+       int                             count;          /* num used entries */
+       int                             dupcnt;         /* count dup hashvals seen */
+       int                             bufsize;        /* total buffer size */
+       int                             firstu;         /* first used byte in buffer */
+       int                             flags;          /* from VOP call */
+       int                             resynch;        /* T/F: resynch with cursor */
+       int                             put_value;      /* T/F: need value for listent */
+       put_listent_func_t              put_listent;    /* list output fmt function */
+       int                             index;          /* index into output buffer */
 } xfs_attr_list_context_t;
 
 /*
index f4fe3715a8032424975eff9f9975a8ae42260197..0dc17219d4129a821474af9c168f1010e2ee87c7 100644 (file)
@@ -109,26 +109,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
        prev->bd_next = bdp->bd_next;   /* remove from after prev */
 }
 
-/*
- * Look for a specific ops vector on the specified behavior chain.
- * Return the associated behavior descriptor.  Or NULL, if not found.
- */
-bhv_desc_t *
-bhv_lookup(bhv_head_t *bhp, void *ops)
-{
-       bhv_desc_t      *curdesc;
-
-       for (curdesc = bhp->bh_first;
-            curdesc != NULL;
-            curdesc = curdesc->bd_next) {
-
-               if (curdesc->bd_ops == ops)
-                       return curdesc;
-       }
-
-       return NULL;
-}
-
 /*
  * Looks for the first behavior within a specified range of positions.
  * Return the associated behavior descriptor.  Or NULL, if none found.
index 6e6e56fb352d2fc56585f923f693c9231795c912..e7ca1fed955a98ff3e15a68ac1dddcdf9e1e020a 100644 (file)
@@ -176,12 +176,10 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
  * Behavior module prototypes.
  */
 extern void            bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
-extern bhv_desc_t *    bhv_lookup(bhv_head_t *bhp, void *ops);
 extern bhv_desc_t *    bhv_lookup_range(bhv_head_t *bhp, int low, int high);
 extern bhv_desc_t *    bhv_base(bhv_head_t *bhp);
 
 /* No bhv locking on Linux */
-#define bhv_lookup_unlocked    bhv_lookup
 #define bhv_base_unlocked      bhv_base
 
 #endif /* __XFS_BEHAVIOR_H__ */
index bf46fae303af9826296dc9767fd8d696e2118862..5b050c06795fbbf3abd51b0f6c77a24daccc33f4 100644 (file)
@@ -2999,7 +2999,7 @@ xfs_bmap_btree_to_extents(
        int                     error;  /* error return value */
        xfs_ifork_t             *ifp;   /* inode fork data */
        xfs_mount_t             *mp;    /* mount point structure */
-       xfs_bmbt_ptr_t          *pp;    /* ptr to block address */
+       __be64                  *pp;    /* ptr to block address */
        xfs_bmbt_block_t        *rblock;/* root btree block */
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -3011,12 +3011,12 @@ xfs_bmap_btree_to_extents(
        ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
        mp = ip->i_mount;
        pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
+       cbno = be64_to_cpu(*pp);
        *logflagsp = 0;
 #ifdef DEBUG
-       if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1)))
+       if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
                return error;
 #endif
-       cbno = INT_GET(*pp, ARCH_CONVERT);
        if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp,
                        XFS_BMAP_BTREE_REF)))
                return error;
@@ -3512,9 +3512,9 @@ xfs_bmap_extents_to_btree(
         */
        kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
        arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
-       INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp));
+       kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
        pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
-       INT_SET(*pp, ARCH_CONVERT, args.fsbno);
+       *pp = cpu_to_be64(args.fsbno);
        /*
         * Do all this logging at the end so that
         * the root is at the right level.
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t *                 /* pointer to found extent entry */
 xfs_bmap_search_extents(
        xfs_inode_t     *ip,            /* incore inode pointer */
        xfs_fileoff_t   bno,            /* block number searched for */
-       int             whichfork,      /* data or attr fork */
+       int             fork,           /* data or attr fork */
        int             *eofp,          /* out: end of file found */
        xfs_extnum_t    *lastxp,        /* out: last extent index */
        xfs_bmbt_irec_t *gotp,          /* out: extent entry found */
@@ -3713,25 +3713,28 @@ xfs_bmap_search_extents(
 {
        xfs_ifork_t     *ifp;           /* inode fork pointer */
        xfs_bmbt_rec_t  *ep;            /* extent record pointer */
-       int             rt;             /* realtime flag    */
 
        XFS_STATS_INC(xs_look_exlist);
-       ifp = XFS_IFORK_PTR(ip, whichfork);
+       ifp = XFS_IFORK_PTR(ip, fork);
 
        ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
 
-       rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
-       if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
-                cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
-                       "start_block : %llx start_off : %llx blkcnt : %llx "
-                       "extent-state : %x \n",
-                       (ip->i_mount)->m_fsname, (long long)ip->i_ino,
+       if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
+                    !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
+               xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
+                               "Access to block zero in inode %llu "
+                               "start_block: %llx start_off: %llx "
+                               "blkcnt: %llx extent-state: %x lastx: %x\n",
+                       (unsigned long long)ip->i_ino,
                        (unsigned long long)gotp->br_startblock,
                        (unsigned long long)gotp->br_startoff,
                        (unsigned long long)gotp->br_blockcount,
-                       gotp->br_state);
-        }
-        return ep;
+                       gotp->br_state, *lastxp);
+               *lastxp = NULLEXTNUM;
+               *eofp = 1;
+               return NULL;
+       }
+       return ep;
 }
 
 
@@ -4494,7 +4497,7 @@ xfs_bmap_read_extents(
        xfs_ifork_t             *ifp;   /* fork structure */
        int                     level;  /* btree level, for checking */
        xfs_mount_t             *mp;    /* file system mount structure */
-       xfs_bmbt_ptr_t          *pp;    /* pointer to block address */
+       __be64                  *pp;    /* pointer to block address */
        /* REFERENCED */
        xfs_extnum_t            room;   /* number of entries there's room for */
 
@@ -4510,10 +4513,10 @@ xfs_bmap_read_extents(
        level = be16_to_cpu(block->bb_level);
        ASSERT(level > 0);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
-       ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
-       ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
-       ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
-       bno = INT_GET(*pp, ARCH_CONVERT);
+       bno = be64_to_cpu(*pp);
+       ASSERT(bno != NULLDFSBNO);
+       ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+       ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
        /*
         * Go down the tree until leaf level is reached, following the first
         * pointer (leftmost) at each level.
@@ -4530,10 +4533,8 @@ xfs_bmap_read_extents(
                        break;
                pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
                        1, mp->m_bmap_dmxr[1]);
-               XFS_WANT_CORRUPTED_GOTO(
-                       XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)),
-                       error0);
-               bno = INT_GET(*pp, ARCH_CONVERT);
+               bno = be64_to_cpu(*pp);
+               XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
                xfs_trans_brelse(tp, bp);
        }
        /*
@@ -6141,7 +6142,7 @@ xfs_check_block(
        short                   sz)
 {
        int                     i, j, dmxr;
-       xfs_bmbt_ptr_t          *pp, *thispa;   /* pointer to block address */
+       __be64                  *pp, *thispa;   /* pointer to block address */
        xfs_bmbt_key_t          *prevp, *keyp;
 
        ASSERT(be16_to_cpu(block->bb_level) > 0);
@@ -6179,11 +6180,10 @@ xfs_check_block(
                                thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
                                        xfs_bmbt, block, j, dmxr);
                        }
-                       if (INT_GET(*thispa, ARCH_CONVERT) ==
-                           INT_GET(*pp, ARCH_CONVERT)) {
+                       if (*thispa == *pp) {
                                cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld",
                                        __FUNCTION__, j, i,
-                                       INT_GET(*thispa, ARCH_CONVERT));
+                                       (unsigned long long)be64_to_cpu(*thispa));
                                panic("%s: ptrs are equal in node\n",
                                        __FUNCTION__);
                        }
@@ -6210,7 +6210,7 @@ xfs_bmap_check_leaf_extents(
        xfs_ifork_t             *ifp;   /* fork structure */
        int                     level;  /* btree level, for checking */
        xfs_mount_t             *mp;    /* file system mount structure */
-       xfs_bmbt_ptr_t          *pp;    /* pointer to block address */
+       __be64                  *pp;    /* pointer to block address */
        xfs_bmbt_rec_t          *ep;    /* pointer to current extent */
        xfs_bmbt_rec_t          *lastp; /* pointer to previous extent */
        xfs_bmbt_rec_t          *nextp; /* pointer to next extent */
@@ -6231,10 +6231,12 @@ xfs_bmap_check_leaf_extents(
        ASSERT(level > 0);
        xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
-       ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
-       ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
-       ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
-       bno = INT_GET(*pp, ARCH_CONVERT);
+       bno = be64_to_cpu(*pp);
+
+       ASSERT(bno != NULLDFSBNO);
+       ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+       ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
+
        /*
         * Go down the tree until leaf level is reached, following the first
         * pointer (leftmost) at each level.
@@ -6265,8 +6267,8 @@ xfs_bmap_check_leaf_extents(
                xfs_check_block(block, mp, 0, 0);
                pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
                        1, mp->m_bmap_dmxr[1]);
-               XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0);
-               bno = INT_GET(*pp, ARCH_CONVERT);
+               bno = be64_to_cpu(*pp);
+               XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
                if (bp_release) {
                        bp_release = 0;
                        xfs_trans_brelse(NULL, bp);
@@ -6372,7 +6374,7 @@ xfs_bmap_count_blocks(
        xfs_ifork_t             *ifp;   /* fork structure */
        int                     level;  /* btree level, for checking */
        xfs_mount_t             *mp;    /* file system mount structure */
-       xfs_bmbt_ptr_t          *pp;    /* pointer to block address */
+       __be64                  *pp;    /* pointer to block address */
 
        bno = NULLFSBLOCK;
        mp = ip->i_mount;
@@ -6395,10 +6397,10 @@ xfs_bmap_count_blocks(
        level = be16_to_cpu(block->bb_level);
        ASSERT(level > 0);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
-       ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
-       ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
-       ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
-       bno = INT_GET(*pp, ARCH_CONVERT);
+       bno = be64_to_cpu(*pp);
+       ASSERT(bno != NULLDFSBNO);
+       ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
+       ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
 
        if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
                XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
@@ -6425,7 +6427,7 @@ xfs_bmap_count_tree(
        int                     error;
        xfs_buf_t               *bp, *nbp;
        int                     level = levelin;
-       xfs_bmbt_ptr_t          *pp;
+       __be64                  *pp;
        xfs_fsblock_t           bno = blockno;
        xfs_fsblock_t           nextbno;
        xfs_bmbt_block_t        *block, *nextblock;
@@ -6452,7 +6454,7 @@ xfs_bmap_count_tree(
                /* Dive to the next level */
                pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
                        xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
-               bno = INT_GET(*pp, ARCH_CONVERT);
+               bno = be64_to_cpu(*pp);
                if (unlikely((error =
                     xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
                        xfs_trans_brelse(tp, bp);
index 18fb7385d719fe4ad25b5f64ff23ec55d710d060..a7b835bf870ae123b0e5839d0fc0dc51687f0326 100644 (file)
@@ -58,7 +58,7 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
 STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
 STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
 STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
-               xfs_bmbt_key_t *, xfs_btree_cur_t **, int *);
+               __uint64_t *, xfs_btree_cur_t **, int *);
 STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);
 
 
@@ -192,16 +192,11 @@ xfs_bmbt_trace_argifk(
        xfs_btree_cur_t         *cur,
        int                     i,
        xfs_fsblock_t           f,
-       xfs_bmbt_key_t          *k,
+       xfs_dfiloff_t           o,
        int                     line)
 {
-       xfs_dfsbno_t            d;
-       xfs_dfiloff_t           o;
-
-       d = (xfs_dfsbno_t)f;
-       o = INT_GET(k->br_startoff, ARCH_CONVERT);
        xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
-               i, d >> 32, (int)d, o >> 32,
+               i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32,
                (int)o, 0, 0, 0,
                0, 0, 0);
 }
@@ -248,7 +243,7 @@ xfs_bmbt_trace_argik(
 {
        xfs_dfiloff_t           o;
 
-       o = INT_GET(k->br_startoff, ARCH_CONVERT);
+       o = be64_to_cpu(k->br_startoff);
        xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
                i, o >> 32, (int)o, 0,
                0, 0, 0, 0,
@@ -286,8 +281,8 @@ xfs_bmbt_trace_cursor(
        xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__)
 #define        XFS_BMBT_TRACE_ARGI(c,i)        \
        xfs_bmbt_trace_argi(fname, c, i, __LINE__)
-#define        XFS_BMBT_TRACE_ARGIFK(c,i,f,k)  \
-       xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__)
+#define        XFS_BMBT_TRACE_ARGIFK(c,i,f,s)  \
+       xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__)
 #define        XFS_BMBT_TRACE_ARGIFR(c,i,f,r)  \
        xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__)
 #define        XFS_BMBT_TRACE_ARGIK(c,i,k)     \
@@ -299,7 +294,7 @@ xfs_bmbt_trace_cursor(
 #define        XFS_BMBT_TRACE_ARGBII(c,b,i,j)
 #define        XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j)
 #define        XFS_BMBT_TRACE_ARGI(c,i)
-#define        XFS_BMBT_TRACE_ARGIFK(c,i,f,k)
+#define        XFS_BMBT_TRACE_ARGIFK(c,i,f,s)
 #define        XFS_BMBT_TRACE_ARGIFR(c,i,f,r)
 #define        XFS_BMBT_TRACE_ARGIK(c,i,k)
 #define        XFS_BMBT_TRACE_CURSOR(c,s)
@@ -357,7 +352,7 @@ xfs_bmbt_delrec(
        XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
        XFS_BMBT_TRACE_ARGI(cur, level);
        ptr = cur->bc_ptrs[level];
-       tcur = (xfs_btree_cur_t *)0;
+       tcur = NULL;
        if (ptr == 0) {
                XFS_BMBT_TRACE_CURSOR(cur, EXIT);
                *stat = 0;
@@ -382,7 +377,7 @@ xfs_bmbt_delrec(
                pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
 #ifdef DEBUG
                for (i = ptr; i < numrecs; i++) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
+                       if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                goto error0;
                        }
@@ -404,7 +399,8 @@ xfs_bmbt_delrec(
                        xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
                }
                if (ptr == 1) {
-                       INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp));
+                       key.br_startoff =
+                               cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
                        kp = &key;
                }
        }
@@ -621,7 +617,7 @@ xfs_bmbt_delrec(
                rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
 #ifdef DEBUG
                for (i = 0; i < numrrecs; i++) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
+                       if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                goto error0;
                        }
@@ -748,7 +744,7 @@ xfs_bmbt_insrec(
        int                     logflags;       /* inode logging flags */
        xfs_fsblock_t           nbno;           /* new block number */
        struct xfs_btree_cur    *ncur;          /* new btree cursor */
-       xfs_bmbt_key_t          nkey;           /* new btree key value */
+       __uint64_t              startoff;       /* new btree key value */
        xfs_bmbt_rec_t          nrec;           /* new record count */
        int                     optr;           /* old key/record index */
        xfs_bmbt_ptr_t          *pp;            /* pointer to bmap block addr */
@@ -759,9 +755,8 @@ xfs_bmbt_insrec(
        ASSERT(level < cur->bc_nlevels);
        XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
        XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
-       ncur = (xfs_btree_cur_t *)0;
-       INT_SET(key.br_startoff, ARCH_CONVERT,
-               xfs_bmbt_disk_get_startoff(recp));
+       ncur = NULL;
+       key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp));
        optr = ptr = cur->bc_ptrs[level];
        if (ptr == 0) {
                XFS_BMBT_TRACE_CURSOR(cur, EXIT);
@@ -820,7 +815,7 @@ xfs_bmbt_insrec(
                                        optr = ptr = cur->bc_ptrs[level];
                                } else {
                                        if ((error = xfs_bmbt_split(cur, level,
-                                                       &nbno, &nkey, &ncur,
+                                                       &nbno, &startoff, &ncur,
                                                        &i))) {
                                                XFS_BMBT_TRACE_CURSOR(cur,
                                                        ERROR);
@@ -840,7 +835,7 @@ xfs_bmbt_insrec(
 #endif
                                                ptr = cur->bc_ptrs[level];
                                                xfs_bmbt_disk_set_allf(&nrec,
-                                                       nkey.br_startoff, 0, 0,
+                                                       startoff, 0, 0,
                                                        XFS_EXT_NORM);
                                        } else {
                                                XFS_BMBT_TRACE_CURSOR(cur,
@@ -858,7 +853,7 @@ xfs_bmbt_insrec(
                pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
 #ifdef DEBUG
                for (i = numrecs; i >= ptr; i--) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT),
+                       if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1],
                                        level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                return error;
@@ -870,14 +865,13 @@ xfs_bmbt_insrec(
                memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
                        (numrecs - ptr + 1) * sizeof(*pp));
 #ifdef DEBUG
-               if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop,
-                               level))) {
+               if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
 #endif
                kp[ptr - 1] = key;
-               INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
+               pp[ptr - 1] = cpu_to_be64(*bnop);
                numrecs++;
                block->bb_numrecs = cpu_to_be16(numrecs);
                xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
@@ -988,7 +982,7 @@ xfs_bmbt_killroot(
        cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
 #ifdef DEBUG
        for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
-               if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) {
+               if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
@@ -1132,7 +1126,7 @@ xfs_bmbt_lookup(
                        d = XFS_FSB_TO_DADDR(mp, fsbno);
                        bp = cur->bc_bufs[level];
                        if (bp && XFS_BUF_ADDR(bp) != d)
-                               bp = (xfs_buf_t *)0;
+                               bp = NULL;
                        if (!bp) {
                                if ((error = xfs_btree_read_bufl(mp, tp, fsbno,
                                                0, &bp, XFS_BMAP_BTREE_REF))) {
@@ -1170,7 +1164,7 @@ xfs_bmbt_lookup(
                                keyno = (low + high) >> 1;
                                if (level > 0) {
                                        kkp = kkbase + keyno - 1;
-                                       startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT);
+                                       startoff = be64_to_cpu(kkp->br_startoff);
                                } else {
                                        krp = krbase + keyno - 1;
                                        startoff = xfs_bmbt_disk_get_startoff(krp);
@@ -1189,13 +1183,13 @@ xfs_bmbt_lookup(
                        if (diff > 0 && --keyno < 1)
                                keyno = 1;
                        pp = XFS_BMAP_PTR_IADDR(block, keyno, cur);
+                       fsbno = be64_to_cpu(*pp);
 #ifdef DEBUG
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
+                       if ((error = xfs_btree_check_lptr(cur, fsbno, level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                return error;
                        }
 #endif
-                       fsbno = INT_GET(*pp, ARCH_CONVERT);
                        cur->bc_ptrs[level] = keyno;
                }
        }
@@ -1313,7 +1307,7 @@ xfs_bmbt_lshift(
                lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
                rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
 #ifdef DEBUG
-               if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) {
+               if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
@@ -1340,7 +1334,7 @@ xfs_bmbt_lshift(
        if (level > 0) {
 #ifdef DEBUG
                for (i = 0; i < rrecs; i++) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
+                       if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
                                        level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                return error;
@@ -1354,8 +1348,7 @@ xfs_bmbt_lshift(
        } else {
                memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
                xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
-               INT_SET(key.br_startoff, ARCH_CONVERT,
-                       xfs_bmbt_disk_get_startoff(rrp));
+               key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
                rkp = &key;
        }
        if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
@@ -1445,7 +1438,7 @@ xfs_bmbt_rshift(
                rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
 #ifdef DEBUG
                for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
+                       if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                return error;
                        }
@@ -1454,7 +1447,7 @@ xfs_bmbt_rshift(
                memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
                memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
 #ifdef DEBUG
-               if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) {
+               if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
@@ -1469,8 +1462,7 @@ xfs_bmbt_rshift(
                memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
                *rrp = *lrp;
                xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
-               INT_SET(key.br_startoff, ARCH_CONVERT,
-                       xfs_bmbt_disk_get_startoff(rrp));
+               key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
                rkp = &key;
        }
        be16_add(&left->bb_numrecs, -1);
@@ -1535,7 +1527,7 @@ xfs_bmbt_split(
        xfs_btree_cur_t         *cur,
        int                     level,
        xfs_fsblock_t           *bnop,
-       xfs_bmbt_key_t          *keyp,
+       __uint64_t              *startoff,
        xfs_btree_cur_t         **curp,
        int                     *stat)          /* success/failure */
 {
@@ -1560,7 +1552,7 @@ xfs_bmbt_split(
        xfs_bmbt_rec_t          *rrp;           /* right record pointer */
 
        XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
-       XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp);
+       XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff);
        args.tp = cur->bc_tp;
        args.mp = cur->bc_mp;
        lbp = cur->bc_bufs[level];
@@ -1619,7 +1611,7 @@ xfs_bmbt_split(
                rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
 #ifdef DEBUG
                for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
-                       if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) {
+                       if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) {
                                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                                return error;
                        }
@@ -1629,13 +1621,13 @@ xfs_bmbt_split(
                memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
                xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
                xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
-               keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT);
+               *startoff = be64_to_cpu(rkp->br_startoff);
        } else {
                lrp = XFS_BMAP_REC_IADDR(left, i, cur);
                rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
                memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
                xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
-               keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp);
+               *startoff = xfs_bmbt_disk_get_startoff(rrp);
        }
        be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
        right->bb_rightsib = left->bb_rightsib;
@@ -1728,9 +1720,9 @@ xfs_bmdr_to_bmbt(
 {
        int                     dmxr;
        xfs_bmbt_key_t          *fkp;
-       xfs_bmbt_ptr_t          *fpp;
+       __be64                  *fpp;
        xfs_bmbt_key_t          *tkp;
-       xfs_bmbt_ptr_t          *tpp;
+       __be64                  *tpp;
 
        rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
        rblock->bb_level = dblock->bb_level;
@@ -1745,7 +1737,7 @@ xfs_bmdr_to_bmbt(
        tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
        dmxr = be16_to_cpu(dblock->bb_numrecs);
        memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
-       memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
+       memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
 }
 
 /*
@@ -1805,7 +1797,7 @@ xfs_bmbt_decrement(
        tp = cur->bc_tp;
        mp = cur->bc_mp;
        for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
-               fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+               fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
                if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
                                XFS_BMAP_BTREE_REF))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -2135,7 +2127,7 @@ xfs_bmbt_increment(
        tp = cur->bc_tp;
        mp = cur->bc_mp;
        for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
-               fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+               fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
                if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
                                XFS_BMAP_BTREE_REF))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -2178,7 +2170,7 @@ xfs_bmbt_insert(
        level = 0;
        nbno = NULLFSBLOCK;
        xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
-       ncur = (xfs_btree_cur_t *)0;
+       ncur = NULL;
        pcur = cur;
        do {
                if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
@@ -2205,7 +2197,7 @@ xfs_bmbt_insert(
                }
                if (ncur) {
                        pcur = ncur;
-                       ncur = (xfs_btree_cur_t *)0;
+                       ncur = NULL;
                }
        } while (nbno != NULLFSBLOCK);
        XFS_BMBT_TRACE_CURSOR(cur, EXIT);
@@ -2356,12 +2348,12 @@ xfs_bmbt_newroot(
        args.firstblock = args.fsbno;
        if (args.fsbno == NULLFSBLOCK) {
 #ifdef DEBUG
-               if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
+               if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
 #endif
-               args.fsbno = INT_GET(*pp, ARCH_CONVERT);
+               args.fsbno = be64_to_cpu(*pp);
                args.type = XFS_ALLOCTYPE_START_BNO;
        } else
                args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2393,7 +2385,7 @@ xfs_bmbt_newroot(
        cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
 #ifdef DEBUG
        for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
-               if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
+               if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
                        XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                        return error;
                }
@@ -2401,13 +2393,12 @@ xfs_bmbt_newroot(
 #endif
        memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
 #ifdef DEBUG
-       if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno,
-                       level))) {
+       if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {
                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                return error;
        }
 #endif
-       INT_SET(*pp, ARCH_CONVERT, args.fsbno);
+       *pp = cpu_to_be64(args.fsbno);
        xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
                cur->bc_private.b.whichfork);
        xfs_btree_setbuf(cur, level, bp);
@@ -2681,9 +2672,9 @@ xfs_bmbt_to_bmdr(
 {
        int                     dmxr;
        xfs_bmbt_key_t          *fkp;
-       xfs_bmbt_ptr_t          *fpp;
+       __be64                  *fpp;
        xfs_bmbt_key_t          *tkp;
-       xfs_bmbt_ptr_t          *tpp;
+       __be64                  *tpp;
 
        ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
        ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
@@ -2698,7 +2689,7 @@ xfs_bmbt_to_bmdr(
        tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
        dmxr = be16_to_cpu(dblock->bb_numrecs);
        memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
-       memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
+       memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
 }
 
 /*
@@ -2740,7 +2731,7 @@ xfs_bmbt_update(
                XFS_BMBT_TRACE_CURSOR(cur, EXIT);
                return 0;
        }
-       INT_SET(key.br_startoff, ARCH_CONVERT, off);
+       key.br_startoff = cpu_to_be64(off);
        if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
                XFS_BMBT_TRACE_CURSOR(cur, ERROR);
                return error;
index 6478cfa0e5395054e35b6c9f75c686f7d6010ad2..49539de9525bc7aa71f93b553b734497c22748fb 100644 (file)
@@ -163,13 +163,14 @@ typedef struct xfs_bmbt_irec
 /*
  * Key structure for non-leaf levels of the tree.
  */
-typedef struct xfs_bmbt_key
-{
-       xfs_dfiloff_t   br_startoff;    /* starting file offset */
+typedef struct xfs_bmbt_key {
+       __be64          br_startoff;    /* starting file offset */
 } xfs_bmbt_key_t, xfs_bmdr_key_t;
 
-typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;   /* btree pointer type */
-                                       /* btree block header type */
+/* btree pointer type */
+typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
+
+/* btree block header type */
 typedef struct xfs_btree_lblock xfs_bmbt_block_t;
 
 #define XFS_BUF_TO_BMBT_BLOCK(bp)      ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
index ee2255bd65624051d63729ceddf4670b4ed9002f..aeb87ca69fcc2e12e3042d21994b3ddbdd41fe75 100644 (file)
@@ -161,7 +161,7 @@ xfs_btree_check_key(
 
                k1 = ak1;
                k2 = ak2;
-               ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT));
+               ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
                break;
            }
        case XFS_BTNUM_INO: {
@@ -170,7 +170,7 @@ xfs_btree_check_key(
 
                k1 = ak1;
                k2 = ak2;
-               ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT));
+               ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
                break;
            }
        default:
@@ -285,8 +285,8 @@ xfs_btree_check_rec(
 
                r1 = ar1;
                r2 = ar2;
-               ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <=
-                      INT_GET(r2->ir_startino, ARCH_CONVERT));
+               ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
+                      be32_to_cpu(r2->ir_startino));
                break;
            }
        default:
index 44f1bd98064a49d04916366c921db35dbf508493..892b06c542637219d46be0f67798fa0e545fd43d 100644 (file)
@@ -145,7 +145,7 @@ typedef struct xfs_btree_cur
        union {
                xfs_alloc_rec_incore_t  a;
                xfs_bmbt_irec_t         b;
-               xfs_inobt_rec_t         i;
+               xfs_inobt_rec_incore_t  i;
        }               bc_rec;         /* current insert/search record value */
        struct xfs_buf  *bc_bufs[XFS_BTREE_MAXLEVELS];  /* buf ptr per level */
        int             bc_ptrs[XFS_BTREE_MAXLEVELS];   /* key/record # */
@@ -243,6 +243,9 @@ xfs_btree_check_lptr(
        xfs_dfsbno_t            ptr,    /* btree block disk address */
        int                     level); /* btree block level */
 
+#define xfs_btree_check_lptr_disk(cur, ptr, level) \
+       xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
+
 /*
  * Checking routine: check that short form block header is ok.
  */
index a4aa53974f7650668204ea2ce22f93de28adfa9c..7a55c248ea706a405fa4eddd1fb8d80a5f0c4d0b 100644 (file)
@@ -234,7 +234,6 @@ xfs_buf_item_format(
        ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
               (bip->bli_flags & XFS_BLI_STALE));
        bp = bip->bli_buf;
-       ASSERT(XFS_BUF_BP_ISMAPPED(bp));
        vecp = log_vector;
 
        /*
@@ -627,25 +626,6 @@ xfs_buf_item_committed(
        return (lsn);
 }
 
-/*
- * This is called when the transaction holding the buffer is aborted.
- * Just behave as if the transaction had been cancelled. If we're shutting down
- * and have aborted this transaction, we'll trap this buffer when it tries to
- * get written out.
- */
-STATIC void
-xfs_buf_item_abort(
-       xfs_buf_log_item_t      *bip)
-{
-       xfs_buf_t       *bp;
-
-       bp = bip->bli_buf;
-       xfs_buftrace("XFS_ABORT", bp);
-       XFS_BUF_SUPER_STALE(bp);
-       xfs_buf_item_unlock(bip);
-       return;
-}
-
 /*
  * This is called to asynchronously write the buffer associated with this
  * buf log item out to disk. The buffer will already have been locked by
@@ -693,7 +673,6 @@ STATIC struct xfs_item_ops xfs_buf_item_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_buf_item_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_buf_item_abort,
        .iop_pushbuf    = NULL,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_buf_item_committing
@@ -901,7 +880,6 @@ xfs_buf_item_relse(
        XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list);
        if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) &&
            (XFS_BUF_IODONE_FUNC(bp) != NULL)) {
-               ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0);
                XFS_BUF_CLR_IODONE_FUNC(bp);
        }
 
index 32ab61d17acefdeab2683925b65b806e556f7d5d..a68bc1f1a313c8862106adedf30ef84d65b92cd8 100644 (file)
@@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
        xfs_da_node_entry_t *btree;
        xfs_dablk_t blkno;
        int probe, span, max, error, retval;
-       xfs_dahash_t hashval;
+       xfs_dahash_t hashval, btreehashval;
        xfs_da_args_t *args;
 
        args = state->args;
@@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
                        return(error);
                }
                curr = blk->bp->data;
-               ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
-                      be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
-                      be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
+               blk->magic = be16_to_cpu(curr->magic);
+               ASSERT(blk->magic == XFS_DA_NODE_MAGIC ||
+                      blk->magic == XFS_DIR2_LEAFN_MAGIC ||
+                      blk->magic == XFS_ATTR_LEAF_MAGIC);
 
                /*
                 * Search an intermediate node for a match.
                 */
-               blk->magic = be16_to_cpu(curr->magic);
                if (blk->magic == XFS_DA_NODE_MAGIC) {
                        node = blk->bp->data;
-                       blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
+                       max = be16_to_cpu(node->hdr.count);
+                       btreehashval = node->btree[max-1].hashval;
+                       blk->hashval = be32_to_cpu(btreehashval);
 
                        /*
                         * Binary search.  (note: small blocks will skip loop)
                         */
-                       max = be16_to_cpu(node->hdr.count);
                        probe = span = max / 2;
                        hashval = args->hashval;
                        for (btree = &node->btree[probe]; span > 4;
                                   btree = &node->btree[probe]) {
                                span /= 2;
-                               if (be32_to_cpu(btree->hashval) < hashval)
+                               btreehashval = be32_to_cpu(btree->hashval);
+                               if (btreehashval < hashval)
                                        probe += span;
-                               else if (be32_to_cpu(btree->hashval) > hashval)
+                               else if (btreehashval > hashval)
                                        probe -= span;
                                else
                                        break;
@@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
                                blk->index = probe;
                                blkno = be32_to_cpu(btree->before);
                        }
-               } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
+               } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
                        blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
                        break;
-               } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
+               } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
                        blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
                        break;
                }
@@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
                if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
                        retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
                                                        &blk->index, state);
-               }
-               else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
+               } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
                        retval = xfs_attr_leaf_lookup_int(blk->bp, args);
                        blk->index = args->index;
                        args->blkno = blk->blkno;
+               } else {
+                       ASSERT(0);
+                       return XFS_ERROR(EFSCORRUPTED);
                }
                if (((retval == ENOENT) || (retval == ENOATTR)) &&
                    (blk->hashval == args->hashval)) {
@@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
                                return(error);
                        if (retval == 0) {
                                continue;
-                       }
-                       else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
+                       } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
                                /* path_shift() gives ENOENT */
                                retval = XFS_ERROR(ENOATTR);
                        }
index bc43163456ef854ae2820a25af87e3a146d73cc9..0893e16b7d834a20a7cf9ef96189336fabcbaa90 100644 (file)
 #ifndef        __XFS_ERROR_H__
 #define        __XFS_ERROR_H__
 
-#define XFS_ERECOVER   1       /* Failure to recover log */
-#define XFS_ELOGSTAT   2       /* Failure to stat log in user space */
-#define XFS_ENOLOGSPACE        3       /* Reservation too large */
-#define XFS_ENOTSUP    4       /* Operation not supported */
-#define        XFS_ENOLSN      5       /* Can't find the lsn you asked for */
-#define XFS_ENOTFOUND  6
-#define XFS_ENOTXFS    7       /* Not XFS filesystem */
-
 #ifdef DEBUG
 #define        XFS_ERROR_NTRAP 10
 extern int     xfs_etrap[XFS_ERROR_NTRAP];
@@ -175,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
 #define                XFS_PTAG_SHUTDOWN_CORRUPT       0x00000010
 #define                XFS_PTAG_SHUTDOWN_IOERROR       0x00000020
 #define                XFS_PTAG_SHUTDOWN_LOGERROR      0x00000040
+#define                XFS_PTAG_FSBLOCK_ZERO           0x00000080
 
 struct xfs_mount;
 /* PRINTFLIKE4 */
index 6cf6d8769b975902c290a4485372b9b507793aa1..6dba78199faf54e40fcc36fcdf9a61cbe865b436 100644 (file)
@@ -33,9 +33,6 @@ kmem_zone_t   *xfs_efi_zone;
 kmem_zone_t    *xfs_efd_zone;
 
 STATIC void    xfs_efi_item_unlock(xfs_efi_log_item_t *);
-STATIC void    xfs_efi_item_abort(xfs_efi_log_item_t *);
-STATIC void    xfs_efd_item_abort(xfs_efd_log_item_t *);
-
 
 void
 xfs_efi_item_free(xfs_efi_log_item_t *efip)
@@ -184,7 +181,7 @@ STATIC void
 xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
 {
        if (efip->efi_item.li_flags & XFS_LI_ABORTED)
-               xfs_efi_item_abort(efip);
+               xfs_efi_item_free(efip);
        return;
 }
 
@@ -201,18 +198,6 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
        return lsn;
 }
 
-/*
- * This is called when the transaction logging the EFI is aborted.
- * Free up the EFI and return.  No need to clean up the slot for
- * the item in the transaction.  That was done by the unpin code
- * which is called prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efi_item_abort(xfs_efi_log_item_t *efip)
-{
-       xfs_efi_item_free(efip);
-}
-
 /*
  * There isn't much you can do to push on an efi item.  It is simply
  * stuck waiting for all of its corresponding efd items to be
@@ -255,7 +240,6 @@ STATIC struct xfs_item_ops xfs_efi_item_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_efi_item_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_efi_item_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_efi_item_abort,
        .iop_pushbuf    = NULL,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_efi_item_committing
@@ -386,33 +370,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
        }
 }
 
-/*
- * This is called when the transaction that should be committing the
- * EFD corresponding to the given EFI is aborted.  The committed and
- * canceled flags are used to coordinate the freeing of the EFI and
- * the references by the transaction that committed it.
- */
-STATIC void
-xfs_efi_cancel(
-       xfs_efi_log_item_t      *efip)
-{
-       xfs_mount_t     *mp;
-       SPLDECL(s);
-
-       mp = efip->efi_item.li_mountp;
-       AIL_LOCK(mp, s);
-       if (efip->efi_flags & XFS_EFI_COMMITTED) {
-               /*
-                * xfs_trans_delete_ail() drops the AIL lock.
-                */
-               xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
-               xfs_efi_item_free(efip);
-       } else {
-               efip->efi_flags |= XFS_EFI_CANCELED;
-               AIL_UNLOCK(mp, s);
-       }
-}
-
 STATIC void
 xfs_efd_item_free(xfs_efd_log_item_t *efdp)
 {
@@ -514,7 +471,7 @@ STATIC void
 xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
 {
        if (efdp->efd_item.li_flags & XFS_LI_ABORTED)
-               xfs_efd_item_abort(efdp);
+               xfs_efd_item_free(efdp);
        return;
 }
 
@@ -540,27 +497,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
        return (xfs_lsn_t)-1;
 }
 
-/*
- * The transaction of which this EFD is a part has been aborted.
- * Inform its companion EFI of this fact and then clean up after
- * ourselves.  No need to clean up the slot for the item in the
- * transaction.  That was done by the unpin code which is called
- * prior to this routine in the abort/fs-shutdown path.
- */
-STATIC void
-xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
-{
-       /*
-        * If we got a log I/O error, it's always the case that the LR with the
-        * EFI got unpinned and freed before the EFD got aborted. So don't
-        * reference the EFI at all in that case.
-        */
-       if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
-               xfs_efi_cancel(efdp->efd_efip);
-
-       xfs_efd_item_free(efdp);
-}
-
 /*
  * There isn't much you can do to push on an efd item.  It is simply
  * stuck waiting for the log to be flushed to disk.
@@ -602,7 +538,6 @@ STATIC struct xfs_item_ops xfs_efd_item_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_efd_item_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_efd_item_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_efd_item_abort,
        .iop_pushbuf    = NULL,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_efd_item_committing
index 0ea45edaab033b31ba258b2cc39c3f48634f0d70..2f049f63e85f73ea3ae1763c5eb66e6798368635 100644 (file)
@@ -33,14 +33,16 @@ typedef struct xfs_extent {
  * conversion routine.
  */
 
+#ifndef HAVE_FORMAT32
 typedef struct xfs_extent_32 {
-       xfs_dfsbno_t    ext_start;
-       xfs_extlen_t    ext_len;
+       __uint64_t      ext_start;
+       __uint32_t      ext_len;
 } __attribute__((packed)) xfs_extent_32_t;
+#endif
 
 typedef struct xfs_extent_64 {
-       xfs_dfsbno_t    ext_start;
-       xfs_extlen_t    ext_len;
+       __uint64_t      ext_start;
+       __uint32_t      ext_len;
        __uint32_t      ext_pad;
 } xfs_extent_64_t;
 
@@ -50,25 +52,27 @@ typedef struct xfs_extent_64 {
  * size is given by efi_nextents.
  */
 typedef struct xfs_efi_log_format {
-       unsigned short          efi_type;       /* efi log item type */
-       unsigned short          efi_size;       /* size of this item */
-       uint                    efi_nextents;   /* # extents to free */
+       __uint16_t              efi_type;       /* efi log item type */
+       __uint16_t              efi_size;       /* size of this item */
+       __uint32_t              efi_nextents;   /* # extents to free */
        __uint64_t              efi_id;         /* efi identifier */
        xfs_extent_t            efi_extents[1]; /* array of extents to free */
 } xfs_efi_log_format_t;
 
+#ifndef HAVE_FORMAT32
 typedef struct xfs_efi_log_format_32 {
-       unsigned short          efi_type;       /* efi log item type */
-       unsigned short          efi_size;       /* size of this item */
-       uint                    efi_nextents;   /* # extents to free */
+       __uint16_t              efi_type;       /* efi log item type */
+       __uint16_t              efi_size;       /* size of this item */
+       __uint32_t              efi_nextents;   /* # extents to free */
        __uint64_t              efi_id;         /* efi identifier */
        xfs_extent_32_t         efi_extents[1]; /* array of extents to free */
 } __attribute__((packed)) xfs_efi_log_format_32_t;
+#endif
 
 typedef struct xfs_efi_log_format_64 {
-       unsigned short          efi_type;       /* efi log item type */
-       unsigned short          efi_size;       /* size of this item */
-       uint                    efi_nextents;   /* # extents to free */
+       __uint16_t              efi_type;       /* efi log item type */
+       __uint16_t              efi_size;       /* size of this item */
+       __uint32_t              efi_nextents;   /* # extents to free */
        __uint64_t              efi_id;         /* efi identifier */
        xfs_extent_64_t         efi_extents[1]; /* array of extents to free */
 } xfs_efi_log_format_64_t;
@@ -79,25 +83,27 @@ typedef struct xfs_efi_log_format_64 {
  * size is given by efd_nextents;
  */
 typedef struct xfs_efd_log_format {
-       unsigned short          efd_type;       /* efd log item type */
-       unsigned short          efd_size;       /* size of this item */
-       uint                    efd_nextents;   /* # of extents freed */
+       __uint16_t              efd_type;       /* efd log item type */
+       __uint16_t              efd_size;       /* size of this item */
+       __uint32_t              efd_nextents;   /* # of extents freed */
        __uint64_t              efd_efi_id;     /* id of corresponding efi */
        xfs_extent_t            efd_extents[1]; /* array of extents freed */
 } xfs_efd_log_format_t;
 
+#ifndef HAVE_FORMAT32
 typedef struct xfs_efd_log_format_32 {
-       unsigned short          efd_type;       /* efd log item type */
-       unsigned short          efd_size;       /* size of this item */
-       uint                    efd_nextents;   /* # of extents freed */
+       __uint16_t              efd_type;       /* efd log item type */
+       __uint16_t              efd_size;       /* size of this item */
+       __uint32_t              efd_nextents;   /* # of extents freed */
        __uint64_t              efd_efi_id;     /* id of corresponding efi */
        xfs_extent_32_t         efd_extents[1]; /* array of extents freed */
 } __attribute__((packed)) xfs_efd_log_format_32_t;
+#endif
 
 typedef struct xfs_efd_log_format_64 {
-       unsigned short          efd_type;       /* efd log item type */
-       unsigned short          efd_size;       /* size of this item */
-       uint                    efd_nextents;   /* # of extents freed */
+       __uint16_t              efd_type;       /* efd log item type */
+       __uint16_t              efd_size;       /* size of this item */
+       __uint32_t              efd_nextents;   /* # of extents freed */
        __uint64_t              efd_efi_id;     /* id of corresponding efi */
        xfs_extent_64_t         efd_extents[1]; /* array of extents freed */
 } xfs_efd_log_format_64_t;
index 0f0ad1535951c8b137278d5bf4c994910adfa8bf..1335449841cdc1ecc77d2bc8c47ba32c91148993 100644 (file)
@@ -22,8 +22,6 @@
  * SGI's XFS filesystem's major stuff (constants, structures)
  */
 
-#define XFS_NAME       "xfs"
-
 /*
  * Direct I/O attribute record used with XFS_IOC_DIOINFO
  * d_miniosz is the min xfer size, xfer size multiple and file seek offset
@@ -426,11 +424,7 @@ typedef struct xfs_handle {
                                 - (char *) &(handle))                    \
                                 + (handle).ha_fid.xfs_fid_len)
 
-#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t))
-
-#define FSHSIZE                sizeof(fsid_t)
-
-/* 
+/*
  * Flags for going down operation
  */
 #define XFS_FSOP_GOING_FLAGS_DEFAULT           0x0     /* going down */
index 33164a85aa9df4c3912a31157c9b8eddc5991f0c..a446e5a115c6bad4f60ece30a66d325f7da6a41f 100644 (file)
@@ -458,7 +458,7 @@ nextag:
                 */
                if (XFS_FORCED_SHUTDOWN(mp)) {
                        up_read(&mp->m_peraglock);
-                       return (xfs_buf_t *)0;
+                       return NULL;
                }
                agno++;
                if (agno >= agcount)
@@ -466,7 +466,7 @@ nextag:
                if (agno == pagno) {
                        if (flags == 0) {
                                up_read(&mp->m_peraglock);
-                               return (xfs_buf_t *)0;
+                               return NULL;
                        }
                        flags = 0;
                }
@@ -529,10 +529,10 @@ xfs_dialloc(
        int             offset;         /* index of inode in chunk */
        xfs_agino_t     pagino;         /* parent's a.g. relative inode # */
        xfs_agnumber_t  pagno;          /* parent's allocation group number */
-       xfs_inobt_rec_t rec;            /* inode allocation record */
+       xfs_inobt_rec_incore_t rec;     /* inode allocation record */
        xfs_agnumber_t  tagno;          /* testing allocation group number */
        xfs_btree_cur_t *tcur;          /* temp cursor */
-       xfs_inobt_rec_t trec;           /* temp inode allocation record */
+       xfs_inobt_rec_incore_t trec;    /* temp inode allocation record */
 
 
        if (*IO_agbp == NULL) {
@@ -945,7 +945,7 @@ xfs_difree(
        int             ilen;   /* inodes in an inode cluster */
        xfs_mount_t     *mp;    /* mount structure for filesystem */
        int             off;    /* offset of inode in inode chunk */
-       xfs_inobt_rec_t rec;    /* btree record */
+       xfs_inobt_rec_incore_t rec;     /* btree record */
 
        mp = tp->t_mountp;
 
@@ -1195,6 +1195,7 @@ xfs_dilocate(
                                        "(0x%llx)",
                                        ino, XFS_AGINO_TO_INO(mp, agno, agino));
                }
+               xfs_stack_trace();
 #endif /* DEBUG */
                return XFS_ERROR(EINVAL);
        }
index 616eeeb6953eb27e796102c7c0aa9b23092268a1..8cdeeaf8632b9bc7b1c5e5e19cf128908a91c2e3 100644 (file)
@@ -568,7 +568,7 @@ xfs_inobt_insrec(
        /*
         * Make a key out of the record data to be inserted, and save it.
         */
-       key.ir_startino = recp->ir_startino; /* INT_: direct copy */
+       key.ir_startino = recp->ir_startino;
        optr = ptr = cur->bc_ptrs[level];
        /*
         * If we're off the left edge, return failure.
@@ -600,7 +600,7 @@ xfs_inobt_insrec(
        }
 #endif
        nbno = NULLAGBLOCK;
-       ncur = (xfs_btree_cur_t *)0;
+       ncur = NULL;
        /*
         * If the block is full, we can't insert the new entry until we
         * make the block un-full.
@@ -641,7 +641,7 @@ xfs_inobt_insrec(
                                                return error;
 #endif
                                        ptr = cur->bc_ptrs[level];
-                                       nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */
+                                       nrec.ir_startino = nkey.ir_startino;
                                } else {
                                        /*
                                         * Otherwise the insert fails.
@@ -681,7 +681,7 @@ xfs_inobt_insrec(
                if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
                        return error;
 #endif
-               kp[ptr - 1] = key; /* INT_: struct copy */
+               kp[ptr - 1] = key;
                pp[ptr - 1] = cpu_to_be32(*bnop);
                numrecs++;
                block->bb_numrecs = cpu_to_be16(numrecs);
@@ -698,7 +698,7 @@ xfs_inobt_insrec(
                 * Now stuff the new record in, bump numrecs
                 * and log the new data.
                 */
-               rp[ptr - 1] = *recp; /* INT_: struct copy */
+               rp[ptr - 1] = *recp;
                numrecs++;
                block->bb_numrecs = cpu_to_be16(numrecs);
                xfs_inobt_log_recs(cur, bp, ptr, numrecs);
@@ -731,7 +731,7 @@ xfs_inobt_insrec(
         */
        *bnop = nbno;
        if (nbno != NULLAGBLOCK) {
-               *recp = nrec; /* INT_: struct copy */
+               *recp = nrec;
                *curp = ncur;
        }
        *stat = 1;
@@ -878,7 +878,7 @@ xfs_inobt_lookup(
                 */
                bp = cur->bc_bufs[level];
                if (bp && XFS_BUF_ADDR(bp) != d)
-                       bp = (xfs_buf_t *)0;
+                       bp = NULL;
                if (!bp) {
                        /*
                         * Need to get a new buffer.  Read it, then
@@ -950,12 +950,12 @@ xfs_inobt_lookup(
                                        xfs_inobt_key_t *kkp;
 
                                        kkp = kkbase + keyno - 1;
-                                       startino = INT_GET(kkp->ir_startino, ARCH_CONVERT);
+                                       startino = be32_to_cpu(kkp->ir_startino);
                                } else {
                                        xfs_inobt_rec_t *krp;
 
                                        krp = krbase + keyno - 1;
-                                       startino = INT_GET(krp->ir_startino, ARCH_CONVERT);
+                                       startino = be32_to_cpu(krp->ir_startino);
                                }
                                /*
                                 * Compute difference to get next direction.
@@ -1117,7 +1117,7 @@ xfs_inobt_lshift(
                if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
                        return error;
 #endif
-               *lpp = *rpp; /* INT_: no-change copy */
+               *lpp = *rpp;
                xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
        }
        /*
@@ -1160,7 +1160,7 @@ xfs_inobt_lshift(
        } else {
                memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
                xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
-               key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
+               key.ir_startino = rrp->ir_startino;
                rkp = &key;
        }
        /*
@@ -1297,13 +1297,13 @@ xfs_inobt_newroot(
         */
        kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
        if (be16_to_cpu(left->bb_level) > 0) {
-               kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */
-               kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */
+               kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
+               kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
        } else {
                rp = XFS_INOBT_REC_ADDR(left, 1, cur);
-               INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT);
+               kp[0].ir_startino = rp->ir_startino;
                rp = XFS_INOBT_REC_ADDR(right, 1, cur);
-               INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT);
+               kp[1].ir_startino = rp->ir_startino;
        }
        xfs_inobt_log_keys(cur, nbp, 1, 2);
        /*
@@ -1410,8 +1410,8 @@ xfs_inobt_rshift(
                if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
                        return error;
 #endif
-               *rkp = *lkp; /* INT_: no change copy */
-               *rpp = *lpp; /* INT_: no change copy */
+               *rkp = *lkp;
+               *rpp = *lpp;
                xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
                xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
        } else {
@@ -1420,7 +1420,7 @@ xfs_inobt_rshift(
                memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
                *rrp = *lrp;
                xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
-               key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
+               key.ir_startino = rrp->ir_startino;
                rkp = &key;
        }
        /*
@@ -1559,7 +1559,7 @@ xfs_inobt_split(
                rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
                memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
                xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
-               keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */
+               keyp->ir_startino = rrp->ir_startino;
        }
        /*
         * Find the left block number by looking in the buffer.
@@ -1813,9 +1813,9 @@ xfs_inobt_get_rec(
         * Point to the record and extract its data.
         */
        rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
-       *ino = INT_GET(rec->ir_startino, ARCH_CONVERT);
-       *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT);
-       *free = INT_GET(rec->ir_free, ARCH_CONVERT);
+       *ino = be32_to_cpu(rec->ir_startino);
+       *fcnt = be32_to_cpu(rec->ir_freecount);
+       *free = be64_to_cpu(rec->ir_free);
        *stat = 1;
        return 0;
 }
@@ -1930,10 +1930,10 @@ xfs_inobt_insert(
 
        level = 0;
        nbno = NULLAGBLOCK;
-       INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino);
-       INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount);
-       INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free);
-       ncur = (xfs_btree_cur_t *)0;
+       nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
+       nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
+       nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
+       ncur = NULL;
        pcur = cur;
        /*
         * Loop going up the tree, starting at the leaf level.
@@ -1965,7 +1965,7 @@ xfs_inobt_insert(
                 */
                if (ncur) {
                        pcur = ncur;
-                       ncur = (xfs_btree_cur_t *)0;
+                       ncur = NULL;
                }
        } while (nbno != NULLAGBLOCK);
        *stat = i;
@@ -2060,9 +2060,9 @@ xfs_inobt_update(
        /*
         * Fill in the new contents and log them.
         */
-       INT_SET(rp->ir_startino, ARCH_CONVERT, ino);
-       INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt);
-       INT_SET(rp->ir_free, ARCH_CONVERT, free);
+       rp->ir_startino = cpu_to_be32(ino);
+       rp->ir_freecount = cpu_to_be32(fcnt);
+       rp->ir_free = cpu_to_be64(free);
        xfs_inobt_log_recs(cur, bp, ptr, ptr);
        /*
         * Updating first record in leaf. Pass new key value up to our parent.
@@ -2070,7 +2070,7 @@ xfs_inobt_update(
        if (ptr == 1) {
                xfs_inobt_key_t key;    /* key containing [ino] */
 
-               INT_SET(key.ir_startino, ARCH_CONVERT, ino);
+               key.ir_startino = cpu_to_be32(ino);
                if ((error = xfs_inobt_updkey(cur, &key, 1)))
                        return error;
        }
index ae3904cb1ee814caaf172f2a9efc8273c216b6f6..2c0e49893ff72731a06d51f81ea216b061014fd7 100644 (file)
@@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
 /*
  * Data record structure
  */
-typedef struct xfs_inobt_rec
-{
+typedef struct xfs_inobt_rec {
+       __be32          ir_startino;    /* starting inode number */
+       __be32          ir_freecount;   /* count of free inodes (set bits) */
+       __be64          ir_free;        /* free inode mask */
+} xfs_inobt_rec_t;
+
+typedef struct xfs_inobt_rec_incore {
        xfs_agino_t     ir_startino;    /* starting inode number */
        __int32_t       ir_freecount;   /* count of free inodes (set bits) */
        xfs_inofree_t   ir_free;        /* free inode mask */
-} xfs_inobt_rec_t;
+} xfs_inobt_rec_incore_t;
+
 
 /*
  * Key structure
  */
-typedef struct xfs_inobt_key
-{
-       xfs_agino_t     ir_startino;    /* starting inode number */
+typedef struct xfs_inobt_key {
+       __be32          ir_startino;    /* starting inode number */
 } xfs_inobt_key_t;
 
 /* btree pointer type */
@@ -77,7 +82,7 @@ typedef       struct xfs_btree_sblock xfs_inobt_block_t;
 #define        XFS_INOBT_IS_FREE(rp,i)         \
                (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
 #define        XFS_INOBT_IS_FREE_DISK(rp,i)    \
-               ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
+               ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0)
 #define        XFS_INOBT_SET_FREE(rp,i)        ((rp)->ir_free |= XFS_INOBT_MASK(i))
 #define        XFS_INOBT_CLR_FREE(rp,i)        ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
 
index 0724df7fabb755fea973ca3ac87176b4e4c24e93..b73d216ecaf939aa4df49f8a89a6cff9e2fafd16 100644 (file)
@@ -50,7 +50,7 @@ void
 xfs_ihash_init(xfs_mount_t *mp)
 {
        __uint64_t      icount;
-       uint            i, flags = KM_SLEEP | KM_MAYFAIL;
+       uint            i;
 
        if (!mp->m_ihsize) {
                icount = mp->m_maxicount ? mp->m_maxicount :
@@ -61,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp)
                                        (64 * NBPP) / sizeof(xfs_ihash_t));
        }
 
-       while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
-                                               sizeof(xfs_ihash_t), flags))) {
-               if ((mp->m_ihsize >>= 1) <= NBPP)
-                       flags = KM_SLEEP;
-       }
-       for (i = 0; i < mp->m_ihsize; i++) {
+       mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
+                                        NBPC * sizeof(xfs_ihash_t),
+                                        mp->m_ihsize * sizeof(xfs_ihash_t),
+                                        KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+       mp->m_ihsize /= sizeof(xfs_ihash_t);
+       for (i = 0; i < mp->m_ihsize; i++)
                rwlock_init(&(mp->m_ihash[i].ih_lock));
-       }
 }
 
 /*
@@ -77,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp)
 void
 xfs_ihash_free(xfs_mount_t *mp)
 {
-       kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t));
+       kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
        mp->m_ihash = NULL;
 }
 
@@ -95,7 +94,7 @@ xfs_chash_init(xfs_mount_t *mp)
        mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
        mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
                                                 * sizeof(xfs_chash_t),
-                                                KM_SLEEP);
+                                                KM_SLEEP | KM_LARGE);
        for (i = 0; i < mp->m_chsize; i++) {
                spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
        }
@@ -244,7 +243,9 @@ again:
 
                                XFS_STATS_INC(xs_ig_found);
 
+                               spin_lock(&ip->i_flags_lock);
                                ip->i_flags &= ~XFS_IRECLAIMABLE;
+                               spin_unlock(&ip->i_flags_lock);
                                version = ih->ih_version;
                                read_unlock(&ih->ih_lock);
                                xfs_ihash_promote(ih, ip, version);
@@ -290,15 +291,17 @@ again:
 
 finish_inode:
                        if (ip->i_d.di_mode == 0) {
-                               if (!(flags & IGET_CREATE))
+                               if (!(flags & XFS_IGET_CREATE))
                                        return ENOENT;
                                xfs_iocore_inode_reinit(ip);
                        }
-       
+
                        if (lock_flags != 0)
                                xfs_ilock(ip, lock_flags);
 
+                       spin_lock(&ip->i_flags_lock);
                        ip->i_flags &= ~XFS_ISTALE;
+                       spin_unlock(&ip->i_flags_lock);
 
                        vn_trace_exit(vp, "xfs_iget.found",
                                                (inst_t *)__return_address);
@@ -320,21 +323,20 @@ finish_inode:
         * Read the disk inode attributes into a new inode structure and get
         * a new vnode for it. This should also initialize i_ino and i_mount.
         */
-       error = xfs_iread(mp, tp, ino, &ip, bno);
-       if (error) {
+       error = xfs_iread(mp, tp, ino, &ip, bno,
+                         (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
+       if (error)
                return error;
-       }
 
        vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
 
        xfs_inode_lock_init(ip, vp);
        xfs_iocore_inode_init(ip);
 
-       if (lock_flags != 0) {
+       if (lock_flags)
                xfs_ilock(ip, lock_flags);
-       }
-               
-       if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
+
+       if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
                xfs_idestroy(ip);
                return ENOENT;
        }
@@ -369,7 +371,9 @@ finish_inode:
        ih->ih_next = ip;
        ip->i_udquot = ip->i_gdquot = NULL;
        ih->ih_version++;
+       spin_lock(&ip->i_flags_lock);
        ip->i_flags |= XFS_INEW;
+       spin_unlock(&ip->i_flags_lock);
 
        write_unlock(&ih->ih_lock);
 
@@ -548,7 +552,7 @@ xfs_inode_lock_init(
        mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
        init_waitqueue_head(&ip->i_ipin_wait);
        atomic_set(&ip->i_pincount, 0);
-       init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number);
+       initnsema(&ip->i_flock, 1, "xfsfino");
 }
 
 /*
index 1f8ecff8553a3b205525d3998abc0968f25bd2e5..c27d7d495aa0f498ade09aa6a5db5a67a8fa01ce 100644 (file)
@@ -854,7 +854,8 @@ xfs_iread(
        xfs_trans_t     *tp,
        xfs_ino_t       ino,
        xfs_inode_t     **ipp,
-       xfs_daddr_t     bno)
+       xfs_daddr_t     bno,
+       uint            imap_flags)
 {
        xfs_buf_t       *bp;
        xfs_dinode_t    *dip;
@@ -866,6 +867,7 @@ xfs_iread(
        ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
        ip->i_ino = ino;
        ip->i_mount = mp;
+       spin_lock_init(&ip->i_flags_lock);
 
        /*
         * Get pointer's to the on-disk inode and the buffer containing it.
@@ -874,7 +876,7 @@ xfs_iread(
         * return NULL as well.  Set i_blkno to 0 so that xfs_itobp() will
         * know that this is a new incore inode.
         */
-       error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0);
+       error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags);
        if (error) {
                kmem_zone_free(xfs_inode_zone, ip);
                return error;
@@ -1113,7 +1115,7 @@ xfs_ialloc(
         * to prevent others from looking at until we're done.
         */
        error = xfs_trans_iget(tp->t_mountp, tp, ino,
-                       IGET_CREATE, XFS_ILOCK_EXCL, &ip);
+                               XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
        if (error != 0) {
                return error;
        }
@@ -2213,7 +2215,9 @@ xfs_ifree_cluster(
 
                        if (ip == free_ip) {
                                if (xfs_iflock_nowait(ip)) {
+                                       spin_lock(&ip->i_flags_lock);
                                        ip->i_flags |= XFS_ISTALE;
+                                       spin_unlock(&ip->i_flags_lock);
 
                                        if (xfs_inode_clean(ip)) {
                                                xfs_ifunlock(ip);
@@ -2227,7 +2231,9 @@ xfs_ifree_cluster(
 
                        if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
                                if (xfs_iflock_nowait(ip)) {
+                                       spin_lock(&ip->i_flags_lock);
                                        ip->i_flags |= XFS_ISTALE;
+                                       spin_unlock(&ip->i_flags_lock);
 
                                        if (xfs_inode_clean(ip)) {
                                                xfs_ifunlock(ip);
@@ -2257,7 +2263,9 @@ xfs_ifree_cluster(
                                AIL_LOCK(mp,s);
                                iip->ili_flush_lsn = iip->ili_item.li_lsn;
                                AIL_UNLOCK(mp, s);
+                               spin_lock(&iip->ili_inode->i_flags_lock);
                                iip->ili_inode->i_flags |= XFS_ISTALE;
+                               spin_unlock(&iip->ili_inode->i_flags_lock);
                                pre_flushed++;
                        }
                        lip = lip->li_bio_list;
@@ -2753,19 +2761,29 @@ xfs_iunpin(
                 * call as the inode reclaim may be blocked waiting for
                 * the inode to become unpinned.
                 */
+               struct inode *inode = NULL;
+
+               spin_lock(&ip->i_flags_lock);
                if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
                        bhv_vnode_t     *vp = XFS_ITOV_NULL(ip);
 
                        /* make sync come back and flush this inode */
                        if (vp) {
-                               struct inode    *inode = vn_to_inode(vp);
+                               inode = vn_to_inode(vp);
 
                                if (!(inode->i_state &
-                                               (I_NEW|I_FREEING|I_CLEAR)))
-                                       mark_inode_dirty_sync(inode);
+                                               (I_NEW|I_FREEING|I_CLEAR))) {
+                                       inode = igrab(inode);
+                                       if (inode)
+                                               mark_inode_dirty_sync(inode);
+                               } else
+                                       inode = NULL;
                        }
                }
+               spin_unlock(&ip->i_flags_lock);
                wake_up(&ip->i_ipin_wait);
+               if (inode)
+                       iput(inode);
        }
 }
 
index d10b76ed1e5bd0c6f99689998f5a342a12939bad..e96eb0835fe658a9a2ba8df257eb94a1f130a15d 100644 (file)
@@ -267,6 +267,7 @@ typedef struct xfs_inode {
        sema_t                  i_flock;        /* inode flush lock */
        atomic_t                i_pincount;     /* inode pin count */
        wait_queue_head_t       i_ipin_wait;    /* inode pinning wait queue */
+       spinlock_t              i_flags_lock;   /* inode i_flags lock */
 #ifdef HAVE_REFCACHE
        struct xfs_inode        **i_refcache;   /* ptr to entry in ref cache */
        struct xfs_inode        *i_release;     /* inode to unref */
@@ -389,11 +390,14 @@ typedef struct xfs_inode {
        (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
 
 /*
- * xfs_iget.c prototypes.
+ * Flags for xfs_iget()
  */
+#define XFS_IGET_CREATE                0x1
+#define XFS_IGET_BULKSTAT      0x2
 
-#define IGET_CREATE    1
-
+/*
+ * xfs_iget.c prototypes.
+ */
 void           xfs_ihash_init(struct xfs_mount *);
 void           xfs_ihash_free(struct xfs_mount *);
 void           xfs_chash_init(struct xfs_mount *);
@@ -425,7 +429,7 @@ int         xfs_itobp(struct xfs_mount *, struct xfs_trans *,
                          xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
                          xfs_daddr_t, uint);
 int            xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-                         xfs_inode_t **, xfs_daddr_t);
+                         xfs_inode_t **, xfs_daddr_t, uint);
 int            xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
 int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
                           xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
index f8e80d8e72370ff12bfa66686256b7641f7ca7cc..a7a92251eb564d84c3898d407b01b04baf7c673f 100644 (file)
@@ -742,21 +742,6 @@ xfs_inode_item_committed(
        return (lsn);
 }
 
-/*
- * The transaction with the inode locked has aborted.  The inode
- * must not be dirty within the transaction (unless we're forcibly
- * shutting down).  We simply unlock just as if the transaction
- * had been cancelled.
- */
-STATIC void
-xfs_inode_item_abort(
-       xfs_inode_log_item_t    *iip)
-{
-       xfs_inode_item_unlock(iip);
-       return;
-}
-
-
 /*
  * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK
  * failed to get the inode flush lock but did get the inode locked SHARED.
@@ -915,7 +900,6 @@ STATIC struct xfs_item_ops xfs_inode_item_ops = {
        .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_inode_item_committed,
        .iop_push       = (void(*)(xfs_log_item_t*))xfs_inode_item_push,
-       .iop_abort      = (void(*)(xfs_log_item_t*))xfs_inode_item_abort,
        .iop_pushbuf    = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf,
        .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
                                        xfs_inode_item_committing
index 5db6cd1b4cf3278fec78975c7969492f96d67dde..bfe92ea17952a3764ffe284231ebb87120f38751 100644 (file)
  * must be added on to the end.
  */
 typedef struct xfs_inode_log_format {
-       unsigned short          ilf_type;       /* inode log item type */
-       unsigned short          ilf_size;       /* size of this item */
-       uint                    ilf_fields;     /* flags for fields logged */
-       ushort                  ilf_asize;      /* size of attr d/ext/root */
-       ushort                  ilf_dsize;      /* size of data/ext/root */
-       xfs_ino_t               ilf_ino;        /* inode number */
+       __uint16_t              ilf_type;       /* inode log item type */
+       __uint16_t              ilf_size;       /* size of this item */
+       __uint32_t              ilf_fields;     /* flags for fields logged */
+       __uint16_t              ilf_asize;      /* size of attr d/ext/root */
+       __uint16_t              ilf_dsize;      /* size of data/ext/root */
+       __uint64_t              ilf_ino;        /* inode number */
        union {
-               xfs_dev_t       ilfu_rdev;      /* rdev value for dev inode*/
+               __uint32_t      ilfu_rdev;      /* rdev value for dev inode*/
                uuid_t          ilfu_uuid;      /* mount point value */
        } ilf_u;
        __int64_t               ilf_blkno;      /* blkno of inode buffer */
-       int                     ilf_len;        /* len of inode buffer */
-       int                     ilf_boffset;    /* off of inode in buffer */
+       __int32_t               ilf_len;        /* len of inode buffer */
+       __int32_t               ilf_boffset;    /* off of inode in buffer */
 } xfs_inode_log_format_t;
 
+#ifndef HAVE_FORMAT32
 typedef struct xfs_inode_log_format_32 {
-       unsigned short          ilf_type;       /* 16: inode log item type */
-       unsigned short          ilf_size;       /* 16: size of this item */
-       uint                    ilf_fields;     /* 32: flags for fields logged */
-       ushort                  ilf_asize;      /* 32: size of attr d/ext/root */
-       ushort                  ilf_dsize;      /* 32: size of data/ext/root */
-       xfs_ino_t               ilf_ino;        /* 64: inode number */
+       __uint16_t              ilf_type;       /* inode log item type */
+       __uint16_t              ilf_size;       /* size of this item */
+       __uint32_t              ilf_fields;     /* flags for fields logged */
+       __uint16_t              ilf_asize;      /* size of attr d/ext/root */
+       __uint16_t              ilf_dsize;      /* size of data/ext/root */
+       __uint64_t              ilf_ino;        /* inode number */
        union {
-               xfs_dev_t       ilfu_rdev;      /* 32: rdev value for dev inode*/
-               uuid_t          ilfu_uuid;      /* 128: mount point value */
+               __uint32_t      ilfu_rdev;      /* rdev value for dev inode*/
+               uuid_t          ilfu_uuid;      /* mount point value */
        } ilf_u;
-       __int64_t               ilf_blkno;      /* 64: blkno of inode buffer */
-       int                     ilf_len;        /* 32: len of inode buffer */
-       int                     ilf_boffset;    /* 32: off of inode in buffer */
+       __int64_t               ilf_blkno;      /* blkno of inode buffer */
+       __int32_t               ilf_len;        /* len of inode buffer */
+       __int32_t               ilf_boffset;    /* off of inode in buffer */
 } __attribute__((packed)) xfs_inode_log_format_32_t;
+#endif
 
 typedef struct xfs_inode_log_format_64 {
-       unsigned short          ilf_type;       /* 16: inode log item type */
-       unsigned short          ilf_size;       /* 16: size of this item */
-       uint                    ilf_fields;     /* 32: flags for fields logged */
-       ushort                  ilf_asize;      /* 32: size of attr d/ext/root */
-       ushort                  ilf_dsize;      /* 32: size of data/ext/root */
-       __uint32_t              ilf_pad;        /* 32: pad for 64 bit boundary */
-       xfs_ino_t               ilf_ino;        /* 64: inode number */
+       __uint16_t              ilf_type;       /* inode log item type */
+       __uint16_t              ilf_size;       /* size of this item */
+       __uint32_t              ilf_fields;     /* flags for fields logged */
+       __uint16_t              ilf_asize;      /* size of attr d/ext/root */
+       __uint16_t              ilf_dsize;      /* size of data/ext/root */
+       __uint32_t              ilf_pad;        /* pad for 64 bit boundary */
+       __uint64_t              ilf_ino;        /* inode number */
        union {
-               xfs_dev_t       ilfu_rdev;      /* 32: rdev value for dev inode*/
-               uuid_t          ilfu_uuid;      /* 128: mount point value */
+               __uint32_t      ilfu_rdev;      /* rdev value for dev inode*/
+               uuid_t          ilfu_uuid;      /* mount point value */
        } ilf_u;
-       __int64_t               ilf_blkno;      /* 64: blkno of inode buffer */
-       int                     ilf_len;        /* 32: len of inode buffer */
-       int                     ilf_boffset;    /* 32: off of inode in buffer */
+       __int64_t               ilf_blkno;      /* blkno of inode buffer */
+       __int32_t               ilf_len;        /* len of inode buffer */
+       __int32_t               ilf_boffset;    /* off of inode in buffer */
 } xfs_inode_log_format_64_t;
 
 /*
index f1949c16df154157bbdada2882d2656ab918311f..19655124da782299a409eee8bb78ed26f676ceae 100644 (file)
@@ -398,6 +398,23 @@ xfs_flush_space(
        return 1;
 }
 
+STATIC int
+xfs_cmn_err_fsblock_zero(
+       xfs_inode_t     *ip,
+       xfs_bmbt_irec_t *imap)
+{
+       xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
+                       "Access to block zero in inode %llu "
+                       "start_block: %llx start_off: %llx "
+                       "blkcnt: %llx extent-state: %x\n",
+               (unsigned long long)ip->i_ino,
+               (unsigned long long)imap->br_startblock,
+               (unsigned long long)imap->br_startoff,
+               (unsigned long long)imap->br_blockcount,
+               imap->br_state);
+       return EFSCORRUPTED;
+}
+
 int
 xfs_iomap_write_direct(
        xfs_inode_t     *ip,
@@ -536,23 +553,17 @@ xfs_iomap_write_direct(
         * Copy any maps to caller's array and return any error.
         */
        if (nimaps == 0) {
-               error = (ENOSPC);
+               error = ENOSPC;
+               goto error_out;
+       }
+
+       if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) {
+               error = xfs_cmn_err_fsblock_zero(ip, &imap);
                goto error_out;
        }
 
        *ret_imap = imap;
        *nmaps = 1;
-       if ( !(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
-                cmn_err(CE_PANIC,"Access to block zero:  fs <%s> inode: %lld "
-                        "start_block : %llx start_off : %llx blkcnt : %llx "
-                        "extent-state : %x \n",
-                        (ip->i_mount)->m_fsname,
-                        (long long)ip->i_ino,
-                        (unsigned long long)ret_imap->br_startblock,
-                       (unsigned long long)ret_imap->br_startoff,
-                        (unsigned long long)ret_imap->br_blockcount,
-                       ret_imap->br_state);
-        }
        return 0;
 
 error0:        /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
@@ -715,17 +726,8 @@ retry:
                goto retry;
        }
 
-       if (!(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
-               cmn_err(CE_PANIC,"Access to block zero:  fs <%s> inode: %lld "
-                        "start_block : %llx start_off : %llx blkcnt : %llx "
-                        "extent-state : %x \n",
-                        (ip->i_mount)->m_fsname,
-                        (long long)ip->i_ino,
-                        (unsigned long long)ret_imap->br_startblock,
-                       (unsigned long long)ret_imap->br_startoff,
-                        (unsigned long long)ret_imap->br_blockcount,
-                       ret_imap->br_state);
-       }
+       if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT)))
+               return xfs_cmn_err_fsblock_zero(ip, &imap[0]);
 
        *ret_imap = imap[0];
        *nmaps = 1;
@@ -853,24 +855,10 @@ xfs_iomap_write_allocate(
                 * See if we were able to allocate an extent that
                 * covers at least part of the callers request
                 */
-
                for (i = 0; i < nimaps; i++) {
-                       if (!(io->io_flags & XFS_IOCORE_RT)  &&
-                           !imap[i].br_startblock) {
-                               cmn_err(CE_PANIC,"Access to block zero:  "
-                                       "fs <%s> inode: %lld "
-                                       "start_block : %llx start_off : %llx "
-                                       "blkcnt : %llx extent-state : %x \n",
-                                       (ip->i_mount)->m_fsname,
-                                       (long long)ip->i_ino,
-                                       (unsigned long long)
-                                               imap[i].br_startblock,
-                                       (unsigned long long)
-                                               imap[i].br_startoff,
-                                       (unsigned long long)
-                                               imap[i].br_blockcount,
-                                       imap[i].br_state);
-                        }
+                       if (unlikely(!imap[i].br_startblock &&
+                                    !(io->io_flags & XFS_IOCORE_RT)))
+                               return xfs_cmn_err_fsblock_zero(ip, &imap[i]);
                        if ((offset_fsb >= imap[i].br_startoff) &&
                            (offset_fsb < (imap[i].br_startoff +
                                           imap[i].br_blockcount))) {
@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten(
                                XFS_WRITE_LOG_COUNT);
                if (error) {
                        xfs_trans_cancel(tp, 0);
-                       goto error0;
+                       return XFS_ERROR(error);
                }
 
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten(
                error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                if (error)
-                       goto error0;
-
-               if ( !(io->io_flags & XFS_IOCORE_RT)  && !imap.br_startblock) {
-                       cmn_err(CE_PANIC,"Access to block zero:  fs <%s> "
-                               "inode: %lld start_block : %llx start_off : "
-                               "%llx blkcnt : %llx extent-state : %x \n",
-                               (ip->i_mount)->m_fsname,
-                               (long long)ip->i_ino,
-                               (unsigned long long)imap.br_startblock,
-                               (unsigned long long)imap.br_startoff,
-                               (unsigned long long)imap.br_blockcount,
-                               imap.br_state);
-               }
+                       return XFS_ERROR(error);
+
+               if (unlikely(!imap.br_startblock &&
+                            !(io->io_flags & XFS_IOCORE_RT)))
+                       return xfs_cmn_err_fsblock_zero(ip, &imap);
 
                if ((numblks_fsb = imap.br_blockcount) == 0) {
                        /*
@@ -999,6 +979,5 @@ error_on_bmapi_transaction:
        xfs_bmap_cancel(&free_list);
        xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
-error0:
        return XFS_ERROR(error);
 }
index 46249e4d1feaba62eec485e23376c2d3508f7440..7775ddc0b3c6b105449bef21a3954741533129f4 100644 (file)
 #include "xfs_error.h"
 #include "xfs_btree.h"
 
+int
+xfs_internal_inum(
+       xfs_mount_t     *mp,
+       xfs_ino_t       ino)
+{
+       return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
+               (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+                (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
+}
+
 STATIC int
 xfs_bulkstat_one_iget(
        xfs_mount_t     *mp,            /* mount point for filesystem */
@@ -52,7 +62,8 @@ xfs_bulkstat_one_iget(
        bhv_vnode_t     *vp;
        int             error;
 
-       error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
+       error = xfs_iget(mp, NULL, ino,
+                        XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno);
        if (error) {
                *stat = BULKSTAT_RV_NOTHING;
                return error;
@@ -212,17 +223,12 @@ xfs_bulkstat_one(
        xfs_dinode_t    *dip;           /* dinode inode pointer */
 
        dip = (xfs_dinode_t *)dibuff;
+       *stat = BULKSTAT_RV_NOTHING;
 
-       if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
-           (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
-            (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) {
-               *stat = BULKSTAT_RV_NOTHING;
+       if (!buffer || xfs_internal_inum(mp, ino))
                return XFS_ERROR(EINVAL);
-       }
-       if (ubsize < sizeof(*buf)) {
-               *stat = BULKSTAT_RV_NOTHING;
+       if (ubsize < sizeof(*buf))
                return XFS_ERROR(ENOMEM);
-       }
 
        buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
 
@@ -238,8 +244,7 @@ xfs_bulkstat_one(
        }
 
        if (copy_to_user(buffer, buf, sizeof(*buf)))  {
-               *stat = BULKSTAT_RV_NOTHING;
-               error =  EFAULT;
+               error = EFAULT;
                goto out_free;
        }
 
@@ -252,6 +257,46 @@ xfs_bulkstat_one(
        return error;
 }
 
+/*
+ * Test to see whether we can use the ondisk inode directly, based
+ * on the given bulkstat flags, filling in dipp accordingly.
+ * Returns zero if the inode is dodgey.
+ */
+STATIC int
+xfs_bulkstat_use_dinode(
+       xfs_mount_t     *mp,
+       int             flags,
+       xfs_buf_t       *bp,
+       int             clustidx,
+       xfs_dinode_t    **dipp)
+{
+       xfs_dinode_t    *dip;
+       unsigned int    aformat;
+
+       *dipp = NULL;
+       if (!bp || (flags & BULKSTAT_FG_IGET))
+               return 1;
+       dip = (xfs_dinode_t *)
+                       xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
+       if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC ||
+           !XFS_DINODE_GOOD_VERSION(
+                       INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
+               return 0;
+       if (flags & BULKSTAT_FG_QUICK) {
+               *dipp = dip;
+               return 1;
+       }
+       /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
+       aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT);
+       if ((XFS_CFORK_Q(&dip->di_core) == 0) ||
+           (aformat == XFS_DINODE_FMT_LOCAL) ||
+           (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
+               *dipp = dip;
+               return 1;
+       }
+       return 1;
+}
+
 /*
  * Return stat information in bulk (by-inode) for the filesystem.
  */
@@ -284,10 +329,11 @@ xfs_bulkstat(
        xfs_agino_t             gino;   /* current btree rec's start inode */
        int                     i;      /* loop index */
        int                     icount; /* count of inodes good in irbuf */
+       size_t                  irbsize; /* size of irec buffer in bytes */
        xfs_ino_t               ino;    /* inode number (filesystem) */
-       xfs_inobt_rec_t         *irbp;  /* current irec buffer pointer */
-       xfs_inobt_rec_t         *irbuf; /* start of irec buffer */
-       xfs_inobt_rec_t         *irbufend; /* end of good irec buffer entries */
+       xfs_inobt_rec_incore_t  *irbp;  /* current irec buffer pointer */
+       xfs_inobt_rec_incore_t  *irbuf; /* start of irec buffer */
+       xfs_inobt_rec_incore_t  *irbufend; /* end of good irec buffer entries */
        xfs_ino_t               lastino=0; /* last inode number returned */
        int                     nbcluster; /* # of blocks in a cluster */
        int                     nicluster; /* # of inodes in a cluster */
@@ -328,13 +374,10 @@ xfs_bulkstat(
                (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
        nimask = ~(nicluster - 1);
        nbcluster = nicluster >> mp->m_sb.sb_inopblog;
-       /*
-        * Allocate a page-sized buffer for inode btree records.
-        * We could try allocating something smaller, but for normal
-        * calls we'll always (potentially) need the whole page.
-        */
-       irbuf = kmem_alloc(NBPC, KM_SLEEP);
-       nirbuf = NBPC / sizeof(*irbuf);
+       irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4,
+                                  KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+       nirbuf = irbsize / sizeof(*irbuf);
+
        /*
         * Loop over the allocation groups, starting from the last
         * inode returned; 0 means start of the allocation group.
@@ -358,7 +401,7 @@ xfs_bulkstat(
                 * Allocate and initialize a btree cursor for ialloc btree.
                 */
                cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO,
-                       (xfs_inode_t *)0, 0);
+                                               (xfs_inode_t *)0, 0);
                irbp = irbuf;
                irbufend = irbuf + nirbuf;
                end_of_ag = 0;
@@ -395,9 +438,9 @@ xfs_bulkstat(
                                                gcnt++;
                                }
                                gfree |= XFS_INOBT_MASKN(0, chunkidx);
-                               INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
-                               INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
-                               INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
+                               irbp->ir_startino = gino;
+                               irbp->ir_freecount = gcnt;
+                               irbp->ir_free = gfree;
                                irbp++;
                                agino = gino + XFS_INODES_PER_CHUNK;
                                icount = XFS_INODES_PER_CHUNK - gcnt;
@@ -451,11 +494,27 @@ xfs_bulkstat(
                        }
                        /*
                         * If this chunk has any allocated inodes, save it.
+                        * Also start read-ahead now for this chunk.
                         */
                        if (gcnt < XFS_INODES_PER_CHUNK) {
-                               INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
-                               INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
-                               INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
+                               /*
+                                * Loop over all clusters in the next chunk.
+                                * Do a readahead if there are any allocated
+                                * inodes in that cluster.
+                                */
+                               for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),
+                                    chunkidx = 0;
+                                    chunkidx < XFS_INODES_PER_CHUNK;
+                                    chunkidx += nicluster,
+                                    agbno += nbcluster) {
+                                       if (XFS_INOBT_MASKN(chunkidx,
+                                                           nicluster) & ~gfree)
+                                               xfs_btree_reada_bufs(mp, agno,
+                                                       agbno, nbcluster);
+                               }
+                               irbp->ir_startino = gino;
+                               irbp->ir_freecount = gcnt;
+                               irbp->ir_free = gfree;
                                irbp++;
                                icount += XFS_INODES_PER_CHUNK - gcnt;
                        }
@@ -478,34 +537,12 @@ xfs_bulkstat(
                irbufend = irbp;
                for (irbp = irbuf;
                     irbp < irbufend && ubleft >= statstruct_size; irbp++) {
-                       /*
-                        * Read-ahead the next chunk's worth of inodes.
-                        */
-                       if (&irbp[1] < irbufend) {
-                               /*
-                                * Loop over all clusters in the next chunk.
-                                * Do a readahead if there are any allocated
-                                * inodes in that cluster.
-                                */
-                               for (agbno = XFS_AGINO_TO_AGBNO(mp,
-                                                       INT_GET(irbp[1].ir_startino, ARCH_CONVERT)),
-                                    chunkidx = 0;
-                                    chunkidx < XFS_INODES_PER_CHUNK;
-                                    chunkidx += nicluster,
-                                    agbno += nbcluster) {
-                                       if (XFS_INOBT_MASKN(chunkidx,
-                                                           nicluster) &
-                                           ~(INT_GET(irbp[1].ir_free, ARCH_CONVERT)))
-                                               xfs_btree_reada_bufs(mp, agno,
-                                                       agbno, nbcluster);
-                               }
-                       }
                        /*
                         * Now process this chunk of inodes.
                         */
-                       for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0;
+                       for (agino = irbp->ir_startino, chunkidx = clustidx = 0;
                             ubleft > 0 &&
-                               INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK;
+                               irbp->ir_freecount < XFS_INODES_PER_CHUNK;
                             chunkidx++, clustidx++, agino++) {
                                ASSERT(chunkidx < XFS_INODES_PER_CHUNK);
                                /*
@@ -525,11 +562,12 @@ xfs_bulkstat(
                                 */
                                if ((chunkidx & (nicluster - 1)) == 0) {
                                        agbno = XFS_AGINO_TO_AGBNO(mp,
-                                                       INT_GET(irbp->ir_startino, ARCH_CONVERT)) +
+                                                       irbp->ir_startino) +
                                                ((chunkidx & nimask) >>
                                                 mp->m_sb.sb_inopblog);
 
-                                       if (flags & BULKSTAT_FG_QUICK) {
+                                       if (flags & (BULKSTAT_FG_QUICK |
+                                                    BULKSTAT_FG_INLINE)) {
                                                ino = XFS_AGINO_TO_INO(mp, agno,
                                                                       agino);
                                                bno = XFS_AGB_TO_DADDR(mp, agno,
@@ -543,6 +581,7 @@ xfs_bulkstat(
                                                                      KM_SLEEP);
                                                ip->i_ino = ino;
                                                ip->i_mount = mp;
+                                               spin_lock_init(&ip->i_flags_lock);
                                                if (bp)
                                                        xfs_buf_relse(bp);
                                                error = xfs_itobp(mp, NULL, ip,
@@ -564,30 +603,34 @@ xfs_bulkstat(
                                /*
                                 * Skip if this inode is free.
                                 */
-                               if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT))
+                               if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
                                        continue;
                                /*
                                 * Count used inodes as free so we can tell
                                 * when the chunk is used up.
                                 */
-                               INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1);
+                               irbp->ir_freecount++;
                                ino = XFS_AGINO_TO_INO(mp, agno, agino);
                                bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
-                               if (flags & BULKSTAT_FG_QUICK) {
-                                       dip = (xfs_dinode_t *)xfs_buf_offset(bp,
-                                             (clustidx << mp->m_sb.sb_inodelog));
-
-                                       if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT)
-                                                   != XFS_DINODE_MAGIC
-                                           || !XFS_DINODE_GOOD_VERSION(
-                                                   INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
-                                               continue;
+                               if (!xfs_bulkstat_use_dinode(mp, flags, bp,
+                                                            clustidx, &dip))
+                                       continue;
+                               /*
+                                * If we need to do an iget, cannot hold bp.
+                                * Drop it, until starting the next cluster.
+                                */
+                               if ((flags & BULKSTAT_FG_INLINE) && !dip) {
+                                       if (bp)
+                                               xfs_buf_relse(bp);
+                                       bp = NULL;
                                }
 
                                /*
                                 * Get the inode and fill in a single buffer.
                                 * BULKSTAT_FG_QUICK uses dip to fill it in.
                                 * BULKSTAT_FG_IGET uses igets.
+                                * BULKSTAT_FG_INLINE uses dip if we have an
+                                * inline attr fork, else igets.
                                 * See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
                                 * This is also used to count inodes/blks, etc
                                 * in xfs_qm_quotacheck.
@@ -597,8 +640,15 @@ xfs_bulkstat(
                                                ubleft, private_data,
                                                bno, &ubused, dip, &fmterror);
                                if (fmterror == BULKSTAT_RV_NOTHING) {
-                                       if (error == ENOMEM)
+                                        if (error == EFAULT) {
+                                                ubleft = 0;
+                                                rval = error;
+                                                break;
+                                        }
+                                       else if (error == ENOMEM)
                                                ubleft = 0;
+                                       else
+                                               lastino = ino;
                                        continue;
                                }
                                if (fmterror == BULKSTAT_RV_GIVEUP) {
@@ -633,7 +683,7 @@ xfs_bulkstat(
        /*
         * Done, we're either out of filesystem or space to put the data.
         */
-       kmem_free(irbuf, NBPC);
+       kmem_free(irbuf, irbsize);
        *ubcountp = ubelem;
        if (agno >= mp->m_sb.sb_agcount) {
                /*
index be5f12e07d2217d98814127747d8fc9eadb40cc0..f25a28862a1770a02e8c0b3ca4cd43a3b0b82352 100644 (file)
@@ -36,15 +36,16 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount     *mp,
 /*
  * Values for stat return value.
  */
-#define        BULKSTAT_RV_NOTHING     0
-#define        BULKSTAT_RV_DIDONE      1
-#define        BULKSTAT_RV_GIVEUP      2
+#define BULKSTAT_RV_NOTHING    0
+#define BULKSTAT_RV_DIDONE     1
+#define BULKSTAT_RV_GIVEUP     2
 
 /*
  * Values for bulkstat flag argument.
  */
-#define        BULKSTAT_FG_IGET        0x1     /* Go through the buffer cache */
-#define        BULKSTAT_FG_QUICK       0x2     /* No iget, walk the dinode cluster */
+#define BULKSTAT_FG_IGET       0x1     /* Go through the buffer cache */
+#define BULKSTAT_FG_QUICK      0x2     /* No iget, walk the dinode cluster */
+#define BULKSTAT_FG_INLINE     0x4     /* No iget if inline attrs */
 
 /*
  * Return stat information in bulk (by-inode) for the filesystem.
@@ -80,6 +81,11 @@ xfs_bulkstat_one(
        void                    *dibuff,
        int                     *stat);
 
+int
+xfs_internal_inum(
+       xfs_mount_t             *mp,
+       xfs_ino_t               ino);
+
 int                                    /* error status */
 xfs_inumbers(
        xfs_mount_t             *mp,    /* mount point for filesystem */
index 21ac1a67e3e03c763eb61ea9be1e2a2eb170631e..c48bf61f17bd847cdb04a6ca8ad6b6f9f8c7e273 100644 (file)
@@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
                reg[0].i_len  = sizeof(magic);
                XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_UNMOUNT);
 
-               error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
+               error = xfs_log_reserve(mp, 600, 1, &tic,
+                                       XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
                if (!error) {
                        /* remove inited flag */
                        ((xlog_ticket_t *)tic)->t_flags = 0;
@@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp)
                } else {
                        LOG_UNLOCK(log, s);
                }
-               if (tic)
+               if (tic) {
+                       xlog_trace_loggrant(log, tic, "unmount rec");
+                       xlog_ungrant_log_space(log, tic);
                        xlog_state_put_ticket(log, tic);
+               }
        } else {
                /*
                 * We're already in forced_shutdown mode, couldn't
@@ -1196,7 +1200,7 @@ xlog_alloc_log(xfs_mount_t        *mp,
                          kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
                iclog = *iclogp;
                iclog->hic_data = (xlog_in_core_2_t *)
-                         kmem_zalloc(iclogsize, KM_SLEEP);
+                         kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE);
 
                iclog->ic_prev = prev_iclog;
                prev_iclog = iclog;
@@ -2212,9 +2216,13 @@ xlog_state_do_callback(
 
                        iclog = iclog->ic_next;
                } while (first_iclog != iclog);
-               if (repeats && (repeats % 10) == 0) {
+
+               if (repeats > 5000) {
+                       flushcnt += repeats;
+                       repeats = 0;
                        xfs_fs_cmn_err(CE_WARN, log->l_mp,
-                               "xlog_state_do_callback: looping %d", repeats);
+                               "%s: possible infinite loop (%d iterations)",
+                               __FUNCTION__, flushcnt);
                }
        } while (!ioerrors && loopdidcallbacks);
 
@@ -2246,6 +2254,7 @@ xlog_state_do_callback(
        }
 #endif
 
+       flushcnt = 0;
        if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
                flushcnt = log->l_flushcnt;
                log->l_flushcnt = 0;
index eacb3d4987f25ad17a9927d1c302a0f99f879668..ebbe93f4f97bc7925a458996e2f8c11943223f9a 100644 (file)
@@ -47,17 +47,11 @@ static inline xfs_lsn_t     _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
  * Macros, structures, prototypes for interface to the log manager.
  */
 
-/*
- * Flags to xfs_log_mount
- */
-#define XFS_LOG_RECOVER                0x1
-
 /*
  * Flags to xfs_log_done()
  */
 #define XFS_LOG_REL_PERM_RESERV        0x1
 
-
 /*
  * Flags to xfs_log_reserve()
  *
@@ -70,8 +64,6 @@ static inline xfs_lsn_t       _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
 #define XFS_LOG_SLEEP          0x0
 #define XFS_LOG_NOSLEEP                0x1
 #define XFS_LOG_PERM_RESERV    0x2
-#define XFS_LOG_RESV_ALL       (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV)
-
 
 /*
  * Flags to xfs_log_force()
index 34bcbf50789c1e614e474427341cdcd6889e7efa..9bd3cdf11a87068db1b773b5afabb2ea0a5bc913 100644 (file)
@@ -32,7 +32,6 @@ struct xfs_mount;
 #define XLOG_MIN_ICLOGS                2
 #define XLOG_MED_ICLOGS                4
 #define XLOG_MAX_ICLOGS                8
-#define XLOG_CALLBACK_SIZE     10
 #define XLOG_HEADER_MAGIC_NUM  0xFEEDbabe      /* Invalid cycle number */
 #define XLOG_VERSION_1         1
 #define XLOG_VERSION_2         2               /* Large IClogs, Log sunit */
@@ -149,9 +148,6 @@ struct xfs_mount;
 #define XLOG_WAS_CONT_TRANS    0x08    /* Cont this trans into new region */
 #define XLOG_END_TRANS         0x10    /* End a continued transaction */
 #define XLOG_UNMOUNT_TRANS     0x20    /* Unmount a filesystem transaction */
-#define XLOG_SKIP_TRANS                (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \
-                                XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \
-                                XLOG_UNMOUNT_TRANS)
 
 #ifdef __KERNEL__
 /*
@@ -506,6 +502,12 @@ extern int  xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
 #define XLOG_TRACE_SLEEP_FLUSH 3
 #define XLOG_TRACE_WAKE_FLUSH  4
 
+/*
+ * Unmount record type is used as a pseudo transaction type for the ticket.
+ * It's value must be outside the range of XFS_TRANS_* values.
+ */
+#define XLOG_UNMOUNT_REC_TYPE  (-1U)
+
 #endif /* __KERNEL__ */
 
 #endif /* __XFS_LOG_PRIV_H__ */
index b2bd4be4200a305d449d831e6d88edeac614380e..e5f396ff9a3d57f45bb3174449f9cfbd752adf19 100644 (file)
@@ -331,7 +331,7 @@ typedef struct xfs_mount {
        xfs_agnumber_t          m_agirotor;     /* last ag dir inode alloced */
        lock_t                  m_agirotor_lock;/* .. and lock protecting it */
        xfs_agnumber_t          m_maxagi;       /* highest inode alloc group */
-       uint                    m_ihsize;       /* size of next field */
+       size_t                  m_ihsize;       /* size of next field */
        struct xfs_ihash        *m_ihash;       /* fs private inode hash table*/
        struct xfs_inode        *m_inodes;      /* active inode list */
        struct list_head        m_del_inodes;   /* inodes to reclaim */
@@ -541,7 +541,8 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
 #define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
 static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
 {
-       return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
+       return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs),
+                               VFS_POSITION_XFS, VFS_POSITION_XFS));
 }
 
 #define XFS_DADDR_TO_AGNO(mp,d)         xfs_daddr_to_agno(mp,d)
index acb853b33ebbd632765403361e6debf8ae90823a..9dcb32aa4e2ea2a25eac703996bedfc8bb219421 100644 (file)
@@ -281,8 +281,6 @@ typedef struct xfs_qoff_logformat {
                                 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
                                 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
                                 XFS_GQUOTA_ACCT)
-#define XFS_MOUNT_QUOTA_MASK   (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
-                                XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
 
 
 /*
index 5a0b678956e0e3ca616efb76ffb9d827f6d159fa..880c73271c05fac890f3e0dcdd53a4805ae26be0 100644 (file)
@@ -1948,7 +1948,7 @@ xfs_growfs_rt(
         */
        nrextents = nrblocks;
        do_div(nrextents, in->extsize);
-       nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
+       nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
        nrextslog = xfs_highbit32(nrextents);
        nrsumlevels = nrextslog + 1;
        nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
@@ -1976,7 +1976,10 @@ xfs_growfs_rt(
        if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks,
                        mp->m_sb.sb_rsumino)))
                return error;
-       nmp = NULL;
+       /*
+        * Allocate a new (fake) mount/sb.
+        */
+       nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
        /*
         * Loop over the bitmap blocks.
         * We will do everything one bitmap block at a time.
@@ -1987,10 +1990,6 @@ xfs_growfs_rt(
                     ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
             bmbno < nrbmblocks;
             bmbno++) {
-               /*
-                * Allocate a new (fake) mount/sb.
-                */
-               nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
                *nmp = *mp;
                nsbp = &nmp->m_sb;
                /*
@@ -2018,13 +2017,13 @@ xfs_growfs_rt(
                cancelflags = 0;
                if ((error = xfs_trans_reserve(tp, 0,
                                XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0)))
-                       goto error_exit;
+                       break;
                /*
                 * Lock out other callers by grabbing the bitmap inode lock.
                 */
                if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
                                                XFS_ILOCK_EXCL, &ip)))
-                       goto error_exit;
+                       break;
                ASSERT(ip == mp->m_rbmip);
                /*
                 * Update the bitmap inode's size.
@@ -2038,7 +2037,7 @@ xfs_growfs_rt(
                 */
                if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
                                                XFS_ILOCK_EXCL, &ip)))
-                       goto error_exit;
+                       break;
                ASSERT(ip == mp->m_rsumip);
                /*
                 * Update the summary inode's size.
@@ -2053,7 +2052,7 @@ xfs_growfs_rt(
                    mp->m_rsumlevels != nmp->m_rsumlevels) {
                        error = xfs_rtcopy_summary(mp, nmp, tp);
                        if (error)
-                               goto error_exit;
+                               break;
                }
                /*
                 * Update superblock fields.
@@ -2080,17 +2079,12 @@ xfs_growfs_rt(
                error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
                        nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
                if (error)
-                       goto error_exit;
+                       break;
                /*
                 * Mark more blocks free in the superblock.
                 */
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
                        nsbp->sb_rextents - sbp->sb_rextents);
-               /*
-                * Free the fake mp structure.
-                */
-               kmem_free(nmp, sizeof(*nmp));
-               nmp = NULL;
                /*
                 * Update mp values into the real mp structure.
                 */
@@ -2101,15 +2095,15 @@ xfs_growfs_rt(
                 */
                xfs_trans_commit(tp, 0, NULL);
        }
-       return 0;
+
+       if (error)
+               xfs_trans_cancel(tp, cancelflags);
 
        /*
-        * Error paths come here.
+        * Free the fake mp structure.
         */
-error_exit:
-       if (nmp)
-               kmem_free(nmp, sizeof(*nmp));
-       xfs_trans_cancel(tp, cancelflags);
+       kmem_free(nmp, sizeof(*nmp));
+
        return error;
 }
 
index bf168a91ddb83ffd4e91f7456fe83fd5bf937e8f..467854b45c8f6dc4d61ce2a0a9a94423178b5147 100644 (file)
@@ -60,10 +60,6 @@ struct xfs_mount;
         XFS_SB_VERSION_LOGV2BIT | \
         XFS_SB_VERSION_SECTORBIT | \
         XFS_SB_VERSION_MOREBITSBIT)
-#define        XFS_SB_VERSION_OKSASHBITS       \
-       (XFS_SB_VERSION_NUMBITS | \
-        XFS_SB_VERSION_REALFBITS | \
-        XFS_SB_VERSION_OKSASHFBITS)
 #define        XFS_SB_VERSION_OKREALBITS       \
        (XFS_SB_VERSION_NUMBITS | \
         XFS_SB_VERSION_OKREALFBITS | \
@@ -81,9 +77,6 @@ struct xfs_mount;
 #define XFS_SB_VERSION2_RESERVED2BIT   0x00000002
 #define XFS_SB_VERSION2_RESERVED4BIT   0x00000004
 #define XFS_SB_VERSION2_ATTR2BIT       0x00000008      /* Inline attr rework */
-#define XFS_SB_VERSION2_SASHFBITS      0xff000000      /* Mask: features that
-                                                          require changing
-                                                          PROM and SASH */
 
 #define        XFS_SB_VERSION2_OKREALFBITS     \
        (XFS_SB_VERSION2_ATTR2BIT)
@@ -238,12 +231,6 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
 }
 #endif /* __KERNEL__ */
 
-#define        XFS_SB_GOOD_SASH_VERSION(sbp)   \
-       ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
-         ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
-        ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
-         !((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS)))
-
 #define        XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
 static inline unsigned xfs_sb_version_tonew(unsigned v)
 {
@@ -461,15 +448,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
  * File system sector to basic block conversions.
  */
 #define XFS_FSS_TO_BB(mp,sec)  ((sec) << (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSS(mp,bb)   \
-       (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log)
-#define XFS_BB_TO_FSST(mp,bb)  ((bb) >> (mp)->m_sectbb_log)
-
-/*
- * File system sector to byte conversions.
- */
-#define XFS_FSS_TO_B(mp,sectno)        ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog)
-#define XFS_B_TO_FSST(mp,b)    (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog)
 
 /*
  * File system block to basic block conversions.
index 9dc88b380608e6f29a6bef4c7ee5c21945367f0f..c68e00105d238daeedc3aa036e0f234dd38f8a3d 100644 (file)
@@ -149,7 +149,6 @@ typedef struct xfs_item_ops {
        void (*iop_unlock)(xfs_log_item_t *);
        xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
        void (*iop_push)(xfs_log_item_t *);
-       void (*iop_abort)(xfs_log_item_t *);
        void (*iop_pushbuf)(xfs_log_item_t *);
        void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
 } xfs_item_ops_t;
@@ -163,7 +162,6 @@ typedef struct xfs_item_ops {
 #define IOP_UNLOCK(ip)         (*(ip)->li_ops->iop_unlock)(ip)
 #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
 #define IOP_PUSH(ip)           (*(ip)->li_ops->iop_push)(ip)
-#define IOP_ABORT(ip)          (*(ip)->li_ops->iop_abort)(ip)
 #define IOP_PUSHBUF(ip)                (*(ip)->li_ops->iop_pushbuf)(ip)
 #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn)
 
index 558c87ff0c41faeea2da96536da6cf250c2e095d..fc39b166d403e609e356008f05c23fcb682d8b28 100644 (file)
@@ -276,7 +276,7 @@ xfs_trans_update_ail(
        xfs_mount_t     *mp,
        xfs_log_item_t  *lip,
        xfs_lsn_t       lsn,
-       unsigned long   s)
+       unsigned long   s) __releases(mp->m_ail_lock)
 {
        xfs_ail_entry_t         *ailp;
        xfs_log_item_t          *dlip=NULL;
@@ -328,7 +328,7 @@ void
 xfs_trans_delete_ail(
        xfs_mount_t     *mp,
        xfs_log_item_t  *lip,
-       unsigned long   s)
+       unsigned long   s) __releases(mp->m_ail_lock)
 {
        xfs_ail_entry_t         *ailp;
        xfs_log_item_t          *dlip;
index 13edab8a9e94d20493eb227afa5b77f45be9d5d8..447ac4308c917cd445a5a0acea364a7b567d5405 100644 (file)
@@ -46,11 +46,13 @@ xfs_log_busy_slot_t         *xfs_trans_add_busy(xfs_trans_t *tp,
 /*
  * From xfs_trans_ail.c
  */
-void                   xfs_trans_update_ail(struct xfs_mount *,
-                                    struct xfs_log_item *, xfs_lsn_t,
-                                    unsigned long);
-void                   xfs_trans_delete_ail(struct xfs_mount *,
-                                    struct xfs_log_item *, unsigned long);
+void                   xfs_trans_update_ail(struct xfs_mount *mp,
+                                    struct xfs_log_item *lip, xfs_lsn_t lsn,
+                                    unsigned long s)
+                                    __releases(mp->m_ail_lock);
+void                   xfs_trans_delete_ail(struct xfs_mount *mp,
+                                    struct xfs_log_item *lip, unsigned long s)
+                                    __releases(mp->m_ail_lock);
 struct xfs_log_item    *xfs_trans_first_ail(struct xfs_mount *, int *);
 struct xfs_log_item    *xfs_trans_next_ail(struct xfs_mount *,
                                     struct xfs_log_item *, int *, int *);
index a34796e57afb308c58c7ed816d278ad07b2f13b8..62336a4cc5a4c72339932fdc91dcf8dd2323f38a 100644 (file)
@@ -1922,7 +1922,7 @@ xfs_showargs(
        }
 
        if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
-               seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
+               seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
 
        if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
                seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
index 23cfa58377283b073f09503734581ea4df80edf0..061e2ffdd1dee3613bedb671dbdbb9256350aac8 100644 (file)
@@ -2366,10 +2366,15 @@ xfs_remove(
 
        namelen = VNAMELEN(dentry);
 
+       if (!xfs_get_dir_entry(dentry, &ip)) {
+               dm_di_mode = ip->i_d.di_mode;
+               IRELE(ip);
+       }
+
        if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
                                        DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
-                                       name, NULL, 0, 0, 0);
+                                       name, NULL, dm_di_mode, 0, 0);
                if (error)
                        return error;
        }
@@ -2995,7 +3000,7 @@ xfs_rmdir(
        int                     cancel_flags;
        int                     committed;
        bhv_vnode_t             *dir_vp;
-       int                     dm_di_mode = 0;
+       int                     dm_di_mode = S_IFDIR;
        int                     last_cdp_link;
        int                     namelen;
        uint                    resblks;
@@ -3010,11 +3015,16 @@ xfs_rmdir(
                return XFS_ERROR(EIO);
        namelen = VNAMELEN(dentry);
 
+       if (!xfs_get_dir_entry(dentry, &cdp)) {
+               dm_di_mode = cdp->i_d.di_mode;
+               IRELE(cdp);
+       }
+
        if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
                                        dir_vp, DM_RIGHT_NULL,
                                        NULL, DM_RIGHT_NULL,
-                                       name, NULL, 0, 0, 0);
+                                       name, NULL, dm_di_mode, 0, 0);
                if (error)
                        return XFS_ERROR(error);
        }
@@ -3834,7 +3844,9 @@ xfs_reclaim(
                XFS_MOUNT_ILOCK(mp);
                vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
                list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
+               spin_lock(&ip->i_flags_lock);
                ip->i_flags |= XFS_IRECLAIMABLE;
+               spin_unlock(&ip->i_flags_lock);
                XFS_MOUNT_IUNLOCK(mp);
        }
        return 0;
@@ -3859,8 +3871,10 @@ xfs_finish_reclaim(
         * us.
         */
        write_lock(&ih->ih_lock);
+       spin_lock(&ip->i_flags_lock);
        if ((ip->i_flags & XFS_IRECLAIM) ||
            (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
+               spin_unlock(&ip->i_flags_lock);
                write_unlock(&ih->ih_lock);
                if (locked) {
                        xfs_ifunlock(ip);
@@ -3869,6 +3883,7 @@ xfs_finish_reclaim(
                return 1;
        }
        ip->i_flags |= XFS_IRECLAIM;
+       spin_unlock(&ip->i_flags_lock);
        write_unlock(&ih->ih_lock);
 
        /*
@@ -4272,7 +4287,7 @@ xfs_free_file_space(
        xfs_mount_t             *mp;
        int                     nimap;
        uint                    resblks;
-       int                     rounding;
+       uint                    rounding;
        int                     rt;
        xfs_fileoff_t           startoffset_fsb;
        xfs_trans_t             *tp;
@@ -4313,8 +4328,7 @@ xfs_free_file_space(
                vn_iowait(vp);  /* wait for the completion of any pending DIOs */
        }
 
-       rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
-                       (__uint8_t)NBPP);
+       rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
        ilen = len + (offset & (rounding - 1));
        ioffset = offset & ~(rounding - 1);
        if (ilen & (rounding - 1))
index 58f40931a5c1fecdc58dd6cce9a6c0c548280eb2..a5a86b1ff886d73aac3bbccb0a3a9e849cbba52e 100644 (file)
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ    0       /* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS    1       /* System Peripheral */
-#define AT91_ID_PIOA   2       /* Parallel IO Controller A */
-#define AT91_ID_PIOB   3       /* Parallel IO Controller B */
-#define AT91_ID_PIOC   4       /* Parallel IO Controller C */
-#define AT91_ID_PIOD   5       /* Parallel IO Controller D */
-#define AT91_ID_US0    6       /* USART 0 */
-#define AT91_ID_US1    7       /* USART 1 */
-#define AT91_ID_US2    8       /* USART 2 */
-#define AT91_ID_US3    9       /* USART 3 */
-#define AT91_ID_MCI    10      /* Multimedia Card Interface */
-#define AT91_ID_UDP    11      /* USB Device Port */
-#define AT91_ID_TWI    12      /* Two-Wire Interface */
-#define AT91_ID_SPI    13      /* Serial Peripheral Interface */
-#define AT91_ID_SSC0   14      /* Serial Synchronous Controller 0 */
-#define AT91_ID_SSC1   15      /* Serial Synchronous Controller 1 */
-#define AT91_ID_SSC2   16      /* Serial Synchronous Controller 2 */
-#define AT91_ID_TC0    17      /* Timer Counter 0 */
-#define AT91_ID_TC1    18      /* Timer Counter 1 */
-#define AT91_ID_TC2    19      /* Timer Counter 2 */
-#define AT91_ID_TC3    20      /* Timer Counter 3 */
-#define AT91_ID_TC4    21      /* Timer Counter 4 */
-#define AT91_ID_TC5    22      /* Timer Counter 5 */
-#define AT91_ID_UHP    23      /* USB Host port */
-#define AT91_ID_EMAC   24      /* Ethernet MAC */
-#define AT91_ID_IRQ0   25      /* Advanced Interrupt Controller (IRQ0) */
-#define AT91_ID_IRQ1   26      /* Advanced Interrupt Controller (IRQ1) */
-#define AT91_ID_IRQ2   27      /* Advanced Interrupt Controller (IRQ2) */
-#define AT91_ID_IRQ3   28      /* Advanced Interrupt Controller (IRQ3) */
-#define AT91_ID_IRQ4   29      /* Advanced Interrupt Controller (IRQ4) */
-#define AT91_ID_IRQ5   30      /* Advanced Interrupt Controller (IRQ5) */
-#define AT91_ID_IRQ6   31      /* Advanced Interrupt Controller (IRQ6) */
+#define AT91_ID_FIQ            0       /* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS            1       /* System Peripheral */
+#define AT91RM9200_ID_PIOA     2       /* Parallel IO Controller A */
+#define AT91RM9200_ID_PIOB     3       /* Parallel IO Controller B */
+#define AT91RM9200_ID_PIOC     4       /* Parallel IO Controller C */
+#define AT91RM9200_ID_PIOD     5       /* Parallel IO Controller D */
+#define AT91RM9200_ID_US0      6       /* USART 0 */
+#define AT91RM9200_ID_US1      7       /* USART 1 */
+#define AT91RM9200_ID_US2      8       /* USART 2 */
+#define AT91RM9200_ID_US3      9       /* USART 3 */
+#define AT91RM9200_ID_MCI      10      /* Multimedia Card Interface */
+#define AT91RM9200_ID_UDP      11      /* USB Device Port */
+#define AT91RM9200_ID_TWI      12      /* Two-Wire Interface */
+#define AT91RM9200_ID_SPI      13      /* Serial Peripheral Interface */
+#define AT91RM9200_ID_SSC0     14      /* Serial Synchronous Controller 0 */
+#define AT91RM9200_ID_SSC1     15      /* Serial Synchronous Controller 1 */
+#define AT91RM9200_ID_SSC2     16      /* Serial Synchronous Controller 2 */
+#define AT91RM9200_ID_TC0      17      /* Timer Counter 0 */
+#define AT91RM9200_ID_TC1      18      /* Timer Counter 1 */
+#define AT91RM9200_ID_TC2      19      /* Timer Counter 2 */
+#define AT91RM9200_ID_TC3      20      /* Timer Counter 3 */
+#define AT91RM9200_ID_TC4      21      /* Timer Counter 4 */
+#define AT91RM9200_ID_TC5      22      /* Timer Counter 5 */
+#define AT91RM9200_ID_UHP      23      /* USB Host port */
+#define AT91RM9200_ID_EMAC     24      /* Ethernet MAC */
+#define AT91RM9200_ID_IRQ0     25      /* Advanced Interrupt Controller (IRQ0) */
+#define AT91RM9200_ID_IRQ1     26      /* Advanced Interrupt Controller (IRQ1) */
+#define AT91RM9200_ID_IRQ2     27      /* Advanced Interrupt Controller (IRQ2) */
+#define AT91RM9200_ID_IRQ3     28      /* Advanced Interrupt Controller (IRQ3) */
+#define AT91RM9200_ID_IRQ4     29      /* Advanced Interrupt Controller (IRQ4) */
+#define AT91RM9200_ID_IRQ5     30      /* Advanced Interrupt Controller (IRQ5) */
+#define AT91RM9200_ID_IRQ6     31      /* Advanced Interrupt Controller (IRQ6) */
 
 
 /*
  * Peripheral physical base addresses.
  */
-#define AT91_BASE_TCB0         0xfffa0000
-#define AT91_BASE_TC0          0xfffa0000
-#define AT91_BASE_TC1          0xfffa0040
-#define AT91_BASE_TC2          0xfffa0080
-#define AT91_BASE_TCB1         0xfffa4000
-#define AT91_BASE_TC3          0xfffa4000
-#define AT91_BASE_TC4          0xfffa4040
-#define AT91_BASE_TC5          0xfffa4080
-#define AT91_BASE_UDP          0xfffb0000
-#define AT91_BASE_MCI          0xfffb4000
-#define AT91_BASE_TWI          0xfffb8000
-#define AT91_BASE_EMAC         0xfffbc000
-#define AT91_BASE_US0          0xfffc0000
-#define AT91_BASE_US1          0xfffc4000
-#define AT91_BASE_US2          0xfffc8000
-#define AT91_BASE_US3          0xfffcc000
-#define AT91_BASE_SSC0         0xfffd0000
-#define AT91_BASE_SSC1         0xfffd4000
-#define AT91_BASE_SSC2         0xfffd8000
-#define AT91_BASE_SPI          0xfffe0000
+#define AT91RM9200_BASE_TCB0   0xfffa0000
+#define AT91RM9200_BASE_TC0    0xfffa0000
+#define AT91RM9200_BASE_TC1    0xfffa0040
+#define AT91RM9200_BASE_TC2    0xfffa0080
+#define AT91RM9200_BASE_TCB1   0xfffa4000
+#define AT91RM9200_BASE_TC3    0xfffa4000
+#define AT91RM9200_BASE_TC4    0xfffa4040
+#define AT91RM9200_BASE_TC5    0xfffa4080
+#define AT91RM9200_BASE_UDP    0xfffb0000
+#define AT91RM9200_BASE_MCI    0xfffb4000
+#define AT91RM9200_BASE_TWI    0xfffb8000
+#define AT91RM9200_BASE_EMAC   0xfffbc000
+#define AT91RM9200_BASE_US0    0xfffc0000
+#define AT91RM9200_BASE_US1    0xfffc4000
+#define AT91RM9200_BASE_US2    0xfffc8000
+#define AT91RM9200_BASE_US3    0xfffcc000
+#define AT91RM9200_BASE_SSC0   0xfffd0000
+#define AT91RM9200_BASE_SSC1   0xfffd4000
+#define AT91RM9200_BASE_SSC2   0xfffd8000
+#define AT91RM9200_BASE_SPI    0xfffe0000
 #define AT91_BASE_SYS          0xfffff000
 
 
+/*
+ * Internal Memory.
+ */
+#define AT91RM9200_ROM_BASE    0x00100000      /* Internal ROM base address */
+#define AT91RM9200_ROM_SIZE    SZ_128K         /* Internal ROM size (128Kb) */
+
+#define AT91RM9200_SRAM_BASE   0x00200000      /* Internal SRAM base address */
+#define AT91RM9200_SRAM_SIZE   SZ_16K          /* Internal SRAM size (16Kb) */
+
+#define AT91RM9200_UHP_BASE    0x00300000      /* USB Host controller */
+
+
+#if 0
 /*
  * PIO pin definitions (peripheral A/B multiplexing).
  */
 #define AT91_PD25_TPK13                (1 << 25)       /* B: ETM Trace Packet Port 13 */
 #define AT91_PD26_TPK14                (1 << 26)       /* B: ETM Trace Packet Port 14 */
 #define AT91_PD27_TPK15                (1 << 27)       /* B: ETM Trace Packet Port 15 */
+#endif
 
 #endif
index 0f4c12d5f0cdc98e42102fac332dfb9cc73f4f1b..73693fea76a204144d9251e3dd6c81c925bd3aad 100644 (file)
@@ -80,6 +80,9 @@
 #define                AT91_CIDR_NVPTYP        (7    << 28)            /* Nonvolatile Program Memory Type */
 #define                AT91_CIDR_EXT           (1    << 31)            /* Extension Flag */
 
+#define AT91_AIC_FFER          (AT91_AIC + 0x140)      /* Fast Forcing Enable Register [SAM9 only] */
+#define AT91_AIC_FFDR          (AT91_AIC + 0x144)      /* Fast Forcing Disable Register [SAM9 only] */
+#define AT91_AIC_FFSR          (AT91_AIC + 0x148)      /* Fast Forcing Status Register [SAM9 only] */
 
 /*
  * PIO Controllers.
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_twi.h b/include/asm-arm/arch-at91rm9200/at91rm9200_twi.h
new file mode 100644 (file)
index 0000000..93547d7
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_twi.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Two-wire Interface (TWI) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91RM9200_TWI_H
+#define AT91RM9200_TWI_H
+
+#define        AT91_TWI_CR             0x00            /* Control Register */
+#define                AT91_TWI_START          (1 <<  0)       /* Send a Start Condition */
+#define                AT91_TWI_STOP           (1 <<  1)       /* Send a Stop Condition */
+#define                AT91_TWI_MSEN           (1 <<  2)       /* Master Transfer Enable */
+#define                AT91_TWI_MSDIS          (1 <<  3)       /* Master Transfer Disable */
+#define                AT91_TWI_SWRST          (1 <<  7)       /* Software Reset */
+
+#define        AT91_TWI_MMR            0x04            /* Master Mode Register */
+#define                AT91_TWI_IADRSZ         (3    <<  8)    /* Internal Device Address Size */
+#define                        AT91_TWI_IADRSZ_NO              (0 << 8)
+#define                        AT91_TWI_IADRSZ_1               (1 << 8)
+#define                        AT91_TWI_IADRSZ_2               (2 << 8)
+#define                        AT91_TWI_IADRSZ_3               (3 << 8)
+#define                AT91_TWI_MREAD          (1    << 12)    /* Master Read Direction */
+#define                AT91_TWI_DADR           (0x7f << 16)    /* Device Address */
+
+#define        AT91_TWI_IADR           0x0c            /* Internal Address Register */
+
+#define        AT91_TWI_CWGR           0x10            /* Clock Waveform Generator Register */
+#define                AT91_TWI_CLDIV          (0xff <<  0)    /* Clock Low Divisor */
+#define                AT91_TWI_CHDIV          (0xff <<  8)    /* Clock High Divisor */
+#define                AT91_TWI_CKDIV          (7    << 16)    /* Clock Divider */
+
+#define        AT91_TWI_SR             0x20            /* Status Register */
+#define                AT91_TWI_TXCOMP         (1 <<  0)       /* Transmission Complete */
+#define                AT91_TWI_RXRDY          (1 <<  1)       /* Receive Holding Register Ready */
+#define                AT91_TWI_TXRDY          (1 <<  2)       /* Transmit Holding Register Ready */
+#define                AT91_TWI_OVRE           (1 <<  6)       /* Overrun Error */
+#define                AT91_TWI_UNRE           (1 <<  7)       /* Underrun Error */
+#define                AT91_TWI_NACK           (1 <<  8)       /* Not Acknowledged */
+
+#define        AT91_TWI_IER            0x24            /* Interrupt Enable Register */
+#define        AT91_TWI_IDR            0x28            /* Interrupt Disable Register */
+#define        AT91_TWI_IMR            0x2c            /* Interrupt Mask Register */
+#define        AT91_TWI_RHR            0x30            /* Receive Holding Register */
+#define        AT91_TWI_THR            0x34            /* Transmit Holding Register */
+
+#endif
+
index dbde1baaf251e0abe27e0e97b42372abbffb0c93..a011d27876a2dd0b2c42df472f199519b46849da 100644 (file)
 
 #define PIN_BASE               NR_AIC_IRQS
 
-#define PQFP_GPIO_BANKS                3       /* PQFP package has 3 banks */
-#define BGA_GPIO_BANKS         4       /* BGA package has 4 banks */
+#define MAX_GPIO_BANKS         4
 
-/* these pin numbers double as IRQ numbers, like AT91_ID_* values */
+/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
 
 #define        AT91_PIN_PA0    (PIN_BASE + 0x00 + 0)
 #define        AT91_PIN_PA1    (PIN_BASE + 0x00 + 1)
 
 #ifndef __ASSEMBLY__
 /* setup setup routines, called from board init or driver probe() */
-extern int at91_set_A_periph(unsigned pin, int use_pullup);
-extern int at91_set_B_periph(unsigned pin, int use_pullup);
-extern int at91_set_gpio_input(unsigned pin, int use_pullup);
-extern int at91_set_gpio_output(unsigned pin, int value);
-extern int at91_set_deglitch(unsigned pin, int is_on);
-extern int at91_set_multi_drive(unsigned pin, int is_on);
+extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
+extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
+extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
 
 /* callable at any time */
 extern int at91_set_gpio_value(unsigned pin, int value);
 extern int at91_get_gpio_value(unsigned pin);
 
+/* callable only from core power-management code */
 extern void at91_gpio_suspend(void);
 extern void at91_gpio_resume(void);
 #endif
index 235d39d91107914d0101c1e8b4b8e048f3a8d0c4..6551b4d1ff7b21ca6e78e9c53a563fc3e50e114a 100644 (file)
  * Virtual to Physical Address mapping for IO devices.
  */
 #define AT91_VA_BASE_SYS       AT91_IO_P2V(AT91_BASE_SYS)
-#define AT91_VA_BASE_SPI       AT91_IO_P2V(AT91_BASE_SPI)
-#define AT91_VA_BASE_SSC2      AT91_IO_P2V(AT91_BASE_SSC2)
-#define AT91_VA_BASE_SSC1      AT91_IO_P2V(AT91_BASE_SSC1)
-#define AT91_VA_BASE_SSC0      AT91_IO_P2V(AT91_BASE_SSC0)
-#define AT91_VA_BASE_US3       AT91_IO_P2V(AT91_BASE_US3)
-#define AT91_VA_BASE_US2       AT91_IO_P2V(AT91_BASE_US2)
-#define AT91_VA_BASE_US1       AT91_IO_P2V(AT91_BASE_US1)
-#define AT91_VA_BASE_US0       AT91_IO_P2V(AT91_BASE_US0)
-#define AT91_VA_BASE_EMAC      AT91_IO_P2V(AT91_BASE_EMAC)
-#define AT91_VA_BASE_TWI       AT91_IO_P2V(AT91_BASE_TWI)
-#define AT91_VA_BASE_MCI       AT91_IO_P2V(AT91_BASE_MCI)
-#define AT91_VA_BASE_UDP       AT91_IO_P2V(AT91_BASE_UDP)
-#define AT91_VA_BASE_TCB1      AT91_IO_P2V(AT91_BASE_TCB1)
-#define AT91_VA_BASE_TCB0      AT91_IO_P2V(AT91_BASE_TCB0)
-
-/* Internal SRAM */
-#define AT91_SRAM_BASE         0x00200000      /* Internal SRAM base address */
-#define AT91_SRAM_SIZE         0x00004000      /* Internal SRAM SIZE (16Kb) */
+#define AT91_VA_BASE_SPI       AT91_IO_P2V(AT91RM9200_BASE_SPI)
+#define AT91_VA_BASE_EMAC      AT91_IO_P2V(AT91RM9200_BASE_EMAC)
+#define AT91_VA_BASE_TWI       AT91_IO_P2V(AT91RM9200_BASE_TWI)
+#define AT91_VA_BASE_MCI       AT91_IO_P2V(AT91RM9200_BASE_MCI)
+#define AT91_VA_BASE_UDP       AT91_IO_P2V(AT91RM9200_BASE_UDP)
 
  /* Internal SRAM is mapped below the IO devices */
-#define AT91_SRAM_VIRT_BASE    (AT91_IO_VIRT_BASE - AT91_SRAM_SIZE)
+#define AT91_SRAM_VIRT_BASE    (AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE)
 
 /* Serial ports */
 #define AT91_NR_UART           5               /* 4 USART3's and one DBGU port */
@@ -71,9 +58,6 @@
 /* Compact Flash */
 #define AT91_CF_BASE           0x50000000      /* NCS4-NCS6: Compact Flash physical base address */
 
-/* Multi-Master Memory controller */
-#define AT91_UHP_BASE          0x00300000      /* USB Host controller */
-
 /* Clocks */
 #define AT91_SLOW_CLOCK                32768           /* slow clock */
 
index f63842c2c0938f10d170922b7eae79ee084fdffe..763cb96c418bac0f6bebc32dbb40c55f2cc1f8e9 100644 (file)
@@ -32,7 +32,7 @@
 
 
 /*
- * IRQ interrupt symbols are the AT91_ID_* symbols in at91rm9200.h
+ * IRQ interrupt symbols are the AT91xxx_ID_* symbols
  * for IRQs handled directly through the AIC, or else the AT91_PIN_*
  * symbols in gpio.h for ones handled indirectly as GPIOs.
  * We make provision for 4 banks of GPIO.
index 9cb27cd4e6ae9cb3237060ecd8c51f07c7a8822d..0e4a3901d3b36b0afa8ea1acbff9165e1bf515db 100644 (file)
@@ -29,7 +29,7 @@ static irqreturn_t
 p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        do_leds();
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
diff --git a/include/asm-arm/arch-iop32x/debug-macro.S b/include/asm-arm/arch-iop32x/debug-macro.S
new file mode 100644 (file)
index 0000000..9022b68
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-iop32x/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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.
+ */
+
+               .macro  addruart, rx
+               mov     \rx, #0xfe000000        @ physical as well as virtual
+               orr     \rx, \rx, #0x00800000   @ location of the UART
+               .endm
+
+#define UART_SHIFT     0
+#include <asm/hardware/debug-8250.S>
similarity index 71%
rename from include/asm-arm/arch-iop3xx/dma.h
rename to include/asm-arm/arch-iop32x/dma.h
index 1e808db8af2a5a2f19493c9169d9621dca3922a5..e977a9ef3160490dd11cb0034f02a9733aa94da5 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * linux/include/asm-arm/arch-iop3xx/dma.h
+ * include/asm-arm/arch-iop32x/dma.h
  *
- *  Copyright (C) 2004 Intel Corp.
+ * Copyright (C) 2004 Intel Corp.
  *
  * 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
diff --git a/include/asm-arm/arch-iop32x/entry-macro.S b/include/asm-arm/arch-iop32x/entry-macro.S
new file mode 100644 (file)
index 0000000..1500cbb
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-iop32x/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IOP32x-based platforms
+ *
+ * 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 <asm/arch/iop32x.h>
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+               ldr     \base, =IOP3XX_REG_ADDR(0x07D8)
+               ldr     \irqstat, [\base]               @ Read IINTSRC
+               cmp     \irqstat, #0
+               clzne   \irqnr, \irqstat
+               rsbne   \irqnr, \irqnr, #31
+               .endm
diff --git a/include/asm-arm/arch-iop32x/glantank.h b/include/asm-arm/arch-iop32x/glantank.h
new file mode 100644 (file)
index 0000000..3b06561
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * include/asm/arch-iop32x/glantank.h
+ *
+ * IO-Data GLAN Tank board registers
+ */
+
+#ifndef __GLANTANK_H
+#define __GLANTANK_H
+
+#define GLANTANK_UART          0xfe800000      /* UART */
+
+
+#endif
diff --git a/include/asm-arm/arch-iop32x/hardware.h b/include/asm-arm/arch-iop32x/hardware.h
new file mode 100644 (file)
index 0000000..6556ed5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * include/asm-arm/arch-iop32x/hardware.h
+ */
+
+#ifndef __HARDWARE_H
+#define __HARDWARE_H
+
+#include <asm/types.h>
+
+/*
+ * Note about PCI IO space mappings
+ *
+ * To make IO space accesses efficient, we store virtual addresses in
+ * the IO resources.
+ *
+ * The PCI IO space is located at virtual 0xfe000000 from physical
+ * 0x90000000. The PCI BARs must be programmed with physical addresses,
+ * but when we read them, we convert them to virtual addresses. See
+ * arch/arm/plat-iop/pci.c.
+ */
+#define pcibios_assign_all_busses() 1
+#define PCIBIOS_MIN_IO         0x00000000
+#define PCIBIOS_MIN_MEM                0x00000000
+
+#ifndef __ASSEMBLY__
+void iop32x_init_irq(void);
+#endif
+
+
+/*
+ * Generic chipset bits
+ */
+#include "iop32x.h"
+
+/*
+ * Board specific bits
+ */
+#include "glantank.h"
+#include "iq80321.h"
+#include "iq31244.h"
+#include "n2100.h"
+
+
+#endif
similarity index 62%
rename from include/asm-arm/arch-iop3xx/io.h
rename to include/asm-arm/arch-iop32x/io.h
index 36adbdf5055a571898184cdc540f64f3ac061dd0..12d9ee02cde31c26c8421c38a70c140f97ac14a7 100644 (file)
@@ -1,21 +1,22 @@
 /*
- * linux/include/asm-arm/arch-iop3xx/io.h
+ * include/asm-arm/arch-iop32x/io.h
  *
- *  Copyright (C) 2001  MontaVista Software, Inc.
+ * Copyright (C) 2001 MontaVista Software, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
+#ifndef __IO_H
+#define __IO_H
 
 #include <asm/hardware.h>
 
-#define IO_SPACE_LIMIT 0xffffffff
+#define IO_SPACE_LIMIT         0xffffffff
 
 #define __io(p)                        ((void __iomem *)(p))
 #define __mem_pci(a)           (a)
 
+
 #endif
diff --git a/include/asm-arm/arch-iop32x/iop32x.h b/include/asm-arm/arch-iop32x/iop32x.h
new file mode 100644 (file)
index 0000000..4bbd85f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * include/asm-arm/arch-iop32x/iop32x.h
+ *
+ * Intel IOP32X Chip definitions
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef __IOP32X_H
+#define __IOP32X_H
+
+/*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_GPIO_REG(reg)   (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c0 + (reg))
+#define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
+
+#include <asm/hardware/iop3xx.h>
+
+
+#endif
similarity index 55%
rename from include/asm-arm/arch-iop3xx/iq31244.h
rename to include/asm-arm/arch-iop32x/iq31244.h
index 4177cfa8100f6250554c03ae4a2d4af6ebf70dd0..fff4eafa1f6b075e3df5c784a4976cc432013f19 100644 (file)
@@ -1,15 +1,11 @@
 /*
- * linux/include/asm/arch-iop3xx/iq31244.h
+ * include/asm-arm/arch-iop32x/iq31244.h
  *
  * Intel IQ31244 evaluation board registers
  */
 
-#ifndef _IQ31244_H_
-#define _IQ31244_H_
-
-#define        IQ31244_FLASHBASE       0xf0000000      /* Flash */
-#define        IQ31244_FLASHSIZE       0x00800000
-#define        IQ31244_FLASHWIDTH      2
+#ifndef __IQ31244_H
+#define __IQ31244_H
 
 #define IQ31244_UART           0xfe800000      /* UART #1 */
 #define IQ31244_7SEG_1         0xfe840000      /* 7-Segment MSB */
@@ -17,8 +13,5 @@
 #define IQ31244_ROTARY_SW      0xfe8d0000      /* Rotary Switch */
 #define IQ31244_BATT_STAT      0xfe8f0000      /* Battery Status */
 
-#ifndef __ASSEMBLY__
-extern void iq31244_map_io(void);
-#endif
 
-#endif // _IQ31244_H_
+#endif
similarity index 55%
rename from include/asm-arm/arch-iop3xx/iq80321.h
rename to include/asm-arm/arch-iop32x/iq80321.h
index cb8725979ffad5964766d905d2d9d46b469f9154..eb69db9b9a06e1eca64c883b4a4a459ab96599ef 100644 (file)
@@ -1,15 +1,11 @@
 /*
- * linux/include/asm/arch-iop3xx/iq80321.h
+ * include/asm-arm/arch-iop32x/iq80321.h
  *
  * Intel IQ80321 evaluation board registers
  */
 
-#ifndef _IQ80321_H_
-#define _IQ80321_H_
-
-#define        IQ80321_FLASHBASE       0xf0000000      /* Flash */
-#define        IQ80321_FLASHSIZE       0x00800000
-#define        IQ80321_FLASHWIDTH      1
+#ifndef __IQ80321_H
+#define __IQ80321_H
 
 #define IQ80321_UART           0xfe800000      /* UART #1 */
 #define IQ80321_7SEG_1         0xfe840000      /* 7-Segment MSB */
@@ -17,8 +13,5 @@
 #define IQ80321_ROTARY_SW      0xfe8d0000      /* Rotary Switch */
 #define IQ80321_BATT_STAT      0xfe8f0000      /* Battery Status */
 
-#ifndef __ASSEMBLY__
-extern void iq80321_map_io(void);
-#endif
 
-#endif // _IQ80321_H_
+#endif
diff --git a/include/asm-arm/arch-iop32x/irqs.h b/include/asm-arm/arch-iop32x/irqs.h
new file mode 100644 (file)
index 0000000..bbaef87
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * include/asm-arm/arch-iop32x/irqs.h
+ *
+ * Author:     Rory Bolt <rorybolt@pacbell.net>
+ * Copyright:  (C) 2002 Rory Bolt
+ *
+ * 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.
+ */
+
+#ifndef __IRQS_H
+#define __IRQS_H
+
+/*
+ * IOP80321 chipset interrupts
+ */
+#define IRQ_IOP32X_DMA0_EOT    0
+#define IRQ_IOP32X_DMA0_EOC    1
+#define IRQ_IOP32X_DMA1_EOT    2
+#define IRQ_IOP32X_DMA1_EOC    3
+#define IRQ_IOP32X_AA_EOT      6
+#define IRQ_IOP32X_AA_EOC      7
+#define IRQ_IOP32X_CORE_PMON   8
+#define IRQ_IOP32X_TIMER0      9
+#define IRQ_IOP32X_TIMER1      10
+#define IRQ_IOP32X_I2C_0       11
+#define IRQ_IOP32X_I2C_1       12
+#define IRQ_IOP32X_MESSAGING   13
+#define IRQ_IOP32X_ATU_BIST    14
+#define IRQ_IOP32X_PERFMON     15
+#define IRQ_IOP32X_CORE_PMU    16
+#define IRQ_IOP32X_BIU_ERR     17
+#define IRQ_IOP32X_ATU_ERR     18
+#define IRQ_IOP32X_MCU_ERR     19
+#define IRQ_IOP32X_DMA0_ERR    20
+#define IRQ_IOP32X_DMA1_ERR    21
+#define IRQ_IOP32X_AA_ERR      23
+#define IRQ_IOP32X_MSG_ERR     24
+#define IRQ_IOP32X_SSP         25
+#define IRQ_IOP32X_XINT0       27
+#define IRQ_IOP32X_XINT1       28
+#define IRQ_IOP32X_XINT2       29
+#define IRQ_IOP32X_XINT3       30
+#define IRQ_IOP32X_HPI         31
+
+#define NR_IRQS                        32
+
+
+#endif
diff --git a/include/asm-arm/arch-iop32x/memory.h b/include/asm-arm/arch-iop32x/memory.h
new file mode 100644 (file)
index 0000000..764cd3f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * include/asm-arm/arch-iop32x/memory.h
+ */
+
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+#include <asm/hardware.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET    UL(0xa0000000)
+
+/*
+ * Virtual view <-> PCI DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *             address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *             to an address that the kernel can use.
+ */
+#define __virt_to_bus(x)       (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0))
+#define __bus_to_virt(x)       (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2)))
+
+
+#endif
diff --git a/include/asm-arm/arch-iop32x/n2100.h b/include/asm-arm/arch-iop32x/n2100.h
new file mode 100644 (file)
index 0000000..fed31a6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * include/asm/arch-iop32x/n2100.h
+ *
+ * Thecus N2100 board registers
+ */
+
+#ifndef __N2100_H
+#define __N2100_H
+
+#define N2100_UART             0xfe800000      /* UART */
+
+#define N2100_COPY_BUTTON      IOP3XX_GPIO_LINE(0)
+#define N2100_PCA9532_RESET    IOP3XX_GPIO_LINE(2)
+#define N2100_RESET_BUTTON     IOP3XX_GPIO_LINE(3)
+#define N2100_HARDWARE_RESET   IOP3XX_GPIO_LINE(4)
+#define N2100_POWER_BUTTON     IOP3XX_GPIO_LINE(5)
+
+
+#endif
diff --git a/include/asm-arm/arch-iop32x/system.h b/include/asm-arm/arch-iop32x/system.h
new file mode 100644 (file)
index 0000000..17b7eb7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * include/asm-arm/arch-iop32x/system.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/mach-types.h>
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+       local_irq_disable();
+
+       if (machine_is_n2100()) {
+               gpio_line_set(N2100_HARDWARE_RESET, GPIO_LOW);
+               gpio_line_config(N2100_HARDWARE_RESET, GPIO_OUT);
+               while (1)
+                       ;
+       }
+
+       *IOP3XX_PCSR = 0x30;
+
+       /* Jump into ROM at address 0 */
+       cpu_reset(0);
+}
diff --git a/include/asm-arm/arch-iop32x/timex.h b/include/asm-arm/arch-iop32x/timex.h
new file mode 100644 (file)
index 0000000..9934b08
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * include/asm-arm/arch-iop32x/timex.h
+ *
+ * IOP32x architecture timex specifications
+ */
+
+#include <asm/hardware.h>
+
+#define CLOCK_TICK_RATE                (100 * HZ)
diff --git a/include/asm-arm/arch-iop32x/uncompress.h b/include/asm-arm/arch-iop32x/uncompress.h
new file mode 100644 (file)
index 0000000..e64f52b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-iop32x/uncompress.h
+ */
+
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+#include <asm/hardware.h>
+
+static volatile u8 *uart_base;
+
+#define TX_DONE                (UART_LSR_TEMT | UART_LSR_THRE)
+
+static inline void putc(char c)
+{
+       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+               barrier();
+       uart_base[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+       if (machine_is_iq80321())
+               uart_base = (volatile u8 *)IQ80321_UART;
+       else if (machine_is_iq31244())
+               uart_base = (volatile u8 *)IQ31244_UART;
+       else
+               uart_base = (volatile u8 *)0xfe800000;
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-iop32x/vmalloc.h b/include/asm-arm/arch-iop32x/vmalloc.h
new file mode 100644 (file)
index 0000000..0a70baa
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * include/asm-arm/arch-iop32x/vmalloc.h
+ */
+
+#define VMALLOC_END    0xfe000000
diff --git a/include/asm-arm/arch-iop33x/debug-macro.S b/include/asm-arm/arch-iop33x/debug-macro.S
new file mode 100644 (file)
index 0000000..9e7132e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * include/asm-arm/arch-iop33x/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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.
+ */
+
+               .macro  addruart, rx
+               mrc     p15, 0, \rx, c1, c0
+               tst     \rx, #1                 @ mmu enabled?
+               moveq   \rx, #0xff000000        @ physical
+               movne   \rx, #0xfe000000        @ virtual
+               orr     \rx, \rx, #0x00ff0000
+               orr     \rx, \rx, #0x0000f700
+               .endm
+
+#define UART_SHIFT     2
+#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-iop33x/dma.h b/include/asm-arm/arch-iop33x/dma.h
new file mode 100644 (file)
index 0000000..b7775fd
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * include/asm-arm/arch-iop33x/dma.h
+ *
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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.
+ */
diff --git a/include/asm-arm/arch-iop33x/entry-macro.S b/include/asm-arm/arch-iop33x/entry-macro.S
new file mode 100644 (file)
index 0000000..92b7917
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * include/asm-arm/arch-iop33x/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IOP33x-based platforms
+ *
+ * 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 <asm/arch/iop33x.h>
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+               ldr     \base, =IOP3XX_REG_ADDR(0x07C8)
+               ldr     \irqstat, [\base]               @ Read IINTVEC
+               cmp     \irqstat, #0
+               ldreq   \irqstat, [\base]               @ erratum 63 workaround
+               adds    \irqnr, \irqstat, #1
+               movne   \irqnr, \irqstat, lsr #2
+               .endm
diff --git a/include/asm-arm/arch-iop33x/hardware.h b/include/asm-arm/arch-iop33x/hardware.h
new file mode 100644 (file)
index 0000000..0659cf9
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * include/asm-arm/arch-iop33x/hardware.h
+ */
+
+#ifndef __HARDWARE_H
+#define __HARDWARE_H
+
+#include <asm/types.h>
+
+/*
+ * Note about PCI IO space mappings
+ *
+ * To make IO space accesses efficient, we store virtual addresses in
+ * the IO resources.
+ *
+ * The PCI IO space is located at virtual 0xfe000000 from physical
+ * 0x90000000.  The PCI BARs must be programmed with physical addresses,
+ * but when we read them, we convert them to virtual addresses.  See
+ * arch/arm/mach-iop3xx/iop3xx-pci.c
+ */
+#define pcibios_assign_all_busses()    1
+#define PCIBIOS_MIN_IO         0x00000000
+#define PCIBIOS_MIN_MEM                0x00000000
+
+#ifndef __ASSEMBLY__
+void iop33x_init_irq(void);
+
+extern struct platform_device iop33x_uart0_device;
+extern struct platform_device iop33x_uart1_device;
+#endif
+
+
+/*
+ * Generic chipset bits
+ *
+ */
+#include "iop33x.h"
+
+/*
+ * Board specific bits
+ */
+#include "iq80331.h"
+#include "iq80332.h"
+
+
+#endif
diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h
new file mode 100644 (file)
index 0000000..c017402
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-iop33x/io.h
+ *
+ * Copyright (C) 2001  MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __IO_H
+#define __IO_H
+
+#include <asm/hardware.h>
+
+#define IO_SPACE_LIMIT         0xffffffff
+#define __io(p)                        ((void __iomem *)(p))
+#define __mem_pci(a)           (a)
+
+
+#endif
diff --git a/include/asm-arm/arch-iop33x/iop33x.h b/include/asm-arm/arch-iop33x/iop33x.h
new file mode 100644 (file)
index 0000000..7ac6e93
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * include/asm-arm/arch-iop33x/iop33x.h
+ *
+ * Intel IOP33X Chip definitions
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2003, 2004 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef __IOP33X_H
+#define __IOP33X_H
+
+/*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_GPIO_REG(reg)   (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1780 + (reg))
+#define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07d0 + (reg))
+
+#include <asm/hardware/iop3xx.h>
+
+/* UARTs  */
+#define IOP33X_UART0_PHYS      (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1700)
+#define IOP33X_UART0_VIRT      (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1700)
+#define IOP33X_UART1_PHYS      (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740)
+#define IOP33X_UART1_VIRT      (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740)
+
+
+#endif
similarity index 51%
rename from include/asm-arm/arch-iop3xx/iq80331.h
rename to include/asm-arm/arch-iop33x/iq80331.h
index 0668e78d483e377ab91c16f8419968f18e5654a0..79b9302017eaf6d6b96c182abf3e866156c9c4f9 100644 (file)
@@ -1,23 +1,16 @@
 /*
- * linux/include/asm/arch-iop3xx/iq80331.h
+ * include/asm-arm/arch-iop33x/iq80331.h
  *
  * Intel IQ80331 evaluation board registers
  */
 
-#ifndef _IQ80331_H_
-#define _IQ80331_H_
-
-#define        IQ80331_FLASHBASE       0xc0000000      /* Flash */
-#define        IQ80331_FLASHSIZE       0x00800000
-#define        IQ80331_FLASHWIDTH      1
+#ifndef __IQ80331_H
+#define __IQ80331_H
 
 #define IQ80331_7SEG_1         0xce840000      /* 7-Segment MSB */
 #define IQ80331_7SEG_0         0xce850000      /* 7-Segment LSB (WO) */
 #define IQ80331_ROTARY_SW      0xce8d0000      /* Rotary Switch */
 #define IQ80331_BATT_STAT      0xce8f0000      /* Battery Status */
 
-#ifndef __ASSEMBLY__
-extern void iq80331_map_io(void);
-#endif
 
-#endif // _IQ80331_H_
+#endif
similarity index 51%
rename from include/asm-arm/arch-iop3xx/iq80332.h
rename to include/asm-arm/arch-iop33x/iq80332.h
index e5fff1775d1a325b107cd5e580c3c7701de682dc..0531656294922532ae82c61dbd6d8d141ebffa25 100644 (file)
@@ -1,23 +1,16 @@
 /*
- * linux/include/asm/arch-iop3xx/iq80332.h
+ * include/asm-arm/arch-iop33x/iq80332.h
  *
  * Intel IQ80332 evaluation board registers
  */
 
-#ifndef _IQ80332_H_
-#define _IQ80332_H_
-
-#define        IQ80332_FLASHBASE       0xc0000000      /* Flash */
-#define        IQ80332_FLASHSIZE       0x00800000
-#define        IQ80332_FLASHWIDTH      1
+#ifndef __IQ80332_H
+#define __IQ80332_H
 
 #define IQ80332_7SEG_1         0xce840000      /* 7-Segment MSB */
 #define IQ80332_7SEG_0         0xce850000      /* 7-Segment LSB (WO) */
 #define IQ80332_ROTARY_SW      0xce8d0000      /* Rotary Switch */
 #define IQ80332_BATT_STAT      0xce8f0000      /* Battery Status */
 
-#ifndef __ASSEMBLY__
-extern void iq80332_map_io(void);
-#endif
 
-#endif // _IQ80332_H_
+#endif
diff --git a/include/asm-arm/arch-iop33x/irqs.h b/include/asm-arm/arch-iop33x/irqs.h
new file mode 100644 (file)
index 0000000..d045f84
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * include/asm-arm/arch-iop33x/irqs.h
+ *
+ * Author:     Dave Jiang (dave.jiang@intel.com)
+ * Copyright:  (C) 2003 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef __IRQS_H
+#define __IRQS_H
+
+/*
+ * IOP80331 chipset interrupts
+ */
+#define IRQ_IOP33X_DMA0_EOT    0
+#define IRQ_IOP33X_DMA0_EOC    1
+#define IRQ_IOP33X_DMA1_EOT    2
+#define IRQ_IOP33X_DMA1_EOC    3
+#define IRQ_IOP33X_AA_EOT      6
+#define IRQ_IOP33X_AA_EOC      7
+#define IRQ_IOP33X_TIMER0      8
+#define IRQ_IOP33X_TIMER1      9
+#define IRQ_IOP33X_I2C_0       10
+#define IRQ_IOP33X_I2C_1       11
+#define IRQ_IOP33X_MSG         12
+#define IRQ_IOP33X_MSGIBQ      13
+#define IRQ_IOP33X_ATU_BIST    14
+#define IRQ_IOP33X_PERFMON     15
+#define IRQ_IOP33X_CORE_PMU    16
+#define IRQ_IOP33X_XINT0       24
+#define IRQ_IOP33X_XINT1       25
+#define IRQ_IOP33X_XINT2       26
+#define IRQ_IOP33X_XINT3       27
+#define IRQ_IOP33X_XINT8       32
+#define IRQ_IOP33X_XINT9       33
+#define IRQ_IOP33X_XINT10      34
+#define IRQ_IOP33X_XINT11      35
+#define IRQ_IOP33X_XINT12      36
+#define IRQ_IOP33X_XINT13      37
+#define IRQ_IOP33X_XINT14      38
+#define IRQ_IOP33X_XINT15      39
+#define IRQ_IOP33X_UART0       51
+#define IRQ_IOP33X_UART1       52
+#define IRQ_IOP33X_PBIE                53
+#define IRQ_IOP33X_ATU_CRW     54
+#define IRQ_IOP33X_ATU_ERR     55
+#define IRQ_IOP33X_MCU_ERR     56
+#define IRQ_IOP33X_DMA0_ERR    57
+#define IRQ_IOP33X_DMA1_ERR    58
+#define IRQ_IOP33X_AA_ERR      60
+#define IRQ_IOP33X_MSG_ERR     62
+#define IRQ_IOP33X_HPI         63
+
+#define NR_IRQS                        64
+
+
+#endif
diff --git a/include/asm-arm/arch-iop33x/memory.h b/include/asm-arm/arch-iop33x/memory.h
new file mode 100644 (file)
index 0000000..0d39139
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * include/asm-arm/arch-iop33x/memory.h
+ */
+
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+#include <asm/hardware.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET    UL(0x00000000)
+
+/*
+ * Virtual view <-> PCI DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *             address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *             to an address that the kernel can use.
+ */
+#define __virt_to_bus(x)       (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0))
+#define __bus_to_virt(x)       (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2)))
+
+
+#endif
diff --git a/include/asm-arm/arch-iop33x/system.h b/include/asm-arm/arch-iop33x/system.h
new file mode 100644 (file)
index 0000000..00dd07e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * include/asm-arm/arch-iop33x/system.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+       *IOP3XX_PCSR = 0x30;
+
+       /* Jump into ROM at address 0 */
+       cpu_reset(0);
+}
diff --git a/include/asm-arm/arch-iop33x/timex.h b/include/asm-arm/arch-iop33x/timex.h
new file mode 100644 (file)
index 0000000..fe3e1e3
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * include/asm-arm/arch-iop33x/timex.h
+ *
+ * IOP3xx architecture timex specifications
+ */
+
+#include <asm/hardware.h>
+
+#define CLOCK_TICK_RATE                (100 * HZ)
diff --git a/include/asm-arm/arch-iop33x/uncompress.h b/include/asm-arm/arch-iop33x/uncompress.h
new file mode 100644 (file)
index 0000000..e17fbc0
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * include/asm-arm/arch-iop33x/uncompress.h
+ */
+
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+#include <asm/hardware.h>
+
+static volatile u32 *uart_base;
+
+#define TX_DONE                (UART_LSR_TEMT | UART_LSR_THRE)
+
+static inline void putc(char c)
+{
+       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+               barrier();
+       uart_base[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+       if (machine_is_iq80331() || machine_is_iq80332())
+               uart_base = (volatile u32 *)IOP33X_UART0_PHYS;
+       else
+               uart_base = (volatile u32 *)0xfe800000;
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-iop33x/vmalloc.h b/include/asm-arm/arch-iop33x/vmalloc.h
new file mode 100644 (file)
index 0000000..66f545a
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * include/asm-arm/arch-iop33x/vmalloc.h
+ */
+
+#define VMALLOC_END    0xfe000000
diff --git a/include/asm-arm/arch-iop3xx/debug-macro.S b/include/asm-arm/arch-iop3xx/debug-macro.S
deleted file mode 100644 (file)
index ce007e5..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* linux/include/asm-arm/arch-iop3xx/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * 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.
- *
-*/
-
-               .macro  addruart,rx
-               mov     \rx, #0xfe000000        @ physical
-#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
-               orr     \rx, \rx, #0x00800000   @ location of the UART
-#elif defined(CONFIG_ARCH_IOP331)
-               mrc     p15, 0, \rx, c1, c0
-               tst     \rx, #1                 @ MMU enabled?
-               moveq   \rx, #0x000fe000        @ Physical Base
-               movne   \rx, #0
-               orr     \rx, \rx, #0xfe000000
-               orr     \rx, \rx, #0x00f00000   @ Virtual Base
-               orr     \rx, \rx, #0x00001700   @ location of the UART
-#else
-#error Unknown IOP3XX implementation
-#endif
-               .endm
-
-#if !defined(CONFIG_ARCH_IQ80321) || !defined(CONFIG_ARCH_IQ31244) || !defined(CONFIG_ARCH_IQ80331)
-#define FLOW_CONTROL
-#endif
-#define UART_SHIFT     0
-#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-iop3xx/entry-macro.S b/include/asm-arm/arch-iop3xx/entry-macro.S
deleted file mode 100644 (file)
index 926668c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * include/asm-arm/arch-iop3xx/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP3xx-based platforms
- *
- * 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 <asm/arch/irqs.h>
-
-#if defined(CONFIG_ARCH_IOP321)
-               .macro  disable_fiq
-               .endm
-
-               /*
-                * Note: only deal with normal interrupts, not FIQ
-                */
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               mov     \irqnr, #0
-               mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
-               cmp     \irqstat, #0
-               beq     1001f
-               clz     \irqnr, \irqstat
-               mov     \base, #31
-               subs    \irqnr,\base,\irqnr
-               add     \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
-1001:
-               .endm
-
-#elif defined(CONFIG_ARCH_IOP331)
-               .macro  disable_fiq
-               .endm
-
-               /*
-                * Note: only deal with normal interrupts, not FIQ
-                */
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               mov     \irqnr, #0
-               mrc     p6, 0, \irqstat, c4, c0, 0      @ Read IINTSRC0
-               cmp     \irqstat, #0
-               bne     1002f
-               mrc     p6, 0, \irqstat, c5, c0, 0      @ Read IINTSRC1
-               cmp     \irqstat, #0
-               beq     1001f
-               clz     \irqnr, \irqstat
-               rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
-               add     \irqnr,\irqnr,#IRQ_IOP331_XINT8
-               b       1001f
-1002:  clz     \irqnr, \irqstat
-               rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
-               add     \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT
-1001:
-               .endm
-
-#endif
-
diff --git a/include/asm-arm/arch-iop3xx/hardware.h b/include/asm-arm/arch-iop3xx/hardware.h
deleted file mode 100644 (file)
index 3b13817..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/hardware.h
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/types.h>
-
-/*
- * Note about PCI IO space mappings
- *
- * To make IO space accesses efficient, we store virtual addresses in
- * the IO resources.
- *
- * The PCI IO space is located at virtual 0xfe000000 from physical
- * 0x90000000.  The PCI BARs must be programmed with physical addresses,
- * but when we read them, we convert them to virtual addresses.  See
- * arch/arm/mach-iop3xx/iop3xx-pci.c
- */
-
-#define pcibios_assign_all_busses() 1
-
-
-/*
- * The min PCI I/O and MEM space are dependent on what specific
- * chipset/platform we are running on, so instead of hardcoding with
- * #ifdefs, we just fill these in the platform level PCI init code.
- */
-#ifndef __ASSEMBLY__
-extern unsigned long iop3xx_pcibios_min_io;
-extern unsigned long iop3xx_pcibios_min_mem;
-
-extern unsigned int processor_id;
-#endif
-
-/*
- * We just set these to zero since they are really bogus anyways
- */
-#define PCIBIOS_MIN_IO      (iop3xx_pcibios_min_io)
-#define PCIBIOS_MIN_MEM     (iop3xx_pcibios_min_mem)
-
-/*
- * Generic chipset bits
- *
- */
-#include "iop321.h"
-#include "iop331.h"
-
-/*
- * Board specific bits
- */
-#include "iq80321.h"
-#include "iq31244.h"
-#include "iq80331.h"
-#include "iq80332.h"
-
-#endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-iop3xx/iop321-irqs.h b/include/asm-arm/arch-iop3xx/iop321-irqs.h
deleted file mode 100644 (file)
index 2fcc165..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/irqs.h
- *
- * Author:     Rory Bolt <rorybolt@pacbell.net>
- * Copyright:  (C) 2002 Rory Bolt
- *
- * 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.
- *
- */
-#ifndef _IOP321_IRQS_H_
-#define _IOP321_IRQS_H_
-
-/*
- * IOP80321 chipset interrupts
- */
-#define IOP321_IRQ_OFS         0
-#define IOP321_IRQ(x)          (IOP321_IRQ_OFS + (x))
-
-/*
- * On IRQ or FIQ register
- */
-#define IRQ_IOP321_DMA0_EOT    IOP321_IRQ(0)
-#define IRQ_IOP321_DMA0_EOC    IOP321_IRQ(1)
-#define IRQ_IOP321_DMA1_EOT    IOP321_IRQ(2)
-#define IRQ_IOP321_DMA1_EOC    IOP321_IRQ(3)
-#define IRQ_IOP321_RSVD_4      IOP321_IRQ(4)
-#define IRQ_IOP321_RSVD_5      IOP321_IRQ(5)
-#define IRQ_IOP321_AA_EOT      IOP321_IRQ(6)
-#define IRQ_IOP321_AA_EOC      IOP321_IRQ(7)
-#define IRQ_IOP321_CORE_PMON   IOP321_IRQ(8)
-#define IRQ_IOP321_TIMER0      IOP321_IRQ(9)
-#define IRQ_IOP321_TIMER1      IOP321_IRQ(10)
-#define IRQ_IOP321_I2C_0       IOP321_IRQ(11)
-#define IRQ_IOP321_I2C_1       IOP321_IRQ(12)
-#define IRQ_IOP321_MESSAGING   IOP321_IRQ(13)
-#define IRQ_IOP321_ATU_BIST    IOP321_IRQ(14)
-#define IRQ_IOP321_PERFMON     IOP321_IRQ(15)
-#define IRQ_IOP321_CORE_PMU    IOP321_IRQ(16)
-#define IRQ_IOP321_BIU_ERR     IOP321_IRQ(17)
-#define IRQ_IOP321_ATU_ERR     IOP321_IRQ(18)
-#define IRQ_IOP321_MCU_ERR     IOP321_IRQ(19)
-#define IRQ_IOP321_DMA0_ERR    IOP321_IRQ(20)
-#define IRQ_IOP321_DMA1_ERR    IOP321_IRQ(21)
-#define IRQ_IOP321_RSVD_22     IOP321_IRQ(22)
-#define IRQ_IOP321_AA_ERR      IOP321_IRQ(23)
-#define IRQ_IOP321_MSG_ERR     IOP321_IRQ(24)
-#define IRQ_IOP321_SSP         IOP321_IRQ(25)
-#define IRQ_IOP321_RSVD_26     IOP321_IRQ(26)
-#define IRQ_IOP321_XINT0       IOP321_IRQ(27)
-#define IRQ_IOP321_XINT1       IOP321_IRQ(28)
-#define IRQ_IOP321_XINT2       IOP321_IRQ(29)
-#define IRQ_IOP321_XINT3       IOP321_IRQ(30)
-#define IRQ_IOP321_HPI         IOP321_IRQ(31)
-
-#define NR_IOP321_IRQS         (IOP321_IRQ(31) + 1)
-
-#define NR_IRQS                        NR_IOP321_IRQS
-
-
-/*
- * Interrupts available on the IQ80321 board
- */
-
-/*
- * On board devices
- */
-#define        IRQ_IQ80321_I82544      IRQ_IOP321_XINT0
-#define IRQ_IQ80321_UART       IRQ_IOP321_XINT1
-
-/*
- * PCI interrupts
- */
-#define        IRQ_IQ80321_INTA        IRQ_IOP321_XINT0
-#define        IRQ_IQ80321_INTB        IRQ_IOP321_XINT1
-#define        IRQ_IQ80321_INTC        IRQ_IOP321_XINT2
-#define        IRQ_IQ80321_INTD        IRQ_IOP321_XINT3
-
-/*
- * Interrupts on the IQ31244 board
- */
-
-/*
- * On board devices
- */
-#define IRQ_IQ31244_UART       IRQ_IOP321_XINT1
-#define        IRQ_IQ31244_I82546      IRQ_IOP321_XINT0
-#define IRQ_IQ31244_SATA       IRQ_IOP321_XINT2
-#define        IRQ_IQ31244_PCIX_SLOT   IRQ_IOP321_XINT3
-
-/*
- * PCI interrupts
- */
-#define        IRQ_IQ31244_INTA        IRQ_IOP321_XINT0
-#define        IRQ_IQ31244_INTB        IRQ_IOP321_XINT1
-#define        IRQ_IQ31244_INTC        IRQ_IOP321_XINT2
-#define        IRQ_IQ31244_INTD        IRQ_IOP321_XINT3
-
-#endif // _IOP321_IRQ_H_
diff --git a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h
deleted file mode 100644 (file)
index f8df778..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * linux/include/asm/arch-iop3xx/iop321.h
- *
- * Intel IOP321 Chip definitions
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- * Copyright (C) 2004 Intel Corp.
- *
- * 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.
- */
-
-#ifndef _IOP321_HW_H_
-#define _IOP321_HW_H_
-
-
-/*
- * This is needed for mixed drivers that need to work on all
- * IOP3xx variants but behave slightly differently on each.
- */
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_ARCH_IOP321
-#define iop_is_321() (((processor_id & 0xfffff5e0) == 0x69052420))
-#else
-#define        iop_is_321()    0
-#endif
-#endif
-
-/*
- * IOP321 I/O and Mem space regions for PCI autoconfiguration
- */
-#define IOP321_PCI_IO_WINDOW_SIZE   0x00010000
-#define IOP321_PCI_LOWER_IO_PA      0x90000000
-#define IOP321_PCI_LOWER_IO_VA      0xfe000000
-#define IOP321_PCI_LOWER_IO_BA      (*IOP321_OIOWTVR)
-#define IOP321_PCI_UPPER_IO_PA      (IOP321_PCI_LOWER_IO_PA + IOP321_PCI_IO_WINDOW_SIZE - 1)
-#define IOP321_PCI_UPPER_IO_VA      (IOP321_PCI_LOWER_IO_VA + IOP321_PCI_IO_WINDOW_SIZE - 1)
-#define IOP321_PCI_UPPER_IO_BA      (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1)
-#define IOP321_PCI_IO_OFFSET        (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA)
-
-/* #define IOP321_PCI_MEM_WINDOW_SIZE  (~*IOP321_IALR1 + 1) */
-#define IOP321_PCI_MEM_WINDOW_SIZE  0x04000000 /* 64M outbound window */
-#define IOP321_PCI_LOWER_MEM_PA     0x80000000
-#define IOP321_PCI_LOWER_MEM_BA     (*IOP321_OMWTVR0)
-#define IOP321_PCI_UPPER_MEM_PA     (IOP321_PCI_LOWER_MEM_PA + IOP321_PCI_MEM_WINDOW_SIZE - 1)
-#define IOP321_PCI_UPPER_MEM_BA     (IOP321_PCI_LOWER_MEM_BA + IOP321_PCI_MEM_WINDOW_SIZE - 1)
-#define IOP321_PCI_MEM_OFFSET       (IOP321_PCI_LOWER_MEM_PA - IOP321_PCI_LOWER_MEM_BA)
-
-
-/*
- * IOP321 chipset registers
- */
-#define IOP321_VIRT_MEM_BASE 0xfeffe000  /* chip virtual mem address*/
-#define IOP321_PHYS_MEM_BASE 0xffffe000  /* chip physical memory address */
-#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg))
-
-/* Reserved 0x00000000 through 0x000000FF */
-
-/* Address Translation Unit 0x00000100 through 0x000001FF */
-#define IOP321_ATUVID     (volatile u16 *)IOP321_REG_ADDR(0x00000100)
-#define IOP321_ATUDID     (volatile u16 *)IOP321_REG_ADDR(0x00000102)
-#define IOP321_ATUCMD     (volatile u16 *)IOP321_REG_ADDR(0x00000104)
-#define IOP321_ATUSR      (volatile u16 *)IOP321_REG_ADDR(0x00000106)
-#define IOP321_ATURID     (volatile u8  *)IOP321_REG_ADDR(0x00000108)
-#define IOP321_ATUCCR     (volatile u32 *)IOP321_REG_ADDR(0x00000109)
-#define IOP321_ATUCLSR    (volatile u8  *)IOP321_REG_ADDR(0x0000010C)
-#define IOP321_ATULT      (volatile u8  *)IOP321_REG_ADDR(0x0000010D)
-#define IOP321_ATUHTR     (volatile u8  *)IOP321_REG_ADDR(0x0000010E)
-#define IOP321_ATUBIST    (volatile u8  *)IOP321_REG_ADDR(0x0000010F)
-#define IOP321_IABAR0     (volatile u32 *)IOP321_REG_ADDR(0x00000110)
-#define IOP321_IAUBAR0    (volatile u32 *)IOP321_REG_ADDR(0x00000114)
-#define IOP321_IABAR1     (volatile u32 *)IOP321_REG_ADDR(0x00000118)
-#define IOP321_IAUBAR1    (volatile u32 *)IOP321_REG_ADDR(0x0000011C)
-#define IOP321_IABAR2     (volatile u32 *)IOP321_REG_ADDR(0x00000120)
-#define IOP321_IAUBAR2    (volatile u32 *)IOP321_REG_ADDR(0x00000124)
-#define IOP321_ASVIR      (volatile u16 *)IOP321_REG_ADDR(0x0000012C)
-#define IOP321_ASIR       (volatile u16 *)IOP321_REG_ADDR(0x0000012E)
-#define IOP321_ERBAR      (volatile u32 *)IOP321_REG_ADDR(0x00000130)
-/* Reserved 0x00000134 through 0x0000013B */
-#define IOP321_ATUILR     (volatile u8  *)IOP321_REG_ADDR(0x0000013C)
-#define IOP321_ATUIPR     (volatile u8  *)IOP321_REG_ADDR(0x0000013D)
-#define IOP321_ATUMGNT    (volatile u8  *)IOP321_REG_ADDR(0x0000013E)
-#define IOP321_ATUMLAT    (volatile u8  *)IOP321_REG_ADDR(0x0000013F)
-#define IOP321_IALR0      (volatile u32 *)IOP321_REG_ADDR(0x00000140)
-#define IOP321_IATVR0     (volatile u32 *)IOP321_REG_ADDR(0x00000144)
-#define IOP321_ERLR       (volatile u32 *)IOP321_REG_ADDR(0x00000148)
-#define IOP321_ERTVR      (volatile u32 *)IOP321_REG_ADDR(0x0000014C)
-#define IOP321_IALR1      (volatile u32 *)IOP321_REG_ADDR(0x00000150)
-#define IOP321_IALR2      (volatile u32 *)IOP321_REG_ADDR(0x00000154)
-#define IOP321_IATVR2     (volatile u32 *)IOP321_REG_ADDR(0x00000158)
-#define IOP321_OIOWTVR    (volatile u32 *)IOP321_REG_ADDR(0x0000015C)
-#define IOP321_OMWTVR0    (volatile u32 *)IOP321_REG_ADDR(0x00000160)
-#define IOP321_OUMWTVR0   (volatile u32 *)IOP321_REG_ADDR(0x00000164)
-#define IOP321_OMWTVR1    (volatile u32 *)IOP321_REG_ADDR(0x00000168)
-#define IOP321_OUMWTVR1   (volatile u32 *)IOP321_REG_ADDR(0x0000016C)
-/* Reserved 0x00000170 through 0x00000177*/
-#define IOP321_OUDWTVR    (volatile u32 *)IOP321_REG_ADDR(0x00000178)
-/* Reserved 0x0000017C through 0x0000017F*/
-#define IOP321_ATUCR      (volatile u32 *)IOP321_REG_ADDR(0x00000180)
-#define IOP321_PCSR       (volatile u32 *)IOP321_REG_ADDR(0x00000184)
-#define IOP321_ATUISR     (volatile u32 *)IOP321_REG_ADDR(0x00000188)
-#define IOP321_ATUIMR     (volatile u32 *)IOP321_REG_ADDR(0x0000018C)
-#define IOP321_IABAR3     (volatile u32 *)IOP321_REG_ADDR(0x00000190)
-#define IOP321_IAUBAR3    (volatile u32 *)IOP321_REG_ADDR(0x00000194)
-#define IOP321_IALR3      (volatile u32 *)IOP321_REG_ADDR(0x00000198)
-#define IOP321_IATVR3     (volatile u32 *)IOP321_REG_ADDR(0x0000019C)
-/* Reserved 0x000001A0 through 0x000001A3*/
-#define IOP321_OCCAR      (volatile u32 *)IOP321_REG_ADDR(0x000001A4)
-/* Reserved 0x000001A8 through 0x000001AB*/
-#define IOP321_OCCDR      (volatile u32 *)IOP321_REG_ADDR(0x000001AC)
-/* Reserved 0x000001B0 through 0x000001BB*/
-#define IOP321_PDSCR      (volatile u32 *)IOP321_REG_ADDR(0x000001BC)
-#define IOP321_PMCAPID    (volatile u8  *)IOP321_REG_ADDR(0x000001C0)
-#define IOP321_PMNEXT     (volatile u8  *)IOP321_REG_ADDR(0x000001C1)
-#define IOP321_APMCR      (volatile u16 *)IOP321_REG_ADDR(0x000001C2)
-#define IOP321_APMCSR     (volatile u16 *)IOP321_REG_ADDR(0x000001C4)
-/* Reserved 0x000001C6 through 0x000001DF */
-#define IOP321_PCIXCAPID  (volatile u8  *)IOP321_REG_ADDR(0x000001E0)
-#define IOP321_PCIXNEXT   (volatile u8  *)IOP321_REG_ADDR(0x000001E1)
-#define IOP321_PCIXCMD    (volatile u16 *)IOP321_REG_ADDR(0x000001E2)
-#define IOP321_PCIXSR     (volatile u32 *)IOP321_REG_ADDR(0x000001E4)
-#define IOP321_PCIIRSR    (volatile u32 *)IOP321_REG_ADDR(0x000001EC)
-
-/* Messaging Unit 0x00000300 through 0x000003FF */
-
-/* Reserved 0x00000300 through 0x0000030c */
-#define IOP321_IMR0       (volatile u32 *)IOP321_REG_ADDR(0x00000310)
-#define IOP321_IMR1       (volatile u32 *)IOP321_REG_ADDR(0x00000314)
-#define IOP321_OMR0       (volatile u32 *)IOP321_REG_ADDR(0x00000318)
-#define IOP321_OMR1       (volatile u32 *)IOP321_REG_ADDR(0x0000031C)
-#define IOP321_IDR        (volatile u32 *)IOP321_REG_ADDR(0x00000320)
-#define IOP321_IISR       (volatile u32 *)IOP321_REG_ADDR(0x00000324)
-#define IOP321_IIMR       (volatile u32 *)IOP321_REG_ADDR(0x00000328)
-#define IOP321_ODR        (volatile u32 *)IOP321_REG_ADDR(0x0000032C)
-#define IOP321_OISR       (volatile u32 *)IOP321_REG_ADDR(0x00000330)
-#define IOP321_OIMR       (volatile u32 *)IOP321_REG_ADDR(0x00000334)
-/* Reserved 0x00000338 through 0x0000034F */
-#define IOP321_MUCR       (volatile u32 *)IOP321_REG_ADDR(0x00000350)
-#define IOP321_QBAR       (volatile u32 *)IOP321_REG_ADDR(0x00000354)
-/* Reserved 0x00000358 through 0x0000035C */
-#define IOP321_IFHPR      (volatile u32 *)IOP321_REG_ADDR(0x00000360)
-#define IOP321_IFTPR      (volatile u32 *)IOP321_REG_ADDR(0x00000364)
-#define IOP321_IPHPR      (volatile u32 *)IOP321_REG_ADDR(0x00000368)
-#define IOP321_IPTPR      (volatile u32 *)IOP321_REG_ADDR(0x0000036C)
-#define IOP321_OFHPR      (volatile u32 *)IOP321_REG_ADDR(0x00000370)
-#define IOP321_OFTPR      (volatile u32 *)IOP321_REG_ADDR(0x00000374)
-#define IOP321_OPHPR      (volatile u32 *)IOP321_REG_ADDR(0x00000378)
-#define IOP321_OPTPR      (volatile u32 *)IOP321_REG_ADDR(0x0000037C)
-#define IOP321_IAR        (volatile u32 *)IOP321_REG_ADDR(0x00000380)
-
-#define IOP321_IIxR_MASK       0x7f /* masks all */
-#define IOP321_IIxR_IRI                0x40 /* RC Index Register Interrupt */
-#define IOP321_IIxR_OFQF       0x20 /* RC Output Free Q Full (ERROR) */
-#define IOP321_IIxR_ipq                0x10 /* RC Inbound Post Q (post) */
-#define IOP321_IIxR_ERRDI      0x08 /* RO Error Doorbell Interrupt */
-#define IOP321_IIxR_IDI                0x04 /* RO Inbound Doorbell Interrupt */
-#define IOP321_IIxR_IM1                0x02 /* RC Inbound Message 1 Interrupt */
-#define IOP321_IIxR_IM0                0x01 /* RC Inbound Message 0 Interrupt */
-
-/* Reserved 0x00000384 through 0x000003FF */
-
-/* DMA Controller 0x00000400 through 0x000004FF */
-#define IOP321_DMA0_CCR   (volatile u32 *)IOP321_REG_ADDR(0x00000400)
-#define IOP321_DMA0_CSR   (volatile u32 *)IOP321_REG_ADDR(0x00000404)
-#define IOP321_DMA0_DAR   (volatile u32 *)IOP321_REG_ADDR(0x0000040C)
-#define IOP321_DMA0_NDAR  (volatile u32 *)IOP321_REG_ADDR(0x00000410)
-#define IOP321_DMA0_PADR  (volatile u32 *)IOP321_REG_ADDR(0x00000414)
-#define IOP321_DMA0_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000418)
-#define IOP321_DMA0_LADR  (volatile u32 *)IOP321_REG_ADDR(0X0000041C)
-#define IOP321_DMA0_BCR   (volatile u32 *)IOP321_REG_ADDR(0x00000420)
-#define IOP321_DMA0_DCR   (volatile u32 *)IOP321_REG_ADDR(0x00000424)
-/* Reserved 0x00000428 through 0x0000043C */
-#define IOP321_DMA1_CCR   (volatile u32 *)IOP321_REG_ADDR(0x00000440)
-#define IOP321_DMA1_CSR   (volatile u32 *)IOP321_REG_ADDR(0x00000444)
-#define IOP321_DMA1_DAR   (volatile u32 *)IOP321_REG_ADDR(0x0000044C)
-#define IOP321_DMA1_NDAR  (volatile u32 *)IOP321_REG_ADDR(0x00000450)
-#define IOP321_DMA1_PADR  (volatile u32 *)IOP321_REG_ADDR(0x00000454)
-#define IOP321_DMA1_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000458)
-#define IOP321_DMA1_LADR  (volatile u32 *)IOP321_REG_ADDR(0x0000045C)
-#define IOP321_DMA1_BCR   (volatile u32 *)IOP321_REG_ADDR(0x00000460)
-#define IOP321_DMA1_DCR   (volatile u32 *)IOP321_REG_ADDR(0x00000464)
-/* Reserved 0x00000468 through 0x000004FF */
-
-/* Memory controller 0x00000500 through 0x0005FF */
-
-/* Peripheral bus interface unit 0x00000680 through 0x0006FF */
-#define IOP321_PBCR       (volatile u32 *)IOP321_REG_ADDR(0x00000680)
-#define IOP321_PBISR      (volatile u32 *)IOP321_REG_ADDR(0x00000684)
-#define IOP321_PBBAR0     (volatile u32 *)IOP321_REG_ADDR(0x00000688)
-#define IOP321_PBLR0      (volatile u32 *)IOP321_REG_ADDR(0x0000068C)
-#define IOP321_PBBAR1     (volatile u32 *)IOP321_REG_ADDR(0x00000690)
-#define IOP321_PBLR1      (volatile u32 *)IOP321_REG_ADDR(0x00000694)
-#define IOP321_PBBAR2     (volatile u32 *)IOP321_REG_ADDR(0x00000698)
-#define IOP321_PBLR2      (volatile u32 *)IOP321_REG_ADDR(0x0000069C)
-#define IOP321_PBBAR3     (volatile u32 *)IOP321_REG_ADDR(0x000006A0)
-#define IOP321_PBLR3      (volatile u32 *)IOP321_REG_ADDR(0x000006A4)
-#define IOP321_PBBAR4     (volatile u32 *)IOP321_REG_ADDR(0x000006A8)
-#define IOP321_PBLR4      (volatile u32 *)IOP321_REG_ADDR(0x000006AC)
-#define IOP321_PBBAR5     (volatile u32 *)IOP321_REG_ADDR(0x000006B0)
-#define IOP321_PBLR5      (volatile u32 *)IOP321_REG_ADDR(0x000006B4)
-#define IOP321_PBDSCR     (volatile u32 *)IOP321_REG_ADDR(0x000006B8)
-/* Reserved 0x000006BC */
-#define IOP321_PMBR0      (volatile u32 *)IOP321_REG_ADDR(0x000006C0)
-/* Reserved 0x000006C4 through 0x000006DC */
-#define IOP321_PMBR1      (volatile u32 *)IOP321_REG_ADDR(0x000006E0)
-#define IOP321_PMBR2      (volatile u32 *)IOP321_REG_ADDR(0x000006E4)
-
-#define IOP321_PBCR_EN    0x1
-
-#define IOP321_PBISR_BOOR_ERR 0x1
-
-/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */
-#define IOP321_GTMR    (volatile u32 *)IOP321_REG_ADDR(0x00000700)
-#define IOP321_ESR     (volatile u32 *)IOP321_REG_ADDR(0x00000704)
-#define IOP321_EMISR   (volatile u32 *)IOP321_REG_ADDR(0x00000708)
-/* reserved 0x00000070c */
-#define IOP321_GTSR    (volatile u32 *)IOP321_REG_ADDR(0x00000710)
-/* PERC0 DOESN'T EXIST - index from 1! */
-#define IOP321_PERCR0  (volatile u32 *)IOP321_REG_ADDR(0x00000710)
-
-#define IOP321_GTMR_NGCE       0x04 /* (Not) Global Counter Enable */
-
-/* Internal arbitration unit 0x00000780 through 0x0007BF */
-#define IOP321_IACR    (volatile u32 *)IOP321_REG_ADDR(0x00000780)
-#define IOP321_MTTR1   (volatile u32 *)IOP321_REG_ADDR(0x00000784)
-#define IOP321_MTTR2   (volatile u32 *)IOP321_REG_ADDR(0x00000788)
-
-/* General Purpose I/O Registers */
-#define IOP321_GPOE       (volatile u32 *)IOP321_REG_ADDR(0x000007C4)
-#define IOP321_GPID       (volatile u32 *)IOP321_REG_ADDR(0x000007C8)
-#define IOP321_GPOD       (volatile u32 *)IOP321_REG_ADDR(0x000007CC)
-
-/* Interrupt Controller */
-#define IOP321_INTCTL     (volatile u32 *)IOP321_REG_ADDR(0x000007D0)
-#define IOP321_INTSTR     (volatile u32 *)IOP321_REG_ADDR(0x000007D4)
-#define IOP321_IINTSRC    (volatile u32 *)IOP321_REG_ADDR(0x000007D8)
-#define IOP321_FINTSRC    (volatile u32 *)IOP321_REG_ADDR(0x000007DC)
-
-/* Timers */
-
-#define IOP321_TU_TMR0         (volatile u32 *)IOP321_REG_ADDR(0x000007E0)
-#define IOP321_TU_TMR1         (volatile u32 *)IOP321_REG_ADDR(0x000007E4)
-
-#ifdef CONFIG_ARCH_IQ80321
-#define        IOP321_TICK_RATE        200000000       /* 200 MHz clock */
-#elif defined(CONFIG_ARCH_IQ31244)
-#define IOP321_TICK_RATE       198000000       /* 33.000 MHz crystal */
-#endif
-
-#ifdef CONFIG_ARCH_EP80219
-#undef IOP321_TICK_RATE
-#define IOP321_TICK_RATE 200000000 /* 33.333333 Mhz crystal */
-#endif
-
-#define IOP321_TMR_TC          0x01
-#define        IOP321_TMR_EN           0x02
-#define IOP321_TMR_RELOAD      0x04
-#define        IOP321_TMR_PRIVILEGED   0x09
-
-#define        IOP321_TMR_RATIO_1_1    0x00
-#define        IOP321_TMR_RATIO_4_1    0x10
-#define        IOP321_TMR_RATIO_8_1    0x20
-#define        IOP321_TMR_RATIO_16_1   0x30
-
-#define IOP321_TU_TCR0    (volatile u32 *)IOP321_REG_ADDR(0x000007E8)
-#define IOP321_TU_TCR1    (volatile u32 *)IOP321_REG_ADDR(0x000007EC)
-#define IOP321_TU_TRR0    (volatile u32 *)IOP321_REG_ADDR(0x000007F0)
-#define IOP321_TU_TRR1    (volatile u32 *)IOP321_REG_ADDR(0x000007F4)
-#define IOP321_TU_TISR    (volatile u32 *)IOP321_REG_ADDR(0x000007F8)
-#define IOP321_TU_WDTCR   (volatile u32 *)IOP321_REG_ADDR(0x000007FC)
-
-/* Application accelerator unit 0x00000800 - 0x000008FF */
-#define IOP321_AAU_ACR     (volatile u32 *)IOP321_REG_ADDR(0x00000800)
-#define IOP321_AAU_ASR     (volatile u32 *)IOP321_REG_ADDR(0x00000804)
-#define IOP321_AAU_ADAR    (volatile u32 *)IOP321_REG_ADDR(0x00000808)
-#define IOP321_AAU_ANDAR   (volatile u32 *)IOP321_REG_ADDR(0x0000080C)
-#define IOP321_AAU_SAR1    (volatile u32 *)IOP321_REG_ADDR(0x00000810)
-#define IOP321_AAU_SAR2    (volatile u32 *)IOP321_REG_ADDR(0x00000814)
-#define IOP321_AAU_SAR3    (volatile u32 *)IOP321_REG_ADDR(0x00000818)
-#define IOP321_AAU_SAR4    (volatile u32 *)IOP321_REG_ADDR(0x0000081C)
-#define IOP321_AAU_SAR5    (volatile u32 *)IOP321_REG_ADDR(0x0000082C)
-#define IOP321_AAU_SAR6    (volatile u32 *)IOP321_REG_ADDR(0x00000830)
-#define IOP321_AAU_SAR7    (volatile u32 *)IOP321_REG_ADDR(0x00000834)
-#define IOP321_AAU_SAR8    (volatile u32 *)IOP321_REG_ADDR(0x00000838)
-#define IOP321_AAU_SAR9    (volatile u32 *)IOP321_REG_ADDR(0x00000840)
-#define IOP321_AAU_SAR10   (volatile u32 *)IOP321_REG_ADDR(0x00000844)
-#define IOP321_AAU_SAR11   (volatile u32 *)IOP321_REG_ADDR(0x00000848)
-#define IOP321_AAU_SAR12   (volatile u32 *)IOP321_REG_ADDR(0x0000084C)
-#define IOP321_AAU_SAR13   (volatile u32 *)IOP321_REG_ADDR(0x00000850)
-#define IOP321_AAU_SAR14   (volatile u32 *)IOP321_REG_ADDR(0x00000854)
-#define IOP321_AAU_SAR15   (volatile u32 *)IOP321_REG_ADDR(0x00000858)
-#define IOP321_AAU_SAR16   (volatile u32 *)IOP321_REG_ADDR(0x0000085C)
-#define IOP321_AAU_SAR17   (volatile u32 *)IOP321_REG_ADDR(0x00000864)
-#define IOP321_AAU_SAR18   (volatile u32 *)IOP321_REG_ADDR(0x00000868)
-#define IOP321_AAU_SAR19   (volatile u32 *)IOP321_REG_ADDR(0x0000086C)
-#define IOP321_AAU_SAR20   (volatile u32 *)IOP321_REG_ADDR(0x00000870)
-#define IOP321_AAU_SAR21   (volatile u32 *)IOP321_REG_ADDR(0x00000874)
-#define IOP321_AAU_SAR22   (volatile u32 *)IOP321_REG_ADDR(0x00000878)
-#define IOP321_AAU_SAR23   (volatile u32 *)IOP321_REG_ADDR(0x0000087C)
-#define IOP321_AAU_SAR24   (volatile u32 *)IOP321_REG_ADDR(0x00000880)
-#define IOP321_AAU_SAR25   (volatile u32 *)IOP321_REG_ADDR(0x00000888)
-#define IOP321_AAU_SAR26   (volatile u32 *)IOP321_REG_ADDR(0x0000088C)
-#define IOP321_AAU_SAR27   (volatile u32 *)IOP321_REG_ADDR(0x00000890)
-#define IOP321_AAU_SAR28   (volatile u32 *)IOP321_REG_ADDR(0x00000894)
-#define IOP321_AAU_SAR29   (volatile u32 *)IOP321_REG_ADDR(0x00000898)
-#define IOP321_AAU_SAR30   (volatile u32 *)IOP321_REG_ADDR(0x0000089C)
-#define IOP321_AAU_SAR31   (volatile u32 *)IOP321_REG_ADDR(0x000008A0)
-#define IOP321_AAU_SAR32   (volatile u32 *)IOP321_REG_ADDR(0x000008A4)
-#define IOP321_AAU_DAR     (volatile u32 *)IOP321_REG_ADDR(0x00000820)
-#define IOP321_AAU_ABCR    (volatile u32 *)IOP321_REG_ADDR(0x00000824)
-#define IOP321_AAU_ADCR    (volatile u32 *)IOP321_REG_ADDR(0x00000828)
-#define IOP321_AAU_EDCR0   (volatile u32 *)IOP321_REG_ADDR(0x0000083c)
-#define IOP321_AAU_EDCR1   (volatile u32 *)IOP321_REG_ADDR(0x00000860)
-#define IOP321_AAU_EDCR2   (volatile u32 *)IOP321_REG_ADDR(0x00000884)
-
-
-/* SSP serial port unit 0x00001600 - 0x0000167F */
-/* I2C bus interface unit 0x00001680 - 0x000016FF */
-#define IOP321_ICR0       (volatile u32 *)IOP321_REG_ADDR(0x00001680)
-#define IOP321_ISR0       (volatile u32 *)IOP321_REG_ADDR(0x00001684)
-#define IOP321_ISAR0      (volatile u32 *)IOP321_REG_ADDR(0x00001688)
-#define IOP321_IDBR0      (volatile u32 *)IOP321_REG_ADDR(0x0000168C)
-/* Reserved 0x00001690 */
-#define IOP321_IBMR0      (volatile u32 *)IOP321_REG_ADDR(0x00001694)
-/* Reserved 0x00001698 */
-/* Reserved 0x0000169C */
-#define IOP321_ICR1       (volatile u32 *)IOP321_REG_ADDR(0x000016A0)
-#define IOP321_ISR1       (volatile u32 *)IOP321_REG_ADDR(0x000016A4)
-#define IOP321_ISAR1      (volatile u32 *)IOP321_REG_ADDR(0x000016A8)
-#define IOP321_IDBR1      (volatile u32 *)IOP321_REG_ADDR(0x000016AC)
-#define IOP321_IBMR1      (volatile u32 *)IOP321_REG_ADDR(0x000016B4)
-/* Reserved 0x000016B8 through 0x000016FC */
-
-/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */
-
-
-#ifndef __ASSEMBLY__
-extern void iop321_map_io(void);
-extern void iop321_init_irq(void);
-extern void iop321_time_init(void);
-#endif
-
-#endif // _IOP321_HW_H_
diff --git a/include/asm-arm/arch-iop3xx/iop331-irqs.h b/include/asm-arm/arch-iop3xx/iop331-irqs.h
deleted file mode 100644 (file)
index 7135ad7..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/irqs.h
- *
- * Author:     Dave Jiang (dave.jiang@intel.com)
- * Copyright:  (C) 2003 Intel Corp.
- *
- * 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.
- *
- */
-#ifndef _IOP331_IRQS_H_
-#define _IOP331_IRQS_H_
-
-/*
- * IOP80331 chipset interrupts
- */
-#define IOP331_IRQ_OFS         0
-#define IOP331_IRQ(x)          (IOP331_IRQ_OFS + (x))
-
-/*
- * On IRQ or FIQ register
- */
-#define IRQ_IOP331_DMA0_EOT    IOP331_IRQ(0)
-#define IRQ_IOP331_DMA0_EOC    IOP331_IRQ(1)
-#define IRQ_IOP331_DMA1_EOT    IOP331_IRQ(2)
-#define IRQ_IOP331_DMA1_EOC    IOP331_IRQ(3)
-#define IRQ_IOP331_RSVD_4      IOP331_IRQ(4)
-#define IRQ_IOP331_RSVD_5      IOP331_IRQ(5)
-#define IRQ_IOP331_AA_EOT      IOP331_IRQ(6)
-#define IRQ_IOP331_AA_EOC      IOP331_IRQ(7)
-#define IRQ_IOP331_TIMER0      IOP331_IRQ(8)
-#define IRQ_IOP331_TIMER1      IOP331_IRQ(9)
-#define IRQ_IOP331_I2C_0       IOP331_IRQ(10)
-#define IRQ_IOP331_I2C_1       IOP331_IRQ(11)
-#define IRQ_IOP331_MSG     IOP331_IRQ(12)
-#define IRQ_IOP331_MSGIBQ   IOP331_IRQ(13)
-#define IRQ_IOP331_ATU_BIST    IOP331_IRQ(14)
-#define IRQ_IOP331_PERFMON     IOP331_IRQ(15)
-#define IRQ_IOP331_CORE_PMU    IOP331_IRQ(16)
-#define IRQ_IOP331_RSVD_17     IOP331_IRQ(17)
-#define IRQ_IOP331_RSVD_18     IOP331_IRQ(18)
-#define IRQ_IOP331_RSVD_19     IOP331_IRQ(19)
-#define IRQ_IOP331_RSVD_20     IOP331_IRQ(20)
-#define IRQ_IOP331_RSVD_21     IOP331_IRQ(21)
-#define IRQ_IOP331_RSVD_22     IOP331_IRQ(22)
-#define IRQ_IOP331_RSVD_23     IOP331_IRQ(23)
-#define IRQ_IOP331_XINT0       IOP331_IRQ(24)
-#define IRQ_IOP331_XINT1       IOP331_IRQ(25)
-#define IRQ_IOP331_XINT2       IOP331_IRQ(26)
-#define IRQ_IOP331_XINT3       IOP331_IRQ(27)
-#define IRQ_IOP331_RSVD_28  IOP331_IRQ(28)
-#define IRQ_IOP331_RSVD_29  IOP331_IRQ(29)
-#define IRQ_IOP331_RSVD_30  IOP331_IRQ(30)
-#define IRQ_IOP331_RSVD_31  IOP331_IRQ(31)
-#define IRQ_IOP331_XINT8    IOP331_IRQ(32)  // 0
-#define IRQ_IOP331_XINT9    IOP331_IRQ(33)  // 1
-#define IRQ_IOP331_XINT10   IOP331_IRQ(34)  // 2
-#define IRQ_IOP331_XINT11   IOP331_IRQ(35)  // 3
-#define IRQ_IOP331_XINT12   IOP331_IRQ(36)  // 4
-#define IRQ_IOP331_XINT13   IOP331_IRQ(37)  // 5
-#define IRQ_IOP331_XINT14   IOP331_IRQ(38)  // 6
-#define IRQ_IOP331_XINT15   IOP331_IRQ(39)  // 7
-#define IRQ_IOP331_RSVD_40  IOP331_IRQ(40)  // 8
-#define IRQ_IOP331_RSVD_41  IOP331_IRQ(41)  // 9
-#define IRQ_IOP331_RSVD_42  IOP331_IRQ(42)  // 10
-#define IRQ_IOP331_RSVD_43  IOP331_IRQ(43)  // 11
-#define IRQ_IOP331_RSVD_44  IOP331_IRQ(44)  // 12
-#define IRQ_IOP331_RSVD_45  IOP331_IRQ(45)  // 13
-#define IRQ_IOP331_RSVD_46  IOP331_IRQ(46)  // 14
-#define IRQ_IOP331_RSVD_47  IOP331_IRQ(47)  // 15
-#define IRQ_IOP331_RSVD_48  IOP331_IRQ(48)  // 16
-#define IRQ_IOP331_RSVD_49  IOP331_IRQ(49)  // 17
-#define IRQ_IOP331_RSVD_50  IOP331_IRQ(50)  // 18
-#define IRQ_IOP331_UART0    IOP331_IRQ(51)  // 19
-#define IRQ_IOP331_UART1    IOP331_IRQ(52)  // 20
-#define IRQ_IOP331_PBIE     IOP331_IRQ(53)  // 21
-#define IRQ_IOP331_ATU_CRW  IOP331_IRQ(54)  // 22
-#define IRQ_IOP331_ATU_ERR     IOP331_IRQ(55)  // 23
-#define IRQ_IOP331_MCU_ERR     IOP331_IRQ(56)  // 24
-#define IRQ_IOP331_DMA0_ERR    IOP331_IRQ(57)  // 25
-#define IRQ_IOP331_DMA1_ERR    IOP331_IRQ(58)  // 26
-#define IRQ_IOP331_RSVD_59  IOP331_IRQ(59)  // 27
-#define IRQ_IOP331_AA_ERR      IOP331_IRQ(60)  // 28
-#define IRQ_IOP331_RSVD_61  IOP331_IRQ(61)  // 29
-#define IRQ_IOP331_MSG_ERR     IOP331_IRQ(62)  // 30
-#define IRQ_IOP331_HPI         IOP331_IRQ(63)  // 31
-
-#define NR_IOP331_IRQS         (IOP331_IRQ(63) + 1)
-
-#define NR_IRQS                        NR_IOP331_IRQS
-
-
-/*
- * Interrupts available on the IQ80331 board
- */
-
-/*
- * On board devices
- */
-#define        IRQ_IQ80331_I82544      IRQ_IOP331_XINT0
-#define IRQ_IQ80331_UART0      IRQ_IOP331_UART0
-#define IRQ_IQ80331_UART1      IRQ_IOP331_UART1
-
-/*
- * PCI interrupts
- */
-#define        IRQ_IQ80331_INTA        IRQ_IOP331_XINT0
-#define        IRQ_IQ80331_INTB        IRQ_IOP331_XINT1
-#define        IRQ_IQ80331_INTC        IRQ_IOP331_XINT2
-#define        IRQ_IQ80331_INTD        IRQ_IOP331_XINT3
-
-/*
- * Interrupts available on the IQ80332 board
- */
-
-/*
- * On board devices
- */
-#define        IRQ_IQ80332_I82544      IRQ_IOP331_XINT0
-#define IRQ_IQ80332_UART0      IRQ_IOP331_UART0
-#define IRQ_IQ80332_UART1      IRQ_IOP331_UART1
-
-/*
- * PCI interrupts
- */
-#define        IRQ_IQ80332_INTA        IRQ_IOP331_XINT0
-#define        IRQ_IQ80332_INTB        IRQ_IOP331_XINT1
-#define        IRQ_IQ80332_INTC        IRQ_IOP331_XINT2
-#define        IRQ_IQ80332_INTD        IRQ_IOP331_XINT3
-
-#endif // _IOP331_IRQ_H_
diff --git a/include/asm-arm/arch-iop3xx/iop331.h b/include/asm-arm/arch-iop3xx/iop331.h
deleted file mode 100644 (file)
index fbf0cc1..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * linux/include/asm/arch-iop3xx/iop331.h
- *
- * Intel IOP331 Chip definitions
- *
- * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2003, 2004 Intel Corp.
- *
- * 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.
- */
-
-#ifndef _IOP331_HW_H_
-#define _IOP331_HW_H_
-
-
-/*
- * This is needed for mixed drivers that need to work on all
- * IOP3xx variants but behave slightly differently on each.
- */
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_ARCH_IOP331
-/*#define      iop_is_331()    ((processor_id & 0xffffffb0) == 0x69054090) */
-#define        iop_is_331()    ((processor_id & 0xffffff30) == 0x69054010)
-#else
-#define        iop_is_331()    0
-#endif
-#endif
-
-/*
- * IOP331 I/O and Mem space regions for PCI autoconfiguration
- */
-#define IOP331_PCI_IO_WINDOW_SIZE   0x00010000
-#define IOP331_PCI_LOWER_IO_PA      0x90000000
-#define IOP331_PCI_LOWER_IO_VA      0xfe000000
-#define IOP331_PCI_LOWER_IO_BA      (*IOP331_OIOWTVR)
-#define IOP331_PCI_UPPER_IO_PA      (IOP331_PCI_LOWER_IO_PA + IOP331_PCI_IO_WINDOW_SIZE - 1)
-#define IOP331_PCI_UPPER_IO_VA      (IOP331_PCI_LOWER_IO_VA + IOP331_PCI_IO_WINDOW_SIZE - 1)
-#define IOP331_PCI_UPPER_IO_BA      (IOP331_PCI_LOWER_IO_BA + IOP331_PCI_IO_WINDOW_SIZE - 1)
-#define IOP331_PCI_IO_OFFSET        (IOP331_PCI_LOWER_IO_VA - IOP331_PCI_LOWER_IO_BA)
-
-/* this can be 128M if OMWTVR1 is set */
-#define IOP331_PCI_MEM_WINDOW_SIZE     0x04000000 /* 64M outbound window */
-/* #define IOP331_PCI_MEM_WINDOW_SIZE  (~*IOP331_IALR1 + 1) */
-#define IOP331_PCI_LOWER_MEM_PA     0x80000000
-#define IOP331_PCI_LOWER_MEM_BA     (*IOP331_OMWTVR0)
-#define IOP331_PCI_UPPER_MEM_PA     (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1)
-#define IOP331_PCI_UPPER_MEM_BA     (IOP331_PCI_LOWER_MEM_BA + IOP331_PCI_MEM_WINDOW_SIZE - 1)
-#define IOP331_PCI_MEM_OFFSET       (IOP331_PCI_LOWER_MEM_PA - IOP331_PCI_LOWER_MEM_BA)
-
-/*
- * IOP331 chipset registers
- */
-#define IOP331_VIRT_MEM_BASE  0xfeffe000  /* chip virtual mem address*/
-#define IOP331_PHYS_MEM_BASE  0xffffe000  /* chip physical memory address */
-#define IOP331_REG_ADDR(reg) (IOP331_VIRT_MEM_BASE | (reg))
-
-/* Reserved 0x00000000 through 0x000000FF */
-
-/* Address Translation Unit 0x00000100 through 0x000001FF */
-#define IOP331_ATUVID     (volatile u16 *)IOP331_REG_ADDR(0x00000100)
-#define IOP331_ATUDID     (volatile u16 *)IOP331_REG_ADDR(0x00000102)
-#define IOP331_ATUCMD     (volatile u16 *)IOP331_REG_ADDR(0x00000104)
-#define IOP331_ATUSR      (volatile u16 *)IOP331_REG_ADDR(0x00000106)
-#define IOP331_ATURID     (volatile u8  *)IOP331_REG_ADDR(0x00000108)
-#define IOP331_ATUCCR     (volatile u32 *)IOP331_REG_ADDR(0x00000109)
-#define IOP331_ATUCLSR    (volatile u8  *)IOP331_REG_ADDR(0x0000010C)
-#define IOP331_ATULT      (volatile u8  *)IOP331_REG_ADDR(0x0000010D)
-#define IOP331_ATUHTR     (volatile u8  *)IOP331_REG_ADDR(0x0000010E)
-#define IOP331_ATUBIST    (volatile u8  *)IOP331_REG_ADDR(0x0000010F)
-#define IOP331_IABAR0     (volatile u32 *)IOP331_REG_ADDR(0x00000110)
-#define IOP331_IAUBAR0    (volatile u32 *)IOP331_REG_ADDR(0x00000114)
-#define IOP331_IABAR1     (volatile u32 *)IOP331_REG_ADDR(0x00000118)
-#define IOP331_IAUBAR1    (volatile u32 *)IOP331_REG_ADDR(0x0000011C)
-#define IOP331_IABAR2     (volatile u32 *)IOP331_REG_ADDR(0x00000120)
-#define IOP331_IAUBAR2    (volatile u32 *)IOP331_REG_ADDR(0x00000124)
-#define IOP331_ASVIR      (volatile u16 *)IOP331_REG_ADDR(0x0000012C)
-#define IOP331_ASIR       (volatile u16 *)IOP331_REG_ADDR(0x0000012E)
-#define IOP331_ERBAR      (volatile u32 *)IOP331_REG_ADDR(0x00000130)
-#define IOP331_ATU_CAPPTR (volatile u32 *)IOP331_REG_ADDR(0x00000134)
-/* Reserved 0x00000138 through 0x0000013B */
-#define IOP331_ATUILR     (volatile u8  *)IOP331_REG_ADDR(0x0000013C)
-#define IOP331_ATUIPR     (volatile u8  *)IOP331_REG_ADDR(0x0000013D)
-#define IOP331_ATUMGNT    (volatile u8  *)IOP331_REG_ADDR(0x0000013E)
-#define IOP331_ATUMLAT    (volatile u8  *)IOP331_REG_ADDR(0x0000013F)
-#define IOP331_IALR0      (volatile u32 *)IOP331_REG_ADDR(0x00000140)
-#define IOP331_IATVR0     (volatile u32 *)IOP331_REG_ADDR(0x00000144)
-#define IOP331_ERLR       (volatile u32 *)IOP331_REG_ADDR(0x00000148)
-#define IOP331_ERTVR      (volatile u32 *)IOP331_REG_ADDR(0x0000014C)
-#define IOP331_IALR1      (volatile u32 *)IOP331_REG_ADDR(0x00000150)
-#define IOP331_IALR2      (volatile u32 *)IOP331_REG_ADDR(0x00000154)
-#define IOP331_IATVR2     (volatile u32 *)IOP331_REG_ADDR(0x00000158)
-#define IOP331_OIOWTVR    (volatile u32 *)IOP331_REG_ADDR(0x0000015C)
-#define IOP331_OMWTVR0    (volatile u32 *)IOP331_REG_ADDR(0x00000160)
-#define IOP331_OUMWTVR0   (volatile u32 *)IOP331_REG_ADDR(0x00000164)
-#define IOP331_OMWTVR1    (volatile u32 *)IOP331_REG_ADDR(0x00000168)
-#define IOP331_OUMWTVR1   (volatile u32 *)IOP331_REG_ADDR(0x0000016C)
-/* Reserved 0x00000170 through 0x00000177*/
-#define IOP331_OUDWTVR    (volatile u32 *)IOP331_REG_ADDR(0x00000178)
-/* Reserved 0x0000017C through 0x0000017F*/
-#define IOP331_ATUCR      (volatile u32 *)IOP331_REG_ADDR(0x00000180)
-#define IOP331_PCSR       (volatile u32 *)IOP331_REG_ADDR(0x00000184)
-#define IOP331_ATUISR     (volatile u32 *)IOP331_REG_ADDR(0x00000188)
-#define IOP331_ATUIMR     (volatile u32 *)IOP331_REG_ADDR(0x0000018C)
-#define IOP331_IABAR3     (volatile u32 *)IOP331_REG_ADDR(0x00000190)
-#define IOP331_IAUBAR3    (volatile u32 *)IOP331_REG_ADDR(0x00000194)
-#define IOP331_IALR3      (volatile u32 *)IOP331_REG_ADDR(0x00000198)
-#define IOP331_IATVR3     (volatile u32 *)IOP331_REG_ADDR(0x0000019C)
-/* Reserved 0x000001A0 through 0x000001A3*/
-#define IOP331_OCCAR      (volatile u32 *)IOP331_REG_ADDR(0x000001A4)
-/* Reserved 0x000001A8 through 0x000001AB*/
-#define IOP331_OCCDR      (volatile u32 *)IOP331_REG_ADDR(0x000001AC)
-/* Reserved 0x000001B0 through 0x000001BB*/
-#define IOP331_VPDCAPID   (volatile u8 *)IOP331_REG_ADDR(0x000001B8)
-#define IOP331_VPDNXTP    (volatile u8 *)IOP331_REG_ADDR(0x000001B9)
-#define IOP331_VPDAR     (volatile u16 *)IOP331_REG_ADDR(0x000001BA)
-#define IOP331_VPDDR      (volatile u32 *)IOP331_REG_ADDR(0x000001BC)
-#define IOP331_PMCAPID    (volatile u8 *)IOP331_REG_ADDR(0x000001C0)
-#define IOP331_PMNEXT     (volatile u8 *)IOP331_REG_ADDR(0x000001C1)
-#define IOP331_APMCR      (volatile u16 *)IOP331_REG_ADDR(0x000001C2)
-#define IOP331_APMCSR     (volatile u16 *)IOP331_REG_ADDR(0x000001C4)
-/* Reserved 0x000001C6 through 0x000001CF */
-#define IOP331_MSICAPID   (volatile u8 *)IOP331_REG_ADDR(0x000001D0)
-#define IOP331_MSINXTP   (volatile u8 *)IOP331_REG_ADDR(0x000001D1)
-#define IOP331_MSIMCR     (volatile u16 *)IOP331_REG_ADDR(0x000001D2)
-#define IOP331_MSIMAR     (volatile u32 *)IOP331_REG_ADDR(0x000001D4)
-#define IOP331_MSIMUAR   (volatile u32 *)IOP331_REG_ADDR(0x000001D8)
-#define IOP331_MSIMDR    (volatile u32 *)IOP331_REG_ADDR(0x000001DC)
-#define IOP331_PCIXCAPID  (volatile u8 *)IOP331_REG_ADDR(0x000001E0)
-#define IOP331_PCIXNEXT   (volatile u8 *)IOP331_REG_ADDR(0x000001E1)
-#define IOP331_PCIXCMD    (volatile u16 *)IOP331_REG_ADDR(0x000001E2)
-#define IOP331_PCIXSR     (volatile u32 *)IOP331_REG_ADDR(0x000001E4)
-#define IOP331_PCIIRSR    (volatile u32 *)IOP331_REG_ADDR(0x000001EC)
-
-/* Messaging Unit 0x00000300 through 0x000003FF */
-
-/* Reserved 0x00000300 through 0x0000030c */
-#define IOP331_IMR0       (volatile u32 *)IOP331_REG_ADDR(0x00000310)
-#define IOP331_IMR1       (volatile u32 *)IOP331_REG_ADDR(0x00000314)
-#define IOP331_OMR0       (volatile u32 *)IOP331_REG_ADDR(0x00000318)
-#define IOP331_OMR1       (volatile u32 *)IOP331_REG_ADDR(0x0000031C)
-#define IOP331_IDR        (volatile u32 *)IOP331_REG_ADDR(0x00000320)
-#define IOP331_IISR       (volatile u32 *)IOP331_REG_ADDR(0x00000324)
-#define IOP331_IIMR       (volatile u32 *)IOP331_REG_ADDR(0x00000328)
-#define IOP331_ODR        (volatile u32 *)IOP331_REG_ADDR(0x0000032C)
-#define IOP331_OISR       (volatile u32 *)IOP331_REG_ADDR(0x00000330)
-#define IOP331_OIMR       (volatile u32 *)IOP331_REG_ADDR(0x00000334)
-/* Reserved 0x00000338 through 0x0000034F */
-#define IOP331_MUCR       (volatile u32 *)IOP331_REG_ADDR(0x00000350)
-#define IOP331_QBAR       (volatile u32 *)IOP331_REG_ADDR(0x00000354)
-/* Reserved 0x00000358 through 0x0000035C */
-#define IOP331_IFHPR      (volatile u32 *)IOP331_REG_ADDR(0x00000360)
-#define IOP331_IFTPR      (volatile u32 *)IOP331_REG_ADDR(0x00000364)
-#define IOP331_IPHPR      (volatile u32 *)IOP331_REG_ADDR(0x00000368)
-#define IOP331_IPTPR      (volatile u32 *)IOP331_REG_ADDR(0x0000036C)
-#define IOP331_OFHPR      (volatile u32 *)IOP331_REG_ADDR(0x00000370)
-#define IOP331_OFTPR      (volatile u32 *)IOP331_REG_ADDR(0x00000374)
-#define IOP331_OPHPR      (volatile u32 *)IOP331_REG_ADDR(0x00000378)
-#define IOP331_OPTPR      (volatile u32 *)IOP331_REG_ADDR(0x0000037C)
-#define IOP331_IAR        (volatile u32 *)IOP331_REG_ADDR(0x00000380)
-/* Reserved 0x00000384 through 0x000003FF */
-
-/* DMA Controller 0x00000400 through 0x000004FF */
-#define IOP331_DMA0_CCR   (volatile u32 *)IOP331_REG_ADDR(0x00000400)
-#define IOP331_DMA0_CSR   (volatile u32 *)IOP331_REG_ADDR(0x00000404)
-#define IOP331_DMA0_DAR   (volatile u32 *)IOP331_REG_ADDR(0x0000040C)
-#define IOP331_DMA0_NDAR  (volatile u32 *)IOP331_REG_ADDR(0x00000410)
-#define IOP331_DMA0_PADR  (volatile u32 *)IOP331_REG_ADDR(0x00000414)
-#define IOP331_DMA0_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000418)
-#define IOP331_DMA0_LADR  (volatile u32 *)IOP331_REG_ADDR(0X0000041C)
-#define IOP331_DMA0_BCR   (volatile u32 *)IOP331_REG_ADDR(0x00000420)
-#define IOP331_DMA0_DCR   (volatile u32 *)IOP331_REG_ADDR(0x00000424)
-/* Reserved 0x00000428 through 0x0000043C */
-#define IOP331_DMA1_CCR   (volatile u32 *)IOP331_REG_ADDR(0x00000440)
-#define IOP331_DMA1_CSR   (volatile u32 *)IOP331_REG_ADDR(0x00000444)
-#define IOP331_DMA1_DAR   (volatile u32 *)IOP331_REG_ADDR(0x0000044C)
-#define IOP331_DMA1_NDAR  (volatile u32 *)IOP331_REG_ADDR(0x00000450)
-#define IOP331_DMA1_PADR  (volatile u32 *)IOP331_REG_ADDR(0x00000454)
-#define IOP331_DMA1_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000458)
-#define IOP331_DMA1_LADR  (volatile u32 *)IOP331_REG_ADDR(0x0000045C)
-#define IOP331_DMA1_BCR   (volatile u32 *)IOP331_REG_ADDR(0x00000460)
-#define IOP331_DMA1_DCR   (volatile u32 *)IOP331_REG_ADDR(0x00000464)
-/* Reserved 0x00000468 through 0x000004FF */
-
-/* Memory controller 0x00000500 through 0x0005FF */
-
-/* Peripheral bus interface unit 0x00000680 through 0x0006FF */
-#define IOP331_PBCR       (volatile u32 *)IOP331_REG_ADDR(0x00000680)
-#define IOP331_PBISR      (volatile u32 *)IOP331_REG_ADDR(0x00000684)
-#define IOP331_PBBAR0     (volatile u32 *)IOP331_REG_ADDR(0x00000688)
-#define IOP331_PBLR0      (volatile u32 *)IOP331_REG_ADDR(0x0000068C)
-#define IOP331_PBBAR1     (volatile u32 *)IOP331_REG_ADDR(0x00000690)
-#define IOP331_PBLR1      (volatile u32 *)IOP331_REG_ADDR(0x00000694)
-#define IOP331_PBBAR2     (volatile u32 *)IOP331_REG_ADDR(0x00000698)
-#define IOP331_PBLR2      (volatile u32 *)IOP331_REG_ADDR(0x0000069C)
-#define IOP331_PBBAR3     (volatile u32 *)IOP331_REG_ADDR(0x000006A0)
-#define IOP331_PBLR3      (volatile u32 *)IOP331_REG_ADDR(0x000006A4)
-#define IOP331_PBBAR4     (volatile u32 *)IOP331_REG_ADDR(0x000006A8)
-#define IOP331_PBLR4      (volatile u32 *)IOP331_REG_ADDR(0x000006AC)
-#define IOP331_PBBAR5     (volatile u32 *)IOP331_REG_ADDR(0x000006B0)
-#define IOP331_PBLR5      (volatile u32 *)IOP331_REG_ADDR(0x000006B4)
-#define IOP331_PBDSCR     (volatile u32 *)IOP331_REG_ADDR(0x000006B8)
-/* Reserved 0x000006BC */
-#define IOP331_PMBR0      (volatile u32 *)IOP331_REG_ADDR(0x000006C0)
-/* Reserved 0x000006C4 through 0x000006DC */
-#define IOP331_PMBR1      (volatile u32 *)IOP331_REG_ADDR(0x000006E0)
-#define IOP331_PMBR2      (volatile u32 *)IOP331_REG_ADDR(0x000006E4)
-
-#define IOP331_PBCR_EN    0x1
-
-#define IOP331_PBISR_BOOR_ERR 0x1
-
-
-
-/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */
-/* Internal arbitration unit 0x00000780 through 0x0007BF */
-
-/* Interrupt Controller */
-#define IOP331_INTCTL0    (volatile u32 *)IOP331_REG_ADDR(0x00000790)
-#define IOP331_INTCTL1    (volatile u32 *)IOP331_REG_ADDR(0x00000794)
-#define IOP331_INTSTR0    (volatile u32 *)IOP331_REG_ADDR(0x00000798)
-#define IOP331_INTSTR1    (volatile u32 *)IOP331_REG_ADDR(0x0000079C)
-#define IOP331_IINTSRC0   (volatile u32 *)IOP331_REG_ADDR(0x000007A0)
-#define IOP331_IINTSRC1   (volatile u32 *)IOP331_REG_ADDR(0x000007A4)
-#define IOP331_FINTSRC0   (volatile u32 *)IOP331_REG_ADDR(0x000007A8)
-#define IOP331_FINTSRC1   (volatile u32 *)IOP331_REG_ADDR(0x000007AC)
-#define IOP331_IPR0       (volatile u32 *)IOP331_REG_ADDR(0x000007B0)
-#define IOP331_IPR1       (volatile u32 *)IOP331_REG_ADDR(0x000007B4)
-#define IOP331_IPR2       (volatile u32 *)IOP331_REG_ADDR(0x000007B8)
-#define IOP331_IPR3       (volatile u32 *)IOP331_REG_ADDR(0x000007BC)
-#define IOP331_INTBASE    (volatile u32 *)IOP331_REG_ADDR(0x000007C0)
-#define IOP331_INTSIZE    (volatile u32 *)IOP331_REG_ADDR(0x000007C4)
-#define IOP331_IINTVEC    (volatile u32 *)IOP331_REG_ADDR(0x000007C8)
-#define IOP331_FINTVEC    (volatile u32 *)IOP331_REG_ADDR(0x000007CC)
-
-
-/* Timers */
-
-#define IOP331_TU_TMR0         (volatile u32 *)IOP331_REG_ADDR(0x000007D0)
-#define IOP331_TU_TMR1         (volatile u32 *)IOP331_REG_ADDR(0x000007D4)
-
-#define IOP331_TMR_TC          0x01
-#define        IOP331_TMR_EN           0x02
-#define IOP331_TMR_RELOAD      0x04
-#define        IOP331_TMR_PRIVILEGED   0x09
-
-#define        IOP331_TMR_RATIO_1_1    0x00
-#define        IOP331_TMR_RATIO_4_1    0x10
-#define        IOP331_TMR_RATIO_8_1    0x20
-#define        IOP331_TMR_RATIO_16_1   0x30
-
-#define IOP331_TU_TCR0    (volatile u32 *)IOP331_REG_ADDR(0x000007D8)
-#define IOP331_TU_TCR1    (volatile u32 *)IOP331_REG_ADDR(0x000007DC)
-#define IOP331_TU_TRR0    (volatile u32 *)IOP331_REG_ADDR(0x000007E0)
-#define IOP331_TU_TRR1    (volatile u32 *)IOP331_REG_ADDR(0x000007E4)
-#define IOP331_TU_TISR    (volatile u32 *)IOP331_REG_ADDR(0x000007E8)
-#define IOP331_TU_WDTCR   (volatile u32 *)IOP331_REG_ADDR(0x000007EC)
-
-#if defined(CONFIG_ARCH_IOP331)
-#define        IOP331_TICK_RATE        266000000       /* 266 MHz IB clock */
-#endif
-
-#if defined(CONFIG_IOP331_STEPD) || defined(CONFIG_ARCH_IQ80333)
-#undef IOP331_TICK_RATE
-#define IOP331_TICK_RATE       333000000       /* 333 Mhz IB clock */
-#endif
-
-/* Application accelerator unit 0x00000800 - 0x000008FF */
-#define IOP331_AAU_ACR     (volatile u32 *)IOP331_REG_ADDR(0x00000800)
-#define IOP331_AAU_ASR     (volatile u32 *)IOP331_REG_ADDR(0x00000804)
-#define IOP331_AAU_ADAR    (volatile u32 *)IOP331_REG_ADDR(0x00000808)
-#define IOP331_AAU_ANDAR   (volatile u32 *)IOP331_REG_ADDR(0x0000080C)
-#define IOP331_AAU_SAR1    (volatile u32 *)IOP331_REG_ADDR(0x00000810)
-#define IOP331_AAU_SAR2    (volatile u32 *)IOP331_REG_ADDR(0x00000814)
-#define IOP331_AAU_SAR3    (volatile u32 *)IOP331_REG_ADDR(0x00000818)
-#define IOP331_AAU_SAR4    (volatile u32 *)IOP331_REG_ADDR(0x0000081C)
-#define IOP331_AAU_SAR5    (volatile u32 *)IOP331_REG_ADDR(0x0000082C)
-#define IOP331_AAU_SAR6    (volatile u32 *)IOP331_REG_ADDR(0x00000830)
-#define IOP331_AAU_SAR7    (volatile u32 *)IOP331_REG_ADDR(0x00000834)
-#define IOP331_AAU_SAR8    (volatile u32 *)IOP331_REG_ADDR(0x00000838)
-#define IOP331_AAU_SAR9    (volatile u32 *)IOP331_REG_ADDR(0x00000840)
-#define IOP331_AAU_SAR10   (volatile u32 *)IOP331_REG_ADDR(0x00000844)
-#define IOP331_AAU_SAR11   (volatile u32 *)IOP331_REG_ADDR(0x00000848)
-#define IOP331_AAU_SAR12   (volatile u32 *)IOP331_REG_ADDR(0x0000084C)
-#define IOP331_AAU_SAR13   (volatile u32 *)IOP331_REG_ADDR(0x00000850)
-#define IOP331_AAU_SAR14   (volatile u32 *)IOP331_REG_ADDR(0x00000854)
-#define IOP331_AAU_SAR15   (volatile u32 *)IOP331_REG_ADDR(0x00000858)
-#define IOP331_AAU_SAR16   (volatile u32 *)IOP331_REG_ADDR(0x0000085C)
-#define IOP331_AAU_SAR17   (volatile u32 *)IOP331_REG_ADDR(0x00000864)
-#define IOP331_AAU_SAR18   (volatile u32 *)IOP331_REG_ADDR(0x00000868)
-#define IOP331_AAU_SAR19   (volatile u32 *)IOP331_REG_ADDR(0x0000086C)
-#define IOP331_AAU_SAR20   (volatile u32 *)IOP331_REG_ADDR(0x00000870)
-#define IOP331_AAU_SAR21   (volatile u32 *)IOP331_REG_ADDR(0x00000874)
-#define IOP331_AAU_SAR22   (volatile u32 *)IOP331_REG_ADDR(0x00000878)
-#define IOP331_AAU_SAR23   (volatile u32 *)IOP331_REG_ADDR(0x0000087C)
-#define IOP331_AAU_SAR24   (volatile u32 *)IOP331_REG_ADDR(0x00000880)
-#define IOP331_AAU_SAR25   (volatile u32 *)IOP331_REG_ADDR(0x00000888)
-#define IOP331_AAU_SAR26   (volatile u32 *)IOP331_REG_ADDR(0x0000088C)
-#define IOP331_AAU_SAR27   (volatile u32 *)IOP331_REG_ADDR(0x00000890)
-#define IOP331_AAU_SAR28   (volatile u32 *)IOP331_REG_ADDR(0x00000894)
-#define IOP331_AAU_SAR29   (volatile u32 *)IOP331_REG_ADDR(0x00000898)
-#define IOP331_AAU_SAR30   (volatile u32 *)IOP331_REG_ADDR(0x0000089C)
-#define IOP331_AAU_SAR31   (volatile u32 *)IOP331_REG_ADDR(0x000008A0)
-#define IOP331_AAU_SAR32   (volatile u32 *)IOP331_REG_ADDR(0x000008A4)
-#define IOP331_AAU_DAR     (volatile u32 *)IOP331_REG_ADDR(0x00000820)
-#define IOP331_AAU_ABCR    (volatile u32 *)IOP331_REG_ADDR(0x00000824)
-#define IOP331_AAU_ADCR    (volatile u32 *)IOP331_REG_ADDR(0x00000828)
-#define IOP331_AAU_EDCR0   (volatile u32 *)IOP331_REG_ADDR(0x0000083c)
-#define IOP331_AAU_EDCR1   (volatile u32 *)IOP331_REG_ADDR(0x00000860)
-#define IOP331_AAU_EDCR2   (volatile u32 *)IOP331_REG_ADDR(0x00000884)
-
-
-#define IOP331_SPDSCR    (volatile u32 *)IOP331_REG_ADDR(0x000015C0)
-#define IOP331_PPDSCR    (volatile u32 *)IOP331_REG_ADDR(0x000015C8)
-/* SSP serial port unit 0x00001600 - 0x0000167F */
-
-/* I2C bus interface unit 0x00001680 - 0x000016FF */
-/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */
-
-#define IOP331_ICR0       (volatile u32 *)IOP331_REG_ADDR(0x00001680)
-#define IOP331_ISR0       (volatile u32 *)IOP331_REG_ADDR(0x00001684)
-#define IOP331_ISAR0      (volatile u32 *)IOP331_REG_ADDR(0x00001688)
-#define IOP331_IDBR0      (volatile u32 *)IOP331_REG_ADDR(0x0000168C)
-/* Reserved 0x00001690 */
-#define IOP331_IBMR0      (volatile u32 *)IOP331_REG_ADDR(0x00001694)
-/* Reserved 0x00001698 */
-/* Reserved 0x0000169C */
-#define IOP331_ICR1       (volatile u32 *)IOP331_REG_ADDR(0x000016A0)
-#define IOP331_ISR1       (volatile u32 *)IOP331_REG_ADDR(0x000016A4)
-#define IOP331_ISAR1      (volatile u32 *)IOP331_REG_ADDR(0x000016A8)
-#define IOP331_IDBR1      (volatile u32 *)IOP331_REG_ADDR(0x000016AC)
-#define IOP331_IBMR1      (volatile u32 *)IOP331_REG_ADDR(0x000016B4)
-/* Reserved 0x000016B8 through 0x000016FF */
-
-/* 0x00001700 through 0x0000172C  UART 0 */
-
-/* Reserved 0x00001730 through 0x0000173F */
-
-/* 0x00001740 through 0x0000176C UART 1 */
-
-#define IOP331_UART0_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001700) /* UART #1 physical */
-#define IOP331_UART1_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001740) /* UART #2 physical */
-#define IOP331_UART0_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */
-#define IOP331_UART1_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */
-
-/* Reserved 0x00001770 through 0x0000177F */
-
-/* General Purpose I/O Registers */
-#define IOP331_GPOE       (volatile u32 *)IOP331_REG_ADDR(0x00001780)
-#define IOP331_GPID       (volatile u32 *)IOP331_REG_ADDR(0x00001784)
-#define IOP331_GPOD       (volatile u32 *)IOP331_REG_ADDR(0x00001788)
-
-/* Reserved 0x0000178c through 0x000019ff */
-
-
-#ifndef __ASSEMBLY__
-extern void iop331_map_io(void);
-extern void iop331_init_irq(void);
-extern void iop331_time_init(void);
-#endif
-
-#endif // _IOP331_HW_H_
diff --git a/include/asm-arm/arch-iop3xx/irqs.h b/include/asm-arm/arch-iop3xx/irqs.h
deleted file mode 100644 (file)
index b2c03f4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/irqs.h
- *
- * Copyright:  (C) 2001-2003 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-/*
- * Chipset-specific bits
- */
-#ifdef CONFIG_ARCH_IOP321
-#include "iop321-irqs.h"
-#endif
-
-#ifdef CONFIG_ARCH_IOP331
-#include "iop331-irqs.h"
-#endif
diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
deleted file mode 100644 (file)
index e43ebd9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/memory.h
- */
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <asm/hardware.h>
-
-/*
- * Physical DRAM offset.
- */
-#ifndef CONFIG_ARCH_IOP331
-#define PHYS_OFFSET    UL(0xa0000000)
-#else
-#define PHYS_OFFSET    UL(0x00000000)
-#endif
-
-/*
- * Virtual view <-> PCI DMA view memory address translations
- * virt_to_bus: Used to translate the virtual address to an
- *             address suitable to be passed to set_dma_addr
- * bus_to_virt: Used to convert an address for DMA operations
- *             to an address that the kernel can use.
- */
-#if defined(CONFIG_ARCH_IOP321)
-
-#define __virt_to_bus(x)       (((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0))
-#define __bus_to_virt(x)    (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2)))
-
-#elif defined(CONFIG_ARCH_IOP331)
-
-#define __virt_to_bus(x)       (((__virt_to_phys(x)) & ~(*IOP331_IATVR2)) | ((*IOP331_IABAR2) & 0xfffffff0))
-#define __bus_to_virt(x)    (__phys_to_virt(((x) & ~(*IOP331_IALR2)) | ( *IOP331_IATVR2)))
-
-#endif
-
-#endif
diff --git a/include/asm-arm/arch-iop3xx/system.h b/include/asm-arm/arch-iop3xx/system.h
deleted file mode 100644 (file)
index af6ae8c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/system.h
- *
- *  Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-static inline void arch_idle(void)
-{
-       cpu_do_idle();
-}
-
-
-static inline void arch_reset(char mode)
-{
-#ifdef CONFIG_ARCH_IOP321
-    *IOP321_PCSR = 0x30;
-#endif
-
-#ifdef CONFIG_ARCH_IOP331
-    *IOP331_PCSR = 0x30;
-#endif
-
-       if ( 1 && mode == 's') {
-               /* Jump into ROM at address 0 */
-               cpu_reset(0);
-       } else {
-               /* No on-chip reset capability */
-               cpu_reset(0);
-       }
-}
-
diff --git a/include/asm-arm/arch-iop3xx/timex.h b/include/asm-arm/arch-iop3xx/timex.h
deleted file mode 100644 (file)
index 14ca8d0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/timex.h
- *
- * IOP3xx architecture timex specifications
- */
-#include <asm/hardware.h>
-
-#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
-
-#define CLOCK_TICK_RATE IOP321_TICK_RATE
-
-#elif defined(CONFIG_ARCH_IQ80331) || defined(CONFIG_MACH_IQ80332)
-
-#define CLOCK_TICK_RATE IOP331_TICK_RATE
-
-#else
-
-#error "No IOP3xx timex information for this architecture"
-
-#endif
diff --git a/include/asm-arm/arch-iop3xx/uncompress.h b/include/asm-arm/arch-iop3xx/uncompress.h
deleted file mode 100644 (file)
index fbdd5af..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-iop3xx/uncompress.h
- */
-#include <asm/types.h>
-#include <asm/mach-types.h>
-#include <linux/serial_reg.h>
-#include <asm/hardware.h>
-
-#ifdef CONFIG_ARCH_IOP321
-#define UTYPE unsigned char *
-#elif defined(CONFIG_ARCH_IOP331)
-#define UTYPE u32 *
-#else
-#error "Missing IOP3xx arch type def"
-#endif
-
-static volatile UTYPE uart_base;
-
-#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
-
-static inline void putc(char c)
-{
-       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
-               barrier();
-       *uart_base = c;
-}
-
-static inline void flush(void)
-{
-}
-
-static __inline__ void __arch_decomp_setup(unsigned long arch_id)
-{
-        if(machine_is_iq80321())
-                       uart_base = (volatile UTYPE)IQ80321_UART;
-               else if(machine_is_iq31244())
-                       uart_base = (volatile UTYPE)IQ31244_UART;
-               else if(machine_is_iq80331() || machine_is_iq80332())
-                       uart_base = (volatile UTYPE)IOP331_UART0_PHYS;
-               else
-                       uart_base = (volatile UTYPE)0xfe800000;
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
-#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-iop3xx/vmalloc.h b/include/asm-arm/arch-iop3xx/vmalloc.h
deleted file mode 100644 (file)
index 0f2f684..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop3xx/vmalloc.h
- */
-
-/*
- * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts.  That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-//#define VMALLOC_END       (0xe8000000)
-/* increase usable physical RAM to ~992M per RMK */
-#define VMALLOC_END       (0xfe000000)
-
index 13aee17b04750b692d5cab4b445d61d84163d740..8d10a91876932587e6c96cf3d259902b2f20dd66 100644 (file)
@@ -89,6 +89,11 @@ struct ixp4xx_i2c_pins {
 
 struct sys_timer;
 
+/*
+ * Frequency of clock used for primary clocksource
+ */
+extern unsigned long ixp4xx_timer_freq;
+
 /*
  * Functions used by platform-level setup code
  */
index cd080d8384d9232135a68802facdea5dca5a3783..d744d97c18a5fee15f664302ed6085424a9c7f3d 100644 (file)
@@ -31,9 +31,9 @@
 static inline unsigned int __arch_getw(unsigned long a)
 {
        unsigned int value;
-       __asm__ __volatile__("ldr%?h    %0, [%1, #0]    @ getw"
+       __asm__ __volatile__("ldrh    %0, [%1, #0]    @ getw"
                : "=&r" (value)
-               : "r" (a));
+               : "r" (a) : "cc");
        return value;
 }
 
@@ -42,8 +42,8 @@ static inline unsigned int __arch_getw(unsigned long a)
 
 static inline void __arch_putw(unsigned int value, unsigned long a)
 {
-        __asm__ __volatile__("str%?h    %0, [%1, #0]    @ putw"
-                : : "r" (value), "r" (a));
+        __asm__ __volatile__("strh    %0, [%1, #0]    @ putw"
+                : : "r" (value), "r" (a) : "cc");
 }
 
 /*
index 7b98b533e63a85e84e36618a713d5a6412b9478f..c69cb508735f74aed3db85f0d7e1e662eba0896e 100644 (file)
@@ -45,7 +45,7 @@
 static irqreturn_t
 timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
index 0070f6d3b75ceb30550118e6c94db29ae0fe00ed..9aee15d97145df25e9c2b32f1e56a510e64aa192 100644 (file)
 #define AMS_DELTA_LATCH2_NAND_NWE      0x0020
 #define AMS_DELTA_LATCH2_NAND_ALE      0x0040
 #define AMS_DELTA_LATCH2_NAND_CLE      0x0080
+#define AMD_DELTA_LATCH2_KEYBRD_PWR    0x0100
+#define AMD_DELTA_LATCH2_KEYBRD_DATA   0x0200
+#define AMD_DELTA_LATCH2_SCARD_RSTIN   0x0400
+#define AMD_DELTA_LATCH2_SCARD_CMDVCC  0x0800
 #define AMS_DELTA_LATCH2_MODEM_NRESET  0x1000
 #define AMS_DELTA_LATCH2_MODEM_CODEC   0x2000
 
+#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA 0
+#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK  1
+#define AMS_DELTA_GPIO_PIN_MODEM_IRQ   2
+#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH 4
+#define AMS_DELTA_GPIO_PIN_SCARD_NOFF  6
+#define AMS_DELTA_GPIO_PIN_SCARD_IO    7
+#define AMS_DELTA_GPIO_PIN_CONFIG      11
 #define AMS_DELTA_GPIO_PIN_NAND_RB     12
 
 #ifndef __ASSEMBLY__
index f83003f5287b04dbd63b3998ea8e98beae0b7286..fa68810499034057f5b8544606a8579dd8d58eee 100644 (file)
@@ -45,6 +45,7 @@ struct clk_functions {
        struct clk *    (*clk_get_parent)(struct clk *clk);
        void            (*clk_allow_idle)(struct clk *clk);
        void            (*clk_deny_idle)(struct clk *clk);
+       void            (*clk_disable_unused)(struct clk *clk);
 };
 
 extern unsigned int mpurate;
index 1b1b02307e77f5c600ed32064915bf0594158511..d591d0585bbab64f7cb944788ac02c5f957d258c 100644 (file)
@@ -331,6 +331,12 @@ enum omap_dma_color_mode {
        OMAP_DMA_TRANSPARENT_COPY
 };
 
+enum omap_dma_write_mode {
+       OMAP_DMA_WRITE_NON_POSTED = 0,
+       OMAP_DMA_WRITE_POSTED,
+       OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
 struct omap_dma_channel_params {
        int data_type;          /* data type 8,16,32 */
        int elem_count;         /* number of elements in a frame */
@@ -338,13 +344,13 @@ struct omap_dma_channel_params {
 
        int src_port;           /* Only on OMAP1 REVISIT: Is this needed? */
        int src_amode;          /* constant , post increment, indexed , double indexed */
-       int src_start;          /* source address : physical */
+       unsigned long src_start;        /* source address : physical */
        int src_ei;             /* source element index */
        int src_fi;             /* source frame index */
 
        int dst_port;           /* Only on OMAP1 REVISIT: Is this needed? */
        int dst_amode;          /* constant , post increment, indexed , double indexed */
-       int dst_start;          /* source address : physical */
+       unsigned long dst_start;        /* source address : physical */
        int dst_ei;             /* source element index */
        int dst_fi;             /* source frame index */
 
@@ -356,7 +362,7 @@ struct omap_dma_channel_params {
 };
 
 
-extern void omap_set_dma_priority(int dst_port, int priority);
+extern void omap_set_dma_priority(int lch, int dst_port, int priority);
 extern int omap_request_dma(int dev_id, const char *dev_name,
                            void (* callback)(int lch, u16 ch_status, void *data),
                            void *data, int *dma_ch);
@@ -371,6 +377,7 @@ extern void omap_set_dma_transfer_params(int lch, int data_type,
                                         int dma_trigger, int src_or_dst_synch);
 extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
                                    u32 color);
+extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
 
 extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                                    unsigned long src_start,
@@ -394,6 +401,9 @@ extern void omap_set_dma_params(int lch,
 extern void omap_dma_link_lch (int lch_head, int lch_queue);
 extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
 
+extern int omap_set_dma_callback(int lch,
+                       void (* callback)(int lch, u16 ch_status, void *data),
+                       void *data);
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
 extern int omap_get_dma_src_addr_counter(int lch);
index 7a289ff07404c3b333c756e5b751316b9bfffb88..b5f3a71b899dbdb836394f84652831151b4390a5 100644 (file)
@@ -52,6 +52,8 @@ int omap_dm_timer_init(void);
 struct omap_dm_timer *omap_dm_timer_request(void);
 struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 void omap_dm_timer_free(struct omap_dm_timer *timer);
+void omap_dm_timer_enable(struct omap_dm_timer *timer);
+void omap_dm_timer_disable(struct omap_dm_timer *timer);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
index 1a0a5207822d660fc1e74efb1d501621a4a5c308..7c03ef6c14c4f6e7d4391bb5275ef9be61045aec 100644 (file)
@@ -85,7 +85,7 @@ extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
 extern u32 gpmc_cs_read_reg(int cs, int idx);
 extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
 extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
-extern unsigned long gpmc_cs_get_base_addr(int cs);
-
+extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+extern void gpmc_cs_free(int cs);
 
 #endif
index 2542495d8a435db14adc3baaaa1429d8bc114c49..c5bb05a69b81ec815c405d79b8b3bd553e29abc3 100644 (file)
 #define INT_24XX_SDMA_IRQ1     13
 #define INT_24XX_SDMA_IRQ2     14
 #define INT_24XX_SDMA_IRQ3     15
+#define INT_24XX_CAM_IRQ       24
 #define INT_24XX_DSS_IRQ       25
 #define INT_24XX_GPIO_BANK1    29
 #define INT_24XX_GPIO_BANK2    30
 #define INT_24XX_UART1_IRQ     72
 #define INT_24XX_UART2_IRQ     73
 #define INT_24XX_UART3_IRQ     74
+#define INT_24XX_MMC_IRQ       83
 
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
  * 16 MPUIO lines */
index 8a023a984acb52435367435a21320259e604b37f..b7f83075436ec7e226e224d327fa678f4a8c4e41 100644 (file)
@@ -14,7 +14,10 @@ struct omap_kp_platform_data {
        int rows;
        int cols;
        int *keymap;
+       unsigned int keymapsize;
        unsigned int rep:1;
+       unsigned long delay;
+       unsigned int dbounce:1;
        /* specific to OMAP242x*/
        unsigned int *row_gpios;
        unsigned int *col_gpios;
index 679869c5e68fbdd0ff4aca17028645cb9ee5bab6..828cc5c114e18e66e4e0c7a797b4df3d928dc281 100644 (file)
@@ -320,6 +320,17 @@ enum omap1xxx_index {
        P15_1610_UWIRE_CS3,
        N15_1610_UWIRE_CS1,
 
+       /* OMAP-1610 SPI */
+       U19_1610_SPIF_SCK,
+       U18_1610_SPIF_DIN,
+       P20_1610_SPIF_DIN,
+       W21_1610_SPIF_DOUT,
+       R18_1610_SPIF_DOUT,
+       N14_1610_SPIF_CS0,
+       N15_1610_SPIF_CS1,
+       T19_1610_SPIF_CS2,
+       P15_1610_SPIF_CS3,
+
        /* OMAP-1610 Flash */
        L3_1610_FLASH_CS2B_OE,
        M8_1610_FLASH_CS2B_WE,
@@ -461,6 +472,20 @@ enum omap24xx_index {
        K15_24XX_UART3_TX,
        K14_24XX_UART3_RX,
 
+       /* MMC/SDIO */
+       G19_24XX_MMC_CLKO,
+       H18_24XX_MMC_CMD,
+       F20_24XX_MMC_DAT0,
+       H14_24XX_MMC_DAT1,
+       E19_24XX_MMC_DAT2,
+       D19_24XX_MMC_DAT3,
+       F19_24XX_MMC_DAT_DIR0,
+       E20_24XX_MMC_DAT_DIR1,
+       F18_24XX_MMC_DAT_DIR2,
+       E18_24XX_MMC_DAT_DIR3,
+       G18_24XX_MMC_CMD_DIR,
+       H15_24XX_MMC_CLKI,
+
        /* Keypad GPIO*/
        T19_24XX_KBR0,
        R19_24XX_KBR1,
index 3661e465b0a5a51efe1e874e02ca826d9f3f8d77..7ac22483697130e6cdf7b57ccc9b3beac3376149 100644 (file)
 #define MAX_DMA_ADDRESS                0x40000000
 #define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
 
+/* We use `virtual` dma channels to hide the fact we have only a limited
+ * number of DMA channels, and not of all of them (dependant on the device)
+ * can be attached to any DMA source. We therefore let the DMA core handle
+ * the allocation of hardware channels to clients.
+*/
+
+enum dma_ch {
+       DMACH_XD0,
+       DMACH_XD1,
+       DMACH_SDI,
+       DMACH_SPI0,
+       DMACH_SPI1,
+       DMACH_UART0,
+       DMACH_UART1,
+       DMACH_UART2,
+       DMACH_TIMER,
+       DMACH_I2S_IN,
+       DMACH_I2S_OUT,
+       DMACH_PCM_IN,
+       DMACH_PCM_OUT,
+       DMACH_MIC_IN,
+       DMACH_USB_EP1,
+       DMACH_USB_EP2,
+       DMACH_USB_EP3,
+       DMACH_USB_EP4,
+       DMACH_UART0_SRC2,       /* s3c2412 second uart sources */
+       DMACH_UART1_SRC2,
+       DMACH_UART2_SRC2,
+       DMACH_MAX,              /* the end entry */
+};
+
+#define DMACH_LOW_LEVEL        (1<<28) /* use this to specifiy hardware ch no */
+
 /* we have 4 dma channels */
 #define S3C2410_DMA_CHANNELS        (4)
 
@@ -149,6 +182,8 @@ struct s3c2410_dma_stats {
        unsigned long           timeout_failed;
 };
 
+struct s3c2410_dma_map;
+
 /* struct s3c2410_dma_chan
  *
  * full state information for each DMA channel
@@ -174,6 +209,8 @@ struct s3c2410_dma_chan {
        unsigned long            load_timeout;
        unsigned int             flags;         /* channel flags */
 
+       struct s3c24xx_dma_map  *map;           /* channel hw maps */
+
        /* channel's hardware position and configuration */
        void __iomem            *regs;          /* channels registers */
        void __iomem            *addr_reg;      /* data address register */
@@ -283,6 +320,7 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 #define S3C2410_DMA_DCSRC       (0x18)
 #define S3C2410_DMA_DCDST       (0x1C)
 #define S3C2410_DMA_DMASKTRIG   (0x20)
+#define S3C2412_DMA_DMAREQSEL  (0x24)
 
 #define S3C2410_DISRCC_INC     (1<<0)
 #define S3C2410_DISRCC_APB     (1<<1)
@@ -349,4 +387,32 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 #define S3C2440_DCON_CH3_PCMOUT        (6<<24)
 #endif
 
+#ifdef CONFIG_CPU_S3C2412
+
+#define S3C2412_DMAREQSEL_SRC(x)       ((x)<<1)
+
+#define S3C2412_DMAREQSEL_HW           (1)
+
+#define S3C2412_DMAREQSEL_SPI0TX       S3C2412_DMAREQSEL_SRC(0)
+#define S3C2412_DMAREQSEL_SPI0RX       S3C2412_DMAREQSEL_SRC(1)
+#define S3C2412_DMAREQSEL_SPI1TX       S3C2412_DMAREQSEL_SRC(2)
+#define S3C2412_DMAREQSEL_SPI1RX       S3C2412_DMAREQSEL_SRC(3)
+#define S3C2412_DMAREQSEL_I2STX                S3C2412_DMAREQSEL_SRC(4)
+#define S3C2412_DMAREQSEL_I2SRX                S3C2412_DMAREQSEL_SRC(5)
+#define S3C2412_DMAREQSEL_TIMER                S3C2412_DMAREQSEL_SRC(9)
+#define S3C2412_DMAREQSEL_SDI          S3C2412_DMAREQSEL_SRC(10)
+#define S3C2412_DMAREQSEL_USBEP1       S3C2412_DMAREQSEL_SRC(13)
+#define S3C2412_DMAREQSEL_USBEP2       S3C2412_DMAREQSEL_SRC(14)
+#define S3C2412_DMAREQSEL_USBEP3       S3C2412_DMAREQSEL_SRC(15)
+#define S3C2412_DMAREQSEL_USBEP4       S3C2412_DMAREQSEL_SRC(16)
+#define S3C2412_DMAREQSEL_XDREQ0       S3C2412_DMAREQSEL_SRC(17)
+#define S3C2412_DMAREQSEL_XDREQ1       S3C2412_DMAREQSEL_SRC(18)
+#define S3C2412_DMAREQSEL_UART0_0      S3C2412_DMAREQSEL_SRC(19)
+#define S3C2412_DMAREQSEL_UART0_1      S3C2412_DMAREQSEL_SRC(20)
+#define S3C2412_DMAREQSEL_UART1_0      S3C2412_DMAREQSEL_SRC(21)
+#define S3C2412_DMAREQSEL_UART1_1      S3C2412_DMAREQSEL_SRC(22)
+#define S3C2412_DMAREQSEL_UART2_0      S3C2412_DMAREQSEL_SRC(23)
+#define S3C2412_DMAREQSEL_UART2_1      S3C2412_DMAREQSEL_SRC(24)
+
+#endif
 #endif /* __ASM_ARCH_DMA_H */
index 27ba0ac3fdd5ad48f5d8e9e40e610189d86bc421..7895042d176b3f4710514c7e6593484b709bf937 100644 (file)
 #define S3C2440_PA_CAMIF   (0x4F000000)
 #define S3C2440_SZ_CAMIF   SZ_1M
 
+/* AC97 */
+
+#define S3C2440_PA_AC97           (0x5B000000)
+#define S3C2440_SZ_AC97           SZ_1M
+
 /* ISA style IO, for each machine to sort out mappings for, if it
  * implements it. We reserve two 16M regions for ISA.
  */
index e2d406218ae554fe39b92bbd1c86af76554d86c1..a14164dfa525ae9638f40dedd4bd2cad5a7717bc 100644 (file)
 
 /* start peripherals off after the S3C2410 */
 
-#define OSIRIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x05000000))
+#define OSIRIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x04000000))
 
-#define OSIRIS_PA_CPLD         (S3C2410_CS1 | (3<<25))
+#define OSIRIS_PA_CPLD         (S3C2410_CS1 | (1<<26))
 
 /* we put the CPLD registers next, to get them out of the way */
 
-#define OSIRIS_VA_CTRL1            OSIRIS_IOADDR(0x00000000)    /* 0x01300000 */
+#define OSIRIS_VA_CTRL1            OSIRIS_IOADDR(0x00000000)
 #define OSIRIS_PA_CTRL1            (OSIRIS_PA_CPLD)
 
-#define OSIRIS_VA_CTRL2            OSIRIS_IOADDR(0x00100000)    /* 0x01400000 */
-#define OSIRIS_PA_CTRL2            (OSIRIS_PA_CPLD + (1<<24))
+#define OSIRIS_VA_CTRL2            OSIRIS_IOADDR(0x00100000)
+#define OSIRIS_PA_CTRL2            (OSIRIS_PA_CPLD + (1<<23))
 
-#define OSIRIS_VA_CTRL3            OSIRIS_IOADDR(0x00200000)    /* 0x01500000 */
-#define OSIRIS_PA_CTRL3            (OSIRIS_PA_CPLD + (2<<24))
+#define OSIRIS_VA_CTRL3            OSIRIS_IOADDR(0x00200000)
+#define OSIRIS_PA_CTRL3            (OSIRIS_PA_CPLD + (2<<23))
 
-#define OSIRIS_VA_CTRL4            OSIRIS_IOADDR(0x00300000)    /* 0x01600000 */
-#define OSIRIS_PA_CTRL4            (OSIRIS_PA_CPLD + (3<<24))
+#define OSIRIS_VA_CTRL4            OSIRIS_IOADDR(0x00300000)
+#define OSIRIS_PA_CTRL4            (OSIRIS_PA_CPLD + (3<<23))
 
 #endif /* __ASM_ARCH_OSIRISMAP_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-ac97.h b/include/asm-arm/arch-s3c2410/regs-ac97.h
new file mode 100644 (file)
index 0000000..bdd6a4f
--- /dev/null
@@ -0,0 +1,23 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-ac97.h
+ *
+ * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk>
+ *             http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440 AC97 Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_AC97_H
+#define __ASM_ARCH_REGS_AC97_H __FILE__
+
+#define S3C_AC97_GLBCTRL       (0x00)
+#define S3C_AC97_GLBSTAT       (0x04)
+#define S3C_AC97_CODEC_CMD     (0x08)
+#define S3C_AC97_PCM_ADDR      (0x10)
+#define S3C_AC97_PCM_DATA      (0x18)
+#define S3C_AC97_MIC_DATA      (0x1C)
+
+#endif /* __ASM_ARCH_REGS_AC97_H */
index b306d6e3135d00d212e1606adaef7047bfcfa970..6d7881c8cfc8ee35077a018f56b17a1a7f2d98ba 100644 (file)
@@ -63,6 +63,8 @@
 #define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
 #define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >>  0) & 0xFF)
 
+/* LDCCON4 changes for STN mode on the S3C2412 */
+
 #define S3C2410_LCDCON4_MVAL(x)            ((x) << 8)
 #define S3C2410_LCDCON4_HSPW(x)            ((x) << 0)
 #define S3C2410_LCDCON4_WLH(x)     ((x) << 0)
 #define        S3C2410_LCDINT_FRSYNC   (1<<1)
 #define S3C2410_LCDINT_FICNT   (1<<0)
 
+/* s3c2442 extra stn registers */
+
+#define S3C2442_REDLUT         S3C2410_LCDREG(0x20)
+#define S3C2442_GREENLUT       S3C2410_LCDREG(0x24)
+#define S3C2442_BLUELUT                S3C2410_LCDREG(0x28)
+#define S3C2442_DITHMODE       S3C2410_LCDREG(0x20)
+
 #define S3C2410_LPCSEL    S3C2410_LCDREG(0x60)
 
 #define S3C2410_TFTPAL(x)  S3C2410_LCDREG((0x400 + (x)*4))
 
+/* S3C2412 registers */
+
+#define S3C2412_TPAL           S3C2410_LCDREG(0x20)
+
+#define S3C2412_LCDINTPND      S3C2410_LCDREG(0x24)
+#define S3C2412_LCDSRCPND      S3C2410_LCDREG(0x28)
+#define S3C2412_LCDINTMSK      S3C2410_LCDREG(0x2C)
+
+#define S3C2412_TCONSEL                S3C2410_LCDREG(0x30)
+
+#define S3C2412_LCDCON6                S3C2410_LCDREG(0x34)
+#define S3C2412_LCDCON7                S3C2410_LCDREG(0x38)
+#define S3C2412_LCDCON8                S3C2410_LCDREG(0x3C)
+#define S3C2412_LCDCON9                S3C2410_LCDREG(0x40)
+
+#define S3C2412_REDLUT(x)      S3C2410_LCDREG(0x44 + ((x)*4))
+#define S3C2412_GREENLUT(x)    S3C2410_LCDREG(0x60 + ((x)*4))
+#define S3C2412_BLUELUT(x)     S3C2410_LCDREG(0x98 + ((x)*4))
+
+#define S3C2412_FRCPAT(x)      S3C2410_LCDREG(0xB4 + ((x)*4))
+
 #endif /* ___ASM_ARCH_REGS_LCD_H */
 
 
index 4b0ce3e7de9a4267088ab585e46232214b139879..ea88aa6bfc78e91c9d0442ab2b504e3ddabe1c56 100644 (file)
@@ -128,10 +128,10 @@ static inline int atomic_add_return(int i, atomic_t *v)
        unsigned long flags;
        int val;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        val = v->counter;
        v->counter = val += i;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return val;
 }
@@ -141,10 +141,10 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        unsigned long flags;
        int val;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        val = v->counter;
        v->counter = val -= i;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return val;
 }
@@ -154,11 +154,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
        int ret;
        unsigned long flags;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        ret = v->counter;
        if (likely(ret == old))
                v->counter = new;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return ret;
 }
@@ -167,9 +167,9 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
        unsigned long flags;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        *addr &= ~mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 }
 
 #endif /* __LINUX_ARM_ARCH__ */
index 0ac54b1a8bad7c0e8e7a7a3ec8f5063d6c972732..b41831b6432fb44f7967720b31e892e58005ed82 100644 (file)
@@ -37,9 +37,9 @@ static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        *p |= mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 }
 
 static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
@@ -49,9 +49,9 @@ static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        *p &= ~mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 }
 
 static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
@@ -61,9 +61,9 @@ static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned lon
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        *p ^= mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 }
 
 static inline int
@@ -75,10 +75,10 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        res = *p;
        *p = res | mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return res & mask;
 }
@@ -92,10 +92,10 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        res = *p;
        *p = res & ~mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return res & mask;
 }
@@ -109,10 +109,10 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 
        p += bit >> 5;
 
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        res = *p;
        *p = res ^ mask;
-       local_irq_restore(flags);
+       raw_local_irq_restore(flags);
 
        return res & mask;
 }
index e4a2569c636c688da3da32b7ff73fde1105a3fcd..f0845646aacb34a05332f7b7348cbbec436ed9f1 100644 (file)
@@ -25,7 +25,7 @@
 #undef _CACHE
 #undef MULTI_CACHE
 
-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+#if defined(CONFIG_CPU_CACHE_V3)
 # ifdef _CACHE
 #  define MULTI_CACHE 1
 # else
@@ -33,7 +33,7 @@
 # endif
 #endif
 
-#if defined(CONFIG_CPU_ARM720T)
+#if defined(CONFIG_CPU_CACHE_V4)
 # ifdef _CACHE
 #  define MULTI_CACHE 1
 # else
 # endif
 #endif
 
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+#if defined(CONFIG_CPU_ARM940T)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE arm940
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM946E)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE arm946
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4WB)
 # ifdef _CACHE
 #  define MULTI_CACHE 1
 # else
diff --git a/include/asm-arm/flat.h b/include/asm-arm/flat.h
new file mode 100644 (file)
index 0000000..9669464
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-arm/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __ARM_FLAT_H__
+#define __ARM_FLAT_H__
+
+#define        flat_stack_align(sp)                    /* nothing needed */
+#define        flat_argvp_envp_on_stack()              1
+#define        flat_old_ram_flag(flags)                (flags)
+#define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
+#define        flat_get_addr_from_rp(rp, relval, flags) get_unaligned(rp)
+#define        flat_put_addr_at_rp(rp, val, relval)    put_unaligned(val,rp)
+#define        flat_get_relocate_addr(rel)             (rel)
+
+#endif /* __ARM_FLAT_H__ */
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h
new file mode 100644 (file)
index 0000000..1018a74
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * include/asm-arm/hardware/iop3xx.h
+ *
+ * Intel IOP32X and IOP33X register definitions
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef __IOP3XX_H
+#define __IOP3XX_H
+
+/*
+ * IOP3XX GPIO handling
+ */
+#define GPIO_IN                        0
+#define GPIO_OUT               1
+#define GPIO_LOW               0
+#define GPIO_HIGH              1
+#define IOP3XX_GPIO_LINE(x)    (x)
+
+#ifndef __ASSEMBLY__
+extern void gpio_line_config(int line, int direction);
+extern int  gpio_line_get(int line);
+extern void gpio_line_set(int line, int value);
+#endif
+
+
+/*
+ * IOP3XX processor registers
+ */
+#define IOP3XX_PERIPHERAL_PHYS_BASE    0xffffe000
+#define IOP3XX_PERIPHERAL_VIRT_BASE    0xfeffe000
+#define IOP3XX_PERIPHERAL_SIZE         0x00002000
+#define IOP3XX_REG_ADDR(reg)           (IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
+
+/* Address Translation Unit  */
+#define IOP3XX_ATUVID          (volatile u16 *)IOP3XX_REG_ADDR(0x0100)
+#define IOP3XX_ATUDID          (volatile u16 *)IOP3XX_REG_ADDR(0x0102)
+#define IOP3XX_ATUCMD          (volatile u16 *)IOP3XX_REG_ADDR(0x0104)
+#define IOP3XX_ATUSR           (volatile u16 *)IOP3XX_REG_ADDR(0x0106)
+#define IOP3XX_ATURID          (volatile u8  *)IOP3XX_REG_ADDR(0x0108)
+#define IOP3XX_ATUCCR          (volatile u32 *)IOP3XX_REG_ADDR(0x0109)
+#define IOP3XX_ATUCLSR         (volatile u8  *)IOP3XX_REG_ADDR(0x010c)
+#define IOP3XX_ATULT           (volatile u8  *)IOP3XX_REG_ADDR(0x010d)
+#define IOP3XX_ATUHTR          (volatile u8  *)IOP3XX_REG_ADDR(0x010e)
+#define IOP3XX_ATUBIST         (volatile u8  *)IOP3XX_REG_ADDR(0x010f)
+#define IOP3XX_IABAR0          (volatile u32 *)IOP3XX_REG_ADDR(0x0110)
+#define IOP3XX_IAUBAR0         (volatile u32 *)IOP3XX_REG_ADDR(0x0114)
+#define IOP3XX_IABAR1          (volatile u32 *)IOP3XX_REG_ADDR(0x0118)
+#define IOP3XX_IAUBAR1         (volatile u32 *)IOP3XX_REG_ADDR(0x011c)
+#define IOP3XX_IABAR2          (volatile u32 *)IOP3XX_REG_ADDR(0x0120)
+#define IOP3XX_IAUBAR2         (volatile u32 *)IOP3XX_REG_ADDR(0x0124)
+#define IOP3XX_ASVIR           (volatile u16 *)IOP3XX_REG_ADDR(0x012c)
+#define IOP3XX_ASIR            (volatile u16 *)IOP3XX_REG_ADDR(0x012e)
+#define IOP3XX_ERBAR           (volatile u32 *)IOP3XX_REG_ADDR(0x0130)
+#define IOP3XX_ATUILR          (volatile u8  *)IOP3XX_REG_ADDR(0x013c)
+#define IOP3XX_ATUIPR          (volatile u8  *)IOP3XX_REG_ADDR(0x013d)
+#define IOP3XX_ATUMGNT         (volatile u8  *)IOP3XX_REG_ADDR(0x013e)
+#define IOP3XX_ATUMLAT         (volatile u8  *)IOP3XX_REG_ADDR(0x013f)
+#define IOP3XX_IALR0           (volatile u32 *)IOP3XX_REG_ADDR(0x0140)
+#define IOP3XX_IATVR0          (volatile u32 *)IOP3XX_REG_ADDR(0x0144)
+#define IOP3XX_ERLR            (volatile u32 *)IOP3XX_REG_ADDR(0x0148)
+#define IOP3XX_ERTVR           (volatile u32 *)IOP3XX_REG_ADDR(0x014c)
+#define IOP3XX_IALR1           (volatile u32 *)IOP3XX_REG_ADDR(0x0150)
+#define IOP3XX_IALR2           (volatile u32 *)IOP3XX_REG_ADDR(0x0154)
+#define IOP3XX_IATVR2          (volatile u32 *)IOP3XX_REG_ADDR(0x0158)
+#define IOP3XX_OIOWTVR         (volatile u32 *)IOP3XX_REG_ADDR(0x015c)
+#define IOP3XX_OMWTVR0         (volatile u32 *)IOP3XX_REG_ADDR(0x0160)
+#define IOP3XX_OUMWTVR0                (volatile u32 *)IOP3XX_REG_ADDR(0x0164)
+#define IOP3XX_OMWTVR1         (volatile u32 *)IOP3XX_REG_ADDR(0x0168)
+#define IOP3XX_OUMWTVR1                (volatile u32 *)IOP3XX_REG_ADDR(0x016c)
+#define IOP3XX_OUDWTVR         (volatile u32 *)IOP3XX_REG_ADDR(0x0178)
+#define IOP3XX_ATUCR           (volatile u32 *)IOP3XX_REG_ADDR(0x0180)
+#define IOP3XX_PCSR            (volatile u32 *)IOP3XX_REG_ADDR(0x0184)
+#define IOP3XX_ATUISR          (volatile u32 *)IOP3XX_REG_ADDR(0x0188)
+#define IOP3XX_ATUIMR          (volatile u32 *)IOP3XX_REG_ADDR(0x018c)
+#define IOP3XX_IABAR3          (volatile u32 *)IOP3XX_REG_ADDR(0x0190)
+#define IOP3XX_IAUBAR3         (volatile u32 *)IOP3XX_REG_ADDR(0x0194)
+#define IOP3XX_IALR3           (volatile u32 *)IOP3XX_REG_ADDR(0x0198)
+#define IOP3XX_IATVR3          (volatile u32 *)IOP3XX_REG_ADDR(0x019c)
+#define IOP3XX_OCCAR           (volatile u32 *)IOP3XX_REG_ADDR(0x01a4)
+#define IOP3XX_OCCDR           (volatile u32 *)IOP3XX_REG_ADDR(0x01ac)
+#define IOP3XX_PDSCR           (volatile u32 *)IOP3XX_REG_ADDR(0x01bc)
+#define IOP3XX_PMCAPID         (volatile u8  *)IOP3XX_REG_ADDR(0x01c0)
+#define IOP3XX_PMNEXT          (volatile u8  *)IOP3XX_REG_ADDR(0x01c1)
+#define IOP3XX_APMCR           (volatile u16 *)IOP3XX_REG_ADDR(0x01c2)
+#define IOP3XX_APMCSR          (volatile u16 *)IOP3XX_REG_ADDR(0x01c4)
+#define IOP3XX_PCIXCAPID       (volatile u8  *)IOP3XX_REG_ADDR(0x01e0)
+#define IOP3XX_PCIXNEXT                (volatile u8  *)IOP3XX_REG_ADDR(0x01e1)
+#define IOP3XX_PCIXCMD         (volatile u16 *)IOP3XX_REG_ADDR(0x01e2)
+#define IOP3XX_PCIXSR          (volatile u32 *)IOP3XX_REG_ADDR(0x01e4)
+#define IOP3XX_PCIIRSR         (volatile u32 *)IOP3XX_REG_ADDR(0x01ec)
+
+/* Messaging Unit  */
+#define IOP3XX_IMR0            (volatile u32 *)IOP3XX_REG_ADDR(0x0310)
+#define IOP3XX_IMR1            (volatile u32 *)IOP3XX_REG_ADDR(0x0314)
+#define IOP3XX_OMR0            (volatile u32 *)IOP3XX_REG_ADDR(0x0318)
+#define IOP3XX_OMR1            (volatile u32 *)IOP3XX_REG_ADDR(0x031c)
+#define IOP3XX_IDR             (volatile u32 *)IOP3XX_REG_ADDR(0x0320)
+#define IOP3XX_IISR            (volatile u32 *)IOP3XX_REG_ADDR(0x0324)
+#define IOP3XX_IIMR            (volatile u32 *)IOP3XX_REG_ADDR(0x0328)
+#define IOP3XX_ODR             (volatile u32 *)IOP3XX_REG_ADDR(0x032c)
+#define IOP3XX_OISR            (volatile u32 *)IOP3XX_REG_ADDR(0x0330)
+#define IOP3XX_OIMR            (volatile u32 *)IOP3XX_REG_ADDR(0x0334)
+#define IOP3XX_MUCR            (volatile u32 *)IOP3XX_REG_ADDR(0x0350)
+#define IOP3XX_QBAR            (volatile u32 *)IOP3XX_REG_ADDR(0x0354)
+#define IOP3XX_IFHPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0360)
+#define IOP3XX_IFTPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0364)
+#define IOP3XX_IPHPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0368)
+#define IOP3XX_IPTPR           (volatile u32 *)IOP3XX_REG_ADDR(0x036c)
+#define IOP3XX_OFHPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0370)
+#define IOP3XX_OFTPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0374)
+#define IOP3XX_OPHPR           (volatile u32 *)IOP3XX_REG_ADDR(0x0378)
+#define IOP3XX_OPTPR           (volatile u32 *)IOP3XX_REG_ADDR(0x037c)
+#define IOP3XX_IAR             (volatile u32 *)IOP3XX_REG_ADDR(0x0380)
+
+/* DMA Controller  */
+#define IOP3XX_DMA0_CCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0400)
+#define IOP3XX_DMA0_CSR                (volatile u32 *)IOP3XX_REG_ADDR(0x0404)
+#define IOP3XX_DMA0_DAR                (volatile u32 *)IOP3XX_REG_ADDR(0x040c)
+#define IOP3XX_DMA0_NDAR       (volatile u32 *)IOP3XX_REG_ADDR(0x0410)
+#define IOP3XX_DMA0_PADR       (volatile u32 *)IOP3XX_REG_ADDR(0x0414)
+#define IOP3XX_DMA0_PUADR      (volatile u32 *)IOP3XX_REG_ADDR(0x0418)
+#define IOP3XX_DMA0_LADR       (volatile u32 *)IOP3XX_REG_ADDR(0x041c)
+#define IOP3XX_DMA0_BCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0420)
+#define IOP3XX_DMA0_DCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0424)
+#define IOP3XX_DMA1_CCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0440)
+#define IOP3XX_DMA1_CSR                (volatile u32 *)IOP3XX_REG_ADDR(0x0444)
+#define IOP3XX_DMA1_DAR                (volatile u32 *)IOP3XX_REG_ADDR(0x044c)
+#define IOP3XX_DMA1_NDAR       (volatile u32 *)IOP3XX_REG_ADDR(0x0450)
+#define IOP3XX_DMA1_PADR       (volatile u32 *)IOP3XX_REG_ADDR(0x0454)
+#define IOP3XX_DMA1_PUADR      (volatile u32 *)IOP3XX_REG_ADDR(0x0458)
+#define IOP3XX_DMA1_LADR       (volatile u32 *)IOP3XX_REG_ADDR(0x045c)
+#define IOP3XX_DMA1_BCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0460)
+#define IOP3XX_DMA1_DCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0464)
+
+/* Peripheral bus interface  */
+#define IOP3XX_PBCR            (volatile u32 *)IOP3XX_REG_ADDR(0x0680)
+#define IOP3XX_PBISR           (volatile u32 *)IOP3XX_REG_ADDR(0x0684)
+#define IOP3XX_PBBAR0          (volatile u32 *)IOP3XX_REG_ADDR(0x0688)
+#define IOP3XX_PBLR0           (volatile u32 *)IOP3XX_REG_ADDR(0x068c)
+#define IOP3XX_PBBAR1          (volatile u32 *)IOP3XX_REG_ADDR(0x0690)
+#define IOP3XX_PBLR1           (volatile u32 *)IOP3XX_REG_ADDR(0x0694)
+#define IOP3XX_PBBAR2          (volatile u32 *)IOP3XX_REG_ADDR(0x0698)
+#define IOP3XX_PBLR2           (volatile u32 *)IOP3XX_REG_ADDR(0x069c)
+#define IOP3XX_PBBAR3          (volatile u32 *)IOP3XX_REG_ADDR(0x06a0)
+#define IOP3XX_PBLR3           (volatile u32 *)IOP3XX_REG_ADDR(0x06a4)
+#define IOP3XX_PBBAR4          (volatile u32 *)IOP3XX_REG_ADDR(0x06a8)
+#define IOP3XX_PBLR4           (volatile u32 *)IOP3XX_REG_ADDR(0x06ac)
+#define IOP3XX_PBBAR5          (volatile u32 *)IOP3XX_REG_ADDR(0x06b0)
+#define IOP3XX_PBLR5           (volatile u32 *)IOP3XX_REG_ADDR(0x06b4)
+#define IOP3XX_PMBR0           (volatile u32 *)IOP3XX_REG_ADDR(0x06c0)
+#define IOP3XX_PMBR1           (volatile u32 *)IOP3XX_REG_ADDR(0x06e0)
+#define IOP3XX_PMBR2           (volatile u32 *)IOP3XX_REG_ADDR(0x06e4)
+
+/* Peripheral performance monitoring unit  */
+#define IOP3XX_GTMR            (volatile u32 *)IOP3XX_REG_ADDR(0x0700)
+#define IOP3XX_ESR             (volatile u32 *)IOP3XX_REG_ADDR(0x0704)
+#define IOP3XX_EMISR           (volatile u32 *)IOP3XX_REG_ADDR(0x0708)
+#define IOP3XX_GTSR            (volatile u32 *)IOP3XX_REG_ADDR(0x0710)
+/* PERCR0 DOESN'T EXIST - index from 1! */
+#define IOP3XX_PERCR0          (volatile u32 *)IOP3XX_REG_ADDR(0x0710)
+
+/* General Purpose I/O  */
+#define IOP3XX_GPOE            (volatile u32 *)IOP3XX_GPIO_REG(0x0004)
+#define IOP3XX_GPID            (volatile u32 *)IOP3XX_GPIO_REG(0x0008)
+#define IOP3XX_GPOD            (volatile u32 *)IOP3XX_GPIO_REG(0x000c)
+
+/* Timers  */
+#define IOP3XX_TU_TMR0         (volatile u32 *)IOP3XX_TIMER_REG(0x0000)
+#define IOP3XX_TU_TMR1         (volatile u32 *)IOP3XX_TIMER_REG(0x0004)
+#define IOP3XX_TU_TCR0         (volatile u32 *)IOP3XX_TIMER_REG(0x0008)
+#define IOP3XX_TU_TCR1         (volatile u32 *)IOP3XX_TIMER_REG(0x000c)
+#define IOP3XX_TU_TRR0         (volatile u32 *)IOP3XX_TIMER_REG(0x0010)
+#define IOP3XX_TU_TRR1         (volatile u32 *)IOP3XX_TIMER_REG(0x0014)
+#define IOP3XX_TU_TISR         (volatile u32 *)IOP3XX_TIMER_REG(0x0018)
+#define IOP3XX_TU_WDTCR                (volatile u32 *)IOP3XX_TIMER_REG(0x001c)
+#define IOP3XX_TMR_TC          0x01
+#define IOP3XX_TMR_EN          0x02
+#define IOP3XX_TMR_RELOAD      0x04
+#define IOP3XX_TMR_PRIVILEGED  0x09
+#define IOP3XX_TMR_RATIO_1_1   0x00
+#define IOP3XX_TMR_RATIO_4_1   0x10
+#define IOP3XX_TMR_RATIO_8_1   0x20
+#define IOP3XX_TMR_RATIO_16_1  0x30
+
+/* Application accelerator unit  */
+#define IOP3XX_AAU_ACR         (volatile u32 *)IOP3XX_REG_ADDR(0x0800)
+#define IOP3XX_AAU_ASR         (volatile u32 *)IOP3XX_REG_ADDR(0x0804)
+#define IOP3XX_AAU_ADAR                (volatile u32 *)IOP3XX_REG_ADDR(0x0808)
+#define IOP3XX_AAU_ANDAR       (volatile u32 *)IOP3XX_REG_ADDR(0x080c)
+#define IOP3XX_AAU_SAR1                (volatile u32 *)IOP3XX_REG_ADDR(0x0810)
+#define IOP3XX_AAU_SAR2                (volatile u32 *)IOP3XX_REG_ADDR(0x0814)
+#define IOP3XX_AAU_SAR3                (volatile u32 *)IOP3XX_REG_ADDR(0x0818)
+#define IOP3XX_AAU_SAR4                (volatile u32 *)IOP3XX_REG_ADDR(0x081c)
+#define IOP3XX_AAU_DAR         (volatile u32 *)IOP3XX_REG_ADDR(0x0820)
+#define IOP3XX_AAU_ABCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0824)
+#define IOP3XX_AAU_ADCR                (volatile u32 *)IOP3XX_REG_ADDR(0x0828)
+#define IOP3XX_AAU_SAR5                (volatile u32 *)IOP3XX_REG_ADDR(0x082c)
+#define IOP3XX_AAU_SAR6                (volatile u32 *)IOP3XX_REG_ADDR(0x0830)
+#define IOP3XX_AAU_SAR7                (volatile u32 *)IOP3XX_REG_ADDR(0x0834)
+#define IOP3XX_AAU_SAR8                (volatile u32 *)IOP3XX_REG_ADDR(0x0838)
+#define IOP3XX_AAU_EDCR0       (volatile u32 *)IOP3XX_REG_ADDR(0x083c)
+#define IOP3XX_AAU_SAR9                (volatile u32 *)IOP3XX_REG_ADDR(0x0840)
+#define IOP3XX_AAU_SAR10       (volatile u32 *)IOP3XX_REG_ADDR(0x0844)
+#define IOP3XX_AAU_SAR11       (volatile u32 *)IOP3XX_REG_ADDR(0x0848)
+#define IOP3XX_AAU_SAR12       (volatile u32 *)IOP3XX_REG_ADDR(0x084c)
+#define IOP3XX_AAU_SAR13       (volatile u32 *)IOP3XX_REG_ADDR(0x0850)
+#define IOP3XX_AAU_SAR14       (volatile u32 *)IOP3XX_REG_ADDR(0x0854)
+#define IOP3XX_AAU_SAR15       (volatile u32 *)IOP3XX_REG_ADDR(0x0858)
+#define IOP3XX_AAU_SAR16       (volatile u32 *)IOP3XX_REG_ADDR(0x085c)
+#define IOP3XX_AAU_EDCR1       (volatile u32 *)IOP3XX_REG_ADDR(0x0860)
+#define IOP3XX_AAU_SAR17       (volatile u32 *)IOP3XX_REG_ADDR(0x0864)
+#define IOP3XX_AAU_SAR18       (volatile u32 *)IOP3XX_REG_ADDR(0x0868)
+#define IOP3XX_AAU_SAR19       (volatile u32 *)IOP3XX_REG_ADDR(0x086c)
+#define IOP3XX_AAU_SAR20       (volatile u32 *)IOP3XX_REG_ADDR(0x0870)
+#define IOP3XX_AAU_SAR21       (volatile u32 *)IOP3XX_REG_ADDR(0x0874)
+#define IOP3XX_AAU_SAR22       (volatile u32 *)IOP3XX_REG_ADDR(0x0878)
+#define IOP3XX_AAU_SAR23       (volatile u32 *)IOP3XX_REG_ADDR(0x087c)
+#define IOP3XX_AAU_SAR24       (volatile u32 *)IOP3XX_REG_ADDR(0x0880)
+#define IOP3XX_AAU_EDCR2       (volatile u32 *)IOP3XX_REG_ADDR(0x0884)
+#define IOP3XX_AAU_SAR25       (volatile u32 *)IOP3XX_REG_ADDR(0x0888)
+#define IOP3XX_AAU_SAR26       (volatile u32 *)IOP3XX_REG_ADDR(0x088c)
+#define IOP3XX_AAU_SAR27       (volatile u32 *)IOP3XX_REG_ADDR(0x0890)
+#define IOP3XX_AAU_SAR28       (volatile u32 *)IOP3XX_REG_ADDR(0x0894)
+#define IOP3XX_AAU_SAR29       (volatile u32 *)IOP3XX_REG_ADDR(0x0898)
+#define IOP3XX_AAU_SAR30       (volatile u32 *)IOP3XX_REG_ADDR(0x089c)
+#define IOP3XX_AAU_SAR31       (volatile u32 *)IOP3XX_REG_ADDR(0x08a0)
+#define IOP3XX_AAU_SAR32       (volatile u32 *)IOP3XX_REG_ADDR(0x08a4)
+
+/* I2C bus interface unit  */
+#define IOP3XX_ICR0            (volatile u32 *)IOP3XX_REG_ADDR(0x1680)
+#define IOP3XX_ISR0            (volatile u32 *)IOP3XX_REG_ADDR(0x1684)
+#define IOP3XX_ISAR0           (volatile u32 *)IOP3XX_REG_ADDR(0x1688)
+#define IOP3XX_IDBR0           (volatile u32 *)IOP3XX_REG_ADDR(0x168c)
+#define IOP3XX_IBMR0           (volatile u32 *)IOP3XX_REG_ADDR(0x1694)
+#define IOP3XX_ICR1            (volatile u32 *)IOP3XX_REG_ADDR(0x16a0)
+#define IOP3XX_ISR1            (volatile u32 *)IOP3XX_REG_ADDR(0x16a4)
+#define IOP3XX_ISAR1           (volatile u32 *)IOP3XX_REG_ADDR(0x16a8)
+#define IOP3XX_IDBR1           (volatile u32 *)IOP3XX_REG_ADDR(0x16ac)
+#define IOP3XX_IBMR1           (volatile u32 *)IOP3XX_REG_ADDR(0x16b4)
+
+
+/*
+ * IOP3XX I/O and Mem space regions for PCI autoconfiguration
+ */
+#define IOP3XX_PCI_MEM_WINDOW_SIZE     0x04000000
+#define IOP3XX_PCI_LOWER_MEM_PA                0x80000000
+#define IOP3XX_PCI_LOWER_MEM_BA                (*IOP3XX_OMWTVR0)
+
+#define IOP3XX_PCI_IO_WINDOW_SIZE      0x00010000
+#define IOP3XX_PCI_LOWER_IO_PA         0x90000000
+#define IOP3XX_PCI_LOWER_IO_VA         0xfe000000
+#define IOP3XX_PCI_LOWER_IO_BA         (*IOP3XX_OIOWTVR)
+
+
+#ifndef __ASSEMBLY__
+void iop3xx_map_io(void);
+void iop3xx_init_time(unsigned long);
+unsigned long iop3xx_gettimeoffset(void);
+
+extern struct platform_device iop3xx_i2c0_device;
+extern struct platform_device iop3xx_i2c1_device;
+
+extern inline void iop3xx_cp6_enable(void)
+{
+       u32 temp;
+
+       asm volatile (
+               "mrc    p15, 0, %0, c15, c1, 0\n\t"
+               "orr    %0, %0, #(1 << 6)\n\t"
+               "mcr    p15, 0, %0, c15, c1, 0\n\t"
+               "mrc    p15, 0, %0, c15, c1, 0\n\t"
+               "mov    %0, %0\n\t"
+               "sub    pc, pc, #4\n\t"
+               : "=r" (temp) );
+}
+
+extern inline void iop3xx_cp6_disable(void)
+{
+       u32 temp;
+
+       asm volatile (
+               "mrc    p15, 0, %0, c15, c1, 0\n\t"
+               "bic    %0, %0, #(1 << 6)\n\t"
+               "mcr    p15, 0, %0, c15, c1, 0\n\t"
+               "mrc    p15, 0, %0, c15, c1, 0\n\t"
+               "mov    %0, %0\n\t"
+               "sub    pc, pc, #4\n\t"
+               : "=r" (temp) );
+}
+#endif
+
+
+#endif
index 22dfb1737768537c45cb73df860b7d4f22d2621b..adab77780ed3afe2522c1b2cb34fb7ae05b222d4 100644 (file)
 #define        LOCOMO_DAC_SDAOEB       0x01    /* SDA pin output data       */
 
 /* SPI interface */
-#define LOCOMO_SPIMD   0x60            /* SPI mode setting */
-#define LOCOMO_SPICT   0x64            /* SPI mode control */
-#define LOCOMO_SPIST   0x68            /* SPI status */
-#define LOCOMO_SPIIS   0x70            /* SPI interrupt status */
-#define LOCOMO_SPIWE   0x74            /* SPI interrupt status write enable */
-#define LOCOMO_SPIIE   0x78            /* SPI interrupt enable */
-#define LOCOMO_SPIIR   0x7c            /* SPI interrupt request */
-#define LOCOMO_SPITD   0x80            /* SPI transfer data write */
-#define LOCOMO_SPIRD   0x84            /* SPI receive data read */
-#define LOCOMO_SPITS   0x88            /* SPI transfer data shift */
-#define LOCOMO_SPIRS   0x8C            /* SPI receive data shift */
+#define LOCOMO_SPI     0x60
+#define LOCOMO_SPIMD   0x00            /* SPI mode setting */
+#define LOCOMO_SPICT   0x04            /* SPI mode control */
+#define LOCOMO_SPIST   0x08            /* SPI status */
+#define LOCOMO_SPIIS   0x10            /* SPI interrupt status */
+#define LOCOMO_SPIWE   0x14            /* SPI interrupt status write enable */
+#define LOCOMO_SPIIE   0x18            /* SPI interrupt enable */
+#define LOCOMO_SPIIR   0x1c            /* SPI interrupt request */
+#define LOCOMO_SPITD   0x20            /* SPI transfer data write */
+#define LOCOMO_SPIRD   0x24            /* SPI receive data read */
+#define LOCOMO_SPITS   0x28            /* SPI transfer data shift */
+#define LOCOMO_SPIRS   0x2C            /* SPI receive data shift */
 #define        LOCOMO_SPI_TEND (1 << 3)        /* Transfer end bit */
 #define        LOCOMO_SPI_OVRN (1 << 2)        /* Over Run bit */
 #define        LOCOMO_SPI_RFW  (1 << 1)        /* write buffer bit */
@@ -161,6 +162,7 @@ extern struct bus_type locomo_bus_type;
 #define LOCOMO_DEVID_AUDIO     3
 #define LOCOMO_DEVID_LED       4
 #define LOCOMO_DEVID_UART      5
+#define LOCOMO_DEVID_SPI               6
 
 struct locomo_dev {
        struct device   dev;
@@ -197,10 +199,11 @@ int locomo_driver_register(struct locomo_driver *);
 void locomo_driver_unregister(struct locomo_driver *);
 
 /* GPIO control functions */
-void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir);
-unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits);
-unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits);
-void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set);
+void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir);
+int locomo_gpio_read_level(struct device *dev, unsigned int bits);
+int locomo_gpio_read_output(struct device *dev, unsigned int bits);
+void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set);
+
 
 /* M62332 control function */
 void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
index ecf15b83956f88ce1b09ef99943ad95501de7263..a836e76a14f7de1b8b8c8da0215304de6ad8801a 100644 (file)
@@ -25,6 +25,7 @@ struct sharpsl_charger_machinfo {
        void (*measure_temp)(int);
        void (*presuspend)(void);
        void (*postsuspend)(void);
+       void (*earlyresume)(void);
        unsigned long (*read_devdata)(int);
 #define SHARPSL_BATT_VOLT       1
 #define SHARPSL_BATT_TEMP       2
index bf7b9dea30f1f9b0ae7f16dfbc1cd752e5c5327c..8076a85c367541479c6e6aaa4dd54e358cb3ba6f 100644 (file)
@@ -280,6 +280,10 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
 #define BIOVEC_MERGEABLE(vec1, vec2)   \
        ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
 
+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
+extern int valid_phys_addr_range(unsigned long addr, size_t size);
+extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
diff --git a/include/asm-arm/irqflags.h b/include/asm-arm/irqflags.h
new file mode 100644 (file)
index 0000000..6d09974
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef __ASM_ARM_IRQFLAGS_H
+#define __ASM_ARM_IRQFLAGS_H
+
+#ifdef __KERNEL__
+
+#include <asm/ptrace.h>
+
+/*
+ * CPU interrupt mask handling.
+ */
+#if __LINUX_ARM_ARCH__ >= 6
+
+#define raw_local_irq_save(x)                                  \
+       ({                                                      \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_irq_save\n"     \
+       "cpsid  i"                                              \
+       : "=r" (x) : : "memory", "cc");                         \
+       })
+
+#define raw_local_irq_enable()  __asm__("cpsie i       @ __sti" : : : "memory", "cc")
+#define raw_local_irq_disable() __asm__("cpsid i       @ __cli" : : : "memory", "cc")
+#define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory", "cc")
+#define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory", "cc")
+
+#else
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define raw_local_irq_save(x)                                  \
+       ({                                                      \
+               unsigned long temp;                             \
+               (void) (&temp == &x);                           \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_irq_save\n"     \
+"      orr     %1, %0, #128\n"                                 \
+"      msr     cpsr_c, %1"                                     \
+       : "=r" (x), "=r" (temp)                                 \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+       
+/*
+ * Enable IRQs
+ */
+#define raw_local_irq_enable()                                 \
+       ({                                                      \
+               unsigned long temp;                             \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_irq_enable\n"   \
+"      bic     %0, %0, #128\n"                                 \
+"      msr     cpsr_c, %0"                                     \
+       : "=r" (temp)                                           \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+
+/*
+ * Disable IRQs
+ */
+#define raw_local_irq_disable()                                        \
+       ({                                                      \
+               unsigned long temp;                             \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_irq_disable\n"  \
+"      orr     %0, %0, #128\n"                                 \
+"      msr     cpsr_c, %0"                                     \
+       : "=r" (temp)                                           \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+
+/*
+ * Enable FIQs
+ */
+#define local_fiq_enable()                                     \
+       ({                                                      \
+               unsigned long temp;                             \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ stf\n"                \
+"      bic     %0, %0, #64\n"                                  \
+"      msr     cpsr_c, %0"                                     \
+       : "=r" (temp)                                           \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+
+/*
+ * Disable FIQs
+ */
+#define local_fiq_disable()                                    \
+       ({                                                      \
+               unsigned long temp;                             \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ clf\n"                \
+"      orr     %0, %0, #64\n"                                  \
+"      msr     cpsr_c, %0"                                     \
+       : "=r" (temp)                                           \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+
+#endif
+
+/*
+ * Save the current interrupt enable state.
+ */
+#define raw_local_save_flags(x)                                        \
+       ({                                                      \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_save_flags"     \
+       : "=r" (x) : : "memory", "cc");                         \
+       })
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define raw_local_irq_restore(x)                               \
+       __asm__ __volatile__(                                   \
+       "msr    cpsr_c, %0              @ local_irq_restore\n"  \
+       :                                                       \
+       : "r" (x)                                               \
+       : "memory", "cc")
+
+#define raw_irqs_disabled_flags(flags) \
+({                                     \
+       (int)((flags) & PSR_I_BIT);     \
+})
+
+#endif
+#endif
index 923e0ca66200c1f0a592ff470528d4c524a15583..24621c49a0c73abaa778a9b1d60801c23f409bc8 100644 (file)
@@ -52,13 +52,9 @@ void pci_common_init(struct hw_pci *);
 /*
  * PCI controllers
  */
-extern int iop321_setup(int nr, struct pci_sys_data *);
-extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *);
-extern void iop321_init(void);
-
-extern int iop331_setup(int nr, struct pci_sys_data *);
-extern struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *);
-extern void iop331_init(void);
+extern int iop3xx_pci_setup(int nr, struct pci_sys_data *);
+extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *);
+extern void iop3xx_pci_preinit(void);
 
 extern int dc21285_setup(int nr, struct pci_sys_data *);
 extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *);
index dee0bc336fe8393ae8e13b4079a1a3f3eab6f328..1eb93f5c0d6cf921c6bfc3cf211bf84b654687c6 100644 (file)
@@ -38,7 +38,9 @@ struct sys_timer {
        void                    (*init)(void);
        void                    (*suspend)(void);
        void                    (*resume)(void);
+#ifndef CONFIG_GENERIC_TIME
        unsigned long           (*offset)(void);
+#endif
 
 #ifdef CONFIG_NO_IDLE_HZ
        struct dyn_tick_timer   *dyn_tick;
index 02bd3ee935b07e0c88c2f865aa6c4510d814c4dc..7e85db77d99b12f635514a7c84e9b8c713064af4 100644 (file)
@@ -174,9 +174,6 @@ typedef unsigned long pgprot_t;
 
 #endif /* STRICT_MM_TYPECHECKS */
 
-/* the upper-most page table pointer */
-extern pmd_t *top_pmd;
-
 #endif /* CONFIG_MMU */
 
 #include <asm/memory.h>
index 4d10d319fa34d1c5d4aade4c2eddbeaa5391e31f..ed8cb5963e99cde381f94171b1f59a98aa1805d8 100644 (file)
@@ -135,6 +135,13 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #define FIRST_USER_PGD_NR      1
 #define USER_PTRS_PER_PGD      ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
 
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT          20
+#define SECTION_SIZE           (1UL << SECTION_SHIFT)
+#define SECTION_MASK           (~(SECTION_SIZE-1))
+
 /*
  * ARMv6 supersection address mask and size definitions.
  */
index 1bde92cdaebd01739c3db199a438f47a7ffd0493..ea7e54c319be535ed1777640f0e1740b36c748a5 100644 (file)
 #   define CPU_NAME cpu_arm6
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM7TDMI
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_arm7tdmi
+#  endif
+# endif
 # ifdef CONFIG_CPU_ARM710
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
 #   define CPU_NAME cpu_arm720
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM740T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_arm740
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM9TDMI
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_arm9tdmi
+#  endif
+# endif
 # ifdef CONFIG_CPU_ARM920T
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
 #   define CPU_NAME cpu_arm926
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM940T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_arm940
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM946E
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_arm946
+#  endif
+# endif
 # ifdef CONFIG_CPU_SA110
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
index ea3ed24652333e8dbcc3020074a626050895ed84..aa4b5782f0c9723cf1d604ca7756a09bea8e6829 100644 (file)
@@ -194,13 +194,15 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
 # define NR_BANKS 8
 #endif
 
+struct membank {
+       unsigned long start;
+       unsigned long size;
+       int           node;
+};
+
 struct meminfo {
        int nr_banks;
-       struct {
-               unsigned long start;
-               unsigned long size;
-               int           node;
-       } bank[NR_BANKS];
+       struct membank bank[NR_BANKS];
 };
 
 /*
index 0947cbf9b69a3394bd3cba0803a112ece0c183c1..f05fbe31576cbeabb2b6d717698d7cebfdc63b4e 100644 (file)
@@ -46,6 +46,7 @@
 #define CPUID_TCM      2
 #define CPUID_TLBTYPE  3
 
+#ifdef CONFIG_CPU_CP15
 #define read_cpuid(reg)                                                        \
        ({                                                              \
                unsigned int __val;                                     \
@@ -55,6 +56,9 @@
                    : "cc");                                            \
                __val;                                                  \
        })
+#else
+#define read_cpuid(reg) (processor_id)
+#endif
 
 /*
  * This is used to ensure the compiler did actually allocate the register we
@@ -207,130 +211,7 @@ static inline void sched_cacheflush(void)
 {
 }
 
-/*
- * CPU interrupt mask handling.
- */
-#if __LINUX_ARM_ARCH__ >= 6
-
-#define local_irq_save(x)                                      \
-       ({                                                      \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ local_irq_save\n"     \
-       "cpsid  i"                                              \
-       : "=r" (x) : : "memory", "cc");                         \
-       })
-
-#define local_irq_enable()  __asm__("cpsie i   @ __sti" : : : "memory", "cc")
-#define local_irq_disable() __asm__("cpsid i   @ __cli" : : : "memory", "cc")
-#define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory", "cc")
-#define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory", "cc")
-
-#else
-
-/*
- * Save the current interrupt enable state & disable IRQs
- */
-#define local_irq_save(x)                                      \
-       ({                                                      \
-               unsigned long temp;                             \
-               (void) (&temp == &x);                           \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ local_irq_save\n"     \
-"      orr     %1, %0, #128\n"                                 \
-"      msr     cpsr_c, %1"                                     \
-       : "=r" (x), "=r" (temp)                                 \
-       :                                                       \
-       : "memory", "cc");                                      \
-       })
-       
-/*
- * Enable IRQs
- */
-#define local_irq_enable()                                     \
-       ({                                                      \
-               unsigned long temp;                             \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ local_irq_enable\n"   \
-"      bic     %0, %0, #128\n"                                 \
-"      msr     cpsr_c, %0"                                     \
-       : "=r" (temp)                                           \
-       :                                                       \
-       : "memory", "cc");                                      \
-       })
-
-/*
- * Disable IRQs
- */
-#define local_irq_disable()                                    \
-       ({                                                      \
-               unsigned long temp;                             \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ local_irq_disable\n"  \
-"      orr     %0, %0, #128\n"                                 \
-"      msr     cpsr_c, %0"                                     \
-       : "=r" (temp)                                           \
-       :                                                       \
-       : "memory", "cc");                                      \
-       })
-
-/*
- * Enable FIQs
- */
-#define local_fiq_enable()                                     \
-       ({                                                      \
-               unsigned long temp;                             \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ stf\n"                \
-"      bic     %0, %0, #64\n"                                  \
-"      msr     cpsr_c, %0"                                     \
-       : "=r" (temp)                                           \
-       :                                                       \
-       : "memory", "cc");                                      \
-       })
-
-/*
- * Disable FIQs
- */
-#define local_fiq_disable()                                    \
-       ({                                                      \
-               unsigned long temp;                             \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ clf\n"                \
-"      orr     %0, %0, #64\n"                                  \
-"      msr     cpsr_c, %0"                                     \
-       : "=r" (temp)                                           \
-       :                                                       \
-       : "memory", "cc");                                      \
-       })
-
-#endif
-
-/*
- * Save the current interrupt enable state.
- */
-#define local_save_flags(x)                                    \
-       ({                                                      \
-       __asm__ __volatile__(                                   \
-       "mrs    %0, cpsr                @ local_save_flags"     \
-       : "=r" (x) : : "memory", "cc");                         \
-       })
-
-/*
- * restore saved IRQ & FIQ state
- */
-#define local_irq_restore(x)                                   \
-       __asm__ __volatile__(                                   \
-       "msr    cpsr_c, %0              @ local_irq_restore\n"  \
-       :                                                       \
-       : "r" (x)                                               \
-       : "memory", "cc")
-
-#define irqs_disabled()                        \
-({                                     \
-       unsigned long flags;            \
-       local_save_flags(flags);        \
-       (int)(flags & PSR_I_BIT);       \
-})
+#include <linux/irqflags.h>
 
 #ifdef CONFIG_SMP
 
@@ -405,17 +286,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
 #error SMP is not supported on this platform
 #endif
        case 1:
-               local_irq_save(flags);
+               raw_local_irq_save(flags);
                ret = *(volatile unsigned char *)ptr;
                *(volatile unsigned char *)ptr = x;
-               local_irq_restore(flags);
+               raw_local_irq_restore(flags);
                break;
 
        case 4:
-               local_irq_save(flags);
+               raw_local_irq_save(flags);
                ret = *(volatile unsigned long *)ptr;
                *(volatile unsigned long *)ptr = x;
-               local_irq_restore(flags);
+               raw_local_irq_restore(flags);
                break;
 #else
        case 1:
diff --git a/include/asm-arm/timeofday.h b/include/asm-arm/timeofday.h
new file mode 100644 (file)
index 0000000..27254bd
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef _ASM_ARM_TIMEOFDAY_H
+#define _ASM_ARM_TIMEOFDAY_H
+#include <asm-generic/timeofday.h>
+#endif
index d97fc76189a5e5c95570424a19e0e0f5790a8fea..cd10a0b5f8ae77510234c15c9295f80944f59f4a 100644 (file)
@@ -247,16 +247,16 @@ static inline void local_flush_tlb_all(void)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V3_FULL))
-               asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
-               asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
-               asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
-               asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -266,25 +266,25 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_FULL))
-                       asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_U_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_D_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_I_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
        }
 
        if (tlb_flag(TLB_V6_U_ASID))
-               asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
        if (tlb_flag(TLB_V6_D_ASID))
-               asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
        if (tlb_flag(TLB_V6_I_ASID))
-               asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
 }
 
 static inline void
@@ -296,27 +296,27 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
        uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero));
 
        if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_PAGE))
-                       asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_U_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_D_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_I_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
                if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
        }
 
        if (tlb_flag(TLB_V6_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
        if (tlb_flag(TLB_V6_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
        if (tlb_flag(TLB_V6_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -327,31 +327,31 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        kaddr &= PAGE_MASK;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V3_PAGE))
-               asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
        if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
-               asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V6_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V6_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V6_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
 
        /* The ARM ARM states that the completion of a TLB maintenance
         * operation is only guaranteed by a DSB instruction
         */
        if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 }
 
 /*
@@ -373,11 +373,11 @@ static inline void flush_pmd_entry(pmd_t *pmd)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_DCLEAN))
-               asm("mcr%?      p15, 0, %0, c7, c10, 1  @ flush_pmd"
-                       : : "r" (pmd));
+               asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
+                       : : "r" (pmd) : "cc");
        if (tlb_flag(TLB_WB))
-               asm("mcr%?      p15, 0, %0, c7, c10, 4  @ flush_pmd"
-                       : : "r" (zero));
+               asm("mcr        p15, 0, %0, c7, c10, 4  @ flush_pmd"
+                       : : "r" (zero) : "cc");
 }
 
 static inline void clean_pmd_entry(pmd_t *pmd)
@@ -385,8 +385,8 @@ static inline void clean_pmd_entry(pmd_t *pmd)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_DCLEAN))
-               asm("mcr%?      p15, 0, %0, c7, c10, 1  @ flush_pmd"
-                       : : "r" (pmd));
+               asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
+                       : : "r" (pmd) : "cc");
 }
 
 #undef tlb_flag
index 1b39c2f322c9a5b332352512a6ff81ffe0f25a5e..795b9e5b9e6ab88e07641189eaba1c3110a7cba4 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <asm/types.h>
 
-extern int __bug_unaligned_x(void *ptr);
+extern int __bug_unaligned_x(const void *ptr);
 
 /*
  * What is the most efficient way of loading/storing an unaligned value?
@@ -51,44 +51,32 @@ extern int __bug_unaligned_x(void *ptr);
 #define __get_unaligned_4_be(__p)                                      \
        (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
 
-#define __get_unaligned_le(ptr)                                        \
-       ({                                                      \
-               __typeof__(*(ptr)) __v;                         \
-               __u8 *__p = (__u8 *)(ptr);                      \
-               switch (sizeof(*(ptr))) {                       \
-               case 1: __v = *(ptr);                   break;  \
-               case 2: __v = __get_unaligned_2_le(__p);        break;  \
-               case 4: __v = __get_unaligned_4_le(__p);        break;  \
-               case 8: {                                       \
-                               unsigned int __v1, __v2;        \
-                               __v2 = __get_unaligned_4_le((__p+4)); \
-                               __v1 = __get_unaligned_4_le(__p);       \
-                               __v = ((unsigned long long)__v2 << 32 | __v1);  \
-                       }                                       \
-                       break;                                  \
-               default: __v = __bug_unaligned_x(__p);  break;  \
-               }                                               \
-               __v;                                            \
+#define __get_unaligned_8_le(__p)                                      \
+       ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 |      \
+               __get_unaligned_4_le(__p))
+
+#define __get_unaligned_8_be(__p)                                      \
+       ((unsigned long long)__get_unaligned_4_be(__p) << 32 |          \
+               __get_unaligned_4_be((__p+4)))
+
+#define __get_unaligned_le(ptr)                                                \
+       ({                                                              \
+               const __u8 *__p = (const __u8 *)(ptr);                  \
+               __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p,        \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p), \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p), \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p), \
+                   (void)__bug_unaligned_x(__p)))));                   \
        })
 
-#define __get_unaligned_be(ptr)                                        \
-       ({                                                      \
-               __typeof__(*(ptr)) __v;                         \
-               __u8 *__p = (__u8 *)(ptr);                      \
-               switch (sizeof(*(ptr))) {                       \
-               case 1: __v = *(ptr);                   break;  \
-               case 2: __v = __get_unaligned_2_be(__p);        break;  \
-               case 4: __v = __get_unaligned_4_be(__p);        break;  \
-               case 8: {                                       \
-                               unsigned int __v1, __v2;        \
-                               __v2 = __get_unaligned_4_be(__p); \
-                               __v1 = __get_unaligned_4_be((__p+4));   \
-                               __v = ((unsigned long long)__v2 << 32 | __v1);  \
-                       }                                       \
-                       break;                                  \
-               default: __v = __bug_unaligned_x(__p);  break;  \
-               }                                               \
-               __v;                                            \
+#define __get_unaligned_be(ptr)                                                \
+       ({                                                              \
+               const __u8 *__p = (const __u8 *)(ptr);                  \
+               __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p,        \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p), \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p), \
+                 __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p), \
+                   (void)__bug_unaligned_x(__p)))));                   \
        })
 
 
index 8ceab7bcd8b4f229f45536f8208e5394c99e9695..a5250895155ef6e5affcae708a4a79f692f037e2 100644 (file)
 #endif
 
 #ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) do { \
-       if (unlikely((condition)!=0)) { \
-               printk("BUG: warning at %s:%d/%s()\n", __FILE__, __LINE__, __FUNCTION__); \
-               dump_stack(); \
-       } \
-} while (0)
+#define WARN_ON(condition) ({                                          \
+       typeof(condition) __ret_warn_on = (condition);                  \
+       if (unlikely(__ret_warn_on)) {                                  \
+               printk("BUG: warning at %s:%d/%s()\n", __FILE__,        \
+                       __LINE__, __FUNCTION__);                        \
+               dump_stack();                                           \
+       }                                                               \
+       unlikely(__ret_warn_on);                                        \
+})
 #endif
 
 #else /* !CONFIG_BUG */
 #endif
 
 #ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) do { if (condition) ; } while(0)
+#define WARN_ON(condition) unlikely((condition))
 #endif
 #endif
 
-#define WARN_ON_ONCE(condition)                                \
-({                                                     \
+#define WARN_ON_ONCE(condition)        ({                      \
        static int __warn_once = 1;                     \
-       int __ret = 0;                                  \
+       typeof(condition) __ret_warn_once = (condition);\
                                                        \
-       if (unlikely((condition) && __warn_once)) {     \
-               __warn_once = 0;                        \
-               WARN_ON(1);                             \
-               __ret = 1;                              \
-       }                                               \
-       __ret;                                          \
+       if (likely(__warn_once))                        \
+               if (WARN_ON(__ret_warn_once))           \
+                       __warn_once = 0;                \
+       unlikely(__ret_warn_once);                      \
 })
 
 #ifdef CONFIG_SMP
index 576ae01d71c81d98d91357c55a56ddbeee1499e6..81999a3ebe7c4c712ac91da21fc963e24c638270 100644 (file)
@@ -21,7 +21,7 @@ static inline dma_addr_t
 dma_map_single(struct device *dev, void *ptr, size_t size,
               enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
        WARN_ON(size == 0);
        flush_write_buffers();
        return virt_to_phys(ptr);
@@ -31,7 +31,7 @@ static inline void
 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                 enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
 }
 
 static inline int
@@ -40,7 +40,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 {
        int i;
 
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
        WARN_ON(nents == 0 || sg[0].length == 0);
 
        for (i = 0; i < nents; i++ ) {
@@ -57,7 +57,7 @@ static inline dma_addr_t
 dma_map_page(struct device *dev, struct page *page, unsigned long offset,
             size_t size, enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
        return page_to_phys(page) + offset;
 }
 
@@ -65,7 +65,7 @@ static inline void
 dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
               enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
 }
 
 
@@ -73,7 +73,7 @@ static inline void
 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
             enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
+       BUG_ON(!valid_dma_direction(direction));
 }
 
 static inline void
index 6312c3e798147d508c1c695c175559dd96dc8daf..4182c347ef85052178ee67b193d3c5750c14aa58 100644 (file)
@@ -16,7 +16,7 @@
 
 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
 {
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode_vm(regs));
 #endif
index a81b0596159508618a3e2b2bfc11ea5b9d62fe47..254a0fe01c6a3f46b5983afc9336b11a61a3d81d 100644 (file)
@@ -88,7 +88,7 @@ static inline void clustered_apic_check(void)
 
 static inline int apicid_to_node(int logical_apicid)
 {
-       return logical_apicid >> 5;          /* 2 clusterids per CEC */
+       return apicid_2_node[logical_apicid];
 }
 
 /* Mapping from cpu number to logical apicid */
index 95568e6ca91cf3cff150c743ff9f0f87a070a4d9..8db618c5a72b0e50ec0502e7b0d6b8baadec456c 100644 (file)
@@ -9,7 +9,7 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
        /* Clear the interrupt */
        co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
 
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode_vm(regs));
 #endif
index eaf518098981cc843e564d3ec1b650f17442256e..099fe9f5c1b2bcc922079c7fa64b21b197d864b7 100644 (file)
@@ -3,7 +3,7 @@
 
 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
 {
-       do_timer(regs);
+       do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode_vm(regs));
 #endif
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 32ac8c91d5c5ccb2e8856ee2a6943d59609d090e..915c26a31b79a6f0a855ae06920810761978abe8 100644 (file)
@@ -46,6 +46,8 @@ extern u8 x86_cpu_to_apicid[];
 
 #define cpu_physical_id(cpu)   x86_cpu_to_apicid[cpu]
 
+extern u8 apicid_2_node[];
+
 #ifdef CONFIG_HOTPLUG_CPU
 extern void cpu_exit_clear(void);
 extern void cpu_uninit(void);
index f44b529e329821a91a2fedf715ac83b55f6f3085..978b2c7e84eaf25f9d32a7ffb06c8744ed65fdf4 100644 (file)
@@ -70,9 +70,10 @@ struct bug_entry *find_bug(unsigned long bugaddr);
                    "i" (__FILE__), "i" (__FUNCTION__));        \
 } while (0)
 
-#define WARN_ON(x) do {                                                \
-       if (__builtin_constant_p(x)) {                          \
-               if (x)                                          \
+#define WARN_ON(x) ({                                          \
+       typeof(x) __ret_warn_on = (x);                          \
+       if (__builtin_constant_p(__ret_warn_on)) {              \
+               if (__ret_warn_on)                              \
                        __WARN();                               \
        } else {                                                \
                __asm__ __volatile__(                           \
@@ -80,11 +81,12 @@ struct bug_entry *find_bug(unsigned long bugaddr);
                ".section __bug_table,\"a\"\n"                  \
                "\t"PPC_LONG"   1b,%1,%2,%3\n"                  \
                ".previous"                                     \
-               : : "r" ((long)(x)),                            \
+               : : "r" (__ret_warn_on),                        \
                    "i" (__LINE__ + BUG_WARNING_TRAP),          \
                    "i" (__FILE__), "i" (__FUNCTION__));        \
        }                                                       \
-} while (0)
+       unlikely(__ret_warn_on);                                \
+})
 
 #define HAVE_ARCH_BUG
 #define HAVE_ARCH_BUG_ON
index b1770703b7060baf948721d41ebec79a84a311ca..79283dac8281453419dde45f78a28f4732553469 100644 (file)
@@ -80,7 +80,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
        parm_list.product_id_addr = (unsigned long) id;
        parm_list.buffer_addr = virt_to_phys(buffer);
        asm volatile(
-               "diag %1,%0,0xdc"
+               "       diag    %1,%0,0xdc"
                : "=d" (ry)
                : "d" (&parm_list), "m" (parm_list), "m" (*id)
                : "cc");
index 399bf02894dd10cf5fc320557484eb0fcb27f7cd..af20c7462485f06de1dfb888e6f48769f0e64e9e 100644 (file)
@@ -30,20 +30,43 @@ typedef struct {
 
 #ifdef __KERNEL__
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
 #define __CS_LOOP(ptr, op_val, op_string) ({                           \
        typeof(ptr->counter) old_val, new_val;                          \
-        __asm__ __volatile__("   l     %0,0(%3)\n"                     \
-                             "0: lr    %1,%0\n"                                \
-                             op_string "  %1,%4\n"                     \
-                             "   cs    %0,%1,0(%3)\n"                  \
-                             "   jl    0b"                             \
-                             : "=&d" (old_val), "=&d" (new_val),       \
-                              "=m" (((atomic_t *)(ptr))->counter)      \
-                            : "a" (ptr), "d" (op_val),                 \
-                              "m" (((atomic_t *)(ptr))->counter)       \
-                            : "cc", "memory" );                        \
+       asm volatile(                                                   \
+               "       l       %0,%2\n"                                \
+               "0:     lr      %1,%0\n"                                \
+               op_string "     %1,%3\n"                                \
+               "       cs      %0,%1,%2\n"                             \
+               "       jl      0b"                                     \
+               : "=&d" (old_val), "=&d" (new_val),                     \
+                 "=Q" (((atomic_t *)(ptr))->counter)                   \
+               : "d" (op_val),  "Q" (((atomic_t *)(ptr))->counter)     \
+               : "cc", "memory");                                      \
        new_val;                                                        \
 })
+
+#else /* __GNUC__ */
+
+#define __CS_LOOP(ptr, op_val, op_string) ({                           \
+       typeof(ptr->counter) old_val, new_val;                          \
+       asm volatile(                                                   \
+               "       l       %0,0(%3)\n"                             \
+               "0:     lr      %1,%0\n"                                \
+               op_string "     %1,%4\n"                                \
+               "       cs      %0,%1,0(%3)\n"                          \
+               "       jl      0b"                                     \
+               : "=&d" (old_val), "=&d" (new_val),                     \
+                 "=m" (((atomic_t *)(ptr))->counter)                   \
+               : "a" (ptr), "d" (op_val),                              \
+                 "m" (((atomic_t *)(ptr))->counter)                    \
+               : "cc", "memory");                                      \
+       new_val;                                                        \
+})
+
+#endif /* __GNUC__ */
+
 #define atomic_read(v)          ((v)->counter)
 #define atomic_set(v,i)         (((v)->counter) = (i))
 
@@ -81,10 +104,19 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v)
 
 static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
-       __asm__ __volatile__("  cs   %0,%3,0(%2)\n"
-                            : "+d" (old), "=m" (v->counter)
-                            : "a" (v), "d" (new), "m" (v->counter)
-                            : "cc", "memory" );
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+       asm volatile(
+               "       cs      %0,%2,%1"
+               : "+d" (old), "=Q" (v->counter)
+               : "d" (new), "Q" (v->counter)
+               : "cc", "memory");
+#else /* __GNUC__ */
+       asm volatile(
+               "       cs      %0,%3,0(%2)"
+               : "+d" (old), "=m" (v->counter)
+               : "a" (v), "d" (new), "m" (v->counter)
+               : "cc", "memory");
+#endif /* __GNUC__ */
        return old;
 }
 
@@ -113,20 +145,43 @@ typedef struct {
 } __attribute__ ((aligned (8))) atomic64_t;
 #define ATOMIC64_INIT(i)  { (i) }
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
 #define __CSG_LOOP(ptr, op_val, op_string) ({                          \
        typeof(ptr->counter) old_val, new_val;                          \
-        __asm__ __volatile__("   lg    %0,0(%3)\n"                     \
-                             "0: lgr   %1,%0\n"                                \
-                             op_string "  %1,%4\n"                     \
-                             "   csg   %0,%1,0(%3)\n"                  \
-                             "   jl    0b"                             \
-                             : "=&d" (old_val), "=&d" (new_val),       \
-                              "=m" (((atomic_t *)(ptr))->counter)      \
-                            : "a" (ptr), "d" (op_val),                 \
-                              "m" (((atomic_t *)(ptr))->counter)       \
-                            : "cc", "memory" );                        \
+       asm volatile(                                                   \
+               "       lg      %0,%2\n"                                \
+               "0:     lgr     %1,%0\n"                                \
+               op_string "     %1,%3\n"                                \
+               "       csg     %0,%1,%2\n"                             \
+               "       jl      0b"                                     \
+               : "=&d" (old_val), "=&d" (new_val),                     \
+                 "=Q" (((atomic_t *)(ptr))->counter)                   \
+               : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter)      \
+               : "cc", "memory" );                                     \
        new_val;                                                        \
 })
+
+#else /* __GNUC__ */
+
+#define __CSG_LOOP(ptr, op_val, op_string) ({                          \
+       typeof(ptr->counter) old_val, new_val;                          \
+       asm volatile(                                                   \
+               "       lg      %0,0(%3)\n"                             \
+               "0:     lgr     %1,%0\n"                                \
+               op_string "     %1,%4\n"                                \
+               "       csg     %0,%1,0(%3)\n"                          \
+               "       jl      0b"                                     \
+               : "=&d" (old_val), "=&d" (new_val),                     \
+                 "=m" (((atomic_t *)(ptr))->counter)                   \
+               : "a" (ptr), "d" (op_val),                              \
+                 "m" (((atomic_t *)(ptr))->counter)                    \
+               : "cc", "memory" );                                     \
+       new_val;                                                        \
+})
+
+#endif /* __GNUC__ */
+
 #define atomic64_read(v)          ((v)->counter)
 #define atomic64_set(v,i)         (((v)->counter) = (i))
 
@@ -163,10 +218,19 @@ static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
 static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
                                             long long old, long long new)
 {
-       __asm__ __volatile__("  csg  %0,%3,0(%2)\n"
-                            : "+d" (old), "=m" (v->counter)
-                            : "a" (v), "d" (new), "m" (v->counter)
-                            : "cc", "memory" );
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+       asm volatile(
+               "       csg     %0,%2,%1"
+               : "+d" (old), "=Q" (v->counter)
+               : "d" (new), "Q" (v->counter)
+               : "cc", "memory");
+#else /* __GNUC__ */
+       asm volatile(
+               "       csg     %0,%3,0(%2)"
+               : "+d" (old), "=m" (v->counter)
+               : "a" (v), "d" (new), "m" (v->counter)
+               : "cc", "memory");
+#endif /* __GNUC__ */
        return old;
 }
 
index 0ddcdba79e4a91b6b04b140810994f31bd5636a8..f79c9b792af1d88d0d54ed7f5762bc232c96b51d 100644 (file)
@@ -67,16 +67,35 @@ extern const char _sb_findmap[];
 #define __BITOPS_AND           "nr"
 #define __BITOPS_XOR           "xr"
 
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)                \
-       __asm__ __volatile__("   l   %0,0(%4)\n"                        \
-                            "0: lr  %1,%0\n"                           \
-                            __op_string "  %1,%3\n"                    \
-                            "   cs  %0,%1,0(%4)\n"                     \
-                            "   jl  0b"                                \
-                            : "=&d" (__old), "=&d" (__new),            \
-                              "=m" (*(unsigned long *) __addr)         \
-                            : "d" (__val), "a" (__addr),               \
-                              "m" (*(unsigned long *) __addr) : "cc" );
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+       asm volatile(                                           \
+               "       l       %0,%2\n"                        \
+               "0:     lr      %1,%0\n"                        \
+               __op_string "   %1,%3\n"                        \
+               "       cs      %0,%1,%2\n"                     \
+               "       jl      0b"                             \
+               : "=&d" (__old), "=&d" (__new),                 \
+                 "=Q" (*(unsigned long *) __addr)              \
+               : "d" (__val), "Q" (*(unsigned long *) __addr)  \
+               : "cc");
+
+#else /* __GNUC__ */
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+       asm volatile(                                           \
+               "       l       %0,0(%4)\n"                     \
+               "0:     lr      %1,%0\n"                        \
+               __op_string "   %1,%3\n"                        \
+               "       cs      %0,%1,0(%4)\n"                  \
+               "       jl      0b"                             \
+               : "=&d" (__old), "=&d" (__new),                 \
+                 "=m" (*(unsigned long *) __addr)              \
+               : "d" (__val), "a" (__addr),                    \
+                 "m" (*(unsigned long *) __addr) : "cc");
+
+#endif /* __GNUC__ */
 
 #else /* __s390x__ */
 
@@ -86,21 +105,41 @@ extern const char _sb_findmap[];
 #define __BITOPS_AND           "ngr"
 #define __BITOPS_XOR           "xgr"
 
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)                \
-       __asm__ __volatile__("   lg  %0,0(%4)\n"                        \
-                            "0: lgr %1,%0\n"                           \
-                            __op_string "  %1,%3\n"                    \
-                            "   csg %0,%1,0(%4)\n"                     \
-                            "   jl  0b"                                \
-                            : "=&d" (__old), "=&d" (__new),            \
-                              "=m" (*(unsigned long *) __addr)         \
-                            : "d" (__val), "a" (__addr),               \
-                              "m" (*(unsigned long *) __addr) : "cc" );
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+       asm volatile(                                           \
+               "       lg      %0,%2\n"                        \
+               "0:     lgr     %1,%0\n"                        \
+               __op_string "   %1,%3\n"                        \
+               "       csg     %0,%1,%2\n"                     \
+               "       jl      0b"                             \
+               : "=&d" (__old), "=&d" (__new),                 \
+                 "=Q" (*(unsigned long *) __addr)              \
+               : "d" (__val), "Q" (*(unsigned long *) __addr)  \
+               : "cc");
+
+#else /* __GNUC__ */
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)        \
+       asm volatile(                                           \
+               "       lg      %0,0(%4)\n"                     \
+               "0:     lgr     %1,%0\n"                        \
+               __op_string "   %1,%3\n"                        \
+               "       csg     %0,%1,0(%4)\n"                  \
+               "       jl      0b"                             \
+               : "=&d" (__old), "=&d" (__new),                 \
+                 "=m" (*(unsigned long *) __addr)              \
+               : "d" (__val), "a" (__addr),                    \
+                 "m" (*(unsigned long *) __addr) : "cc");
+
+
+#endif /* __GNUC__ */
 
 #endif /* __s390x__ */
 
 #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
-#define __BITOPS_BARRIER() __asm__ __volatile__ ( "" : : : "memory" )
+#define __BITOPS_BARRIER() asm volatile("" : : : "memory")
 
 #ifdef CONFIG_SMP
 /*
@@ -217,10 +256,10 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-        asm volatile("oc 0(1,%1),0(%2)"
-                    : "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc" );
+       asm volatile(
+               "       oc      0(1,%1),0(%2)"
+               : "=m" (*(char *) addr) : "a" (addr),
+                 "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
 }
 
 static inline void 
@@ -229,40 +268,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-       switch (nr&7) {
-       case 0:
-               asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 1:
-               asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 2:
-               asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 3:
-               asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 4:
-               asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 5:
-               asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 6:
-               asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 7:
-               asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       }
+       *(unsigned char *) addr |= 1 << (nr & 7);
 }
 
 #define set_bit_simple(nr,addr) \
@@ -279,10 +285,10 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-        asm volatile("nc 0(1,%1),0(%2)"
-                    : "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_ni_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc" );
+       asm volatile(
+               "       nc      0(1,%1),0(%2)"
+               : "=m" (*(char *) addr) : "a" (addr),
+                 "a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc");
 }
 
 static inline void 
@@ -291,40 +297,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-       switch (nr&7) {
-       case 0:
-               asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 1:
-               asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 2:
-               asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 3:
-               asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 4:
-               asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 5:
-               asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 6:
-               asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 7:
-               asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       }
+       *(unsigned char *) addr &= ~(1 << (nr & 7));
 }
 
 #define clear_bit_simple(nr,addr) \
@@ -340,10 +313,10 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-        asm volatile("xc 0(1,%1),0(%2)"
-                    :  "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc" );
+       asm volatile(
+               "       xc      0(1,%1),0(%2)"
+               :  "=m" (*(char *) addr) : "a" (addr),
+                  "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
 }
 
 static inline void 
@@ -352,40 +325,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr)
        unsigned long addr;
 
        addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
-       switch (nr&7) {
-       case 0:
-               asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 1:
-               asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 2:
-               asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 3:
-               asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 4:
-               asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 5:
-               asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 6:
-               asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       case 7:
-               asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr)
-                             : "a" (addr), "m" (*(char *) addr) : "cc" );
-               break;
-       }
+       *(unsigned char *) addr ^= 1 << (nr & 7);
 }
 
 #define change_bit_simple(nr,addr) \
@@ -404,10 +344,11 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
        ch = *(unsigned char *) addr;
-        asm volatile("oc 0(1,%1),0(%2)"
-                    : "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc", "memory" );
+       asm volatile(
+               "       oc      0(1,%1),0(%2)"
+               : "=m" (*(char *) addr)
+               : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+                 "m" (*(char *) addr) : "cc", "memory");
        return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_set_bit(X,Y)                test_and_set_bit_simple(X,Y)
@@ -423,10 +364,11 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
        ch = *(unsigned char *) addr;
-        asm volatile("nc 0(1,%1),0(%2)"
-                    : "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_ni_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc", "memory" );
+       asm volatile(
+               "       nc      0(1,%1),0(%2)"
+               : "=m" (*(char *) addr)
+               : "a" (addr), "a" (_ni_bitmap + (nr & 7)),
+                 "m" (*(char *) addr) : "cc", "memory");
        return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_clear_bit(X,Y)      test_and_clear_bit_simple(X,Y)
@@ -442,10 +384,11 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 
        addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
        ch = *(unsigned char *) addr;
-        asm volatile("xc 0(1,%1),0(%2)"
-                    : "=m" (*(char *) addr)
-                    : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-                      "m" (*(char *) addr) : "cc", "memory" );
+       asm volatile(
+               "       xc      0(1,%1),0(%2)"
+               : "=m" (*(char *) addr)
+               : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+                 "m" (*(char *) addr) : "cc", "memory");
        return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_change_bit(X,Y)     test_and_change_bit_simple(X,Y)
@@ -557,35 +500,36 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size)
 
         if (!size)
                 return 0;
-        __asm__("   lhi  %1,-1\n"
-                "   lr   %2,%3\n"
-                "   slr  %0,%0\n"
-                "   ahi  %2,31\n"
-                "   srl  %2,5\n"
-                "0: c    %1,0(%0,%4)\n"
-                "   jne  1f\n"
-                "   la   %0,4(%0)\n"
-                "   brct %2,0b\n"
-                "   lr   %0,%3\n"
-                "   j    4f\n"
-                "1: l    %2,0(%0,%4)\n"
-                "   sll  %0,3\n"
-                "   lhi  %1,0xff\n"
-                "   tml  %2,0xffff\n"
-                "   jno  2f\n"
-                "   ahi  %0,16\n"
-                "   srl  %2,16\n"
-                "2: tml  %2,0x00ff\n"
-                "   jno  3f\n"
-                "   ahi  %0,8\n"
-                "   srl  %2,8\n"
-                "3: nr   %2,%1\n"
-                "   ic   %2,0(%2,%5)\n"
-                "   alr  %0,%2\n"
-                "4:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
-                : "a" (size), "a" (addr), "a" (&_zb_findmap),
-                 "m" (*(addrtype *) addr) : "cc" );
+       asm volatile(
+               "       lhi     %1,-1\n"
+               "       lr      %2,%3\n"
+               "       slr     %0,%0\n"
+               "       ahi     %2,31\n"
+               "       srl     %2,5\n"
+               "0:     c       %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       la      %0,4(%0)\n"
+               "       brct    %2,0b\n"
+               "       lr      %0,%3\n"
+               "       j       4f\n"
+               "1:     l       %2,0(%0,%4)\n"
+               "       sll     %0,3\n"
+               "       lhi     %1,0xff\n"
+               "       tml     %2,0xffff\n"
+               "       jno     2f\n"
+               "       ahi     %0,16\n"
+               "       srl     %2,16\n"
+               "2:     tml     %2,0x00ff\n"
+               "       jno     3f\n"
+               "       ahi     %0,8\n"
+               "       srl     %2,8\n"
+               "3:     nr      %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       alr     %0,%2\n"
+               "4:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
+               : "a" (size), "a" (addr), "a" (&_zb_findmap),
+                 "m" (*(addrtype *) addr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -598,35 +542,36 @@ find_first_bit(const unsigned long * addr, unsigned long size)
 
         if (!size)
                 return 0;
-        __asm__("   slr  %1,%1\n"
-                "   lr   %2,%3\n"
-                "   slr  %0,%0\n"
-                "   ahi  %2,31\n"
-                "   srl  %2,5\n"
-                "0: c    %1,0(%0,%4)\n"
-                "   jne  1f\n"
-                "   la   %0,4(%0)\n"
-                "   brct %2,0b\n"
-                "   lr   %0,%3\n"
-                "   j    4f\n"
-                "1: l    %2,0(%0,%4)\n"
-                "   sll  %0,3\n"
-                "   lhi  %1,0xff\n"
-                "   tml  %2,0xffff\n"
-                "   jnz  2f\n"
-                "   ahi  %0,16\n"
-                "   srl  %2,16\n"
-                "2: tml  %2,0x00ff\n"
-                "   jnz  3f\n"
-                "   ahi  %0,8\n"
-                "   srl  %2,8\n"
-                "3: nr   %2,%1\n"
-                "   ic   %2,0(%2,%5)\n"
-                "   alr  %0,%2\n"
-                "4:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
-                : "a" (size), "a" (addr), "a" (&_sb_findmap),
-                 "m" (*(addrtype *) addr) : "cc" );
+       asm volatile(
+               "       slr     %1,%1\n"
+               "       lr      %2,%3\n"
+               "       slr     %0,%0\n"
+               "       ahi     %2,31\n"
+               "       srl     %2,5\n"
+               "0:     c       %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       la      %0,4(%0)\n"
+               "       brct    %2,0b\n"
+               "       lr      %0,%3\n"
+               "       j       4f\n"
+               "1:     l       %2,0(%0,%4)\n"
+               "       sll     %0,3\n"
+               "       lhi     %1,0xff\n"
+               "       tml     %2,0xffff\n"
+               "       jnz     2f\n"
+               "       ahi     %0,16\n"
+               "       srl     %2,16\n"
+               "2:     tml     %2,0x00ff\n"
+               "       jnz     3f\n"
+               "       ahi     %0,8\n"
+               "       srl     %2,8\n"
+               "3:     nr      %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       alr     %0,%2\n"
+               "4:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
+               : "a" (size), "a" (addr), "a" (&_sb_findmap),
+                 "m" (*(addrtype *) addr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -640,39 +585,40 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size)
 
         if (!size)
                 return 0;
-        __asm__("   lghi  %1,-1\n"
-                "   lgr   %2,%3\n"
-                "   slgr  %0,%0\n"
-                "   aghi  %2,63\n"
-                "   srlg  %2,%2,6\n"
-                "0: cg    %1,0(%0,%4)\n"
-                "   jne   1f\n"
-                "   la    %0,8(%0)\n"
-                "   brct  %2,0b\n"
-                "   lgr   %0,%3\n"
-                "   j     5f\n"
-                "1: lg    %2,0(%0,%4)\n"
-                "   sllg  %0,%0,3\n"
-                "   clr   %2,%1\n"
-               "   jne   2f\n"
-               "   aghi  %0,32\n"
-                "   srlg  %2,%2,32\n"
-               "2: lghi  %1,0xff\n"
-                "   tmll  %2,0xffff\n"
-                "   jno   3f\n"
-                "   aghi  %0,16\n"
-                "   srl   %2,16\n"
-                "3: tmll  %2,0x00ff\n"
-                "   jno   4f\n"
-                "   aghi  %0,8\n"
-                "   srl   %2,8\n"
-                "4: ngr   %2,%1\n"
-                "   ic    %2,0(%2,%5)\n"
-                "   algr  %0,%2\n"
-                "5:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+       asm volatile(
+               "       lghi    %1,-1\n"
+               "       lgr     %2,%3\n"
+               "       slgr    %0,%0\n"
+               "       aghi    %2,63\n"
+               "       srlg    %2,%2,6\n"
+               "0:     cg      %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       la      %0,8(%0)\n"
+               "       brct    %2,0b\n"
+               "       lgr     %0,%3\n"
+               "       j       5f\n"
+               "1:     lg      %2,0(%0,%4)\n"
+               "       sllg    %0,%0,3\n"
+               "       clr     %2,%1\n"
+               "       jne     2f\n"
+               "       aghi    %0,32\n"
+               "       srlg    %2,%2,32\n"
+               "2:     lghi    %1,0xff\n"
+               "       tmll    %2,0xffff\n"
+               "       jno     3f\n"
+               "       aghi    %0,16\n"
+               "       srl     %2,16\n"
+               "3:     tmll    %2,0x00ff\n"
+               "       jno     4f\n"
+               "       aghi    %0,8\n"
+               "       srl     %2,8\n"
+               "4:     ngr     %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       algr    %0,%2\n"
+               "5:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
                : "a" (size), "a" (addr), "a" (&_zb_findmap),
-                 "m" (*(addrtype *) addr) : "cc" );
+                 "m" (*(addrtype *) addr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -684,39 +630,40 @@ find_first_bit(const unsigned long * addr, unsigned long size)
 
         if (!size)
                 return 0;
-        __asm__("   slgr  %1,%1\n"
-                "   lgr   %2,%3\n"
-                "   slgr  %0,%0\n"
-                "   aghi  %2,63\n"
-                "   srlg  %2,%2,6\n"
-                "0: cg    %1,0(%0,%4)\n"
-                "   jne   1f\n"
-                "   aghi  %0,8\n"
-                "   brct  %2,0b\n"
-                "   lgr   %0,%3\n"
-                "   j     5f\n"
-                "1: lg    %2,0(%0,%4)\n"
-                "   sllg  %0,%0,3\n"
-                "   clr   %2,%1\n"
-               "   jne   2f\n"
-               "   aghi  %0,32\n"
-                "   srlg  %2,%2,32\n"
-               "2: lghi  %1,0xff\n"
-                "   tmll  %2,0xffff\n"
-                "   jnz   3f\n"
-                "   aghi  %0,16\n"
-                "   srl   %2,16\n"
-                "3: tmll  %2,0x00ff\n"
-                "   jnz   4f\n"
-                "   aghi  %0,8\n"
-                "   srl   %2,8\n"
-                "4: ngr   %2,%1\n"
-                "   ic    %2,0(%2,%5)\n"
-                "   algr  %0,%2\n"
-                "5:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+       asm volatile(
+               "       slgr    %1,%1\n"
+               "       lgr     %2,%3\n"
+               "       slgr    %0,%0\n"
+               "       aghi    %2,63\n"
+               "       srlg    %2,%2,6\n"
+               "0:     cg      %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       aghi    %0,8\n"
+               "       brct    %2,0b\n"
+               "       lgr     %0,%3\n"
+               "       j       5f\n"
+               "1:     lg      %2,0(%0,%4)\n"
+               "       sllg    %0,%0,3\n"
+               "       clr     %2,%1\n"
+               "       jne     2f\n"
+               "       aghi    %0,32\n"
+               "       srlg    %2,%2,32\n"
+               "2:     lghi    %1,0xff\n"
+               "       tmll    %2,0xffff\n"
+               "       jnz     3f\n"
+               "       aghi    %0,16\n"
+               "       srl     %2,16\n"
+               "3:     tmll    %2,0x00ff\n"
+               "       jnz     4f\n"
+               "       aghi    %0,8\n"
+               "       srl     %2,8\n"
+               "4:     ngr     %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       algr    %0,%2\n"
+               "5:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
                : "a" (size), "a" (addr), "a" (&_sb_findmap),
-                 "m" (*(addrtype *) addr) : "cc" );
+                 "m" (*(addrtype *) addr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -832,36 +779,37 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size)
 
         if (!size)
                 return 0;
-        __asm__("   lhi  %1,-1\n"
-                "   lr   %2,%3\n"
-                "   ahi  %2,31\n"
-                "   srl  %2,5\n"
-                "   slr  %0,%0\n"
-                "0: cl   %1,0(%0,%4)\n"
-                "   jne  1f\n"
-                "   ahi  %0,4\n"
-                "   brct %2,0b\n"
-                "   lr   %0,%3\n"
-                "   j    4f\n"
-                "1: l    %2,0(%0,%4)\n"
-                "   sll  %0,3\n"
-                "   ahi  %0,24\n"
-                "   lhi  %1,0xff\n"
-                "   tmh  %2,0xffff\n"
-                "   jo   2f\n"
-                "   ahi  %0,-16\n"
-                "   srl  %2,16\n"
-                "2: tml  %2,0xff00\n"
-                "   jo   3f\n"
-                "   ahi  %0,-8\n"
-                "   srl  %2,8\n"
-                "3: nr   %2,%1\n"
-                "   ic   %2,0(%2,%5)\n"
-                "   alr  %0,%2\n"
-                "4:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
-                : "a" (size), "a" (vaddr), "a" (&_zb_findmap),
-                 "m" (*(addrtype *) vaddr) : "cc" );
+       asm volatile(
+               "       lhi     %1,-1\n"
+               "       lr      %2,%3\n"
+               "       ahi     %2,31\n"
+               "       srl     %2,5\n"
+               "       slr     %0,%0\n"
+               "0:     cl      %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       ahi     %0,4\n"
+               "       brct    %2,0b\n"
+               "       lr      %0,%3\n"
+               "       j       4f\n"
+               "1:     l       %2,0(%0,%4)\n"
+               "       sll     %0,3\n"
+               "       ahi     %0,24\n"
+               "       lhi     %1,0xff\n"
+               "       tmh     %2,0xffff\n"
+               "       jo      2f\n"
+               "       ahi     %0,-16\n"
+               "       srl     %2,16\n"
+               "2:     tml     %2,0xff00\n"
+               "       jo      3f\n"
+               "       ahi     %0,-8\n"
+               "       srl     %2,8\n"
+               "3:     nr      %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       alr     %0,%2\n"
+               "4:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
+               : "a" (size), "a" (vaddr), "a" (&_zb_findmap),
+                 "m" (*(addrtype *) vaddr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -875,39 +823,40 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size)
 
         if (!size)
                 return 0;
-        __asm__("   lghi  %1,-1\n"
-                "   lgr   %2,%3\n"
-                "   aghi  %2,63\n"
-                "   srlg  %2,%2,6\n"
-                "   slgr  %0,%0\n"
-                "0: clg   %1,0(%0,%4)\n"
-                "   jne   1f\n"
-                "   aghi  %0,8\n"
-                "   brct  %2,0b\n"
-                "   lgr   %0,%3\n"
-                "   j     5f\n"
-                "1: cl    %1,0(%0,%4)\n"
-               "   jne   2f\n"
-               "   aghi  %0,4\n"
-               "2: l     %2,0(%0,%4)\n"
-                "   sllg  %0,%0,3\n"
-                "   aghi  %0,24\n"
-                "   lghi  %1,0xff\n"
-                "   tmlh  %2,0xffff\n"
-                "   jo    3f\n"
-                "   aghi  %0,-16\n"
-                "   srl   %2,16\n"
-                "3: tmll  %2,0xff00\n"
-                "   jo    4f\n"
-                "   aghi  %0,-8\n"
-                "   srl   %2,8\n"
-                "4: ngr   %2,%1\n"
-                "   ic    %2,0(%2,%5)\n"
-                "   algr  %0,%2\n"
-                "5:"
-                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+       asm volatile(
+               "       lghi    %1,-1\n"
+               "       lgr     %2,%3\n"
+               "       aghi    %2,63\n"
+               "       srlg    %2,%2,6\n"
+               "       slgr    %0,%0\n"
+               "0:     clg     %1,0(%0,%4)\n"
+               "       jne     1f\n"
+               "       aghi    %0,8\n"
+               "       brct    %2,0b\n"
+               "       lgr     %0,%3\n"
+               "       j       5f\n"
+               "1:     cl      %1,0(%0,%4)\n"
+               "       jne     2f\n"
+               "       aghi    %0,4\n"
+               "2:     l       %2,0(%0,%4)\n"
+               "       sllg    %0,%0,3\n"
+               "       aghi    %0,24\n"
+               "       lghi    %1,0xff\n"
+               "       tmlh    %2,0xffff\n"
+               "       jo      3f\n"
+               "       aghi    %0,-16\n"
+               "       srl     %2,16\n"
+               "3:     tmll    %2,0xff00\n"
+               "       jo      4f\n"
+               "       aghi    %0,-8\n"
+               "       srl     %2,8\n"
+               "4:     ngr     %2,%1\n"
+               "       ic      %2,0(%2,%5)\n"
+               "       algr    %0,%2\n"
+               "5:"
+               : "=&a" (res), "=&d" (cmp), "=&a" (count)
                : "a" (size), "a" (vaddr), "a" (&_zb_findmap),
-                 "m" (*(addrtype *) vaddr) : "cc" );
+                 "m" (*(addrtype *) vaddr) : "cc");
         return (res < size) ? res : size;
 }
 
@@ -927,13 +876,16 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
        p = addr + offset / __BITOPS_WORDSIZE;
         if (bit) {
 #ifndef __s390x__
-                asm("   ic   %0,0(%1)\n"
-                   "   icm  %0,2,1(%1)\n"
-                   "   icm  %0,4,2(%1)\n"
-                   "   icm  %0,8,3(%1)"
-                   : "=&a" (word) : "a" (p), "m" (*p) : "cc" );
+               asm volatile(
+                       "       ic      %0,0(%1)\n"
+                       "       icm     %0,2,1(%1)\n"
+                       "       icm     %0,4,2(%1)\n"
+                       "       icm     %0,8,3(%1)"
+                       : "=&a" (word) : "a" (p), "m" (*p) : "cc");
 #else
-                asm("   lrvg %0,%1" : "=a" (word) : "m" (*p) );
+               asm volatile(
+                       "       lrvg    %0,%1"
+                       : "=a" (word) : "m" (*p) );
 #endif
                /*
                 * s390 version of ffz returns __BITOPS_WORDSIZE
index 2cc35a0e188e1712def6878400af75694d5b92e4..1fe2492baa8d141414c66f343f6ddae3e30eeed5 100644 (file)
 #ifdef __GNUC__
 
 #ifdef __s390x__
-static __inline__ __u64 ___arch__swab64p(const __u64 *x)
+static inline __u64 ___arch__swab64p(const __u64 *x)
 {
        __u64 result;
 
-       __asm__ __volatile__ (
-               "   lrvg %0,%1"
-               : "=d" (result) : "m" (*x) );
+       asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x));
        return result;
 }
 
-static __inline__ __u64 ___arch__swab64(__u64 x)
+static inline __u64 ___arch__swab64(__u64 x)
 {
        __u64 result;
 
-       __asm__ __volatile__ (
-               "   lrvgr %0,%1"
-               : "=d" (result) : "d" (x) );
+       asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x));
        return result;
 }
 
-static __inline__ void ___arch__swab64s(__u64 *x)
+static inline void ___arch__swab64s(__u64 *x)
 {
        *x = ___arch__swab64p(x);
 }
 #endif /* __s390x__ */
 
-static __inline__ __u32 ___arch__swab32p(const __u32 *x)
+static inline __u32 ___arch__swab32p(const __u32 *x)
 {
        __u32 result;
        
-       __asm__ __volatile__ (
+       asm volatile(
 #ifndef __s390x__
-               "        icm   %0,8,3(%1)\n"
-               "        icm   %0,4,2(%1)\n"
-               "        icm   %0,2,1(%1)\n"
-               "        ic    %0,0(%1)"
-               : "=&d" (result) : "a" (x), "m" (*x) : "cc" );
+               "       icm     %0,8,3(%1)\n"
+               "       icm     %0,4,2(%1)\n"
+               "       icm     %0,2,1(%1)\n"
+               "       ic      %0,0(%1)"
+               : "=&d" (result) : "a" (x), "m" (*x) : "cc");
 #else /* __s390x__ */
-               "   lrv  %0,%1"
-               : "=d" (result) : "m" (*x) );
+               "       lrv     %0,%1"
+               : "=d" (result) : "m" (*x));
 #endif /* __s390x__ */
        return result;
 }
 
-static __inline__ __u32 ___arch__swab32(__u32 x)
+static inline __u32 ___arch__swab32(__u32 x)
 {
 #ifndef __s390x__
        return ___arch__swab32p(&x);
 #else /* __s390x__ */
        __u32 result;
        
-       __asm__ __volatile__ (
-               "   lrvr  %0,%1"
-               : "=d" (result) : "d" (x) );
+       asm volatile("lrvr  %0,%1" : "=d" (result) : "d" (x));
        return result;
 #endif /* __s390x__ */
 }
@@ -81,14 +75,14 @@ static __inline__ __u16 ___arch__swab16p(const __u16 *x)
 {
        __u16 result;
        
-       __asm__ __volatile__ (
+       asm volatile(
 #ifndef __s390x__
-               "        icm   %0,2,1(%1)\n"
-               "        ic    %0,0(%1)\n"
-               : "=&d" (result) : "a" (x), "m" (*x) : "cc" );
+               "       icm     %0,2,1(%1)\n"
+               "       ic      %0,0(%1)\n"
+               : "=&d" (result) : "a" (x), "m" (*x) : "cc");
 #else /* __s390x__ */
-               "   lrvh %0,%1"
-               : "=d" (result) : "m" (*x) );
+               "       lrvh    %0,%1"
+               : "=d" (result) : "m" (*x));
 #endif /* __s390x__ */
        return result;
 }
index 471f2af2b16ae58d91a214402da3d416d1f0e435..37c362d89fad62210c78d8068b953c66679f11dc 100644 (file)
 static inline unsigned int
 csum_partial(const unsigned char * buff, int len, unsigned int sum)
 {
-       /*
-        * Experiments with ethernet and slip connections show that buf
-        * is aligned on either a 2-byte or 4-byte boundary.
-        */
-#ifndef __s390x__
-       register_pair rp;
-
-       rp.subreg.even = (unsigned long) buff;
-       rp.subreg.odd = (unsigned long) len;
-       __asm__ __volatile__ (
-               "0:  cksm %0,%1\n"      /* do checksum on longs */
-               "    jo   0b\n"
-               : "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-        __asm__ __volatile__ (
-                "    lgr  2,%1\n"    /* address in gpr 2 */
-                "    lgfr 3,%2\n"    /* length in gpr 3 */
-                "0:  cksm %0,2\n"    /* do checksum on longs */
-                "    jo   0b\n"
-                : "+&d" (sum)
-                : "d" (buff), "d" (len)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
-       return sum;
-}
-
-/*
- * csum_partial as an inline function
- */
-static inline unsigned int 
-csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
-{
-#ifndef __s390x__
-       register_pair rp;
+       register unsigned long reg2 asm("2") = (unsigned long) buff;
+       register unsigned long reg3 asm("3") = (unsigned long) len;
 
-       rp.subreg.even = (unsigned long) buff;
-       rp.subreg.odd = (unsigned long) len;
-       __asm__ __volatile__ (
-               "0:  cksm %0,%1\n"    /* do checksum on longs */
-               "    jo   0b\n"
-                : "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-       __asm__ __volatile__ (
-               "    lgr  2,%1\n"    /* address in gpr 2 */
-               "    lgfr 3,%2\n"    /* length in gpr 3 */
-               "0:  cksm %0,2\n"    /* do checksum on longs */
-               "    jo   0b\n"
-                : "+&d" (sum)
-               : "d" (buff), "d" (len)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
+       asm volatile(
+               "0:     cksm    %0,%1\n"        /* do checksum on longs */
+               "       jo      0b\n"
+               : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory");
        return sum;
 }
 
@@ -114,7 +70,7 @@ static inline unsigned int
 csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum)
 {
         memcpy(dst,src,len);
-        return csum_partial_inline(dst, len, sum);
+       return csum_partial(dst, len, sum);
 }
 
 /*
@@ -126,22 +82,22 @@ csum_fold(unsigned int sum)
 #ifndef __s390x__
        register_pair rp;
 
-       __asm__ __volatile__ (
-               "    slr  %N1,%N1\n" /* %0 = H L */
-               "    lr   %1,%0\n"   /* %0 = H L, %1 = H L 0 0 */
-               "    srdl %1,16\n"   /* %0 = H L, %1 = 0 H L 0 */
-               "    alr  %1,%N1\n"  /* %0 = H L, %1 = L H L 0 */
-               "    alr  %0,%1\n"   /* %0 = H+L+C L+H */
-               "    srl  %0,16\n"   /* %0 = H+L+C */
-               : "+&d" (sum), "=d" (rp) : : "cc" );
+       asm volatile(
+               "       slr     %N1,%N1\n"      /* %0 = H L */
+               "       lr      %1,%0\n"        /* %0 = H L, %1 = H L 0 0 */
+               "       srdl    %1,16\n"        /* %0 = H L, %1 = 0 H L 0 */
+               "       alr     %1,%N1\n"       /* %0 = H L, %1 = L H L 0 */
+               "       alr     %0,%1\n"        /* %0 = H+L+C L+H */
+               "       srl     %0,16\n"        /* %0 = H+L+C */
+               : "+&d" (sum), "=d" (rp) : : "cc");
 #else /* __s390x__ */
-       __asm__ __volatile__ (
-               "    sr   3,3\n"   /* %0 = H*65536 + L */
-               "    lr   2,%0\n"  /* %0 = H L, R2/R3 = H L / 0 0 */
-               "    srdl 2,16\n"  /* %0 = H L, R2/R3 = 0 H / L 0 */
-               "    alr  2,3\n"   /* %0 = H L, R2/R3 = L H / L 0 */
-               "    alr  %0,2\n"  /* %0 = H+L+C L+H */
-                "    srl  %0,16\n" /* %0 = H+L+C */
+       asm volatile(
+               "       sr      3,3\n"          /* %0 = H*65536 + L */
+               "       lr      2,%0\n"         /* %0 = H L, 2/3 = H L / 0 0 */
+               "       srdl    2,16\n"         /* %0 = H L, 2/3 = 0 H / L 0 */
+               "       alr     2,3\n"          /* %0 = H L, 2/3 = L H / L 0 */
+               "       alr     %0,2\n"         /* %0 = H+L+C L+H */
+               "       srl     %0,16\n"        /* %0 = H+L+C */
                : "+&d" (sum) : : "cc", "2", "3");
 #endif /* __s390x__ */
        return ((unsigned short) ~sum);
@@ -155,29 +111,7 @@ csum_fold(unsigned int sum)
 static inline unsigned short
 ip_fast_csum(unsigned char *iph, unsigned int ihl)
 {
-       unsigned long sum;
-#ifndef __s390x__
-       register_pair rp;
-
-       rp.subreg.even = (unsigned long) iph;
-       rp.subreg.odd = (unsigned long) ihl*4;
-        __asm__ __volatile__ (
-               "    sr   %0,%0\n"   /* set sum to zero */
-                "0:  cksm %0,%1\n"   /* do checksum on longs */
-                "    jo   0b\n"
-                : "=&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-        __asm__ __volatile__ (
-               "    slgr %0,%0\n"   /* set sum to zero */
-                "    lgr  2,%1\n"    /* address in gpr 2 */
-                "    lgfr 3,%2\n"    /* length in gpr 3 */
-                "0:  cksm %0,2\n"    /* do checksum on ints */
-                "    jo   0b\n"
-                : "=&d" (sum)
-                : "d" (iph), "d" (ihl*4)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
-        return csum_fold(sum);
+       return csum_fold(csum_partial(iph, ihl*4, 0));
 }
 
 /*
@@ -190,47 +124,47 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
                    unsigned int sum)
 {
 #ifndef __s390x__
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += saddr */
-                "    brc   12,0f\n"
-               "    ahi   %0,1\n"   /* add carry */
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += saddr */
+               "       brc     12,0f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "0:"
-               : "+&d" (sum) : "d" (saddr) : "cc" );
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += daddr */
-                "    brc   12,1f\n"
-                "    ahi   %0,1\n"   /* add carry */
+               : "+&d" (sum) : "d" (saddr) : "cc");
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += daddr */
+               "       brc     12,1f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "1:"
-               : "+&d" (sum) : "d" (daddr) : "cc" );
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += (len<<16) + (proto<<8) */
-               "    brc   12,2f\n"
-               "    ahi   %0,1\n"   /* add carry */
+               : "+&d" (sum) : "d" (daddr) : "cc");
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += (len<<16) + (proto<<8) */
+               "       brc     12,2f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "2:"
                : "+&d" (sum)
                : "d" (((unsigned int) len<<16) + (unsigned int) proto)
-               : "cc" );
+               : "cc");
 #else /* __s390x__ */
-       __asm__ __volatile__ (
-                "    lgfr  %0,%0\n"
-                "    algr  %0,%1\n"  /* sum += saddr */
-                "    brc   12,0f\n"
-               "    aghi  %0,1\n"   /* add carry */
-               "0:  algr  %0,%2\n"  /* sum += daddr */
-                "    brc   12,1f\n"
-                "    aghi  %0,1\n"   /* add carry */
-               "1:  algfr %0,%3\n"  /* sum += (len<<16) + proto */
-               "    brc   12,2f\n"
-               "    aghi  %0,1\n"   /* add carry */
-               "2:  srlg  0,%0,32\n"
-                "    alr   %0,0\n"   /* fold to 32 bits */
-                "    brc   12,3f\n"
-                "    ahi   %0,1\n"   /* add carry */
-                "3:  llgfr %0,%0"
+       asm volatile(
+               "       lgfr    %0,%0\n"
+               "       algr    %0,%1\n"  /* sum += saddr */
+               "       brc     12,0f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "0:     algr    %0,%2\n"  /* sum += daddr */
+               "       brc     12,1f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "1:     algfr   %0,%3\n"  /* sum += (len<<16) + proto */
+               "       brc     12,2f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "2:     srlg    0,%0,32\n"
+               "       alr     %0,0\n"   /* fold to 32 bits */
+               "       brc     12,3f\n"
+               "       ahi     %0,1\n"   /* add carry */
+               "3:     llgfr   %0,%0"
                : "+&d" (sum)
                : "d" (saddr), "d" (daddr),
                  "d" (((unsigned int) len<<16) + (unsigned int) proto)
-               : "cc", "0" );
+               : "cc", "0");
 #endif /* __s390x__ */
        return sum;
 }
index af098dc3cf59b614aedb59f80fb85d83d46e8217..6cd978cefb2850be383e462f77a05c23ff7adc33 100644 (file)
@@ -1,49 +1 @@
-#ifndef __S390_DIV64
-#define __S390_DIV64
-
-#ifndef __s390x__
-
-/* for do_div "base" needs to be smaller than 2^31-1 */
-#define do_div(n, base) ({                                      \
-       unsigned long long __n = (n);                           \
-       unsigned long __r;                                      \
-                                                               \
-       asm ("   slr  0,0\n"                                    \
-            "   l    1,%1\n"                                   \
-            "   srdl 0,1\n"                                    \
-            "   dr   0,%2\n"                                   \
-            "   alr  1,1\n"                                    \
-            "   alr  0,0\n"                                    \
-            "   lhi  2,1\n"                                    \
-            "   n    2,%1\n"                                   \
-            "   alr  0,2\n"                                    \
-            "   clr  0,%2\n"                                   \
-            "   jl   0f\n"                                     \
-            "   slr  0,%2\n"                                   \
-             "   ahi  1,1\n"                                   \
-            "0: st   1,%1\n"                                   \
-            "   l    1,4+%1\n"                                 \
-            "   srdl 0,1\n"                                    \
-             "   dr   0,%2\n"                                  \
-            "   alr  1,1\n"                                    \
-            "   alr  0,0\n"                                    \
-            "   lhi  2,1\n"                                    \
-            "   n    2,4+%1\n"                                 \
-            "   alr  0,2\n"                                    \
-            "   clr  0,%2\n"                                   \
-             "   jl   1f\n"                                    \
-            "   slr  0,%2\n"                                   \
-            "   ahi  1,1\n"                                    \
-            "1: st   1,4+%1\n"                                 \
-             "   lr   %0,0"                                    \
-            : "=d" (__r), "=m" (__n)                           \
-            : "d" (base), "m" (__n) : "0", "1", "2", "cc" );   \
-       (n) = (__n);                                            \
-        __r;                                                    \
-})
-
-#else /* __s390x__ */
 #include <asm-generic/div64.h>
-#endif /* __s390x__ */
-
-#endif
index 15fd2eda6c90191913581024465d59fcfb694e88..7f6f641d32f4b3b42e0eaeacbc03eef3beaf7855 100644 (file)
@@ -26,16 +26,16 @@ codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
 {
        if (nr-- <= 0)
                return;
-        __asm__ __volatile__(
-               "   bras 1,1f\n"
-               "   tr   0(1,%0),0(%2)\n"
-                "0: tr   0(256,%0),0(%2)\n"
-               "   la   %0,256(%0)\n"
-               "1: ahi  %1,-256\n"
-               "   jnm  0b\n"
-               "   ex   %1,0(1)"
-                : "+&a" (addr), "+&a" (nr)
-                : "a" (codepage) : "cc", "memory", "1" );
+       asm volatile(
+               "       bras    1,1f\n"
+               "       tr      0(1,%0),0(%2)\n"
+               "0:     tr      0(256,%0),0(%2)\n"
+               "       la      %0,256(%0)\n"
+               "1:     ahi     %1,-256\n"
+               "       jnm     0b\n"
+               "       ex      %1,0(1)"
+               : "+&a" (addr), "+&a" (nr)
+               : "a" (codepage) : "cc", "memory", "1");
 }
 
 #define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr)
index a6cc27e7700741adcaaee09e4fdfaec81260d1a5..63c78b9399c489b4fdee65ed05aec791e798e82d 100644 (file)
 static inline unsigned long virt_to_phys(volatile void * address)
 {
        unsigned long real_address;
-       __asm__ (
+       asm volatile(
 #ifndef __s390x__
-                "   lra    %0,0(%1)\n"
-                 "   jz     0f\n"
-                 "   sr     %0,%0\n"
+                "      lra     %0,0(%1)\n"
 #else /* __s390x__ */
-                "   lrag   %0,0(%1)\n"
-                 "   jz     0f\n"
-                 "   slgr   %0,%0\n"
+                "      lrag    %0,0(%1)\n"
 #endif /* __s390x__ */
+                "      jz      0f\n"
+                "      la      %0,0\n"
                  "0:"
-                 : "=a" (real_address) : "a" (address) : "cc" );
+                : "=a" (real_address) : "a" (address) : "cc");
         return real_address;
 }
 
index bd1a721f7aa2e82f1da34afb8d7f7771e260033c..7da991a858f8c97f1f390fd8285ebb3ab9e3c592 100644 (file)
@@ -19,8 +19,5 @@ enum interruption_class {
        NR_IRQS,
 };
 
-#define touch_nmi_watchdog() do { } while(0)
-
 #endif /* __KERNEL__ */
 #endif
-
index 3b566a5b3cc73e19d2487931283da12a0b008d65..3f26131120b746c47c81e7d370d76a2422b46153 100644 (file)
 
 #ifdef __KERNEL__
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
+/* store then or system mask. */
+#define __raw_local_irq_stosm(__or)                                    \
+({                                                                     \
+       unsigned long __mask;                                           \
+       asm volatile(                                                   \
+               "       stosm   %0,%1"                                  \
+               : "=Q" (__mask) : "i" (__or) : "memory");               \
+       __mask;                                                         \
+})
+
+/* store then and system mask. */
+#define __raw_local_irq_stnsm(__and)                                   \
+({                                                                     \
+       unsigned long __mask;                                           \
+       asm volatile(                                                   \
+               "       stnsm   %0,%1"                                  \
+               : "=Q" (__mask) : "i" (__and) : "memory");              \
+       __mask;                                                         \
+})
+
+/* set system mask. */
+#define __raw_local_irq_ssm(__mask)                                    \
+({                                                                     \
+       asm volatile("ssm   %0" : : "Q" (__mask) : "memory");           \
+})
+
+#else /* __GNUC__ */
+
+/* store then or system mask. */
+#define __raw_local_irq_stosm(__or)                                    \
+({                                                                     \
+       unsigned long __mask;                                           \
+       asm volatile(                                                   \
+               "       stosm   0(%1),%2"                               \
+               : "=m" (__mask)                                         \
+               : "a" (&__mask), "i" (__or) : "memory");                \
+       __mask;                                                         \
+})
+
+/* store then and system mask. */
+#define __raw_local_irq_stnsm(__and)                                   \
+({                                                                     \
+       unsigned long __mask;                                           \
+       asm volatile(                                                   \
+               "       stnsm   0(%1),%2"                               \
+               : "=m" (__mask)                                         \
+               : "a" (&__mask), "i" (__and) : "memory");               \
+       __mask;                                                         \
+})
+
+/* set system mask. */
+#define __raw_local_irq_ssm(__mask)                                    \
+({                                                                     \
+       asm volatile(                                                   \
+               "       ssm     0(%0)"                                  \
+               : : "a" (&__mask), "m" (__mask) : "memory");            \
+})
+
+#endif /* __GNUC__ */
+
 /* interrupt control.. */
-#define raw_local_irq_enable() ({ \
-       unsigned long  __dummy; \
-       __asm__ __volatile__ ( \
-               "stosm 0(%1),0x03" \
-               : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
-       })
-
-#define raw_local_irq_disable() ({ \
-       unsigned long __flags; \
-       __asm__ __volatile__ ( \
-               "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
-       __flags; \
-       })
-
-#define raw_local_save_flags(x)                                                        \
-do {                                                                           \
-       typecheck(unsigned long, x);                                            \
-       __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) );  \
-} while (0)
+static inline unsigned long raw_local_irq_enable(void)
+{
+       return __raw_local_irq_stosm(0x03);
+}
 
-#define raw_local_irq_restore(x)                                               \
-do {                                                                           \
-       typecheck(unsigned long, x);                                            \
-       __asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory");   \
+static inline unsigned long raw_local_irq_disable(void)
+{
+       return __raw_local_irq_stnsm(0xfc);
+}
+
+#define raw_local_save_flags(x)                                                \
+do {                                                                   \
+       typecheck(unsigned long, x);                                    \
+       (x) = __raw_local_irq_stosm(0x00);                              \
 } while (0)
 
-#define raw_irqs_disabled()            \
-({                                     \
-       unsigned long flags;            \
-       raw_local_save_flags(flags);    \
-       !((flags >> __FLAG_SHIFT) & 3); \
-})
+static inline void raw_local_irq_restore(unsigned long flags)
+{
+       __raw_local_irq_ssm(flags);
+}
 
 static inline int raw_irqs_disabled_flags(unsigned long flags)
 {
-       return !((flags >> __FLAG_SHIFT) & 3);
+       return !(flags & (3UL << (BITS_PER_LONG - 8)));
 }
 
 /* For spinlocks etc */
index 18695d10dedfdd6477973ca18efce6ff08cebd2d..06583ed0bde7bbc97a124a66fc92cf041f6acfb8 100644 (file)
@@ -359,7 +359,7 @@ extern struct _lowcore *lowcore_ptr[];
 
 static inline void set_prefix(__u32 address)
 {
-        __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" );
+       asm volatile("spx %0" : : "m" (address) : "memory");
 }
 
 #define __PANIC_MAGIC           0xDEADC0DE
index b2628dc5c49075d0841c9b440c2b8a8288f4cd6e..796c400f2b79963c5f63f2bf7a5640d3a4e6880f 100644 (file)
 #include <asm/setup.h>
 #ifndef __ASSEMBLY__
 
-#ifndef __s390x__
-
-static inline void clear_page(void *page)
-{
-       register_pair rp;
-
-       rp.subreg.even = (unsigned long) page;
-       rp.subreg.odd = (unsigned long) 4096;
-        asm volatile ("   slr  1,1\n"
-                     "   mvcl %0,0"
-                     : "+&a" (rp) : : "memory", "cc", "1" );
-}
-
-static inline void copy_page(void *to, void *from)
-{
-        if (MACHINE_HAS_MVPG)
-               asm volatile ("   sr   0,0\n"
-                             "   mvpg %0,%1"
-                             : : "a" ((void *)(to)), "a" ((void *)(from))
-                             : "memory", "cc", "0" );
-       else
-               asm volatile ("   mvc  0(256,%0),0(%1)\n"
-                             "   mvc  256(256,%0),256(%1)\n"
-                             "   mvc  512(256,%0),512(%1)\n"
-                             "   mvc  768(256,%0),768(%1)\n"
-                             "   mvc  1024(256,%0),1024(%1)\n"
-                             "   mvc  1280(256,%0),1280(%1)\n"
-                             "   mvc  1536(256,%0),1536(%1)\n"
-                             "   mvc  1792(256,%0),1792(%1)\n"
-                             "   mvc  2048(256,%0),2048(%1)\n"
-                             "   mvc  2304(256,%0),2304(%1)\n"
-                             "   mvc  2560(256,%0),2560(%1)\n"
-                             "   mvc  2816(256,%0),2816(%1)\n"
-                             "   mvc  3072(256,%0),3072(%1)\n"
-                             "   mvc  3328(256,%0),3328(%1)\n"
-                             "   mvc  3584(256,%0),3584(%1)\n"
-                             "   mvc  3840(256,%0),3840(%1)\n"
-                             : : "a"((void *)(to)),"a"((void *)(from)) 
-                             : "memory" );
-}
-
-#else /* __s390x__ */
-
 static inline void clear_page(void *page)
 {
-        asm volatile ("   lgr  2,%0\n"
-                      "   lghi 3,4096\n"
-                      "   slgr 1,1\n"
-                      "   mvcl 2,0"
-                      : : "a" ((void *) (page))
-                     : "memory", "cc", "1", "2", "3" );
+       register unsigned long reg1 asm ("1") = 0;
+       register void *reg2 asm ("2") = page;
+       register unsigned long reg3 asm ("3") = 4096;
+       asm volatile(
+               "       mvcl    2,0"
+               : "+d" (reg2), "+d" (reg3) : "d" (reg1) : "memory", "cc");
 }
 
 static inline void copy_page(void *to, void *from)
 {
-        if (MACHINE_HAS_MVPG)
-               asm volatile ("   sgr  0,0\n"
-                             "   mvpg %0,%1"
-                             : : "a" ((void *)(to)), "a" ((void *)(from))
-                             : "memory", "cc", "0" );
-       else
-               asm volatile ("   mvc  0(256,%0),0(%1)\n"
-                             "   mvc  256(256,%0),256(%1)\n"
-                             "   mvc  512(256,%0),512(%1)\n"
-                             "   mvc  768(256,%0),768(%1)\n"
-                             "   mvc  1024(256,%0),1024(%1)\n"
-                             "   mvc  1280(256,%0),1280(%1)\n"
-                             "   mvc  1536(256,%0),1536(%1)\n"
-                             "   mvc  1792(256,%0),1792(%1)\n"
-                             "   mvc  2048(256,%0),2048(%1)\n"
-                             "   mvc  2304(256,%0),2304(%1)\n"
-                             "   mvc  2560(256,%0),2560(%1)\n"
-                             "   mvc  2816(256,%0),2816(%1)\n"
-                             "   mvc  3072(256,%0),3072(%1)\n"
-                             "   mvc  3328(256,%0),3328(%1)\n"
-                             "   mvc  3584(256,%0),3584(%1)\n"
-                             "   mvc  3840(256,%0),3840(%1)\n"
-                             : : "a"((void *)(to)),"a"((void *)(from)) 
-                             : "memory" );
+       if (MACHINE_HAS_MVPG) {
+               register unsigned long reg0 asm ("0") = 0;
+               asm volatile(
+                       "       mvpg    %0,%1"
+                       : : "a" (to), "a" (from), "d" (reg0)
+                       : "memory", "cc");
+       } else
+               asm volatile(
+                       "       mvc     0(256,%0),0(%1)\n"
+                       "       mvc     256(256,%0),256(%1)\n"
+                       "       mvc     512(256,%0),512(%1)\n"
+                       "       mvc     768(256,%0),768(%1)\n"
+                       "       mvc     1024(256,%0),1024(%1)\n"
+                       "       mvc     1280(256,%0),1280(%1)\n"
+                       "       mvc     1536(256,%0),1536(%1)\n"
+                       "       mvc     1792(256,%0),1792(%1)\n"
+                       "       mvc     2048(256,%0),2048(%1)\n"
+                       "       mvc     2304(256,%0),2304(%1)\n"
+                       "       mvc     2560(256,%0),2560(%1)\n"
+                       "       mvc     2816(256,%0),2816(%1)\n"
+                       "       mvc     3072(256,%0),3072(%1)\n"
+                       "       mvc     3328(256,%0),3328(%1)\n"
+                       "       mvc     3584(256,%0),3584(%1)\n"
+                       "       mvc     3840(256,%0),3840(%1)\n"
+                       : : "a" (to), "a" (from) : "memory");
 }
 
-#endif /* __s390x__ */
-
 #define clear_user_page(page, vaddr, pg)       clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)    copy_page(to, from)
 
@@ -159,7 +115,7 @@ extern unsigned int default_storage_key;
 static inline void
 page_set_storage_key(unsigned long addr, unsigned int skey)
 {
-       asm volatile ( "sske %0,%1" : : "d" (skey), "a" (addr) );
+       asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
 }
 
 static inline unsigned int
@@ -167,8 +123,7 @@ page_get_storage_key(unsigned long addr)
 {
        unsigned int skey;
 
-       asm volatile ( "iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0) );
-
+       asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0));
        return skey;
 }
 
index e965309fedac640486c65a130a59ada9c0eb6caf..ecdff13b250512839a494c7d4432b5de2bd2dddc 100644 (file)
@@ -31,9 +31,9 @@
  * the S390 page table tree.
  */
 #ifndef __ASSEMBLY__
+#include <linux/mm_types.h>
 #include <asm/bug.h>
 #include <asm/processor.h>
-#include <linux/threads.h>
 
 struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
 struct mm_struct;
@@ -554,9 +554,10 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
                /* ipte in zarch mode can do the math */
                pte_t *pto = ptep;
 #endif
-               asm volatile ("ipte %2,%3"
-                             : "=m" (*ptep) : "m" (*ptep),
-                               "a" (pto), "a" (address) );
+               asm volatile(
+                       "       ipte    %2,%3"
+                       : "=m" (*ptep) : "m" (*ptep),
+                         "a" (pto), "a" (address));
        }
        pte_val(*ptep) = _PAGE_TYPE_EMPTY;
 }
@@ -596,30 +597,31 @@ ptep_establish(struct vm_area_struct *vma,
  * should therefore only be called if it is not mapped in any
  * address space.
  */
-#define page_test_and_clear_dirty(_page)                                 \
-({                                                                       \
-       struct page *__page = (_page);                                    \
-       unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
-       int __skey = page_get_storage_key(__physpage);                    \
-       if (__skey & _PAGE_CHANGED)                                       \
-               page_set_storage_key(__physpage, __skey & ~_PAGE_CHANGED);\
-       (__skey & _PAGE_CHANGED);                                         \
-})
+static inline int page_test_and_clear_dirty(struct page *page)
+{
+       unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
+       int skey = page_get_storage_key(physpage);
+
+       if (skey & _PAGE_CHANGED)
+               page_set_storage_key(physpage, skey & ~_PAGE_CHANGED);
+       return skey & _PAGE_CHANGED;
+}
 
 /*
  * Test and clear referenced bit in storage key.
  */
-#define page_test_and_clear_young(page)                                          \
-({                                                                       \
-       struct page *__page = (page);                                     \
-       unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
-       int __ccode;                                                      \
-       asm volatile ("rrbe 0,%1\n\t"                                     \
-                     "ipm  %0\n\t"                                       \
-                     "srl  %0,28\n\t"                                    \
-                      : "=d" (__ccode) : "a" (__physpage) : "cc" );      \
-       (__ccode & 2);                                                    \
-})
+static inline int page_test_and_clear_young(struct page *page)
+{
+       unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
+       int ccode;
+
+       asm volatile (
+               "rrbe 0,%1\n"
+               "ipm  %0\n"
+               "srl  %0,28\n"
+               : "=d" (ccode) : "a" (physpage) : "cc" );
+       return ccode & 2;
+}
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -632,32 +634,28 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
        return __pte;
 }
 
-#define mk_pte(pg, pgprot)                                                \
-({                                                                        \
-       struct page *__page = (pg);                                       \
-       pgprot_t __pgprot = (pgprot);                                     \
-       unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
-       pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
-       __pte;                                                            \
-})
+static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
+{
+       unsigned long physpage = __pa((page - mem_map) << PAGE_SHIFT);
 
-#define pfn_pte(pfn, pgprot)                                              \
-({                                                                        \
-       pgprot_t __pgprot = (pgprot);                                     \
-       unsigned long __physpage = __pa((pfn) << PAGE_SHIFT);             \
-       pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
-       __pte;                                                            \
-})
+       return mk_pte_phys(physpage, pgprot);
+}
+
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+       unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
+
+       return mk_pte_phys(physpage, pgprot);
+}
 
 #ifdef __s390x__
 
-#define pfn_pmd(pfn, pgprot)                                              \
-({                                                                        \
-       pgprot_t __pgprot = (pgprot);                                     \
-       unsigned long __physpage = __pa((pfn) << PAGE_SHIFT);             \
-       pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot));           \
-       __pmd;                                                            \
-})
+static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
+{
+       unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
+
+       return __pmd(physpage + pgprot_val(pgprot));
+}
 
 #endif /* __s390x__ */
 
index 578c2209fa76c269587b0b9507217bf3fa9d0563..cbbedc63ba25bac653aba4363ea5e1c6c2822fbb 100644 (file)
@@ -13,7 +13,6 @@
 #ifndef __ASM_S390_PROCESSOR_H
 #define __ASM_S390_PROCESSOR_H
 
-#include <asm/page.h>
 #include <asm/ptrace.h>
 
 #ifdef __KERNEL__
@@ -21,7 +20,7 @@
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
  */
-#define current_text_addr() ({ void *pc; __asm__("basr %0,0":"=a"(pc)); pc; })
+#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
 
 /*
  *  CPU type and hardware bug flags. Kept separately for each CPU.
@@ -202,7 +201,7 @@ unsigned long get_wchan(struct task_struct *p);
 static inline void cpu_relax(void)
 {
        if (MACHINE_HAS_DIAG44)
-               asm volatile ("diag 0,0,68" : : : "memory");
+               asm volatile("diag 0,0,68" : : : "memory");
        else
                barrier();
 }
@@ -213,9 +212,9 @@ static inline void cpu_relax(void)
 static inline void __load_psw(psw_t psw)
 {
 #ifndef __s390x__
-       asm volatile ("lpsw  0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+       asm volatile("lpsw  0(%0)" : : "a" (&psw), "m" (psw) : "cc");
 #else
-       asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+       asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
 #endif
 }
 
@@ -232,20 +231,20 @@ static inline void __load_psw_mask (unsigned long mask)
        psw.mask = mask;
 
 #ifndef __s390x__
-       asm volatile (
-               "    basr %0,0\n"
-               "0:  ahi  %0,1f-0b\n"
-               "    st   %0,4(%1)\n"
-               "    lpsw 0(%1)\n"
+       asm volatile(
+               "       basr    %0,0\n"
+               "0:     ahi     %0,1f-0b\n"
+               "       st      %0,4(%1)\n"
+               "       lpsw    0(%1)\n"
                "1:"
-               : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" );
+               : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
 #else /* __s390x__ */
-       asm volatile (
-               "    larl  %0,1f\n"
-               "    stg   %0,8(%1)\n"
-               "    lpswe 0(%1)\n"
+       asm volatile(
+               "       larl    %0,1f\n"
+               "       stg     %0,8(%1)\n"
+               "       lpswe   0(%1)\n"
                "1:"
-               : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" );
+               : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
 #endif /* __s390x__ */
 }
  
@@ -274,56 +273,57 @@ static inline void disabled_wait(unsigned long code)
          * the processor is dead afterwards
          */
 #ifndef __s390x__
-        asm volatile ("    stctl 0,0,0(%2)\n"
-                      "    ni    0(%2),0xef\n" /* switch off protection */
-                      "    lctl  0,0,0(%2)\n"
-                      "    stpt  0xd8\n"       /* store timer */
-                      "    stckc 0xe0\n"       /* store clock comparator */
-                      "    stpx  0x108\n"      /* store prefix register */
-                      "    stam  0,15,0x120\n" /* store access registers */
-                      "    std   0,0x160\n"    /* store f0 */
-                      "    std   2,0x168\n"    /* store f2 */
-                      "    std   4,0x170\n"    /* store f4 */
-                      "    std   6,0x178\n"    /* store f6 */
-                      "    stm   0,15,0x180\n" /* store general registers */
-                      "    stctl 0,15,0x1c0\n" /* store control registers */
-                      "    oi    0x1c0,0x10\n" /* fake protection bit */
-                      "    lpsw 0(%1)"
-                      : "=m" (ctl_buf)
-                     : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
+       asm volatile(
+               "       stctl   0,0,0(%2)\n"
+               "       ni      0(%2),0xef\n"   /* switch off protection */
+               "       lctl    0,0,0(%2)\n"
+               "       stpt    0xd8\n"         /* store timer */
+               "       stckc   0xe0\n"         /* store clock comparator */
+               "       stpx    0x108\n"        /* store prefix register */
+               "       stam    0,15,0x120\n"   /* store access registers */
+               "       std     0,0x160\n"      /* store f0 */
+               "       std     2,0x168\n"      /* store f2 */
+               "       std     4,0x170\n"      /* store f4 */
+               "       std     6,0x178\n"      /* store f6 */
+               "       stm     0,15,0x180\n"   /* store general registers */
+               "       stctl   0,15,0x1c0\n"   /* store control registers */
+               "       oi      0x1c0,0x10\n"   /* fake protection bit */
+               "       lpsw    0(%1)"
+               : "=m" (ctl_buf)
+               : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc");
 #else /* __s390x__ */
-        asm volatile ("    stctg 0,0,0(%2)\n"
-                      "    ni    4(%2),0xef\n" /* switch off protection */
-                      "    lctlg 0,0,0(%2)\n"
-                      "    lghi  1,0x1000\n"
-                      "    stpt  0x328(1)\n"      /* store timer */
-                      "    stckc 0x330(1)\n"      /* store clock comparator */
-                      "    stpx  0x318(1)\n"      /* store prefix register */
-                      "    stam  0,15,0x340(1)\n" /* store access registers */
-                      "    stfpc 0x31c(1)\n"      /* store fpu control */
-                      "    std   0,0x200(1)\n"    /* store f0 */
-                      "    std   1,0x208(1)\n"    /* store f1 */
-                      "    std   2,0x210(1)\n"    /* store f2 */
-                      "    std   3,0x218(1)\n"    /* store f3 */
-                      "    std   4,0x220(1)\n"    /* store f4 */
-                      "    std   5,0x228(1)\n"    /* store f5 */
-                      "    std   6,0x230(1)\n"    /* store f6 */
-                      "    std   7,0x238(1)\n"    /* store f7 */
-                      "    std   8,0x240(1)\n"    /* store f8 */
-                      "    std   9,0x248(1)\n"    /* store f9 */
-                      "    std   10,0x250(1)\n"   /* store f10 */
-                      "    std   11,0x258(1)\n"   /* store f11 */
-                      "    std   12,0x260(1)\n"   /* store f12 */
-                      "    std   13,0x268(1)\n"   /* store f13 */
-                      "    std   14,0x270(1)\n"   /* store f14 */
-                      "    std   15,0x278(1)\n"   /* store f15 */
-                      "    stmg  0,15,0x280(1)\n" /* store general registers */
-                      "    stctg 0,15,0x380(1)\n" /* store control registers */
-                      "    oi    0x384(1),0x10\n" /* fake protection bit */
-                      "    lpswe 0(%1)"
-                      : "=m" (ctl_buf)
-                     : "a" (&dw_psw), "a" (&ctl_buf),
-                       "m" (dw_psw) : "cc", "0", "1");
+       asm volatile(
+               "       stctg   0,0,0(%2)\n"
+               "       ni      4(%2),0xef\n"   /* switch off protection */
+               "       lctlg   0,0,0(%2)\n"
+               "       lghi    1,0x1000\n"
+               "       stpt    0x328(1)\n"     /* store timer */
+               "       stckc   0x330(1)\n"     /* store clock comparator */
+               "       stpx    0x318(1)\n"     /* store prefix register */
+               "       stam    0,15,0x340(1)\n"/* store access registers */
+               "       stfpc   0x31c(1)\n"     /* store fpu control */
+               "       std     0,0x200(1)\n"   /* store f0 */
+               "       std     1,0x208(1)\n"   /* store f1 */
+               "       std     2,0x210(1)\n"   /* store f2 */
+               "       std     3,0x218(1)\n"   /* store f3 */
+               "       std     4,0x220(1)\n"   /* store f4 */
+               "       std     5,0x228(1)\n"   /* store f5 */
+               "       std     6,0x230(1)\n"   /* store f6 */
+               "       std     7,0x238(1)\n"   /* store f7 */
+               "       std     8,0x240(1)\n"   /* store f8 */
+               "       std     9,0x248(1)\n"   /* store f9 */
+               "       std     10,0x250(1)\n"  /* store f10 */
+               "       std     11,0x258(1)\n"  /* store f11 */
+               "       std     12,0x260(1)\n"  /* store f12 */
+               "       std     13,0x268(1)\n"  /* store f13 */
+               "       std     14,0x270(1)\n"  /* store f14 */
+               "       std     15,0x278(1)\n"  /* store f15 */
+               "       stmg    0,15,0x280(1)\n"/* store general registers */
+               "       stctg   0,15,0x380(1)\n"/* store control registers */
+               "       oi      0x384(1),0x10\n"/* fake protection bit */
+               "       lpswe   0(%1)"
+               : "=m" (ctl_buf)
+               : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0");
 #endif /* __s390x__ */
 }
 
index 4d75d77b0f9960cad73cedb09adaae4e85a6c5c1..8d2bf65b0b6487a4c64df4444f3740d16c0428cb 100644 (file)
@@ -479,7 +479,7 @@ extern void show_regs(struct pt_regs * regs);
 static inline void
 psw_set_key(unsigned int key)
 {
-       asm volatile ( "spka 0(%0)" : : "d" (key) );
+       asm volatile("spka 0(%0)" : : "d" (key));
 }
 
 #endif /* __ASSEMBLY__ */
index 13ec16965150af1ca147ff4426b81b351d234c24..90f4eccaa290eb936de85dca4a6e96825f5e20bf 100644 (file)
@@ -122,23 +122,23 @@ static inline void __down_read(struct rw_semaphore *sem)
 {
        signed long old, new;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   ahi  %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       ahi     %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   aghi %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       aghi    %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count),
-                 "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" );
+                 "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
        if (old < 0)
                rwsem_down_read_failed(sem);
 }
@@ -150,27 +150,27 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
 {
        signed long old, new;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: ltr  %1,%0\n"
-               "   jm   1f\n"
-               "   ahi  %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b\n"
+               "       l       %0,0(%3)\n"
+               "0:     ltr     %1,%0\n"
+               "       jm      1f\n"
+               "       ahi     %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b\n"
                "1:"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: ltgr %1,%0\n"
-               "   jm   1f\n"
-               "   aghi %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b\n"
+               "       lg      %0,0(%3)\n"
+               "0:     ltgr    %1,%0\n"
+               "       jm      1f\n"
+               "       aghi    %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b\n"
                "1:"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count),
-                 "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" );
+                 "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
        return old >= 0 ? 1 : 0;
 }
 
@@ -182,23 +182,23 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
        signed long old, new, tmp;
 
        tmp = RWSEM_ACTIVE_WRITE_BIAS;
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   a    %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       a       %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   ag   %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       ag      %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count), "m" (tmp)
-               : "cc", "memory" );
+               : "cc", "memory");
        if (old != 0)
                rwsem_down_write_failed(sem);
 }
@@ -215,24 +215,24 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
 {
        signed long old;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%2)\n"
-               "0: ltr  %0,%0\n"
-               "   jnz  1f\n"
-               "   cs   %0,%4,0(%2)\n"
-               "   jl   0b\n"
+               "       l       %0,0(%2)\n"
+               "0:     ltr     %0,%0\n"
+               "       jnz     1f\n"
+               "       cs      %0,%4,0(%2)\n"
+               "       jl      0b\n"
 #else /* __s390x__ */
-               "   lg   %0,0(%2)\n"
-               "0: ltgr %0,%0\n"
-               "   jnz  1f\n"
-               "   csg  %0,%4,0(%2)\n"
-               "   jl   0b\n"
+               "       lg      %0,0(%2)\n"
+               "0:     ltgr    %0,%0\n"
+               "       jnz     1f\n"
+               "       csg     %0,%4,0(%2)\n"
+               "       jl      0b\n"
 #endif /* __s390x__ */
                "1:"
-                : "=&d" (old), "=m" (sem->count)
+               : "=&d" (old), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count),
-                 "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory" );
+                 "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory");
        return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
 }
 
@@ -243,24 +243,24 @@ static inline void __up_read(struct rw_semaphore *sem)
 {
        signed long old, new;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   ahi  %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       ahi     %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   aghi %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       aghi    %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count),
                  "i" (-RWSEM_ACTIVE_READ_BIAS)
-               : "cc", "memory" );
+               : "cc", "memory");
        if (new < 0)
                if ((new & RWSEM_ACTIVE_MASK) == 0)
                        rwsem_wake(sem);
@@ -274,23 +274,23 @@ static inline void __up_write(struct rw_semaphore *sem)
        signed long old, new, tmp;
 
        tmp = -RWSEM_ACTIVE_WRITE_BIAS;
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   a    %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       a       %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   ag   %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       ag      %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count), "m" (tmp)
-               : "cc", "memory" );
+               : "cc", "memory");
        if (new < 0)
                if ((new & RWSEM_ACTIVE_MASK) == 0)
                        rwsem_wake(sem);
@@ -304,23 +304,23 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
        signed long old, new, tmp;
 
        tmp = -RWSEM_WAITING_BIAS;
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   a    %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       a       %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   ag   %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       ag      %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count), "m" (tmp)
-               : "cc", "memory" );
+               : "cc", "memory");
        if (new > 1)
                rwsem_downgrade_wake(sem);
 }
@@ -332,23 +332,23 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
 {
        signed long old, new;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   ar   %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       ar      %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   agr  %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       agr     %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count), "d" (delta)
-               : "cc", "memory" );
+               : "cc", "memory");
 }
 
 /*
@@ -358,23 +358,23 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
 {
        signed long old, new;
 
-       __asm__ __volatile__(
+       asm volatile(
 #ifndef __s390x__
-               "   l    %0,0(%3)\n"
-               "0: lr   %1,%0\n"
-               "   ar   %1,%5\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       l       %0,0(%3)\n"
+               "0:     lr      %1,%0\n"
+               "       ar      %1,%5\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b"
 #else /* __s390x__ */
-               "   lg   %0,0(%3)\n"
-               "0: lgr  %1,%0\n"
-               "   agr  %1,%5\n"
-               "   csg  %0,%1,0(%3)\n"
-               "   jl   0b"
+               "       lg      %0,0(%3)\n"
+               "0:     lgr     %1,%0\n"
+               "       agr     %1,%5\n"
+               "       csg     %0,%1,0(%3)\n"
+               "       jl      0b"
 #endif /* __s390x__ */
-                : "=&d" (old), "=&d" (new), "=m" (sem->count)
+               : "=&d" (old), "=&d" (new), "=m" (sem->count)
                : "a" (&sem->count), "m" (sem->count), "d" (delta)
-               : "cc", "memory" );
+               : "cc", "memory");
        return new;
 }
 
index 32cdc69f39f4dd28c42521e67d77a7b536356cdc..dbce058aefa92a6ed2f6781d1a5b1c147e1eae27 100644 (file)
@@ -85,17 +85,17 @@ static inline int down_trylock(struct semaphore * sem)
         *       sem->count.counter = --new_val;
         * In the ppc code this is called atomic_dec_if_positive.
         */
-       __asm__ __volatile__ (
-               "   l    %0,0(%3)\n"
-               "0: ltr  %1,%0\n"
-               "   jle  1f\n"
-               "   ahi  %1,-1\n"
-               "   cs   %0,%1,0(%3)\n"
-               "   jl   0b\n"
+       asm volatile(
+               "       l       %0,0(%3)\n"
+               "0:     ltr     %1,%0\n"
+               "       jle     1f\n"
+               "       ahi     %1,-1\n"
+               "       cs      %0,%1,0(%3)\n"
+               "       jl      0b\n"
                "1:"
                : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter)
                : "a" (&sem->count.counter), "m" (sem->count.counter)
-               : "cc", "memory" );
+               : "cc", "memory");
        return old_val <= 0;
 }
 
index de69dfa46fbba0baee8e305a61639adb1614d167..8ca8c77b2d04c75fa3d0498217d521f2001d66f1 100644 (file)
        unsigned int __r2 = (x2) + (y2);                        \
        unsigned int __r1 = (x1);                               \
        unsigned int __r0 = (x0);                               \
-       __asm__ ("   alr %2,%3\n"                               \
-                "   brc 12,0f\n"                               \
-                "   lhi 0,1\n"                                 \
-                "   alr %1,0\n"                                \
-                "   brc 12,0f\n"                               \
-                "   alr %0,0\n"                                \
-                "0:"                                           \
-                : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0)     \
-                : "d" (y0), "i" (1) : "cc", "0" );             \
-       __asm__ ("   alr %1,%2\n"                               \
-                "   brc 12,0f\n"                               \
-                "   ahi %0,1\n"                                \
-                "0:"                                           \
-                : "+&d" (__r2), "+&d" (__r1)                   \
-                : "d" (y1) : "cc" );                           \
+       asm volatile(                                           \
+               "       alr     %2,%3\n"                        \
+               "       brc     12,0f\n"                        \
+               "       lhi     0,1\n"                          \
+               "       alr     %1,0\n"                         \
+               "       brc     12,0f\n"                        \
+               "       alr     %0,0\n"                         \
+               "0:"                                            \
+               : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0)      \
+               : "d" (y0), "i" (1) : "cc", "0" );              \
+       asm volatile(                                           \
+               "       alr     %1,%2\n"                        \
+               "       brc     12,0f\n"                        \
+               "       ahi     %0,1\n"                         \
+               "0:"                                            \
+               : "+&d" (__r2), "+&d" (__r1)                    \
+               : "d" (y1) : "cc");                             \
        (r2) = __r2;                                            \
        (r1) = __r1;                                            \
        (r0) = __r0;                                            \
        unsigned int __r2 = (x2) - (y2);                        \
        unsigned int __r1 = (x1);                               \
        unsigned int __r0 = (x0);                               \
-       __asm__ ("   slr %2,%3\n"                               \
-                "   brc 3,0f\n"                                \
-                "   lhi 0,1\n"                                 \
-                "   slr %1,0\n"                                \
-                "   brc 3,0f\n"                                \
-                "   slr %0,0\n"                                \
-                "0:"                                           \
-                : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0)     \
-                : "d" (y0) : "cc", "0" );                      \
-       __asm__ ("   slr %1,%2\n"                               \
-                "   brc 3,0f\n"                                \
-                "   ahi %0,-1\n"                               \
-                "0:"                                           \
-                : "+&d" (__r2), "+&d" (__r1)                   \
-                : "d" (y1) : "cc" );                           \
+       asm volatile(                                           \
+               "       slr   %2,%3\n"                          \
+               "       brc     3,0f\n"                         \
+               "       lhi     0,1\n"                          \
+               "       slr     %1,0\n"                         \
+               "       brc     3,0f\n"                         \
+               "       slr     %0,0\n"                         \
+               "0:"                                            \
+               : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0)      \
+               : "d" (y0) : "cc", "0");                        \
+       asm volatile(                                           \
+               "       slr     %1,%2\n"                        \
+               "       brc     3,0f\n"                         \
+               "       ahi     %0,-1\n"                        \
+               "0:"                                            \
+               : "+&d" (__r2), "+&d" (__r1)                    \
+               : "d" (y1) : "cc");                             \
        (r2) = __r2;                                            \
        (r1) = __r1;                                            \
        (r0) = __r0;                                            \
index fc56458aff66b8e52470235c6d11923d8ea027a2..e16d56f8dfe1dd01864c3993c60a2f0a43757799 100644 (file)
@@ -70,16 +70,16 @@ typedef enum
 static inline sigp_ccode
 signal_processor(__u16 cpu_addr, sigp_order_code order_code)
 {
+       register unsigned long reg1 asm ("1") = 0;
        sigp_ccode ccode;
 
-       __asm__ __volatile__(
-               "    sr     1,1\n"        /* parameter=0 in gpr 1 */
-               "    sigp   1,%1,0(%2)\n"
-               "    ipm    %0\n"
-               "    srl    %0,28\n"
-               : "=d" (ccode)
-               : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code)
-               : "cc" , "memory", "1" );
+       asm volatile(
+               "       sigp    %1,%2,0(%3)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               :       "=d"    (ccode)
+               : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
+                 "a" (order_code) : "cc" , "memory");
        return ccode;
 }
 
@@ -87,20 +87,18 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code)
  * Signal processor with parameter
  */
 static inline sigp_ccode
-signal_processor_p(__u32 parameter, __u16 cpu_addr,
-                  sigp_order_code order_code)
+signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code)
 {
+       register unsigned int reg1 asm ("1") = parameter;
        sigp_ccode ccode;
-       
-       __asm__ __volatile__(
-               "    lr     1,%1\n"       /* parameter in gpr 1 */
-               "    sigp   1,%2,0(%3)\n"
-               "    ipm    %0\n"
-               "    srl    %0,28\n"
+
+       asm volatile(
+               "       sigp    %1,%2,0(%3)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
                : "=d" (ccode)
-               : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]),
-                  "a" (order_code)
-               : "cc" , "memory", "1" );
+               : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
+                 "a" (order_code) : "cc" , "memory");
        return ccode;
 }
 
@@ -108,24 +106,21 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr,
  * Signal processor with parameter and return status
  */
 static inline sigp_ccode
-signal_processor_ps(__u32 *statusptr, __u32 parameter,
-                   __u16 cpu_addr, sigp_order_code order_code)
+signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr,
+                   sigp_order_code order_code)
 {
+       register unsigned int reg1 asm ("1") = parameter;
        sigp_ccode ccode;
-       
-       __asm__ __volatile__(
-               "    sr     2,2\n"        /* clear status */
-               "    lr     3,%2\n"       /* parameter in gpr 3 */
-               "    sigp   2,%3,0(%4)\n"
-               "    st     2,%1\n"
-               "    ipm    %0\n"
-               "    srl    %0,28\n"
-               : "=d" (ccode), "=m" (*statusptr)
-               : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]),
-                  "a" (order_code)
-               : "cc" , "memory", "2" , "3"
-               );
-   return ccode;
+
+       asm volatile(
+               "       sigp    %1,%2,0(%3)\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               : "=d" (ccode), "+d" (reg1)
+               : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code)
+               : "cc" , "memory");
+       *statusptr = reg1;
+       return ccode;
 }
 
 #endif /* __SIGP__ */
index 9fb02e9779c9fe470d9386f02901a0ee16f46062..c3cf030ada4d480bebcf788d5ce688fe1de37d91 100644 (file)
@@ -56,7 +56,7 @@ static inline __u16 hard_smp_processor_id(void)
 {
         __u16 cpu_address;
  
-        __asm__ ("stap %0\n" : "=m" (cpu_address));
+       asm volatile("stap %0" : "=m" (cpu_address));
         return cpu_address;
 }
 
index 273dbecf8acef0465060133bbac01bab72118fc5..ce3edf6d63b3bdf4bac03a982d00151577843d4c 100644 (file)
 #ifndef __ASM_SPINLOCK_H
 #define __ASM_SPINLOCK_H
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+
+static inline int
+_raw_compare_and_swap(volatile unsigned int *lock,
+                     unsigned int old, unsigned int new)
+{
+       asm volatile(
+               "       cs      %0,%3,%1"
+               : "=d" (old), "=Q" (*lock)
+               : "0" (old), "d" (new), "Q" (*lock)
+               : "cc", "memory" );
+       return old;
+}
+
+#else /* __GNUC__ */
+
 static inline int
 _raw_compare_and_swap(volatile unsigned int *lock,
                      unsigned int old, unsigned int new)
 {
-       asm volatile ("cs %0,%3,0(%4)"
-                     : "=d" (old), "=m" (*lock)
-                     : "0" (old), "d" (new), "a" (lock), "m" (*lock)
-                     : "cc", "memory" );
+       asm volatile(
+               "       cs      %0,%3,0(%4)"
+               : "=d" (old), "=m" (*lock)
+               : "0" (old), "d" (new), "a" (lock), "m" (*lock)
+               : "cc", "memory" );
        return old;
 }
 
+#endif /* __GNUC__ */
+
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
  * on the local processor, one does not.
index 23a4c390489f0fd448ae8dc5f42b6cdeeebe9e02..d074673a6d9b500010e3c7f4ad25cfbaea5b2d68 100644 (file)
@@ -60,12 +60,13 @@ static inline void *memchr(const void * s, int c, size_t n)
        register int r0 asm("0") = (char) c;
        const void *ret = s + n;
 
-       asm volatile ("0: srst  %0,%1\n"
-                     "   jo    0b\n"
-                     "   jl    1f\n"
-                     "   la    %0,0\n"
-                     "1:"
-                     : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+       asm volatile(
+               "0:     srst    %0,%1\n"
+               "       jo      0b\n"
+               "       jl      1f\n"
+               "       la      %0,0\n"
+               "1:"
+               : "+a" (ret), "+&a" (s) : "d" (r0) : "cc");
        return (void *) ret;
 }
 
@@ -74,9 +75,10 @@ static inline void *memscan(void *s, int c, size_t n)
        register int r0 asm("0") = (char) c;
        const void *ret = s + n;
 
-       asm volatile ("0: srst  %0,%1\n"
-                     "   jo    0b\n"
-                     : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+       asm volatile(
+               "0:     srst    %0,%1\n"
+               "       jo      0b\n"
+               : "+a" (ret), "+&a" (s) : "d" (r0) : "cc");
        return (void *) ret;
 }
 
@@ -86,12 +88,13 @@ static inline char *strcat(char *dst, const char *src)
        unsigned long dummy;
        char *ret = dst;
 
-       asm volatile ("0: srst  %0,%1\n"
-                     "   jo    0b\n"
-                     "1: mvst  %0,%2\n"
-                     "   jo    1b"
-                     : "=&a" (dummy), "+a" (dst), "+a" (src)
-                     : "d" (r0), "0" (0) : "cc", "memory" );
+       asm volatile(
+               "0:     srst    %0,%1\n"
+               "       jo      0b\n"
+               "1:     mvst    %0,%2\n"
+               "       jo      1b"
+               : "=&a" (dummy), "+a" (dst), "+a" (src)
+               : "d" (r0), "0" (0) : "cc", "memory" );
        return ret;
 }
 
@@ -100,10 +103,11 @@ static inline char *strcpy(char *dst, const char *src)
        register int r0 asm("0") = 0;
        char *ret = dst;
 
-       asm volatile ("0: mvst  %0,%1\n"
-                     "   jo    0b"
-                     : "+&a" (dst), "+&a" (src) : "d" (r0)
-                     : "cc", "memory" );
+       asm volatile(
+               "0:     mvst    %0,%1\n"
+               "       jo      0b"
+               : "+&a" (dst), "+&a" (src) : "d" (r0)
+               : "cc", "memory");
        return ret;
 }
 
@@ -112,9 +116,10 @@ static inline size_t strlen(const char *s)
        register unsigned long r0 asm("0") = 0;
        const char *tmp = s;
 
-       asm volatile ("0: srst  %0,%1\n"
-                     "   jo    0b"
-                     : "+d" (r0), "+a" (tmp) :  : "cc" );
+       asm volatile(
+               "0:     srst    %0,%1\n"
+               "       jo      0b"
+               : "+d" (r0), "+a" (tmp) :  : "cc");
        return r0 - (unsigned long) s;
 }
 
@@ -124,9 +129,10 @@ static inline size_t strnlen(const char * s, size_t n)
        const char *tmp = s;
        const char *end = s + n;
 
-       asm volatile ("0: srst  %0,%1\n"
-                     "   jo    0b"
-                     : "+a" (end), "+a" (tmp) : "d" (r0)  : "cc" );
+       asm volatile(
+               "0:     srst    %0,%1\n"
+               "       jo      0b"
+               : "+a" (end), "+a" (tmp) : "d" (r0)  : "cc");
        return end - s;
 }
 
index 16040048cd1b3498ba48761adb7daa11cddb6d76..ccbafe4bf2cbf229614d053a29d66212f78cb558 100644 (file)
@@ -23,74 +23,68 @@ struct task_struct;
 
 extern struct task_struct *__switch_to(void *, void *);
 
-#ifdef __s390x__
-#define __FLAG_SHIFT 56
-#else /* ! __s390x__ */
-#define __FLAG_SHIFT 24
-#endif /* ! __s390x__ */
-
 static inline void save_fp_regs(s390_fp_regs *fpregs)
 {
-       asm volatile (
-               "   std   0,8(%1)\n"
-               "   std   2,24(%1)\n"
-               "   std   4,40(%1)\n"
-               "   std   6,56(%1)"
-               : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" );
+       asm volatile(
+               "       std     0,8(%1)\n"
+               "       std     2,24(%1)\n"
+               "       std     4,40(%1)\n"
+               "       std     6,56(%1)"
+               : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
        if (!MACHINE_HAS_IEEE)
                return;
        asm volatile(
-               "   stfpc 0(%1)\n"
-               "   std   1,16(%1)\n"
-               "   std   3,32(%1)\n"
-               "   std   5,48(%1)\n"
-               "   std   7,64(%1)\n"
-               "   std   8,72(%1)\n"
-               "   std   9,80(%1)\n"
-               "   std   10,88(%1)\n"
-               "   std   11,96(%1)\n"
-               "   std   12,104(%1)\n"
-               "   std   13,112(%1)\n"
-               "   std   14,120(%1)\n"
-               "   std   15,128(%1)\n"
-               : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" );
+               "       stfpc   0(%1)\n"
+               "       std     1,16(%1)\n"
+               "       std     3,32(%1)\n"
+               "       std     5,48(%1)\n"
+               "       std     7,64(%1)\n"
+               "       std     8,72(%1)\n"
+               "       std     9,80(%1)\n"
+               "       std     10,88(%1)\n"
+               "       std     11,96(%1)\n"
+               "       std     12,104(%1)\n"
+               "       std     13,112(%1)\n"
+               "       std     14,120(%1)\n"
+               "       std     15,128(%1)\n"
+               : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
 }
 
 static inline void restore_fp_regs(s390_fp_regs *fpregs)
 {
-       asm volatile (
-               "   ld    0,8(%0)\n"
-               "   ld    2,24(%0)\n"
-               "   ld    4,40(%0)\n"
-               "   ld    6,56(%0)"
-               : : "a" (fpregs), "m" (*fpregs) );
+       asm volatile(
+               "       ld      0,8(%0)\n"
+               "       ld      2,24(%0)\n"
+               "       ld      4,40(%0)\n"
+               "       ld      6,56(%0)"
+               : : "a" (fpregs), "m" (*fpregs));
        if (!MACHINE_HAS_IEEE)
                return;
        asm volatile(
-               "   lfpc  0(%0)\n"
-               "   ld    1,16(%0)\n"
-               "   ld    3,32(%0)\n"
-               "   ld    5,48(%0)\n"
-               "   ld    7,64(%0)\n"
-               "   ld    8,72(%0)\n"
-               "   ld    9,80(%0)\n"
-               "   ld    10,88(%0)\n"
-               "   ld    11,96(%0)\n"
-               "   ld    12,104(%0)\n"
-               "   ld    13,112(%0)\n"
-               "   ld    14,120(%0)\n"
-               "   ld    15,128(%0)\n"
-               : : "a" (fpregs), "m" (*fpregs) );
+               "       lfpc    0(%0)\n"
+               "       ld      1,16(%0)\n"
+               "       ld      3,32(%0)\n"
+               "       ld      5,48(%0)\n"
+               "       ld      7,64(%0)\n"
+               "       ld      8,72(%0)\n"
+               "       ld      9,80(%0)\n"
+               "       ld      10,88(%0)\n"
+               "       ld      11,96(%0)\n"
+               "       ld      12,104(%0)\n"
+               "       ld      13,112(%0)\n"
+               "       ld      14,120(%0)\n"
+               "       ld      15,128(%0)\n"
+               : : "a" (fpregs), "m" (*fpregs));
 }
 
 static inline void save_access_regs(unsigned int *acrs)
 {
-       asm volatile ("stam 0,15,0(%0)" : : "a" (acrs) : "memory" );
+       asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory");
 }
 
 static inline void restore_access_regs(unsigned int *acrs)
 {
-       asm volatile ("lam 0,15,0(%0)" : : "a" (acrs) );
+       asm volatile("lam 0,15,0(%0)" : : "a" (acrs));
 }
 
 #define switch_to(prev,next,last) do {                                      \
@@ -126,7 +120,7 @@ extern void account_system_vtime(struct task_struct *);
        account_vtime(prev);                                                 \
 } while (0)
 
-#define nop() __asm__ __volatile__ ("nop")
+#define nop() asm volatile("nop")
 
 #define xchg(ptr,x)                                                      \
 ({                                                                       \
@@ -147,15 +141,15 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
                shift = (3 ^ (addr & 3)) << 3;
                addr ^= addr & 3;
                asm volatile(
-                       "    l   %0,0(%4)\n"
-                       "0:  lr  0,%0\n"
-                       "    nr  0,%3\n"
-                       "    or  0,%2\n"
-                       "    cs  %0,0,0(%4)\n"
-                       "    jl  0b\n"
+                       "       l       %0,0(%4)\n"
+                       "0:     lr      0,%0\n"
+                       "       nr      0,%3\n"
+                       "       or      0,%2\n"
+                       "       cs      %0,0,0(%4)\n"
+                       "       jl      0b\n"
                        : "=&d" (old), "=m" (*(int *) addr)
                        : "d" (x << shift), "d" (~(255 << shift)), "a" (addr),
-                         "m" (*(int *) addr) : "memory", "cc", "0" );
+                         "m" (*(int *) addr) : "memory", "cc", "0");
                x = old >> shift;
                break;
        case 2:
@@ -163,36 +157,36 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
                shift = (2 ^ (addr & 2)) << 3;
                addr ^= addr & 2;
                asm volatile(
-                       "    l   %0,0(%4)\n"
-                       "0:  lr  0,%0\n"
-                       "    nr  0,%3\n"
-                       "    or  0,%2\n"
-                       "    cs  %0,0,0(%4)\n"
-                       "    jl  0b\n"
+                       "       l       %0,0(%4)\n"
+                       "0:     lr      0,%0\n"
+                       "       nr      0,%3\n"
+                       "       or      0,%2\n"
+                       "       cs      %0,0,0(%4)\n"
+                       "       jl      0b\n"
                        : "=&d" (old), "=m" (*(int *) addr)
                        : "d" (x << shift), "d" (~(65535 << shift)), "a" (addr),
-                         "m" (*(int *) addr) : "memory", "cc", "0" );
+                         "m" (*(int *) addr) : "memory", "cc", "0");
                x = old >> shift;
                break;
        case 4:
-               asm volatile (
-                       "    l   %0,0(%3)\n"
-                       "0:  cs  %0,%2,0(%3)\n"
-                       "    jl  0b\n"
+               asm volatile(
+                       "       l       %0,0(%3)\n"
+                       "0:     cs      %0,%2,0(%3)\n"
+                       "       jl      0b\n"
                        : "=&d" (old), "=m" (*(int *) ptr)
                        : "d" (x), "a" (ptr), "m" (*(int *) ptr)
-                       : "memory", "cc" );
+                       : "memory", "cc");
                x = old;
                break;
 #ifdef __s390x__
        case 8:
-               asm volatile (
-                       "    lg  %0,0(%3)\n"
-                       "0:  csg %0,%2,0(%3)\n"
-                       "    jl  0b\n"
+               asm volatile(
+                       "       lg      %0,0(%3)\n"
+                       "0:     csg     %0,%2,0(%3)\n"
+                       "       jl      0b\n"
                        : "=&d" (old), "=m" (*(long *) ptr)
                        : "d" (x), "a" (ptr), "m" (*(long *) ptr)
-                       : "memory", "cc" );
+                       : "memory", "cc");
                x = old;
                break;
 #endif /* __s390x__ */
@@ -224,55 +218,55 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
                shift = (3 ^ (addr & 3)) << 3;
                addr ^= addr & 3;
                asm volatile(
-                       "    l   %0,0(%4)\n"
-                       "0:  nr  %0,%5\n"
-                        "    lr  %1,%0\n"
-                       "    or  %0,%2\n"
-                       "    or  %1,%3\n"
-                       "    cs  %0,%1,0(%4)\n"
-                       "    jnl 1f\n"
-                       "    xr  %1,%0\n"
-                       "    nr  %1,%5\n"
-                       "    jnz 0b\n"
+                       "       l       %0,0(%4)\n"
+                       "0:     nr      %0,%5\n"
+                       "       lr      %1,%0\n"
+                       "       or      %0,%2\n"
+                       "       or      %1,%3\n"
+                       "       cs      %0,%1,0(%4)\n"
+                       "       jnl     1f\n"
+                       "       xr      %1,%0\n"
+                       "       nr      %1,%5\n"
+                       "       jnz     0b\n"
                        "1:"
                        : "=&d" (prev), "=&d" (tmp)
                        : "d" (old << shift), "d" (new << shift), "a" (ptr),
                          "d" (~(255 << shift))
-                       : "memory", "cc" );
+                       : "memory", "cc");
                return prev >> shift;
        case 2:
                addr = (unsigned long) ptr;
                shift = (2 ^ (addr & 2)) << 3;
                addr ^= addr & 2;
                asm volatile(
-                       "    l   %0,0(%4)\n"
-                       "0:  nr  %0,%5\n"
-                        "    lr  %1,%0\n"
-                       "    or  %0,%2\n"
-                       "    or  %1,%3\n"
-                       "    cs  %0,%1,0(%4)\n"
-                       "    jnl 1f\n"
-                       "    xr  %1,%0\n"
-                       "    nr  %1,%5\n"
-                       "    jnz 0b\n"
+                       "       l       %0,0(%4)\n"
+                       "0:     nr      %0,%5\n"
+                       "       lr      %1,%0\n"
+                       "       or      %0,%2\n"
+                       "       or      %1,%3\n"
+                       "       cs      %0,%1,0(%4)\n"
+                       "       jnl     1f\n"
+                       "       xr      %1,%0\n"
+                       "       nr      %1,%5\n"
+                       "       jnz     0b\n"
                        "1:"
                        : "=&d" (prev), "=&d" (tmp)
                        : "d" (old << shift), "d" (new << shift), "a" (ptr),
                          "d" (~(65535 << shift))
-                       : "memory", "cc" );
+                       : "memory", "cc");
                return prev >> shift;
        case 4:
-               asm volatile (
-                       "    cs  %0,%2,0(%3)\n"
+               asm volatile(
+                       "       cs      %0,%2,0(%3)\n"
                        : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
-                       : "memory", "cc" );
+                       : "memory", "cc");
                return prev;
 #ifdef __s390x__
        case 8:
-               asm volatile (
-                       "    csg %0,%2,0(%3)\n"
+               asm volatile(
+                       "       csg     %0,%2,0(%3)\n"
                        : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
-                       : "memory", "cc" );
+                       : "memory", "cc");
                return prev;
 #endif /* __s390x__ */
         }
@@ -289,8 +283,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
  * all memory ops have completed wrt other CPU's ( see 7-15 POP  DJB ).
  */
 
-#define eieio()  __asm__ __volatile__ ( "bcr 15,0" : : : "memory" ) 
-# define SYNC_OTHER_CORES(x)   eieio() 
+#define eieio()        asm volatile("bcr 15,0" : : : "memory")
+#define SYNC_OTHER_CORES(x)   eieio()
 #define mb()    eieio()
 #define rmb()   eieio()
 #define wmb()   eieio()
@@ -307,117 +301,56 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 
 #ifdef __s390x__
 
-#define __ctl_load(array, low, high) ({ \
-       typedef struct { char _[sizeof(array)]; } addrtype; \
-       __asm__ __volatile__ ( \
-               "   bras  1,0f\n" \
-                "   lctlg 0,0,0(%0)\n" \
-               "0: ex    %1,0(1)" \
-               : : "a" (&array), "a" (((low)<<4)+(high)), \
-                   "m" (*(addrtype *)(array)) : "1" ); \
+#define __ctl_load(array, low, high) ({                                \
+       typedef struct { char _[sizeof(array)]; } addrtype;     \
+       asm volatile(                                           \
+               "       lctlg   %1,%2,0(%0)\n"                  \
+               : : "a" (&array), "i" (low), "i" (high),        \
+                   "m" (*(addrtype *)(array)));                \
        })
 
-#define __ctl_store(array, low, high) ({ \
-       typedef struct { char _[sizeof(array)]; } addrtype; \
-       __asm__ __volatile__ ( \
-               "   bras  1,0f\n" \
-               "   stctg 0,0,0(%1)\n" \
-               "0: ex    %2,0(1)" \
-               : "=m" (*(addrtype *)(array)) \
-               : "a" (&array), "a" (((low)<<4)+(high)) : "1" ); \
+#define __ctl_store(array, low, high) ({                       \
+       typedef struct { char _[sizeof(array)]; } addrtype;     \
+       asm volatile(                                           \
+               "       stctg   %2,%3,0(%1)\n"                  \
+               : "=m" (*(addrtype *)(array))                   \
+               : "a" (&array), "i" (low), "i" (high));         \
        })
 
-#define __ctl_set_bit(cr, bit) ({ \
-        __u8 __dummy[24]; \
-        __asm__ __volatile__ ( \
-                "    bras  1,0f\n"       /* skip indirect insns */ \
-                "    stctg 0,0,0(%1)\n" \
-                "    lctlg 0,0,0(%1)\n" \
-                "0:  ex    %2,0(1)\n"    /* execute stctl */ \
-                "    lg    0,0(%1)\n" \
-                "    ogr   0,%3\n"       /* set the bit */ \
-                "    stg   0,0(%1)\n" \
-                "1:  ex    %2,6(1)"      /* execute lctl */ \
-                : "=m" (__dummy) \
-               : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
-                 "a" (cr*17), "a" (1L<<(bit)) \
-                : "cc", "0", "1" ); \
-        })
-
-#define __ctl_clear_bit(cr, bit) ({ \
-        __u8 __dummy[16]; \
-        __asm__ __volatile__ ( \
-                "    bras  1,0f\n"       /* skip indirect insns */ \
-                "    stctg 0,0,0(%1)\n" \
-                "    lctlg 0,0,0(%1)\n" \
-                "0:  ex    %2,0(1)\n"    /* execute stctl */ \
-                "    lg    0,0(%1)\n" \
-                "    ngr   0,%3\n"       /* set the bit */ \
-                "    stg   0,0(%1)\n" \
-                "1:  ex    %2,6(1)"      /* execute lctl */ \
-                : "=m" (__dummy) \
-               : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
-                 "a" (cr*17), "a" (~(1L<<(bit))) \
-                : "cc", "0", "1" ); \
-        })
-
 #else /* __s390x__ */
 
-#define __ctl_load(array, low, high) ({ \
-       typedef struct { char _[sizeof(array)]; } addrtype; \
-       __asm__ __volatile__ ( \
-               "   bras  1,0f\n" \
-                "   lctl 0,0,0(%0)\n" \
-               "0: ex    %1,0(1)" \
-               : : "a" (&array), "a" (((low)<<4)+(high)), \
-                   "m" (*(addrtype *)(array)) : "1" ); \
-       })
+#define __ctl_load(array, low, high) ({                                \
+       typedef struct { char _[sizeof(array)]; } addrtype;     \
+       asm volatile(                                           \
+               "       lctl    %1,%2,0(%0)\n"                  \
+               : : "a" (&array), "i" (low), "i" (high),        \
+                   "m" (*(addrtype *)(array)));                \
+})
 
-#define __ctl_store(array, low, high) ({ \
-       typedef struct { char _[sizeof(array)]; } addrtype; \
-       __asm__ __volatile__ ( \
-               "   bras  1,0f\n" \
-               "   stctl 0,0,0(%1)\n" \
-               "0: ex    %2,0(1)" \
-               : "=m" (*(addrtype *)(array)) \
-               : "a" (&array), "a" (((low)<<4)+(high)): "1" ); \
+#define __ctl_store(array, low, high) ({                       \
+       typedef struct { char _[sizeof(array)]; } addrtype;     \
+       asm volatile(                                           \
+               "       stctl   %2,%3,0(%1)\n"                  \
+               : "=m" (*(addrtype *)(array))                   \
+               : "a" (&array), "i" (low), "i" (high));         \
        })
 
-#define __ctl_set_bit(cr, bit) ({ \
-        __u8 __dummy[16]; \
-        __asm__ __volatile__ ( \
-                "    bras  1,0f\n"       /* skip indirect insns */ \
-                "    stctl 0,0,0(%1)\n" \
-                "    lctl  0,0,0(%1)\n" \
-                "0:  ex    %2,0(1)\n"    /* execute stctl */ \
-                "    l     0,0(%1)\n" \
-                "    or    0,%3\n"       /* set the bit */ \
-                "    st    0,0(%1)\n" \
-                "1:  ex    %2,4(1)"      /* execute lctl */ \
-                : "=m" (__dummy) \
-               : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
-                 "a" (cr*17), "a" (1<<(bit)) \
-                : "cc", "0", "1" ); \
-        })
-
-#define __ctl_clear_bit(cr, bit) ({ \
-        __u8 __dummy[16]; \
-        __asm__ __volatile__ ( \
-                "    bras  1,0f\n"       /* skip indirect insns */ \
-                "    stctl 0,0,0(%1)\n" \
-                "    lctl  0,0,0(%1)\n" \
-                "0:  ex    %2,0(1)\n"    /* execute stctl */ \
-                "    l     0,0(%1)\n" \
-                "    nr    0,%3\n"       /* set the bit */ \
-                "    st    0,0(%1)\n" \
-                "1:  ex    %2,4(1)"      /* execute lctl */ \
-                : "=m" (__dummy) \
-               : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \
-                 "a" (cr*17), "a" (~(1<<(bit))) \
-                : "cc", "0", "1" ); \
-        })
 #endif /* __s390x__ */
 
+#define __ctl_set_bit(cr, bit) ({      \
+       unsigned long __dummy;          \
+       __ctl_store(__dummy, cr, cr);   \
+       __dummy |= 1UL << (bit);        \
+       __ctl_load(__dummy, cr, cr);    \
+})
+
+#define __ctl_clear_bit(cr, bit) ({    \
+       unsigned long __dummy;          \
+       __ctl_store(__dummy, cr, cr);   \
+       __dummy &= ~(1UL << (bit));     \
+       __ctl_load(__dummy, cr, cr);    \
+})
+
 #include <linux/irqflags.h>
 
 /*
@@ -427,8 +360,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 static inline void
 __set_psw_mask(unsigned long mask)
 {
-       local_save_flags(mask);
-       __load_psw_mask(mask);
+       __load_psw_mask(mask | (__raw_local_irq_stosm(0x00) & ~(-1UL >> 8)));
 }
 
 #define local_mcck_enable()  __set_psw_mask(PSW_KERNEL_BITS)
index 5d0332a4c2bdd0b8d737aea0f8fd5d4fa96e546b..4df4a41029a32d22bb5c5ce618c8743637f2db77 100644 (file)
 
 typedef unsigned long long cycles_t;
 
-static inline cycles_t get_cycles(void)
-{
-       cycles_t cycles;
-
-       __asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc");
-       return cycles >> 2;
-}
-
 static inline unsigned long long get_clock (void)
 {
        unsigned long long clk;
 
-       __asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+       asm volatile("stck %0" : "=Q" (clk) : : "cc");
+#else /* __GNUC__ */
+       asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
+#endif /* __GNUC__ */
        return clk;
 }
 
+static inline cycles_t get_cycles(void)
+{
+       return (cycles_t) get_clock() >> 2;
+}
+
 #endif
index 73cd85bebfb2ade78de40e577452ff86054bbb14..fa4dc916a9bfe5de40fd2bb5f1bc31dd8015dadb 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #define local_flush_tlb() \
-do {  __asm__ __volatile__("ptlb": : :"memory"); } while (0)
+do {  asm volatile("ptlb": : :"memory"); } while (0)
 
 #ifndef CONFIG_SMP
 
@@ -68,24 +68,24 @@ extern void smp_ptlb_all(void);
 
 static inline void global_flush_tlb(void)
 {
+       register unsigned long reg2 asm("2");
+       register unsigned long reg3 asm("3");
+       register unsigned long reg4 asm("4");
+       long dummy;
+
 #ifndef __s390x__
        if (!MACHINE_HAS_CSP) {
                smp_ptlb_all();
                return;
        }
 #endif /* __s390x__ */
-       {
-               register unsigned long addr asm("4");
-               long dummy;
-
-               dummy = 0;
-               addr = ((unsigned long) &dummy) + 1;
-               __asm__ __volatile__ (
-                       "    slr  2,2\n"
-                       "    slr  3,3\n"
-                       "    csp  2,%0"
-                       : : "a" (addr), "m" (dummy) : "cc", "2", "3" );
-       }
+
+       dummy = 0;
+       reg2 = reg3 = 0;
+       reg4 = ((unsigned long) &dummy) + 1;
+       asm volatile(
+               "       csp     %0,%2"
+               : : "d" (reg2), "d" (reg3), "d" (reg4), "m" (dummy) : "cc" );
 }
 
 /*
@@ -102,9 +102,9 @@ static inline void __flush_tlb_mm(struct mm_struct * mm)
        if (unlikely(cpus_empty(mm->cpu_vm_mask)))
                return;
        if (MACHINE_HAS_IDTE) {
-               asm volatile (".insn rrf,0xb98e0000,0,%0,%1,0"
-                             : : "a" (2048),
-                             "a" (__pa(mm->pgd)&PAGE_MASK) : "cc" );
+               asm volatile(
+                       "       .insn   rrf,0xb98e0000,0,%0,%1,0"
+                       : : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc");
                return;
        }
        preempt_disable();
index e2047b0c90921a1898c1b6a94dadede886d25ec3..72ae4efddb49017af8c3a2ca7d619c531506a158 100644 (file)
 #define get_ds()        (KERNEL_DS)
 #define get_fs()        (current->thread.mm_segment)
 
-#ifdef __s390x__
 #define set_fs(x) \
 ({                                                                     \
        unsigned long __pto;                                            \
        current->thread.mm_segment = (x);                               \
        __pto = current->thread.mm_segment.ar4 ?                        \
                S390_lowcore.user_asce : S390_lowcore.kernel_asce;      \
-       asm volatile ("lctlg 7,7,%0" : : "m" (__pto) );                 \
+       __ctl_load(__pto, 7, 7);                                        \
 })
-#else /* __s390x__ */
-#define set_fs(x) \
-({                                                                     \
-       unsigned long __pto;                                            \
-       current->thread.mm_segment = (x);                               \
-       __pto = current->thread.mm_segment.ar4 ?                        \
-               S390_lowcore.user_asce : S390_lowcore.kernel_asce;      \
-       asm volatile ("lctl  7,7,%0" : : "m" (__pto) );                 \
-})
-#endif /* __s390x__ */
 
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
index d49c54cb5505a03d8ee8920af9e2d08f662bbffd..0361ac5dcde38333183b8e1e89676b61d28c37bf 100644 (file)
@@ -355,145 +355,145 @@ do {                                                         \
 
 #define _svc_clobber "1", "cc", "memory"
 
-#define _syscall0(type,name)                                \
-type name(void) {                                           \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la  %%r1,%1\n"                          \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name)                          \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall0(type,name)                                   \
+type name(void) {                                              \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name)                             \
+               : _svc_clobber);                                \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
-#define _syscall1(type,name,type1,arg1)                             \
-type name(type1 arg1) {                                             \
-       register type1 __arg1 asm("2") = arg1;               \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la  %%r1,%1\n"                          \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name),                         \
-                 "0" (__arg1)                               \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall1(type,name,type1,arg1)                                \
+type name(type1 arg1) {                                                \
+       register type1 __arg1 asm("2") = arg1;                  \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name),                            \
+                 "0" (__arg1)                                  \
+               : _svc_clobber);                                \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
-#define _syscall2(type,name,type1,arg1,type2,arg2)          \
-type name(type1 arg1, type2 arg2) {                         \
-       register type1 __arg1 asm("2") = arg1;               \
-       register type2 __arg2 asm("3") = arg2;               \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la %%r1,%1\n"                           \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name),                         \
-                 "0" (__arg1),                              \
-                 "d" (__arg2)                               \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall2(type,name,type1,arg1,type2,arg2)             \
+type name(type1 arg1, type2 arg2) {                            \
+       register type1 __arg1 asm("2") = arg1;                  \
+       register type2 __arg2 asm("3") = arg2;                  \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name),                            \
+                 "0" (__arg1),                                 \
+                 "d" (__arg2)                                  \
+               : _svc_clobber );                               \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)\
-type name(type1 arg1, type2 arg2, type3 arg3) {                     \
-       register type1 __arg1 asm("2") = arg1;               \
-       register type2 __arg2 asm("3") = arg2;               \
-       register type3 __arg3 asm("4") = arg3;               \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la  %%r1,%1\n"                          \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name),                         \
-                 "0" (__arg1),                              \
-                 "d" (__arg2),                              \
-                 "d" (__arg3)                               \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)  \
+type name(type1 arg1, type2 arg2, type3 arg3) {                        \
+       register type1 __arg1 asm("2") = arg1;                  \
+       register type2 __arg2 asm("3") = arg2;                  \
+       register type3 __arg3 asm("4") = arg3;                  \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name),                            \
+                 "0" (__arg1),                                 \
+                 "d" (__arg2),                                 \
+                 "d" (__arg3)                                  \
+               : _svc_clobber);                                \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,\
-                 type4,name4)                               \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {  \
-       register type1 __arg1 asm("2") = arg1;               \
-       register type2 __arg2 asm("3") = arg2;               \
-       register type3 __arg3 asm("4") = arg3;               \
-       register type4 __arg4 asm("5") = arg4;               \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la  %%r1,%1\n"                          \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name),                         \
-                 "0" (__arg1),                              \
-                 "d" (__arg2),                              \
-                 "d" (__arg3),                              \
-                 "d" (__arg4)                               \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,  \
+                 type4,name4)                                  \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {    \
+       register type1 __arg1 asm("2") = arg1;                  \
+       register type2 __arg2 asm("3") = arg2;                  \
+       register type3 __arg3 asm("4") = arg3;                  \
+       register type4 __arg4 asm("5") = arg4;                  \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name),                            \
+                 "0" (__arg1),                                 \
+                 "d" (__arg2),                                 \
+                 "d" (__arg3),                                 \
+                 "d" (__arg4)                                  \
+               : _svc_clobber);                                \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,\
-                 type4,name4,type5,name5)                   \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
-         type5 arg5) {                                      \
-       register type1 __arg1 asm("2") = arg1;               \
-       register type2 __arg2 asm("3") = arg2;               \
-       register type3 __arg3 asm("4") = arg3;               \
-       register type4 __arg4 asm("5") = arg4;               \
-       register type5 __arg5 asm("6") = arg5;               \
-       register long __svcres asm("2");                     \
-       long __res;                                          \
-       __asm__ __volatile__ (                               \
-               "    .if %1 < 256\n"                         \
-               "    svc %b1\n"                              \
-               "    .else\n"                                \
-               "    la  %%r1,%1\n"                          \
-               "    svc 0\n"                                \
-               "    .endif"                                 \
-               : "=d" (__svcres)                            \
-               : "i" (__NR_##name),                         \
-                 "0" (__arg1),                              \
-                 "d" (__arg2),                              \
-                 "d" (__arg3),                              \
-                 "d" (__arg4),                              \
-                 "d" (__arg5)                               \
-               : _svc_clobber );                            \
-       __res = __svcres;                                    \
-       __syscall_return(type,__res);                        \
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,  \
+                 type4,name4,type5,name5)                      \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,      \
+         type5 arg5) {                                         \
+       register type1 __arg1 asm("2") = arg1;                  \
+       register type2 __arg2 asm("3") = arg2;                  \
+       register type3 __arg3 asm("4") = arg3;                  \
+       register type4 __arg4 asm("5") = arg4;                  \
+       register type5 __arg5 asm("6") = arg5;                  \
+       register long __svcres asm("2");                        \
+       long __res;                                             \
+       asm volatile(                                           \
+               "       .if     %1 < 256\n"                     \
+               "       svc     %b1\n"                          \
+               "       .else\n"                                \
+               "       la      %%r1,%1\n"                      \
+               "       svc     0\n"                            \
+               "       .endif"                                 \
+               : "=d" (__svcres)                               \
+               : "i" (__NR_##name),                            \
+                 "0" (__arg1),                                 \
+                 "d" (__arg2),                                 \
+                 "d" (__arg3),                                 \
+                 "d" (__arg4),                                 \
+                 "d" (__arg5)                                  \
+               : _svc_clobber);                                \
+       __res = __svcres;                                       \
+       __syscall_return(type,__res);                           \
 }
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
index 4862daf8b9068390c31e247d7fc2ed34dce7f9e7..188f726217766f8e45bc7dce5a130e509d9b2f68 100644 (file)
@@ -274,12 +274,6 @@ static inline pte_t pte_mkread(pte_t pte)
        return(pte_mknewprot(pte)); 
 }
 
-static inline pte_t pte_mkexec(pte_t pte)
-{ 
-       pte_set_bits(pte, _PAGE_USER);
-       return(pte_mknewprot(pte)); 
-}
-
 static inline pte_t pte_mkdirty(pte_t pte)
 { 
        pte_set_bits(pte, _PAGE_DIRTY);
index b6da83dcc7a6690e81bde6956cd16acf6ef12a15..10174b110a5cf9bb332b531c24f2cedef3b35c0a 100644 (file)
@@ -55,13 +55,6 @@ extern dma_addr_t bad_dma_address;
 extern struct dma_mapping_ops* dma_ops;
 extern int iommu_merge;
 
-static inline int valid_dma_direction(int dma_direction)
-{
-       return ((dma_direction == DMA_BIDIRECTIONAL) ||
-               (dma_direction == DMA_TO_DEVICE) ||
-               (dma_direction == DMA_FROM_DEVICE));
-}
-
 static inline int dma_mapping_error(dma_addr_t dma_addr)
 {
        if (dma_ops->mapping_error)
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 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 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 1df2ac30a4d2650fc952b0c0e9862abaac547852..f7a52e19b4bee532fd3fc988ac6421867e123a0f 100644 (file)
@@ -58,6 +58,7 @@ header-y += elf-em.h
 header-y += fadvise.h
 header-y += fd.h
 header-y += fdreg.h
+header-y += fib_rules.h
 header-y += ftape-header-segment.h
 header-y += ftape-vendors.h
 header-y += fuse.h
@@ -70,6 +71,7 @@ header-y += hysdn_if.h
 header-y += i2c-dev.h
 header-y += i8k.h
 header-y += icmp.h
+header-y += if_addr.h
 header-y += if_arcnet.h
 header-y += if_arp.h
 header-y += if_bonding.h
@@ -79,6 +81,7 @@ header-y += if_fddi.h
 header-y += if.h
 header-y += if_hippi.h
 header-y += if_infiniband.h
+header-y += if_link.h
 header-y += if_packet.h
 header-y += if_plip.h
 header-y += if_ppp.h
@@ -110,6 +113,7 @@ header-y += mmtimer.h
 header-y += mqueue.h
 header-y += mtio.h
 header-y += ncp_no.h
+header-y += neighbour.h
 header-y += netfilter_arp.h
 header-y += netrom.h
 header-y += nfs2.h
index 6ba3aa8a81f4953b84cb1ef0edf093ed1b7af8ad..75b8baca08f3a999d0b84da8d30ea80a35b479ed 100644 (file)
@@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk)
 #include <asm/byteorder.h>
 
 struct ddpehdr {
-#ifdef __LITTLE_ENDIAN_BITFIELD
-       __u16   deh_len:10,
-               deh_hops:4,
-               deh_pad:2;
-#else
-       __u16   deh_pad:2,
-               deh_hops:4,
-               deh_len:10;
-#endif
+       __be16  deh_len_hops;   /* lower 10 bits are length, next 4 - hops */
        __be16  deh_sum;
        __be16  deh_dnet;
        __be16  deh_snet;
@@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)
        return (struct ddpehdr *)skb->h.raw;
 }
 
-/*
- *     Don't drop the struct into the struct above.  You'll get some
- *     surprise padding.
- */
-struct ddpebits {
-#ifdef __LITTLE_ENDIAN_BITFIELD
-       __u16   deh_len:10,
-               deh_hops:4,
-               deh_pad:2;
-#else
-       __u16   deh_pad:2,
-               deh_hops:4,
-               deh_len:10;
-#endif
-};
-
-/* Short form header */
-struct ddpshdr {
-#ifdef __LITTLE_ENDIAN_BITFIELD
-       __u16   dsh_len:10,
-               dsh_pad:6;
-#else
-       __u16   dsh_pad:6,
-               dsh_len:10;
-#endif
-       __u8    dsh_dport;
-       __u8    dsh_sport;
-       /* And netatalk apps expect to stick the type in themselves */
-};
-
 /* AppleTalk AARP headers */
 struct elapaarp {
        __be16  hw_type;
index f267f2442766d9c07123dfffe7959bfc52685ae3..6f5a1bab8f5012705e0b1d0de7bde0a021962f84 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * 
- * ATM Lan Emulation Daemon vs. driver interface
- *
- * mkiiskila@yahoo.com
+ * ATM Lan Emulation Daemon driver interface
  *
+ * Marko Kiiskila <mkiiskila@yahoo.com>
  */
 
 #ifndef _ATMLEC_H_
 #include <linux/atmioc.h>
 #include <linux/atm.h>
 #include <linux/if_ether.h>
+
 /* ATM lec daemon control socket */
-#define ATMLEC_CTRL _IO('a',ATMIOC_LANE)
-#define ATMLEC_DATA _IO('a',ATMIOC_LANE+1)
-#define ATMLEC_MCAST _IO('a',ATMIOC_LANE+2)
+#define ATMLEC_CTRL    _IO('a', ATMIOC_LANE)
+#define ATMLEC_DATA    _IO('a', ATMIOC_LANE+1)
+#define ATMLEC_MCAST   _IO('a', ATMIOC_LANE+2)
 
 /* Maximum number of LEC interfaces (tweakable) */
 #define MAX_LEC_ITF 48
 
-/* From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring.
+/*
+ * From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring.
  * E.g. if MAX_LEC_ITF = 48 and NUM_TR_DEVS = 8, then lec0-lec39 are for
  * Ethernet ELANs and lec40-lec47 are for Token Ring ELANS.
  */
 #define NUM_TR_DEVS 8
 
-typedef enum { 
-        l_set_mac_addr,   l_del_mac_addr, 
-        l_svc_setup, 
-        l_addr_delete,    l_topology_change, 
-        l_flush_complete, l_arp_update,
-        l_narp_req, /* LANE2 mandates the use of this */
-        l_config,         l_flush_tran_id, 
-        l_set_lecid,      l_arp_xmt,
-        l_rdesc_arp_xmt,
-        l_associate_req,
-        l_should_bridge   /* should we bridge this MAC? */
+typedef enum {
+       l_set_mac_addr,
+       l_del_mac_addr,
+       l_svc_setup,
+       l_addr_delete,
+       l_topology_change,
+       l_flush_complete,
+       l_arp_update,
+       l_narp_req,             /* LANE2 mandates the use of this */
+       l_config,
+       l_flush_tran_id,
+       l_set_lecid,
+       l_arp_xmt,
+       l_rdesc_arp_xmt,
+       l_associate_req,
+       l_should_bridge         /* should we bridge this MAC? */
 } atmlec_msg_type;
 
 #define ATMLEC_MSG_TYPE_MAX l_should_bridge
 
 struct atmlec_config_msg {
-        unsigned int maximum_unknown_frame_count;
-        unsigned int max_unknown_frame_time;
-        unsigned short max_retry_count;
-        unsigned int aging_time;
-        unsigned int forward_delay_time;
-        unsigned int arp_response_time;
-        unsigned int flush_timeout;
-        unsigned int path_switching_delay;
-        unsigned int  lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */
-        int mtu;
-        int is_proxy;
+       unsigned int maximum_unknown_frame_count;
+       unsigned int max_unknown_frame_time;
+       unsigned short max_retry_count;
+       unsigned int aging_time;
+       unsigned int forward_delay_time;
+       unsigned int arp_response_time;
+       unsigned int flush_timeout;
+       unsigned int path_switching_delay;
+       unsigned int lane_version;      /* LANE2: 1 for LANEv1, 2 for LANEv2 */
+       int mtu;
+       int is_proxy;
 };
+
 struct atmlec_msg {
-        atmlec_msg_type type;
-        int             sizeoftlvs;        /* LANE2: if != 0, tlvs follow */ 
-        union {
-                struct {
-                        unsigned char mac_addr[ETH_ALEN];
-                        unsigned char atm_addr[ATM_ESA_LEN];
-                        unsigned int flag;/* Topology_change flag, 
-                                              remoteflag, permanent flag,
-                                              lecid, transaction id */
-                        unsigned int targetless_le_arp; /* LANE2 */
-                        unsigned int no_source_le_narp; /* LANE2 */
-                } normal;
-                struct atmlec_config_msg config;
-                struct {
-                        uint16_t lec_id;                     /* requestor lec_id  */
-                        uint32_t tran_id;                    /* transaction id    */
-                        unsigned char mac_addr[ETH_ALEN];    /* dst mac addr      */
-                        unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */
-                } proxy;
-                    /* For mapping LE_ARP requests to responses. Filled by */
-        } content;       /* zeppelin, returned by kernel. Used only when proxying */ 
+       atmlec_msg_type type;
+       int sizeoftlvs;         /* LANE2: if != 0, tlvs follow */
+       union {
+               struct {
+                       unsigned char mac_addr[ETH_ALEN];
+                       unsigned char atm_addr[ATM_ESA_LEN];
+                       unsigned int flag;      /*
+                                                * Topology_change flag,
+                                                * remoteflag, permanent flag,
+                                                * lecid, transaction id
+                                                */
+                       unsigned int targetless_le_arp; /* LANE2 */
+                       unsigned int no_source_le_narp; /* LANE2 */
+               } normal;
+               struct atmlec_config_msg config;
+               struct {
+                       uint16_t lec_id;                        /* requestor lec_id  */
+                       uint32_t tran_id;                       /* transaction id    */
+                       unsigned char mac_addr[ETH_ALEN];       /* dst mac addr      */
+                       unsigned char atm_addr[ATM_ESA_LEN];    /* reqestor ATM addr */
+               } proxy;        /*
+                                * For mapping LE_ARP requests to responses. Filled by
+                                * zeppelin, returned by kernel. Used only when proxying
+                                */
+       } content;
 } __ATM_API_ALIGN;
 
 struct atmlec_ioc {
-        int dev_num;
-        unsigned char atm_addr[ATM_ESA_LEN];
-        unsigned char receive;    /* 1= receive vcc, 0 = send vcc */
+       int dev_num;
+       unsigned char atm_addr[ATM_ESA_LEN];
+       unsigned char receive;  /* 1= receive vcc, 0 = send vcc */
 };
 #endif /* _ATMLEC_H_ */
index 40a6c26294ae9fda282d26f27b8f7c9cac622d30..c3aa097518144c14556fef3e9998dbd3e5a46c69 100644 (file)
 #define AUDIT_MAC_POLICY_LOAD  1403    /* Policy file load */
 #define AUDIT_MAC_STATUS       1404    /* Changed enforcing,permissive,off */
 #define AUDIT_MAC_CONFIG_CHANGE        1405    /* Changes to booleans */
+#define AUDIT_MAC_UNLBL_ALLOW  1406    /* NetLabel: allow unlabeled traffic */
+#define AUDIT_MAC_CIPSOV4_ADD  1407    /* NetLabel: add CIPSOv4 DOI entry */
+#define AUDIT_MAC_CIPSOV4_DEL  1408    /* NetLabel: del CIPSOv4 DOI entry */
+#define AUDIT_MAC_MAP_ADD      1409    /* NetLabel: add LSM domain mapping */
+#define AUDIT_MAC_MAP_DEL      1410    /* NetLabel: del LSM domain mapping */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
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 c773ee545ebd046a7256c3c13a44a1bb894760b2..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
@@ -417,9 +465,9 @@ struct request_queue
        unsigned int            sg_timeout;
        unsigned int            sg_reserved_size;
        int                     node;
-
+#ifdef CONFIG_BLK_DEV_IO_TRACE
        struct blk_trace        *blk_trace;
-
+#endif
        /*
         * reserved for flush operations
         */
@@ -432,9 +480,6 @@ struct request_queue
        struct mutex            sysfs_lock;
 };
 
-#define RQ_INACTIVE            (-1)
-#define RQ_ACTIVE              1
-
 #define QUEUE_FLAG_CLUSTER     0       /* cluster several segments into 1 */
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
 #define QUEUE_FLAG_STOPPED     2       /* queue is stopped */
@@ -490,25 +535,34 @@ enum {
 #define blk_queue_stopped(q)   test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_flushing(q)  ((q)->ordseq)
 
-#define blk_fs_request(rq)     ((rq)->flags & REQ_CMD)
-#define blk_pc_request(rq)     ((rq)->flags & REQ_BLOCK_PC)
-#define blk_noretry_request(rq)        ((rq)->flags & REQ_FAILFAST)
-#define blk_rq_started(rq)     ((rq)->flags & REQ_STARTED)
+#define blk_fs_request(rq)     ((rq)->cmd_type == REQ_TYPE_FS)
+#define blk_pc_request(rq)     ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
+#define blk_special_request(rq)        ((rq)->cmd_type == REQ_TYPE_SPECIAL)
+#define blk_sense_request(rq)  ((rq)->cmd_type == REQ_TYPE_SENSE)
+
+#define blk_noretry_request(rq)        ((rq)->cmd_flags & REQ_FAILFAST)
+#define blk_rq_started(rq)     ((rq)->cmd_flags & REQ_STARTED)
 
 #define blk_account_rq(rq)     (blk_rq_started(rq) && blk_fs_request(rq))
 
-#define blk_pm_suspend_request(rq)     ((rq)->flags & REQ_PM_SUSPEND)
-#define blk_pm_resume_request(rq)      ((rq)->flags & REQ_PM_RESUME)
+#define blk_pm_suspend_request(rq)     ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND)
+#define blk_pm_resume_request(rq)      ((rq)->cmd_type == REQ_TYPE_PM_RESUME)
 #define blk_pm_request(rq)     \
-       ((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+       (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq))
 
-#define blk_sorted_rq(rq)      ((rq)->flags & REQ_SORTED)
-#define blk_barrier_rq(rq)     ((rq)->flags & REQ_HARDBARRIER)
-#define blk_fua_rq(rq)         ((rq)->flags & REQ_FUA)
+#define blk_sorted_rq(rq)      ((rq)->cmd_flags & REQ_SORTED)
+#define blk_barrier_rq(rq)     ((rq)->cmd_flags & REQ_HARDBARRIER)
+#define blk_fua_rq(rq)         ((rq)->cmd_flags & REQ_FUA)
 
 #define list_entry_rq(ptr)     list_entry((ptr), struct request, queuelist)
 
-#define rq_data_dir(rq)                ((rq)->flags & 1)
+#define rq_data_dir(rq)                ((rq)->cmd_flags & 1)
+
+/*
+ * We regard a request as sync, if it's a READ or a SYNC write.
+ */
+#define rq_is_sync(rq)         (rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC)
+#define rq_is_meta(rq)         ((rq)->cmd_flags & REQ_RW_META)
 
 static inline int blk_queue_full(struct request_queue *q, int rw)
 {
@@ -541,13 +595,7 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw)
 #define RQ_NOMERGE_FLAGS       \
        (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
 #define rq_mergeable(rq)       \
-       (!((rq)->flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
-
-/*
- * noop, requests are automagically marked as active/inactive by I/O
- * scheduler -- see elv_next_request
- */
-#define blk_queue_headactive(q, head_active)
+       (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
 
 /*
  * q->prep_rq_fn return values
@@ -586,11 +634,6 @@ static inline void blk_queue_bounce(request_queue_t *q, struct bio **bio)
        if ((rq->bio))                  \
                for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next)
 
-struct sec_size {
-       unsigned block_size;
-       unsigned block_size_bits;
-};
-
 extern int blk_register_queue(struct gendisk *disk);
 extern void blk_unregister_queue(struct gendisk *disk);
 extern void register_disk(struct gendisk *dev);
@@ -612,6 +655,7 @@ extern void blk_stop_queue(request_queue_t *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(request_queue_t *q);
 extern void blk_run_queue(request_queue_t *);
+extern void blk_start_queueing(request_queue_t *);
 extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
 extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
 extern int blk_rq_unmap_user(struct bio *, unsigned int);
@@ -655,16 +699,6 @@ extern void end_that_request_last(struct request *, int);
 extern void end_request(struct request *req, int uptodate);
 extern void blk_complete_request(struct request *);
 
-static inline int rq_all_done(struct request *rq, unsigned int nr_bytes)
-{
-       if (blk_fs_request(rq))
-               return (nr_bytes >= (rq->hard_nr_sectors << 9));
-       else if (blk_pc_request(rq))
-               return nr_bytes >= rq->data_len;
-
-       return 0;
-}
-
 /*
  * end_that_request_first/chunk() takes an uptodate argument. we account
  * any value <= as an io error. 0 means -EIO for compatability reasons,
@@ -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 bea0255196c435c5c1ba986c7c9361034f36ad86..d61ef59515381310ccc2b1d1d7126e0a271ba4cc 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)
@@ -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 */
index 060b96112ec66fcfebcd6e8f5ea4c86f4bec5dde..0780de440220e43211f6f9a00cd3dc29ba77b290 100644 (file)
@@ -14,7 +14,7 @@
 # define __releases(x) __attribute__((context(1,0)))
 # define __acquire(x)  __context__(1)
 # define __release(x)  __context__(-1)
-# define __cond_lock(x)        ((x) ? ({ __context__(1); 1; }) : 0)
+# define __cond_lock(x,c)      ((c) ? ({ __acquire(x); 1; }) : 0)
 extern void __chk_user_ptr(void __user *);
 extern void __chk_io_ptr(void __iomem *);
 #else
@@ -31,7 +31,7 @@ extern void __chk_io_ptr(void __iomem *);
 # define __releases(x)
 # define __acquire(x) (void)0
 # define __release(x) (void)0
-# define __cond_lock(x) (x)
+# define __cond_lock(x,c) (c)
 #endif
 
 #ifdef __KERNEL__
index 9354722a9217807cb0d4d6a2d3e716a0db73bb25..4d8adf6636810875b00f070dd548193e620b7015 100644 (file)
@@ -63,6 +63,8 @@ static inline int cpuset_do_slab_mem_spread(void)
        return current->flags & PF_SPREAD_SLAB;
 }
 
+extern void cpuset_track_online_nodes(void);
+
 #else /* !CONFIG_CPUSETS */
 
 static inline int cpuset_init_early(void) { return 0; }
@@ -126,6 +128,8 @@ static inline int cpuset_do_slab_mem_spread(void)
        return 0;
 }
 
+static inline void cpuset_track_online_nodes(void) {}
+
 #endif /* !CONFIG_CPUSETS */
 
 #endif /* _LINUX_CPUSET_H */
index a41f38428c37d794ac80f947502c4142123a4afc..1dba681e428d27e1750652e94b9a84c080cb1b59 100644 (file)
@@ -87,6 +87,6 @@ struct cramfs_super {
 /* Uncompression interfaces to the underlying zlib */
 int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
 int cramfs_uncompress_init(void);
-int cramfs_uncompress_exit(void);
+void cramfs_uncompress_exit(void);
 
 #endif
index 635690cf3e3dc77ff54f8d07555da2ffc4dff165..ff203c465fed260f75de3c0d80a71e7d90f101d2 100644 (file)
@@ -24,6 +24,13 @@ enum dma_data_direction {
 #define DMA_28BIT_MASK 0x000000000fffffffULL
 #define DMA_24BIT_MASK 0x0000000000ffffffULL
 
+static inline int valid_dma_direction(int dma_direction)
+{
+       return ((dma_direction == DMA_BIDIRECTIONAL) ||
+               (dma_direction == DMA_TO_DEVICE) ||
+               (dma_direction == DMA_FROM_DEVICE));
+}
+
 #include <asm/dma-mapping.h>
 
 /* Backwards compat, remove in 2.7.x */
index b2cd2071d432d137b8d913134c21b0b93a920b25..38dc403be70b5bc4f49aee4132ba7ea85ca61399 100644 (file)
@@ -27,7 +27,8 @@ enum dmi_device_type {
        DMI_DEV_TYPE_ETHERNET,
        DMI_DEV_TYPE_TOKENRING,
        DMI_DEV_TYPE_SOUND,
-       DMI_DEV_TYPE_IPMI = -1
+       DMI_DEV_TYPE_IPMI = -1,
+       DMI_DEV_TYPE_OEM_STRING = -2
 };
 
 struct dmi_header {
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 408118a07763fecc3718d8dcc6569857d3aa52e4..92f8d4fab32be96bd86e29612b78c6a8cb1b952b 100644 (file)
@@ -38,7 +38,7 @@ struct sock_exterr_skb
        } header;
        struct sock_extended_err        ee;
        u16                             addr_offset;
-       u16                             port;
+       __be16                          port;
 };
 
 #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 9f7c2513866f4d1a857398711f09864239b7162c..74183e6f7f458052c72d0bf3e8297c83a32ff18c 100644 (file)
@@ -112,5 +112,6 @@ struct task_struct;
 
 struct files_struct *get_files_struct(struct task_struct *);
 void FASTCALL(put_files_struct(struct files_struct *fs));
+void reset_files_struct(struct task_struct *, struct files_struct *);
 
 #endif /* __LINUX_FILE_H */
index 8f74dfbb2edd256c312b5db9efdc33e4cbeb3cbd..5baf3a153403ce9ffe8975acc108203d9b5d0dc5 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
@@ -553,7 +592,9 @@ struct inode {
        unsigned int            i_flags;
 
        atomic_t                i_writecount;
+#ifdef CONFIG_SECURITY
        void                    *i_security;
+#endif
        void                    *i_private; /* fs or device private pointer */
 #ifdef __NEED_I_SIZE_ORDERED
        seqcount_t              i_size_seqcount;
@@ -645,7 +686,6 @@ struct fown_struct {
        rwlock_t lock;          /* protects pid, uid, euid fields */
        int pid;                /* pid or -pgrp where SIGIO should be sent */
        uid_t uid, euid;        /* uid/euid of process setting the owner */
-       void *security;
        int signum;             /* posix.1b rt signal to be delivered on IO */
 };
 
@@ -688,8 +728,9 @@ struct file {
        struct file_ra_state    f_ra;
 
        unsigned long           f_version;
+#ifdef CONFIG_SECURITY
        void                    *f_security;
-
+#endif
        /* needed for tty driver, and maybe others */
        void                    *private_data;
 
@@ -877,7 +918,9 @@ struct super_block {
        int                     s_syncing;
        int                     s_need_sync_fs;
        atomic_t                s_active;
+#ifdef CONFIG_SECURITY
        void                    *s_security;
+#endif
        struct xattr_handler    **s_xattr;
 
        struct list_head        s_inodes;       /* all inodes */
@@ -1143,9 +1186,10 @@ struct super_operations {
 
        int (*show_options)(struct seq_file *, struct vfsmount *);
        int (*show_stats)(struct seq_file *, struct vfsmount *);
-
+#ifdef CONFIG_QUOTA
        ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
        ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
+#endif
 };
 
 /* Inode state bits.  Protected by inode_lock. */
@@ -1438,6 +1482,7 @@ extern void __init vfs_caches_init(unsigned long);
 extern void putname(const char *name);
 #endif
 
+#ifdef CONFIG_BLOCK
 extern int register_blkdev(unsigned int, const char *);
 extern int unregister_blkdev(unsigned int, const char *);
 extern struct block_device *bdget(dev_t);
@@ -1446,11 +1491,15 @@ 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 long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
@@ -1466,6 +1515,7 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *);
 #define bd_claim_by_disk(bdev, holder, disk)   bd_claim(bdev, holder)
 #define bd_release_from_disk(bdev, disk)       bd_release(bdev)
 #endif
+#endif
 
 /* fs/char_dev.c */
 #define CHRDEV_MAJOR_HASH_SIZE 255
@@ -1479,14 +1529,19 @@ extern int chrdev_open(struct inode *, struct file *);
 extern void chrdev_show(struct seq_file *,off_t);
 
 /* fs/block_dev.c */
-#define BLKDEV_MAJOR_HASH_SIZE 255
 #define BDEVNAME_SIZE  32      /* Largest string for a blockdev identifier */
+
+#ifdef CONFIG_BLOCK
+#define BLKDEV_MAJOR_HASH_SIZE 255
 extern const char *__bdevname(dev_t, char *buffer);
 extern const char *bdevname(struct block_device *bdev, char *buffer);
 extern struct block_device *lookup_bdev(const char *);
 extern struct block_device *open_bdev_excl(const char *, int, void *);
 extern void close_bdev_excl(struct block_device *);
 extern void blkdev_show(struct seq_file *,off_t);
+#else
+#define BLKDEV_MAJOR_HASH_SIZE 0
+#endif
 
 extern void init_special_inode(struct inode *, umode_t, dev_t);
 
@@ -1500,6 +1555,7 @@ extern const struct file_operations rdwr_fifo_fops;
 
 extern int fs_may_remount_ro(struct super_block *);
 
+#ifdef CONFIG_BLOCK
 /*
  * return READ, READA, or WRITE
  */
@@ -1511,9 +1567,10 @@ extern int fs_may_remount_ro(struct super_block *);
 #define bio_data_dir(bio)      ((bio)->bi_rw & 1)
 
 extern int check_disk_change(struct block_device *);
-extern int invalidate_inodes(struct super_block *);
 extern int __invalidate_device(struct block_device *);
 extern int invalidate_partition(struct gendisk *, int);
+#endif
+extern int invalidate_inodes(struct super_block *);
 unsigned long invalidate_mapping_pages(struct address_space *mapping,
                                        pgoff_t start, pgoff_t end);
 unsigned long invalidate_inode_pages(struct address_space *mapping);
@@ -1541,11 +1598,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,
@@ -1628,9 +1688,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);
@@ -1711,6 +1773,7 @@ static inline void do_generic_file_read(struct file * filp, loff_t *ppos,
                                actor);
 }
 
+#ifdef CONFIG_BLOCK
 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        struct block_device *bdev, const struct iovec *iov, loff_t offset,
        unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
@@ -1748,6 +1811,7 @@ static inline ssize_t blockdev_direct_IO_own_locking(int rw, struct kiocb *iocb,
        return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
                                nr_segs, get_block, end_io, DIO_OWN_LOCKING);
 }
+#endif
 
 extern const struct file_operations generic_ro_fops;
 
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h
new file mode 100644 (file)
index 0000000..80764f4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * fs/generic_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef GENERIC_ACL_H
+#define GENERIC_ACL_H
+
+#include <linux/posix_acl.h>
+#include <linux/posix_acl_xattr.h>
+
+/**
+ * struct generic_acl_operations  -  filesystem operations
+ *
+ * Filesystems must make these operations available to the generic
+ * operations.
+ */
+struct generic_acl_operations {
+       struct posix_acl *(*getacl)(struct inode *, int);
+       void (*setacl)(struct inode *, int, struct posix_acl *);
+};
+
+size_t generic_acl_list(struct inode *, struct generic_acl_operations *, int,
+                       char *, size_t);
+int generic_acl_get(struct inode *, struct generic_acl_operations *, int,
+                   void *, size_t);
+int generic_acl_set(struct inode *, struct generic_acl_operations *, int,
+                   const void *, size_t);
+int generic_acl_init(struct inode *, struct inode *,
+                    struct generic_acl_operations *);
+int generic_acl_chmod(struct inode *, struct generic_acl_operations *);
+
+#endif
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 4fc379de6c2ffceea015fa9b80ba987cfc42742e..fca93025ab5191db9a1d4aeb9734dbfa2f574a20 100644 (file)
@@ -138,6 +138,7 @@ extern long hrtimer_nanosleep(struct timespec *rqtp,
                              struct timespec __user *rmtp,
                              const enum hrtimer_mode mode,
                              const clockid_t clockid);
+extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
 
 extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
                                 struct task_struct *tsk);
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 f0b571f1060ba23aa0542d1bc33943e2fbd0ef75..878cfe4e587f29d0d5dd3129180227bed8bf8990 100644 (file)
 struct icmphdr {
   __u8         type;
   __u8         code;
-  __u16                checksum;
+  __be16       checksum;
   union {
        struct {
-               __u16   id;
-               __u16   sequence;
+               __be16  id;
+               __be16  sequence;
        } echo;
-       __u32   gateway;
+       __be32  gateway;
        struct {
-               __u16   __unused;
-               __u16   mtu;
+               __be16  __unused;
+               __be16  mtu;
        } frag;
   } un;
 };
index 8018c2e22c0c3c6bdf237378cc18f15668eb89e4..32bf419351f184242dfd5af400dd1859f297282d 100644 (file)
@@ -214,134 +214,4 @@ struct ifconf
 #define        ifc_buf ifc_ifcu.ifcu_buf               /* buffer address       */
 #define        ifc_req ifc_ifcu.ifcu_req               /* array of structures  */
 
-/* The struct should be in sync with struct net_device_stats */
-struct rtnl_link_stats
-{
-       __u32   rx_packets;             /* total packets received       */
-       __u32   tx_packets;             /* total packets transmitted    */
-       __u32   rx_bytes;               /* total bytes received         */
-       __u32   tx_bytes;               /* total bytes transmitted      */
-       __u32   rx_errors;              /* bad packets received         */
-       __u32   tx_errors;              /* packet transmit problems     */
-       __u32   rx_dropped;             /* no space in linux buffers    */
-       __u32   tx_dropped;             /* no space available in linux  */
-       __u32   multicast;              /* multicast packets received   */
-       __u32   collisions;
-
-       /* detailed rx_errors: */
-       __u32   rx_length_errors;
-       __u32   rx_over_errors;         /* receiver ring buff overflow  */
-       __u32   rx_crc_errors;          /* recved pkt with crc error    */
-       __u32   rx_frame_errors;        /* recv'd frame alignment error */
-       __u32   rx_fifo_errors;         /* recv'r fifo overrun          */
-       __u32   rx_missed_errors;       /* receiver missed packet       */
-
-       /* detailed tx_errors */
-       __u32   tx_aborted_errors;
-       __u32   tx_carrier_errors;
-       __u32   tx_fifo_errors;
-       __u32   tx_heartbeat_errors;
-       __u32   tx_window_errors;
-
-       /* for cslip etc */
-       __u32   rx_compressed;
-       __u32   tx_compressed;
-};
-
-/* The struct should be in sync with struct ifmap */
-struct rtnl_link_ifmap
-{
-       __u64   mem_start;
-       __u64   mem_end;
-       __u64   base_addr;
-       __u16   irq;
-       __u8    dma;
-       __u8    port;
-};
-
-enum
-{
-       IFLA_UNSPEC,
-       IFLA_ADDRESS,
-       IFLA_BROADCAST,
-       IFLA_IFNAME,
-       IFLA_MTU,
-       IFLA_LINK,
-       IFLA_QDISC,
-       IFLA_STATS,
-       IFLA_COST,
-#define IFLA_COST IFLA_COST
-       IFLA_PRIORITY,
-#define IFLA_PRIORITY IFLA_PRIORITY
-       IFLA_MASTER,
-#define IFLA_MASTER IFLA_MASTER
-       IFLA_WIRELESS,          /* Wireless Extension event - see wireless.h */
-#define IFLA_WIRELESS IFLA_WIRELESS
-       IFLA_PROTINFO,          /* Protocol specific information for a link */
-#define IFLA_PROTINFO IFLA_PROTINFO
-       IFLA_TXQLEN,
-#define IFLA_TXQLEN IFLA_TXQLEN
-       IFLA_MAP,
-#define IFLA_MAP IFLA_MAP
-       IFLA_WEIGHT,
-#define IFLA_WEIGHT IFLA_WEIGHT
-       IFLA_OPERSTATE,
-       IFLA_LINKMODE,
-       __IFLA_MAX
-};
-
-
-#define IFLA_MAX (__IFLA_MAX - 1)
-
-/* ifi_flags.
-
-   IFF_* flags.
-
-   The only change is:
-   IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
-   more not changeable by user. They describe link media
-   characteristics and set by device driver.
-
-   Comments:
-   - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
-   - If neither of these three flags are set;
-     the interface is NBMA.
-
-   - IFF_MULTICAST does not mean anything special:
-   multicasts can be used on all not-NBMA links.
-   IFF_MULTICAST means that this media uses special encapsulation
-   for multicast frames. Apparently, all IFF_POINTOPOINT and
-   IFF_BROADCAST devices are able to use multicasts too.
- */
-
-/* IFLA_LINK.
-   For usual devices it is equal ifi_index.
-   If it is a "virtual interface" (f.e. tunnel), ifi_link
-   can point to real physical interface (f.e. for bandwidth calculations),
-   or maybe 0, what means, that real media is unknown (usual
-   for IPIP tunnels, when route to endpoint is allowed to change)
- */
-
-/* Subtype attributes for IFLA_PROTINFO */
-enum
-{
-       IFLA_INET6_UNSPEC,
-       IFLA_INET6_FLAGS,       /* link flags                   */
-       IFLA_INET6_CONF,        /* sysctl parameters            */
-       IFLA_INET6_STATS,       /* statistics                   */
-       IFLA_INET6_MCAST,       /* MC things. What of them?     */
-       IFLA_INET6_CACHEINFO,   /* time values and max reasm size */
-       __IFLA_INET6_MAX
-};
-
-#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-
-struct ifla_cacheinfo
-{
-       __u32   max_reasm_len;
-       __u32   tstamp;         /* ipv6InterfaceTable updated timestamp */
-       __u32   reachable_time;
-       __u32   retrans_time;
-};
-
 #endif /* _LINUX_IF_H */
index a8b1a2071838f70794fc7605b0b44f5def7f44d4..7f5714214ee35e787aa77dfbd3b8cf63d21ca620 100644 (file)
@@ -130,11 +130,11 @@ struct arpreq_old {
 
 struct arphdr
 {
-       unsigned short  ar_hrd;         /* format of hardware address   */
-       unsigned short  ar_pro;         /* format of protocol address   */
+       __be16          ar_hrd;         /* format of hardware address   */
+       __be16          ar_pro;         /* format of protocol address   */
        unsigned char   ar_hln;         /* length of hardware address   */
        unsigned char   ar_pln;         /* length of protocol address   */
-       unsigned short  ar_op;          /* ARP opcode (command)         */
+       __be16          ar_op;          /* ARP opcode (command)         */
 
 #if 0
         /*
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
new file mode 100644 (file)
index 0000000..e963a07
--- /dev/null
@@ -0,0 +1,136 @@
+#ifndef _LINUX_IF_LINK_H
+#define _LINUX_IF_LINK_H
+
+#include <linux/netlink.h>
+
+/* The struct should be in sync with struct net_device_stats */
+struct rtnl_link_stats
+{
+       __u32   rx_packets;             /* total packets received       */
+       __u32   tx_packets;             /* total packets transmitted    */
+       __u32   rx_bytes;               /* total bytes received         */
+       __u32   tx_bytes;               /* total bytes transmitted      */
+       __u32   rx_errors;              /* bad packets received         */
+       __u32   tx_errors;              /* packet transmit problems     */
+       __u32   rx_dropped;             /* no space in linux buffers    */
+       __u32   tx_dropped;             /* no space available in linux  */
+       __u32   multicast;              /* multicast packets received   */
+       __u32   collisions;
+
+       /* detailed rx_errors: */
+       __u32   rx_length_errors;
+       __u32   rx_over_errors;         /* receiver ring buff overflow  */
+       __u32   rx_crc_errors;          /* recved pkt with crc error    */
+       __u32   rx_frame_errors;        /* recv'd frame alignment error */
+       __u32   rx_fifo_errors;         /* recv'r fifo overrun          */
+       __u32   rx_missed_errors;       /* receiver missed packet       */
+
+       /* detailed tx_errors */
+       __u32   tx_aborted_errors;
+       __u32   tx_carrier_errors;
+       __u32   tx_fifo_errors;
+       __u32   tx_heartbeat_errors;
+       __u32   tx_window_errors;
+
+       /* for cslip etc */
+       __u32   rx_compressed;
+       __u32   tx_compressed;
+};
+
+/* The struct should be in sync with struct ifmap */
+struct rtnl_link_ifmap
+{
+       __u64   mem_start;
+       __u64   mem_end;
+       __u64   base_addr;
+       __u16   irq;
+       __u8    dma;
+       __u8    port;
+};
+
+enum
+{
+       IFLA_UNSPEC,
+       IFLA_ADDRESS,
+       IFLA_BROADCAST,
+       IFLA_IFNAME,
+       IFLA_MTU,
+       IFLA_LINK,
+       IFLA_QDISC,
+       IFLA_STATS,
+       IFLA_COST,
+#define IFLA_COST IFLA_COST
+       IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+       IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+       IFLA_WIRELESS,          /* Wireless Extension event - see wireless.h */
+#define IFLA_WIRELESS IFLA_WIRELESS
+       IFLA_PROTINFO,          /* Protocol specific information for a link */
+#define IFLA_PROTINFO IFLA_PROTINFO
+       IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+       IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+       IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+       IFLA_OPERSTATE,
+       IFLA_LINKMODE,
+       __IFLA_MAX
+};
+
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+/* ifi_flags.
+
+   IFF_* flags.
+
+   The only change is:
+   IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
+   more not changeable by user. They describe link media
+   characteristics and set by device driver.
+
+   Comments:
+   - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
+   - If neither of these three flags are set;
+     the interface is NBMA.
+
+   - IFF_MULTICAST does not mean anything special:
+   multicasts can be used on all not-NBMA links.
+   IFF_MULTICAST means that this media uses special encapsulation
+   for multicast frames. Apparently, all IFF_POINTOPOINT and
+   IFF_BROADCAST devices are able to use multicasts too.
+ */
+
+/* IFLA_LINK.
+   For usual devices it is equal ifi_index.
+   If it is a "virtual interface" (f.e. tunnel), ifi_link
+   can point to real physical interface (f.e. for bandwidth calculations),
+   or maybe 0, what means, that real media is unknown (usual
+   for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
+/* Subtype attributes for IFLA_PROTINFO */
+enum
+{
+       IFLA_INET6_UNSPEC,
+       IFLA_INET6_FLAGS,       /* link flags                   */
+       IFLA_INET6_CONF,        /* sysctl parameters            */
+       IFLA_INET6_STATS,       /* statistics                   */
+       IFLA_INET6_MCAST,       /* MC things. What of them?     */
+       IFLA_INET6_CACHEINFO,   /* time values and max reasm size */
+       __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+struct ifla_cacheinfo
+{
+       __u32   max_reasm_len;
+       __u32   tstamp;         /* ipv6InterfaceTable updated timestamp */
+       __u32   reachable_time;
+       __u32   retrans_time;
+};
+
+#endif /* _LINUX_IF_LINK_H */
index 899c3d4776f3dffc690274bd3dfb44224c6608ab..03f43e2893a4a6110c55bd50372aeee716e9d113 100644 (file)
@@ -30,8 +30,8 @@ struct igmphdr
 {
        __u8 type;
        __u8 code;              /* For newer IGMP */
-       __u16 csum;
-       __u32 group;
+       __be16 csum;
+       __be32 group;
 };
 
 /* V3 group record types [grec_type] */
@@ -45,25 +45,25 @@ struct igmphdr
 struct igmpv3_grec {
        __u8    grec_type;
        __u8    grec_auxwords;
-       __u16   grec_nsrcs;
-       __u32   grec_mca;
-       __u32   grec_src[0];
+       __be16  grec_nsrcs;
+       __be32  grec_mca;
+       __be32  grec_src[0];
 };
 
 struct igmpv3_report {
        __u8 type;
        __u8 resv1;
-       __u16 csum;
-       __u16 resv2;
-       __u16 ngrec;
+       __be16 csum;
+       __be16 resv2;
+       __be16 ngrec;
        struct igmpv3_grec grec[0];
 };
 
 struct igmpv3_query {
        __u8 type;
        __u8 code;
-       __u16 csum;
-       __u32 group;
+       __be16 csum;
+       __be32 group;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8 qrv:3,
             suppress:1,
@@ -76,8 +76,8 @@ struct igmpv3_query {
 #error "Please fix <asm/byteorder.h>"
 #endif
        __u8 qqic;
-       __u16 nsrcs;
-       __u32 srcs[0];
+       __be16 nsrcs;
+       __be32 srcs[0];
 };
 
 #define IGMP_HOST_MEMBERSHIP_QUERY     0x11    /* From RFC1112 */
@@ -136,11 +136,11 @@ struct ip_sf_socklist
 {
        unsigned int            sl_max;
        unsigned int            sl_count;
-       __u32                   sl_addr[0];
+       __be32                  sl_addr[0];
 };
 
 #define IP_SFLSIZE(count)      (sizeof(struct ip_sf_socklist) + \
-       (count) * sizeof(__u32))
+       (count) * sizeof(__be32))
 
 #define IP_SFBLOCK     10      /* allocate this many at once */
 
@@ -159,7 +159,7 @@ struct ip_mc_socklist
 struct ip_sf_list
 {
        struct ip_sf_list       *sf_next;
-       __u32                   sf_inaddr;
+       __be32                  sf_inaddr;
        unsigned long           sf_count[2];    /* include/exclude counts */
        unsigned char           sf_gsresp;      /* include in g & s response? */
        unsigned char           sf_oldin;       /* change state */
@@ -197,7 +197,7 @@ struct ip_mc_list
 #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
 #define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value)
 
-extern int ip_check_mc(struct in_device *dev, u32 mc_addr, u32 src_addr, u16 proto);
+extern int ip_check_mc(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto);
 extern int igmp_rcv(struct sk_buff *);
 extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
 extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
@@ -209,13 +209,13 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
                struct ip_msfilter __user *optval, int __user *optlen);
 extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
                struct group_filter __user *optval, int __user *optlen);
-extern int ip_mc_sf_allow(struct sock *sk, u32 local, u32 rmt, int dif);
+extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, int dif);
 extern void ip_mr_init(void);
 extern void ip_mc_init_dev(struct in_device *);
 extern void ip_mc_destroy_dev(struct in_device *);
 extern void ip_mc_up(struct in_device *);
 extern void ip_mc_down(struct in_device *);
-extern void ip_mc_dec_group(struct in_device *in_dev, u32 addr);
-extern void ip_mc_inc_group(struct in_device *in_dev, u32 addr);
+extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
+extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
 #endif
 #endif
index bcaca8399aed62006eb601272771dbfe7c997039..d79fc75fa7c2c3d86dbf0c38f1834bc437aa524a 100644 (file)
@@ -123,17 +123,17 @@ struct ip_mreqn
 };
 
 struct ip_mreq_source {
-       __u32           imr_multiaddr;
-       __u32           imr_interface;
-       __u32           imr_sourceaddr;
+       __be32          imr_multiaddr;
+       __be32          imr_interface;
+       __be32          imr_sourceaddr;
 };
 
 struct ip_msfilter {
-       __u32           imsf_multiaddr;
-       __u32           imsf_interface;
+       __be32          imsf_multiaddr;
+       __be32          imsf_interface;
        __u32           imsf_fmode;
        __u32           imsf_numsrc;
-       __u32           imsf_slist[1];
+       __be32          imsf_slist[1];
 };
 
 #define IP_MSFILTER_SIZE(numsrc) \
index d776829b443f57e52f24e0bb8b45909936f4fd48..9be6a4756f0b39fc6cb22b7c80e3da310b52f77f 100644 (file)
@@ -32,8 +32,8 @@ struct in6_addr
        union 
        {
                __u8            u6_addr8[16];
-               __u16           u6_addr16[8];
-               __u32           u6_addr32[4];
+               __be16          u6_addr16[8];
+               __be32          u6_addr32[4];
        } in6_u;
 #define s6_addr                        in6_u.u6_addr8
 #define s6_addr16              in6_u.u6_addr16
@@ -53,7 +53,7 @@ extern const struct in6_addr in6addr_loopback;
 
 struct sockaddr_in6 {
        unsigned short int      sin6_family;    /* AF_INET6 */
-       __u16                   sin6_port;      /* Transport layer port # */
+       __be16                  sin6_port;      /* Transport layer port # */
        __u32                   sin6_flowinfo;  /* IPv6 flow information */
        struct in6_addr         sin6_addr;      /* IPv6 address */
        __u32                   sin6_scope_id;  /* scope id (new in RFC2553) */
index a4606e5810e570ae28158f6b73839f81585b231f..6e8bc548635af6a2cb1a685158751ca437dff476 100644 (file)
@@ -9,10 +9,10 @@
 
 /* Socket identity */
 struct inet_diag_sockid {
-       __u16   idiag_sport;
-       __u16   idiag_dport;
-       __u32   idiag_src[4];
-       __u32   idiag_dst[4];
+       __be16  idiag_sport;
+       __be16  idiag_dport;
+       __be32  idiag_src[4];
+       __be32  idiag_dst[4];
        __u32   idiag_if;
        __u32   idiag_cookie[2];
 #define INET_DIAG_NOCOOKIE (~0U)
@@ -67,7 +67,7 @@ struct inet_diag_hostcond {
        __u8    family;
        __u8    prefix_len;
        int     port;
-       __u32   addr[0];
+       __be32  addr[0];
 };
 
 /* Base info structure. It contains socket identity (addrs/ports/cookie)
index 92297ff24e8525de2617dff728b3420a4649f66a..5a0ab04627bc19a0c6dfd364fe56e6927db57f33 100644 (file)
@@ -90,11 +90,11 @@ struct in_ifaddr
        struct in_ifaddr        *ifa_next;
        struct in_device        *ifa_dev;
        struct rcu_head         rcu_head;
-       u32                     ifa_local;
-       u32                     ifa_address;
-       u32                     ifa_mask;
-       u32                     ifa_broadcast;
-       u32                     ifa_anycast;
+       __be32                  ifa_local;
+       __be32                  ifa_address;
+       __be32                  ifa_mask;
+       __be32                  ifa_broadcast;
+       __be32                  ifa_anycast;
        unsigned char           ifa_scope;
        unsigned char           ifa_flags;
        unsigned char           ifa_prefixlen;
@@ -104,18 +104,18 @@ struct in_ifaddr
 extern int register_inetaddr_notifier(struct notifier_block *nb);
 extern int unregister_inetaddr_notifier(struct notifier_block *nb);
 
-extern struct net_device       *ip_dev_find(u32 addr);
-extern int             inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b);
+extern struct net_device       *ip_dev_find(__be32 addr);
+extern int             inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
 extern int             devinet_ioctl(unsigned int cmd, void __user *);
 extern void            devinet_init(void);
 extern struct in_device *inetdev_init(struct net_device *dev);
 extern struct in_device        *inetdev_by_index(int);
-extern u32             inet_select_addr(const struct net_device *dev, u32 dst, int scope);
-extern u32             inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope);
-extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask);
+extern __be32          inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
+extern __be32          inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
+extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
 extern void            inet_forward_change(void);
 
-static __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa)
+static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
 {
        return !((addr^ifa->ifa_address)&ifa->ifa_mask);
 }
@@ -183,7 +183,7 @@ static inline void in_dev_put(struct in_device *idev)
 
 #endif /* __KERNEL__ */
 
-static __inline__ __u32 inet_make_mask(int logmask)
+static __inline__ __be32 inet_make_mask(int logmask)
 {
        if (logmask)
                return htonl(~((1<<(32-logmask))-1));
index d5afee95fd435294f2ee894cd75a31b7cc96be7b..1f97e3d92639e75aaed86a8066518e2526fa1dee 100644 (file)
@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
 #endif
 }
 
+static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
+{
+       disable_irq_nosync(irq);
+#ifdef CONFIG_LOCKDEP
+       local_irq_save(*flags);
+#endif
+}
+
 static inline void disable_irq_lockdep(unsigned int irq)
 {
        disable_irq(irq);
@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq)
        enable_irq(irq);
 }
 
+static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
+{
+#ifdef CONFIG_LOCKDEP
+       local_irq_restore(*flags);
+#endif
+       enable_irq(irq);
+}
+
 /* IRQ wakeup (PM) control: */
 extern int set_irq_wake(unsigned int irq, unsigned int on);
 
index 2f4600146f833a509e3d7cac68b97013142c9e09..6b25d36fc54c481779a0d15b708e9bcca9c713a4 100644 (file)
@@ -96,7 +96,7 @@ struct iphdr {
        __be16  frag_off;
        __u8    ttl;
        __u8    protocol;
-       __u16   check;
+       __be16  check;
        __be32  saddr;
        __be32  daddr;
        /*The options start here. */
@@ -105,22 +105,22 @@ struct iphdr {
 struct ip_auth_hdr {
        __u8  nexthdr;
        __u8  hdrlen;           /* This one is measured in 32 bit units! */
-       __u16 reserved;
-       __u32 spi;
-       __u32 seq_no;           /* Sequence number */
+       __be16 reserved;
+       __be32 spi;
+       __be32 seq_no;          /* Sequence number */
        __u8  auth_data[0];     /* Variable len but >=4. Mind the 64 bit alignment! */
 };
 
 struct ip_esp_hdr {
-       __u32 spi;
-       __u32 seq_no;           /* Sequence number */
+       __be32 spi;
+       __be32 seq_no;          /* Sequence number */
        __u8  enc_data[0];      /* Variable len but >=8. Mind the 64 bit alignment! */
 };
 
 struct ip_comp_hdr {
        __u8 nexthdr;
        __u8 flags;
-       __u16 cpi;
+       __be16 cpi;
 };
 
 #endif /* _LINUX_IP_H */
index caca57df0d7d5f23039d961878dae5753e22718d..4f435c59de06775b5a1a5ba831ca3f0089006b80 100644 (file)
@@ -99,22 +99,22 @@ struct ipv6_destopt_hao {
 struct ipv6_auth_hdr {
        __u8  nexthdr;
        __u8  hdrlen;           /* This one is measured in 32 bit units! */
-       __u16 reserved;
-       __u32 spi;
-       __u32 seq_no;           /* Sequence number */
+       __be16 reserved;
+       __be32 spi;
+       __be32 seq_no;           /* Sequence number */
        __u8  auth_data[0];     /* Length variable but >=4. Mind the 64 bit alignment! */
 };
 
 struct ipv6_esp_hdr {
-       __u32 spi;
-       __u32 seq_no;           /* Sequence number */
+       __be32 spi;
+       __be32 seq_no;           /* Sequence number */
        __u8  enc_data[0];      /* Length variable but >=8. Mind the 64 bit alignment! */
 };
 
 struct ipv6_comp_hdr {
        __u8 nexthdr;
        __u8 flags;
-       __u16 cpi;
+       __be16 cpi;
 };
 
 /*
@@ -136,7 +136,7 @@ struct ipv6hdr {
 #endif
        __u8                    flow_lbl[3];
 
-       __u16                   payload_len;
+       __be16                  payload_len;
        __u8                    nexthdr;
        __u8                    hop_limit;
 
@@ -461,7 +461,7 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 
 #define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
        (((__sk)->sk_hash == (__hash))                          && \
-        ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports))   && \
+        ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      && \
         ((__sk)->sk_family             == AF_INET6)            && \
         ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))     && \
         ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
index a6d9daa38c6d4da99fa6f6bffe9b99a5c6c79ae0..fe89444b1c6f32145f4a0a02d1e8f13258e3f299 100644 (file)
@@ -977,7 +977,6 @@ extern void    journal_write_revoke_records(journal_t *, transaction_t *);
 extern int     journal_set_revoke(journal_t *, unsigned long, tid_t);
 extern int     journal_test_revoke(journal_t *, unsigned long, tid_t);
 extern void    journal_clear_revoke(journal_t *);
-extern void    journal_brelse_array(struct buffer_head *b[], int n);
 extern void    journal_switch_revoke_table(journal_t *journal);
 
 /*
index dc23c7c639f321f9bbb857d2176130c3316c4489..88afceffb7cb45df03ecbcd1045af2117f429fb1 100644 (file)
@@ -12,6 +12,9 @@
 #ifndef __LINUX_LEDS_H_INCLUDED
 #define __LINUX_LEDS_H_INCLUDED
 
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
 struct device;
 struct class_device;
 /*
index 65a5b5ceda4947d1478bba79abbda826963d128e..a9c90287c0ffef0509a6ed74719a39a7dcee28ba 100644 (file)
@@ -39,6 +39,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
  * This is only for internal list manipulation where we know
  * the prev/next entries already!
  */
+#ifndef CONFIG_DEBUG_LIST
 static inline void __list_add(struct list_head *new,
                              struct list_head *prev,
                              struct list_head *next)
@@ -48,6 +49,11 @@ static inline void __list_add(struct list_head *new,
        new->prev = prev;
        prev->next = new;
 }
+#else
+extern void __list_add(struct list_head *new,
+                             struct list_head *prev,
+                             struct list_head *next);
+#endif
 
 /**
  * list_add - add a new entry
@@ -57,10 +63,15 @@ static inline void __list_add(struct list_head *new,
  * Insert a new entry after the specified head.
  * This is good for implementing stacks.
  */
+#ifndef CONFIG_DEBUG_LIST
 static inline void list_add(struct list_head *new, struct list_head *head)
 {
        __list_add(new, head, head->next);
 }
+#else
+extern void list_add(struct list_head *new, struct list_head *head);
+#endif
+
 
 /**
  * list_add_tail - add a new entry
@@ -153,12 +164,16 @@ static inline void __list_del(struct list_head * prev, struct list_head * next)
  * Note: list_empty on entry does not return true after this, the entry is
  * in an undefined state.
  */
+#ifndef CONFIG_DEBUG_LIST
 static inline void list_del(struct list_head *entry)
 {
        __list_del(entry->prev, entry->next);
        entry->next = LIST_POISON1;
        entry->prev = LIST_POISON2;
 }
+#else
+extern void list_del(struct list_head *entry);
+#endif
 
 /**
  * list_del_rcu - deletes entry from list without re-initialization
index c040a8c969aa503d2904b88cb61921aac212496a..1314ca0f29be78f637f027614d09d5a062e091a2 100644 (file)
@@ -8,13 +8,13 @@
 #ifndef __LINUX_LOCKDEP_H
 #define __LINUX_LOCKDEP_H
 
+#ifdef CONFIG_LOCKDEP
+
 #include <linux/linkage.h>
 #include <linux/list.h>
 #include <linux/debug_locks.h>
 #include <linux/stacktrace.h>
 
-#ifdef CONFIG_LOCKDEP
-
 /*
  * Lock-class usage-state bits:
  */
index e76c7611d6cc56e115ad71a49aa25861cc2208f6..191a595055f0063db70032a2074d8addb5eb0ad9 100644 (file)
@@ -59,10 +59,9 @@ struct loop_device {
        struct bio              *lo_bio;
        struct bio              *lo_biotail;
        int                     lo_state;
-       struct completion       lo_done;
-       struct completion       lo_bh_done;
        struct mutex            lo_ctl_mutex;
-       int                     lo_pending;
+       struct task_struct      *lo_thread;
+       wait_queue_head_t       lo_event;
 
        request_queue_t         *lo_queue;
 };
index 7b703b6d43582dd918a1c8c397a2a3932accf72c..4edf1934e5cae2911ccf0b0917d7072fd6f672c4 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);
index ba095aebedffb67cf060fa2fc5e0c56c9483a05c..587264a58d5605835319bcfc77912e9763391128 100644 (file)
@@ -85,6 +85,8 @@ struct mmc_host {
        unsigned long           caps;           /* Host capabilities */
 
 #define MMC_CAP_4_BIT_DATA     (1 << 0)        /* Can the host do 4 bit transfers */
+#define MMC_CAP_MULTIWRITE     (1 << 1)        /* Can accurately report bytes sent to card on error */
+#define MMC_CAP_BYTEBLOCK      (1 << 2)        /* Can do non-log2 block sizes */
 
        /* host specific block data */
        unsigned int            max_seg_size;   /* see blk_queue_max_segment_size */
index 627e2c08ce41d3fe4851c346e061a046dd0dfc20..a3594dfd696399ae8609417cafdc1f0ca844272a 100644 (file)
@@ -68,7 +68,6 @@ struct mmc_command {
 struct mmc_data {
        unsigned int            timeout_ns;     /* data timeout (in ns, max 80ms) */
        unsigned int            timeout_clks;   /* data timeout (in clocks) */
-       unsigned int            blksz_bits;     /* data block size */
        unsigned int            blksz;          /* data block size */
        unsigned int            blocks;         /* number of blocks */
        unsigned int            error;          /* data error */
index d4486cc2e7fe6cdf822d95543610fddee2835185..2c599175c583c36a0bbd71528640489fceb6c149 100644 (file)
@@ -232,17 +232,17 @@ enum module_state
 };
 
 /* Similar stuff for section attributes. */
-#define MODULE_SECT_NAME_LEN 32
 struct module_sect_attr
 {
        struct module_attribute mattr;
-       char name[MODULE_SECT_NAME_LEN];
+       char *name;
        unsigned long address;
 };
 
 struct module_sect_attrs
 {
        struct attribute_group grp;
+       int nsections;
        struct module_sect_attr attrs[0];
 };
 
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 e05d54a90743e4890a99436c0616ad428142643c..7da2cee8e1328731ef3fccbcb011f2d9524be3b6 100644 (file)
@@ -142,7 +142,7 @@ struct vif_device
        unsigned long   rate_limit;             /* Traffic shaping (NI)         */
        unsigned char   threshold;              /* TTL threshold                */
        unsigned short  flags;                  /* Control flags                */
-       __u32           local,remote;           /* Addresses(remote for tunnels)*/
+       __be32          local,remote;           /* Addresses(remote for tunnels)*/
        int             link;                   /* Physical interface index     */
 };
 
@@ -151,8 +151,8 @@ struct vif_device
 struct mfc_cache 
 {
        struct mfc_cache *next;                 /* Next entry on cache line     */
-       __u32 mfc_mcastgrp;                     /* Group the entry belongs to   */
-       __u32 mfc_origin;                       /* Source of packet             */
+       __be32 mfc_mcastgrp;                    /* Group the entry belongs to   */
+       __be32 mfc_origin;                      /* Source of packet             */
        vifi_t mfc_parent;                      /* Source interface             */
        int mfc_flags;                          /* Flags on line                */
 
@@ -179,9 +179,9 @@ struct mfc_cache
 #define MFC_LINES              64
 
 #ifdef __BIG_ENDIAN
-#define MFC_HASH(a,b)  ((((a)>>24)^((b)>>26))&(MFC_LINES-1))
+#define MFC_HASH(a,b)  (((((__force u32)(__be32)a)>>24)^(((__force u32)(__be32)b)>>26))&(MFC_LINES-1))
 #else
-#define MFC_HASH(a,b)  (((a)^((b)>>2))&(MFC_LINES-1))
+#define MFC_HASH(a,b)  ((((__force u32)(__be32)a)^(((__force u32)(__be32)b)>>2))&(MFC_LINES-1))
 #endif         
 
 #endif
@@ -213,8 +213,8 @@ struct pimreghdr
 {
        __u8    type;
        __u8    reserved;
-       __u16   csum;
-       __u32   flags;
+       __be16  csum;
+       __be32  flags;
 };
 
 extern int pim_rcv_v1(struct sk_buff *);
index bae62d62dc3e07e44b54d54c272f74d28c744c77..ce6c85815cbd17be44e95f9244c84bbc7c5f3b4b 100644 (file)
@@ -204,6 +204,7 @@ struct fat_mount_options {
                 unicode_xlate:1, /* create escape sequences for unhandled Unicode */
                 numtail:1,       /* Does first alias have a numeric '~1' type tail? */
                 atari:1,         /* Use Atari GEMDOS variation of MS-DOS fs */
+                flush:1,         /* write things quickly */
                 nocase:1;        /* Does this need case conversion? 0=need case conversion*/
 };
 
@@ -412,6 +413,8 @@ extern int fat_sync_inode(struct inode *inode);
 extern int fat_fill_super(struct super_block *sb, void *data, int silent,
                        struct inode_operations *fs_dir_inode_ops, int isvfat);
 
+extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
+                           struct inode *i2);
 /* fat/misc.c */
 extern void fat_fs_panic(struct super_block *s, const char *fmt, ...);
 extern void fat_clusters_flush(struct super_block *sb);
index 45511a5918d3edf6be65188c3b1c64ab650da1e8..c6470ba006680a3d97191f7baf62c73bd3b0c96b 100644 (file)
@@ -54,6 +54,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 #define LOOKUP_OPEN            (0x0100)
 #define LOOKUP_CREATE          (0x0200)
 #define LOOKUP_ACCESS          (0x0400)
+#define LOOKUP_CHDIR           (0x0800)
 
 extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
 extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
index 13d6d4eb8b3af70b008be76f6fcf3fc23dc602cb..9264139bd8df0ee171c2d52531fa626720c42a1f 100644 (file)
@@ -187,7 +187,7 @@ struct hh_cache
 {
        struct hh_cache *hh_next;       /* Next entry                        */
        atomic_t        hh_refcnt;      /* number of users                   */
-       unsigned short  hh_type;        /* protocol identifier, f.e ETH_P_IP
+       __be16          hh_type;        /* protocol identifier, f.e ETH_P_IP
                                          *  NOTE:  For VLANs, this will be the
                                          *  encapuslated type. --BLG
                                          */
index 149e87c9ab1367cd95e5f058a40427f2167303f5..44e39b61d9e7e3b11e4b3e863204b4a89bb8cd1b 100644 (file)
@@ -46,11 +46,11 @@ struct arpt_arp {
        struct arpt_devaddr_info tgt_devaddr;
 
        /* ARP operation code. */
-       u_int16_t arpop, arpop_mask;
+       __be16 arpop, arpop_mask;
 
        /* ARP hardware address and protocol address format. */
-       u_int16_t arhrd, arhrd_mask;
-       u_int16_t arpro, arpro_mask;
+       __be16 arhrd, arhrd_mask;
+       __be16 arpro, arpro_mask;
 
        /* The protocol address length is only accepted if it is 4
         * so there is no use in offering a way to do filtering on it.
index 51dbec1892c802c3d313c3593fb0d2967a90ad2e..64e868034c4ab5868f3e2894194a39814bc66993 100644 (file)
@@ -157,7 +157,7 @@ struct ip_conntrack_expect
        unsigned int flags;
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
-       u_int32_t saved_ip;
+       __be32 saved_ip;
        /* This is the original per-proto part, used to map the
         * expected connection the way the recipient expects. */
        union ip_conntrack_manip_proto saved_proto;
index 3cbff7379002ced59a07d65ab88587767df8b59e..943cc6a4871d172d96ffc19f622ae5edc226c32f 100644 (file)
@@ -30,7 +30,7 @@ struct ip_ct_h323_master {
 struct ip_conntrack_expect;
 
 extern int get_h225_addr(unsigned char *data, TransportAddress * addr,
-                        u_int32_t * ip, u_int16_t * port);
+                        __be32 * ip, u_int16_t * port);
 extern void ip_conntrack_h245_expect(struct ip_conntrack *new,
                                     struct ip_conntrack_expect *this);
 extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
@@ -38,11 +38,11 @@ extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
 extern int (*set_h245_addr_hook) (struct sk_buff ** pskb,
                                  unsigned char **data, int dataoff,
                                  H245_TransportAddress * addr,
-                                 u_int32_t ip, u_int16_t port);
+                                 __be32 ip, u_int16_t port);
 extern int (*set_h225_addr_hook) (struct sk_buff ** pskb,
                                  unsigned char **data, int dataoff,
                                  TransportAddress * addr,
-                                 u_int32_t ip, u_int16_t port);
+                                 __be32 ip, u_int16_t port);
 extern int (*set_sig_addr_hook) (struct sk_buff ** pskb,
                                 struct ip_conntrack * ct,
                                 enum ip_conntrack_info ctinfo,
index 2fdabdb4c0ef5d0395cab5dc55d75eff1b378dd1..c228bde74c3325c0d26f3319297a63c36f1792dd 100644 (file)
@@ -23,13 +23,13 @@ union ip_conntrack_manip_proto
                __be16 port;
        } tcp;
        struct {
-               u_int16_t port;
+               __be16 port;
        } udp;
        struct {
-               u_int16_t id;
+               __be16 id;
        } icmp;
        struct {
-               u_int16_t port;
+               __be16 port;
        } sctp;
        struct {
                __be16 key;     /* key is 32bit, pptp only uses 16 */
@@ -39,7 +39,7 @@ union ip_conntrack_manip_proto
 /* The manipulable part of the tuple. */
 struct ip_conntrack_manip
 {
-       u_int32_t ip;
+       __be32 ip;
        union ip_conntrack_manip_proto u;
 };
 
@@ -50,22 +50,22 @@ struct ip_conntrack_tuple
 
        /* These are the parts of the tuple which are fixed. */
        struct {
-               u_int32_t ip;
+               __be32 ip;
                union {
                        /* Add other protocols here. */
                        u_int16_t all;
 
                        struct {
-                               u_int16_t port;
+                               __be16 port;
                        } tcp;
                        struct {
-                               u_int16_t port;
+                               __be16 port;
                        } udp;
                        struct {
                                u_int8_t type, code;
                        } icmp;
                        struct {
-                               u_int16_t port;
+                               __be16 port;
                        } sctp;
                        struct {
                                __be16 key;     /* key is 32bit, 
index 98f8407e4cb5011f0d343f241cc4b4741e56962b..bdf553620ca188ddbc53695d14d0389dd386d716 100644 (file)
@@ -33,7 +33,7 @@ struct ip_nat_range
        unsigned int flags;
 
        /* Inclusive: network order. */
-       u_int32_t min_ip, max_ip;
+       __be32 min_ip, max_ip;
 
        /* Inclusive: network order */
        union ip_conntrack_manip_proto min, max;
index aa08d68c4841ebdf265a99494bc9a88933f5d815..a03507f465f8e8be148f1accd413ca4373ff69e7 100644 (file)
@@ -26,7 +26,7 @@ typedef struct ipq_packet_msg {
        unsigned int hook;              /* Netfilter hook we rode in on */
        char indev_name[IFNAMSIZ];      /* Name of incoming interface */
        char outdev_name[IFNAMSIZ];     /* Name of outgoing interface */
-       unsigned short hw_protocol;     /* Hardware protocol (network order) */
+       __be16 hw_protocol;             /* Hardware protocol (network order) */
        unsigned short hw_type;         /* Hardware type */
        unsigned char hw_addrlen;       /* Hardware address length */
        unsigned char hw_addr[8];       /* Hardware address */
index 3ecb3bd63676a118de24f0e7616dfa1f27e0c2ef..34ab0fb736e2f75d057ea3c6e2bd1d9a65410eaf 100644 (file)
@@ -8,7 +8,7 @@
 
 struct ipt_iprange {
        /* Inclusive: network order. */
-       u_int32_t min_ip, max_ip;
+       __be32 min_ip, max_ip;
 };
 
 struct ipt_iprange_info
index c8f4d2f627d70099019f2e423cb8aec909d48034..e16904e28c3a39b57480d5bc5e64f5923cc5434a 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef LINUX_NMI_H
 #define LINUX_NMI_H
 
+#include <linux/sched.h>
 #include <asm/irq.h>
 
 /**
@@ -16,7 +17,7 @@
 #ifdef ARCH_HAS_NMI_WATCHDOG
 extern void touch_nmi_watchdog(void);
 #else
-# define touch_nmi_watchdog() do { } while(0)
+# define touch_nmi_watchdog() touch_softlockup_watchdog()
 #endif
 
 #endif
index 9d7921dd50f0c19a3d500d4aeb8bc64a7d8242b9..4830a3bedfb240480e1ade7c58d030b0ab12e978 100644 (file)
 
 #define PageUptodate(page)     test_bit(PG_uptodate, &(page)->flags)
 #ifdef CONFIG_S390
-#define SetPageUptodate(_page) \
-       do {                                                                  \
-               struct page *__page = (_page);                                \
-               if (!test_and_set_bit(PG_uptodate, &__page->flags))           \
-                       page_test_and_clear_dirty(_page);                     \
-       } while (0)
+static inline void SetPageUptodate(struct page *page)
+{
+       if (!test_and_set_bit(PG_uptodate, &page->flags))
+               page_test_and_clear_dirty(page);
+}
 #else
 #define SetPageUptodate(page)  set_bit(PG_uptodate, &(page)->flags)
 #endif
index ab032ceafa84cfab770bbba5a4c8080c6dd12c4f..c9ffbc3843d57894d44474bf841664203d60091a 100644 (file)
 
 #define PCI_VENDOR_ID_AMD              0x1022
 #define PCI_DEVICE_ID_AMD_K8_NB                0x1100
+#define PCI_DEVICE_ID_AMD_K8_NB_MISC   0x1103
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME   0x2001
 #define PCI_DEVICE_ID_AMD_SCSI         0x2020
 #define PCI_DEVICE_ID_AMD_8151_0       0x7454
 #define PCI_DEVICE_ID_AMD_8131_BRIDGE  0x7450
 #define PCI_DEVICE_ID_AMD_8131_APIC    0x7451
+#define PCI_DEVICE_ID_AMD_8132_BRIDGE  0x7458
 #define PCI_DEVICE_ID_AMD_CS5536_ISA    0x2090
 #define PCI_DEVICE_ID_AMD_CS5536_FLASH  0x2091
 #define PCI_DEVICE_ID_AMD_CS5536_AUDIO  0x2093
 #define PCI_DEVICE_ID_TIGON3_5705_2    0x1654
 #define PCI_DEVICE_ID_TIGON3_5720      0x1658
 #define PCI_DEVICE_ID_TIGON3_5721      0x1659
+#define PCI_DEVICE_ID_TIGON3_5722      0x165a
 #define PCI_DEVICE_ID_TIGON3_5705M     0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2   0x165e
 #define PCI_DEVICE_ID_TIGON3_5714      0x1668
 #define PCI_DEVICE_ID_TIGON3_5705F     0x166e
 #define PCI_DEVICE_ID_TIGON3_5754M     0x1672
 #define PCI_DEVICE_ID_TIGON3_5755M     0x1673
+#define PCI_DEVICE_ID_TIGON3_5756      0x1674
 #define PCI_DEVICE_ID_TIGON3_5750      0x1676
 #define PCI_DEVICE_ID_TIGON3_5751      0x1677
 #define PCI_DEVICE_ID_TIGON3_5715      0x1678
 #define PCI_DEVICE_ID_TIGON3_5901      0x170d
 #define PCI_DEVICE_ID_BCM4401B1                0x170c
 #define PCI_DEVICE_ID_TIGON3_5901_2    0x170e
+#define PCI_DEVICE_ID_TIGON3_5906      0x1712
+#define PCI_DEVICE_ID_TIGON3_5906M     0x1713
 #define PCI_DEVICE_ID_BCM4401          0x4401
 #define PCI_DEVICE_ID_BCM4401B0                0x4402
 
index 3835a9642f13f3702d31b6dfd3202dd96c194407..46ec72fa2c8435db3e9d8bd17605916aff3b5e54 100644 (file)
@@ -74,7 +74,7 @@ static inline int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp,
        return 0;
 }
 
-static inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask)
+static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask)
 {
        return kzalloc(size, gfp);
 }
index 95572c434bc991dc23dd5b9074d3bb36bd69b192..a7dd38f30ade61d1cf6fba16d7f7f60b3e8cc944 100644 (file)
@@ -72,6 +72,7 @@ struct k_clock {
        int (*timer_create) (struct k_itimer *timer);
        int (*nsleep) (const clockid_t which_clock, int flags,
                       struct timespec *, struct timespec __user *);
+       long (*nsleep_restart) (struct restart_block *restart_block);
        int (*timer_set) (struct k_itimer * timr, int flags,
                          struct itimerspec * new_setting,
                          struct itimerspec * old_setting);
@@ -97,6 +98,7 @@ int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
 int posix_cpu_timer_create(struct k_itimer *timer);
 int posix_cpu_nsleep(const clockid_t which_clock, int flags,
                     struct timespec *rqtp, struct timespec __user *rmtp);
+long posix_cpu_nsleep_restart(struct restart_block *restart_block);
 int posix_cpu_timer_set(struct k_itimer *timer, int flags,
                        struct itimerspec *new, struct itimerspec *old);
 int posix_cpu_timer_del(struct k_itimer *timer);
@@ -111,4 +113,6 @@ void posix_cpu_timers_exit_group(struct task_struct *task);
 void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
                           cputime_t *newval, cputime_t *oldval);
 
+long clock_nanosleep_restart(struct restart_block *restart_block);
+
 #endif
index 8b2749a259dc0a040194b8c353c2e3a56ce7136a..eeb1976ef7bf2069a587c4a042624599c0c59099 100644 (file)
@@ -16,8 +16,8 @@
 #define PTRACE_KILL               8
 #define PTRACE_SINGLESTEP         9
 
-#define PTRACE_ATTACH          0x10
-#define PTRACE_DETACH          0x11
+#define PTRACE_ATTACH            16
+#define PTRACE_DETACH            17
 
 #define PTRACE_SYSCALL           24
 
index eb3e547c8fee37798521949cc4f341df352a6d6d..c588709acbbc90b868681dda826605fa14afb0a5 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.
@@ -95,5 +97,6 @@ extern void md_new_event(mddev_t *mddev);
 
 extern void md_update_sb(mddev_t * mddev);
 
+#endif /* CONFIG_MD */
 #endif 
 
index d28890295852ce4f9be9f6bf0c6529f7b81041e6..920b94fe31fa2ed5184f8cdb4d41683efeeb15f4 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)
@@ -362,5 +364,6 @@ static inline void safe_put_page(struct page *p)
        if (p) put_page(p);
 }
 
+#endif /* CONFIG_BLOCK */
 #endif
 
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 806ec5b067075554792d5631996b24595157d697..fe00f781a622ab73a2230414a09b4e6fe6df96ae 100644 (file)
@@ -56,6 +56,16 @@ extern int reiserfs_xattr_posix_acl_init(void) __init;
 extern int reiserfs_xattr_posix_acl_exit(void);
 extern struct reiserfs_xattr_handler posix_acl_default_handler;
 extern struct reiserfs_xattr_handler posix_acl_access_handler;
+
+static inline void reiserfs_init_acl_access(struct inode *inode)
+{
+       REISERFS_I(inode)->i_acl_access = NULL;
+}
+
+static inline void reiserfs_init_acl_default(struct inode *inode)
+{
+       REISERFS_I(inode)->i_acl_default = NULL;
+}
 #else
 
 #define reiserfs_cache_default_acl(inode) 0
@@ -87,4 +97,11 @@ reiserfs_inherit_default_acl(const struct inode *dir, struct dentry *dentry,
        return 0;
 }
 
+static inline void reiserfs_init_acl_access(struct inode *inode)
+{
+}
+
+static inline void reiserfs_init_acl_default(struct inode *inode)
+{
+}
 #endif
index 28493ffaafe7b26e1dfec49fab09333658702d3e..9c63abffd7b298fec7ca9431a73ac328415da264 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 |        \
@@ -2163,15 +2161,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 149be8d9a0c9fe200f59ff809e8005b3ecca3ebc..5b3b297aa2c5b647294e69ac0090cef6c0deeb16 100644 (file)
@@ -52,10 +52,13 @@ struct reiserfs_inode_info {
         ** flushed */
        unsigned long i_trans_id;
        struct reiserfs_journal_list *i_jl;
-
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
        struct posix_acl *i_acl_access;
        struct posix_acl *i_acl_default;
+#endif
+#ifdef CONFIG_REISERFS_FS_XATTR
        struct rw_semaphore xattr_sem;
+#endif
        struct inode vfs_inode;
 };
 
index 5e961035c72576052cec535a48faf0814719f809..966c35851b2e784a445bac96e1458554ab8784de 100644 (file)
@@ -97,6 +97,11 @@ static inline void reiserfs_mark_inode_private(struct inode *inode)
        inode->i_flags |= S_PRIVATE;
 }
 
+static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
+{
+       init_rwsem(&REISERFS_I(inode)->xattr_sem);
+}
+
 #else
 
 #define is_reiserfs_priv_object(inode) 0
@@ -129,6 +134,9 @@ static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags)
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL);     /* to be sure */
        return 0;
 };
+static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
+{
+}
 #endif
 
 #endif                         /* __KERNEL__ */
index 9c92dc8b9a082616c4bc6622e87ca0176a622b8e..3a18addaed4ccb7436bffc9cf5fd0666f145d35c 100644 (file)
@@ -2,7 +2,7 @@
 #define __LINUX_RTNETLINK_H
 
 #include <linux/netlink.h>
-#include <linux/if.h>
+#include <linux/if_link.h>
 
 /****
  *             Routing/neighbour discovery messages.
index 9d4aa7f95bc8a9172b021f5d1c5137290f51c336..fc4a9873ec10fb5cdb603671fc0d266f9ecd1646 100644 (file)
@@ -148,6 +148,7 @@ extern unsigned long weighted_cpuload(const int cpu);
 #define EXIT_DEAD              32
 /* in tsk->state again */
 #define TASK_NONINTERACTIVE    64
+#define TASK_DEAD              128
 
 #define __set_task_state(tsk, state_value)             \
        do { (tsk)->state = (state_value); } while (0)
@@ -504,8 +505,8 @@ struct signal_struct {
 #define rt_prio(prio)          unlikely((prio) < MAX_RT_PRIO)
 #define rt_task(p)             rt_prio((p)->prio)
 #define batch_task(p)          (unlikely((p)->policy == SCHED_BATCH))
-#define has_rt_policy(p) \
-       unlikely((p)->policy != SCHED_NORMAL && (p)->policy != SCHED_BATCH)
+#define is_rt_policy(p)                ((p) != SCHED_NORMAL && (p) != SCHED_BATCH)
+#define has_rt_policy(p)       unlikely(is_rt_policy((p)->policy))
 
 /*
  * Some day this will be a full-fledged user tracking system..
@@ -709,7 +710,6 @@ extern unsigned int max_cache_size;
 
 
 struct io_context;                     /* See blkdev.h */
-void exit_io_context(void);
 struct cpuset;
 
 #define NGROUPS_SMALL          32
@@ -784,8 +784,9 @@ struct task_struct {
        struct prio_array *array;
 
        unsigned short ioprio;
+#ifdef CONFIG_BLK_DEV_IO_TRACE
        unsigned int btrace_seq;
-
+#endif
        unsigned long sleep_avg;
        unsigned long long timestamp, last_ran;
        unsigned long long sched_time; /* sched_clock time spent running */
@@ -886,8 +887,10 @@ struct task_struct {
                                     - initialized normally by flush_old_exec */
 /* file system info */
        int link_count, total_link_count;
+#ifdef CONFIG_SYSVIPC
 /* ipc stuff */
        struct sysv_sem sysvsem;
+#endif
 /* CPU-specific state of this task */
        struct thread_struct thread;
 /* filesystem information */
@@ -1030,6 +1033,16 @@ static inline int pid_alive(struct task_struct *p)
        return p->pids[PIDTYPE_PID].pid != NULL;
 }
 
+/**
+ * is_init - check if a task structure is the first user space
+ *          task the kernel created.
+ * @p: Task structure to be checked.
+ */
+static inline int is_init(struct task_struct *tsk)
+{
+       return tsk->pid == 1;
+}
+
 extern void free_task(struct task_struct *tsk);
 #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
 
@@ -1048,7 +1061,6 @@ static inline void put_task_struct(struct task_struct *t)
                                        /* Not implemented yet, only for 486*/
 #define PF_STARTING    0x00000002      /* being created */
 #define PF_EXITING     0x00000004      /* getting shut down */
-#define PF_DEAD                0x00000008      /* Dead */
 #define PF_FORKNOEXEC  0x00000040      /* forked but didn't exec */
 #define PF_SUPERPRIV   0x00000100      /* used super-user privileges */
 #define PF_DUMPCORE    0x00000200      /* dumped core */
@@ -1193,7 +1205,7 @@ extern void switch_uid(struct user_struct *);
 
 #include <asm/current.h>
 
-extern void do_timer(struct pt_regs *);
+extern void do_timer(unsigned long ticks);
 
 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
index 90dd069cc145c4b26a6fefe020aacee17d28aa65..1a82d30c4b17eea493a8f1ff3fd6c293d48dc434 100644 (file)
@@ -4,6 +4,7 @@ u32 scx200_gpio_configure(unsigned index, u32 set, u32 clear);
 
 extern unsigned scx200_gpio_base;
 extern long scx200_gpio_shadow[2];
+extern struct nsc_gpio_ops scx200_gpio_ops;
 
 #define scx200_gpio_present() (scx200_gpio_base!=0)
 
index 9f56fb8a4a6c358091915aa34e5fae8c045a585d..9b5fea81f55e4e96dfdca7fb83a3ecd0834c2137 100644 (file)
@@ -1595,6 +1595,7 @@ static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
 
 static inline int security_inode_alloc (struct inode *inode)
 {
+       inode->i_security = NULL;
        return security_ops->inode_alloc_security (inode);
 }
 
index c057f0b32318bdc40ea879086805e174db29c035..f3c51899117f5e83abb3a44c5b94ff11574df382 100644 (file)
@@ -19,6 +19,10 @@ struct shmem_inode_info {
        swp_entry_t             i_direct[SHMEM_NR_DIRECT]; /* first blocks */
        struct list_head        swaplist;       /* chain of maybes on swap */
        struct inode            vfs_inode;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       struct posix_acl        *i_acl;
+       struct posix_acl        *i_default_acl;
+#endif
 };
 
 struct shmem_sb_info {
@@ -36,4 +40,24 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
        return container_of(inode, struct shmem_inode_info, vfs_inode);
 }
 
+#ifdef CONFIG_TMPFS_POSIX_ACL
+int shmem_permission(struct inode *, int, struct nameidata *);
+int shmem_acl_init(struct inode *, struct inode *);
+void shmem_acl_destroy_inode(struct inode *);
+
+extern struct xattr_handler shmem_xattr_acl_access_handler;
+extern struct xattr_handler shmem_xattr_acl_default_handler;
+
+extern struct generic_acl_operations shmem_acl_ops;
+
+#else
+static inline int shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+       return 0;
+}
+static inline void shmem_acl_destroy_inode(struct inode *inode)
+{
+}
+#endif  /* CONFIG_TMPFS_POSIX_ACL */
+
 #endif
index 31473db92d3b68f81663687a55ef9521a19ccdc8..b800d2d68b325d139af36320db55e7d9db1d26f1 100644 (file)
@@ -167,9 +167,9 @@ do {                                                                \
  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
  * methods are defined as nops in the case they are not required.
  */
-#define spin_trylock(lock)             __cond_lock(_spin_trylock(lock))
-#define read_trylock(lock)             __cond_lock(_read_trylock(lock))
-#define write_trylock(lock)            __cond_lock(_write_trylock(lock))
+#define spin_trylock(lock)             __cond_lock(lock, _spin_trylock(lock))
+#define read_trylock(lock)             __cond_lock(lock, _read_trylock(lock))
+#define write_trylock(lock)            __cond_lock(lock, _write_trylock(lock))
 
 #define spin_lock(lock)                        _spin_lock(lock)
 
@@ -236,19 +236,19 @@ do {                                                              \
                                        _write_unlock_irqrestore(lock, flags)
 #define write_unlock_bh(lock)          _write_unlock_bh(lock)
 
-#define spin_trylock_bh(lock)          __cond_lock(_spin_trylock_bh(lock))
+#define spin_trylock_bh(lock)  __cond_lock(lock, _spin_trylock_bh(lock))
 
 #define spin_trylock_irq(lock) \
 ({ \
        local_irq_disable(); \
-       _spin_trylock(lock) ? \
+       spin_trylock(lock) ? \
        1 : ({ local_irq_enable(); 0;  }); \
 })
 
 #define spin_trylock_irqsave(lock, flags) \
 ({ \
        local_irq_save(flags); \
-       _spin_trylock(lock) ? \
+       spin_trylock(lock) ? \
        1 : ({ local_irq_restore(flags); 0; }); \
 })
 
@@ -264,7 +264,7 @@ do {                                                                \
  */
 extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #define atomic_dec_and_lock(atomic, lock) \
-               __cond_lock(_atomic_dec_and_lock(atomic, lock))
+               __cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
 
 /**
  * spin_can_lock - would spin_trylock() succeed?
index b2c4f8299464e86558b2721823bd0723da5f1ea3..8828b8155e9c11db7abb99c8342b7ee66d8e6839 100644 (file)
@@ -19,41 +19,41 @@ int in_lock_functions(unsigned long addr);
 
 #define assert_spin_locked(x)  BUG_ON(!spin_is_locked(x))
 
-void __lockfunc _spin_lock(spinlock_t *lock)           __acquires(spinlock_t);
+void __lockfunc _spin_lock(spinlock_t *lock)           __acquires(lock);
 void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
-                                                       __acquires(spinlock_t);
-void __lockfunc _read_lock(rwlock_t *lock)             __acquires(rwlock_t);
-void __lockfunc _write_lock(rwlock_t *lock)            __acquires(rwlock_t);
-void __lockfunc _spin_lock_bh(spinlock_t *lock)                __acquires(spinlock_t);
-void __lockfunc _read_lock_bh(rwlock_t *lock)          __acquires(rwlock_t);
-void __lockfunc _write_lock_bh(rwlock_t *lock)         __acquires(rwlock_t);
-void __lockfunc _spin_lock_irq(spinlock_t *lock)       __acquires(spinlock_t);
-void __lockfunc _read_lock_irq(rwlock_t *lock)         __acquires(rwlock_t);
-void __lockfunc _write_lock_irq(rwlock_t *lock)                __acquires(rwlock_t);
+                                                       __acquires(lock);
+void __lockfunc _read_lock(rwlock_t *lock)             __acquires(lock);
+void __lockfunc _write_lock(rwlock_t *lock)            __acquires(lock);
+void __lockfunc _spin_lock_bh(spinlock_t *lock)                __acquires(lock);
+void __lockfunc _read_lock_bh(rwlock_t *lock)          __acquires(lock);
+void __lockfunc _write_lock_bh(rwlock_t *lock)         __acquires(lock);
+void __lockfunc _spin_lock_irq(spinlock_t *lock)       __acquires(lock);
+void __lockfunc _read_lock_irq(rwlock_t *lock)         __acquires(lock);
+void __lockfunc _write_lock_irq(rwlock_t *lock)                __acquires(lock);
 unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
-                                                       __acquires(spinlock_t);
+                                                       __acquires(lock);
 unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
-                                                       __acquires(rwlock_t);
+                                                       __acquires(lock);
 unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
-                                                       __acquires(rwlock_t);
+                                                       __acquires(lock);
 int __lockfunc _spin_trylock(spinlock_t *lock);
 int __lockfunc _read_trylock(rwlock_t *lock);
 int __lockfunc _write_trylock(rwlock_t *lock);
 int __lockfunc _spin_trylock_bh(spinlock_t *lock);
-void __lockfunc _spin_unlock(spinlock_t *lock)         __releases(spinlock_t);
-void __lockfunc _read_unlock(rwlock_t *lock)           __releases(rwlock_t);
-void __lockfunc _write_unlock(rwlock_t *lock)          __releases(rwlock_t);
-void __lockfunc _spin_unlock_bh(spinlock_t *lock)      __releases(spinlock_t);
-void __lockfunc _read_unlock_bh(rwlock_t *lock)                __releases(rwlock_t);
-void __lockfunc _write_unlock_bh(rwlock_t *lock)       __releases(rwlock_t);
-void __lockfunc _spin_unlock_irq(spinlock_t *lock)     __releases(spinlock_t);
-void __lockfunc _read_unlock_irq(rwlock_t *lock)       __releases(rwlock_t);
-void __lockfunc _write_unlock_irq(rwlock_t *lock)      __releases(rwlock_t);
+void __lockfunc _spin_unlock(spinlock_t *lock)         __releases(lock);
+void __lockfunc _read_unlock(rwlock_t *lock)           __releases(lock);
+void __lockfunc _write_unlock(rwlock_t *lock)          __releases(lock);
+void __lockfunc _spin_unlock_bh(spinlock_t *lock)      __releases(lock);
+void __lockfunc _read_unlock_bh(rwlock_t *lock)                __releases(lock);
+void __lockfunc _write_unlock_bh(rwlock_t *lock)       __releases(lock);
+void __lockfunc _spin_unlock_irq(spinlock_t *lock)     __releases(lock);
+void __lockfunc _read_unlock_irq(rwlock_t *lock)       __releases(lock);
+void __lockfunc _write_unlock_irq(rwlock_t *lock)      __releases(lock);
 void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
-                                                       __releases(spinlock_t);
+                                                       __releases(lock);
 void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
-                                                       __releases(rwlock_t);
+                                                       __releases(lock);
 void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
-                                                       __releases(rwlock_t);
+                                                       __releases(lock);
 
 #endif /* __LINUX_SPINLOCK_API_SMP_H */
index a6de332e57d456a6243cc4496aa1b3ddf8491d96..862c0d8c83817ce2288dd5cd79f5d46ed7557654 100644 (file)
@@ -109,13 +109,13 @@ struct rpc_credops {
        void                    (*crdestroy)(struct rpc_cred *);
 
        int                     (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
-       u32 *                   (*crmarshal)(struct rpc_task *, u32 *);
+       __be32 *                (*crmarshal)(struct rpc_task *, __be32 *);
        int                     (*crrefresh)(struct rpc_task *);
-       u32 *                   (*crvalidate)(struct rpc_task *, u32 *);
+       __be32 *                (*crvalidate)(struct rpc_task *, __be32 *);
        int                     (*crwrap_req)(struct rpc_task *, kxdrproc_t,
-                                               void *, u32 *, void *);
+                                               void *, __be32 *, void *);
        int                     (*crunwrap_resp)(struct rpc_task *, kxdrproc_t,
-                                               void *, u32 *, void *);
+                                               void *, __be32 *, void *);
 };
 
 extern struct rpc_authops      authunix_ops;
@@ -134,10 +134,10 @@ struct rpc_cred * rpcauth_bindcred(struct rpc_task *);
 void                   rpcauth_holdcred(struct rpc_task *);
 void                   put_rpccred(struct rpc_cred *);
 void                   rpcauth_unbindcred(struct rpc_task *);
-u32 *                  rpcauth_marshcred(struct rpc_task *, u32 *);
-u32 *                  rpcauth_checkverf(struct rpc_task *, u32 *);
-int                    rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, u32 *data, void *obj);
-int                    rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, u32 *data, void *obj);
+__be32 *               rpcauth_marshcred(struct rpc_task *, __be32 *);
+__be32 *               rpcauth_checkverf(struct rpc_task *, __be32 *);
+int                    rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj);
+int                    rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, __be32 *data, void *obj);
 int                    rpcauth_refreshcred(struct rpc_task *);
 void                   rpcauth_invalcred(struct rpc_task *);
 int                    rpcauth_uptodatecred(struct rpc_task *);
index f43f237360ae62099997c803b440e2efece721b5..d9f5934ac9fedbbe789fe0da125ac89b979c13b7 100644 (file)
@@ -95,7 +95,7 @@ enum rpc_auth_stat {
  * 2GB.
  */
 
-typedef u32    rpc_fraghdr;
+typedef __be32 rpc_fraghdr;
 
 #define        RPC_LAST_STREAM_FRAGMENT        (1U << 31)
 #define        RPC_FRAGMENT_SIZE_MASK          (~RPC_LAST_STREAM_FRAGMENT)
index 7b27c09b56046e19bef6e499922f628bec5c0a6e..73140ee5c638ab631916ecf6fb697da58384693d 100644 (file)
@@ -78,28 +78,45 @@ struct svc_serv {
  */
 #define RPCSVC_MAXPAGES                ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
 
-static inline u32 svc_getu32(struct kvec *iov)
+static inline u32 svc_getnl(struct kvec *iov)
 {
-       u32 val, *vp;
+       __be32 val, *vp;
        vp = iov->iov_base;
        val = *vp++;
        iov->iov_base = (void*)vp;
-       iov->iov_len -= sizeof(u32);
+       iov->iov_len -= sizeof(__be32);
+       return ntohl(val);
+}
+
+static inline void svc_putnl(struct kvec *iov, u32 val)
+{
+       __be32 *vp = iov->iov_base + iov->iov_len;
+       *vp = htonl(val);
+       iov->iov_len += sizeof(__be32);
+}
+
+static inline __be32 svc_getu32(struct kvec *iov)
+{
+       __be32 val, *vp;
+       vp = iov->iov_base;
+       val = *vp++;
+       iov->iov_base = (void*)vp;
+       iov->iov_len -= sizeof(__be32);
        return val;
 }
 
 static inline void svc_ungetu32(struct kvec *iov)
 {
-       u32 *vp = (u32 *)iov->iov_base;
+       __be32 *vp = (__be32 *)iov->iov_base;
        iov->iov_base = (void *)(vp - 1);
        iov->iov_len += sizeof(*vp);
 }
 
-static inline void svc_putu32(struct kvec *iov, u32 val)
+static inline void svc_putu32(struct kvec *iov, __be32 val)
 {
-       u32 *vp = iov->iov_base + iov->iov_len;
+       __be32 *vp = iov->iov_base + iov->iov_len;
        *vp = val;
-       iov->iov_len += sizeof(u32);
+       iov->iov_len += sizeof(__be32);
 }
 
        
@@ -130,7 +147,7 @@ struct svc_rqst {
        short                   rq_arghi;       /* pages available in argument page list */
        short                   rq_resused;     /* pages used for result */
 
-       u32                     rq_xid;         /* transmission id */
+       __be32                  rq_xid;         /* transmission id */
        u32                     rq_prog;        /* program number */
        u32                     rq_vers;        /* program version */
        u32                     rq_proc;        /* procedure number */
@@ -139,7 +156,7 @@ struct svc_rqst {
                                rq_secure  : 1; /* secure port */
 
 
-       __u32                   rq_daddr;       /* dest addr of request - reply from here */
+       __be32                  rq_daddr;       /* dest addr of request - reply from here */
 
        void *                  rq_argp;        /* decoded arguments */
        void *                  rq_resp;        /* xdr'd results */
@@ -169,7 +186,7 @@ struct svc_rqst {
  * Check buffer bounds after decoding arguments
  */
 static inline int
-xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
+xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
 {
        char *cp = (char *)p;
        struct kvec *vec = &rqstp->rq_arg.head[0];
@@ -178,7 +195,7 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
 }
 
 static inline int
-xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
+xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
 {
        struct kvec *vec = &rqstp->rq_res.head[0];
        char *cp = (char*)p;
@@ -249,10 +266,10 @@ struct svc_deferred_req {
        u32                     prot;   /* protocol (UDP or TCP) */
        struct sockaddr_in      addr;
        struct svc_sock         *svsk;  /* where reply must go */
-       u32                     daddr;  /* where reply must come from */
+       __be32                  daddr;  /* where reply must come from */
        struct cache_deferred_req handle;
        int                     argslen;
-       u32                     args[0];
+       __be32                  args[0];
 };
 
 /*
@@ -284,7 +301,7 @@ struct svc_version {
         * A return value of 0 means drop the request. 
         * vs_dispatch == NULL means use default dispatcher.
         */
-       int                     (*vs_dispatch)(struct svc_rqst *, u32 *);
+       int                     (*vs_dispatch)(struct svc_rqst *, __be32 *);
 };
 
 /*
index 2fe2087edd665130d75dac0836c5763e853bccf6..a6601650deeb4ef4131a319e4757bcadb313e0b1 100644 (file)
@@ -95,7 +95,7 @@ struct auth_ops {
        char *  name;
        struct module *owner;
        int     flavour;
-       int     (*accept)(struct svc_rqst *rq, u32 *authp);
+       int     (*accept)(struct svc_rqst *rq, __be32 *authp);
        int     (*release)(struct svc_rqst *rq);
        void    (*domain_release)(struct auth_domain *);
        int     (*set_client)(struct svc_rqst *rq);
@@ -112,7 +112,7 @@ struct auth_ops {
 #define        SVC_COMPLETE    9
 
 
-extern int     svc_authenticate(struct svc_rqst *rqstp, u32 *authp);
+extern int     svc_authenticate(struct svc_rqst *rqstp, __be32 *authp);
 extern int     svc_authorise(struct svc_rqst *rqstp);
 extern int     svc_set_client(struct svc_rqst *rqstp);
 extern int     svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
index e6d3d349506c6409f0a65e38a89c01723ee1c3ff..953723b09bc6d73cd5ad97bd0143bdf1fbd162f9 100644 (file)
@@ -32,7 +32,7 @@ struct xdr_netobj {
  * side) or svc_rqst pointer (server side).
  * Encode functions always assume there's enough room in the buffer.
  */
-typedef int    (*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
+typedef int    (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj);
 
 /*
  * Basic structure for transmission/reception of a client XDR message.
@@ -88,19 +88,19 @@ struct xdr_buf {
 /*
  * Miscellaneous XDR helper functions
  */
-u32 *  xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
-u32 *  xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
-u32 *  xdr_encode_string(u32 *p, const char *s);
-u32 *  xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
-u32 *  xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
-u32 *  xdr_decode_netobj(u32 *p, struct xdr_netobj *);
+__be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len);
+__be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len);
+__be32 *xdr_encode_string(__be32 *p, const char *s);
+__be32 *xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen);
+__be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *);
+__be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *);
 
 void   xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
                         unsigned int);
 void   xdr_inline_pages(struct xdr_buf *, unsigned int,
                         struct page **, unsigned int, unsigned int);
 
-static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
+static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
 {
        return xdr_encode_opaque(p, s, len);
 }
@@ -108,16 +108,16 @@ static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
 /*
  * Decode 64bit quantities (NFSv3 support)
  */
-static inline u32 *
-xdr_encode_hyper(u32 *p, __u64 val)
+static inline __be32 *
+xdr_encode_hyper(__be32 *p, __u64 val)
 {
        *p++ = htonl(val >> 32);
        *p++ = htonl(val & 0xFFFFFFFF);
        return p;
 }
 
-static inline u32 *
-xdr_decode_hyper(u32 *p, __u64 *valp)
+static inline __be32 *
+xdr_decode_hyper(__be32 *p, __u64 *valp)
 {
        *valp  = ((__u64) ntohl(*p++)) << 32;
        *valp |= ntohl(*p++);
@@ -128,7 +128,7 @@ xdr_decode_hyper(u32 *p, __u64 *valp)
  * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
  */
 static inline int
-xdr_adjust_iovec(struct kvec *iov, u32 *p)
+xdr_adjust_iovec(struct kvec *iov, __be32 *p)
 {
        return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
 }
@@ -180,19 +180,19 @@ extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
  * Provide some simple tools for XDR buffer overflow-checking etc.
  */
 struct xdr_stream {
-       uint32_t *p;            /* start of available buffer */
+       __be32 *p;              /* start of available buffer */
        struct xdr_buf *buf;    /* XDR buffer to read/write */
 
-       uint32_t *end;          /* end of available buffer space */
+       __be32 *end;            /* end of available buffer space */
        struct kvec *iov;       /* pointer to the current kvec */
 };
 
-extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
-extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
+extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
 extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
                unsigned int base, unsigned int len);
-extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
-extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
+extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
+extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
 extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
 extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
 
index bdeba8538c719892407c0f112e809bb166cc179c..6cf6265807529842e10b3b0553bb8d401d17e84a 100644 (file)
@@ -79,7 +79,7 @@ struct rpc_rqst {
         * This is the private part
         */
        struct rpc_task *       rq_task;        /* RPC task data */
-       __u32                   rq_xid;         /* request XID */
+       __be32                  rq_xid;         /* request XID */
        int                     rq_cong;        /* has incremented xprt->cong */
        int                     rq_received;    /* receive completed */
        u32                     rq_seqno;       /* gss seq no. used on req. */
@@ -171,9 +171,9 @@ struct rpc_xprt {
        /*
         * State of TCP reply receive stuff
         */
-       u32                     tcp_recm,       /* Fragment header */
-                               tcp_xid,        /* Current XID */
-                               tcp_reclen,     /* fragment length */
+       __be32                  tcp_recm,       /* Fragment header */
+                               tcp_xid;        /* Current XID */
+       u32                     tcp_reclen,     /* fragment length */
                                tcp_offset;     /* fragment offset */
        unsigned long           tcp_copied,     /* copied to request */
                                tcp_flags;
@@ -253,7 +253,7 @@ void                        xprt_release(struct rpc_task *task);
 struct rpc_xprt *      xprt_get(struct rpc_xprt *xprt);
 void                   xprt_put(struct rpc_xprt *xprt);
 
-static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p)
+static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
 {
        return p + xprt->tsh_size;
 }
@@ -268,7 +268,7 @@ void                        xprt_wait_for_buffer_space(struct rpc_task *task);
 void                   xprt_write_space(struct rpc_xprt *xprt);
 void                   xprt_update_rtt(struct rpc_task *task);
 void                   xprt_adjust_cwnd(struct rpc_task *task, int result);
-struct rpc_rqst *      xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
+struct rpc_rqst *      xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid);
 void                   xprt_complete_rqst(struct rpc_task *task, int copied);
 void                   xprt_release_rqst_cong(struct rpc_task *task);
 void                   xprt_disconnect(struct rpc_xprt *xprt);
index 3f0f716225ecd714d1c21fac4076e6ef6fbbce12..2d1c3d5c83acc150d9838c881d4d22d79509fc4b 100644 (file)
@@ -597,6 +597,6 @@ asmlinkage long sys_get_robust_list(int pid,
                                    size_t __user *len_ptr);
 asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
                                    size_t len);
-asmlinkage long sys_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *cache);
+asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
 
 #endif
index 8ebf497907f8ec8cb8e014b8ff2f5f840261a3f5..0e058a2d1c6d72a62ddcef1e733830bff6323269 100644 (file)
 #include <asm/byteorder.h>
 
 struct tcphdr {
-       __u16   source;
-       __u16   dest;
-       __u32   seq;
-       __u32   ack_seq;
+       __be16  source;
+       __be16  dest;
+       __be32  seq;
+       __be32  ack_seq;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u16   res1:4,
                doff:4,
@@ -50,9 +50,9 @@ struct tcphdr {
 #else
 #error "Adjust your <asm/byteorder.h> defines"
 #endif 
-       __u16   window;
-       __u16   check;
-       __u16   urg_ptr;
+       __be16  window;
+       __be16  check;
+       __be16  urg_ptr;
 };
 
 /*
@@ -62,7 +62,7 @@ struct tcphdr {
  */
 union tcp_word_hdr { 
        struct tcphdr hdr;
-       __u32             words[5];
+       __be32            words[5];
 }; 
 
 #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) 
@@ -166,6 +166,11 @@ struct tcp_info
 #include <net/inet_timewait_sock.h>
 
 /* This defines a selective acknowledgement block. */
+struct tcp_sack_block_wire {
+       __be32  start_seq;
+       __be32  end_seq;
+};
+
 struct tcp_sack_block {
        __u32   start_seq;
        __u32   end_seq;
@@ -211,7 +216,7 @@ struct tcp_sock {
  *     Header prediction flags
  *     0x5?10 << 16 + snd_wnd in net byte order
  */
-       __u32   pred_flags;
+       __be32  pred_flags;
 
 /*
  *     RFC793 variables by their proper names. This means you can
index 99e02ef54c47db8fa1e9ceff2644acb9c2b98b38..bfc84a7aecc5288a762b8d0d5303f2ba17f34d42 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern unsigned short  tr_type_trans(struct sk_buff *skb, struct net_device *dev);
+extern __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
 extern struct net_device *alloc_trdev(int sizeof_priv);
 
index 04827ca65781c0a47177a656eece88906ff9069d..44091c0db0b46b473234172a91d983319648e7ce 100644 (file)
@@ -174,7 +174,7 @@ struct tty_struct {
        struct tty_driver *driver;
        int index;
        struct tty_ldisc ldisc;
-       struct semaphore termios_sem;
+       struct mutex termios_mutex;
        struct termios *termios, *termios_locked;
        char name[64];
        int pgrp;
@@ -190,7 +190,6 @@ struct tty_struct {
        struct tty_struct *link;
        struct fasync_struct *fasync;
        struct tty_bufhead buf;
-       int max_flip_cnt;
        int alt_speed;          /* For magic substitution of 38400 bps */
        wait_queue_head_t write_wait;
        wait_queue_head_t read_wait;
@@ -308,6 +307,9 @@ extern void tty_ldisc_put(int);
 extern void tty_wakeup(struct tty_struct *tty);
 extern void tty_ldisc_flush(struct tty_struct *tty);
 
+extern int tty_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+                    unsigned long arg);
+
 extern struct mutex tty_mutex;
 
 /* n_tty.c */
index 90223f057d507bd86edf2c8e30333319773e8f23..014b41d1e308ca27f01e7f94bf46d906dc97252d 100644 (file)
 #include <linux/types.h>
 
 struct udphdr {
-       __u16   source;
-       __u16   dest;
-       __u16   len;
-       __u16   check;
+       __be16  source;
+       __be16  dest;
+       __be16  len;
+       __be16  check;
 };
 
 /* UDP socket options */
index 0da15b0b02becfc3db29b62afc5cd6270140ed18..190cc1b78fe2a29a071b01bb9ff8dbc4bc5490cc 100644 (file)
@@ -380,10 +380,10 @@ struct usb_device {
        int maxchild;                   /* Number of ports if hub */
        struct usb_device *children[USB_MAXCHILDREN];
 
+       int pm_usage_cnt;               /* usage counter for autosuspend */
 #ifdef CONFIG_PM
        struct work_struct autosuspend; /* for delayed autosuspends */
        struct mutex pm_mutex;          /* protects PM operations */
-       int pm_usage_cnt;               /* usage counter for autosuspend */
 
        unsigned auto_pm:1;             /* autosuspend/resume in progress */
        unsigned do_remote_wakeup:1;    /* remote wakeup should be enabled */
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 176c7f797339b2aa5d4bca59157b7181bcc5bd97..c89df55f6e035df2ef064726c870911506c7debc 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/types.h>
 #include <linux/percpu.h>
-#include <linux/config.h>
 #include <linux/mmzone.h>
 #include <asm/atomic.h>
 
index 918a29763aea3e0afb58cb78d62db873bad16169..1009d3fe1fc214e8eb920e207483ebdd7d35f1b3 100644 (file)
@@ -33,7 +33,8 @@ extern int fg_console, last_console, want_console;
 int vc_allocate(unsigned int console);
 int vc_cons_allocated(unsigned int console);
 int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
-void vc_disallocate(unsigned int console);
+int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
+void vc_deallocate(unsigned int console);
 void reset_palette(struct vc_data *vc);
 void do_blank_screen(int entering_gfx);
 void do_unblank_screen(int leaving_gfx);
index 56a23a0e7f2eb218a91fd889fb86bbdb3471bcef..4f4d98addb448afb61cd3d49b4a2a8cc3a00cbea 100644 (file)
@@ -111,12 +111,15 @@ balance_dirty_pages_ratelimited(struct address_space *mapping)
 }
 
 int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+extern int generic_writepages(struct address_space *mapping,
+                             struct writeback_control *wbc);
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
 int sync_page_range(struct inode *inode, struct address_space *mapping,
                        loff_t pos, loff_t count);
 int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
                           loff_t pos, loff_t count);
 void set_page_dirty_balance(struct page *page);
+void writeback_set_ratelimit(void);
 
 /* pdflush.c */
 extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
index 14ecd19f4cdc5a7298691951d83c28f8f1ce55a4..430afd05826975e4df9a65afe68e5b9729c1b11c 100644 (file)
@@ -12,8 +12,8 @@
  */
 typedef union
 {
-       __u32           a4;
-       __u32           a6[4];
+       __be32          a4;
+       __be32          a6[4];
 } xfrm_address_t;
 
 /* Ident of a specific xfrm_state. It is used on input to lookup
@@ -23,7 +23,7 @@ typedef union
 struct xfrm_id
 {
        xfrm_address_t  daddr;
-       __u32           spi;
+       __be32          spi;
        __u8            proto;
 };
 
@@ -49,10 +49,10 @@ struct xfrm_selector
 {
        xfrm_address_t  daddr;
        xfrm_address_t  saddr;
-       __u16   dport;
-       __u16   dport_mask;
-       __u16   sport;
-       __u16   sport_mask;
+       __be16  dport;
+       __be16  dport_mask;
+       __be16  sport;
+       __be16  sport_mask;
        __u16   family;
        __u8    prefixlen_d;
        __u8    prefixlen_s;
@@ -281,7 +281,7 @@ struct xfrm_usersa_info {
 
 struct xfrm_usersa_id {
        xfrm_address_t                  daddr;
-       __u32                           spi;
+       __be32                          spi;
        __u16                           family;
        __u8                            proto;
 };
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 643bded9f557b5556ea159515b7915cf9016484d..6a3d9a7d302b1494f36e38ecfdf1415d3d24d1e3 100644 (file)
@@ -12,15 +12,15 @@ extern struct neigh_table arp_tbl;
 extern void    arp_init(void);
 extern int     arp_find(unsigned char *haddr, struct sk_buff *skb);
 extern int     arp_ioctl(unsigned int cmd, void __user *arg);
-extern void     arp_send(int type, int ptype, u32 dest_ip, 
-                        struct net_device *dev, u32 src_ip, 
+extern void     arp_send(int type, int ptype, __be32 dest_ip,
+                        struct net_device *dev, __be32 src_ip,
                         unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
 extern int     arp_bind_neighbour(struct dst_entry *dst);
 extern int     arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir);
 extern void    arp_ifdown(struct net_device *dev);
 
-extern struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
-                                 struct net_device *dev, u32 src_ip,
+extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+                                 struct net_device *dev, __be32 src_ip,
                                  unsigned char *dest_hw, unsigned char *src_hw,
                                  unsigned char *target_hw);
 extern void arp_xmit(struct sk_buff *skb);
index b2bdb1aa04291c7104113ef93532dcb26c166a44..10a3eec191fd2bf6110fbd0b4dadaa6fbdf2af8a 100644 (file)
 #define HCI_NOTIFY_VOICE_SETTING       3
 
 /* HCI device types */
-#define HCI_VHCI       0
+#define HCI_VIRTUAL    0
 #define HCI_USB                1
 #define HCI_PCCARD     2
 #define HCI_UART       3
 #define HCI_RS232      4
 #define HCI_PCI                5
+#define HCI_SDIO       6
 
 /* HCI device quirks */
 enum {
@@ -296,6 +297,7 @@ struct hci_cp_host_buffer_size {
 
 /* Link Control */
 #define OGF_LINK_CTL   0x01 
+
 #define OCF_CREATE_CONN                0x0005
 struct hci_cp_create_conn {
        bdaddr_t bdaddr;
@@ -306,6 +308,11 @@ struct hci_cp_create_conn {
        __u8     role_switch;
 } __attribute__ ((packed));
 
+#define OCF_CREATE_CONN_CANCEL 0x0008
+struct hci_cp_create_conn_cancel {
+       bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
 #define OCF_ACCEPT_CONN_REQ    0x0009
 struct hci_cp_accept_conn_req {
        bdaddr_t bdaddr;
@@ -339,6 +346,8 @@ struct hci_cp_inquiry {
 
 #define OCF_INQUIRY_CANCEL     0x0002
 
+#define OCF_EXIT_PERIODIC_INQ  0x0004
+
 #define OCF_LINK_KEY_REPLY     0x000B
 struct hci_cp_link_key_reply {
        bdaddr_t bdaddr;
index d84855fe7336d24938e0aed2055aaf316818cefe..df22efcfcc0b7deceb77ee1094a05d24f00c22d2 100644 (file)
@@ -72,6 +72,9 @@ struct hci_dev {
        __u8            type;
        bdaddr_t        bdaddr;
        __u8            features[8];
+       __u8            hci_ver;
+       __u16           hci_rev;
+       __u16           manufacturer;
        __u16           voice_setting;
 
        __u16           pkt_type;
@@ -165,6 +168,10 @@ struct hci_conn {
        struct timer_list disc_timer;
        struct timer_list idle_timer;
 
+       struct work_struct work;
+
+       struct device   dev;
+
        struct hci_dev  *hdev;
        void            *l2cap_data;
        void            *sco_data;
@@ -309,10 +316,13 @@ static inline void hci_conn_put(struct hci_conn *conn)
        if (atomic_dec_and_test(&conn->refcnt)) {
                unsigned long timeo;
                if (conn->type == ACL_LINK) {
-                       timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
-                       if (!conn->out)
-                               timeo *= 2;
                        del_timer(&conn->idle_timer);
+                       if (conn->state == BT_CONNECTED) {
+                               timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
+                               if (!conn->out)
+                                       timeo *= 2;
+                       } else
+                               timeo = msecs_to_jiffies(10);
                } else
                        timeo = msecs_to_jiffies(10);
                mod_timer(&conn->disc_timer, jiffies + timeo);
@@ -412,6 +422,8 @@ static inline int hci_recv_frame(struct sk_buff *skb)
 
 int hci_register_sysfs(struct hci_dev *hdev);
 void hci_unregister_sysfs(struct hci_dev *hdev);
+void hci_conn_add_sysfs(struct hci_conn *conn);
+void hci_conn_del_sysfs(struct hci_conn *conn);
 
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
 
index 2d72496c20294a4890d414415167d5c1455ecb3a..718b4d9c891fb4a0898384cb08655b652ceb532b 100644 (file)
@@ -128,7 +128,9 @@ extern int cipso_v4_rbm_strictvalid;
 
 #ifdef CONFIG_NETLABEL
 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
-int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head));
+int cipso_v4_doi_remove(u32 doi,
+                       struct netlbl_audit *audit_info,
+                       void (*callback) (struct rcu_head * head));
 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
 int cipso_v4_doi_walk(u32 *skip_cnt,
                     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
@@ -143,6 +145,7 @@ static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
 }
 
 static inline int cipso_v4_doi_remove(u32 doi,
+                                   struct netlbl_audit *audit_info,
                                    void (*callback) (struct rcu_head * head))
 {
        return 0;
index a8d825f90305a751447c207d140853c9bf79c523..e156e38e4ac37db61db754822e59877299e2f9a0 100644 (file)
@@ -84,7 +84,7 @@ struct dst_entry
 struct dst_ops
 {
        unsigned short          family;
-       unsigned short          protocol;
+       __be16                  protocol;
        unsigned                gc_thresh;
 
        int                     (*gc)(void);
index 3ca210ec1379f549e0e2f0d4e3fd821283b70709..ddf5f3ca1720154be67aca197f628f1e7a83fd08 100644 (file)
@@ -16,8 +16,8 @@ struct flowi {
 
        union {
                struct {
-                       __u32                   daddr;
-                       __u32                   saddr;
+                       __be32                  daddr;
+                       __be32                  saddr;
                        __u32                   fwmark;
                        __u8                    tos;
                        __u8                    scope;
@@ -56,8 +56,8 @@ struct flowi {
 #define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
        union {
                struct {
-                       __u16   sport;
-                       __u16   dport;
+                       __be16  sport;
+                       __be16  dport;
                } ports;
 
                struct {
@@ -73,7 +73,7 @@ struct flowi {
                        __u8    objname[16]; /* Not zero terminated */
                } dnports;
 
-               __u32           spi;
+               __be32          spi;
 
 #ifdef CONFIG_IPV6_MIP6
                struct {
index 05f8ff7d9316fe9d881aec2c0238d44221b14b16..dc09474efcf38e2cb02329a4ef0bf2fd8633bf7f 100644 (file)
@@ -38,7 +38,7 @@ struct dst_entry;
 struct net_proto_family;
 struct sk_buff;
 
-extern void    icmp_send(struct sk_buff *skb_in,  int type, int code, u32 info);
+extern void    icmp_send(struct sk_buff *skb_in,  int type, int code, __be32 info);
 extern int     icmp_rcv(struct sk_buff *skb);
 extern int     icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern void    icmp_init(struct net_proto_family *ops);
index de4e83b6da4be2024ec04b1cb5fd53139adbc88e..0bcf9f237e1f0de8fc44bac445c290a9078e041a 100644 (file)
@@ -238,9 +238,9 @@ extern struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
 
 extern struct request_sock *inet_csk_search_req(const struct sock *sk,
                                                struct request_sock ***prevp,
-                                               const __u16 rport,
-                                               const __u32 raddr,
-                                               const __u32 laddr);
+                                               const __be16 rport,
+                                               const __be32 raddr,
+                                               const __be32 laddr);
 extern int inet_csk_bind_conflict(const struct sock *sk,
                                  const struct inet_bind_bucket *tb);
 extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
index b4491c9e2a5a028177913e4f21b45401346e5421..a9eb2eaf094eaf1e9d54c61f070359118309aac8 100644 (file)
@@ -272,42 +272,56 @@ static inline int inet_iif(const struct sk_buff *skb)
 }
 
 extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
-                                          const u32 daddr,
+                                          const __be32 daddr,
                                           const unsigned short hnum,
                                           const int dif);
 
 static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
-                                               u32 daddr, u16 dport, int dif)
+                                               __be32 daddr, __be16 dport, int dif)
 {
        return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
 }
 
 /* Socket demux engine toys. */
+/* What happens here is ugly; there's a pair of adjacent fields in
+   struct inet_sock; __be16 dport followed by __u16 num.  We want to
+   search by pair, so we combine the keys into a single 32bit value
+   and compare with 32bit value read from &...->dport.  Let's at least
+   make sure that it's not mixed with anything else...
+   On 64bit targets we combine comparisons with pair of adjacent __be32
+   fields in the same way.
+*/
+typedef __u32 __bitwise __portpair;
 #ifdef __BIG_ENDIAN
 #define INET_COMBINED_PORTS(__sport, __dport) \
-       (((__u32)(__sport) << 16) | (__u32)(__dport))
+       ((__force __portpair)(((__force __u32)(__be16)(__sport) << 16) | (__u32)(__dport)))
 #else /* __LITTLE_ENDIAN */
 #define INET_COMBINED_PORTS(__sport, __dport) \
-       (((__u32)(__dport) << 16) | (__u32)(__sport))
+       ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
 #endif
 
 #if (BITS_PER_LONG == 64)
+typedef __u64 __bitwise __addrpair;
 #ifdef __BIG_ENDIAN
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
-       const __u64 __name = (((__u64)(__saddr)) << 32) | ((__u64)(__daddr));
+       const __addrpair __name = (__force __addrpair) ( \
+                                  (((__force __u64)(__be32)(__saddr)) << 32) | \
+                                  ((__force __u64)(__be32)(__daddr)));
 #else /* __LITTLE_ENDIAN */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
-       const __u64 __name = (((__u64)(__daddr)) << 32) | ((__u64)(__saddr));
+       const __addrpair __name = (__force __addrpair) ( \
+                                  (((__force __u64)(__be32)(__daddr)) << 32) | \
+                                  ((__force __u64)(__be32)(__saddr)));
 #endif /* __BIG_ENDIAN */
 #define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
        (((__sk)->sk_hash == (__hash))                          &&      \
-        ((*((__u64 *)&(inet_sk(__sk)->daddr))) == (__cookie))  &&      \
-        ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports))   &&      \
+        ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie))     &&      \
+        ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
        (((__sk)->sk_hash == (__hash))                          &&      \
-        ((*((__u64 *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&  \
-        ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&   \
+        ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&     \
+        ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #else /* 32-bit arch */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
@@ -315,13 +329,13 @@ static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
        (((__sk)->sk_hash == (__hash))                          &&      \
         (inet_sk(__sk)->daddr          == (__saddr))           &&      \
         (inet_sk(__sk)->rcv_saddr      == (__daddr))           &&      \
-        ((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports))   &&      \
+        ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
        (((__sk)->sk_hash == (__hash))                          &&      \
         (inet_twsk(__sk)->tw_daddr     == (__saddr))           &&      \
         (inet_twsk(__sk)->tw_rcv_saddr == (__daddr))           &&      \
-        ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&   \
+        ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #endif /* 64-bit arch */
 
@@ -333,12 +347,12 @@ static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
  */
 static inline struct sock *
        __inet_lookup_established(struct inet_hashinfo *hashinfo,
-                                 const u32 saddr, const u16 sport,
-                                 const u32 daddr, const u16 hnum,
+                                 const __be32 saddr, const __be16 sport,
+                                 const __be32 daddr, const u16 hnum,
                                  const int dif)
 {
        INET_ADDR_COOKIE(acookie, saddr, daddr)
-       const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
+       const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
        struct sock *sk;
        const struct hlist_node *node;
        /* Optimize here for direct hit, only listening connections can
@@ -370,8 +384,8 @@ hit:
 
 static inline struct sock *
        inet_lookup_established(struct inet_hashinfo *hashinfo,
-                               const u32 saddr, const u16 sport,
-                               const u32 daddr, const u16 dport,
+                               const __be32 saddr, const __be16 sport,
+                               const __be32 daddr, const __be16 dport,
                                const int dif)
 {
        return __inet_lookup_established(hashinfo, saddr, sport, daddr,
@@ -379,8 +393,8 @@ static inline struct sock *
 }
 
 static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
-                                        const u32 saddr, const u16 sport,
-                                        const u32 daddr, const u16 dport,
+                                        const __be32 saddr, const __be16 sport,
+                                        const __be32 daddr, const __be16 dport,
                                         const int dif)
 {
        u16 hnum = ntohs(dport);
@@ -390,8 +404,8 @@ static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
 }
 
 static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
-                                      const u32 saddr, const u16 sport,
-                                      const u32 daddr, const u16 dport,
+                                      const __be32 saddr, const __be16 sport,
+                                      const __be32 daddr, const __be16 dport,
                                       const int dif)
 {
        struct sock *sk;
index f6242710f2ffe208906cdb9b5857dbc3ace00eaa..ce6da97bc8489d4fc1e5d8838f0dd3541a78cfc5 100644 (file)
@@ -36,7 +36,7 @@
  * @ts_needaddr - Need to record addr of outgoing dev
  */
 struct ip_options {
-       __u32           faddr;
+       __be32          faddr;
        unsigned char   optlen;
        unsigned char   srr;
        unsigned char   rr;
@@ -62,9 +62,9 @@ struct inet_request_sock {
        u16                     inet6_rsk_offset;
        /* 2 bytes hole, try to pack */
 #endif
-       u32                     loc_addr;
-       u32                     rmt_addr;
-       u16                     rmt_port;
+       __be32                  loc_addr;
+       __be32                  rmt_addr;
+       __be16                  rmt_port;
        u16                     snd_wscale : 4, 
                                rcv_wscale : 4, 
                                tstamp_ok  : 1,
@@ -110,15 +110,15 @@ struct inet_sock {
        struct ipv6_pinfo       *pinet6;
 #endif
        /* Socket demultiplex comparisons on incoming packets. */
-       __u32                   daddr;
-       __u32                   rcv_saddr;
-       __u16                   dport;
+       __be32                  daddr;
+       __be32                  rcv_saddr;
+       __be16                  dport;
        __u16                   num;
-       __u32                   saddr;
+       __be32                  saddr;
        __s16                   uc_ttl;
        __u16                   cmsg_flags;
        struct ip_options       *opt;
-       __u16                   sport;
+       __be16                  sport;
        __u16                   id;
        __u8                    tos;
        __u8                    mc_ttl;
@@ -129,7 +129,7 @@ struct inet_sock {
                                hdrincl:1,
                                mc_loop:1;
        int                     mc_index;
-       __u32                   mc_addr;
+       __be32                  mc_addr;
        struct ip_mc_socklist   *mc_list;
        struct {
                unsigned int            flags;
@@ -137,7 +137,7 @@ struct inet_sock {
                struct ip_options       *opt;
                struct rtable           *rt;
                int                     length; /* Total length of all frames */
-               u32                     addr;
+               __be32                  addr;
                struct flowi            fl;
        } cork;
 };
@@ -167,10 +167,10 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
 
 extern int inet_sk_rebuild_header(struct sock *sk);
 
-static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
-                                       const __u32 faddr, const __u16 fport)
+static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
+                                       const __be32 faddr, const __be16 fport)
 {
-       unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+       unsigned int h = ((__force __u32)laddr ^ lport) ^ ((__force __u32)faddr ^ (__force __u32)fport);
        h ^= h >> 16;
        h ^= h >> 8;
        return h;
@@ -179,10 +179,10 @@ static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
 static inline int inet_sk_ehashfn(const struct sock *sk)
 {
        const struct inet_sock *inet = inet_sk(sk);
-       const __u32 laddr = inet->rcv_saddr;
+       const __be32 laddr = inet->rcv_saddr;
        const __u16 lport = inet->num;
-       const __u32 faddr = inet->daddr;
-       const __u16 fport = inet->dport;
+       const __be32 faddr = inet->daddr;
+       const __be16 fport = inet->dport;
 
        return inet_ehashfn(laddr, lport, faddr, fport);
 }
index 600cb543550d8b4f13c7b991b5d8dc308ba144fd..6d14c22a00c5e3e9ab750fb0c68434edba86c853 100644 (file)
@@ -120,10 +120,10 @@ struct inet_timewait_sock {
        unsigned char           tw_rcv_wscale;
        /* Socket demultiplex comparisons on incoming packets. */
        /* these five are in inet_sock */
-       __u16                   tw_sport;
-       __u32                   tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
-       __u32                   tw_rcv_saddr;
-       __u16                   tw_dport;
+       __be16                  tw_sport;
+       __be32                  tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
+       __be32                  tw_rcv_saddr;
+       __be16                  tw_dport;
        __u16                   tw_num;
        /* And these are ours. */
        __u8                    tw_ipv6only:1;
@@ -186,7 +186,7 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
        return (struct inet_timewait_sock *)sk;
 }
 
-static inline u32 inet_rcv_saddr(const struct sock *sk)
+static inline __be32 inet_rcv_saddr(const struct sock *sk)
 {
        return likely(sk->sk_state != TCP_TIME_WAIT) ?
                inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
index 0965515f40cfabba4e3839007ca51ebac6d22113..925573fd2aed04a91e41c0de1b84bf09f68e06c5 100644 (file)
@@ -22,7 +22,7 @@ struct inet_peer
        unsigned long           dtime;          /* the time of last use of not
                                                 * referenced entries */
        atomic_t                refcnt;
-       __u32                   v4daddr;        /* peer's address */
+       __be32                  v4daddr;        /* peer's address */
        __u16                   avl_height;
        __u16                   ip_id_count;    /* IP ID for the next packet */
        atomic_t                rid;            /* Frag reception counter */
@@ -33,7 +33,7 @@ struct inet_peer
 void                   inet_initpeers(void) __init;
 
 /* can be called with or without local BH being disabled */
-struct inet_peer       *inet_getpeer(__u32 daddr, int create);
+struct inet_peer       *inet_getpeer(__be32 daddr, int create);
 
 extern spinlock_t inet_peer_unused_lock;
 extern struct inet_peer **inet_peer_unused_tailp;
index 98f90840077186243bf910db40452ba7cfa881d9..b6d95e5534016c3a3440525bc4ec00d196fcaeb4 100644 (file)
@@ -45,7 +45,7 @@ struct inet_skb_parm
 
 struct ipcm_cookie
 {
-       u32                     addr;
+       __be32                  addr;
        int                     oif;
        struct ip_options       *opt;
 };
@@ -86,7 +86,7 @@ extern int            igmp_mc_proc_init(void);
  */
 
 extern int             ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
-                                             u32 saddr, u32 daddr,
+                                             __be32 saddr, __be32 daddr,
                                              struct ip_options *opt);
 extern int             ip_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt, struct net_device *orig_dev);
@@ -335,7 +335,7 @@ extern int ip_net_unreachable(struct sk_buff *skb);
  *     Functions provided by ip_options.c
  */
  
-extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, u32 daddr, struct rtable *rt, int is_frag);
+extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag);
 extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
 extern void ip_options_fragment(struct sk_buff *skb);
 extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb);
@@ -363,8 +363,8 @@ extern int  ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(s
 
 extern int     ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
 extern void    ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
-                             u16 port, u32 info, u8 *payload);
-extern void    ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
+                             __be16 port, u32 info, u8 *payload);
+extern void    ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
                               u32 info);
 
 /* sysctl helpers - any sysctl which holds a value that ends up being
index fcc159a4ac17f5fd2c9687abf43f6649079fdc1e..82229146bac7f127156050880edc5c150f0de882 100644 (file)
@@ -30,13 +30,13 @@ struct fib_config {
        u8                      fc_type;
        /* 1 byte unused */
        u32                     fc_table;
-       u32                     fc_dst;
-       u32                     fc_src;
-       u32                     fc_gw;
+       __be32                  fc_dst;
+       __be32                  fc_src;
+       __be32                  fc_gw;
        int                     fc_oif;
        u32                     fc_flags;
        u32                     fc_priority;
-       u32                     fc_prefsrc;
+       __be32                  fc_prefsrc;
        struct nlattr           *fc_mx;
        struct rtnexthop        *fc_mp;
        int                     fc_mx_len;
@@ -63,7 +63,7 @@ struct fib_nh {
        __u32                   nh_tclassid;
 #endif
        int                     nh_oif;
-       u32                     nh_gw;
+       __be32                  nh_gw;
 };
 
 /*
@@ -78,7 +78,7 @@ struct fib_info {
        int                     fib_dead;
        unsigned                fib_flags;
        int                     fib_protocol;
-       u32                     fib_prefsrc;
+       __be32                  fib_prefsrc;
        u32                     fib_priority;
        u32                     fib_metrics[RTAX_MAX];
 #define fib_mtu fib_metrics[RTAX_MTU-1]
@@ -107,8 +107,8 @@ struct fib_result {
        unsigned char   type;
        unsigned char   scope;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       __u32           network;
-       __u32           netmask;
+       __be32          network;
+       __be32          netmask;
 #endif
        struct fib_info *fi;
 #ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -117,7 +117,7 @@ struct fib_result {
 };
 
 struct fib_result_nl {
-       u32             fl_addr;   /* To be looked up*/ 
+       __be32          fl_addr;   /* To be looked up*/
        u32             fl_fwmark; 
        unsigned char   fl_tos;
        unsigned char   fl_scope;
@@ -222,17 +222,17 @@ extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *ar
 extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
-extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
-                              struct net_device *dev, u32 *spec_dst, u32 *itag);
+extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+                              struct net_device *dev, __be32 *spec_dst, u32 *itag);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
 struct rtentry;
 
 /* Exported by fib_semantics.c */
-extern int ip_fib_check_default(u32 gw, struct net_device *dev);
-extern int fib_sync_down(u32 local, struct net_device *dev, int force);
+extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
+extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
 extern int fib_sync_up(struct net_device *dev);
-extern u32  __fib_res_prefsrc(struct fib_result *res);
+extern __be32  __fib_res_prefsrc(struct fib_result *res);
 
 /* Exported by fib_hash.c */
 extern struct fib_table *fib_hash_init(u32 id);
index ac747b64734c56a9c83054cf5af20e81ed6e19d2..beffdd66ad74f81ac2c5a9d40003ff4ad372102f 100644 (file)
@@ -17,7 +17,7 @@ struct ip_mp_alg_ops {
        void    (*mp_alg_select_route)(const struct flowi *flp,
                                       struct rtable *rth, struct rtable **rp);
        void    (*mp_alg_flush)(void);
-       void    (*mp_alg_set_nhinfo)(__u32 network, __u32 netmask,
+       void    (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
                                     unsigned char prefixlen,
                                     const struct fib_nh *nh);
        void    (*mp_alg_remove)(struct rtable *rth);
@@ -59,7 +59,7 @@ static inline void multipath_flush(void)
 }
 
 static inline void multipath_set_nhinfo(struct rtable *rth,
-                                       __u32 network, __u32 netmask,
+                                       __be32 network, __be32 netmask,
                                        unsigned char prefixlen,
                                        const struct fib_nh *nh)
 {
index 3b57b159b653dfe8dee821fef097ca234f73a2d6..49c717e3b040075562728bbda430369adf89aa93 100644 (file)
 struct ip_vs_service_user {
        /* virtual service addresses */
        u_int16_t               protocol;
-       u_int32_t               addr;           /* virtual ip address */
-       u_int16_t               port;
+       __be32                  addr;           /* virtual ip address */
+       __be16                  port;
        u_int32_t               fwmark;         /* firwall mark of service */
 
        /* virtual service options */
        char                    sched_name[IP_VS_SCHEDNAME_MAXLEN];
        unsigned                flags;          /* virtual service flags */
        unsigned                timeout;        /* persistent timeout in sec */
-       u_int32_t               netmask;        /* persistent netmask */
+       __be32                  netmask;        /* persistent netmask */
 };
 
 
 struct ip_vs_dest_user {
        /* destination server address */
-       u_int32_t               addr;
-       u_int16_t               port;
+       __be32                  addr;
+       __be16                  port;
 
        /* real server options */
        unsigned                conn_flags;     /* connection flags */
@@ -163,15 +163,15 @@ struct ip_vs_getinfo {
 struct ip_vs_service_entry {
        /* which service: user fills in these */
        u_int16_t               protocol;
-       u_int32_t               addr;           /* virtual address */
-       u_int16_t               port;
+       __be32                  addr;           /* virtual address */
+       __be16                  port;
        u_int32_t               fwmark;         /* firwall mark of service */
 
        /* service options */
        char                    sched_name[IP_VS_SCHEDNAME_MAXLEN];
        unsigned                flags;          /* virtual service flags */
        unsigned                timeout;        /* persistent timeout */
-       u_int32_t               netmask;        /* persistent netmask */
+       __be32                  netmask;        /* persistent netmask */
 
        /* number of real servers */
        unsigned int            num_dests;
@@ -182,8 +182,8 @@ struct ip_vs_service_entry {
 
 
 struct ip_vs_dest_entry {
-       u_int32_t               addr;           /* destination address */
-       u_int16_t               port;
+       __be32                  addr;           /* destination address */
+       __be16                  port;
        unsigned                conn_flags;     /* connection flags */
        int                     weight;         /* destination weight */
 
@@ -203,8 +203,8 @@ struct ip_vs_dest_entry {
 struct ip_vs_get_dests {
        /* which service: user fills in these */
        u_int16_t               protocol;
-       u_int32_t               addr;           /* virtual address */
-       u_int16_t               port;
+       __be32                  addr;           /* virtual address */
+       __be16                  port;
        u_int32_t               fwmark;         /* firwall mark of service */
 
        /* number of real servers */
@@ -502,12 +502,12 @@ struct ip_vs_conn {
        struct list_head        c_list;         /* hashed list heads */
 
        /* Protocol, addresses and port numbers */
-       __u32                   caddr;          /* client address */
-       __u32                   vaddr;          /* virtual address */
-       __u32                   daddr;          /* destination address */
-       __u16                   cport;
-       __u16                   vport;
-       __u16                   dport;
+       __be32                   caddr;          /* client address */
+       __be32                   vaddr;          /* virtual address */
+       __be32                   daddr;          /* destination address */
+       __be16                   cport;
+       __be16                   vport;
+       __be16                   dport;
        __u16                   protocol;       /* Which protocol (TCP/UDP) */
 
        /* counter and timer */
@@ -554,12 +554,12 @@ struct ip_vs_service {
        atomic_t                usecnt;   /* use counter */
 
        __u16                   protocol; /* which protocol (TCP/UDP) */
-       __u32                   addr;     /* IP address for virtual service */
-       __u16                   port;     /* port number for the service */
+       __be32                  addr;     /* IP address for virtual service */
+       __be16                  port;     /* port number for the service */
        __u32                   fwmark;   /* firewall mark of the service */
        unsigned                flags;    /* service status flags */
        unsigned                timeout;  /* persistent timeout in ticks */
-       __u32                   netmask;  /* grouping granularity */
+       __be32                  netmask;  /* grouping granularity */
 
        struct list_head        destinations;  /* real server d-linked list */
        __u32                   num_dests;     /* number of servers */
@@ -581,8 +581,8 @@ struct ip_vs_dest {
        struct list_head        n_list;   /* for the dests in the service */
        struct list_head        d_list;   /* for table with all the dests */
 
-       __u32                   addr;           /* IP address of the server */
-       __u16                   port;           /* port number of the server */
+       __be32                  addr;           /* IP address of the server */
+       __be16                  port;           /* port number of the server */
        volatile unsigned       flags;          /* dest status flags */
        atomic_t                conn_flags;     /* flags to copy to conn */
        atomic_t                weight;         /* server weight */
@@ -605,8 +605,8 @@ struct ip_vs_dest {
        /* for virtual service */
        struct ip_vs_service    *svc;           /* service it belongs to */
        __u16                   protocol;       /* which protocol (TCP/UDP) */
-       __u32                   vaddr;          /* virtual IP address */
-       __u16                   vport;          /* virtual port number */
+       __be32                  vaddr;          /* virtual IP address */
+       __be16                  vport;          /* virtual port number */
        __u32                   vfwmark;        /* firewall mark of service */
 };
 
@@ -648,7 +648,7 @@ struct ip_vs_app
        /* members for application incarnations */
        struct list_head        p_list;         /* member in proto app list */
        struct ip_vs_app        *app;           /* its real application */
-       __u16                   port;           /* port number in net order */
+       __be16                  port;           /* port number in net order */
        atomic_t                usecnt;         /* usage counter */
 
        /* output hook: return false if can't linearize. diff set for TCP.  */
@@ -740,11 +740,11 @@ enum {
 };
 
 extern struct ip_vs_conn *ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
 extern struct ip_vs_conn *ip_vs_ct_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
 extern struct ip_vs_conn *ip_vs_conn_out_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
 
 /* put back the conn without restarting its timer */
 static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
@@ -752,11 +752,11 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
        atomic_dec(&cp->refcnt);
 }
 extern void ip_vs_conn_put(struct ip_vs_conn *cp);
-extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __u16 cport);
+extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
 
 extern struct ip_vs_conn *
-ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
-              __u32 daddr, __u16 dport, unsigned flags,
+ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport,
+              __be32 daddr, __be16 dport, unsigned flags,
               struct ip_vs_dest *dest);
 extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
 
@@ -887,7 +887,7 @@ extern int sysctl_ip_vs_nat_icmp_send;
 extern struct ip_vs_stats ip_vs_stats;
 
 extern struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport);
+ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
 
 static inline void ip_vs_service_put(struct ip_vs_service *svc)
 {
@@ -895,7 +895,7 @@ static inline void ip_vs_service_put(struct ip_vs_service *svc)
 }
 
 extern struct ip_vs_dest *
-ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
+ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport);
 extern int ip_vs_use_count_inc(void);
 extern void ip_vs_use_count_dec(void);
 extern int ip_vs_control_init(void);
index 72bf47b2a4e0c9bfe34583980f429b1d691557c9..8223c4410b4bdb232c505c0e539a4d2cd7a52d2c 100644 (file)
@@ -318,8 +318,8 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
 
 #ifndef __HAVE_ARCH_ADDR_SET
 static inline void ipv6_addr_set(struct in6_addr *addr, 
-                                    __u32 w1, __u32 w2,
-                                    __u32 w3, __u32 w4)
+                                    __be32 w1, __be32 w2,
+                                    __be32 w3, __be32 w4)
 {
        addr->s6_addr32[0] = w1;
        addr->s6_addr32[1] = w2;
@@ -337,7 +337,7 @@ static inline int ipv6_addr_equal(const struct in6_addr *a1,
                a1->s6_addr32[3] == a2->s6_addr32[3]);
 }
 
-static inline int __ipv6_prefix_equal(const u32 *a1, const u32 *a2,
+static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
                                      unsigned int prefixlen)
 {
        unsigned pdw, pbi;
index 1c73bdbc3eb3a76332a6312dee8b1e9d7fd58416..9592c374b41d536e182930ff6f16f7a70d71a813 100644 (file)
 #define IRLAN_SHORT  1
 #define IRLAN_ARRAY  2
 
-#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER)
+/* IrLAN sits on top if IrTTP */
+#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER)
+/* 1 byte for the command code and 1 byte for the parameter count */
+#define IRLAN_CMD_HEADER 2
+
+#define IRLAN_STRING_PARAMETER_LEN(name, value) (1 + strlen((name)) + 2 \
+                                               + strlen ((value)))
+#define IRLAN_BYTE_PARAMETER_LEN(name)          (1 + strlen((name)) + 2 + 1)
+#define IRLAN_SHORT_PARAMETER_LEN(name)         (1 + strlen((name)) + 2 + 2)
 
 /*
  *  IrLAN client
index 3452ae257c845d1d3f93460ffc4165756cd9b3f1..9dd54a5002b2af123c3118f09db60838cc05add0 100644 (file)
@@ -74,6 +74,19 @@ struct discovery_t;
 
 #define PF_BIT    0x10 /* Poll/final bit */
 
+/* Some IrLAP field lengths */
+/*
+ * Only baud rate triplet is 4 bytes (PV can be 2 bytes).
+ * All others params (7) are 3 bytes, so that's 7*3 + 1*4 bytes.
+ */
+#define IRLAP_NEGOCIATION_PARAMS_LEN 25
+#define IRLAP_DISCOVERY_INFO_LEN     32
+
+struct disc_frame {
+       __u8 caddr;          /* Connection address */
+       __u8 control;
+} IRDA_PACK;
+
 struct xid_frame {
        __u8  caddr; /* Connection address */
        __u8  control;
@@ -95,11 +108,25 @@ struct test_frame {
 struct ua_frame {
        __u8 caddr;
        __u8 control;
-
        __u32 saddr; /* Source device address */
        __u32 daddr; /* Dest device address */
 } IRDA_PACK;
-       
+
+struct dm_frame {
+       __u8 caddr;          /* Connection address */
+       __u8 control;
+} IRDA_PACK;
+
+struct rd_frame {
+       __u8 caddr;          /* Connection address */
+       __u8 control;
+} IRDA_PACK;
+
+struct rr_frame {
+       __u8 caddr;          /* Connection address */
+       __u8 control;
+} IRDA_PACK;
+
 struct i_frame {
        __u8 caddr;
        __u8 control;
index 11ecfa58a648ff3ad145b8138055f6ac5ad9f54f..e212b9bc2503d64439cd70c3ffa4d080d15751dd 100644 (file)
@@ -48,7 +48,7 @@
 #define DEV_ADDR_ANY  0xffffffff
 
 #define LMP_HEADER          2    /* Dest LSAP + Source LSAP */
-#define LMP_CONTROL_HEADER  4
+#define LMP_CONTROL_HEADER  4    /* LMP_HEADER + opcode + parameter */
 #define LMP_PID_HEADER      1    /* Used by Ultra */
 #define LMP_MAX_HEADER      (LMP_CONTROL_HEADER+LAP_MAX_HEADER)
 
index 6692430063fdd4a9357aae7e964d0698c305e615..c63a58058e2170b811e01c446b8781b5f1faa93e 100644 (file)
  *
  */
 
+/* NetLabel audit information */
+struct netlbl_audit {
+       u32 secid;
+       uid_t loginuid;
+};
+
 /* Domain mapping definition struct */
 struct netlbl_dom_map;
 
 /* Domain mapping operations */
-int netlbl_domhsh_remove(const char *domain);
+int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
 /* LSM security attributes */
 struct netlbl_lsm_cache {
index 4ab68a7a636a927e915a66139ace5737cab78ed7..ce5cba19c393cf5206643300263e3971e50661d1 100644 (file)
@@ -831,6 +831,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
 #define NLA_PUT_U32(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u32, attrtype, value)
 
+#define NLA_PUT_BE32(skb, attrtype, value) \
+       NLA_PUT_TYPE(skb, __be32, attrtype, value)
+
 #define NLA_PUT_U64(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u64, attrtype, value)
 
@@ -852,6 +855,15 @@ static inline u32 nla_get_u32(struct nlattr *nla)
        return *(u32 *) nla_data(nla);
 }
 
+/**
+ * nla_get_be32 - return payload of __be32 attribute
+ * @nla: __be32 netlink attribute
+ */
+static inline __be32 nla_get_be32(struct nlattr *nla)
+{
+       return *(__be32 *) nla_data(nla);
+}
+
 /**
  * nla_get_u16 - return payload of u16 attribute
  * @nla: u16 netlink attribute
index 7f93ac0e089983a0ceed7e4a11c153f2210ce794..486e37aff06ca28751e2a4a1cbf645b52cd3ebee 100644 (file)
@@ -62,18 +62,18 @@ struct rtable
        __u16                   rt_type;
        __u16                   rt_multipath_alg;
 
-       __u32                   rt_dst; /* Path destination     */
-       __u32                   rt_src; /* Path source          */
+       __be32                  rt_dst; /* Path destination     */
+       __be32                  rt_src; /* Path source          */
        int                     rt_iif;
 
        /* Info on neighbour */
-       __u32                   rt_gateway;
+       __be32                  rt_gateway;
 
        /* Cache lookup keys */
        struct flowi            fl;
 
        /* Miscellaneous cached information */
-       __u32                   rt_spec_dst; /* RFC1122 specific destination */
+       __be32                  rt_spec_dst; /* RFC1122 specific destination */
        struct inet_peer        *peer; /* long-living peer info */
 };
 
@@ -109,18 +109,18 @@ extern struct ip_rt_acct *ip_rt_acct;
 
 struct in_device;
 extern int             ip_rt_init(void);
-extern void            ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
-                                      u32 src, struct net_device *dev);
+extern void            ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
+                                      __be32 src, struct net_device *dev);
 extern void            ip_rt_advice(struct rtable **rp, int advice);
 extern void            rt_cache_flush(int how);
 extern int             __ip_route_output_key(struct rtable **, const struct flowi *flp);
 extern int             ip_route_output_key(struct rtable **, struct flowi *flp);
 extern int             ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
-extern int             ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
+extern int             ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin);
 extern unsigned short  ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
 extern void            ip_rt_send_redirect(struct sk_buff *skb);
 
-extern unsigned                inet_addr_type(u32 addr);
+extern unsigned                inet_addr_type(__be32 addr);
 extern void            ip_rt_multicast_event(struct in_device *);
 extern int             ip_rt_ioctl(unsigned int cmd, void __user *arg);
 extern void            ip_rt_get_source(u8 *src, struct rtable *rt);
@@ -144,9 +144,9 @@ static inline char rt_tos2priority(u8 tos)
        return ip_tos2prio[IPTOS_TOS(tos)>>1];
 }
 
-static inline int ip_route_connect(struct rtable **rp, u32 dst,
-                                  u32 src, u32 tos, int oif, u8 protocol,
-                                  u16 sport, u16 dport, struct sock *sk)
+static inline int ip_route_connect(struct rtable **rp, __be32 dst,
+                                  __be32 src, u32 tos, int oif, u8 protocol,
+                                  __be16 sport, __be16 dport, struct sock *sk)
 {
        struct flowi fl = { .oif = oif,
                            .nl_u = { .ip4_u = { .daddr = dst,
@@ -172,7 +172,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst,
 }
 
 static inline int ip_route_newports(struct rtable **rp, u8 protocol,
-                                   u16 sport, u16 dport, struct sock *sk)
+                                   __be16 sport, __be16 dport, struct sock *sk)
 {
        if (sport != (*rp)->fl.fl_ip_sport ||
            dport != (*rp)->fl.fl_ip_dport) {
index 11e0b1d6bd4734963a8675b7d4c25aa1867607f0..1e2a4ddec96e3c7cfdf8e5ef2010d234c0673821 100644 (file)
@@ -437,8 +437,8 @@ static inline void xfrm_state_hold(struct xfrm_state *x)
 
 static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
 {
-       __u32 *a1 = token1;
-       __u32 *a2 = token2;
+       __be32 *a1 = token1;
+       __be32 *a2 = token2;
        int pdw;
        int pbi;
 
@@ -450,7 +450,7 @@ static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
                        return 0;
 
        if (pbi) {
-               __u32 mask;
+               __be32 mask;
 
                mask = htonl((0xffffffff) << (32 - pbi));
 
@@ -462,9 +462,9 @@ static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
 }
 
 static __inline__
-u16 xfrm_flowi_sport(struct flowi *fl)
+__be16 xfrm_flowi_sport(struct flowi *fl)
 {
-       u16 port;
+       __be16 port;
        switch(fl->proto) {
        case IPPROTO_TCP:
        case IPPROTO_UDP:
@@ -487,9 +487,9 @@ u16 xfrm_flowi_sport(struct flowi *fl)
 }
 
 static __inline__
-u16 xfrm_flowi_dport(struct flowi *fl)
+__be16 xfrm_flowi_dport(struct flowi *fl)
 {
-       u16 port;
+       __be16 port;
        switch(fl->proto) {
        case IPPROTO_TCP:
        case IPPROTO_UDP:
@@ -912,7 +912,7 @@ extern int xfrm_state_check_expire(struct xfrm_state *x);
 extern void xfrm_state_insert(struct xfrm_state *x);
 extern int xfrm_state_add(struct xfrm_state *x);
 extern int xfrm_state_update(struct xfrm_state *x);
-extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
 extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
 #ifdef CONFIG_XFRM_SUB_POLICY
 extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
@@ -935,8 +935,8 @@ static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **s
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
-extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
-extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
 extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
@@ -945,7 +945,7 @@ extern int xfrm4_rcv(struct sk_buff *skb);
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
 extern int xfrm6_rcv(struct sk_buff **pskb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
                            xfrm_address_t *saddr, u8 proto);
@@ -989,7 +989,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
 void xfrm_policy_flush(u8 type);
 u32 xfrm_get_acqseq(void);
-void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
+void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 
                                  xfrm_address_t *daddr, xfrm_address_t *saddr, 
                                  int create, unsigned short family);
@@ -1004,7 +1004,7 @@ extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pi
 extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
 
 extern void xfrm_input_init(void);
-extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);
+extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
 
 extern void xfrm_probe_algs(void);
 extern int xfrm_count_auth_supported(void);
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 4381006dd666aaba6f9d1e29913d65fe5c3e5a8c..d2eb7a84a264f0330d0aab1792f3ac34bbba23b2 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
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 2a7c933651c7c03b0777fcecdc1ea3e06fed259b..f4330acead468a8cd228d0249918dbd748e7fbf2 100644 (file)
@@ -483,10 +483,14 @@ static void do_acct_process(struct file *file)
        ac.ac_ppid = current->parent->tgid;
 #endif
 
-       read_lock(&tasklist_lock);      /* pin current->signal */
+       mutex_lock(&tty_mutex);
+       /* FIXME: Whoever is responsible for current->signal locking needs
+          to use the same locking all over the kernel and document it */
+       read_lock(&tasklist_lock);
        ac.ac_tty = current->signal->tty ?
                old_encode_dev(tty_devnum(current->signal->tty)) : 0;
        read_unlock(&tasklist_lock);
+       mutex_unlock(&tty_mutex);
 
        spin_lock_irq(&current->sighand->siglock);
        ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
index fb83c5cb8c324226c47fb18ca7c708e61ef4421b..105147631753f1b4f68fc17878a0e4531b436593 100644 (file)
@@ -817,6 +817,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                audit_log_format(ab, " success=%s exit=%ld", 
                                 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
                                 context->return_code);
+
+       mutex_lock(&tty_mutex);
        if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
                tty = tsk->signal->tty->name;
        else
@@ -838,6 +840,9 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                  context->gid,
                  context->euid, context->suid, context->fsuid,
                  context->egid, context->sgid, context->fsgid, tty);
+
+       mutex_unlock(&tty_mutex);
+
        audit_log_task_info(ab, tsk);
        if (context->filterkey) {
                audit_log_format(ab, " key=");
index c7685ad00a97c4ddfd2f47029f0b5b4342da80be..edb845a6e84ae5e649ece39e18384620c5dac74e 100644 (file)
@@ -133,7 +133,7 @@ static inline int cap_set_all(kernel_cap_t *effective,
      int found = 0;
 
      do_each_thread(g, target) {
-             if (target == current || target->pid == 1)
+             if (target == current || is_init(target))
                      continue;
              found = 1;
             if (security_capset_check(target, effective, inheritable,
index 126dee9530aacc13a37d304ee8a4b54f69355a82..b4fbd838cd775ac9007af6e7d566652e1ad629de 100644 (file)
 #include <linux/security.h>
 #include <linux/timex.h>
 #include <linux/migrate.h>
+#include <linux/posix-timers.h>
 
 #include <asm/uaccess.h>
 
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
        return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
@@ -601,6 +604,30 @@ long compat_sys_clock_getres(clockid_t which_clock,
        return err;
 } 
 
+static long compat_clock_nanosleep_restart(struct restart_block *restart)
+{
+       long err;
+       mm_segment_t oldfs;
+       struct timespec tu;
+       struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
+
+       restart->arg1 = (unsigned long) &tu;
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+       err = clock_nanosleep_restart(restart);
+       set_fs(oldfs);
+
+       if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
+           put_compat_timespec(&tu, rmtp))
+               return -EFAULT;
+
+       if (err == -ERESTART_RESTARTBLOCK) {
+               restart->fn = compat_clock_nanosleep_restart;
+               restart->arg1 = (unsigned long) rmtp;
+       }
+       return err;
+}
+
 long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
                            struct compat_timespec __user *rqtp,
                            struct compat_timespec __user *rmtp)
@@ -608,6 +635,7 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
        long err;
        mm_segment_t oldfs;
        struct timespec in, out; 
+       struct restart_block *restart;
 
        if (get_compat_timespec(&in, rqtp)) 
                return -EFAULT;
@@ -618,9 +646,16 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
                                  (struct timespec __user *) &in,
                                  (struct timespec __user *) &out);
        set_fs(oldfs);
+
        if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
            put_compat_timespec(&out, rmtp))
                return -EFAULT;
+
+       if (err == -ERESTART_RESTARTBLOCK) {
+               restart = &current_thread_info()->restart_block;
+               restart->fn = compat_clock_nanosleep_restart;
+               restart->arg1 = (unsigned long) rmtp;
+       }
        return err;     
 } 
 
index 1b32c2c04c153a056047134a28ed5f172eeb1f80..8c3c400cce91f4a679e0d034380ca16065b296a5 100644 (file)
@@ -240,7 +240,7 @@ static struct super_block *cpuset_sb;
  * A cpuset can only be deleted if both its 'count' of using tasks
  * is zero, and its list of 'children' cpusets is empty.  Since all
  * tasks in the system use _some_ cpuset, and since there is always at
- * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * least one task in the system (init), therefore, top_cpuset
  * always has either children cpusets and/or using tasks.  So we don't
  * need a special hack to ensure that top_cpuset cannot be deleted.
  *
@@ -912,6 +912,10 @@ static int update_nodemask(struct cpuset *cs, char *buf)
        int fudge;
        int retval;
 
+       /* top_cpuset.mems_allowed tracks node_online_map; it's read-only */
+       if (cs == &top_cpuset)
+               return -EACCES;
+
        trialcs = *cs;
        retval = nodelist_parse(buf, trialcs.mems_allowed);
        if (retval < 0)
@@ -1221,7 +1225,12 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
 
        task_lock(tsk);
        oldcs = tsk->cpuset;
-       if (!oldcs) {
+       /*
+        * After getting 'oldcs' cpuset ptr, be sure still not exiting.
+        * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack
+        * then fail this attach_task(), to avoid breaking top_cpuset.count.
+        */
+       if (tsk->flags & PF_EXITING) {
                task_unlock(tsk);
                mutex_unlock(&callback_mutex);
                put_task_struct(tsk);
@@ -2036,33 +2045,104 @@ out:
        return err;
 }
 
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG)
 /*
- * The top_cpuset tracks what CPUs and Memory Nodes are online,
- * period.  This is necessary in order to make cpusets transparent
- * (of no affect) on systems that are actively using CPU hotplug
- * but making no active use of cpusets.
- *
- * This handles CPU hotplug (cpuhp) events.  If someday Memory
- * Nodes can be hotplugged (dynamically changing node_online_map)
- * then we should handle that too, perhaps in a similar way.
+ * If common_cpu_mem_hotplug_unplug(), below, unplugs any CPUs
+ * or memory nodes, we need to walk over the cpuset hierarchy,
+ * removing that CPU or node from all cpusets.  If this removes the
+ * last CPU or node from a cpuset, then the guarantee_online_cpus()
+ * or guarantee_online_mems() code will use that emptied cpusets
+ * parent online CPUs or nodes.  Cpusets that were already empty of
+ * CPUs or nodes are left empty.
+ *
+ * This routine is intentionally inefficient in a couple of regards.
+ * It will check all cpusets in a subtree even if the top cpuset of
+ * the subtree has no offline CPUs or nodes.  It checks both CPUs and
+ * nodes, even though the caller could have been coded to know that
+ * only one of CPUs or nodes needed to be checked on a given call.
+ * This was done to minimize text size rather than cpu cycles.
+ *
+ * Call with both manage_mutex and callback_mutex held.
+ *
+ * Recursive, on depth of cpuset subtree.
  */
 
-#ifdef CONFIG_HOTPLUG_CPU
-static int cpuset_handle_cpuhp(struct notifier_block *nb,
-                               unsigned long phase, void *cpu)
+static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
+{
+       struct cpuset *c;
+
+       /* Each of our child cpusets mems must be online */
+       list_for_each_entry(c, &cur->children, sibling) {
+               guarantee_online_cpus_mems_in_subtree(c);
+               if (!cpus_empty(c->cpus_allowed))
+                       guarantee_online_cpus(c, &c->cpus_allowed);
+               if (!nodes_empty(c->mems_allowed))
+                       guarantee_online_mems(c, &c->mems_allowed);
+       }
+}
+
+/*
+ * The cpus_allowed and mems_allowed nodemasks in the top_cpuset track
+ * cpu_online_map and node_online_map.  Force the top cpuset to track
+ * whats online after any CPU or memory node hotplug or unplug event.
+ *
+ * To ensure that we don't remove a CPU or node from the top cpuset
+ * that is currently in use by a child cpuset (which would violate
+ * the rule that cpusets must be subsets of their parent), we first
+ * call the recursive routine guarantee_online_cpus_mems_in_subtree().
+ *
+ * Since there are two callers of this routine, one for CPU hotplug
+ * events and one for memory node hotplug events, we could have coded
+ * two separate routines here.  We code it as a single common routine
+ * in order to minimize text size.
+ */
+
+static void common_cpu_mem_hotplug_unplug(void)
 {
        mutex_lock(&manage_mutex);
        mutex_lock(&callback_mutex);
 
+       guarantee_online_cpus_mems_in_subtree(&top_cpuset);
        top_cpuset.cpus_allowed = cpu_online_map;
+       top_cpuset.mems_allowed = node_online_map;
 
        mutex_unlock(&callback_mutex);
        mutex_unlock(&manage_mutex);
+}
+#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The top_cpuset tracks what CPUs and Memory Nodes are online,
+ * period.  This is necessary in order to make cpusets transparent
+ * (of no affect) on systems that are actively using CPU hotplug
+ * but making no active use of cpusets.
+ *
+ * This routine ensures that top_cpuset.cpus_allowed tracks
+ * cpu_online_map on each CPU hotplug (cpuhp) event.
+ */
 
+static int cpuset_handle_cpuhp(struct notifier_block *nb,
+                               unsigned long phase, void *cpu)
+{
+       common_cpu_mem_hotplug_unplug();
        return 0;
 }
 #endif
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * Keep top_cpuset.mems_allowed tracking node_online_map.
+ * Call this routine anytime after you change node_online_map.
+ * See also the previous routine cpuset_handle_cpuhp().
+ */
+
+void cpuset_track_online_nodes()
+{
+       common_cpu_mem_hotplug_unplug();
+}
+#endif
+
 /**
  * cpuset_init_smp - initialize cpus_allowed
  *
index d891883420f7bfd64b0cbc29b7003fcd57d526ef..c189de2927ab6b55ab47baf199d347d65481e906 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/audit.h> /* for audit_free() */
 #include <linux/resource.h>
+#include <linux/blkdev.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -219,7 +220,7 @@ static int will_become_orphaned_pgrp(int pgrp, struct task_struct *ignored_task)
        do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
                if (p == ignored_task
                                || p->exit_state
-                               || p->real_parent->pid == 1)
+                               || is_init(p->real_parent))
                        continue;
                if (process_group(p->real_parent) != pgrp
                            && p->real_parent->signal->session == p->signal->session) {
@@ -249,17 +250,6 @@ static int has_stopped_jobs(int pgrp)
        do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
                if (p->state != TASK_STOPPED)
                        continue;
-
-               /* If p is stopped by a debugger on a signal that won't
-                  stop it, then don't count p as stopped.  This isn't
-                  perfect but it's a good approximation.  */
-               if (unlikely (p->ptrace)
-                   && p->exit_code != SIGSTOP
-                   && p->exit_code != SIGTSTP
-                   && p->exit_code != SIGTTOU
-                   && p->exit_code != SIGTTIN)
-                       continue;
-
                retval = 1;
                break;
        } while_each_task_pid(pgrp, PIDTYPE_PGID, p);
@@ -292,9 +282,7 @@ static void reparent_to_init(void)
        /* Set the exit signal to SIGCHLD so we signal init on exit */
        current->exit_signal = SIGCHLD;
 
-       if ((current->policy == SCHED_NORMAL ||
-                       current->policy == SCHED_BATCH)
-                               && (task_nice(current) < 0))
+       if (!has_rt_policy(current) && (task_nice(current) < 0))
                set_user_nice(current, 0);
        /* cpus_allowed? */
        /* rt_priority? */
@@ -487,6 +475,18 @@ void fastcall put_files_struct(struct files_struct *files)
 
 EXPORT_SYMBOL(put_files_struct);
 
+void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
+{
+       struct files_struct *old;
+
+       old = tsk->files;
+       task_lock(tsk);
+       tsk->files = files;
+       task_unlock(tsk);
+       put_files_struct(old);
+}
+EXPORT_SYMBOL(reset_files_struct);
+
 static inline void __exit_files(struct task_struct *tsk)
 {
        struct files_struct * files = tsk->files;
@@ -954,15 +954,15 @@ fastcall NORET_TYPE void do_exit(long code)
        if (tsk->splice_pipe)
                __free_pipe_info(tsk->splice_pipe);
 
-       /* PF_DEAD causes final put_task_struct after we schedule. */
        preempt_disable();
-       BUG_ON(tsk->flags & PF_DEAD);
-       tsk->flags |= PF_DEAD;
+       /* causes final put_task_struct in finish_task_switch(). */
+       tsk->state = TASK_DEAD;
 
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
-       for (;;) ;
+       for (;;)
+               cpu_relax();    /* For when BUG is null */
 }
 
 EXPORT_SYMBOL_GPL(do_exit);
@@ -971,7 +971,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)
                complete(comp);
-       
+
        do_exit(code);
 }
 
index a0dad84567c9c7effe6b46f98bf077ee5d9f5e22..1c999f3e0b47f02a4fd805daf90f9b914c44282b 100644 (file)
@@ -183,7 +183,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
        /* One for us, one for whoever does the "release_task()" (usually parent) */
        atomic_set(&tsk->usage,2);
        atomic_set(&tsk->fs_excl, 0);
+#ifdef CONFIG_BLK_DEV_IO_TRACE
        tsk->btrace_seq = 0;
+#endif
        tsk->splice_pipe = NULL;
        return tsk;
 }
@@ -1061,7 +1063,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 #endif
 #ifdef CONFIG_TRACE_IRQFLAGS
        p->irq_events = 0;
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+       p->hardirqs_enabled = 1;
+#else
        p->hardirqs_enabled = 0;
+#endif
        p->hardirq_enable_ip = 0;
        p->hardirq_enable_event = 0;
        p->hardirq_disable_ip = _THIS_IP_;
@@ -1144,7 +1150,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
        /* Our parent execution domain becomes current domain
           These must match for thread signalling to apply */
-          
        p->parent_exec_id = p->self_exec_id;
 
        /* ok, now we should be set up.. */
@@ -1167,6 +1172,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        /* Need tasklist lock for parent etc handling! */
        write_lock_irq(&tasklist_lock);
 
+       /* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
+       p->ioprio = current->ioprio;
+
        /*
         * The task hasn't been attached yet, so its cpus_allowed mask will
         * not be changed, nor will its assigned CPU.
@@ -1226,11 +1234,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                }
        }
 
-       /*
-        * inherit ioprio
-        */
-       p->ioprio = current->ioprio;
-
        if (likely(p->pid)) {
                add_parent(p);
                if (unlikely(p->ptrace & PT_PTRACED))
index 9d260e838cffdca6f951d6625626ab9d62f19d81..4b6770e9806d0c080ef5f9bd542ddb778ddbcff2 100644 (file)
@@ -389,7 +389,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
 {
        struct task_struct *p;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = find_task_by_pid(pid);
        if (!p)
                goto out_unlock;
@@ -403,7 +403,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
        }
        get_task_struct(p);
 out_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        return p;
 }
@@ -1624,7 +1624,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
                struct task_struct *p;
 
                ret = -ESRCH;
-               read_lock(&tasklist_lock);
+               rcu_read_lock();
                p = find_task_by_pid(pid);
                if (!p)
                        goto err_unlock;
@@ -1633,7 +1633,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
                                !capable(CAP_SYS_PTRACE))
                        goto err_unlock;
                head = p->robust_list;
-               read_unlock(&tasklist_lock);
+               rcu_read_unlock();
        }
 
        if (put_user(sizeof(*head), len_ptr))
@@ -1641,7 +1641,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
        return put_user(head, head_ptr);
 
 err_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        return ret;
 }
index 21c38a7e666ba74f373b9693770af4b22b63a685..d0ba190dfeb6b9ae81c98f135515b19a145f8206 100644 (file)
@@ -693,7 +693,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
        return t->task == NULL;
 }
 
-static long __sched nanosleep_restart(struct restart_block *restart)
+long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
 {
        struct hrtimer_sleeper t;
        struct timespec __user *rmtp;
@@ -702,13 +702,13 @@ static long __sched nanosleep_restart(struct restart_block *restart)
 
        restart->fn = do_no_restart_syscall;
 
-       hrtimer_init(&t.timer, restart->arg3, HRTIMER_ABS);
-       t.timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
+       hrtimer_init(&t.timer, restart->arg0, HRTIMER_ABS);
+       t.timer.expires.tv64 = ((u64)restart->arg3 << 32) | (u64) restart->arg2;
 
        if (do_nanosleep(&t, HRTIMER_ABS))
                return 0;
 
-       rmtp = (struct timespec __user *) restart->arg2;
+       rmtp = (struct timespec __user *) restart->arg1;
        if (rmtp) {
                time = ktime_sub(t.timer.expires, t.timer.base->get_time());
                if (time.tv64 <= 0)
@@ -718,7 +718,7 @@ static long __sched nanosleep_restart(struct restart_block *restart)
                        return -EFAULT;
        }
 
-       restart->fn = nanosleep_restart;
+       restart->fn = hrtimer_nanosleep_restart;
 
        /* The other values in restart are already filled in */
        return -ERESTART_RESTARTBLOCK;
@@ -751,11 +751,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
        }
 
        restart = &current_thread_info()->restart_block;
-       restart->fn = nanosleep_restart;
-       restart->arg0 = t.timer.expires.tv64 & 0xFFFFFFFF;
-       restart->arg1 = t.timer.expires.tv64 >> 32;
-       restart->arg2 = (unsigned long) rmtp;
-       restart->arg3 = (unsigned long) t.timer.base->index;
+       restart->fn = hrtimer_nanosleep_restart;
+       restart->arg0 = (unsigned long) t.timer.base->index;
+       restart->arg1 = (unsigned long) rmtp;
+       restart->arg2 = t.timer.expires.tv64 & 0xFFFFFFFF;
+       restart->arg3 = t.timer.expires.tv64 >> 32;
 
        return -ERESTART_RESTARTBLOCK;
 }
index ac1f850d4937e5a020f22132a83da5a49fe9a3bf..736cb0bd498f8ff5c7a50d8b60e3130da43d9d7f 100644 (file)
@@ -40,10 +40,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
        spin_lock_irqsave(&desc->lock, flags);
        irq_chip_set_defaults(chip);
        desc->chip = chip;
-       /*
-        * For compatibility only:
-        */
-       desc->chip = chip;
        spin_unlock_irqrestore(&desc->lock, flags);
 
        return 0;
@@ -146,7 +142,7 @@ static void default_disable(unsigned int irq)
        struct irq_desc *desc = irq_desc + irq;
 
        if (!(desc->status & IRQ_DELAYED_DISABLE))
-               irq_desc[irq].chip->mask(irq);
+               desc->chip->mask(irq);
 }
 
 /*
index 50087ecf337ea17e5429188688187b6623a57f20..fcdd5d2bc3f4b47b57854c41a1cec882939c02ed 100644 (file)
@@ -40,7 +40,7 @@ struct resource crashk_res = {
 
 int kexec_should_crash(struct task_struct *p)
 {
-       if (in_interrupt() || !p->pid || p->pid == 1 || panic_on_oops)
+       if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops)
                return 1;
        return 0;
 }
@@ -995,7 +995,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
        image = xchg(dest_image, image);
 
 out:
-       xchg(&kexec_lock, 0); /* Release the mutex */
+       locked = xchg(&kexec_lock, 0); /* Release the mutex */
+       BUG_ON(!locked);
        kimage_free(image);
 
        return result;
@@ -1061,7 +1062,8 @@ void crash_kexec(struct pt_regs *regs)
                        machine_crash_shutdown(&fixed_regs);
                        machine_kexec(kexec_crash_image);
                }
-               xchg(&kexec_lock, 0);
+               locked = xchg(&kexec_lock, 0);
+               BUG_ON(!locked);
        }
 }
 
index 64ab045c3d9d3a72126971f51c0081e199a4468d..5d1d907378a299ad6c6aab16b15d55d1248f296e 100644 (file)
@@ -122,6 +122,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
 
        len = min(len, fifo->size - fifo->in + fifo->out);
 
+       /*
+        * Ensure that we sample the fifo->out index -before- we
+        * start putting bytes into the kfifo.
+        */
+
+       smp_mb();
+
        /* first put the data starting from fifo->in to buffer end */
        l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
        memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
@@ -129,6 +136,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
        /* then put the rest (if any) at the beginning of the buffer */
        memcpy(fifo->buffer, buffer + l, len - l);
 
+       /*
+        * Ensure that we add the bytes to the kfifo -before-
+        * we update the fifo->in index.
+        */
+
+       smp_wmb();
+
        fifo->in += len;
 
        return len;
@@ -154,6 +168,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
 
        len = min(len, fifo->in - fifo->out);
 
+       /*
+        * Ensure that we sample the fifo->in index -before- we
+        * start removing bytes from the kfifo.
+        */
+
+       smp_rmb();
+
        /* first get the data from fifo->out until the end of the buffer */
        l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
        memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
@@ -161,6 +182,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
        /* then get the rest (if any) from the beginning of the buffer */
        memcpy(buffer + l, fifo->buffer, len - l);
 
+       /*
+        * Ensure that we remove the bytes from the kfifo -before-
+        * we update the fifo->out index.
+        */
+
+       smp_mb();
+
        fifo->out += len;
 
        return len;
index 5c470c57fb57c0997bd5f76e24a1bb5cc24e687b..842f8015d7fd2e6c7bc07f86b9b6766b13864539 100644 (file)
@@ -176,6 +176,8 @@ static int wait_for_helper(void *data)
        if (pid < 0) {
                sub_info->retval = pid;
        } else {
+               int ret;
+
                /*
                 * Normally it is bogus to call wait4() from in-kernel because
                 * wait4() wants to write the exit code to a userspace address.
@@ -185,7 +187,15 @@ static int wait_for_helper(void *data)
                 *
                 * Thus the __user pointer cast is valid here.
                 */
-               sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
+               sys_wait4(pid, (int __user *)&ret, 0, NULL);
+
+               /*
+                * If ret is 0, either ____call_usermodehelper failed and the
+                * real error code is already in sub_info->retval or
+                * sub_info->retval is 0 anyway, so don't mess with it then.
+                */
+               if (ret)
+                       sub_info->retval = ret;
        }
 
        complete(sub_info->complete);
index c088e5542e84074d3f784108805c841c162b0ce9..e596525669ed4fa5018ee452c7bc429b945f8d00 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/stacktrace.h>
 #include <linux/debug_locks.h>
 #include <linux/irqflags.h>
+#include <linux/utsname.h>
 
 #include <asm/sections.h>
 
@@ -121,8 +122,8 @@ static struct list_head chainhash_table[CHAINHASH_SIZE];
  * unique.
  */
 #define iterate_chain_key(key1, key2) \
-       (((key1) << MAX_LOCKDEP_KEYS_BITS/2) ^ \
-       ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS/2)) ^ \
+       (((key1) << MAX_LOCKDEP_KEYS_BITS) ^ \
+       ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS)) ^ \
        (key2))
 
 void lockdep_off(void)
@@ -515,6 +516,13 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
        return 0;
 }
 
+static void print_kernel_version(void)
+{
+       printk("%s %.*s\n", system_utsname.release,
+               (int)strcspn(system_utsname.version, " "),
+               system_utsname.version);
+}
+
 /*
  * When a circular dependency is detected, print the
  * header first:
@@ -531,6 +539,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
 
        printk("\n=======================================================\n");
        printk(  "[ INFO: possible circular locking dependency detected ]\n");
+       print_kernel_version();
        printk(  "-------------------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
                curr->comm, curr->pid);
@@ -712,6 +721,7 @@ print_bad_irq_dependency(struct task_struct *curr,
        printk("\n======================================================\n");
        printk(  "[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
                irqclass, irqclass);
+       print_kernel_version();
        printk(  "------------------------------------------------------\n");
        printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
                curr->comm, curr->pid,
@@ -793,6 +803,7 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
 
        printk("\n=============================================\n");
        printk(  "[ INFO: possible recursive locking detected ]\n");
+       print_kernel_version();
        printk(  "---------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
                curr->comm, curr->pid);
@@ -1375,6 +1386,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
 
        printk("\n=========================================================\n");
        printk(  "[ INFO: possible irq lock inversion dependency detected ]\n");
+       print_kernel_version();
        printk(  "---------------------------------------------------------\n");
        printk("%s/%d just changed the state of lock:\n",
                curr->comm, curr->pid);
@@ -1469,6 +1481,7 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this,
 
        printk("\n=================================\n");
        printk(  "[ INFO: inconsistent lock state ]\n");
+       print_kernel_version();
        printk(  "---------------------------------\n");
 
        printk("inconsistent {%s} -> {%s} usage.\n",
index b7fe6e84096303865f20e1c606c6bb35c77451c8..05625d5dc7583ac5567d3deec22ebd95c57b72bc 100644 (file)
@@ -933,6 +933,15 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
        return sprintf(buf, "0x%lx\n", sattr->address);
 }
 
+static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
+{
+       int section;
+
+       for (section = 0; section < sect_attrs->nsections; section++)
+               kfree(sect_attrs->attrs[section].name);
+       kfree(sect_attrs);
+}
+
 static void add_sect_attrs(struct module *mod, unsigned int nsect,
                char *secstrings, Elf_Shdr *sechdrs)
 {
@@ -949,21 +958,26 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
                        + nloaded * sizeof(sect_attrs->attrs[0]),
                        sizeof(sect_attrs->grp.attrs[0]));
        size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
-       if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL)))
+       sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+       if (sect_attrs == NULL)
                return;
 
        /* Setup section attributes. */
        sect_attrs->grp.name = "sections";
        sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
 
+       sect_attrs->nsections = 0;
        sattr = &sect_attrs->attrs[0];
        gattr = &sect_attrs->grp.attrs[0];
        for (i = 0; i < nsect; i++) {
                if (! (sechdrs[i].sh_flags & SHF_ALLOC))
                        continue;
                sattr->address = sechdrs[i].sh_addr;
-               strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
-                       MODULE_SECT_NAME_LEN);
+               sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
+                                       GFP_KERNEL);
+               if (sattr->name == NULL)
+                       goto out;
+               sect_attrs->nsections++;
                sattr->mattr.show = module_sect_show;
                sattr->mattr.store = NULL;
                sattr->mattr.attr.name = sattr->name;
@@ -979,7 +993,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        mod->sect_attrs = sect_attrs;
        return;
   out:
-       kfree(sect_attrs);
+       free_sect_attrs(sect_attrs);
 }
 
 static void remove_sect_attrs(struct module *mod)
@@ -989,13 +1003,13 @@ static void remove_sect_attrs(struct module *mod)
                                   &mod->sect_attrs->grp);
                /* We are positive that no one is using any sect attrs
                 * at this point.  Deallocate immediately. */
-               kfree(mod->sect_attrs);
+               free_sect_attrs(mod->sect_attrs);
                mod->sect_attrs = NULL;
        }
 }
 
-
 #else
+
 static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
                char *sectstrings, Elf_Shdr *sechdrs)
 {
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 91aea7aa532e53940fc7c63367d6a9634249be95..f406655d66536b8a373b62c082b9ef64364d2c20 100644 (file)
@@ -547,6 +547,7 @@ static void __init kernel_param_sysfs_setup(const char *name,
                                            unsigned int name_skip)
 {
        struct module_kobject *mk;
+       int ret;
 
        mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
        BUG_ON(!mk);
@@ -554,7 +555,8 @@ static void __init kernel_param_sysfs_setup(const char *name,
        mk->mod = THIS_MODULE;
        kobj_set_kset_s(mk, module_subsys);
        kobject_set_name(&mk->kobj, name);
-       kobject_register(&mk->kobj);
+       ret = kobject_register(&mk->kobj);
+       BUG_ON(ret < 0);
 
        /* no need to keep the kobject if no parameter is exported */
        if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
@@ -684,13 +686,20 @@ decl_subsys(module, &module_ktype, NULL);
  */
 static int __init param_sysfs_init(void)
 {
-       subsystem_register(&module_subsys);
+       int ret;
+
+       ret = subsystem_register(&module_subsys);
+       if (ret < 0) {
+               printk(KERN_WARNING "%s (%d): subsystem_register error: %d\n",
+                       __FILE__, __LINE__, ret);
+               return ret;
+       }
 
        param_sysfs_builtin();
 
        return 0;
 }
-__initcall(param_sysfs_init);
+subsys_initcall(param_sysfs_init);
 
 EXPORT_SYMBOL(param_set_byte);
 EXPORT_SYMBOL(param_get_byte);
index d38d9ec3276c3069c1259744496e9d2a05fef117..479b16b44f79f6b639683c724405f51b3ecc156f 100644 (file)
@@ -1393,24 +1393,12 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
        }
 }
 
-static long posix_cpu_clock_nanosleep_restart(struct restart_block *);
-
-int posix_cpu_nsleep(const clockid_t which_clock, int flags,
-                    struct timespec *rqtp, struct timespec __user *rmtp)
+static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
+                           struct timespec *rqtp, struct itimerspec *it)
 {
-       struct restart_block *restart_block =
-           &current_thread_info()->restart_block;
        struct k_itimer timer;
        int error;
 
-       /*
-        * Diagnose required errors first.
-        */
-       if (CPUCLOCK_PERTHREAD(which_clock) &&
-           (CPUCLOCK_PID(which_clock) == 0 ||
-            CPUCLOCK_PID(which_clock) == current->pid))
-               return -EINVAL;
-
        /*
         * Set up a temporary timer and then wait for it to go off.
         */
@@ -1422,11 +1410,12 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags,
        timer.it_process = current;
        if (!error) {
                static struct itimerspec zero_it;
-               struct itimerspec it = { .it_value = *rqtp,
-                                        .it_interval = {} };
+
+               memset(it, 0, sizeof *it);
+               it->it_value = *rqtp;
 
                spin_lock_irq(&timer.it_lock);
-               error = posix_cpu_timer_set(&timer, flags, &it, NULL);
+               error = posix_cpu_timer_set(&timer, flags, it, NULL);
                if (error) {
                        spin_unlock_irq(&timer.it_lock);
                        return error;
@@ -1454,49 +1443,89 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags,
                 * We were interrupted by a signal.
                 */
                sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
-               posix_cpu_timer_set(&timer, 0, &zero_it, &it);
+               posix_cpu_timer_set(&timer, 0, &zero_it, it);
                spin_unlock_irq(&timer.it_lock);
 
-               if ((it.it_value.tv_sec | it.it_value.tv_nsec) == 0) {
+               if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
                        /*
                         * It actually did fire already.
                         */
                        return 0;
                }
 
+               error = -ERESTART_RESTARTBLOCK;
+       }
+
+       return error;
+}
+
+int posix_cpu_nsleep(const clockid_t which_clock, int flags,
+                    struct timespec *rqtp, struct timespec __user *rmtp)
+{
+       struct restart_block *restart_block =
+           &current_thread_info()->restart_block;
+       struct itimerspec it;
+       int error;
+
+       /*
+        * Diagnose required errors first.
+        */
+       if (CPUCLOCK_PERTHREAD(which_clock) &&
+           (CPUCLOCK_PID(which_clock) == 0 ||
+            CPUCLOCK_PID(which_clock) == current->pid))
+               return -EINVAL;
+
+       error = do_cpu_nanosleep(which_clock, flags, rqtp, &it);
+
+       if (error == -ERESTART_RESTARTBLOCK) {
+
+               if (flags & TIMER_ABSTIME)
+                       return -ERESTARTNOHAND;
                /*
-                * Report back to the user the time still remaining.
-                */
-               if (rmtp != NULL && !(flags & TIMER_ABSTIME) &&
-                   copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
+                * Report back to the user the time still remaining.
+                */
+               if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
                        return -EFAULT;
 
-               restart_block->fn = posix_cpu_clock_nanosleep_restart;
-               /* Caller already set restart_block->arg1 */
+               restart_block->fn = posix_cpu_nsleep_restart;
                restart_block->arg0 = which_clock;
                restart_block->arg1 = (unsigned long) rmtp;
                restart_block->arg2 = rqtp->tv_sec;
                restart_block->arg3 = rqtp->tv_nsec;
-
-               error = -ERESTART_RESTARTBLOCK;
        }
-
        return error;
 }
 
-static long
-posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block)
+long posix_cpu_nsleep_restart(struct restart_block *restart_block)
 {
        clockid_t which_clock = restart_block->arg0;
        struct timespec __user *rmtp;
        struct timespec t;
+       struct itimerspec it;
+       int error;
 
        rmtp = (struct timespec __user *) restart_block->arg1;
        t.tv_sec = restart_block->arg2;
        t.tv_nsec = restart_block->arg3;
 
        restart_block->fn = do_no_restart_syscall;
-       return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t, rmtp);
+       error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it);
+
+       if (error == -ERESTART_RESTARTBLOCK) {
+               /*
+                * Report back to the user the time still remaining.
+                */
+               if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
+                       return -EFAULT;
+
+               restart_block->fn = posix_cpu_nsleep_restart;
+               restart_block->arg0 = which_clock;
+               restart_block->arg1 = (unsigned long) rmtp;
+               restart_block->arg2 = t.tv_sec;
+               restart_block->arg3 = t.tv_nsec;
+       }
+       return error;
+
 }
 
 
@@ -1524,6 +1553,10 @@ static int process_cpu_nsleep(const clockid_t which_clock, int flags,
 {
        return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp);
 }
+static long process_cpu_nsleep_restart(struct restart_block *restart_block)
+{
+       return -EINVAL;
+}
 static int thread_cpu_clock_getres(const clockid_t which_clock,
                                   struct timespec *tp)
 {
@@ -1544,6 +1577,10 @@ static int thread_cpu_nsleep(const clockid_t which_clock, int flags,
 {
        return -EINVAL;
 }
+static long thread_cpu_nsleep_restart(struct restart_block *restart_block)
+{
+       return -EINVAL;
+}
 
 static __init int init_posix_cpu_timers(void)
 {
@@ -1553,6 +1590,7 @@ static __init int init_posix_cpu_timers(void)
                .clock_set = do_posix_clock_nosettime,
                .timer_create = process_cpu_timer_create,
                .nsleep = process_cpu_nsleep,
+               .nsleep_restart = process_cpu_nsleep_restart,
        };
        struct k_clock thread = {
                .clock_getres = thread_cpu_clock_getres,
@@ -1560,6 +1598,7 @@ static __init int init_posix_cpu_timers(void)
                .clock_set = do_posix_clock_nosettime,
                .timer_create = thread_cpu_timer_create,
                .nsleep = thread_cpu_nsleep,
+               .nsleep_restart = thread_cpu_nsleep_restart,
        };
 
        register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
index ac6dc8744429f986f2f6c6b628513b2524316374..e5ebcc1ec3a0f4c612ca4f9db9ead45d07d424ce 100644 (file)
@@ -973,3 +973,24 @@ sys_clock_nanosleep(const clockid_t which_clock, int flags,
        return CLOCK_DISPATCH(which_clock, nsleep,
                              (which_clock, flags, &t, rmtp));
 }
+
+/*
+ * nanosleep_restart for monotonic and realtime clocks
+ */
+static int common_nsleep_restart(struct restart_block *restart_block)
+{
+       return hrtimer_nanosleep_restart(restart_block);
+}
+
+/*
+ * This will restart clock_nanosleep. This is required only by
+ * compat_clock_nanosleep_restart for now.
+ */
+long
+clock_nanosleep_restart(struct restart_block *restart_block)
+{
+       clockid_t which_clock = restart_block->arg0;
+
+       return CLOCK_DISPATCH(which_clock, nsleep_restart,
+                             (restart_block));
+}
index 8aad0331d82eae17482a37056c0368a8e6274661..4d50e06fd745cf28fc940252d856b51d1b372110 100644 (file)
@@ -440,6 +440,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
        child = find_task_by_pid(pid);
        if (child)
                get_task_struct(child);
+
        read_unlock(&tasklist_lock);
        if (!child)
                return ERR_PTR(-ESRCH);
index 4d1c3d2471278ebe93e00d7291eb253e83f7d89a..4f2c4272d59c91bda58823e8f6e04e121c85458d 100644 (file)
@@ -192,13 +192,13 @@ static struct rcu_torture_ops *cur_ops = NULL;
  * Definitions for rcu torture testing.
  */
 
-static int rcu_torture_read_lock(void)
+static int rcu_torture_read_lock(void) __acquires(RCU)
 {
        rcu_read_lock();
        return 0;
 }
 
-static void rcu_torture_read_unlock(int idx)
+static void rcu_torture_read_unlock(int idx) __releases(RCU)
 {
        rcu_read_unlock();
 }
@@ -250,13 +250,13 @@ static struct rcu_torture_ops rcu_ops = {
  * Definitions for rcu_bh torture testing.
  */
 
-static int rcu_bh_torture_read_lock(void)
+static int rcu_bh_torture_read_lock(void) __acquires(RCU_BH)
 {
        rcu_read_lock_bh();
        return 0;
 }
 
-static void rcu_bh_torture_read_unlock(int idx)
+static void rcu_bh_torture_read_unlock(int idx) __releases(RCU_BH)
 {
        rcu_read_unlock_bh();
 }
index 85786ff2a4f9b1a9f79ecedb646c316a56a292e6..1d63ecddfa7018cd4a14f8b6dc24c352a9ddc447 100644 (file)
@@ -95,7 +95,7 @@ int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
  *     @buf: the buffer struct
  *     @size: total size of the buffer
  *
- *     Returns a pointer to the resulting buffer, NULL if unsuccessful. The
+ *     Returns a pointer to the resulting buffer, %NULL if unsuccessful. The
  *     passed in size will get page aligned, if it isn't already.
  */
 static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
@@ -132,10 +132,9 @@ depopulate:
 
 /**
  *     relay_create_buf - allocate and initialize a channel buffer
- *     @alloc_size: size of the buffer to allocate
- *     @n_subbufs: number of sub-buffers in the channel
+ *     @chan: the relay channel
  *
- *     Returns channel buffer if successful, NULL otherwise
+ *     Returns channel buffer if successful, %NULL otherwise.
  */
 struct rchan_buf *relay_create_buf(struct rchan *chan)
 {
@@ -163,6 +162,7 @@ free_buf:
 
 /**
  *     relay_destroy_channel - free the channel struct
+ *     @kref: target kernel reference that contains the relay channel
  *
  *     Should only be called from kref_put().
  */
@@ -194,6 +194,7 @@ void relay_destroy_buf(struct rchan_buf *buf)
 
 /**
  *     relay_remove_buf - remove a channel buffer
+ *     @kref: target kernel reference that contains the relay buffer
  *
  *     Removes the file from the fileystem, which also frees the
  *     rchan_buf_struct and the channel buffer.  Should only be called from
@@ -374,7 +375,7 @@ void relay_reset(struct rchan *chan)
 }
 EXPORT_SYMBOL_GPL(relay_reset);
 
-/**
+/*
  *     relay_open_buf - create a new relay channel buffer
  *
  *     Internal - used by relay_open().
@@ -448,12 +449,12 @@ static inline void setup_callbacks(struct rchan *chan,
 /**
  *     relay_open - create a new relay channel
  *     @base_filename: base name of files to create
- *     @parent: dentry of parent directory, NULL for root directory
+ *     @parent: dentry of parent directory, %NULL for root directory
  *     @subbuf_size: size of sub-buffers
  *     @n_subbufs: number of sub-buffers
  *     @cb: client callback functions
  *
- *     Returns channel pointer if successful, NULL otherwise.
+ *     Returns channel pointer if successful, %NULL otherwise.
  *
  *     Creates a channel buffer for each cpu using the sizes and
  *     attributes specified.  The created channel buffer files
@@ -585,7 +586,7 @@ EXPORT_SYMBOL_GPL(relay_switch_subbuf);
  *     subbufs_consumed should be the number of sub-buffers newly consumed,
  *     not the total consumed.
  *
- *     NOTE: kernel clients don't need to call this function if the channel
+ *     NOTE: Kernel clients don't need to call this function if the channel
  *     mode is 'overwrite'.
  */
 void relay_subbufs_consumed(struct rchan *chan,
@@ -641,7 +642,7 @@ EXPORT_SYMBOL_GPL(relay_close);
  *     relay_flush - close the channel
  *     @chan: the channel
  *
- *     Flushes all channel buffers i.e. forces buffer switch.
+ *     Flushes all channel buffers, i.e. forces buffer switch.
  */
 void relay_flush(struct rchan *chan)
 {
@@ -729,7 +730,7 @@ static int relay_file_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-/**
+/*
  *     relay_file_read_consume - update the consumed count for the buffer
  */
 static void relay_file_read_consume(struct rchan_buf *buf,
@@ -756,7 +757,7 @@ static void relay_file_read_consume(struct rchan_buf *buf,
        }
 }
 
-/**
+/*
  *     relay_file_read_avail - boolean, are there unconsumed bytes available?
  */
 static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
@@ -793,6 +794,8 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
 
 /**
  *     relay_file_read_subbuf_avail - return bytes available in sub-buffer
+ *     @read_pos: file read position
+ *     @buf: relay channel buffer
  */
 static size_t relay_file_read_subbuf_avail(size_t read_pos,
                                           struct rchan_buf *buf)
@@ -818,6 +821,8 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos,
 
 /**
  *     relay_file_read_start_pos - find the first available byte to read
+ *     @read_pos: file read position
+ *     @buf: relay channel buffer
  *
  *     If the read_pos is in the middle of padding, return the
  *     position of the first actually available byte, otherwise
@@ -844,6 +849,9 @@ static size_t relay_file_read_start_pos(size_t read_pos,
 
 /**
  *     relay_file_read_end_pos - return the new read position
+ *     @read_pos: file read position
+ *     @buf: relay channel buffer
+ *     @count: number of bytes to be read
  */
 static size_t relay_file_read_end_pos(struct rchan_buf *buf,
                                      size_t read_pos,
@@ -865,7 +873,7 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
        return end_pos;
 }
 
-/**
+/*
  *     subbuf_read_actor - read up to one subbuf's worth of data
  */
 static int subbuf_read_actor(size_t read_start,
@@ -890,7 +898,7 @@ static int subbuf_read_actor(size_t read_start,
        return ret;
 }
 
-/**
+/*
  *     subbuf_send_actor - send up to one subbuf's worth of data
  */
 static int subbuf_send_actor(size_t read_start,
@@ -933,7 +941,7 @@ typedef int (*subbuf_actor_t) (size_t read_start,
                               read_descriptor_t *desc,
                               read_actor_t actor);
 
-/**
+/*
  *     relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
  */
 static inline ssize_t relay_file_read_subbufs(struct file *filp,
index 3e13a1e5856fecf8a06eab48372d12a01efb428b..4ab17da46fd80de1690744f9022691923942cb70 100644 (file)
@@ -251,6 +251,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
 
        /* Grab the next task */
        task = rt_mutex_owner(lock);
+       get_task_struct(task);
        spin_lock_irqsave(&task->pi_lock, flags);
 
        if (waiter == rt_mutex_top_waiter(lock)) {
@@ -269,7 +270,6 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                __rt_mutex_adjust_prio(task);
        }
 
-       get_task_struct(task);
        spin_unlock_irqrestore(&task->pi_lock, flags);
 
        top_waiter = rt_mutex_top_waiter(lock);
@@ -409,7 +409,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
        struct task_struct *owner = rt_mutex_owner(lock);
        struct rt_mutex_waiter *top_waiter = waiter;
        unsigned long flags;
-       int boost = 0, res;
+       int chain_walk = 0, res;
 
        spin_lock_irqsave(&current->pi_lock, flags);
        __rt_mutex_adjust_prio(current);
@@ -433,25 +433,23 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
                plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
 
                __rt_mutex_adjust_prio(owner);
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
-               spin_unlock_irqrestore(&owner->pi_lock, flags);
-       }
-       else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
-               spin_lock_irqsave(&owner->pi_lock, flags);
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
+               if (owner->pi_blocked_on)
+                       chain_walk = 1;
                spin_unlock_irqrestore(&owner->pi_lock, flags);
        }
-       if (!boost)
+       else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+               chain_walk = 1;
+
+       if (!chain_walk)
                return 0;
 
+       /*
+        * The owner can't disappear while holding a lock,
+        * so the owner struct is protected by wait_lock.
+        * Gets dropped in rt_mutex_adjust_prio_chain()!
+        */
+       get_task_struct(owner);
+
        spin_unlock(&lock->wait_lock);
 
        res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
@@ -532,7 +530,7 @@ static void remove_waiter(struct rt_mutex *lock,
        int first = (waiter == rt_mutex_top_waiter(lock));
        struct task_struct *owner = rt_mutex_owner(lock);
        unsigned long flags;
-       int boost = 0;
+       int chain_walk = 0;
 
        spin_lock_irqsave(&current->pi_lock, flags);
        plist_del(&waiter->list_entry, &lock->wait_list);
@@ -554,19 +552,20 @@ static void remove_waiter(struct rt_mutex *lock,
                }
                __rt_mutex_adjust_prio(owner);
 
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
+               if (owner->pi_blocked_on)
+                       chain_walk = 1;
+
                spin_unlock_irqrestore(&owner->pi_lock, flags);
        }
 
        WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
 
-       if (!boost)
+       if (!chain_walk)
                return;
 
+       /* gets dropped in rt_mutex_adjust_prio_chain()! */
+       get_task_struct(owner);
+
        spin_unlock(&lock->wait_lock);
 
        rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
@@ -592,10 +591,10 @@ void rt_mutex_adjust_pi(struct task_struct *task)
                return;
        }
 
-       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-       get_task_struct(task);
        spin_unlock_irqrestore(&task->pi_lock, flags);
 
+       /* gets dropped in rt_mutex_adjust_prio_chain()! */
+       get_task_struct(task);
        rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
 }
 
index 5c848fd4e461c67bded9c27b81405889a80cd656..74f169ac0773cd2ac3eeac0bfbb3c3a631d70c65 100644 (file)
@@ -1755,27 +1755,27 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev)
        __releases(rq->lock)
 {
        struct mm_struct *mm = rq->prev_mm;
-       unsigned long prev_task_flags;
+       long prev_state;
 
        rq->prev_mm = NULL;
 
        /*
         * A task struct has one reference for the use as "current".
-        * If a task dies, then it sets EXIT_ZOMBIE in tsk->exit_state and
-        * calls schedule one last time. The schedule call will never return,
-        * and the scheduled task must drop that reference.
-        * The test for EXIT_ZOMBIE must occur while the runqueue locks are
+        * If a task dies, then it sets TASK_DEAD in tsk->state and calls
+        * schedule one last time. The schedule call will never return, and
+        * the scheduled task must drop that reference.
+        * The test for TASK_DEAD must occur while the runqueue locks are
         * still held, otherwise prev could be scheduled on another cpu, die
         * there before we look at prev->state, and then the reference would
         * be dropped twice.
         *              Manfred Spraul <manfred@colorfullife.com>
         */
-       prev_task_flags = prev->flags;
+       prev_state = prev->state;
        finish_arch_switch(prev);
        finish_lock_switch(rq, prev);
        if (mm)
                mmdrop(mm);
-       if (unlikely(prev_task_flags & PF_DEAD)) {
+       if (unlikely(prev_state == TASK_DEAD)) {
                /*
                 * Remove function-return probe instances associated with this
                 * task and put them back on the free list.
@@ -3348,9 +3348,6 @@ need_resched_nonpreemptible:
 
        spin_lock_irq(&rq->lock);
 
-       if (unlikely(prev->flags & PF_DEAD))
-               prev->state = EXIT_DEAD;
-
        switch_count = &prev->nivcsw;
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                switch_count = &prev->nvcsw;
@@ -4080,6 +4077,8 @@ static void __setscheduler(struct task_struct *p, int policy, int prio)
  * @p: the task in question.
  * @policy: new policy.
  * @param: structure containing the new RT priority.
+ *
+ * NOTE: the task may be already dead
  */
 int sched_setscheduler(struct task_struct *p, int policy,
                       struct sched_param *param)
@@ -4107,28 +4106,32 @@ recheck:
            (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
            (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
                return -EINVAL;
-       if ((policy == SCHED_NORMAL || policy == SCHED_BATCH)
-                                       != (param->sched_priority == 0))
+       if (is_rt_policy(policy) != (param->sched_priority != 0))
                return -EINVAL;
 
        /*
         * Allow unprivileged RT tasks to decrease priority:
         */
        if (!capable(CAP_SYS_NICE)) {
-               /*
-                * can't change policy, except between SCHED_NORMAL
-                * and SCHED_BATCH:
-                */
-               if (((policy != SCHED_NORMAL && p->policy != SCHED_BATCH) &&
-                       (policy != SCHED_BATCH && p->policy != SCHED_NORMAL)) &&
-                               !p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
-                       return -EPERM;
-               /* can't increase priority */
-               if ((policy != SCHED_NORMAL && policy != SCHED_BATCH) &&
-                   param->sched_priority > p->rt_priority &&
-                   param->sched_priority >
-                               p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
-                       return -EPERM;
+               if (is_rt_policy(policy)) {
+                       unsigned long rlim_rtprio;
+                       unsigned long flags;
+
+                       if (!lock_task_sighand(p, &flags))
+                               return -ESRCH;
+                       rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
+                       unlock_task_sighand(p, &flags);
+
+                       /* can't set/change the rt policy */
+                       if (policy != p->policy && !rlim_rtprio)
+                               return -EPERM;
+
+                       /* can't increase priority */
+                       if (param->sched_priority > p->rt_priority &&
+                           param->sched_priority > rlim_rtprio)
+                               return -EPERM;
+               }
+
                /* can't change other user's priorities */
                if ((current->euid != p->euid) &&
                    (current->euid != p->uid))
@@ -4193,14 +4196,13 @@ do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
                return -EINVAL;
        if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
                return -EFAULT;
-       read_lock_irq(&tasklist_lock);
+
+       rcu_read_lock();
+       retval = -ESRCH;
        p = find_process_by_pid(pid);
-       if (!p) {
-               read_unlock_irq(&tasklist_lock);
-               return -ESRCH;
-       }
-       retval = sched_setscheduler(p, policy, &lparam);
-       read_unlock_irq(&tasklist_lock);
+       if (p != NULL)
+               retval = sched_setscheduler(p, policy, &lparam);
+       rcu_read_unlock();
 
        return retval;
 }
@@ -5151,7 +5153,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
        BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD);
 
        /* Cannot have done final schedule yet: would have vanished. */
-       BUG_ON(p->flags & PF_DEAD);
+       BUG_ON(p->state == TASK_DEAD);
 
        get_task_struct(p);
 
@@ -5272,9 +5274,11 @@ static struct notifier_block __cpuinitdata migration_notifier = {
 int __init migration_init(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
+       int err;
 
        /* Start one for the boot CPU: */
-       migration_call(&migration_notifier, CPU_UP_PREPARE, cpu);
+       err = migration_call(&migration_notifier, CPU_UP_PREPARE, cpu);
+       BUG_ON(err == NOTIFY_BAD);
        migration_call(&migration_notifier, CPU_ONLINE, cpu);
        register_cpu_notifier(&migration_notifier);
 
index 05853a7337e3268be684ae2f53248b6e9fc75e56..fb5da6d19f14eef721f28750307c9654f17a8bfa 100644 (file)
@@ -417,9 +417,8 @@ static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
                        siginfo_t *info)
 {
-       int sig = 0;
+       int sig = next_signal(pending, mask);
 
-       sig = next_signal(pending, mask);
        if (sig) {
                if (current->notifier) {
                        if (sigismember(current->notifier_mask, sig)) {
@@ -432,9 +431,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
 
                if (!collect_signal(sig, pending, info))
                        sig = 0;
-                               
        }
-       recalc_sigpending();
 
        return sig;
 }
@@ -451,6 +448,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
        if (!signr)
                signr = __dequeue_signal(&tsk->signal->shared_pending,
                                         mask, info);
+       recalc_sigpending_tsk(tsk);
        if (signr && unlikely(sig_kernel_stop(signr))) {
                /*
                 * Set a marker that we have dequeued a stop signal.  Our
index 3789ca98197c2a793b25dc6ac403e26202312133..bf25015dce162a541059c051567c3569069985b9 100644 (file)
@@ -612,7 +612,9 @@ static struct notifier_block __cpuinitdata cpu_nfb = {
 __init int spawn_ksoftirqd(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
-       cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+       int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+
+       BUG_ON(err == NOTIFY_BAD);
        cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
        register_cpu_notifier(&cpu_nfb);
        return 0;
index 03e6a2b0b787a97f426887f6ecdf709951acaced..50afeb813305d76435e8c6852a80b5b9dc5c8cd9 100644 (file)
@@ -149,8 +149,9 @@ static struct notifier_block __cpuinitdata cpu_nfb = {
 __init void spawn_softlockup_task(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
+       int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
 
-       cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+       BUG_ON(err == NOTIFY_BAD);
        cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
        register_cpu_notifier(&cpu_nfb);
 
index 9644a41e0bef60fd40773976705c6529b49c45d1..d48143eafbfde6388717e67c1c3b74011ea8a747 100644 (file)
 #include <linux/debug_locks.h>
 #include <linux/module.h>
 
-/*
- * Generic declaration of the raw read_trylock() function,
- * architectures are supposed to optimize this:
- */
-int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock)
-{
-       __raw_read_lock(lock);
-       return 1;
-}
-EXPORT_SYMBOL(generic__raw_read_trylock);
-
 int __lockfunc _spin_trylock(spinlock_t *lock)
 {
        preempt_disable();
index 51cacd111dbd8412c35a1d9578cfb3d7eaf86c6a..12458040e66500aec1040b91448c458972d08d69 100644 (file)
@@ -1,3 +1,6 @@
+/* Copyright 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
+ * GPL v2 and any later version.
+ */
 #include <linux/stop_machine.h>
 #include <linux/kthread.h>
 #include <linux/sched.h>
index 3f894775488dd7fb62907d149d0d1959b67de049..b88806c66244b2df825f6bb43bbb20b251cce21c 100644 (file)
@@ -612,7 +612,6 @@ void kernel_restart(char *cmd)
        } else {
                printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
        }
-       printk(".\n");
        machine_restart(cmd);
 }
 EXPORT_SYMBOL_GPL(kernel_restart);
@@ -2084,12 +2083,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 8bfa7d117c54fb8ef2b0e5e458caf3303e17b366..c57c4532e29610c5fa42a29d79085bed85f354a5 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. */
@@ -74,13 +78,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;
@@ -1915,7 +1912,7 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
                return -EPERM;
        }
 
-       op = (current->pid == 1) ? OP_SET : OP_AND;
+       op = is_init(current) ? OP_SET : OP_AND;
        return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
                                do_proc_dointvec_bset_conv,&op);
 }
index 1d7dd6267c2de52206bb2f09ca981ff81db4b1a1..4f55622b0d38462ad59b28322d31ebeee8a0c40c 100644 (file)
@@ -136,7 +136,7 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
        list_add_tail(&timer->entry, vec);
 }
 
-/***
+/**
  * init_timer - initialize a timer.
  * @timer: the timer to be initialized
  *
@@ -175,6 +175,7 @@ static inline void detach_timer(struct timer_list *timer,
  */
 static tvec_base_t *lock_timer_base(struct timer_list *timer,
                                        unsigned long *flags)
+       __acquires(timer->base->lock)
 {
        tvec_base_t *base;
 
@@ -235,7 +236,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
 
 EXPORT_SYMBOL(__mod_timer);
 
-/***
+/**
  * add_timer_on - start a timer on a particular CPU
  * @timer: the timer to be added
  * @cpu: the CPU to start it on
@@ -255,9 +256,10 @@ void add_timer_on(struct timer_list *timer, int cpu)
 }
 
 
-/***
+/**
  * mod_timer - modify a timer's timeout
  * @timer: the timer to be modified
+ * @expires: new timeout in jiffies
  *
  * mod_timer is a more efficient way to update the expire field of an
  * active timer (if the timer is inactive it will be activated)
@@ -291,7 +293,7 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
 
 EXPORT_SYMBOL(mod_timer);
 
-/***
+/**
  * del_timer - deactive a timer.
  * @timer: the timer to be deactivated
  *
@@ -323,7 +325,10 @@ int del_timer(struct timer_list *timer)
 EXPORT_SYMBOL(del_timer);
 
 #ifdef CONFIG_SMP
-/*
+/**
+ * try_to_del_timer_sync - Try to deactivate a timer
+ * @timer: timer do del
+ *
  * This function tries to deactivate a timer. Upon successful (ret >= 0)
  * exit the timer is not queued and the handler is not running on any CPU.
  *
@@ -351,7 +356,7 @@ out:
        return ret;
 }
 
-/***
+/**
  * del_timer_sync - deactivate a timer and wait for the handler to finish.
  * @timer: the timer to be deactivated
  *
@@ -401,15 +406,15 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
        return index;
 }
 
-/***
+#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
+
+/**
  * __run_timers - run all expired timers (if any) on this CPU.
  * @base: the timer vector to be processed.
  *
  * This function cascades all vectors and executes all expired timer
  * vectors.
  */
-#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
-
 static inline void __run_timers(tvec_base_t *base)
 {
        struct timer_list *timer;
@@ -970,7 +975,7 @@ void __init timekeeping_init(void)
 
 
 static int timekeeping_suspended;
-/*
+/**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  * @dev:       unused
  *
@@ -1106,7 +1111,7 @@ static void clocksource_adjust(struct clocksource *clock, s64 offset)
        clock->error -= (interval - offset) << (TICK_LENGTH_SHIFT - clock->shift);
 }
 
-/*
+/**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
  * Called from the timer interrupt, must hold a write on xtime_lock.
@@ -1217,10 +1222,8 @@ static inline void calc_load(unsigned long ticks)
        unsigned long active_tasks; /* fixed-point */
        static int count = LOAD_FREQ;
 
-       count -= ticks;
-       if (count < 0) {
-               count += LOAD_FREQ;
-               active_tasks = count_active_tasks();
+       active_tasks = count_active_tasks();
+       for (count -= ticks; count < 0; count += LOAD_FREQ) {
                CALC_LOAD(avenrun[0], EXP_1, active_tasks);
                CALC_LOAD(avenrun[1], EXP_5, active_tasks);
                CALC_LOAD(avenrun[2], EXP_15, active_tasks);
@@ -1265,11 +1268,8 @@ void run_local_timers(void)
  * Called by the timer interrupt. xtime_lock must already be taken
  * by the timer IRQ!
  */
-static inline void update_times(void)
+static inline void update_times(unsigned long ticks)
 {
-       unsigned long ticks;
-
-       ticks = jiffies - wall_jiffies;
        wall_jiffies += ticks;
        update_wall_time();
        calc_load(ticks);
@@ -1281,12 +1281,10 @@ static inline void update_times(void)
  * jiffies is defined in the linker script...
  */
 
-void do_timer(struct pt_regs *regs)
+void do_timer(unsigned long ticks)
 {
-       jiffies_64++;
-       /* prevent loading jiffies before storing new jiffies_64 value. */
-       barrier();
-       update_times();
+       jiffies_64 += ticks;
+       update_times(ticks);
 }
 
 #ifdef __ARCH_WANT_SYS_ALARM
@@ -1470,8 +1468,9 @@ asmlinkage long sys_gettid(void)
        return current->pid;
 }
 
-/*
+/**
  * sys_sysinfo - fill in sysinfo struct
+ * @info: pointer to buffer to fill
  */ 
 asmlinkage long sys_sysinfo(struct sysinfo __user *info)
 {
@@ -1688,8 +1687,10 @@ static struct notifier_block __cpuinitdata timers_nb = {
 
 void __init init_timers(void)
 {
-       timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
+       int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
                                (void *)(long)smp_processor_id());
+
+       BUG_ON(err == NOTIFY_BAD);
        register_cpu_notifier(&timers_nb);
        open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);
 }
index 3430475fcd886d011c01370a558e0a5965dd950d..2e2368607aab1a8293739315d832c608463d8d5f 100644 (file)
@@ -102,7 +102,7 @@ static struct unwind_table {
        unsigned long size;
        struct unwind_table *link;
        const char *name;
-} root_table, *last_table;
+} root_table;
 
 struct unwind_item {
        enum item_location {
@@ -174,6 +174,8 @@ void __init unwind_init(void)
 
 #ifdef CONFIG_MODULES
 
+static struct unwind_table *last_table;
+
 /* Must be called with module_mutex held. */
 void *unwind_add_table(struct module *module,
                        const void *table_start,
index b0f5ca72599fee5f4ed868457a85c39b5f6e57ef..f9ae75cc014566b95609983b803e0ef6282723f8 100644 (file)
@@ -320,6 +320,15 @@ config DEBUG_VM
 
          If unsure, say N.
 
+config DEBUG_LIST
+       bool "Debug linked list manipulation"
+       depends on DEBUG_KERNEL
+       help
+         Enable this to turn on extended checks in the linked-list
+         walking routines.
+
+         If unsure, say N.
+
 config FRAME_POINTER
        bool "Compile the kernel with frame pointers"
        depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH)
index ef1d37afbbb66df24e3b60ccb304c063abe981f1..402762fead70f6b8e8384b84d85f89d70e7d63f1 100644 (file)
@@ -28,6 +28,7 @@ lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 obj-$(CONFIG_PLIST) += plist.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
+obj-$(CONFIG_DEBUG_LIST) += list_debug.o
 
 ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
   lib-y += dec_and_lock.o
diff --git a/lib/list_debug.c b/lib/list_debug.c
new file mode 100644 (file)
index 0000000..e80d27c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2006, Red Hat, Inc., Dave Jones
+ * Released under the General Public License (GPL).
+ *
+ * This file contains the linked list implementations for
+ * DEBUG_LIST.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+
+void __list_add(struct list_head *new,
+                             struct list_head *prev,
+                             struct list_head *next)
+{
+       if (unlikely(next->prev != prev)) {
+               printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n",
+                       prev, next->prev);
+               BUG();
+       }
+       if (unlikely(prev->next != next)) {
+               printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n",
+                       next, prev->next);
+               BUG();
+       }
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+EXPORT_SYMBOL(__list_add);
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+EXPORT_SYMBOL(list_add);
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+void list_del(struct list_head *entry)
+{
+       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);
+               BUG();
+       }
+       if (unlikely(entry->next->prev != entry)) {
+               printk(KERN_ERR "list_del corruption. next->prev should be %p, "
+                               "but was %p\n", entry, entry->next->prev);
+               BUG();
+       }
+       __list_del(entry->prev, entry->next);
+       entry->next = LIST_POISON1;
+       entry->prev = LIST_POISON2;
+}
+EXPORT_SYMBOL(list_del);
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 b322421c2969f1e3046313e91dcd3a07aa3fca9a..901d0e7da89220fae47848d349633ae43c1afd7e 100644 (file)
@@ -146,7 +146,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
 /*
  * wait for a lock to be granted
  */
-static inline struct rw_semaphore *
+static struct rw_semaphore *
 rwsem_down_failed_common(struct rw_semaphore *sem,
                        struct rwsem_waiter *waiter, signed long adjustment)
 {
index 58c577dd82e5240e551d151b73ea31c55de8c309..dafaf1de2491aedb0a323aed4951e5084e58e18c 100644 (file)
@@ -99,11 +99,12 @@ static inline void debug_spin_unlock(spinlock_t *lock)
 
 static void __spin_lock_debug(spinlock_t *lock)
 {
-       int print_once = 1;
        u64 i;
+       u64 loops = loops_per_jiffy * HZ;
+       int print_once = 1;
 
        for (;;) {
-               for (i = 0; i < loops_per_jiffy * HZ; i++) {
+               for (i = 0; i < loops; i++) {
                        if (__raw_spin_trylock(&lock->raw_lock))
                                return;
                        __delay(1);
@@ -165,11 +166,12 @@ static void rwlock_bug(rwlock_t *lock, const char *msg)
 #if 0          /* __write_lock_debug() can lock up - maybe this can too? */
 static void __read_lock_debug(rwlock_t *lock)
 {
-       int print_once = 1;
        u64 i;
+       u64 loops = loops_per_jiffy * HZ;
+       int print_once = 1;
 
        for (;;) {
-               for (i = 0; i < loops_per_jiffy * HZ; i++) {
+               for (i = 0; i < loops; i++) {
                        if (__raw_read_trylock(&lock->raw_lock))
                                return;
                        __delay(1);
@@ -239,11 +241,12 @@ static inline void debug_write_unlock(rwlock_t *lock)
 #if 0          /* This can cause lockups */
 static void __write_lock_debug(rwlock_t *lock)
 {
-       int print_once = 1;
        u64 i;
+       u64 loops = loops_per_jiffy * HZ;
+       int print_once = 1;
 
        for (;;) {
-               for (i = 0; i < loops_per_jiffy * HZ; i++) {
+               for (i = 0; i < loops; i++) {
                        if (__raw_write_trylock(&lock->raw_lock))
                                return;
                        __delay(1);
index 87847c2ae9e28d9330c28df80dbef75ad99206b4..af575b61526b97749c31bb65221af72eb457353c 100644 (file)
  *
  *   A finite state machine consists of n states (struct ts_fsm_token)
  *   representing the pattern as a finite automation. The data is read
- *   sequentially on a octet basis. Every state token specifies the number
+ *   sequentially on an octet basis. Every state token specifies the number
  *   of recurrences and the type of value accepted which can be either a
  *   specific character or ctype based set of characters. The available
  *   type of recurrences include 1, (0|1), [0 n], and [1 n].
  *
- *   The algorithm differs between strict/non-strict mode specyfing
- *   whether the pattern has to start at the first octect. Strict mode
+ *   The algorithm differs between strict/non-strict mode specifying
+ *   whether the pattern has to start at the first octet. Strict mode
  *   is enabled by default and can be disabled by inserting
  *   TS_FSM_HEAD_IGNORE as the first token in the chain.
  *
@@ -44,7 +44,7 @@ struct ts_fsm
 #define _W             0x200 /* wildcard */
 
 /* Map to _ctype flags and some magic numbers */
-static u16 token_map[TS_FSM_TYPE_MAX+1] = {
+static const u16 token_map[TS_FSM_TYPE_MAX+1] = {
        [TS_FSM_SPECIFIC] = 0,
        [TS_FSM_WILDCARD] = _W,
        [TS_FSM_CNTRL]    = _C,
@@ -61,7 +61,7 @@ static u16 token_map[TS_FSM_TYPE_MAX+1] = {
        [TS_FSM_ASCII]    = _A,
 };
 
-static u16 token_lookup_tbl[256] = {
+static const u16 token_lookup_tbl[256] = {
 _W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,           /*   0-  3 */
 _W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,           /*   4-  7 */
 _W|_A|_C,      _W|_A|_C|_S,  _W|_A|_C|_S,  _W|_A|_C|_S,                /*   8- 11 */
index 60c56c0b5e1049218d38bf81df35ae897dbfdc5a..12b3a4eee88d56a3b4d4fe6c4255fa4a1ca81352 100644 (file)
@@ -12,11 +12,15 @@ obj-y                       := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
                           readahead.o swap.o truncate.o vmscan.o \
                           prio_tree.o util.o mmzone.o vmstat.o $(mmu-y)
 
+ifeq ($(CONFIG_MMU)$(CONFIG_BLOCK),yy)
+obj-y                  += bounce.o
+endif
 obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HUGETLBFS)        += hugetlb.o
 obj-$(CONFIG_NUMA)     += mempolicy.o
 obj-$(CONFIG_SPARSEMEM)        += sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
+obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
 obj-$(CONFIG_SLOB) += slob.o
 obj-$(CONFIG_SLAB) += slab.o
diff --git a/mm/bounce.c b/mm/bounce.c
new file mode 100644 (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 afcdc72b5e906658475a8ff47b5e3dcd389c0188..c4fe97f5ace0851d3023d1305d8de5c7ad2b1dd5 100644 (file)
@@ -1471,7 +1471,7 @@ outside_data_content:
         * accessible..
         */
        if (area->vm_mm == current->mm)
-               return NULL;
+               return NOPAGE_SIGBUS;
        /* Fall through to the non-read-ahead case */
 no_cached_page:
        /*
@@ -1496,7 +1496,7 @@ no_cached_page:
         */
        if (error == -ENOMEM)
                return NOPAGE_OOM;
-       return NULL;
+       return NOPAGE_SIGBUS;
 
 page_not_uptodate:
        if (!did_readaround) {
@@ -1565,7 +1565,7 @@ page_not_uptodate:
         */
        shrink_readahead_size_eio(file, ra);
        page_cache_release(page);
-       return NULL;
+       return NOPAGE_SIGBUS;
 }
 EXPORT_SYMBOL(filemap_nopage);
 
@@ -2020,6 +2020,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 +2032,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;
 }
@@ -2491,3 +2495,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 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 601159a46ab64e538dc1c2cbe710776e3ecb5208..160f5b503eaddeb5880cc0c4ac63c08821074e5c 100644 (file)
@@ -1577,7 +1577,14 @@ gotten:
                entry = mk_pte(new_page, vma->vm_page_prot);
                entry = maybe_mkwrite(pte_mkdirty(entry), vma);
                lazy_mmu_prot_update(entry);
-               ptep_establish(vma, address, page_table, entry);
+               /*
+                * Clear the pte entry and flush it first, before updating the
+                * pte with the new entry. This will avoid a race condition
+                * seen in the presence of one thread doing SMC and another
+                * thread doing COW.
+                */
+               ptep_clear_flush(vma, address, page_table);
+               set_pte_at(mm, address, page_table, entry);
                update_mmu_cache(vma, address, entry);
                lru_cache_add_active(new_page);
                page_add_new_anon_rmap(new_page, vma, address);
index c37319542b700a92339fdfc4427a5fc4d6fa2ee4..2053bb165a21a81d4d32fce38a1cd528981d197d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/pagevec.h>
+#include <linux/writeback.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/cpu.h>
@@ -21,6 +22,7 @@
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
 #include <linux/ioport.h>
+#include <linux/cpuset.h>
 
 #include <asm/tlbflush.h>
 
@@ -191,6 +193,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
        if (need_zonelists_rebuild)
                build_all_zonelists();
        vm_total_pages = nr_free_pagecache_pages();
+       writeback_set_ratelimit();
        return 0;
 }
 
@@ -283,6 +286,8 @@ int add_memory(int nid, u64 start, u64 size)
        /* we online node here. we can't roll back from here. */
        node_set_online(nid);
 
+       cpuset_track_online_nodes();
+
        if (new_pgdat) {
                ret = register_one_node(nid);
                /*
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 bada3d03119ff01381d6d47c1b828b59c3867106..20f41b082e16484a8c52aa04272bf4f30359593c 100644 (file)
@@ -204,15 +204,29 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
        do_posix_clock_monotonic_gettime(&uptime);
        do_each_thread(g, p) {
                unsigned long points;
-               int releasing;
 
-               /* skip kernel threads */
+               /*
+                * skip kernel threads and tasks which have already released
+                * their mm.
+                */
                if (!p->mm)
                        continue;
-               /* skip the init task with pid == 1 */
-               if (p->pid == 1)
+               /* skip the init task */
+               if (is_init(p))
                        continue;
 
+               /*
+                * This task already has access to memory reserves and is
+                * being killed. Don't allow any other task access to the
+                * memory reserve.
+                *
+                * Note: this may have a chance of deadlock if it gets
+                * blocked waiting for another task which itself is waiting
+                * for memory. Is there a better alternative?
+                */
+               if (test_tsk_thread_flag(p, TIF_MEMDIE))
+                       return ERR_PTR(-1UL);
+
                /*
                 * This is in the process of releasing memory so wait for it
                 * to finish before killing some other task by mistake.
@@ -221,21 +235,16 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
                 * go ahead if it is exiting: this will simply set TIF_MEMDIE,
                 * which will allow it to gain access to memory reserves in
                 * the process of exiting and releasing its resources.
-                * Otherwise we could get an OOM deadlock.
+                * Otherwise we could get an easy OOM deadlock.
                 */
-               releasing = test_tsk_thread_flag(p, TIF_MEMDIE) ||
-                                               p->flags & PF_EXITING;
-               if (releasing) {
-                       /* PF_DEAD tasks have already released their mm */
-                       if (p->flags & PF_DEAD)
-                               continue;
-                       if (p->flags & PF_EXITING && p == current) {
-                               chosen = p;
-                               *ppoints = ULONG_MAX;
-                               break;
-                       }
-                       return ERR_PTR(-1UL);
+               if (p->flags & PF_EXITING) {
+                       if (p != current)
+                               return ERR_PTR(-1UL);
+
+                       chosen = p;
+                       *ppoints = ULONG_MAX;
                }
+
                if (p->oomkilladj == OOM_DISABLE)
                        continue;
 
@@ -245,6 +254,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
                        *ppoints = points;
                }
        } while_each_thread(g, p);
+
        return chosen;
 }
 
@@ -255,20 +265,17 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
  */
 static void __oom_kill_task(struct task_struct *p, const char *message)
 {
-       if (p->pid == 1) {
+       if (is_init(p)) {
                WARN_ON(1);
                printk(KERN_WARNING "tried to kill init!\n");
                return;
        }
 
-       task_lock(p);
-       if (!p->mm || p->mm == &init_mm) {
+       if (!p->mm) {
                WARN_ON(1);
                printk(KERN_WARNING "tried to kill an mm-less task!\n");
-               task_unlock(p);
                return;
        }
-       task_unlock(p);
 
        if (message) {
                printk(KERN_ERR "%s: Killed process %d (%s).\n",
@@ -302,7 +309,7 @@ static int oom_kill_task(struct task_struct *p, const char *message)
         * However, this is of no concern to us.
         */
 
-       if (mm == NULL || mm == &init_mm)
+       if (mm == NULL)
                return 1;
 
        __oom_kill_task(p, message);
index 555752907dc3111b8fea4f042f5b1440f041f28d..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
@@ -46,7 +48,6 @@
  */
 static long ratelimit_pages = 32;
 
-static long total_pages;       /* The total number of pages in the machine. */
 static int dirty_exceeded __cacheline_aligned_in_smp;  /* Dirty mem may be over limit */
 
 /*
@@ -126,7 +127,7 @@ get_dirty_limits(long *pbackground, long *pdirty,
        int unmapped_ratio;
        long background;
        long dirty;
-       unsigned long available_memory = total_pages;
+       unsigned long available_memory = vm_total_pages;
        struct task_struct *tsk;
 
 #ifdef CONFIG_HIGHMEM
@@ -141,7 +142,7 @@ get_dirty_limits(long *pbackground, long *pdirty,
 
        unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
                                global_page_state(NR_ANON_PAGES)) * 100) /
-                                       total_pages;
+                                       vm_total_pages;
 
        dirty_ratio = vm_dirty_ratio;
        if (dirty_ratio > unmapped_ratio / 2)
@@ -502,9 +503,9 @@ void laptop_sync_completion(void)
  * will write six megabyte chunks, max.
  */
 
-static void set_ratelimit(void)
+void writeback_set_ratelimit(void)
 {
-       ratelimit_pages = total_pages / (num_online_cpus() * 32);
+       ratelimit_pages = vm_total_pages / (num_online_cpus() * 32);
        if (ratelimit_pages < 16)
                ratelimit_pages = 16;
        if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024)
@@ -514,7 +515,7 @@ static void set_ratelimit(void)
 static int __cpuinit
 ratelimit_handler(struct notifier_block *self, unsigned long u, void *v)
 {
-       set_ratelimit();
+       writeback_set_ratelimit();
        return 0;
 }
 
@@ -533,9 +534,7 @@ void __init page_writeback_init(void)
        long buffer_pages = nr_free_buffer_pages();
        long correction;
 
-       total_pages = nr_free_pagecache_pages();
-
-       correction = (100 * 4 * buffer_pages) / total_pages;
+       correction = (100 * 4 * buffer_pages) / vm_total_pages;
 
        if (correction < 100) {
                dirty_background_ratio *= correction;
@@ -549,10 +548,143 @@ void __init page_writeback_init(void)
                        vm_dirty_ratio = 1;
        }
        mod_timer(&wb_timer, jiffies + dirty_writeback_interval);
-       set_ratelimit();
+       writeback_set_ratelimit();
        register_cpu_notifier(&ratelimit_nb);
 }
 
+/**
+ * generic_writepages - walk the list of dirty pages of the given
+ *                      address space and writepage() all of them.
+ *
+ * @mapping: address space structure to write
+ * @wbc: subtract the number of written pages from *@wbc->nr_to_write
+ *
+ * This is a library function, which implements the writepages()
+ * address_space_operation.
+ *
+ * If a page is already under I/O, generic_writepages() skips it, even
+ * if it's dirty.  This is desirable behaviour for memory-cleaning writeback,
+ * but it is INCORRECT for data-integrity system calls such as fsync().  fsync()
+ * and msync() need to guarantee that all the data which was dirty at the time
+ * the call was made get new I/O started against them.  If wbc->sync_mode is
+ * WB_SYNC_ALL then we were called for data integrity and we must wait for
+ * existing IO to complete.
+ *
+ * Derived from mpage_writepages() - if you fix this you should check that
+ * also!
+ */
+int generic_writepages(struct address_space *mapping,
+                      struct writeback_control *wbc)
+{
+       struct backing_dev_info *bdi = mapping->backing_dev_info;
+       int ret = 0;
+       int done = 0;
+       int (*writepage)(struct page *page, struct writeback_control *wbc);
+       struct pagevec pvec;
+       int nr_pages;
+       pgoff_t index;
+       pgoff_t end;            /* Inclusive */
+       int scanned = 0;
+       int range_whole = 0;
+
+       if (wbc->nonblocking && bdi_write_congested(bdi)) {
+               wbc->encountered_congestion = 1;
+               return 0;
+       }
+
+       writepage = mapping->a_ops->writepage;
+
+       /* deal with chardevs and other special file */
+       if (!writepage)
+               return 0;
+
+       pagevec_init(&pvec, 0);
+       if (wbc->range_cyclic) {
+               index = mapping->writeback_index; /* Start from prev offset */
+               end = -1;
+       } else {
+               index = wbc->range_start >> PAGE_CACHE_SHIFT;
+               end = wbc->range_end >> PAGE_CACHE_SHIFT;
+               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+                       range_whole = 1;
+               scanned = 1;
+       }
+retry:
+       while (!done && (index <= end) &&
+              (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+                                             PAGECACHE_TAG_DIRTY,
+                                             min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+               unsigned i;
+
+               scanned = 1;
+               for (i = 0; i < nr_pages; i++) {
+                       struct page *page = pvec.pages[i];
+
+                       /*
+                        * At this point we hold neither mapping->tree_lock nor
+                        * lock on the page itself: the page may be truncated or
+                        * invalidated (changing page->mapping to NULL), or even
+                        * swizzled back from swapper_space to tmpfs file
+                        * mapping
+                        */
+                       lock_page(page);
+
+                       if (unlikely(page->mapping != mapping)) {
+                               unlock_page(page);
+                               continue;
+                       }
+
+                       if (!wbc->range_cyclic && page->index > end) {
+                               done = 1;
+                               unlock_page(page);
+                               continue;
+                       }
+
+                       if (wbc->sync_mode != WB_SYNC_NONE)
+                               wait_on_page_writeback(page);
+
+                       if (PageWriteback(page) ||
+                           !clear_page_dirty_for_io(page)) {
+                               unlock_page(page);
+                               continue;
+                       }
+
+                       ret = (*writepage)(page, wbc);
+                       if (ret) {
+                               if (ret == -ENOSPC)
+                                       set_bit(AS_ENOSPC, &mapping->flags);
+                               else
+                                       set_bit(AS_EIO, &mapping->flags);
+                       }
+
+                       if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
+                               unlock_page(page);
+                       if (ret || (--(wbc->nr_to_write) <= 0))
+                               done = 1;
+                       if (wbc->nonblocking && bdi_write_congested(bdi)) {
+                               wbc->encountered_congestion = 1;
+                               done = 1;
+                       }
+               }
+               pagevec_release(&pvec);
+               cond_resched();
+       }
+       if (!scanned && !done) {
+               /*
+                * We hit the last page and there is more work to be done: wrap
+                * back to the start of the file
+                */
+               scanned = 1;
+               index = 0;
+               goto retry;
+       }
+       if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+               mapping->writeback_index = index;
+       return ret;
+}
+
+EXPORT_SYMBOL(generic_writepages);
+
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
        int ret;
@@ -675,9 +807,11 @@ int fastcall set_page_dirty(struct page *page)
 
        if (likely(mapping)) {
                int (*spd)(struct page *) = mapping->a_ops->set_page_dirty;
-               if (spd)
-                       return (*spd)(page);
-               return __set_page_dirty_buffers(page);
+#ifdef CONFIG_BLOCK
+               if (!spd)
+                       spd = __set_page_dirty_buffers;
+#endif
+               return (*spd)(page);
        }
        if (!PageDirty(page)) {
                if (!TestSetPageDirty(page))
index eda907c3a86aa14399e8a30aab95ec8dc8cff88c..b96de69f236b22225c4dcb9221d807808a7c8945 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/file.h>
@@ -177,6 +179,7 @@ static const struct address_space_operations shmem_aops;
 static struct file_operations shmem_file_operations;
 static struct inode_operations shmem_inode_operations;
 static struct inode_operations shmem_dir_inode_operations;
+static struct inode_operations shmem_special_inode_operations;
 static struct vm_operations_struct shmem_vm_ops;
 
 static struct backing_dev_info shmem_backing_dev_info  __read_mostly = {
@@ -637,7 +640,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
        struct page *page = NULL;
        int error;
 
-       if (attr->ia_valid & ATTR_SIZE) {
+       if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
                if (attr->ia_size < inode->i_size) {
                        /*
                         * If truncating down to a partial page, then
@@ -670,6 +673,10 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (!error)
                error = inode_setattr(inode, attr);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       if (!error && (attr->ia_valid & ATTR_MODE))
+               error = generic_acl_chmod(inode, &shmem_acl_ops);
+#endif
        if (page)
                page_cache_release(page);
        return error;
@@ -1362,6 +1369,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
 
                switch (mode & S_IFMT) {
                default:
+                       inode->i_op = &shmem_special_inode_operations;
                        init_special_inode(inode, mode, dev);
                        break;
                case S_IFREG:
@@ -1682,7 +1690,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
                                iput(inode);
                                return error;
                        }
-                       error = 0;
+               }
+               error = shmem_acl_init(inode, dir);
+               if (error) {
+                       iput(inode);
+                       return error;
                }
                if (dir->i_mode & S_ISGID) {
                        inode->i_gid = dir->i_gid;
@@ -1897,6 +1909,53 @@ static struct inode_operations shmem_symlink_inode_operations = {
        .put_link       = shmem_put_link,
 };
 
+#ifdef CONFIG_TMPFS_POSIX_ACL
+/**
+ * Superblocks without xattr inode operations will get security.* xattr
+ * support from the VFS "for free". As soon as we have any other xattrs
+ * like ACLs, we also need to implement the security.* handlers at
+ * filesystem level, though.
+ */
+
+static size_t shmem_xattr_security_list(struct inode *inode, char *list,
+                                       size_t list_len, const char *name,
+                                       size_t name_len)
+{
+       return security_inode_listsecurity(inode, list, list_len);
+}
+
+static int shmem_xattr_security_get(struct inode *inode, const char *name,
+                                   void *buffer, size_t size)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return security_inode_getsecurity(inode, name, buffer, size,
+                                         -EOPNOTSUPP);
+}
+
+static int shmem_xattr_security_set(struct inode *inode, const char *name,
+                                   const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return security_inode_setsecurity(inode, name, value, size, flags);
+}
+
+struct xattr_handler shmem_xattr_security_handler = {
+       .prefix = XATTR_SECURITY_PREFIX,
+       .list   = shmem_xattr_security_list,
+       .get    = shmem_xattr_security_get,
+       .set    = shmem_xattr_security_set,
+};
+
+static struct xattr_handler *shmem_xattr_handlers[] = {
+       &shmem_xattr_acl_access_handler,
+       &shmem_xattr_acl_default_handler,
+       &shmem_xattr_security_handler,
+       NULL
+};
+#endif
+
 static int shmem_parse_options(char *options, int *mode, uid_t *uid,
        gid_t *gid, unsigned long *blocks, unsigned long *inodes,
        int *policy, nodemask_t *policy_nodes)
@@ -2094,6 +2153,10 @@ static int shmem_fill_super(struct super_block *sb,
        sb->s_magic = TMPFS_MAGIC;
        sb->s_op = &shmem_ops;
        sb->s_time_gran = 1;
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       sb->s_xattr = shmem_xattr_handlers;
+       sb->s_flags |= MS_POSIXACL;
+#endif
 
        inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
        if (!inode)
@@ -2130,6 +2193,7 @@ static void shmem_destroy_inode(struct inode *inode)
                /* only struct inode is valid if it's an inline symlink */
                mpol_free_shared_policy(&SHMEM_I(inode)->policy);
        }
+       shmem_acl_destroy_inode(inode);
        kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
 }
 
@@ -2141,6 +2205,10 @@ static void init_once(void *foo, struct kmem_cache *cachep,
        if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
            SLAB_CTOR_CONSTRUCTOR) {
                inode_init_once(&p->vfs_inode);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+               p->i_acl = NULL;
+               p->i_default_acl = NULL;
+#endif
        }
 }
 
@@ -2184,6 +2252,14 @@ static struct inode_operations shmem_inode_operations = {
        .truncate       = shmem_truncate,
        .setattr        = shmem_notify_change,
        .truncate_range = shmem_truncate_range,
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = generic_listxattr,
+       .removexattr    = generic_removexattr,
+       .permission     = shmem_permission,
+#endif
+
 };
 
 static struct inode_operations shmem_dir_inode_operations = {
@@ -2198,6 +2274,25 @@ static struct inode_operations shmem_dir_inode_operations = {
        .mknod          = shmem_mknod,
        .rename         = shmem_rename,
 #endif
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       .setattr        = shmem_notify_change,
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = generic_listxattr,
+       .removexattr    = generic_removexattr,
+       .permission     = shmem_permission,
+#endif
+};
+
+static struct inode_operations shmem_special_inode_operations = {
+#ifdef CONFIG_TMPFS_POSIX_ACL
+       .setattr        = shmem_notify_change,
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = generic_listxattr,
+       .removexattr    = generic_removexattr,
+       .permission     = shmem_permission,
+#endif
 };
 
 static struct super_operations shmem_ops = {
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c
new file mode 100644 (file)
index 0000000..c946bf4
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * mm/shmem_acl.c
+ *
+ * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/shmem_fs.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+/**
+ * shmem_get_acl  -   generic_acl_operations->getacl() operation
+ */
+static struct posix_acl *
+shmem_get_acl(struct inode *inode, int type)
+{
+       struct posix_acl *acl = NULL;
+
+       spin_lock(&inode->i_lock);
+       switch(type) {
+               case ACL_TYPE_ACCESS:
+                       acl = posix_acl_dup(SHMEM_I(inode)->i_acl);
+                       break;
+
+               case ACL_TYPE_DEFAULT:
+                       acl = posix_acl_dup(SHMEM_I(inode)->i_default_acl);
+                       break;
+       }
+       spin_unlock(&inode->i_lock);
+
+       return acl;
+}
+
+/**
+ * shmem_get_acl  -   generic_acl_operations->setacl() operation
+ */
+static void
+shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+       struct posix_acl *free = NULL;
+
+       spin_lock(&inode->i_lock);
+       switch(type) {
+               case ACL_TYPE_ACCESS:
+                       free = SHMEM_I(inode)->i_acl;
+                       SHMEM_I(inode)->i_acl = posix_acl_dup(acl);
+                       break;
+
+               case ACL_TYPE_DEFAULT:
+                       free = SHMEM_I(inode)->i_default_acl;
+                       SHMEM_I(inode)->i_default_acl = posix_acl_dup(acl);
+                       break;
+       }
+       spin_unlock(&inode->i_lock);
+       posix_acl_release(free);
+}
+
+struct generic_acl_operations shmem_acl_ops = {
+       .getacl = shmem_get_acl,
+       .setacl = shmem_set_acl,
+};
+
+/**
+ * shmem_list_acl_access, shmem_get_acl_access, shmem_set_acl_access,
+ * shmem_xattr_acl_access_handler  -  plumbing code to implement the
+ * system.posix_acl_access xattr using the generic acl functions.
+ */
+
+static size_t
+shmem_list_acl_access(struct inode *inode, char *list, size_t list_size,
+                     const char *name, size_t name_len)
+{
+       return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_ACCESS,
+                               list, list_size);
+}
+
+static int
+shmem_get_acl_access(struct inode *inode, const char *name, void *buffer,
+                    size_t size)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, buffer,
+                              size);
+}
+
+static int
+shmem_set_acl_access(struct inode *inode, const char *name, const void *value,
+                    size_t size, int flags)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, value,
+                              size);
+}
+
+struct xattr_handler shmem_xattr_acl_access_handler = {
+       .prefix = POSIX_ACL_XATTR_ACCESS,
+       .list   = shmem_list_acl_access,
+       .get    = shmem_get_acl_access,
+       .set    = shmem_set_acl_access,
+};
+
+/**
+ * shmem_list_acl_default, shmem_get_acl_default, shmem_set_acl_default,
+ * shmem_xattr_acl_default_handler  -  plumbing code to implement the
+ * system.posix_acl_default xattr using the generic acl functions.
+ */
+
+static size_t
+shmem_list_acl_default(struct inode *inode, char *list, size_t list_size,
+                      const char *name, size_t name_len)
+{
+       return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT,
+                               list, list_size);
+}
+
+static int
+shmem_get_acl_default(struct inode *inode, const char *name, void *buffer,
+                     size_t size)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, buffer,
+                              size);
+}
+
+static int
+shmem_set_acl_default(struct inode *inode, const char *name, const void *value,
+                     size_t size, int flags)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, value,
+                              size);
+}
+
+struct xattr_handler shmem_xattr_acl_default_handler = {
+       .prefix = POSIX_ACL_XATTR_DEFAULT,
+       .list   = shmem_list_acl_default,
+       .get    = shmem_get_acl_default,
+       .set    = shmem_set_acl_default,
+};
+
+/**
+ * shmem_acl_init  -  Inizialize the acl(s) of a new inode
+ */
+int
+shmem_acl_init(struct inode *inode, struct inode *dir)
+{
+       return generic_acl_init(inode, dir, &shmem_acl_ops);
+}
+
+/**
+ * shmem_acl_destroy_inode  -  destroy acls hanging off the in-memory inode
+ *
+ * This is done before destroying the actual inode.
+ */
+
+void
+shmem_acl_destroy_inode(struct inode *inode)
+{
+       if (SHMEM_I(inode)->i_acl)
+               posix_acl_release(SHMEM_I(inode)->i_acl);
+       SHMEM_I(inode)->i_acl = NULL;
+       if (SHMEM_I(inode)->i_default_acl)
+               posix_acl_release(SHMEM_I(inode)->i_default_acl);
+       SHMEM_I(inode)->i_default_acl = NULL;
+}
+
+/**
+ * shmem_check_acl  -  check_acl() callback for generic_permission()
+ */
+static int
+shmem_check_acl(struct inode *inode, int mask)
+{
+       struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS);
+
+       if (acl) {
+               int error = posix_acl_permission(inode, acl, mask);
+               posix_acl_release(acl);
+               return error;
+       }
+       return -EAGAIN;
+}
+
+/**
+ * shmem_permission  -  permission() inode operation
+ */
+int
+shmem_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+       return generic_permission(inode, mask, shmem_check_acl);
+}
index 792bfe320a8b2c0896f8568f8d07de40203f8cf2..3dbd6f4e74774be9fd1db7e19d581ae31b1f4cce 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1683,10 +1683,32 @@ static void poison_obj(struct kmem_cache *cachep, void *addr, unsigned char val)
 static void dump_line(char *data, int offset, int limit)
 {
        int i;
+       unsigned char error = 0;
+       int bad_count = 0;
+
        printk(KERN_ERR "%03x:", offset);
-       for (i = 0; i < limit; i++)
+       for (i = 0; i < limit; i++) {
+               if (data[offset + i] != POISON_FREE) {
+                       error = data[offset + i];
+                       bad_count++;
+               }
                printk(" %02x", (unsigned char)data[offset + i]);
+       }
        printk("\n");
+
+       if (bad_count == 1) {
+               error ^= POISON_FREE;
+               if (!(error & (error - 1))) {
+                       printk(KERN_ERR "Single bit error detected. Probably "
+                                       "bad RAM.\n");
+#ifdef CONFIG_X86
+                       printk(KERN_ERR "Run memtest86+ or a similar memory "
+                                       "test tool.\n");
+#else
+                       printk(KERN_ERR "Run a memory test tool.\n");
+#endif
+               }
+       }
 }
 #endif
 
index f1f5ec783781cfebcbd4f3c5efe79336eaedcfa1..a15def63f28f19e8e9d0e9f550177b80b033526e 100644 (file)
@@ -1723,13 +1723,14 @@ get_swap_info_struct(unsigned type)
  */
 int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
 {
-       int ret = 0, i = 1 << page_cluster;
+       int our_page_cluster = page_cluster;
+       int ret = 0, i = 1 << our_page_cluster;
        unsigned long toff;
        struct swap_info_struct *swapdev = swp_type(entry) + swap_info;
 
-       if (!page_cluster)      /* no readahead */
+       if (!our_page_cluster)  /* no readahead */
                return 0;
-       toff = (swp_offset(entry) >> page_cluster) << page_cluster;
+       toff = (swp_offset(entry) >> our_page_cluster) << our_page_cluster;
        if (!toff)              /* first page is swap header */
                toff++, i--;
        *offset = toff;
index a654928323dcc4459cf33b59f67be5868d5b105d..8fde6580657ed15c860d2f6e5bffa77c88965240 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);
index d7d8f40c4fed0d17d0113eceb92de3d821e723fc..829deb41ce81d436aad10567d03d35ca86532b58 100644 (file)
@@ -164,7 +164,7 @@ static int tr_rebuild_header(struct sk_buff *skb)
         */
         
        if(trllc->ethertype != htons(ETH_P_IP)) {
-               printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(trllc->ethertype));
+               printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(trllc->ethertype));
                return 0;
        }
 
@@ -186,7 +186,7 @@ static int tr_rebuild_header(struct sk_buff *skb)
  *     it via SNAP.
  */
  
-unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev) 
+__be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 
        struct trh_hdr *trh=(struct trh_hdr *)skb->data;
@@ -229,15 +229,15 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev)
         */
 
        if (trllc->dsap == EXTENDED_SAP &&
-           (trllc->ethertype == ntohs(ETH_P_IP) ||
-            trllc->ethertype == ntohs(ETH_P_IPV6) ||
-            trllc->ethertype == ntohs(ETH_P_ARP)))
+           (trllc->ethertype == htons(ETH_P_IP) ||
+            trllc->ethertype == htons(ETH_P_IPV6) ||
+            trllc->ethertype == htons(ETH_P_ARP)))
        {
                skb_pull(skb, sizeof(struct trllc));
                return trllc->ethertype;
        }
 
-       return ntohs(ETH_P_TR_802_2);
+       return htons(ETH_P_TR_802_2);
 }
 
 /*
index 6528a935622cc61ca2269a250ada0181932c61ff..a81aca43932f975ed912e1f00482e24b5a6d7102 100644 (file)
@@ -231,7 +231,7 @@ config NET_TCPPROBE
        TCP congestion avoidance modules. If you don't understand
        what was just said, you don't need it: say N.
 
-       Documentation on how to use the packet generator can be found
+       Documentation on how to use TCP connection probing can be found
        at http://linux-net.osdl.org/index.php/TcpProbe
 
        To compile this code as a module, choose M here: the
index 96dc6bb52d14aecd00cff0e8f37bed950d6b557f..708e2e0371aff2ae8be46529c112be0078e58686 100644 (file)
@@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
        return sum;
 }
 
-static unsigned short atalk_checksum(const struct sk_buff *skb, int len)
+static __be16 atalk_checksum(const struct sk_buff *skb, int len)
 {
        unsigned long sum;
 
@@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len)
        sum = atalk_sum_skb(skb, 4, len-4, 0);
 
        /* Use 0xFFFF for 0. 0 itself means none */
-       return sum ? htons((unsigned short)sum) : 0xFFFF;
+       return sum ? htons((unsigned short)sum) : htons(0xFFFF);
 }
 
 static struct proto ddp_proto = {
@@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
 #endif
 
 static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
-                              struct ddpehdr *ddp, struct ddpebits *ddphv,
+                              struct ddpehdr *ddp, __u16 len_hops,
                               int origlen)
 {
        struct atalk_route *rt;
@@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
 
        /* Route the packet */
        rt = atrtr_find(&ta);
-       if (!rt || ddphv->deh_hops == DDP_MAXHOPS)
+       /* increment hops count */
+       len_hops += 1 << 10;
+       if (!rt || !(len_hops & (15 << 10)))
                goto free_it;
+
        /* FIXME: use skb->cb to be able to use shared skbs */
-       ddphv->deh_hops++;
 
        /*
         * Route goes through another gateway, so set the target to the
@@ -1335,11 +1337,10 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
         /* Fix up skb->len field */
         skb_trim(skb, min_t(unsigned int, origlen,
                            (rt->dev->hard_header_len +
-                            ddp_dl->header_length + ddphv->deh_len)));
+                            ddp_dl->header_length + (len_hops & 1023))));
 
-       /* Mend the byte order */
        /* FIXME: use skb->cb to be able to use shared skbs */
-       *((__u16 *)ddp) = ntohs(*((__u16 *)ddphv));
+       ddp->deh_len_hops = htons(len_hops);
 
        /*
         * Send the buffer onwards
@@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
        struct atalk_iface *atif;
        struct sockaddr_at tosat;
         int origlen;
-        struct ddpebits ddphv;
+       __u16 len_hops;
 
        /* Don't mangle buffer if shared */
        if (!(skb = skb_share_check(skb, GFP_ATOMIC))) 
@@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 
        ddp = ddp_hdr(skb);
 
-       /*
-        *      Fix up the length field [Ok this is horrible but otherwise
-        *      I end up with unions of bit fields and messy bit field order
-        *      compiler/endian dependencies..]
-        */
-       *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
+       len_hops = ntohs(ddp->deh_len_hops);
 
        /* Trim buffer in case of stray trailing data */
        origlen = skb->len;
-       skb_trim(skb, min_t(unsigned int, skb->len, ddphv.deh_len));
+       skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023));
 
        /*
         * Size check to see if ddp->deh_len was crap
@@ -1430,7 +1426,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
         * valid for net byte orders all over the networking code...
         */
        if (ddp->deh_sum &&
-           atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum)
+           atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum)
                /* Not a valid AppleTalk frame - dustbin time */
                goto freeit;
 
@@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
                /* Not ours, so we route the packet via the correct
                 * AppleTalk iface
                 */
-               atalk_route_packet(skb, dev, ddp, &ddphv, origlen);
+               atalk_route_packet(skb, dev, ddp, len_hops, origlen);
                goto out;
        }
 
@@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                /* Find our address */
                struct atalk_addr *ap = atalk_find_dev_addr(dev);
 
-               if (!ap || skb->len < sizeof(struct ddpshdr))
+               if (!ap || skb->len < sizeof(__be16) || skb->len > 1023)
                        goto freeit;
 
                /* Don't mangle buffer if shared */
@@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                /*
                 * Not sure about this bit...
                 */
-               ddp->deh_len   = skb->len;
-               ddp->deh_hops  = DDP_MAXHOPS;   /* Non routable, so force a drop
-                                                  if we slip up later */
-               /* Mend the byte order */
-               *((__u16 *)ddp) = htons(*((__u16 *)ddp));
+               /* Non routable, so force a drop if we slip up later */
+               ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10));
        }
        skb->h.raw = skb->data;
 
@@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
 
        ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr));
-       ddp->deh_pad  = 0;
-       ddp->deh_hops = 0;
-       ddp->deh_len  = len + sizeof(*ddp);
-       /*
-        * Fix up the length field [Ok this is horrible but otherwise
-        * I end up with unions of bit fields and messy bit field order
-        * compiler/endian dependencies..
-        */
-       *((__u16 *)ddp) = ntohs(*((__u16 *)ddp));
-
+       ddp->deh_len_hops  = htons(len + sizeof(*ddp));
        ddp->deh_dnet  = usat->sat_addr.s_net;
        ddp->deh_snet  = at->src_net;
        ddp->deh_dnode = usat->sat_addr.s_node;
@@ -1712,8 +1696,8 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
        struct ddpehdr *ddp;
        int copied = 0;
+       int offset = 0;
        int err = 0;
-        struct ddpebits ddphv;
        struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                                flags & MSG_DONTWAIT, &err);
        if (!skb)
@@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
 
        /* FIXME: use skb->cb to be able to use shared skbs */
        ddp = ddp_hdr(skb);
-       *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
+       copied = ntohs(ddp->deh_len_hops) & 1023;
 
-       if (sk->sk_type == SOCK_RAW) {
-               copied = ddphv.deh_len;
-               if (copied > size) {
-                       copied = size;
-                       msg->msg_flags |= MSG_TRUNC;
-               }
+       if (sk->sk_type != SOCK_RAW) {
+               offset = sizeof(*ddp);
+               copied -= offset;
+       }
 
-               err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-       } else {
-               copied = ddphv.deh_len - sizeof(*ddp);
-               if (copied > size) {
-                       copied = size;
-                       msg->msg_flags |= MSG_TRUNC;
-               }
-               err = skb_copy_datagram_iovec(skb, sizeof(*ddp),
-                                             msg->msg_iov, copied);
+       if (copied > size) {
+               copied = size;
+               msg->msg_flags |= MSG_TRUNC;
        }
+       err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
 
        if (!err) {
                if (sat) {
index b4aa489849dfefc0185395415de8e88c31b303ab..66c57c1091a8e3ff2020bd75135f7ac65e971544 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lec.c: Lan Emulation driver 
- * Marko Kiiskila mkiiskila@yahoo.com
  *
+ * Marko Kiiskila <mkiiskila@yahoo.com>
  */
 
 #include <linux/kernel.h>
@@ -38,7 +38,7 @@
 #include <linux/if_bridge.h>
 #include "../bridge/br_private.h"
 
-static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
+static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
 #endif
 
 /* Modular too */
@@ -55,38 +55,41 @@ static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
 #define DPRINTK(format,args...)
 #endif
 
-#define DUMP_PACKETS 0 /* 0 = None,
-                        * 1 = 30 first bytes
-                        * 2 = Whole packet
-                        */
+#define DUMP_PACKETS 0         /*
+                                * 0 = None,
+                                * 1 = 30 first bytes
+                                * 2 = Whole packet
+                                */
 
-#define LEC_UNRES_QUE_LEN 8 /* number of tx packets to queue for a
-                               single destination while waiting for SVC */
+#define LEC_UNRES_QUE_LEN 8    /*
+                                * number of tx packets to queue for a
+                                * single destination while waiting for SVC
+                                */
 
 static int lec_open(struct net_device *dev);
 static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lec_close(struct net_device *dev);
 static struct net_device_stats *lec_get_stats(struct net_device *dev);
 static void lec_init(struct net_device *dev);
-static struct lec_arp_tablelec_arp_find(struct lec_priv *priv,
-                                                     unsigned char *mac_addr);
+static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
+                                         unsigned char *mac_addr);
 static int lec_arp_remove(struct lec_priv *priv,
-                                    struct lec_arp_table *to_remove);
+                         struct lec_arp_table *to_remove);
 /* LANE2 functions */
-static void lane2_associate_ind (struct net_device *dev, u8 *mac_address,
-                          u8 *tlvs, u32 sizeoftlvs);
+static void lane2_associate_ind(struct net_device *dev, u8 *mac_address,
+                               u8 *tlvs, u32 sizeoftlvs);
 static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
-                  u8 **tlvs, u32 *sizeoftlvs);
-static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
-                         u8 *tlvs, u32 sizeoftlvs);
+                        u8 **tlvs, u32 *sizeoftlvs);
+static int lane2_associate_req(struct net_device *dev, u8 *lan_dst,
+                              u8 *tlvs, u32 sizeoftlvs);
 
-static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, 
+static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
                           unsigned long permanent);
 static void lec_arp_check_empties(struct lec_priv *priv,
                                  struct atm_vcc *vcc, struct sk_buff *skb);
 static void lec_arp_destroy(struct lec_priv *priv);
 static void lec_arp_init(struct lec_priv *priv);
-static struct atm_vcclec_arp_resolve(struct lec_priv *priv,
+static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
                                       unsigned char *mac_to_find,
                                       int is_rdesc,
                                       struct lec_arp_table **ret_entry);
@@ -100,16 +103,30 @@ static void lec_set_flush_tran_id(struct lec_priv *priv,
                                  unsigned long tran_id);
 static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
                          struct atm_vcc *vcc,
-                         void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb));
+                         void (*old_push) (struct atm_vcc *vcc,
+                                           struct sk_buff *skb));
 static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
 
+/* must be done under lec_arp_lock */
+static inline void lec_arp_hold(struct lec_arp_table *entry)
+{
+       atomic_inc(&entry->usage);
+}
+
+static inline void lec_arp_put(struct lec_arp_table *entry)
+{
+       if (atomic_dec_and_test(&entry->usage))
+               kfree(entry);
+}
+
+
 static struct lane2_ops lane2_ops = {
-       lane2_resolve,         /* resolve,             spec 3.1.3 */
-       lane2_associate_req,   /* associate_req,       spec 3.1.4 */
-       NULL                  /* associate indicator, spec 3.1.5 */
+       lane2_resolve,          /* resolve,             spec 3.1.3 */
+       lane2_associate_req,    /* associate_req,       spec 3.1.4 */
+       NULL                    /* associate indicator, spec 3.1.5 */
 };
 
-static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
 /* Device structures */
 static struct net_device *dev_lec[MAX_LEC_ITF];
@@ -117,36 +134,39 @@ static struct net_device *dev_lec[MAX_LEC_ITF];
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
 {
-        struct ethhdr *eth;
-        char *buff;
-        struct lec_priv *priv;
-
-        /* Check if this is a BPDU. If so, ask zeppelin to send
-         * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
-         * as the Config BPDU has */
-        eth = (struct ethhdr *)skb->data;
-        buff = skb->data + skb->dev->hard_header_len;
-        if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
+       struct ethhdr *eth;
+       char *buff;
+       struct lec_priv *priv;
+
+       /*
+        * Check if this is a BPDU. If so, ask zeppelin to send
+        * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
+        * as the Config BPDU has
+        */
+       eth = (struct ethhdr *)skb->data;
+       buff = skb->data + skb->dev->hard_header_len;
+       if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
                struct sock *sk;
-                struct sk_buff *skb2;
-                struct atmlec_msg *mesg;
-
-                skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
-                if (skb2 == NULL) return;
-                skb2->len = sizeof(struct atmlec_msg);
-                mesg = (struct atmlec_msg *)skb2->data;
-                mesg->type = l_topology_change;
-                buff += 4;
-                mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */
-
-                priv = (struct lec_priv *)dev->priv;
-                atm_force_charge(priv->lecd, skb2->truesize);
+               struct sk_buff *skb2;
+               struct atmlec_msg *mesg;
+
+               skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
+               if (skb2 == NULL)
+                       return;
+               skb2->len = sizeof(struct atmlec_msg);
+               mesg = (struct atmlec_msg *)skb2->data;
+               mesg->type = l_topology_change;
+               buff += 4;
+               mesg->content.normal.flag = *buff & 0x01;       /* 0x01 is topology change */
+
+               priv = (struct lec_priv *)dev->priv;
+               atm_force_charge(priv->lecd, skb2->truesize);
                sk = sk_atm(priv->lecd);
-                skb_queue_tail(&sk->sk_receive_queue, skb2);
-                sk->sk_data_ready(sk, skb2->len);
-        }
+               skb_queue_tail(&sk->sk_receive_queue, skb2);
+               sk->sk_data_ready(sk, skb2->len);
+       }
 
-        return;
+       return;
 }
 #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
 
@@ -162,36 +182,35 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
 #ifdef CONFIG_TR
 static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
 {
-        struct trh_hdr *trh;
-        int riflen, num_rdsc;
-        
-        trh = (struct trh_hdr *)packet;
-        if (trh->daddr[0] & (uint8_t)0x80)
-                return bus_mac; /* multicast */
-
-        if (trh->saddr[0] & TR_RII) {
-                riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
-                if ((ntohs(trh->rcf) >> 13) != 0)
-                        return bus_mac; /* ARE or STE */
-        }
-        else
-                return trh->daddr; /* not source routed */
-
-        if (riflen < 6)
-                return trh->daddr; /* last hop, source routed */
-                
-        /* riflen is 6 or more, packet has more than one route descriptor */
-        num_rdsc = (riflen/2) - 1;
-        memset(rdesc, 0, ETH_ALEN);
-        /* offset 4 comes from LAN destination field in LE control frames */
-        if (trh->rcf & htons((uint16_t)TR_RCF_DIR_BIT))
-                memcpy(&rdesc[4], &trh->rseg[num_rdsc-2], sizeof(uint16_t));
-        else {
-                memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
-                rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
-        }
-
-        return NULL;
+       struct trh_hdr *trh;
+       int riflen, num_rdsc;
+
+       trh = (struct trh_hdr *)packet;
+       if (trh->daddr[0] & (uint8_t) 0x80)
+               return bus_mac; /* multicast */
+
+       if (trh->saddr[0] & TR_RII) {
+               riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
+               if ((ntohs(trh->rcf) >> 13) != 0)
+                       return bus_mac; /* ARE or STE */
+       } else
+               return trh->daddr;      /* not source routed */
+
+       if (riflen < 6)
+               return trh->daddr;      /* last hop, source routed */
+
+       /* riflen is 6 or more, packet has more than one route descriptor */
+       num_rdsc = (riflen / 2) - 1;
+       memset(rdesc, 0, ETH_ALEN);
+       /* offset 4 comes from LAN destination field in LE control frames */
+       if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT))
+               memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(uint16_t));
+       else {
+               memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t));
+               rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
+       }
+
+       return NULL;
 }
 #endif /* CONFIG_TR */
 
@@ -204,15 +223,14 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
  * there is non-reboot way to recover if something goes wrong.
  */
 
-static int 
-lec_open(struct net_device *dev)
+static int lec_open(struct net_device *dev)
 {
-        struct lec_priv *priv = (struct lec_priv *)dev->priv;
-        
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+
        netif_start_queue(dev);
-        memset(&priv->stats,0,sizeof(struct net_device_stats));
-        
-        return 0;
+       memset(&priv->stats, 0, sizeof(struct net_device_stats));
+
+       return 0;
 }
 
 static __inline__ void
@@ -231,160 +249,166 @@ lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv)
        priv->stats.tx_bytes += skb->len;
 }
 
-static void
-lec_tx_timeout(struct net_device *dev)
+static void lec_tx_timeout(struct net_device *dev)
 {
        printk(KERN_INFO "%s: tx timeout\n", dev->name);
        dev->trans_start = jiffies;
        netif_wake_queue(dev);
 }
 
-static int 
-lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-        struct sk_buff *skb2;
-        struct lec_priv *priv = (struct lec_priv *)dev->priv;
-        struct lecdatahdr_8023 *lec_h;
-        struct atm_vcc *vcc;
+       struct sk_buff *skb2;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lecdatahdr_8023 *lec_h;
+       struct atm_vcc *vcc;
        struct lec_arp_table *entry;
-        unsigned char *dst;
+       unsigned char *dst;
        int min_frame_size;
 #ifdef CONFIG_TR
-        unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */
+       unsigned char rdesc[ETH_ALEN];  /* Token Ring route descriptor */
 #endif
-        int is_rdesc;
+       int is_rdesc;
 #if DUMP_PACKETS > 0
-        char buf[300];
-        int i=0;
+       char buf[300];
+       int i = 0;
 #endif /* DUMP_PACKETS >0 */
-        
-        DPRINTK("lec_start_xmit called\n");  
-        if (!priv->lecd) {
-                printk("%s:No lecd attached\n",dev->name);
-                priv->stats.tx_errors++;
-                netif_stop_queue(dev);
-                return -EUNATCH;
-        } 
-
-        DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
-                (long)skb->head, (long)skb->data, (long)skb->tail,
-                (long)skb->end);
+
+       DPRINTK("lec_start_xmit called\n");
+       if (!priv->lecd) {
+               printk("%s:No lecd attached\n", dev->name);
+               priv->stats.tx_errors++;
+               netif_stop_queue(dev);
+               return -EUNATCH;
+       }
+
+       DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
+               (long)skb->head, (long)skb->data, (long)skb->tail,
+               (long)skb->end);
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-        if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
-                lec_handle_bridge(skb, dev);
+       if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
+               lec_handle_bridge(skb, dev);
 #endif
 
-        /* Make sure we have room for lec_id */
-        if (skb_headroom(skb) < 2) {
+       /* Make sure we have room for lec_id */
+       if (skb_headroom(skb) < 2) {
 
-                DPRINTK("lec_start_xmit: reallocating skb\n");
-                skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
-                kfree_skb(skb);
-                if (skb2 == NULL) return 0;
-                skb = skb2;
-        }
-        skb_push(skb, 2);
+               DPRINTK("lec_start_xmit: reallocating skb\n");
+               skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+               kfree_skb(skb);
+               if (skb2 == NULL)
+                       return 0;
+               skb = skb2;
+       }
+       skb_push(skb, 2);
 
-        /* Put le header to place, works for TokenRing too */
-        lec_h = (struct lecdatahdr_8023*)skb->data;
-        lec_h->le_header = htons(priv->lecid); 
+       /* Put le header to place, works for TokenRing too */
+       lec_h = (struct lecdatahdr_8023 *)skb->data;
+       lec_h->le_header = htons(priv->lecid);
 
 #ifdef CONFIG_TR
-        /* Ugly. Use this to realign Token Ring packets for
-         * e.g. PCA-200E driver. */
-        if (priv->is_trdev) {
-                skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
-                kfree_skb(skb);
-                if (skb2 == NULL) return 0;
-                skb = skb2;
-        }
+       /*
+        * Ugly. Use this to realign Token Ring packets for
+        * e.g. PCA-200E driver.
+        */
+       if (priv->is_trdev) {
+               skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
+               kfree_skb(skb);
+               if (skb2 == NULL)
+                       return 0;
+               skb = skb2;
+       }
 #endif
 
 #if DUMP_PACKETS > 0
-        printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
-               skb->len, priv->lecid);
+       printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
+              skb->len, priv->lecid);
 #if DUMP_PACKETS >= 2
-        for(i=0;i<skb->len && i <99;i++) {
-                sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
-        }
+       for (i = 0; i < skb->len && i < 99; i++) {
+               sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+       }
 #elif DUMP_PACKETS >= 1
-        for(i=0;i<skb->len && i < 30;i++) {
-                sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
-        }
+       for (i = 0; i < skb->len && i < 30; i++) {
+               sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+       }
 #endif /* DUMP_PACKETS >= 1 */
-        if (i==skb->len)
-                printk("%s\n",buf);
-        else
-                printk("%s...\n",buf);
+       if (i == skb->len)
+               printk("%s\n", buf);
+       else
+               printk("%s...\n", buf);
 #endif /* DUMP_PACKETS > 0 */
 
-        /* Minimum ethernet-frame size */
+       /* Minimum ethernet-frame size */
 #ifdef CONFIG_TR
-        if (priv->is_trdev)
-                min_frame_size = LEC_MINIMUM_8025_SIZE;
+       if (priv->is_trdev)
+               min_frame_size = LEC_MINIMUM_8025_SIZE;
        else
 #endif
-        min_frame_size = LEC_MINIMUM_8023_SIZE;
-        if (skb->len < min_frame_size) {
-                if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
-                        skb2 = skb_copy_expand(skb, 0,
-                            min_frame_size - skb->truesize, GFP_ATOMIC);
-                                dev_kfree_skb(skb);
-                        if (skb2 == NULL) {
-                                priv->stats.tx_dropped++;
-                                return 0;
-                        }
-                        skb = skb2;
-                }
+               min_frame_size = LEC_MINIMUM_8023_SIZE;
+       if (skb->len < min_frame_size) {
+               if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
+                       skb2 = skb_copy_expand(skb, 0,
+                                              min_frame_size - skb->truesize,
+                                              GFP_ATOMIC);
+                       dev_kfree_skb(skb);
+                       if (skb2 == NULL) {
+                               priv->stats.tx_dropped++;
+                               return 0;
+                       }
+                       skb = skb2;
+               }
                skb_put(skb, min_frame_size - skb->len);
-        }
-        
-        /* Send to right vcc */
-        is_rdesc = 0;
-        dst = lec_h->h_dest;
+       }
+
+       /* Send to right vcc */
+       is_rdesc = 0;
+       dst = lec_h->h_dest;
 #ifdef CONFIG_TR
-        if (priv->is_trdev) {
-                dst = get_tr_dst(skb->data+2, rdesc);
-                if (dst == NULL) {
-                        dst = rdesc;
-                        is_rdesc = 1;
-                }
-        }
+       if (priv->is_trdev) {
+               dst = get_tr_dst(skb->data + 2, rdesc);
+               if (dst == NULL) {
+                       dst = rdesc;
+                       is_rdesc = 1;
+               }
+       }
 #endif
-        entry = NULL;
-        vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
-        DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
-                vcc, vcc?vcc->flags:0, entry);
-        if (!vcc || !test_bit(ATM_VF_READY,&vcc->flags)) {    
-                if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
-                        DPRINTK("%s:lec_start_xmit: queuing packet, ", dev->name);
-                        DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                                lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
-                        skb_queue_tail(&entry->tx_wait, skb);
-                } else {
-                        DPRINTK("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", dev->name);
-                        DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                                lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
-                        priv->stats.tx_dropped++;
-                        dev_kfree_skb(skb);
-                }
-                return 0;
-        }
-                
-#if DUMP_PACKETS > 0                    
-        printk("%s:sending to vpi:%d vci:%d\n", dev->name,
-               vcc->vpi, vcc->vci);       
+       entry = NULL;
+       vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
+       DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name,
+               vcc, vcc ? vcc->flags : 0, entry);
+       if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) {
+               if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
+                       DPRINTK("%s:lec_start_xmit: queuing packet, ",
+                               dev->name);
+                       DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                               lec_h->h_dest[0], lec_h->h_dest[1],
+                               lec_h->h_dest[2], lec_h->h_dest[3],
+                               lec_h->h_dest[4], lec_h->h_dest[5]);
+                       skb_queue_tail(&entry->tx_wait, skb);
+               } else {
+                       DPRINTK
+                           ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
+                            dev->name);
+                       DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                               lec_h->h_dest[0], lec_h->h_dest[1],
+                               lec_h->h_dest[2], lec_h->h_dest[3],
+                               lec_h->h_dest[4], lec_h->h_dest[5]);
+                       priv->stats.tx_dropped++;
+                       dev_kfree_skb(skb);
+               }
+               goto out;
+       }
+#if DUMP_PACKETS > 0
+       printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci);
 #endif /* DUMP_PACKETS > 0 */
-                
-        while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
-                DPRINTK("lec.c: emptying tx queue, ");
-                DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                        lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
-                        lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
+
+       while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
+               DPRINTK("lec.c: emptying tx queue, ");
+               DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                       lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
+                       lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
                lec_send(vcc, skb2, priv);
-        }
+       }
 
        lec_send(vcc, skb, priv);
 
@@ -404,210 +428,219 @@ lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        netif_wake_queue(dev);
        }
 
+out:
+       if (entry)
+               lec_arp_put(entry);
        dev->trans_start = jiffies;
-        return 0;
+       return 0;
 }
 
 /* The inverse routine to net_open(). */
-static int 
-lec_close(struct net_device *dev) 
+static int lec_close(struct net_device *dev)
 {
-        netif_stop_queue(dev);
-        return 0;
+       netif_stop_queue(dev);
+       return 0;
 }
 
 /*
  * Get the current statistics.
  * This may be called with the card open or closed.
  */
-static struct net_device_stats *
-lec_get_stats(struct net_device *dev)
+static struct net_device_stats *lec_get_stats(struct net_device *dev)
 {
-        return &((struct lec_priv *)dev->priv)->stats;
+       return &((struct lec_priv *)dev->priv)->stats;
 }
 
-static int 
-lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
+static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        unsigned long flags;
-        struct net_device *dev = (struct net_device*)vcc->proto_data;
-        struct lec_priv *priv = (struct lec_priv*)dev->priv;
-        struct atmlec_msg *mesg;
-        struct lec_arp_table *entry;
-        int i;
-        char *tmp; /* FIXME */
+       struct net_device *dev = (struct net_device *)vcc->proto_data;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct atmlec_msg *mesg;
+       struct lec_arp_table *entry;
+       int i;
+       char *tmp;              /* FIXME */
 
        atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
-        mesg = (struct atmlec_msg *)skb->data;
-        tmp = skb->data;
-        tmp += sizeof(struct atmlec_msg);
-        DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
-        switch(mesg->type) {
-        case l_set_mac_addr:
-                for (i=0;i<6;i++) {
-                        dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
-                }    
-                break;
-        case l_del_mac_addr:
-                for(i=0;i<6;i++) {
-                        dev->dev_addr[i] = 0;
-                }
-                break;
-        case l_addr_delete:
-                lec_addr_delete(priv, mesg->content.normal.atm_addr, 
-                                mesg->content.normal.flag);
-                break;
-        case l_topology_change:
-                priv->topology_change = mesg->content.normal.flag;  
-                break;
-        case l_flush_complete:
-                lec_flush_complete(priv, mesg->content.normal.flag);
-                break;
-        case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
+       mesg = (struct atmlec_msg *)skb->data;
+       tmp = skb->data;
+       tmp += sizeof(struct atmlec_msg);
+       DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
+       switch (mesg->type) {
+       case l_set_mac_addr:
+               for (i = 0; i < 6; i++) {
+                       dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
+               }
+               break;
+       case l_del_mac_addr:
+               for (i = 0; i < 6; i++) {
+                       dev->dev_addr[i] = 0;
+               }
+               break;
+       case l_addr_delete:
+               lec_addr_delete(priv, mesg->content.normal.atm_addr,
+                               mesg->content.normal.flag);
+               break;
+       case l_topology_change:
+               priv->topology_change = mesg->content.normal.flag;
+               break;
+       case l_flush_complete:
+               lec_flush_complete(priv, mesg->content.normal.flag);
+               break;
+       case l_narp_req:        /* LANE2: see 7.1.35 in the lane2 spec */
                spin_lock_irqsave(&priv->lec_arp_lock, flags);
-                entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
-                lec_arp_remove(priv, entry);
+               entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
+               lec_arp_remove(priv, entry);
                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
-                if (mesg->content.normal.no_source_le_narp)
-                        break;
-                /* FALL THROUGH */
-        case l_arp_update:
-                lec_arp_update(priv, mesg->content.normal.mac_addr,
-                               mesg->content.normal.atm_addr,
-                               mesg->content.normal.flag,
-                               mesg->content.normal.targetless_le_arp);
-                DPRINTK("lec: in l_arp_update\n");
-                if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
-                        DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs);
-                        lane2_associate_ind(dev,
-                                            mesg->content.normal.mac_addr,
-                                            tmp, mesg->sizeoftlvs);
-                }
-                break;
-        case l_config:
-                priv->maximum_unknown_frame_count = 
-                        mesg->content.config.maximum_unknown_frame_count;
-                priv->max_unknown_frame_time = 
-                        (mesg->content.config.max_unknown_frame_time*HZ);
-                priv->max_retry_count = 
-                        mesg->content.config.max_retry_count;
-                priv->aging_time = (mesg->content.config.aging_time*HZ);
-                priv->forward_delay_time = 
-                        (mesg->content.config.forward_delay_time*HZ);
-                priv->arp_response_time = 
-                        (mesg->content.config.arp_response_time*HZ);
-                priv->flush_timeout = (mesg->content.config.flush_timeout*HZ);
-                priv->path_switching_delay = 
-                        (mesg->content.config.path_switching_delay*HZ);
-                priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
+               if (mesg->content.normal.no_source_le_narp)
+                       break;
+               /* FALL THROUGH */
+       case l_arp_update:
+               lec_arp_update(priv, mesg->content.normal.mac_addr,
+                              mesg->content.normal.atm_addr,
+                              mesg->content.normal.flag,
+                              mesg->content.normal.targetless_le_arp);
+               DPRINTK("lec: in l_arp_update\n");
+               if (mesg->sizeoftlvs != 0) {    /* LANE2 3.1.5 */
+                       DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n",
+                               mesg->sizeoftlvs);
+                       lane2_associate_ind(dev, mesg->content.normal.mac_addr,
+                                           tmp, mesg->sizeoftlvs);
+               }
+               break;
+       case l_config:
+               priv->maximum_unknown_frame_count =
+                   mesg->content.config.maximum_unknown_frame_count;
+               priv->max_unknown_frame_time =
+                   (mesg->content.config.max_unknown_frame_time * HZ);
+               priv->max_retry_count = mesg->content.config.max_retry_count;
+               priv->aging_time = (mesg->content.config.aging_time * HZ);
+               priv->forward_delay_time =
+                   (mesg->content.config.forward_delay_time * HZ);
+               priv->arp_response_time =
+                   (mesg->content.config.arp_response_time * HZ);
+               priv->flush_timeout = (mesg->content.config.flush_timeout * HZ);
+               priv->path_switching_delay =
+                   (mesg->content.config.path_switching_delay * HZ);
+               priv->lane_version = mesg->content.config.lane_version; /* LANE2 */
                priv->lane2_ops = NULL;
                if (priv->lane_version > 1)
                        priv->lane2_ops = &lane2_ops;
                if (dev->change_mtu(dev, mesg->content.config.mtu))
                        printk("%s: change_mtu to %d failed\n", dev->name,
-                           mesg->content.config.mtu);
+                              mesg->content.config.mtu);
                priv->is_proxy = mesg->content.config.is_proxy;
-                break;
-        case l_flush_tran_id:
-                lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
-                                      mesg->content.normal.flag);
-                break;
-        case l_set_lecid:
-                priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag);
-                break;
-        case l_should_bridge: {
+               break;
+       case l_flush_tran_id:
+               lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
+                                     mesg->content.normal.flag);
+               break;
+       case l_set_lecid:
+               priv->lecid =
+                   (unsigned short)(0xffff & mesg->content.normal.flag);
+               break;
+       case l_should_bridge:
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-                struct net_bridge_fdb_entry *f;
-
-                DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                        dev->name,
-                        mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1],
-                        mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3],
-                        mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]);
-
-                if (br_fdb_get_hook == NULL || dev->br_port == NULL)
-                        break;
-
-                f = br_fdb_get_hook(dev->br_port->br, mesg->content.proxy.mac_addr);
-                if (f != NULL &&
-                    f->dst->dev != dev &&
-                    f->dst->state == BR_STATE_FORWARDING) {
-                                /* hit from bridge table, send LE_ARP_RESPONSE */
-                        struct sk_buff *skb2;
-                       struct sock *sk;
-
-                        DPRINTK("%s: entry found, responding to zeppelin\n", dev->name);
-                        skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
-                        if (skb2 == NULL) {
-                                br_fdb_put_hook(f);
-                                break;
-                        }
-                        skb2->len = sizeof(struct atmlec_msg);
-                        memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
-                        atm_force_charge(priv->lecd, skb2->truesize);
-                       sk = sk_atm(priv->lecd);
-                        skb_queue_tail(&sk->sk_receive_queue, skb2);
-                        sk->sk_data_ready(sk, skb2->len);
-                }
-                if (f != NULL) br_fdb_put_hook(f);
+               {
+                       struct net_bridge_fdb_entry *f;
+
+                       DPRINTK
+                           ("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                            dev->name, mesg->content.proxy.mac_addr[0],
+                            mesg->content.proxy.mac_addr[1],
+                            mesg->content.proxy.mac_addr[2],
+                            mesg->content.proxy.mac_addr[3],
+                            mesg->content.proxy.mac_addr[4],
+                            mesg->content.proxy.mac_addr[5]);
+
+                       if (br_fdb_get_hook == NULL || dev->br_port == NULL)
+                               break;
+
+                       f = br_fdb_get_hook(dev->br_port->br,
+                                           mesg->content.proxy.mac_addr);
+                       if (f != NULL && f->dst->dev != dev
+                           && f->dst->state == BR_STATE_FORWARDING) {
+                               /* hit from bridge table, send LE_ARP_RESPONSE */
+                               struct sk_buff *skb2;
+                               struct sock *sk;
+
+                               DPRINTK
+                                   ("%s: entry found, responding to zeppelin\n",
+                                    dev->name);
+                               skb2 =
+                                   alloc_skb(sizeof(struct atmlec_msg),
+                                             GFP_ATOMIC);
+                               if (skb2 == NULL) {
+                                       br_fdb_put_hook(f);
+                                       break;
+                               }
+                               skb2->len = sizeof(struct atmlec_msg);
+                               memcpy(skb2->data, mesg,
+                                      sizeof(struct atmlec_msg));
+                               atm_force_charge(priv->lecd, skb2->truesize);
+                               sk = sk_atm(priv->lecd);
+                               skb_queue_tail(&sk->sk_receive_queue, skb2);
+                               sk->sk_data_ready(sk, skb2->len);
+                       }
+                       if (f != NULL)
+                               br_fdb_put_hook(f);
+               }
 #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
-                }
-                break;
-        default:
-                printk("%s: Unknown message type %d\n", dev->name, mesg->type);
-                dev_kfree_skb(skb);
-                return -EINVAL;
-        }
-        dev_kfree_skb(skb);
-        return 0;
+               break;
+       default:
+               printk("%s: Unknown message type %d\n", dev->name, mesg->type);
+               dev_kfree_skb(skb);
+               return -EINVAL;
+       }
+       dev_kfree_skb(skb);
+       return 0;
 }
 
-static void 
-lec_atm_close(struct atm_vcc *vcc)
+static void lec_atm_close(struct atm_vcc *vcc)
 {
-        struct sk_buff *skb;
-        struct net_device *dev = (struct net_device *)vcc->proto_data;
-        struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct sk_buff *skb;
+       struct net_device *dev = (struct net_device *)vcc->proto_data;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
 
-        priv->lecd = NULL;
-        /* Do something needful? */
+       priv->lecd = NULL;
+       /* Do something needful? */
 
-        netif_stop_queue(dev);
-        lec_arp_destroy(priv);
+       netif_stop_queue(dev);
+       lec_arp_destroy(priv);
 
-        if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
+       if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
                printk("%s lec_atm_close: closing with messages pending\n",
-                       dev->name);
-        while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
-                atm_return(vcc, skb->truesize);
+                      dev->name);
+       while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
+               atm_return(vcc, skb->truesize);
                dev_kfree_skb(skb);
-        }
-  
+       }
+
        printk("%s: Shut down!\n", dev->name);
-        module_put(THIS_MODULE);
+       module_put(THIS_MODULE);
 }
 
 static struct atmdev_ops lecdev_ops = {
-        .close = lec_atm_close,
-        .send  = lec_atm_send
+       .close = lec_atm_close,
+       .send = lec_atm_send
 };
 
 static struct atm_dev lecatm_dev = {
-       .ops    = &lecdev_ops,
-       .type   = "lec",
-       .number = 999,  /* dummy device number */
-       .lock   = SPIN_LOCK_UNLOCKED
+       .ops = &lecdev_ops,
+       .type = "lec",
+       .number = 999,          /* dummy device number */
+       .lock = SPIN_LOCK_UNLOCKED
 };
 
 /*
  * LANE2: new argument struct sk_buff *data contains
  * the LE_ARP based TLVs introduced in the LANE2 spec
  */
-static int 
-send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, 
-             unsigned char *mac_addr, unsigned char *atm_addr,
-             struct sk_buff *data)
+static int
+send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
+            unsigned char *mac_addr, unsigned char *atm_addr,
+            struct sk_buff *data)
 {
        struct sock *sk;
        struct sk_buff *skb;
@@ -621,187 +654,193 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
                return -1;
        skb->len = sizeof(struct atmlec_msg);
        mesg = (struct atmlec_msg *)skb->data;
-        memset(mesg, 0, sizeof(struct atmlec_msg));
+       memset(mesg, 0, sizeof(struct atmlec_msg));
        mesg->type = type;
-        if (data != NULL)
-                mesg->sizeoftlvs = data->len;
+       if (data != NULL)
+               mesg->sizeoftlvs = data->len;
        if (mac_addr)
                memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);
-        else
-                mesg->content.normal.targetless_le_arp = 1;
+       else
+               mesg->content.normal.targetless_le_arp = 1;
        if (atm_addr)
                memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
 
-        atm_force_charge(priv->lecd, skb->truesize);
+       atm_force_charge(priv->lecd, skb->truesize);
        sk = sk_atm(priv->lecd);
        skb_queue_tail(&sk->sk_receive_queue, skb);
-        sk->sk_data_ready(sk, skb->len);
+       sk->sk_data_ready(sk, skb->len);
 
-        if (data != NULL) {
-                DPRINTK("lec: about to send %d bytes of data\n", data->len);
-                atm_force_charge(priv->lecd, data->truesize);
-                skb_queue_tail(&sk->sk_receive_queue, data);
-                sk->sk_data_ready(sk, skb->len);
-        }
+       if (data != NULL) {
+               DPRINTK("lec: about to send %d bytes of data\n", data->len);
+               atm_force_charge(priv->lecd, data->truesize);
+               skb_queue_tail(&sk->sk_receive_queue, data);
+               sk->sk_data_ready(sk, skb->len);
+       }
 
-        return 0;
+       return 0;
 }
 
 /* shamelessly stolen from drivers/net/net_init.c */
 static int lec_change_mtu(struct net_device *dev, int new_mtu)
 {
-        if ((new_mtu < 68) || (new_mtu > 18190))
-                return -EINVAL;
-        dev->mtu = new_mtu;
-        return 0;
+       if ((new_mtu < 68) || (new_mtu > 18190))
+               return -EINVAL;
+       dev->mtu = new_mtu;
+       return 0;
 }
 
 static void lec_set_multicast_list(struct net_device *dev)
 {
-       /* by default, all multicast frames arrive over the bus.
-         * eventually support selective multicast service
-         */
-        return;
+       /*
+        * by default, all multicast frames arrive over the bus.
+        * eventually support selective multicast service
+        */
+       return;
 }
 
-static void 
-lec_init(struct net_device *dev)
+static void lec_init(struct net_device *dev)
 {
-        dev->change_mtu = lec_change_mtu;
-        dev->open = lec_open;
-        dev->stop = lec_close;
-        dev->hard_start_xmit = lec_start_xmit;
+       dev->change_mtu = lec_change_mtu;
+       dev->open = lec_open;
+       dev->stop = lec_close;
+       dev->hard_start_xmit = lec_start_xmit;
        dev->tx_timeout = lec_tx_timeout;
 
-        dev->get_stats = lec_get_stats;
-        dev->set_multicast_list = lec_set_multicast_list;
-        dev->do_ioctl  = NULL;
-        printk("%s: Initialized!\n",dev->name);
-        return;
+       dev->get_stats = lec_get_stats;
+       dev->set_multicast_list = lec_set_multicast_list;
+       dev->do_ioctl = NULL;
+       printk("%s: Initialized!\n", dev->name);
+       return;
 }
 
 static unsigned char lec_ctrl_magic[] = {
-        0xff,
-        0x00,
-        0x01,
-        0x01 };
+       0xff,
+       0x00,
+       0x01,
+       0x01
+};
 
 #define LEC_DATA_DIRECT_8023  2
 #define LEC_DATA_DIRECT_8025  3
 
 static int lec_is_data_direct(struct atm_vcc *vcc)
-{ 
+{
        return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
                (vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
-} 
+}
 
-static void 
-lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
+static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        unsigned long flags;
-        struct net_device *dev = (struct net_device *)vcc->proto_data;
-        struct lec_priv *priv = (struct lec_priv *)dev->priv; 
+       struct net_device *dev = (struct net_device *)vcc->proto_data;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
 
 #if DUMP_PACKETS >0
-        int i=0;
-        char buf[300];
+       int i = 0;
+       char buf[300];
 
-        printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
-               vcc->vpi, vcc->vci);
+       printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
+              vcc->vpi, vcc->vci);
 #endif
-        if (!skb) {
-                DPRINTK("%s: null skb\n",dev->name);
-                lec_vcc_close(priv, vcc);
-                return;
-        }
+       if (!skb) {
+               DPRINTK("%s: null skb\n", dev->name);
+               lec_vcc_close(priv, vcc);
+               return;
+       }
 #if DUMP_PACKETS > 0
-        printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
-               skb->len, priv->lecid);
+       printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
+              skb->len, priv->lecid);
 #if DUMP_PACKETS >= 2
-        for(i=0;i<skb->len && i <99;i++) {
-                sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);
-        }
+       for (i = 0; i < skb->len && i < 99; i++) {
+               sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+       }
 #elif DUMP_PACKETS >= 1
-        for(i=0;i<skb->len && i < 30;i++) {
-                sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);
-        }
+       for (i = 0; i < skb->len && i < 30; i++) {
+               sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+       }
 #endif /* DUMP_PACKETS >= 1 */
-        if (i==skb->len)
-                printk("%s\n",buf);
-        else
-                printk("%s...\n",buf);
+       if (i == skb->len)
+               printk("%s\n", buf);
+       else
+               printk("%s...\n", buf);
 #endif /* DUMP_PACKETS > 0 */
-        if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
+       if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) {        /* Control frame, to daemon */
                struct sock *sk = sk_atm(vcc);
 
-                DPRINTK("%s: To daemon\n",dev->name);
-                skb_queue_tail(&sk->sk_receive_queue, skb);
-                sk->sk_data_ready(sk, skb->len);
-        } else { /* Data frame, queue to protocol handlers */
+               DPRINTK("%s: To daemon\n", dev->name);
+               skb_queue_tail(&sk->sk_receive_queue, skb);
+               sk->sk_data_ready(sk, skb->len);
+       } else {                /* Data frame, queue to protocol handlers */
                struct lec_arp_table *entry;
-                unsigned char *src, *dst;
-
-                atm_return(vcc,skb->truesize);
-                if (*(uint16_t *)skb->data == htons(priv->lecid) ||
-                    !priv->lecd ||
-                    !(dev->flags & IFF_UP)) { 
-                        /* Probably looping back, or if lecd is missing,
-                           lecd has gone down */
-                        DPRINTK("Ignoring frame...\n");
-                        dev_kfree_skb(skb);
-                        return;
-                }
+               unsigned char *src, *dst;
+
+               atm_return(vcc, skb->truesize);
+               if (*(uint16_t *) skb->data == htons(priv->lecid) ||
+                   !priv->lecd || !(dev->flags & IFF_UP)) {
+                       /*
+                        * Probably looping back, or if lecd is missing,
+                        * lecd has gone down
+                        */
+                       DPRINTK("Ignoring frame...\n");
+                       dev_kfree_skb(skb);
+                       return;
+               }
 #ifdef CONFIG_TR
-                if (priv->is_trdev)
-                       dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest;
-                else
+               if (priv->is_trdev)
+                       dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
+               else
 #endif
-               dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest;
+                       dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
 
-               /* If this is a Data Direct VCC, and the VCC does not match
+               /*
+                * If this is a Data Direct VCC, and the VCC does not match
                 * the LE_ARP cache entry, delete the LE_ARP cache entry.
                 */
                spin_lock_irqsave(&priv->lec_arp_lock, flags);
                if (lec_is_data_direct(vcc)) {
 #ifdef CONFIG_TR
                        if (priv->is_trdev)
-                               src = ((struct lecdatahdr_8025 *) skb->data)->h_source;
+                               src =
+                                   ((struct lecdatahdr_8025 *)skb->data)->
+                                   h_source;
                        else
 #endif
-                       src = ((struct lecdatahdr_8023 *) skb->data)->h_source;
+                               src =
+                                   ((struct lecdatahdr_8023 *)skb->data)->
+                                   h_source;
                        entry = lec_arp_find(priv, src);
                        if (entry && entry->vcc != vcc) {
                                lec_arp_remove(priv, entry);
-                               kfree(entry);
+                               lec_arp_put(entry);
                        }
                }
                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
-                if (!(dst[0]&0x01) &&   /* Never filter Multi/Broadcast */
-                    !priv->is_proxy &&  /* Proxy wants all the packets */
+               if (!(dst[0] & 0x01) && /* Never filter Multi/Broadcast */
+                   !priv->is_proxy &&  /* Proxy wants all the packets */
                    memcmp(dst, dev->dev_addr, dev->addr_len)) {
-                        dev_kfree_skb(skb);
-                        return;
-                }
-                if (priv->lec_arp_empty_ones) {
-                        lec_arp_check_empties(priv, vcc, skb);
-                }
-                skb->dev = dev;
-                skb_pull(skb, 2); /* skip lec_id */
+                       dev_kfree_skb(skb);
+                       return;
+               }
+               if (!hlist_empty(&priv->lec_arp_empty_ones)) {
+                       lec_arp_check_empties(priv, vcc, skb);
+               }
+               skb->dev = dev;
+               skb_pull(skb, 2);       /* skip lec_id */
 #ifdef CONFIG_TR
-                if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);
-                else
+               if (priv->is_trdev)
+                       skb->protocol = tr_type_trans(skb, dev);
+               else
 #endif
-                skb->protocol = eth_type_trans(skb, dev);
-                priv->stats.rx_packets++;
-                priv->stats.rx_bytes += skb->len;
-                memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
-                netif_rx(skb);
-        }
+                       skb->protocol = eth_type_trans(skb, dev);
+               priv->stats.rx_packets++;
+               priv->stats.rx_bytes += skb->len;
+               memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
+               netif_rx(skb);
+       }
 }
 
-static void
-lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
+static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
        struct net_device *dev = skb->dev;
@@ -820,123 +859,121 @@ lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
        }
 }
 
-static int 
-lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
+static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
 {
        struct lec_vcc_priv *vpriv;
-        int bytes_left;
-        struct atmlec_ioc ioc_data;
-
-        /* Lecd must be up in this case */
-        bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
-        if (bytes_left != 0) {
-                printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
-                       bytes_left);
-        }
-        if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF || 
-            !dev_lec[ioc_data.dev_num])
-                return -EINVAL;
+       int bytes_left;
+       struct atmlec_ioc ioc_data;
+
+       /* Lecd must be up in this case */
+       bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
+       if (bytes_left != 0) {
+               printk
+                   ("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
+                    bytes_left);
+       }
+       if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
+           !dev_lec[ioc_data.dev_num])
+               return -EINVAL;
        if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
                return -ENOMEM;
        vpriv->xoff = 0;
        vpriv->old_pop = vcc->pop;
        vcc->user_back = vpriv;
        vcc->pop = lec_pop;
-        lec_vcc_added(dev_lec[ioc_data.dev_num]->priv, 
-                      &ioc_data, vcc, vcc->push);
-        vcc->proto_data = dev_lec[ioc_data.dev_num];
-        vcc->push = lec_push;
-        return 0;
+       lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
+                     &ioc_data, vcc, vcc->push);
+       vcc->proto_data = dev_lec[ioc_data.dev_num];
+       vcc->push = lec_push;
+       return 0;
 }
 
-static int 
-lec_mcast_attach(struct atm_vcc *vcc, int arg)
+static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
 {
-        if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
-                return -EINVAL;
-        vcc->proto_data = dev_lec[arg];
-        return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));
+       if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
+               return -EINVAL;
+       vcc->proto_data = dev_lec[arg];
+       return (lec_mcast_make((struct lec_priv *)dev_lec[arg]->priv, vcc));
 }
 
 /* Initialize device. */
-static int 
-lecd_attach(struct atm_vcc *vcc, int arg)
-{  
-        int i;
-        struct lec_priv *priv;
-
-        if (arg<0)
-                i = 0;
-        else
-                i = arg;
+static int lecd_attach(struct atm_vcc *vcc, int arg)
+{
+       int i;
+       struct lec_priv *priv;
+
+       if (arg < 0)
+               i = 0;
+       else
+               i = arg;
 #ifdef CONFIG_TR
-        if (arg >= MAX_LEC_ITF)
-                return -EINVAL;
-#else /* Reserve the top NUM_TR_DEVS for TR */
-        if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))
-                return -EINVAL;
+       if (arg >= MAX_LEC_ITF)
+               return -EINVAL;
+#else                          /* Reserve the top NUM_TR_DEVS for TR */
+       if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS))
+               return -EINVAL;
 #endif
-        if (!dev_lec[i]) {
-                int is_trdev, size;
+       if (!dev_lec[i]) {
+               int is_trdev, size;
 
-                is_trdev = 0;
-                if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
-                        is_trdev = 1;
+               is_trdev = 0;
+               if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
+                       is_trdev = 1;
 
-                size = sizeof(struct lec_priv);
+               size = sizeof(struct lec_priv);
 #ifdef CONFIG_TR
-                if (is_trdev)
-                        dev_lec[i] = alloc_trdev(size);
-                else
+               if (is_trdev)
+                       dev_lec[i] = alloc_trdev(size);
+               else
 #endif
-                dev_lec[i] = alloc_etherdev(size);
-                if (!dev_lec[i])
-                        return -ENOMEM;
-                snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
-                if (register_netdev(dev_lec[i])) {
-                        free_netdev(dev_lec[i]);
-                        return -EINVAL;
-                }
-
-                priv = dev_lec[i]->priv;
-                priv->is_trdev = is_trdev;
-                lec_init(dev_lec[i]);
-        } else {
-                priv = dev_lec[i]->priv;
-                if (priv->lecd)
-                        return -EADDRINUSE;
-        }
-        lec_arp_init(priv);
-       priv->itfnum = i;  /* LANE2 addition */
-        priv->lecd = vcc;
-        vcc->dev = &lecatm_dev;
-        vcc_insert_socket(sk_atm(vcc));
-        
-        vcc->proto_data = dev_lec[i];
-       set_bit(ATM_VF_META,&vcc->flags);
-       set_bit(ATM_VF_READY,&vcc->flags);
-
-        /* Set default values to these variables */
-        priv->maximum_unknown_frame_count = 1;
-        priv->max_unknown_frame_time = (1*HZ);
-        priv->vcc_timeout_period = (1200*HZ);
-        priv->max_retry_count = 1;
-        priv->aging_time = (300*HZ);
-        priv->forward_delay_time = (15*HZ);
-        priv->topology_change = 0;
-        priv->arp_response_time = (1*HZ);
-        priv->flush_timeout = (4*HZ);
-        priv->path_switching_delay = (6*HZ);
-
-        if (dev_lec[i]->flags & IFF_UP) {
-                netif_start_queue(dev_lec[i]);
-        }
-        __module_get(THIS_MODULE);
-        return i;
+                       dev_lec[i] = alloc_etherdev(size);
+               if (!dev_lec[i])
+                       return -ENOMEM;
+               snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
+               if (register_netdev(dev_lec[i])) {
+                       free_netdev(dev_lec[i]);
+                       return -EINVAL;
+               }
+
+               priv = dev_lec[i]->priv;
+               priv->is_trdev = is_trdev;
+               lec_init(dev_lec[i]);
+       } else {
+               priv = dev_lec[i]->priv;
+               if (priv->lecd)
+                       return -EADDRINUSE;
+       }
+       lec_arp_init(priv);
+       priv->itfnum = i;       /* LANE2 addition */
+       priv->lecd = vcc;
+       vcc->dev = &lecatm_dev;
+       vcc_insert_socket(sk_atm(vcc));
+
+       vcc->proto_data = dev_lec[i];
+       set_bit(ATM_VF_META, &vcc->flags);
+       set_bit(ATM_VF_READY, &vcc->flags);
+
+       /* Set default values to these variables */
+       priv->maximum_unknown_frame_count = 1;
+       priv->max_unknown_frame_time = (1 * HZ);
+       priv->vcc_timeout_period = (1200 * HZ);
+       priv->max_retry_count = 1;
+       priv->aging_time = (300 * HZ);
+       priv->forward_delay_time = (15 * HZ);
+       priv->topology_change = 0;
+       priv->arp_response_time = (1 * HZ);
+       priv->flush_timeout = (4 * HZ);
+       priv->path_switching_delay = (6 * HZ);
+
+       if (dev_lec[i]->flags & IFF_UP) {
+               netif_start_queue(dev_lec[i]);
+       }
+       __module_get(THIS_MODULE);
+       return i;
 }
 
 #ifdef CONFIG_PROC_FS
-static charlec_arp_get_status_string(unsigned char status)
+static char *lec_arp_get_status_string(unsigned char status)
 {
        static char *lec_arp_status_string[] = {
                "ESI_UNKNOWN       ",
@@ -966,52 +1003,54 @@ static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
        if (entry->vcc)
                seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
        else
-               seq_printf(seq, "        ");
+               seq_printf(seq, "        ");
        if (entry->recv_vcc) {
                seq_printf(seq, "     %3d %3d", entry->recv_vcc->vpi,
                           entry->recv_vcc->vci);
-        }
-        seq_putc(seq, '\n');
+       }
+       seq_putc(seq, '\n');
 }
 
-
 struct lec_state {
        unsigned long flags;
        struct lec_priv *locked;
-       struct lec_arp_table *entry;
+       struct hlist_node *node;
        struct net_device *dev;
        int itf;
        int arp_table;
        int misc_table;
 };
 
-static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
+static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
                          loff_t *l)
 {
-       struct lec_arp_table *e = state->entry;
+       struct hlist_node *e = state->node;
+       struct lec_arp_table *tmp;
 
        if (!e)
-               e = tbl;
+               e = tbl->first;
        if (e == (void *)1) {
-               e = tbl;
+               e = tbl->first;
                --*l;
        }
-       for (; e; e = e->next) {
+
+       hlist_for_each_entry_from(tmp, e, next) {
                if (--*l < 0)
                        break;
        }
-       state->entry = e;
+       state->node = e;
+
        return (*l < 0) ? state : NULL;
 }
 
 static void *lec_arp_walk(struct lec_state *state, loff_t *l,
-                             struct lec_priv *priv)
+                         struct lec_priv *priv)
 {
        void *v = NULL;
        int p;
 
        for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
-               v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
+               v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
                if (v)
                        break;
        }
@@ -1022,10 +1061,10 @@ static void *lec_arp_walk(struct lec_state *state, loff_t *l,
 static void *lec_misc_walk(struct lec_state *state, loff_t *l,
                           struct lec_priv *priv)
 {
-       struct lec_arp_table *lec_misc_tables[] = {
-               priv->lec_arp_empty_ones,
-               priv->lec_no_forward,
-               priv->mcast_fwds
+       struct hlist_head *lec_misc_tables[] = {
+               &priv->lec_arp_empty_ones,
+               &priv->lec_no_forward,
+               &priv->mcast_fwds
        };
        void *v = NULL;
        int q;
@@ -1046,8 +1085,7 @@ static void *lec_priv_walk(struct lec_state *state, loff_t *l,
                state->locked = priv;
                spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
        }
-       if (!lec_arp_walk(state, l, priv) &&
-           !lec_misc_walk(state, l, priv)) {
+       if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) {
                spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
                state->locked = NULL;
                /* Partial state reset for the next time we get called */
@@ -1081,7 +1119,7 @@ static void *lec_get_idx(struct lec_state *state, loff_t l)
                if (v)
                        break;
        }
-       return v; 
+       return v;
 }
 
 static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1093,9 +1131,9 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
        state->locked = NULL;
        state->arp_table = 0;
        state->misc_table = 0;
-       state->entry = (void *)1;
+       state->node = (void *)1;
 
-       return *pos ? lec_get_idx(state, *pos) : (void*)1;
+       return *pos ? lec_get_idx(state, *pos) : (void *)1;
 }
 
 static void lec_seq_stop(struct seq_file *seq, void *v)
@@ -1120,27 +1158,28 @@ static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 static int lec_seq_show(struct seq_file *seq, void *v)
 {
-       static char lec_banner[] = "Itf  MAC          ATM destination" 
-               "                          Status            Flags "
-               "VPI/VCI Recv VPI/VCI\n";
+       static char lec_banner[] = "Itf  MAC          ATM destination"
+           "                          Status            Flags "
+           "VPI/VCI Recv VPI/VCI\n";
 
        if (v == (void *)1)
                seq_puts(seq, lec_banner);
        else {
                struct lec_state *state = seq->private;
-               struct net_device *dev = state->dev; 
+               struct net_device *dev = state->dev;
+               struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next);
 
                seq_printf(seq, "%s ", dev->name);
-               lec_info(seq, state->entry);
+               lec_info(seq, entry);
        }
        return 0;
 }
 
 static struct seq_operations lec_seq_ops = {
-       .start  = lec_seq_start,
-       .next   = lec_seq_next,
-       .stop   = lec_seq_stop,
-       .show   = lec_seq_show,
+       .start = lec_seq_start,
+       .next = lec_seq_next,
+       .stop = lec_seq_stop,
+       .show = lec_seq_show,
 };
 
 static int lec_seq_open(struct inode *inode, struct file *file)
@@ -1174,11 +1213,11 @@ static int lec_seq_release(struct inode *inode, struct file *file)
 }
 
 static struct file_operations lec_seq_fops = {
-       .owner          = THIS_MODULE,
-       .open           = lec_seq_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = lec_seq_release,
+       .owner = THIS_MODULE,
+       .open = lec_seq_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = lec_seq_release,
 };
 #endif
 
@@ -1186,38 +1225,38 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct atm_vcc *vcc = ATM_SD(sock);
        int err = 0;
-       
+
        switch (cmd) {
-               case ATMLEC_CTRL: 
-               case ATMLEC_MCAST:
-               case ATMLEC_DATA:
-                       if (!capable(CAP_NET_ADMIN))
-                               return -EPERM;
-                       break;
-               default:
-                       return -ENOIOCTLCMD;
+       case ATMLEC_CTRL:
+       case ATMLEC_MCAST:
+       case ATMLEC_DATA:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               break;
+       default:
+               return -ENOIOCTLCMD;
        }
 
        switch (cmd) {
-               case ATMLEC_CTRL:
-                       err = lecd_attach(vcc, (int) arg);
-                       if (err >= 0)
-                               sock->state = SS_CONNECTED;
-                       break;
-               case ATMLEC_MCAST:
-                       err = lec_mcast_attach(vcc, (int) arg);
-                       break;
-               case ATMLEC_DATA:
-                       err = lec_vcc_attach(vcc, (void __user *) arg);
-                       break;
+       case ATMLEC_CTRL:
+               err = lecd_attach(vcc, (int)arg);
+               if (err >= 0)
+                       sock->state = SS_CONNECTED;
+               break;
+       case ATMLEC_MCAST:
+               err = lec_mcast_attach(vcc, (int)arg);
+               break;
+       case ATMLEC_DATA:
+               err = lec_vcc_attach(vcc, (void __user *)arg);
+               break;
        }
 
        return err;
 }
 
 static struct atm_ioctl lane_ioctl_ops = {
-       .owner  = THIS_MODULE,
-       .ioctl  = lane_ioctl,
+       .owner = THIS_MODULE,
+       .ioctl = lane_ioctl,
 };
 
 static int __init lane_module_init(void)
@@ -1231,29 +1270,29 @@ static int __init lane_module_init(void)
 #endif
 
        register_atm_ioctl(&lane_ioctl_ops);
-        printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
-        return 0;
+       printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
+       return 0;
 }
 
 static void __exit lane_module_cleanup(void)
 {
-        int i;
-        struct lec_priv *priv;
+       int i;
+       struct lec_priv *priv;
 
        remove_proc_entry("lec", atm_proc_root);
 
        deregister_atm_ioctl(&lane_ioctl_ops);
 
-        for (i = 0; i < MAX_LEC_ITF; i++) {
-                if (dev_lec[i] != NULL) {
-                        priv = (struct lec_priv *)dev_lec[i]->priv;
+       for (i = 0; i < MAX_LEC_ITF; i++) {
+               if (dev_lec[i] != NULL) {
+                       priv = (struct lec_priv *)dev_lec[i]->priv;
                        unregister_netdev(dev_lec[i]);
-                        free_netdev(dev_lec[i]);
-                        dev_lec[i] = NULL;
-                }
-        }
+                       free_netdev(dev_lec[i]);
+                       dev_lec[i] = NULL;
+               }
+       }
 
-        return;                                    
+       return;
 }
 
 module_init(lane_module_init);
@@ -1267,34 +1306,34 @@ module_exit(lane_module_cleanup);
  * If dst_mac == NULL, targetless LE_ARP will be sent
  */
 static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
-    u8 **tlvs, u32 *sizeoftlvs)
+                        u8 **tlvs, u32 *sizeoftlvs)
 {
        unsigned long flags;
-        struct lec_priv *priv = (struct lec_priv *)dev->priv;
-        struct lec_arp_table *table;
-        struct sk_buff *skb;
-        int retval;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_arp_table *table;
+       struct sk_buff *skb;
+       int retval;
 
-        if (force == 0) {
+       if (force == 0) {
                spin_lock_irqsave(&priv->lec_arp_lock, flags);
-                table = lec_arp_find(priv, dst_mac);
+               table = lec_arp_find(priv, dst_mac);
                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-                if(table == NULL)
-                        return -1;
-                
-                *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
-                if (*tlvs == NULL)
-                        return -1;
-                
-                memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
-                *sizeoftlvs = table->sizeoftlvs;
-                
-                return 0;
-        }
+               if (table == NULL)
+                       return -1;
+
+               *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
+               if (*tlvs == NULL)
+                       return -1;
+
+               memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
+               *sizeoftlvs = table->sizeoftlvs;
+
+               return 0;
+       }
 
        if (sizeoftlvs == NULL)
                retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
-               
+
        else {
                skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
                if (skb == NULL)
@@ -1303,9 +1342,8 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
                memcpy(skb->data, *tlvs, *sizeoftlvs);
                retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
        }
-        return retval;
-}        
-
+       return retval;
+}
 
 /*
  * LANE2: 3.1.4, LE_ASSOCIATE.request
@@ -1314,80 +1352,85 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
  * Returns 1 for success, 0 for failure (out of memory)
  *
  */
-static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,
-                         u8 *tlvs, u32 sizeoftlvs)
+static int lane2_associate_req(struct net_device *dev, u8 *lan_dst,
+                              u8 *tlvs, u32 sizeoftlvs)
 {
-        int retval;
-        struct sk_buff *skb;
-        struct lec_priv *priv = (struct lec_priv*)dev->priv;
-
-        if (compare_ether_addr(lan_dst, dev->dev_addr))
-                return (0);       /* not our mac address */
-
-        kfree(priv->tlvs); /* NULL if there was no previous association */
-
-        priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
-        if (priv->tlvs == NULL)
-                return (0);
-        priv->sizeoftlvs = sizeoftlvs;
-        memcpy(priv->tlvs, tlvs, sizeoftlvs);
-
-        skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
-        if (skb == NULL)
-                return 0;
-        skb->len = sizeoftlvs;
-        memcpy(skb->data, tlvs, sizeoftlvs);
-        retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
-        if (retval != 0)
-                printk("lec.c: lane2_associate_req() failed\n");
-        /* If the previous association has changed we must
-         * somehow notify other LANE entities about the change
-         */
-        return (1);
+       int retval;
+       struct sk_buff *skb;
+       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+
+       if (compare_ether_addr(lan_dst, dev->dev_addr))
+               return (0);     /* not our mac address */
+
+       kfree(priv->tlvs);      /* NULL if there was no previous association */
+
+       priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
+       if (priv->tlvs == NULL)
+               return (0);
+       priv->sizeoftlvs = sizeoftlvs;
+       memcpy(priv->tlvs, tlvs, sizeoftlvs);
+
+       skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
+       if (skb == NULL)
+               return 0;
+       skb->len = sizeoftlvs;
+       memcpy(skb->data, tlvs, sizeoftlvs);
+       retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
+       if (retval != 0)
+               printk("lec.c: lane2_associate_req() failed\n");
+       /*
+        * If the previous association has changed we must
+        * somehow notify other LANE entities about the change
+        */
+       return (1);
 }
 
 /*
  * LANE2: 3.1.5, LE_ASSOCIATE.indication
  *
  */
-static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
-    u8 *tlvs, u32 sizeoftlvs)
+static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr,
+                               u8 *tlvs, u32 sizeoftlvs)
 {
 #if 0
-        int i = 0;
+       int i = 0;
 #endif
        struct lec_priv *priv = (struct lec_priv *)dev->priv;
-#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you
-         uncomment this code, make sure the TLVs get freed when entry is killed */
-        struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
+#if 0                          /*
+                                * Why have the TLVs in LE_ARP entries
+                                * since we do not use them? When you
+                                * uncomment this code, make sure the
+                                * TLVs get freed when entry is killed
+                                */
+       struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
 
-        if (entry == NULL)
-                return;     /* should not happen */
+       if (entry == NULL)
+               return;         /* should not happen */
 
-        kfree(entry->tlvs);
+       kfree(entry->tlvs);
 
-        entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
-        if (entry->tlvs == NULL)
-                return;
+       entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);
+       if (entry->tlvs == NULL)
+               return;
 
-        entry->sizeoftlvs = sizeoftlvs;
-        memcpy(entry->tlvs, tlvs, sizeoftlvs);
+       entry->sizeoftlvs = sizeoftlvs;
+       memcpy(entry->tlvs, tlvs, sizeoftlvs);
 #endif
 #if 0
-        printk("lec.c: lane2_associate_ind()\n");
-        printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
-        while (i < sizeoftlvs)
-                printk("%02x ", tlvs[i++]);
-        
-        printk("\n");
+       printk("lec.c: lane2_associate_ind()\n");
+       printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
+       while (i < sizeoftlvs)
+               printk("%02x ", tlvs[i++]);
+
+       printk("\n");
 #endif
 
-        /* tell MPOA about the TLVs we saw */
-        if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
-                priv->lane2_ops->associate_indicator(dev, mac_addr,
-                                                     tlvs, sizeoftlvs);
-        }
-        return;
+       /* tell MPOA about the TLVs we saw */
+       if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
+               priv->lane2_ops->associate_indicator(dev, mac_addr,
+                                                    tlvs, sizeoftlvs);
+       }
+       return;
 }
 
 /*
@@ -1395,7 +1438,6 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
  *
  * lec_arpc.c was added here when making
  * lane client modular. October 1997
- *
  */
 
 #include <linux/types.h>
@@ -1406,7 +1448,6 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
 #include <linux/inetdevice.h>
 #include <net/route.h>
 
-
 #if 0
 #define DPRINTK(format,args...)
 /*
@@ -1417,7 +1458,7 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
 
 #define LEC_ARP_REFRESH_INTERVAL (3*HZ)
 
-static void lec_arp_check_expire(unsigned long data);
+static void lec_arp_check_expire(void *data);
 static void lec_arp_expire_arp(unsigned long data);
 
 /* 
@@ -1429,474 +1470,397 @@ static void lec_arp_expire_arp(unsigned long data);
 /*
  * Initialization of arp-cache
  */
-static void 
-lec_arp_init(struct lec_priv *priv)
+static void lec_arp_init(struct lec_priv *priv)
 {
-        unsigned short i;
+       unsigned short i;
 
-        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                priv->lec_arp_tables[i] = NULL;
-        }        
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
+       }
+        INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
+        INIT_HLIST_HEAD(&priv->lec_no_forward);
+        INIT_HLIST_HEAD(&priv->mcast_fwds);
        spin_lock_init(&priv->lec_arp_lock);
-        init_timer(&priv->lec_arp_timer);
-        priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
-        priv->lec_arp_timer.data = (unsigned long)priv;
-        priv->lec_arp_timer.function = lec_arp_check_expire;
-        add_timer(&priv->lec_arp_timer);
+       INIT_WORK(&priv->lec_arp_work, lec_arp_check_expire, priv);
+       schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
 }
 
-static void
-lec_arp_clear_vccs(struct lec_arp_table *entry)
+static void lec_arp_clear_vccs(struct lec_arp_table *entry)
 {
-        if (entry->vcc) {
+       if (entry->vcc) {
                struct atm_vcc *vcc = entry->vcc;
                struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
-               struct net_device *dev = (struct net_device*) vcc->proto_data;
+               struct net_device *dev = (struct net_device *)vcc->proto_data;
 
-                vcc->pop = vpriv->old_pop;
+               vcc->pop = vpriv->old_pop;
                if (vpriv->xoff)
                        netif_wake_queue(dev);
                kfree(vpriv);
                vcc->user_back = NULL;
-                vcc->push = entry->old_push;
+               vcc->push = entry->old_push;
                vcc_release_async(vcc, -EPIPE);
-                vcc = NULL;
-        }
-        if (entry->recv_vcc) {
-                entry->recv_vcc->push = entry->old_recv_push;
+               entry->vcc = NULL;
+       }
+       if (entry->recv_vcc) {
+               entry->recv_vcc->push = entry->old_recv_push;
                vcc_release_async(entry->recv_vcc, -EPIPE);
-                entry->recv_vcc = NULL;
-        }        
+               entry->recv_vcc = NULL;
+       }
 }
 
 /*
  * Insert entry to lec_arp_table
  * LANE2: Add to the end of the list to satisfy 8.1.13
  */
-static inline void 
-lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
+static inline void
+lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
 {
-        unsigned short place;
-        struct lec_arp_table *tmp;
-
-        place = HASH(to_add->mac_addr[ETH_ALEN-1]);
-        tmp = priv->lec_arp_tables[place];
-        to_add->next = NULL;
-        if (tmp == NULL)
-                priv->lec_arp_tables[place] = to_add;
-  
-        else {  /* add to the end */
-                while (tmp->next)
-                        tmp = tmp->next;
-                tmp->next = to_add;
-        }
-
-        DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
-                0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],
-                0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],
-                0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]);
+       struct hlist_head *tmp;
+
+       tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
+       hlist_add_head(&entry->next, tmp);
+
+       DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+               0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1],
+               0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3],
+               0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]);
 }
 
 /*
  * Remove entry from lec_arp_table
  */
-static int 
-lec_arp_remove(struct lec_priv *priv,
-               struct lec_arp_table *to_remove)
+static int
+lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
 {
-        unsigned short place;
-        struct lec_arp_table *tmp;
-        int remove_vcc=1;
-
-        if (!to_remove) {
-                return -1;
-        }
-        place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
-        tmp = priv->lec_arp_tables[place];
-        if (tmp == to_remove) {
-                priv->lec_arp_tables[place] = tmp->next;
-        } else {
-                while(tmp && tmp->next != to_remove) {
-                        tmp = tmp->next;
-                }
-                if (!tmp) {/* Entry was not found */
-                        return -1;
-                }
-        }
-        tmp->next = to_remove->next;
-        del_timer(&to_remove->timer);
-  
-        /* If this is the only MAC connected to this VCC, also tear down
-           the VCC */
-        if (to_remove->status >= ESI_FLUSH_PENDING) {
-                /*
-                 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
-                 */
-                for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) {
-                        for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) {
-                                if (memcmp(tmp->atm_addr, to_remove->atm_addr,
-                                           ATM_ESA_LEN)==0) {
-                                        remove_vcc=0;
-                                        break;
-                                }
-                        }
-                }
-                if (remove_vcc)
-                        lec_arp_clear_vccs(to_remove);
-        }
-        skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
-
-        DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
-                0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
-                0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
-                0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]);
-        return 0;
+       struct hlist_node *node;
+       struct lec_arp_table *entry;
+       int i, remove_vcc = 1;
+
+       if (!to_remove) {
+               return -1;
+       }
+
+       hlist_del(&to_remove->next);
+       del_timer(&to_remove->timer);
+
+       /* If this is the only MAC connected to this VCC, also tear down the VCC */
+       if (to_remove->status >= ESI_FLUSH_PENDING) {
+               /*
+                * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
+                */
+               for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                       hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+                               if (memcmp(to_remove->atm_addr,
+                                          entry->atm_addr, ATM_ESA_LEN) == 0) {
+                                       remove_vcc = 0;
+                                       break;
+                               }
+                       }
+               }
+               if (remove_vcc)
+                       lec_arp_clear_vccs(to_remove);
+       }
+       skb_queue_purge(&to_remove->tx_wait);   /* FIXME: good place for this? */
+
+       DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+               0xff & to_remove->mac_addr[0], 0xff & to_remove->mac_addr[1],
+               0xff & to_remove->mac_addr[2], 0xff & to_remove->mac_addr[3],
+               0xff & to_remove->mac_addr[4], 0xff & to_remove->mac_addr[5]);
+       return 0;
 }
 
 #if DEBUG_ARP_TABLE
-static char*
-get_status_string(unsigned char st)
+static char *get_status_string(unsigned char st)
 {
-        switch(st) {
-        case ESI_UNKNOWN:
-                return "ESI_UNKNOWN";
-        case ESI_ARP_PENDING:
-                return "ESI_ARP_PENDING";
-        case ESI_VC_PENDING:
-                return "ESI_VC_PENDING";
-        case ESI_FLUSH_PENDING:
-                return "ESI_FLUSH_PENDING";
-        case ESI_FORWARD_DIRECT:
-                return "ESI_FORWARD_DIRECT";
-        default:
-                return "<UNKNOWN>";
-        }
+       switch (st) {
+       case ESI_UNKNOWN:
+               return "ESI_UNKNOWN";
+       case ESI_ARP_PENDING:
+               return "ESI_ARP_PENDING";
+       case ESI_VC_PENDING:
+               return "ESI_VC_PENDING";
+       case ESI_FLUSH_PENDING:
+               return "ESI_FLUSH_PENDING";
+       case ESI_FORWARD_DIRECT:
+               return "ESI_FORWARD_DIRECT";
+       default:
+               return "<UNKNOWN>";
+       }
 }
-#endif
 
-static void
-dump_arp_table(struct lec_priv *priv)
+static void dump_arp_table(struct lec_priv *priv)
 {
-#if DEBUG_ARP_TABLE
-        int i,j, offset;
-        struct lec_arp_table *rulla;
-        char buf[1024];
-        struct lec_arp_table **lec_arp_tables =
-                (struct lec_arp_table **)priv->lec_arp_tables;
-        struct lec_arp_table *lec_arp_empty_ones =
-                (struct lec_arp_table *)priv->lec_arp_empty_ones;
-        struct lec_arp_table *lec_no_forward =
-                (struct lec_arp_table *)priv->lec_no_forward;
-        struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
-
-
-        printk("Dump %p:\n",priv);
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                rulla = lec_arp_tables[i];
-                offset = 0;
-                offset += sprintf(buf,"%d: %p\n",i, rulla);
-                while (rulla) {
-                        offset += sprintf(buf+offset,"Mac:");
-                        for(j=0;j<ETH_ALEN;j++) {
-                                offset+=sprintf(buf+offset,
-                                                "%2.2x ",
-                                                rulla->mac_addr[j]&0xff);
-                        }
-                        offset +=sprintf(buf+offset,"Atm:");
-                        for(j=0;j<ATM_ESA_LEN;j++) {
-                                offset+=sprintf(buf+offset,
-                                                "%2.2x ",
-                                                rulla->atm_addr[j]&0xff);
-                        }      
-                        offset+=sprintf(buf+offset,
-                                        "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-                                        rulla->vcc?rulla->vcc->vpi:0, 
-                                        rulla->vcc?rulla->vcc->vci:0,
-                                        rulla->recv_vcc?rulla->recv_vcc->vpi:0,
-                                        rulla->recv_vcc?rulla->recv_vcc->vci:0,
-                                        rulla->last_used,
-                                        rulla->timestamp, rulla->no_tries);
-                        offset+=sprintf(buf+offset,
-                                        "Flags:%x, Packets_flooded:%x, Status: %s ",
-                                        rulla->flags, rulla->packets_flooded, 
-                                        get_status_string(rulla->status));
-                        offset+=sprintf(buf+offset,"->%p\n",rulla->next);
-                        rulla = rulla->next;
-                }
-                printk("%s",buf);
-        }
-        rulla = lec_no_forward;
-        if (rulla)
-                printk("No forward\n");  
-        while(rulla) {
-                offset=0;
-                offset += sprintf(buf+offset,"Mac:");
-                for(j=0;j<ETH_ALEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->mac_addr[j]&0xff);
-                }
-                offset +=sprintf(buf+offset,"Atm:");
-                for(j=0;j<ATM_ESA_LEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->atm_addr[j]&0xff);
-                }      
-                offset+=sprintf(buf+offset,
-                                "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-                                rulla->vcc?rulla->vcc->vpi:0, 
-                                rulla->vcc?rulla->vcc->vci:0, 
-                                rulla->recv_vcc?rulla->recv_vcc->vpi:0,
-                                rulla->recv_vcc?rulla->recv_vcc->vci:0,
-                                rulla->last_used, 
-                                rulla->timestamp, rulla->no_tries);
-                offset+=sprintf(buf+offset,
-                                "Flags:%x, Packets_flooded:%x, Status: %s ",
-                                rulla->flags, rulla->packets_flooded, 
-                                get_status_string(rulla->status));
-                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
-                rulla = rulla->next;
-                printk("%s",buf);
-        }
-        rulla = lec_arp_empty_ones;
-        if (rulla)
-                printk("Empty ones\n");  
-        while(rulla) {
-                offset=0;
-                offset += sprintf(buf+offset,"Mac:");
-                for(j=0;j<ETH_ALEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->mac_addr[j]&0xff);
-                }
-                offset +=sprintf(buf+offset,"Atm:");
-                for(j=0;j<ATM_ESA_LEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->atm_addr[j]&0xff);
-                }      
-                offset+=sprintf(buf+offset,
-                                "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-                                rulla->vcc?rulla->vcc->vpi:0, 
-                                rulla->vcc?rulla->vcc->vci:0, 
-                                rulla->recv_vcc?rulla->recv_vcc->vpi:0,
-                                rulla->recv_vcc?rulla->recv_vcc->vci:0,
-                                rulla->last_used, 
-                                rulla->timestamp, rulla->no_tries);
-                offset+=sprintf(buf+offset,
-                                "Flags:%x, Packets_flooded:%x, Status: %s ",
-                                rulla->flags, rulla->packets_flooded, 
-                                get_status_string(rulla->status));
-                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
-                rulla = rulla->next;
-                printk("%s",buf);
-        }
-
-        rulla = mcast_fwds;
-        if (rulla)
-                printk("Multicast Forward VCCs\n");  
-        while(rulla) {
-                offset=0;
-                offset += sprintf(buf+offset,"Mac:");
-                for(j=0;j<ETH_ALEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->mac_addr[j]&0xff);
-                }
-                offset +=sprintf(buf+offset,"Atm:");
-                for(j=0;j<ATM_ESA_LEN;j++) {
-                        offset+=sprintf(buf+offset,"%2.2x ",
-                                        rulla->atm_addr[j]&0xff);
-                }      
-                offset+=sprintf(buf+offset,
-                                "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
-                                rulla->vcc?rulla->vcc->vpi:0, 
-                                rulla->vcc?rulla->vcc->vci:0, 
-                                rulla->recv_vcc?rulla->recv_vcc->vpi:0,
-                                rulla->recv_vcc?rulla->recv_vcc->vci:0,
-                                rulla->last_used, 
-                                rulla->timestamp, rulla->no_tries);
-                offset+=sprintf(buf+offset,
-                                "Flags:%x, Packets_flooded:%x, Status: %s ",
-                                rulla->flags, rulla->packets_flooded, 
-                                get_status_string(rulla->status));
-                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);
-                rulla = rulla->next;
-                printk("%s",buf);
-        }
+       struct hlist_node *node;
+       struct lec_arp_table *rulla;
+       char buf[256];
+       int i, j, offset;
+
+       printk("Dump %p:\n", priv);
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) {
+                       offset = 0;
+                       offset += sprintf(buf, "%d: %p\n", i, rulla);
+                       offset += sprintf(buf + offset, "Mac:");
+                       for (j = 0; j < ETH_ALEN; j++) {
+                               offset += sprintf(buf + offset,
+                                                 "%2.2x ",
+                                                 rulla->mac_addr[j] & 0xff);
+                       }
+                       offset += sprintf(buf + offset, "Atm:");
+                       for (j = 0; j < ATM_ESA_LEN; j++) {
+                               offset += sprintf(buf + offset,
+                                                 "%2.2x ",
+                                                 rulla->atm_addr[j] & 0xff);
+                       }
+                       offset += sprintf(buf + offset,
+                                         "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+                                         rulla->vcc ? rulla->vcc->vpi : 0,
+                                         rulla->vcc ? rulla->vcc->vci : 0,
+                                         rulla->recv_vcc ? rulla->recv_vcc->
+                                         vpi : 0,
+                                         rulla->recv_vcc ? rulla->recv_vcc->
+                                         vci : 0, rulla->last_used,
+                                         rulla->timestamp, rulla->no_tries);
+                       offset +=
+                           sprintf(buf + offset,
+                                   "Flags:%x, Packets_flooded:%x, Status: %s ",
+                                   rulla->flags, rulla->packets_flooded,
+                                   get_status_string(rulla->status));
+                       printk("%s\n", buf);
+               }
+       }
+
+       if (!hlist_empty(&priv->lec_no_forward))
+               printk("No forward\n");
+       hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) {
+               offset = 0;
+               offset += sprintf(buf + offset, "Mac:");
+               for (j = 0; j < ETH_ALEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->mac_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset, "Atm:");
+               for (j = 0; j < ATM_ESA_LEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->atm_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset,
+                                 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+                                 rulla->vcc ? rulla->vcc->vpi : 0,
+                                 rulla->vcc ? rulla->vcc->vci : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+                                 rulla->last_used,
+                                 rulla->timestamp, rulla->no_tries);
+               offset += sprintf(buf + offset,
+                                 "Flags:%x, Packets_flooded:%x, Status: %s ",
+                                 rulla->flags, rulla->packets_flooded,
+                                 get_status_string(rulla->status));
+               printk("%s\n", buf);
+       }
+
+       if (!hlist_empty(&priv->lec_arp_empty_ones))
+               printk("Empty ones\n");
+       hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) {
+               offset = 0;
+               offset += sprintf(buf + offset, "Mac:");
+               for (j = 0; j < ETH_ALEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->mac_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset, "Atm:");
+               for (j = 0; j < ATM_ESA_LEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->atm_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset,
+                                 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+                                 rulla->vcc ? rulla->vcc->vpi : 0,
+                                 rulla->vcc ? rulla->vcc->vci : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+                                 rulla->last_used,
+                                 rulla->timestamp, rulla->no_tries);
+               offset += sprintf(buf + offset,
+                                 "Flags:%x, Packets_flooded:%x, Status: %s ",
+                                 rulla->flags, rulla->packets_flooded,
+                                 get_status_string(rulla->status));
+               printk("%s", buf);
+       }
+
+       if (!hlist_empty(&priv->mcast_fwds))
+               printk("Multicast Forward VCCs\n");
+       hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) {
+               offset = 0;
+               offset += sprintf(buf + offset, "Mac:");
+               for (j = 0; j < ETH_ALEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->mac_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset, "Atm:");
+               for (j = 0; j < ATM_ESA_LEN; j++) {
+                       offset += sprintf(buf + offset, "%2.2x ",
+                                         rulla->atm_addr[j] & 0xff);
+               }
+               offset += sprintf(buf + offset,
+                                 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
+                                 rulla->vcc ? rulla->vcc->vpi : 0,
+                                 rulla->vcc ? rulla->vcc->vci : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
+                                 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
+                                 rulla->last_used,
+                                 rulla->timestamp, rulla->no_tries);
+               offset += sprintf(buf + offset,
+                                 "Flags:%x, Packets_flooded:%x, Status: %s ",
+                                 rulla->flags, rulla->packets_flooded,
+                                 get_status_string(rulla->status));
+               printk("%s\n", buf);
+       }
 
-#endif
 }
+#else
+#define dump_arp_table(priv) do { } while (0)
+#endif
 
 /*
  * Destruction of arp-cache
  */
-static void
-lec_arp_destroy(struct lec_priv *priv)
+static void lec_arp_destroy(struct lec_priv *priv)
 {
        unsigned long flags;
-        struct lec_arp_table *entry, *next;
-        int i;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry;
+       int i;
+
+       cancel_rearming_delayed_work(&priv->lec_arp_work);
 
-        del_timer_sync(&priv->lec_arp_timer);
-        
-        /*
-         * Remove all entries
-         */
+       /*
+        * Remove all entries
+        */
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) {
-                        next = entry->next;
-                        lec_arp_remove(priv, entry);
-                        kfree(entry);
-                }
-        }
-        entry = priv->lec_arp_empty_ones;
-        while(entry) {
-                next = entry->next;
-                del_timer_sync(&entry->timer);
-                lec_arp_clear_vccs(entry);
-                kfree(entry);
-                entry = next;
-        }
-        priv->lec_arp_empty_ones = NULL;
-        entry = priv->lec_no_forward;
-        while(entry) {
-                next = entry->next;
-                del_timer_sync(&entry->timer);
-                lec_arp_clear_vccs(entry);
-                kfree(entry);
-                entry = next;
-        }
-        priv->lec_no_forward = NULL;
-        entry = priv->mcast_fwds;
-        while(entry) {
-                next = entry->next;
-                /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
-                lec_arp_clear_vccs(entry);
-                kfree(entry);
-                entry = next;
-        }
-        priv->mcast_fwds = NULL;
-        priv->mcast_vcc = NULL;
-        memset(priv->lec_arp_tables, 0, 
-               sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+                       lec_arp_remove(priv, entry);
+                       lec_arp_put(entry);
+               }
+               INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
+       }
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+               del_timer_sync(&entry->timer);
+               lec_arp_clear_vccs(entry);
+               hlist_del(&entry->next);
+               lec_arp_put(entry);
+       }
+       INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
+               del_timer_sync(&entry->timer);
+               lec_arp_clear_vccs(entry);
+               hlist_del(&entry->next);
+               lec_arp_put(entry);
+       }
+       INIT_HLIST_HEAD(&priv->lec_no_forward);
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
+               /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
+               lec_arp_clear_vccs(entry);
+               hlist_del(&entry->next);
+               lec_arp_put(entry);
+       }
+       INIT_HLIST_HEAD(&priv->mcast_fwds);
+       priv->mcast_vcc = NULL;
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
-
 /* 
  * Find entry by mac_address
  */
-static struct lec_arp_table*
-lec_arp_find(struct lec_priv *priv,
-             unsigned char *mac_addr)
+static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
+                                         unsigned char *mac_addr)
 {
-        unsigned short place;
-        struct lec_arp_table *to_return;
-
-        DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
-                mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff, 
-                mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
-        place = HASH(mac_addr[ETH_ALEN-1]);
-  
-        to_return = priv->lec_arp_tables[place];
-        while(to_return) {
-                if (!compare_ether_addr(mac_addr, to_return->mac_addr)) {
-                        return to_return;
-                }
-                to_return = to_return->next;
-        }
-        return NULL;
+       struct hlist_node *node;
+       struct hlist_head *head;
+       struct lec_arp_table *entry;
+
+       DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+               mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff,
+               mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff);
+
+       head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
+       hlist_for_each_entry(entry, node, head, next) {
+               if (!compare_ether_addr(mac_addr, entry->mac_addr)) {
+                       return entry;
+               }
+       }
+       return NULL;
 }
 
-static struct lec_arp_table*
-make_entry(struct lec_priv *priv, unsigned char *mac_addr)
+static struct lec_arp_table *make_entry(struct lec_priv *priv,
+                                       unsigned char *mac_addr)
 {
-        struct lec_arp_table *to_return;
-
-        to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
-        if (!to_return) {
-                printk("LEC: Arp entry kmalloc failed\n");
-                return NULL;
-        }
-        memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
-        init_timer(&to_return->timer);
-        to_return->timer.function = lec_arp_expire_arp;
-        to_return->timer.data = (unsigned long) to_return;
-        to_return->last_used = jiffies;
-        to_return->priv = priv;
-        skb_queue_head_init(&to_return->tx_wait);
-        return to_return;
+       struct lec_arp_table *to_return;
+
+       to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
+       if (!to_return) {
+               printk("LEC: Arp entry kmalloc failed\n");
+               return NULL;
+       }
+       memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
+       INIT_HLIST_NODE(&to_return->next);
+       init_timer(&to_return->timer);
+       to_return->timer.function = lec_arp_expire_arp;
+       to_return->timer.data = (unsigned long)to_return;
+       to_return->last_used = jiffies;
+       to_return->priv = priv;
+       skb_queue_head_init(&to_return->tx_wait);
+       atomic_set(&to_return->usage, 1);
+       return to_return;
 }
 
-/*
- *
- * Arp sent timer expired
- *
- */
-static void
-lec_arp_expire_arp(unsigned long data)
+/* Arp sent timer expired */
+static void lec_arp_expire_arp(unsigned long data)
 {
-        struct lec_arp_table *entry;
-
-        entry = (struct lec_arp_table *)data;
-
-        DPRINTK("lec_arp_expire_arp\n");
-        if (entry->status == ESI_ARP_PENDING) {
-                if (entry->no_tries <= entry->priv->max_retry_count) {
-                        if (entry->is_rdesc)
-                                send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL);
-                        else
-                                send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL);
-                        entry->no_tries++;
-                }
-                mod_timer(&entry->timer, jiffies + (1*HZ));
-        }
+       struct lec_arp_table *entry;
+
+       entry = (struct lec_arp_table *)data;
+
+       DPRINTK("lec_arp_expire_arp\n");
+       if (entry->status == ESI_ARP_PENDING) {
+               if (entry->no_tries <= entry->priv->max_retry_count) {
+                       if (entry->is_rdesc)
+                               send_to_lecd(entry->priv, l_rdesc_arp_xmt,
+                                            entry->mac_addr, NULL, NULL);
+                       else
+                               send_to_lecd(entry->priv, l_arp_xmt,
+                                            entry->mac_addr, NULL, NULL);
+                       entry->no_tries++;
+               }
+               mod_timer(&entry->timer, jiffies + (1 * HZ));
+       }
 }
 
-/*
- *
- * Unknown/unused vcc expire, remove associated entry
- *
- */
-static void
-lec_arp_expire_vcc(unsigned long data)
+/* Unknown/unused vcc expire, remove associated entry */
+static void lec_arp_expire_vcc(unsigned long data)
 {
        unsigned long flags;
-        struct lec_arp_table *to_remove = (struct lec_arp_table*)data;
-        struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
-        struct lec_arp_table *entry = NULL;
+       struct lec_arp_table *to_remove = (struct lec_arp_table *)data;
+       struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
 
-        del_timer(&to_remove->timer);
+       del_timer(&to_remove->timer);
 
-        DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
-                to_remove, priv, 
-                to_remove->vcc?to_remove->recv_vcc->vpi:0,
-                to_remove->vcc?to_remove->recv_vcc->vci:0);
-        DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);
+       DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
+               to_remove, priv,
+               to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
+               to_remove->vcc ? to_remove->recv_vcc->vci : 0);
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        if (to_remove == priv->lec_arp_empty_ones)
-                priv->lec_arp_empty_ones = to_remove->next;
-        else {
-                entry = priv->lec_arp_empty_ones;
-                while (entry && entry->next != to_remove)
-                        entry = entry->next;
-                if (entry)
-                        entry->next = to_remove->next;
-        }
-        if (!entry) {
-                if (to_remove == priv->lec_no_forward) {
-                        priv->lec_no_forward = to_remove->next;
-                } else {
-                        entry = priv->lec_no_forward;
-                        while (entry && entry->next != to_remove)
-                                entry = entry->next;
-                        if (entry)
-                                entry->next = to_remove->next;
-                }
-       }
+       hlist_del(&to_remove->next);
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
-        lec_arp_clear_vccs(to_remove);
-        kfree(to_remove);
+       lec_arp_clear_vccs(to_remove);
+       lec_arp_put(to_remove);
 }
 
 /*
@@ -1915,158 +1879,171 @@ lec_arp_expire_vcc(unsigned long data)
  *       to ESI_FORWARD_DIRECT. This causes the flush period to end
  *       regardless of the progress of the flush protocol.
  */
-static void
-lec_arp_check_expire(unsigned long data)
+static void lec_arp_check_expire(void *data)
 {
        unsigned long flags;
-        struct lec_priv *priv = (struct lec_priv *)data;
-        struct lec_arp_table *entry, *next;
-        unsigned long now;
-        unsigned long time_to_check;
-        int i;
-
-        DPRINTK("lec_arp_check_expire %p\n",priv);
-        DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
-                priv->lec_no_forward);
+       struct lec_priv *priv = data;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry;
+       unsigned long now;
+       unsigned long time_to_check;
+       int i;
+
+       DPRINTK("lec_arp_check_expire %p\n", priv);
        now = jiffies;
+restart:
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-       for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-               for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {
-                       if ((entry->flags) & LEC_REMOTE_FLAG && 
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+                       if ((entry->flags) & LEC_REMOTE_FLAG &&
                            priv->topology_change)
                                time_to_check = priv->forward_delay_time;
                        else
                                time_to_check = priv->aging_time;
 
                        DPRINTK("About to expire: %lx - %lx > %lx\n",
-                               now,entry->last_used, time_to_check);
-                       if( time_after(now, entry->last_used+
-                          time_to_check) && 
-                           !(entry->flags & LEC_PERMANENT_FLAG) &&
-                           !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
+                               now, entry->last_used, time_to_check);
+                       if (time_after(now, entry->last_used + time_to_check)
+                           && !(entry->flags & LEC_PERMANENT_FLAG)
+                           && !(entry->mac_addr[0] & 0x01)) {  /* LANE2: 7.1.20 */
                                /* Remove entry */
                                DPRINTK("LEC:Entry timed out\n");
-                               next = entry->next;      
                                lec_arp_remove(priv, entry);
-                               kfree(entry);
-                               entry = next;
+                               lec_arp_put(entry);
                        } else {
                                /* Something else */
                                if ((entry->status == ESI_VC_PENDING ||
-                                    entry->status == ESI_ARP_PENDING) 
+                                    entry->status == ESI_ARP_PENDING)
                                    && time_after_eq(now,
-                                   entry->timestamp +
-                                   priv->max_unknown_frame_time)) {
+                                                    entry->timestamp +
+                                                    priv->
+                                                    max_unknown_frame_time)) {
                                        entry->timestamp = jiffies;
                                        entry->packets_flooded = 0;
                                        if (entry->status == ESI_VC_PENDING)
-                                               send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
+                                               send_to_lecd(priv, l_svc_setup,
+                                                            entry->mac_addr,
+                                                            entry->atm_addr,
+                                                            NULL);
                                }
-                               if (entry->status == ESI_FLUSH_PENDING 
-                                  &&
-                                  time_after_eq(now, entry->timestamp+
-                                  priv->path_switching_delay)) {
+                               if (entry->status == ESI_FLUSH_PENDING
+                                   &&
+                                   time_after_eq(now, entry->timestamp +
+                                                 priv->path_switching_delay)) {
                                        struct sk_buff *skb;
+                                       struct atm_vcc *vcc = entry->vcc;
 
+                                       lec_arp_hold(entry);
+                                       spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                                        while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
-                                               lec_send(entry->vcc, skb, entry->priv);
+                                               lec_send(vcc, skb, entry->priv);
                                        entry->last_used = jiffies;
-                                       entry->status = 
-                                               ESI_FORWARD_DIRECT;
+                                       entry->status = ESI_FORWARD_DIRECT;
+                                       lec_arp_put(entry);
+                                       goto restart;
                                }
-                               entry = entry->next;
                        }
                }
        }
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
-        mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL);
+       schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
 }
+
 /*
  * Try to find vcc where mac_address is attached.
  * 
  */
-static struct atm_vcc*
-lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find,
-               int is_rdesc, struct lec_arp_table **ret_entry)
+static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
+                                      unsigned char *mac_to_find, int is_rdesc,
+                                      struct lec_arp_table **ret_entry)
 {
        unsigned long flags;
-        struct lec_arp_table *entry;
+       struct lec_arp_table *entry;
        struct atm_vcc *found;
 
-        if (mac_to_find[0] & 0x01) {
-                switch (priv->lane_version) {
-                case 1:
-                        return priv->mcast_vcc;
-                        break;
-                case 2:  /* LANE2 wants arp for multicast addresses */
-                        if (!compare_ether_addr(mac_to_find, bus_mac))
-                                return priv->mcast_vcc;
-                        break;
-                default:
-                        break;
-                }
-        }
+       if (mac_to_find[0] & 0x01) {
+               switch (priv->lane_version) {
+               case 1:
+                       return priv->mcast_vcc;
+                       break;
+               case 2: /* LANE2 wants arp for multicast addresses */
+                       if (!compare_ether_addr(mac_to_find, bus_mac))
+                               return priv->mcast_vcc;
+                       break;
+               default:
+                       break;
+               }
+       }
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        entry = lec_arp_find(priv, mac_to_find);
-  
-        if (entry) {
-                if (entry->status == ESI_FORWARD_DIRECT) {
-                        /* Connection Ok */
-                        entry->last_used = jiffies;
-                        *ret_entry = entry;
-                        found = entry->vcc;
+       entry = lec_arp_find(priv, mac_to_find);
+
+       if (entry) {
+               if (entry->status == ESI_FORWARD_DIRECT) {
+                       /* Connection Ok */
+                       entry->last_used = jiffies;
+                       lec_arp_hold(entry);
+                       *ret_entry = entry;
+                       found = entry->vcc;
                        goto out;
-                }
-               /* If the LE_ARP cache entry is still pending, reset count to 0
+               }
+               /*
+                * If the LE_ARP cache entry is still pending, reset count to 0
                 * so another LE_ARP request can be made for this frame.
                 */
                if (entry->status == ESI_ARP_PENDING) {
                        entry->no_tries = 0;
                }
-                /* Data direct VC not yet set up, check to see if the unknown
-                   frame count is greater than the limit. If the limit has
-                   not been reached, allow the caller to send packet to
-                   BUS. */
-                if (entry->status != ESI_FLUSH_PENDING &&
-                    entry->packets_flooded<priv->maximum_unknown_frame_count) {
-                        entry->packets_flooded++;
-                        DPRINTK("LEC_ARP: Flooding..\n");
-                        found = priv->mcast_vcc;
+               /*
+                * Data direct VC not yet set up, check to see if the unknown
+                * frame count is greater than the limit. If the limit has
+                * not been reached, allow the caller to send packet to
+                * BUS.
+                */
+               if (entry->status != ESI_FLUSH_PENDING &&
+                   entry->packets_flooded <
+                   priv->maximum_unknown_frame_count) {
+                       entry->packets_flooded++;
+                       DPRINTK("LEC_ARP: Flooding..\n");
+                       found = priv->mcast_vcc;
                        goto out;
-                }
-               /* We got here because entry->status == ESI_FLUSH_PENDING
+               }
+               /*
+                * We got here because entry->status == ESI_FLUSH_PENDING
                 * or BUS flood limit was reached for an entry which is
                 * in ESI_ARP_PENDING or ESI_VC_PENDING state.
                 */
-                *ret_entry = entry;
-                DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc);
-                found = NULL;
-        } else {
-                /* No matching entry was found */
-                entry = make_entry(priv, mac_to_find);
-                DPRINTK("LEC_ARP: Making entry\n");
-                if (!entry) {
-                        found = priv->mcast_vcc;
+               lec_arp_hold(entry);
+               *ret_entry = entry;
+               DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status,
+                       entry->vcc);
+               found = NULL;
+       } else {
+               /* No matching entry was found */
+               entry = make_entry(priv, mac_to_find);
+               DPRINTK("LEC_ARP: Making entry\n");
+               if (!entry) {
+                       found = priv->mcast_vcc;
                        goto out;
-                }
-                lec_arp_add(priv, entry);
-                /* We want arp-request(s) to be sent */
-                entry->packets_flooded =1;
-                entry->status = ESI_ARP_PENDING;
-                entry->no_tries = 1;
-                entry->last_used = entry->timestamp = jiffies;
-                entry->is_rdesc = is_rdesc;
-                if (entry->is_rdesc)
-                        send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL);
-                else
-                        send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
-                entry->timer.expires = jiffies + (1*HZ);
-                entry->timer.function = lec_arp_expire_arp;
-                add_timer(&entry->timer);
-                found = priv->mcast_vcc;
-        }
+               }
+               lec_arp_add(priv, entry);
+               /* We want arp-request(s) to be sent */
+               entry->packets_flooded = 1;
+               entry->status = ESI_ARP_PENDING;
+               entry->no_tries = 1;
+               entry->last_used = entry->timestamp = jiffies;
+               entry->is_rdesc = is_rdesc;
+               if (entry->is_rdesc)
+                       send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL,
+                                    NULL);
+               else
+                       send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
+               entry->timer.expires = jiffies + (1 * HZ);
+               entry->timer.function = lec_arp_expire_arp;
+               add_timer(&entry->timer);
+               found = priv->mcast_vcc;
+       }
 
 out:
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
@@ -2074,30 +2051,30 @@ out:
 }
 
 static int
-lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, 
-                unsigned long permanent)
+lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
+               unsigned long permanent)
 {
        unsigned long flags;
-        struct lec_arp_table *entry, *next;
-        int i;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry;
+       int i;
 
-        DPRINTK("lec_addr_delete\n");
+       DPRINTK("lec_addr_delete\n");
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) {
-                        next = entry->next;
-                        if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
-                            && (permanent || 
-                                !(entry->flags & LEC_PERMANENT_FLAG))) {
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+                       if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
+                           && (permanent ||
+                               !(entry->flags & LEC_PERMANENT_FLAG))) {
                                lec_arp_remove(priv, entry);
-                                kfree(entry);
-                        }
+                               lec_arp_put(entry);
+                       }
                        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-                        return 0;
-                }
-        }
+                       return 0;
+               }
+       }
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-        return -1;
+       return -1;
 }
 
 /*
@@ -2105,109 +2082,98 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
  */
 static void
 lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
-               unsigned char *atm_addr, unsigned long remoteflag,
-               unsigned int targetless_le_arp)
+              unsigned char *atm_addr, unsigned long remoteflag,
+              unsigned int targetless_le_arp)
 {
        unsigned long flags;
-        struct lec_arp_table *entry, *tmp;
-        int i;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry, *tmp;
+       int i;
 
-        DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " ");
-        DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
-                mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],
-                mac_addr[4],mac_addr[5]);
+       DPRINTK("lec:%s", (targetless_le_arp) ? "targetless " : " ");
+       DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+               mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
+               mac_addr[4], mac_addr[5]);
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        entry = lec_arp_find(priv, mac_addr);
-        if (entry == NULL && targetless_le_arp)
-                goto out;   /* LANE2: ignore targetless LE_ARPs for which
-                             * we have no entry in the cache. 7.1.30
-                             */
-        if (priv->lec_arp_empty_ones) {
-                entry = priv->lec_arp_empty_ones;
-                if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
-                        priv->lec_arp_empty_ones = entry->next;
-                } else {
-                        while(entry->next && memcmp(entry->next->atm_addr, 
-                                                    atm_addr, ATM_ESA_LEN))
-                                entry = entry->next;
-                        if (entry->next) {
-                                tmp = entry;
-                                entry = entry->next;
-                                tmp->next = entry->next;
-                        } else
-                                entry = NULL;
-                        
-                }
-                if (entry) {
-                        del_timer(&entry->timer);
-                        tmp = lec_arp_find(priv, mac_addr);
-                        if (tmp) {
-                                del_timer(&tmp->timer);
-                                tmp->status = ESI_FORWARD_DIRECT;
-                                memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
-                                tmp->vcc = entry->vcc;
-                                tmp->old_push = entry->old_push;
-                                tmp->last_used = jiffies;
-                                del_timer(&entry->timer);
-                                kfree(entry);
-                                entry=tmp;
-                        } else {
-                                entry->status = ESI_FORWARD_DIRECT;
-                                memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
-                                entry->last_used = jiffies;
-                                lec_arp_add(priv, entry);
-                        }
-                        if (remoteflag)
-                                entry->flags|=LEC_REMOTE_FLAG;
-                        else
-                                entry->flags&=~LEC_REMOTE_FLAG;
-                        DPRINTK("After update\n");
-                        dump_arp_table(priv);
-                        goto out;
-                }
-        }
-        entry = lec_arp_find(priv, mac_addr);
-        if (!entry) {
-                entry = make_entry(priv, mac_addr);
-                if (!entry)
+       entry = lec_arp_find(priv, mac_addr);
+       if (entry == NULL && targetless_le_arp)
+               goto out;       /*
+                                * LANE2: ignore targetless LE_ARPs for which
+                                * we have no entry in the cache. 7.1.30
+                                */
+       if (!hlist_empty(&priv->lec_arp_empty_ones)) {
+               hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+                       if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
+                               hlist_del(&entry->next);
+                               del_timer(&entry->timer);
+                               tmp = lec_arp_find(priv, mac_addr);
+                               if (tmp) {
+                                       del_timer(&tmp->timer);
+                                       tmp->status = ESI_FORWARD_DIRECT;
+                                       memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
+                                       tmp->vcc = entry->vcc;
+                                       tmp->old_push = entry->old_push;
+                                       tmp->last_used = jiffies;
+                                       del_timer(&entry->timer);
+                                       lec_arp_put(entry);
+                                       entry = tmp;
+                               } else {
+                                       entry->status = ESI_FORWARD_DIRECT;
+                                       memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
+                                       entry->last_used = jiffies;
+                                       lec_arp_add(priv, entry);
+                               }
+                               if (remoteflag)
+                                       entry->flags |= LEC_REMOTE_FLAG;
+                               else
+                                       entry->flags &= ~LEC_REMOTE_FLAG;
+                               DPRINTK("After update\n");
+                               dump_arp_table(priv);
+                               goto out;
+                       }
+               }
+       }
+
+       entry = lec_arp_find(priv, mac_addr);
+       if (!entry) {
+               entry = make_entry(priv, mac_addr);
+               if (!entry)
                        goto out;
-                entry->status = ESI_UNKNOWN;
-                lec_arp_add(priv, entry);
-                /* Temporary, changes before end of function */
-        }
-        memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
-        del_timer(&entry->timer);
-        for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) {
-                        if (entry != tmp &&
-                            !memcmp(tmp->atm_addr, atm_addr,
-                                    ATM_ESA_LEN)) { 
-                                /* Vcc to this host exists */
-                                if (tmp->status > ESI_VC_PENDING) {
-                                        /*
-                                         * ESI_FLUSH_PENDING,
-                                         * ESI_FORWARD_DIRECT
-                                         */
-                                        entry->vcc = tmp->vcc;
-                                        entry->old_push=tmp->old_push;
-                                }
-                                entry->status=tmp->status;
-                                break;
-                        }
-                }
-        }
-        if (remoteflag)
-                entry->flags|=LEC_REMOTE_FLAG;
-        else
-                entry->flags&=~LEC_REMOTE_FLAG;
-        if (entry->status == ESI_ARP_PENDING ||
-            entry->status == ESI_UNKNOWN) {
-                entry->status = ESI_VC_PENDING;
-                send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
-        }
-        DPRINTK("After update2\n");
-        dump_arp_table(priv);
+               entry->status = ESI_UNKNOWN;
+               lec_arp_add(priv, entry);
+               /* Temporary, changes before end of function */
+       }
+       memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
+       del_timer(&entry->timer);
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) {
+                       if (entry != tmp &&
+                           !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
+                               /* Vcc to this host exists */
+                               if (tmp->status > ESI_VC_PENDING) {
+                                       /*
+                                        * ESI_FLUSH_PENDING,
+                                        * ESI_FORWARD_DIRECT
+                                        */
+                                       entry->vcc = tmp->vcc;
+                                       entry->old_push = tmp->old_push;
+                               }
+                               entry->status = tmp->status;
+                               break;
+                       }
+               }
+       }
+       if (remoteflag)
+               entry->flags |= LEC_REMOTE_FLAG;
+       else
+               entry->flags &= ~LEC_REMOTE_FLAG;
+       if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
+               entry->status = ESI_VC_PENDING;
+               send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
+       }
+       DPRINTK("After update2\n");
+       dump_arp_table(priv);
 out:
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
@@ -2217,299 +2183,299 @@ out:
  */
 static void
 lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
-              struct atm_vcc *vcc,
-              void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb))
+             struct atm_vcc *vcc,
+             void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
 {
        unsigned long flags;
-        struct lec_arp_table *entry;
-        int i, found_entry=0;
+       struct hlist_node *node;
+       struct lec_arp_table *entry;
+       int i, found_entry = 0;
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        if (ioc_data->receive == 2) {
-                /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
+       if (ioc_data->receive == 2) {
+               /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
 
-                DPRINTK("LEC_ARP: Attaching mcast forward\n");
+               DPRINTK("LEC_ARP: Attaching mcast forward\n");
 #if 0
-                entry = lec_arp_find(priv, bus_mac);
-                if (!entry) {
-                        printk("LEC_ARP: Multicast entry not found!\n");
+               entry = lec_arp_find(priv, bus_mac);
+               if (!entry) {
+                       printk("LEC_ARP: Multicast entry not found!\n");
                        goto out;
-                }
-                memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-                entry->recv_vcc = vcc;
-                entry->old_recv_push = old_push;
+               }
+               memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+               entry->recv_vcc = vcc;
+               entry->old_recv_push = old_push;
 #endif
-                entry = make_entry(priv, bus_mac);
-                if (entry == NULL)
+               entry = make_entry(priv, bus_mac);
+               if (entry == NULL)
                        goto out;
-                del_timer(&entry->timer);
-                memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-                entry->recv_vcc = vcc;
-                entry->old_recv_push = old_push;
-                entry->next = priv->mcast_fwds;
-                priv->mcast_fwds = entry;
-                goto out;
-        } else if (ioc_data->receive == 1) {
-                /* Vcc which we don't want to make default vcc, attach it
-                   anyway. */
-                DPRINTK("LEC_ARP:Attaching data direct, not default :%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
-                        ioc_data->atm_addr[0],ioc_data->atm_addr[1],
-                        ioc_data->atm_addr[2],ioc_data->atm_addr[3],
-                        ioc_data->atm_addr[4],ioc_data->atm_addr[5],
-                        ioc_data->atm_addr[6],ioc_data->atm_addr[7],
-                        ioc_data->atm_addr[8],ioc_data->atm_addr[9],
-                        ioc_data->atm_addr[10],ioc_data->atm_addr[11],
-                        ioc_data->atm_addr[12],ioc_data->atm_addr[13],
-                        ioc_data->atm_addr[14],ioc_data->atm_addr[15],
-                        ioc_data->atm_addr[16],ioc_data->atm_addr[17],
-                        ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
-                entry = make_entry(priv, bus_mac);
-                if (entry == NULL)
+               del_timer(&entry->timer);
+               memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+               entry->recv_vcc = vcc;
+               entry->old_recv_push = old_push;
+               hlist_add_head(&entry->next, &priv->mcast_fwds);
+               goto out;
+       } else if (ioc_data->receive == 1) {
+               /*
+                * Vcc which we don't want to make default vcc,
+                * attach it anyway.
+                */
+               DPRINTK
+                   ("LEC_ARP:Attaching data direct, not default: "
+                    "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+                    ioc_data->atm_addr[0], ioc_data->atm_addr[1],
+                    ioc_data->atm_addr[2], ioc_data->atm_addr[3],
+                    ioc_data->atm_addr[4], ioc_data->atm_addr[5],
+                    ioc_data->atm_addr[6], ioc_data->atm_addr[7],
+                    ioc_data->atm_addr[8], ioc_data->atm_addr[9],
+                    ioc_data->atm_addr[10], ioc_data->atm_addr[11],
+                    ioc_data->atm_addr[12], ioc_data->atm_addr[13],
+                    ioc_data->atm_addr[14], ioc_data->atm_addr[15],
+                    ioc_data->atm_addr[16], ioc_data->atm_addr[17],
+                    ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
+               entry = make_entry(priv, bus_mac);
+               if (entry == NULL)
                        goto out;
-                memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-                memset(entry->mac_addr, 0, ETH_ALEN);
-                entry->recv_vcc = vcc;
-                entry->old_recv_push = old_push;
-                entry->status = ESI_UNKNOWN;
-                entry->timer.expires = jiffies + priv->vcc_timeout_period;
-                entry->timer.function = lec_arp_expire_vcc;
-                add_timer(&entry->timer);
-                entry->next = priv->lec_no_forward;
-                priv->lec_no_forward = entry;
+               memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+               memset(entry->mac_addr, 0, ETH_ALEN);
+               entry->recv_vcc = vcc;
+               entry->old_recv_push = old_push;
+               entry->status = ESI_UNKNOWN;
+               entry->timer.expires = jiffies + priv->vcc_timeout_period;
+               entry->timer.function = lec_arp_expire_vcc;
+               hlist_add_head(&entry->next, &priv->lec_no_forward);
+               add_timer(&entry->timer);
                dump_arp_table(priv);
                goto out;
-        }
-        DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
-                ioc_data->atm_addr[0],ioc_data->atm_addr[1],
-                ioc_data->atm_addr[2],ioc_data->atm_addr[3],
-                ioc_data->atm_addr[4],ioc_data->atm_addr[5],
-                ioc_data->atm_addr[6],ioc_data->atm_addr[7],
-                ioc_data->atm_addr[8],ioc_data->atm_addr[9],
-                ioc_data->atm_addr[10],ioc_data->atm_addr[11],
-                ioc_data->atm_addr[12],ioc_data->atm_addr[13],
-                ioc_data->atm_addr[14],ioc_data->atm_addr[15],
-                ioc_data->atm_addr[16],ioc_data->atm_addr[17],
-                ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
-        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
-                        if (memcmp(ioc_data->atm_addr, entry->atm_addr, 
-                                   ATM_ESA_LEN)==0) {
-                                DPRINTK("LEC_ARP: Attaching data direct\n");
-                                DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
-                                        entry->vcc?entry->vcc->vci:0,
-                                        entry->recv_vcc?entry->recv_vcc->vci:0);
-                                found_entry=1;
-                                del_timer(&entry->timer);
-                                entry->vcc = vcc;
-                                entry->old_push = old_push;
-                                if (entry->status == ESI_VC_PENDING) {
-                                        if(priv->maximum_unknown_frame_count
-                                           ==0)
-                                                entry->status = 
-                                                        ESI_FORWARD_DIRECT;
-                                        else {
-                                                entry->timestamp = jiffies;
-                                                entry->status = 
-                                                        ESI_FLUSH_PENDING;
+       }
+       DPRINTK
+           ("LEC_ARP:Attaching data direct, default: "
+            "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
+            ioc_data->atm_addr[0], ioc_data->atm_addr[1],
+            ioc_data->atm_addr[2], ioc_data->atm_addr[3],
+            ioc_data->atm_addr[4], ioc_data->atm_addr[5],
+            ioc_data->atm_addr[6], ioc_data->atm_addr[7],
+            ioc_data->atm_addr[8], ioc_data->atm_addr[9],
+            ioc_data->atm_addr[10], ioc_data->atm_addr[11],
+            ioc_data->atm_addr[12], ioc_data->atm_addr[13],
+            ioc_data->atm_addr[14], ioc_data->atm_addr[15],
+            ioc_data->atm_addr[16], ioc_data->atm_addr[17],
+            ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+                       if (memcmp
+                           (ioc_data->atm_addr, entry->atm_addr,
+                            ATM_ESA_LEN) == 0) {
+                               DPRINTK("LEC_ARP: Attaching data direct\n");
+                               DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n",
+                                       entry->vcc ? entry->vcc->vci : 0,
+                                       entry->recv_vcc ? entry->recv_vcc->
+                                       vci : 0);
+                               found_entry = 1;
+                               del_timer(&entry->timer);
+                               entry->vcc = vcc;
+                               entry->old_push = old_push;
+                               if (entry->status == ESI_VC_PENDING) {
+                                       if (priv->maximum_unknown_frame_count
+                                           == 0)
+                                               entry->status =
+                                                   ESI_FORWARD_DIRECT;
+                                       else {
+                                               entry->timestamp = jiffies;
+                                               entry->status =
+                                                   ESI_FLUSH_PENDING;
 #if 0
-                                                send_to_lecd(priv,l_flush_xmt,
-                                                             NULL,
-                                                             entry->atm_addr,
-                                                             NULL);
+                                               send_to_lecd(priv, l_flush_xmt,
+                                                            NULL,
+                                                            entry->atm_addr,
+                                                            NULL);
 #endif
-                                        }
-                                } else {
-                                        /* They were forming a connection
-                                           to us, and we to them. Our
-                                           ATM address is numerically lower
-                                           than theirs, so we make connection
-                                           we formed into default VCC (8.1.11).
-                                           Connection they made gets torn
-                                           down. This might confuse some
-                                           clients. Can be changed if
-                                           someone reports trouble... */
-                                        ;
-                                }
-                        }
-                }
-        }
-        if (found_entry) {
-                DPRINTK("After vcc was added\n");
-                dump_arp_table(priv);
+                                       }
+                               } else {
+                                       /*
+                                        * They were forming a connection
+                                        * to us, and we to them. Our
+                                        * ATM address is numerically lower
+                                        * than theirs, so we make connection
+                                        * we formed into default VCC (8.1.11).
+                                        * Connection they made gets torn
+                                        * down. This might confuse some
+                                        * clients. Can be changed if
+                                        * someone reports trouble...
+                                        */
+                                       ;
+                               }
+                       }
+               }
+       }
+       if (found_entry) {
+               DPRINTK("After vcc was added\n");
+               dump_arp_table(priv);
                goto out;
-        }
-        /* Not found, snatch address from first data packet that arrives from
-           this vcc */
-        entry = make_entry(priv, bus_mac);
-        if (!entry)
+       }
+       /*
+        * Not found, snatch address from first data packet that arrives
+        * from this vcc
+        */
+       entry = make_entry(priv, bus_mac);
+       if (!entry)
                goto out;
-        entry->vcc = vcc;
-        entry->old_push = old_push;
-        memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
-        memset(entry->mac_addr, 0, ETH_ALEN);
-        entry->status = ESI_UNKNOWN;
-        entry->next = priv->lec_arp_empty_ones;
-        priv->lec_arp_empty_ones = entry;
-        entry->timer.expires = jiffies + priv->vcc_timeout_period;
-        entry->timer.function = lec_arp_expire_vcc;
-        add_timer(&entry->timer);
-        DPRINTK("After vcc was added\n");
+       entry->vcc = vcc;
+       entry->old_push = old_push;
+       memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
+       memset(entry->mac_addr, 0, ETH_ALEN);
+       entry->status = ESI_UNKNOWN;
+       hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
+       entry->timer.expires = jiffies + priv->vcc_timeout_period;
+       entry->timer.function = lec_arp_expire_vcc;
+       add_timer(&entry->timer);
+       DPRINTK("After vcc was added\n");
        dump_arp_table(priv);
 out:
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
-static void
-lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
+static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
 {
        unsigned long flags;
-        struct lec_arp_table *entry;
-        int i;
-  
-        DPRINTK("LEC:lec_flush_complete %lx\n",tran_id);
+       struct hlist_node *node;
+       struct lec_arp_table *entry;
+       int i;
+
+       DPRINTK("LEC:lec_flush_complete %lx\n", tran_id);
+restart:
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
-                for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
-                        if (entry->flush_tran_id == tran_id &&
-                            entry->status == ESI_FLUSH_PENDING) {
-                               struct sk_buff *skb;
-
-                               while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
-                                       lec_send(entry->vcc, skb, entry->priv);
-                                entry->status = ESI_FORWARD_DIRECT;
-                                DPRINTK("LEC_ARP: Flushed\n");
-                        }
-                }
-        }
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+                       if (entry->flush_tran_id == tran_id
+                           && entry->status == ESI_FLUSH_PENDING) {
+                               struct sk_buff *skb;
+                               struct atm_vcc *vcc = entry->vcc;
+
+                               lec_arp_hold(entry);
+                               spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+                               while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
+                                       lec_send(vcc, skb, entry->priv);
+                               entry->last_used = jiffies;
+                               entry->status = ESI_FORWARD_DIRECT;
+                               lec_arp_put(entry);
+                               DPRINTK("LEC_ARP: Flushed\n");
+                               goto restart;
+                       }
+               }
+       }
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-        dump_arp_table(priv);
+       dump_arp_table(priv);
 }
 
 static void
 lec_set_flush_tran_id(struct lec_priv *priv,
-                      unsigned char *atm_addr, unsigned long tran_id)
+                     unsigned char *atm_addr, unsigned long tran_id)
 {
        unsigned long flags;
-        struct lec_arp_table *entry;
-        int i;
+       struct hlist_node *node;
+       struct lec_arp_table *entry;
+       int i;
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
-                for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next)
-                        if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
-                                entry->flush_tran_id = tran_id;
-                                DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry);
-                        }
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
+               hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
+                       if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
+                               entry->flush_tran_id = tran_id;
+                               DPRINTK("Set flush transaction id to %lx for %p\n",
+                                       tran_id, entry);
+                       }
+               }
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
-static int 
-lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
+static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
 {
        unsigned long flags;
-        unsigned char mac_addr[] = {
-                0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-        struct lec_arp_table *to_add;
+       unsigned char mac_addr[] = {
+               0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+       };
+       struct lec_arp_table *to_add;
        struct lec_vcc_priv *vpriv;
        int err = 0;
-  
+
        if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
                return -ENOMEM;
        vpriv->xoff = 0;
        vpriv->old_pop = vcc->pop;
        vcc->user_back = vpriv;
-        vcc->pop = lec_pop;
+       vcc->pop = lec_pop;
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        to_add = make_entry(priv, mac_addr);
-        if (!to_add) {
+       to_add = make_entry(priv, mac_addr);
+       if (!to_add) {
                vcc->pop = vpriv->old_pop;
                kfree(vpriv);
-                err = -ENOMEM;
+               err = -ENOMEM;
                goto out;
-        }
-        memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
-        to_add->status = ESI_FORWARD_DIRECT;
-        to_add->flags |= LEC_PERMANENT_FLAG;
-        to_add->vcc = vcc;
-        to_add->old_push = vcc->push;
-        vcc->push = lec_push;
-        priv->mcast_vcc = vcc;
-        lec_arp_add(priv, to_add);
+       }
+       memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
+       to_add->status = ESI_FORWARD_DIRECT;
+       to_add->flags |= LEC_PERMANENT_FLAG;
+       to_add->vcc = vcc;
+       to_add->old_push = vcc->push;
+       vcc->push = lec_push;
+       priv->mcast_vcc = vcc;
+       lec_arp_add(priv, to_add);
 out:
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-        return err;
+       return err;
 }
 
-static void
-lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
+static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
 {
        unsigned long flags;
-        struct lec_arp_table *entry, *next;
-        int i;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry;
+       int i;
+
+       DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
+       dump_arp_table(priv);
 
-        DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
-        dump_arp_table(priv);
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for(entry = priv->lec_arp_tables[i];entry; entry=next) {
-                        next = entry->next;
-                        if (vcc == entry->vcc) {
-                                lec_arp_remove(priv, entry);
-                                kfree(entry);
-                                if (priv->mcast_vcc == vcc) {
-                                        priv->mcast_vcc = NULL;
-                                }
-                        }
-                }
-        }
-
-        entry = priv->lec_arp_empty_ones;
-        priv->lec_arp_empty_ones = NULL;
-        while (entry != NULL) {
-                next = entry->next;
-                if (entry->vcc == vcc) { /* leave it out from the list */
-                        lec_arp_clear_vccs(entry);
-                        del_timer(&entry->timer);
-                        kfree(entry);
-                }
-                else {              /* put it back to the list */
-                        entry->next = priv->lec_arp_empty_ones;
-                        priv->lec_arp_empty_ones = entry;
-                }
-                entry = next;
-        }
-        
-        entry = priv->lec_no_forward;
-        priv->lec_no_forward = NULL;
-        while (entry != NULL) {
-                next = entry->next;
-                if (entry->recv_vcc == vcc) {
-                        lec_arp_clear_vccs(entry);
-                        del_timer(&entry->timer);
-                        kfree(entry);
-                }
-                else {
-                        entry->next = priv->lec_no_forward;
-                        priv->lec_no_forward = entry;
-                }
-                entry = next;
-        }
-
-        entry = priv->mcast_fwds;
-        priv->mcast_fwds = NULL;
-        while (entry != NULL) {
-                next = entry->next;
-                if (entry->recv_vcc == vcc) {
-                        lec_arp_clear_vccs(entry);
-                        /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
-                        kfree(entry);
-                }
-                else {
-                        entry->next = priv->mcast_fwds;
-                        priv->mcast_fwds = entry;
-                }
-                entry = next;
-        }
+
+       for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+               hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
+                       if (vcc == entry->vcc) {
+                               lec_arp_remove(priv, entry);
+                               lec_arp_put(entry);
+                               if (priv->mcast_vcc == vcc) {
+                                       priv->mcast_vcc = NULL;
+                               }
+                       }
+               }
+       }
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+               if (entry->vcc == vcc) {
+                       lec_arp_clear_vccs(entry);
+                       del_timer(&entry->timer);
+                       hlist_del(&entry->next);
+                       lec_arp_put(entry);
+               }
+       }
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
+               if (entry->recv_vcc == vcc) {
+                       lec_arp_clear_vccs(entry);
+                       del_timer(&entry->timer);
+                       hlist_del(&entry->next);
+                       lec_arp_put(entry);
+               }
+       }
+
+       hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
+               if (entry->recv_vcc == vcc) {
+                       lec_arp_clear_vccs(entry);
+                       /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
+                       hlist_del(&entry->next);
+                       lec_arp_put(entry);
+               }
+       }
 
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
        dump_arp_table(priv);
@@ -2517,57 +2483,42 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
 
 static void
 lec_arp_check_empties(struct lec_priv *priv,
-                      struct atm_vcc *vcc, struct sk_buff *skb)
+                     struct atm_vcc *vcc, struct sk_buff *skb)
 {
-        unsigned long flags;
-        struct lec_arp_table *entry, *prev;
-        struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
-        unsigned char *src;
+       unsigned long flags;
+       struct hlist_node *node, *next;
+       struct lec_arp_table *entry, *tmp;
+       struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
+       unsigned char *src;
 #ifdef CONFIG_TR
-        struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
+       struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
 
-        if (priv->is_trdev) src = tr_hdr->h_source;
-        else
+       if (priv->is_trdev)
+               src = tr_hdr->h_source;
+       else
 #endif
-        src = hdr->h_source;
+               src = hdr->h_source;
 
        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-        entry = priv->lec_arp_empty_ones;
-        if (vcc == entry->vcc) {
-                del_timer(&entry->timer);
-                memcpy(entry->mac_addr, src, ETH_ALEN);
-                entry->status = ESI_FORWARD_DIRECT;
-                entry->last_used = jiffies;
-                priv->lec_arp_empty_ones = entry->next;
-                /* We might have got an entry */
-                if ((prev = lec_arp_find(priv,src))) {
-                        lec_arp_remove(priv, prev);
-                        kfree(prev);
-                }
-                lec_arp_add(priv, entry);
-               goto out;
-        }
-        prev = entry;
-        entry = entry->next;
-        while (entry && entry->vcc != vcc) {
-                prev= entry;
-                entry = entry->next;
-        }
-        if (!entry) {
-                DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
-               goto out;
-        }
-        del_timer(&entry->timer);
-        memcpy(entry->mac_addr, src, ETH_ALEN);
-        entry->status = ESI_FORWARD_DIRECT;
-        entry->last_used = jiffies;
-        prev->next = entry->next;
-        if ((prev = lec_arp_find(priv, src))) {
-                lec_arp_remove(priv, prev);
-                kfree(prev);
-        }
-        lec_arp_add(priv, entry);
+       hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
+               if (vcc == entry->vcc) {
+                       del_timer(&entry->timer);
+                       memcpy(entry->mac_addr, src, ETH_ALEN);
+                       entry->status = ESI_FORWARD_DIRECT;
+                       entry->last_used = jiffies;
+                       /* We might have got an entry */
+                       if ((tmp = lec_arp_find(priv, src))) {
+                               lec_arp_remove(priv, tmp);
+                               lec_arp_put(tmp);
+                       }
+                       hlist_del(&entry->next);
+                       lec_arp_add(priv, entry);
+                       goto out;
+               }
+       }
+       DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
 out:
        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
+
 MODULE_LICENSE("GPL");
index c22a8bfa1f813bb0a61b9af087eb496a5daa91ae..8ac6b73216357aac3816c8e1165ed74ba19cee22 100644 (file)
@@ -1,14 +1,13 @@
 /*
- *
  * Lan Emulation client header file
  *
- * Marko Kiiskila mkiiskila@yahoo.com
- *
+ * Marko Kiiskila <mkiiskila@yahoo.com>
  */
 
 #ifndef _LEC_H_
 #define _LEC_H_
 
+#include <linux/config.h>
 #include <linux/atmdev.h>
 #include <linux/netdevice.h>
 #include <linux/atmlec.h>
 #define LEC_HEADER_LEN 16
 
 struct lecdatahdr_8023 {
-  unsigned short le_header;
-  unsigned char h_dest[ETH_ALEN];
-  unsigned char h_source[ETH_ALEN];
-  unsigned short h_type;
+       unsigned short le_header;
+       unsigned char h_dest[ETH_ALEN];
+       unsigned char h_source[ETH_ALEN];
+       unsigned short h_type;
 };
 
 struct lecdatahdr_8025 {
-  unsigned short le_header;
-  unsigned char ac_pad;
-  unsigned char fc;
-  unsigned char h_dest[ETH_ALEN];
-  unsigned char h_source[ETH_ALEN];
+       unsigned short le_header;
+       unsigned char ac_pad;
+       unsigned char fc;
+       unsigned char h_dest[ETH_ALEN];
+       unsigned char h_source[ETH_ALEN];
 };
 
 #define LEC_MINIMUM_8023_SIZE   62
@@ -44,17 +43,18 @@ struct lecdatahdr_8025 {
  *
  */
 struct lane2_ops {
-       int  (*resolve)(struct net_device *dev, u8 *dst_mac, int force,
-                        u8 **tlvs, u32 *sizeoftlvs);
-        int  (*associate_req)(struct net_device *dev, u8 *lan_dst,
-                              u8 *tlvs, u32 sizeoftlvs);
-       void (*associate_indicator)(struct net_device *dev, u8 *mac_addr,
-                                    u8 *tlvs, u32 sizeoftlvs);
+       int (*resolve) (struct net_device *dev, u8 *dst_mac, int force,
+                       u8 **tlvs, u32 *sizeoftlvs);
+       int (*associate_req) (struct net_device *dev, u8 *lan_dst,
+                             u8 *tlvs, u32 sizeoftlvs);
+       void (*associate_indicator) (struct net_device *dev, u8 *mac_addr,
+                                    u8 *tlvs, u32 sizeoftlvs);
 };
 
 /*
  * ATM LAN Emulation supports both LLC & Dix Ethernet EtherType
  * frames. 
+ *
  * 1. Dix Ethernet EtherType frames encoded by placing EtherType
  *    field in h_type field. Data follows immediatelly after header.
  * 2. LLC Data frames whose total length, including LLC field and data,
@@ -70,72 +70,88 @@ struct lane2_ops {
 #define LEC_ARP_TABLE_SIZE 16
 
 struct lec_priv {
-        struct net_device_stats stats;
-        unsigned short lecid;      /* Lecid of this client */
-        struct lec_arp_table *lec_arp_empty_ones;
-        /* Used for storing VCC's that don't have a MAC address attached yet */
-        struct lec_arp_table *lec_arp_tables[LEC_ARP_TABLE_SIZE];
-        /* Actual LE ARP table */
-        struct lec_arp_table *lec_no_forward;
-        /* Used for storing VCC's (and forward packets from) which are to
-           age out by not using them to forward packets. 
-           This is because to some LE clients there will be 2 VCCs. Only
-           one of them gets used. */
-        struct lec_arp_table *mcast_fwds;
-        /* With LANEv2 it is possible that BUS (or a special multicast server)
-           establishes multiple Multicast Forward VCCs to us. This list
-           collects all those VCCs. LANEv1 client has only one item in this
-           list. These entries are not aged out. */
-        spinlock_t lec_arp_lock;
-        struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
-        struct atm_vcc *lecd;
-        struct timer_list lec_arp_timer;
-        /* C10 */
-        unsigned int maximum_unknown_frame_count;
-/* Within the period of time defined by this variable, the client will send 
-   no more than C10 frames to BUS for a given unicast destination. (C11) */
-        unsigned long max_unknown_frame_time;
-/* If no traffic has been sent in this vcc for this period of time,
-   vcc will be torn down (C12)*/
-        unsigned long vcc_timeout_period;
-/* An LE Client MUST not retry an LE_ARP_REQUEST for a 
-   given frame's LAN Destination more than maximum retry count times,
-   after the first LEC_ARP_REQUEST (C13)*/
-        unsigned short max_retry_count;
-/* Max time the client will maintain an entry in its arp cache in
-   absence of a verification of that relationship (C17)*/
-        unsigned long aging_time;
-/* Max time the client will maintain an entry in cache when
-   topology change flag is true (C18) */
-        unsigned long forward_delay_time;
-/* Topology change flag  (C19)*/
-        int topology_change;
-/* Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
-   cycle to take (C20)*/
-        unsigned long arp_response_time;
-/* Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
-   LE_FLUSH_REQUEST has been sent before taking recover action. (C21)*/
-        unsigned long flush_timeout;
-/* The time since sending a frame to the bus after which the
-   LE Client may assume that the frame has been either discarded or
-   delivered to the recipient (C22) */
-        unsigned long path_switching_delay;
+       struct net_device_stats stats;
+       unsigned short lecid;                   /* Lecid of this client */
+       struct hlist_head lec_arp_empty_ones;
+                                               /* Used for storing VCC's that don't have a MAC address attached yet */
+       struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE];
+                                               /* Actual LE ARP table */
+       struct hlist_head lec_no_forward;
+                                               /*
+                                                * Used for storing VCC's (and forward packets from) which are to
+                                                * age out by not using them to forward packets.
+                                                * This is because to some LE clients there will be 2 VCCs. Only
+                                                * one of them gets used.
+                                                */
+       struct hlist_head mcast_fwds;
+                                               /*
+                                                * With LANEv2 it is possible that BUS (or a special multicast server)
+                                                * establishes multiple Multicast Forward VCCs to us. This list
+                                                * collects all those VCCs. LANEv1 client has only one item in this
+                                                * list. These entries are not aged out.
+                                                */
+       spinlock_t lec_arp_lock;
+       struct atm_vcc *mcast_vcc;              /* Default Multicast Send VCC */
+       struct atm_vcc *lecd;
+       struct work_struct lec_arp_work;        /* C10 */
+       unsigned int maximum_unknown_frame_count;
+                                               /*
+                                                * Within the period of time defined by this variable, the client will send
+                                                * no more than C10 frames to BUS for a given unicast destination. (C11)
+                                                */
+       unsigned long max_unknown_frame_time;
+                                               /*
+                                                * If no traffic has been sent in this vcc for this period of time,
+                                                * vcc will be torn down (C12)
+                                                */
+       unsigned long vcc_timeout_period;
+                                               /*
+                                                * An LE Client MUST not retry an LE_ARP_REQUEST for a
+                                                * given frame's LAN Destination more than maximum retry count times,
+                                                * after the first LEC_ARP_REQUEST (C13)
+                                                */
+       unsigned short max_retry_count;
+                                               /*
+                                                * Max time the client will maintain an entry in its arp cache in
+                                                * absence of a verification of that relationship (C17)
+                                                */
+       unsigned long aging_time;
+                                               /*
+                                                * Max time the client will maintain an entry in cache when
+                                                * topology change flag is true (C18)
+                                                */
+       unsigned long forward_delay_time;       /* Topology change flag (C19) */
+       int topology_change;
+                                               /*
+                                                * Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
+                                                * cycle to take (C20)
+                                                */
+       unsigned long arp_response_time;
+                                               /*
+                                                * Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
+                                                * LE_FLUSH_REQUEST has been sent before taking recover action. (C21)
+                                                */
+       unsigned long flush_timeout;
+                                               /* The time since sending a frame to the bus after which the
+                                                * LE Client may assume that the frame has been either discarded or
+                                                * delivered to the recipient (C22)
+                                                */
+       unsigned long path_switching_delay;
 
-        u8 *tlvs;          /* LANE2: TLVs are new                */
-        u32 sizeoftlvs;    /* The size of the tlv array in bytes */
-        int lane_version;  /* LANE2                              */
-       int itfnum;        /* e.g. 2 for lec2, 5 for lec5        */
-        struct lane2_ops *lane2_ops; /* can be NULL for LANE v1  */
-        int is_proxy;      /* bridge between ATM and Ethernet    */
-        int is_trdev;      /* Device type, 0 = Ethernet, 1 = TokenRing */
+       u8 *tlvs;                               /* LANE2: TLVs are new */
+       u32 sizeoftlvs;                         /* The size of the tlv array in bytes */
+       int lane_version;                       /* LANE2 */
+       int itfnum;                             /* e.g. 2 for lec2, 5 for lec5 */
+       struct lane2_ops *lane2_ops;            /* can be NULL for LANE v1 */
+       int is_proxy;                           /* bridge between ATM and Ethernet */
+       int is_trdev;                           /* Device type, 0 = Ethernet, 1 = TokenRing */
 };
 
 struct lec_vcc_priv {
-       void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
+       void (*old_pop) (struct atm_vcc *vcc, struct sk_buff *skb);
        int xoff;
 };
 
 #define LEC_VCC_PRIV(vcc)      ((struct lec_vcc_priv *)((vcc)->user_back))
 
-#endif /* _LEC_H_ */
-
+#endif                         /* _LEC_H_ */
index 397448094648e938ba9c869dfb6c4a796229f1bc..ec67435a40a6ffe172aa6d71c01396c5c652d832 100644 (file)
@@ -1,92 +1,96 @@
 /*
  * Lec arp cache
- * Marko Kiiskila mkiiskila@yahoo.com
  *
+ * Marko Kiiskila <mkiiskila@yahoo.com>
  */
-#ifndef _LEC_ARP_H
-#define _LEC_ARP_H
+#ifndef _LEC_ARP_H_
+#define _LEC_ARP_H_
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/if_ether.h>
 #include <linux/atmlec.h>
 
 struct lec_arp_table {
-        struct lec_arp_table *next;          /* Linked entry list */
-        unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */
-        unsigned char mac_addr[ETH_ALEN];    /* Mac address */
-        int is_rdesc;                        /* Mac address is a route descriptor */
-        struct atm_vcc *vcc;                 /* Vcc this entry is attached */
-        struct atm_vcc *recv_vcc;            /* Vcc we receive data from */
-        void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); 
-                                             /* Push that leads to daemon */
-        void (*old_recv_push)(struct atm_vcc *vcc, struct sk_buff *skb);
-                                             /* Push that leads to daemon */
-        void (*old_close)(struct atm_vcc *vcc);
-                                             /* We want to see when this
-                                              * vcc gets closed */
-        unsigned long last_used;             /* For expiry */
-        unsigned long timestamp;             /* Used for various timestamping
-                                              * things:
-                                              * 1. FLUSH started 
-                                              *    (status=ESI_FLUSH_PENDING)
-                                              * 2. Counting to 
-                                              *    max_unknown_frame_time
-                                              *    (status=ESI_ARP_PENDING||
-                                              *     status=ESI_VC_PENDING)
-                                              */
-        unsigned char no_tries;              /* No of times arp retry has been 
-                                                tried */
-        unsigned char status;                /* Status of this entry */
-        unsigned short flags;                /* Flags for this entry */
-        unsigned short packets_flooded;      /* Data packets flooded */
-        unsigned long flush_tran_id;         /* Transaction id in flush protocol */
-        struct timer_list timer;             /* Arping timer */
-        struct lec_priv *priv;               /* Pointer back */
+       struct hlist_node next;         /* Linked entry list */
+       unsigned char atm_addr[ATM_ESA_LEN];    /* Atm address */
+       unsigned char mac_addr[ETH_ALEN];       /* Mac address */
+       int is_rdesc;                   /* Mac address is a route descriptor */
+       struct atm_vcc *vcc;            /* Vcc this entry is attached */
+       struct atm_vcc *recv_vcc;       /* Vcc we receive data from */
 
-        u8  *tlvs;             /* LANE2: Each MAC address can have TLVs    */
-        u32 sizeoftlvs;        /* associated with it. sizeoftlvs tells the */
-                               /* the length of the tlvs array             */
-        struct sk_buff_head tx_wait; /* wait queue for outgoing packets    */
+       void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb);
+                                       /* Push that leads to daemon */
+
+       void (*old_recv_push) (struct atm_vcc *vcc, struct sk_buff *skb);
+                                       /* Push that leads to daemon */
+
+       unsigned long last_used;        /* For expiry */
+       unsigned long timestamp;        /* Used for various timestamping things:
+                                        * 1. FLUSH started
+                                        *    (status=ESI_FLUSH_PENDING)
+                                        * 2. Counting to
+                                        *    max_unknown_frame_time
+                                        *    (status=ESI_ARP_PENDING||
+                                        *     status=ESI_VC_PENDING)
+                                        */
+       unsigned char no_tries;         /* No of times arp retry has been tried */
+       unsigned char status;           /* Status of this entry */
+       unsigned short flags;           /* Flags for this entry */
+       unsigned short packets_flooded; /* Data packets flooded */
+       unsigned long flush_tran_id;    /* Transaction id in flush protocol */
+       struct timer_list timer;        /* Arping timer */
+       struct lec_priv *priv;          /* Pointer back */
+       u8 *tlvs;
+       u32 sizeoftlvs;                 /*
+                                        * LANE2: Each MAC address can have TLVs
+                                        * associated with it.  sizeoftlvs tells the
+                                        * the length of the tlvs array
+                                        */
+       struct sk_buff_head tx_wait;    /* wait queue for outgoing packets */
+       atomic_t usage;                 /* usage count */
 };
 
-struct tlv {                   /* LANE2: Template tlv struct for accessing */
-                               /* the tlvs in the lec_arp_table->tlvs array*/
-        u32 type;
-        u8  length;
-        u8  value[255];
+/*
+ * LANE2: Template tlv struct for accessing
+ * the tlvs in the lec_arp_table->tlvs array
+ */
+struct tlv {
+       u32 type;
+       u8 length;
+       u8 value[255];
 };
 
 /* Status fields */
-#define ESI_UNKNOWN 0       /*
-                             * Next packet sent to this mac address
-                             * causes ARP-request to be sent 
-                             */
-#define ESI_ARP_PENDING 1   /*
-                             * There is no ATM address associated with this
-                             * 48-bit address.  The LE-ARP protocol is in
-                             * progress.
-                             */
-#define ESI_VC_PENDING 2    /*
-                             * There is a valid ATM address associated with 
-                             * this 48-bit address but there is no VC set 
-                             * up to that ATM address.  The signaling 
-                             * protocol is in process.
-                             */
-#define ESI_FLUSH_PENDING 4 /*
-                             * The LEC has been notified of the FLUSH_START
-                             * status and it is assumed that the flush 
-                             * protocol is in process.
-                             */
-#define ESI_FORWARD_DIRECT 5 /*
-                              * Either the Path Switching Delay (C22) has 
-                              * elapsed or the LEC has notified the Mapping 
-                              * that the flush protocol has completed.  In 
-                              * either case, it is safe to forward packets 
-                              * to this address via the data direct VC.
-                              */
+#define ESI_UNKNOWN 0          /*
+                                * Next packet sent to this mac address
+                                * causes ARP-request to be sent
+                                */
+#define ESI_ARP_PENDING 1      /*
+                                * There is no ATM address associated with this
+                                * 48-bit address.  The LE-ARP protocol is in
+                                * progress.
+                                */
+#define ESI_VC_PENDING 2       /*
+                                * There is a valid ATM address associated with
+                                * this 48-bit address but there is no VC set
+                                * up to that ATM address.  The signaling
+                                * protocol is in process.
+                                */
+#define ESI_FLUSH_PENDING 4    /*
+                                * The LEC has been notified of the FLUSH_START
+                                * status and it is assumed that the flush
+                                * protocol is in process.
+                                */
+#define ESI_FORWARD_DIRECT 5   /*
+                                * Either the Path Switching Delay (C22) has
+                                * elapsed or the LEC has notified the Mapping
+                                * that the flush protocol has completed.  In
+                                * either case, it is safe to forward packets
+                                * to this address via the data direct VC.
+                                */
 
 /* Flag values */
 #define LEC_REMOTE_FLAG      0x0001
 #define LEC_PERMANENT_FLAG   0x0002
 
-#endif
+#endif /* _LEC_ARP_H_ */
index b87c2a88bdce40c63fdc136cac99e4ec7463eabb..0d2b994af5115931e419d3696b8e36e70fdaf493 100644 (file)
@@ -560,7 +560,6 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
        struct atmmpc_ioc ioc_data;
        in_cache_entry *in_entry;
        uint32_t  ipaddr;
-       unsigned char *ip;
 
        bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
        if (bytes_left != 0) {
@@ -583,9 +582,8 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
                        if (in_entry != NULL) mpc->in_ops->put(in_entry);
                        return -EINVAL;
                }
-               ip = (unsigned char*)&in_entry->ctrl_info.in_dst_ip;
                printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %u.%u.%u.%u\n",
-                      mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
                in_entry->shortcut = vcc;
                mpc->in_ops->put(in_entry);
        } else {
@@ -616,10 +614,8 @@ static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
        dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name);
        in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
        if (in_entry) {
-               unsigned char *ip __attribute__ ((unused)) =
-                   (unsigned char *)&in_entry->ctrl_info.in_dst_ip;
                dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n",
-                      mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
                in_entry->shortcut = NULL;
                mpc->in_ops->put(in_entry);
        }
@@ -1154,18 +1150,17 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
 {
        uint32_t dst_ip = msg->content.in_info.in_dst_ip;
        uint32_t mask = msg->ip_mask;
-       unsigned char *ip = (unsigned char *)&dst_ip;
        in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
 
        if(entry == NULL){
                printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ", mpc->dev->name);
-               printk("ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+               printk("ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
                return;
        }
 
        do {
                dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %u.%u.%u.%u\n" ,
-                       mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+                       mpc->dev->name, NIPQUAD(dst_ip));
                write_lock_bh(&mpc->ingress_lock);
                mpc->in_ops->remove_entry(entry, mpc);
                write_unlock_bh(&mpc->ingress_lock);
index 781ed1b9329d32f4308b734081f2ccd1ebd2466b..fbf13cdcf46ed2af4edfa2f1bf085af201e0ed6f 100644 (file)
@@ -87,7 +87,6 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
 static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,
                                          struct mpoa_client *client)
 {
-       unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip;
        in_cache_entry* entry = kmalloc(sizeof(in_cache_entry), GFP_KERNEL);
 
        if (entry == NULL) {
@@ -95,7 +94,7 @@ static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,
                return NULL;
        }
 
-       dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+       dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
        memset(entry,0,sizeof(in_cache_entry));
 
        atomic_set(&entry->use, 1);
@@ -152,10 +151,7 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
 
        if( entry->count > mpc->parameters.mpc_p1 &&
            entry->entry_state == INGRESS_INVALID){
-               unsigned char *ip __attribute__ ((unused)) =
-                   (unsigned char *)&entry->ctrl_info.in_dst_ip;
-
-               dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);
+               dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, NIPQUAD(entry->ctrl_info.in_dst_ip));
                entry->entry_state = INGRESS_RESOLVING;
                msg.type =  SND_MPOA_RES_RQST;
                memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN );
@@ -187,11 +183,9 @@ static void in_cache_remove_entry(in_cache_entry *entry,
 {
        struct atm_vcc *vcc;
        struct k_message msg;
-       unsigned char *ip;
 
        vcc = entry->shortcut;
-       ip = (unsigned char *)&entry->ctrl_info.in_dst_ip;
-       dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",ip[0], ip[1], ip[2], ip[3]);
+       dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",NIPQUAD(entry->ctrl_info.in_dst_ip));
 
        if (entry->prev != NULL)
                entry->prev->next = entry->next;
index 788ea7a2b74498c10534501e62c3e91fd17c117e..305a099b7477eb8fd0e4a7a7b487b7bd435e6677 100644 (file)
@@ -276,7 +276,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
                set_current_state(TASK_INTERRUPTIBLE);
 
                if (!timeo) {
-                       err = -EAGAIN;
+                       err = -EINPROGRESS;
                        break;
                }
 
index e620061fb50fd83cd530167d863b1745f3f7a3fd..2312d050eeedfb66ed382108f0703f6d2dfc5b9d 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 
 #include "bnep.h"
@@ -515,6 +516,26 @@ static int bnep_session(void *arg)
        return 0;
 }
 
+static struct device *bnep_get_device(struct bnep_session *session)
+{
+       bdaddr_t *src = &bt_sk(session->sock->sk)->src;
+       bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
+       struct hci_dev *hdev;
+       struct hci_conn *conn;
+
+       hdev = hci_get_route(dst, src);
+       if (!hdev)
+               return NULL;
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+       if (!conn)
+               return NULL;
+
+       hci_dev_put(hdev);
+
+       return &conn->dev;
+}
+
 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 {
        struct net_device *dev;
@@ -534,7 +555,6 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
        if (!dev)
                return -ENOMEM;
 
-
        down_write(&bnep_session_sem);
 
        ss = __bnep_get_session(dst);
@@ -551,7 +571,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
        memcpy(s->eh.h_source, &dst, ETH_ALEN);
        memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
 
-       s->dev = dev;
+       s->dev   = dev;
        s->sock  = sock;
        s->role  = req->role;
        s->state = BT_CONNECTED;
@@ -568,6 +588,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
        bnep_set_default_proto_filter(s);
 #endif
 
+       SET_NETDEV_DEV(dev, bnep_get_device(s));
+
        err = register_netdev(dev);
        if (err) {
                goto failed;
index 420ed4d7e57e98e44615196248e7afb94d36498e..90e3a285a17eaf9a4bde198879748d8a4da680a7 100644 (file)
@@ -84,6 +84,20 @@ static void hci_acl_connect(struct hci_conn *conn)
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
 }
 
+static void hci_acl_connect_cancel(struct hci_conn *conn)
+{
+       struct hci_cp_create_conn_cancel cp;
+
+       BT_DBG("%p", conn);
+
+       if (conn->hdev->hci_ver < 2)
+               return;
+
+       bacpy(&cp.bdaddr, &conn->dst);
+       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+                               OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+}
+
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
 {
        struct hci_cp_disconnect cp;
@@ -94,7 +108,8 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
 
        cp.handle = __cpu_to_le16(conn->handle);
        cp.reason = reason;
-       hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, sizeof(cp), &cp);
+       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+                               OCF_DISCONNECT, sizeof(cp), &cp);
 }
 
 void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -124,12 +139,20 @@ static void hci_conn_timeout(unsigned long arg)
                return;
 
        hci_dev_lock(hdev);
-       if (conn->state == BT_CONNECTED)
+
+       switch (conn->state) {
+       case BT_CONNECT:
+               hci_acl_connect_cancel(conn);
+               break;
+       case BT_CONNECTED:
                hci_acl_disconn(conn, 0x13);
-       else
+               break;
+       default:
                conn->state = BT_CLOSED;
+               break;
+       }
+
        hci_dev_unlock(hdev);
-       return;
 }
 
 static void hci_conn_idle(unsigned long arg)
@@ -179,6 +202,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
        if (hdev->notify)
                hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
 
+       hci_conn_add_sysfs(conn);
+
        tasklet_enable(&hdev->tx_task);
 
        return conn;
@@ -211,6 +236,8 @@ int hci_conn_del(struct hci_conn *conn)
 
        tasklet_disable(&hdev->tx_task);
 
+       hci_conn_del_sysfs(conn);
+
        hci_conn_hash_del(hdev, conn);
        if (hdev->notify)
                hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
@@ -221,7 +248,9 @@ int hci_conn_del(struct hci_conn *conn)
 
        hci_dev_put(hdev);
 
-       kfree(conn);
+       /* will free via device release */
+       put_device(&conn->dev);
+
        return 0;
 }
 
index 5ed47427790385fc335168857d02082deb2ab498..338ae977a31b2209fb39e1a97d644db185d4597a 100644 (file)
@@ -206,6 +206,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
        /* Read Local Supported Features */
        hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
 
+       /* Read Local Version */
+       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
+
        /* Read Buffer Size (ACL mtu, max pkt, etc.) */
        hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
 
index 3896dabab11da70898640581f9c3e5b2195f7678..d43d0c8909752564796b540a61cb58389cc8cb0d 100644 (file)
@@ -62,6 +62,7 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
 
        switch (ocf) {
        case OCF_INQUIRY_CANCEL:
+       case OCF_EXIT_PERIODIC_INQ:
                status = *((__u8 *) skb->data);
 
                if (status) {
@@ -297,6 +298,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
 /* Command Complete OGF INFO_PARAM  */
 static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
+       struct hci_rp_read_loc_version *lv;
        struct hci_rp_read_local_features *lf;
        struct hci_rp_read_buffer_size *bs;
        struct hci_rp_read_bd_addr *ba;
@@ -304,6 +306,23 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
        BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
        switch (ocf) {
+       case OCF_READ_LOCAL_VERSION:
+               lv = (struct hci_rp_read_loc_version *) skb->data;
+
+               if (lv->status) {
+                       BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
+                       break;
+               }
+
+               hdev->hci_ver = lv->hci_ver;
+               hdev->hci_rev = btohs(lv->hci_rev);
+               hdev->manufacturer = btohs(lv->manufacturer);
+
+               BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
+                               hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
+
+               break;
+
        case OCF_READ_LOCAL_FEATURES:
                lf = (struct hci_rp_read_local_features *) skb->data;
 
@@ -328,7 +347,8 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
                if (hdev->features[1] & LMP_HV3)
                        hdev->pkt_type |= (HCI_HV3);
 
-               BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+               BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
+                               lf->features[0], lf->features[1], lf->features[2]);
 
                break;
 
@@ -757,6 +777,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 
                        hci_send_cmd(hdev, OGF_LINK_CTL,
                                OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+               } else {
+                       /* Update disconnect timer */
+                       hci_conn_hold(conn);
+                       hci_conn_put(conn);
                }
        } else
                conn->state = BT_CLOSED;
index 3987d167f04e73225ea98556bd1f583c899e9223..989b22d9042e92f929435d9f0290d2d429e7fd75 100644 (file)
 #define BT_DBG(D...)
 #endif
 
-static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+static inline char *typetostr(int type)
 {
-       struct hci_dev *hdev = dev_get_drvdata(dev);
-       return sprintf(buf, "%s\n", hdev->name);
+       switch (type) {
+       case HCI_VIRTUAL:
+               return "VIRTUAL";
+       case HCI_USB:
+               return "USB";
+       case HCI_PCCARD:
+               return "PCCARD";
+       case HCI_UART:
+               return "UART";
+       case HCI_RS232:
+               return "RS232";
+       case HCI_PCI:
+               return "PCI";
+       case HCI_SDIO:
+               return "SDIO";
+       default:
+               return "UNKNOWN";
+       }
 }
 
 static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       return sprintf(buf, "%d\n", hdev->type);
+       return sprintf(buf, "%s\n", typetostr(hdev->type));
 }
 
 static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
@@ -33,10 +49,22 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
        return sprintf(buf, "%s\n", batostr(&bdaddr));
 }
 
-static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_dev *hdev = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n", hdev->manufacturer);
+}
+
+static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       return sprintf(buf, "0x%lx\n", hdev->flags);
+       return sprintf(buf, "%d\n", hdev->hci_ver);
+}
+
+static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_dev *hdev = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n", hdev->hci_rev);
 }
 
 static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
@@ -141,10 +169,11 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
        return count;
 }
 
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
+static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
+static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
+static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
 static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
 
 static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
@@ -155,10 +184,11 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
                                show_sniff_min_interval, store_sniff_min_interval);
 
 static struct device_attribute *bt_attrs[] = {
-       &dev_attr_name,
        &dev_attr_type,
        &dev_attr_address,
-       &dev_attr_flags,
+       &dev_attr_manufacturer,
+       &dev_attr_hci_version,
+       &dev_attr_hci_revision,
        &dev_attr_inquiry_cache,
        &dev_attr_idle_timeout,
        &dev_attr_sniff_max_interval,
@@ -166,6 +196,32 @@ static struct device_attribute *bt_attrs[] = {
        NULL
 };
 
+static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_conn *conn = dev_get_drvdata(dev);
+       return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
+}
+
+static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_conn *conn = dev_get_drvdata(dev);
+       bdaddr_t bdaddr;
+       baswap(&bdaddr, &conn->dst);
+       return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+#define CONN_ATTR(_name,_mode,_show,_store) \
+struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
+static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
+
+static struct device_attribute *conn_attrs[] = {
+       &conn_attr_type,
+       &conn_attr_address,
+       NULL
+};
+
 struct class *bt_class = NULL;
 EXPORT_SYMBOL_GPL(bt_class);
 
@@ -177,8 +233,57 @@ static struct platform_device *bt_platform;
 
 static void bt_release(struct device *dev)
 {
-       struct hci_dev *hdev = dev_get_drvdata(dev);
-       kfree(hdev);
+       void *data = dev_get_drvdata(dev);
+       kfree(data);
+}
+
+static void add_conn(void *data)
+{
+       struct hci_conn *conn = data;
+       int i;
+
+       device_register(&conn->dev);
+
+       for (i = 0; conn_attrs[i]; i++)
+               device_create_file(&conn->dev, conn_attrs[i]);
+}
+
+void hci_conn_add_sysfs(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+       bdaddr_t *ba = &conn->dst;
+
+       BT_DBG("conn %p", conn);
+
+       conn->dev.parent  = &hdev->dev;
+       conn->dev.release = bt_release;
+
+       snprintf(conn->dev.bus_id, BUS_ID_SIZE,
+                       "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
+                       conn->type == ACL_LINK ? "acl" : "sco",
+                       ba->b[5], ba->b[4], ba->b[3],
+                       ba->b[2], ba->b[1], ba->b[0]);
+
+       dev_set_drvdata(&conn->dev, conn);
+
+       INIT_WORK(&conn->work, add_conn, (void *) conn);
+
+       schedule_work(&conn->work);
+}
+
+static void del_conn(void *data)
+{
+       struct hci_conn *conn = data;
+       device_del(&conn->dev);
+}
+
+void hci_conn_del_sysfs(struct hci_conn *conn)
+{
+       BT_DBG("conn %p", conn);
+
+       INIT_WORK(&conn->work, del_conn, (void *) conn);
+
+       schedule_work(&conn->work);
 }
 
 int hci_register_sysfs(struct hci_dev *hdev)
@@ -214,11 +319,9 @@ int hci_register_sysfs(struct hci_dev *hdev)
 
 void hci_unregister_sysfs(struct hci_dev *hdev)
 {
-       struct device *dev = &hdev->dev;
-
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-       device_del(dev);
+       device_del(&hdev->dev);
 }
 
 int __init bt_sysfs_init(void)
@@ -245,7 +348,7 @@ int __init bt_sysfs_init(void)
        return 0;
 }
 
-void __exit bt_sysfs_cleanup(void)
+void bt_sysfs_cleanup(void)
 {
        class_destroy(bt_class);
 
index c6e3a2c27c6ecc864dfa85153b1b42f557957f69..03b5dadb49511f90b0c57ee6d9d677d580c5ef18 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/input.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 
 #include "hidp.h"
@@ -528,6 +529,26 @@ static int hidp_session(void *arg)
        return 0;
 }
 
+static struct device *hidp_get_device(struct hidp_session *session)
+{
+       bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
+       bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
+       struct hci_dev *hdev;
+       struct hci_conn *conn;
+
+       hdev = hci_get_route(dst, src);
+       if (!hdev)
+               return NULL;
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+       if (!conn)
+               return NULL;
+
+       hci_dev_put(hdev);
+
+       return &conn->dev;
+}
+
 static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
 {
        struct input_dev *input = session->input;
@@ -566,6 +587,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
                input->relbit[0] |= BIT(REL_WHEEL);
        }
 
+       input->cdev.dev = hidp_get_device(session);
+
        input->event = hidp_input_event;
 
        input_register_device(input);
index 332dd8f436ea0a2957df07db7d7b4aedcffa888f..468df3b953f6d3c615169a0939e50ec924eb1af8 100644 (file)
@@ -644,7 +644,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_psm    = htobs(RFCOMM_PSM);
        *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
-       if (*err == 0 || *err == -EAGAIN)
+       if (*err == 0 || *err == -EINPROGRESS)
                return s;
 
        rfcomm_session_del(s);
index bd8d671a0ba6f1622ee54e463c2d393b0a6a8943..26f322737db0c83702267b25190dca8fa925c324 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/skbuff.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/rfcomm.h>
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
@@ -161,6 +162,24 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
        return dev;
 }
 
+static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
+{
+       struct hci_dev *hdev;
+       struct hci_conn *conn;
+
+       hdev = hci_get_route(&dev->dst, &dev->src);
+       if (!hdev)
+               return NULL;
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
+       if (!conn)
+               return NULL;
+
+       hci_dev_put(hdev);
+
+       return &conn->dev;
+}
+
 static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 {
        struct rfcomm_dev *dev;
@@ -244,7 +263,7 @@ out:
                return err;
        }
 
-       tty_register_device(rfcomm_tty_driver, dev->id, NULL);
+       tty_register_device(rfcomm_tty_driver, dev->id, rfcomm_get_device(dev));
 
        return dev->id;
 }
index d19fc4b328dcfa481f9d982a830172c1e3cd1582..0aa7b9910a86159a66043ba819298a02f6b917f1 100644 (file)
@@ -20,7 +20,7 @@ static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
    const void *data, unsigned int datalen)
 {
        struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
-       u32 _sip, *siptr, _dip, *diptr;
+       __be32 _sip, *siptr, _dip, *diptr;
        struct arphdr _ah, *ap;
        unsigned char _sha[ETH_ALEN], *shp;
        struct sk_buff *skb = *pskb;
index 14de297d024d1e8771180dde2e07aec624b90e1c..4d891beab13899cd96c74b8a6a88b5ef5d6aba43 100644 (file)
@@ -1480,14 +1480,16 @@ gso:
        if (q->enqueue) {
                /* Grab device queue */
                spin_lock(&dev->queue_lock);
+               q = dev->qdisc;
+               if (q->enqueue) {
+                       rc = q->enqueue(skb, q);
+                       qdisc_run(dev);
+                       spin_unlock(&dev->queue_lock);
 
-               rc = q->enqueue(skb, q);
-
-               qdisc_run(dev);
-
+                       rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
+                       goto out;
+               }
                spin_unlock(&dev->queue_lock);
-               rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
-               goto out;
        }
 
        /* The device has no queue. Common case for software devices:
index e0ca04f38cef3d7058e4ffe548e9b2aa85f92f47..87dc556fd9d6c694f65e33c6868aebdeef8325cc 100644 (file)
@@ -806,13 +806,6 @@ int dev_ethtool(struct ifreq *ifr)
        int rc;
        unsigned long old_features;
 
-       /*
-        * XXX: This can be pushed down into the ethtool_* handlers that
-        * need it.  Keep existing behaviour for the moment.
-        */
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
-
        if (!dev || !netif_device_present(dev))
                return -ENODEV;
 
@@ -822,6 +815,27 @@ int dev_ethtool(struct ifreq *ifr)
        if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
                return -EFAULT;
 
+       /* Allow some commands to be done by anyone */
+       switch(ethcmd) {
+       case ETHTOOL_GDRVINFO:
+       case ETHTOOL_GMSGLVL:
+       case ETHTOOL_GCOALESCE:
+       case ETHTOOL_GRINGPARAM:
+       case ETHTOOL_GPAUSEPARAM:
+       case ETHTOOL_GRXCSUM:
+       case ETHTOOL_GTXCSUM:
+       case ETHTOOL_GSG:
+       case ETHTOOL_GSTRINGS:
+       case ETHTOOL_GTSO:
+       case ETHTOOL_GPERMADDR:
+       case ETHTOOL_GUFO:
+       case ETHTOOL_GGSO:
+               break;
+       default:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+       }
+
        if(dev->ethtool_ops->begin)
                if ((rc = dev->ethtool_ops->begin(dev)) < 0)
                        return rc;
@@ -947,6 +961,10 @@ int dev_ethtool(struct ifreq *ifr)
        return rc;
 
  ioctl:
+       /* Keep existing behaviour for the moment.       */
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
        if (dev->do_ioctl)
                return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
        return -EOPNOTSUPP;
index b6c69e1463e87f0dc756022ade88e52e4062dea0..8ce8c471d8687427ad2b88acf5d33a17a874bbbc 100644 (file)
@@ -1079,7 +1079,7 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl,
 }
 
 static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
-                         u16 protocol)
+                         __be16 protocol)
 {
        struct hh_cache *hh;
        struct net_device *dev = dst->dev;
index 72145d4a260082fc6e798522e95052a36f1643c6..dd023fd2830409475f42b8cd8ccb7fb16cd03aa2 100644 (file)
  *
  * MPLS support by Steven Whitehouse <steve@chygwyn.com>
  *
+ * 802.1Q/Q-in-Q support by Francesco Fondelli (FF) <francesco.fondelli@gmail.com>
+ *
  */
 #include <linux/sys.h>
 #include <linux/types.h>
 #include <linux/inetdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_arp.h>
+#include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <asm/div64.h>         /* do_div */
 #include <asm/timex.h>
 
-#define VERSION  "pktgen v2.67: Packet Generator for packet performance testing.\n"
+#define VERSION  "pktgen v2.68: Packet Generator for packet performance testing.\n"
 
 /* #define PG_DEBUG(a) a */
 #define PG_DEBUG(a)
 #define F_TXSIZE_RND  (1<<6)   /* Transmit size is random */
 #define F_IPV6        (1<<7)   /* Interface in IPV6 Mode */
 #define F_MPLS_RND    (1<<8)   /* Random MPLS labels */
+#define F_VID_RND     (1<<9)   /* Random VLAN ID */
+#define F_SVID_RND    (1<<10)  /* Random SVLAN ID */
 
 /* Thread control flag bits */
 #define T_TERMINATE   (1<<0)
@@ -198,6 +203,9 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
 
 #define MAX_CFLOWS  65536
 
+#define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4)
+#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4)
+
 struct flow_state {
        __u32 cur_daddr;
        int count;
@@ -284,10 +292,23 @@ struct pktgen_dev {
        __u16 udp_dst_min;      /* inclusive, dest UDP port */
        __u16 udp_dst_max;      /* exclusive, dest UDP port */
 
+       /* DSCP + ECN */
+       __u8 tos;            /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */
+       __u8 traffic_class;  /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */
+
        /* MPLS */
        unsigned nr_labels;     /* Depth of stack, 0 = no MPLS */
        __be32 labels[MAX_MPLS_LABELS];
 
+       /* VLAN/SVLAN (802.1Q/Q-in-Q) */
+       __u8  vlan_p;
+       __u8  vlan_cfi;
+       __u16 vlan_id;  /* 0xffff means no vlan tag */
+
+       __u8  svlan_p;
+       __u8  svlan_cfi;
+       __u16 svlan_id; /* 0xffff means no svlan tag */
+
        __u32 src_mac_count;    /* How many MACs to iterate through */
        __u32 dst_mac_count;    /* How many MACs to iterate through */
 
@@ -644,6 +665,24 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
                                   i == pkt_dev->nr_labels-1 ? "\n" : ", ");
        }
 
+       if (pkt_dev->vlan_id != 0xffff) {
+               seq_printf(seq, "     vlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
+                          pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
+       }
+
+       if (pkt_dev->svlan_id != 0xffff) {
+               seq_printf(seq, "     svlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
+                          pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
+       }
+
+       if (pkt_dev->tos) {
+               seq_printf(seq, "     tos: 0x%02x\n", pkt_dev->tos);
+       }
+
+       if (pkt_dev->traffic_class) {
+               seq_printf(seq, "     traffic_class: 0x%02x\n", pkt_dev->traffic_class);
+       }
+
        seq_printf(seq, "     Flags: ");
 
        if (pkt_dev->flags & F_IPV6)
@@ -673,6 +712,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
        if (pkt_dev->flags & F_MACDST_RND)
                seq_printf(seq, "MACDST_RND  ");
 
+       if (pkt_dev->flags & F_VID_RND)
+               seq_printf(seq, "VID_RND  ");
+
+       if (pkt_dev->flags & F_SVID_RND)
+               seq_printf(seq, "SVID_RND  ");
+
        seq_puts(seq, "\n");
 
        sa = pkt_dev->started_at;
@@ -715,12 +760,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 }
 
 
-static int hex32_arg(const char __user *user_buffer, __u32 *num)
+static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
 {
        int i = 0;
        *num = 0;
 
-       for(; i < 8; i++) {
+       for(; i < maxlen; i++) {
                char c;
                *num <<= 4;
                if (get_user(c, &user_buffer[i]))
@@ -815,7 +860,7 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
        pkt_dev->nr_labels = 0;
        do {
                __u32 tmp;
-               len = hex32_arg(&buffer[i], &tmp);
+               len = hex32_arg(&buffer[i], 8, &tmp);
                if (len <= 0)
                        return len;
                pkt_dev->labels[n] = htonl(tmp);
@@ -1140,11 +1185,27 @@ static ssize_t pktgen_if_write(struct file *file,
                else if (strcmp(f, "!MPLS_RND") == 0)
                        pkt_dev->flags &= ~F_MPLS_RND;
 
+               else if (strcmp(f, "VID_RND") == 0)
+                       pkt_dev->flags |= F_VID_RND;
+
+               else if (strcmp(f, "!VID_RND") == 0)
+                       pkt_dev->flags &= ~F_VID_RND;
+
+               else if (strcmp(f, "SVID_RND") == 0)
+                       pkt_dev->flags |= F_SVID_RND;
+
+               else if (strcmp(f, "!SVID_RND") == 0)
+                       pkt_dev->flags &= ~F_SVID_RND;
+
+               else if (strcmp(f, "!IPV6") == 0)
+                       pkt_dev->flags &= ~F_IPV6;
+
                else {
                        sprintf(pg_result,
                                "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
                                f,
-                               "IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
+                               "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
+                               "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n");
                        return count;
                }
                sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -1445,6 +1506,160 @@ static ssize_t pktgen_if_write(struct file *file,
                        offset += sprintf(pg_result + offset,
                                          "%08x%s", ntohl(pkt_dev->labels[n]),
                                          n == pkt_dev->nr_labels-1 ? "" : ",");
+
+               if (pkt_dev->nr_labels && pkt_dev->vlan_id != 0xffff) {
+                       pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+                       pkt_dev->svlan_id = 0xffff;
+
+                       if (debug)
+                               printk("pktgen: VLAN/SVLAN auto turned off\n");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "vlan_id")) {
+               len = num_arg(&user_buffer[i], 4, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if (value <= 4095) {
+                       pkt_dev->vlan_id = value;  /* turn on VLAN */
+
+                       if (debug)
+                               printk("pktgen: VLAN turned on\n");
+
+                       if (debug && pkt_dev->nr_labels)
+                               printk("pktgen: MPLS auto turned off\n");
+
+                       pkt_dev->nr_labels = 0;    /* turn off MPLS */
+                       sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id);
+               } else {
+                       pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+                       pkt_dev->svlan_id = 0xffff;
+
+                       if (debug)
+                               printk("pktgen: VLAN/SVLAN turned off\n");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "vlan_p")) {
+               len = num_arg(&user_buffer[i], 1, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
+                       pkt_dev->vlan_p = value;
+                       sprintf(pg_result, "OK: vlan_p=%u", pkt_dev->vlan_p);
+               } else {
+                       sprintf(pg_result, "ERROR: vlan_p must be 0-7");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "vlan_cfi")) {
+               len = num_arg(&user_buffer[i], 1, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
+                       pkt_dev->vlan_cfi = value;
+                       sprintf(pg_result, "OK: vlan_cfi=%u", pkt_dev->vlan_cfi);
+               } else {
+                       sprintf(pg_result, "ERROR: vlan_cfi must be 0-1");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "svlan_id")) {
+               len = num_arg(&user_buffer[i], 4, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
+                       pkt_dev->svlan_id = value;  /* turn on SVLAN */
+
+                       if (debug)
+                               printk("pktgen: SVLAN turned on\n");
+
+                       if (debug && pkt_dev->nr_labels)
+                               printk("pktgen: MPLS auto turned off\n");
+
+                       pkt_dev->nr_labels = 0;    /* turn off MPLS */
+                       sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id);
+               } else {
+                       pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
+                       pkt_dev->svlan_id = 0xffff;
+
+                       if (debug)
+                               printk("pktgen: VLAN/SVLAN turned off\n");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "svlan_p")) {
+               len = num_arg(&user_buffer[i], 1, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
+                       pkt_dev->svlan_p = value;
+                       sprintf(pg_result, "OK: svlan_p=%u", pkt_dev->svlan_p);
+               } else {
+                       sprintf(pg_result, "ERROR: svlan_p must be 0-7");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "svlan_cfi")) {
+               len = num_arg(&user_buffer[i], 1, &value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
+                       pkt_dev->svlan_cfi = value;
+                       sprintf(pg_result, "OK: svlan_cfi=%u", pkt_dev->svlan_cfi);
+               } else {
+                       sprintf(pg_result, "ERROR: svlan_cfi must be 0-1");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "tos")) {
+               __u32 tmp_value = 0;
+               len = hex32_arg(&user_buffer[i], 2, &tmp_value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if (len == 2) {
+                       pkt_dev->tos = tmp_value;
+                       sprintf(pg_result, "OK: tos=0x%02x", pkt_dev->tos);
+               } else {
+                       sprintf(pg_result, "ERROR: tos must be 00-ff");
+               }
+               return count;
+       }
+
+       if (!strcmp(name, "traffic_class")) {
+               __u32 tmp_value = 0;
+               len = hex32_arg(&user_buffer[i], 2, &tmp_value);
+               if (len < 0) {
+                       return len;
+               }
+               i += len;
+               if (len == 2) {
+                       pkt_dev->traffic_class = tmp_value;
+                       sprintf(pg_result, "OK: traffic_class=0x%02x", pkt_dev->traffic_class);
+               } else {
+                       sprintf(pg_result, "ERROR: traffic_class must be 00-ff");
+               }
                return count;
        }
 
@@ -1949,6 +2164,14 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
                                                      htonl(0x000fffff));
        }
 
+       if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) {
+               pkt_dev->vlan_id = pktgen_random() % 4096;
+       }
+
+       if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) {
+               pkt_dev->svlan_id = pktgen_random() % 4096;
+       }
+
        if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
                if (pkt_dev->flags & F_UDPSRC_RND)
                        pkt_dev->cur_udp_src =
@@ -2092,10 +2315,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        struct pktgen_hdr *pgh = NULL;
        __be16 protocol = __constant_htons(ETH_P_IP);
        __be32 *mpls;
+       __be16 *vlan_tci = NULL;                 /* Encapsulates priority and VLAN ID */
+       __be16 *vlan_encapsulated_proto = NULL;  /* packet type ID field (or len) for VLAN tag */
+       __be16 *svlan_tci = NULL;                /* Encapsulates priority and SVLAN ID */
+       __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
+
 
        if (pkt_dev->nr_labels)
                protocol = __constant_htons(ETH_P_MPLS_UC);
 
+       if (pkt_dev->vlan_id != 0xffff)
+               protocol = __constant_htons(ETH_P_8021Q);
+
        /* Update any of the values, used when we're incrementing various
         * fields.
         */
@@ -2103,7 +2334,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
        datalen = (odev->hard_header_len + 16) & ~0xf;
        skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
-                       pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
+                       pkt_dev->nr_labels*sizeof(u32) +
+                       VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
+                       GFP_ATOMIC);
        if (!skb) {
                sprintf(pkt_dev->result, "No memory");
                return NULL;
@@ -2116,6 +2349,24 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
        if (pkt_dev->nr_labels)
                mpls_push(mpls, pkt_dev);
+
+       if (pkt_dev->vlan_id != 0xffff) {
+               if(pkt_dev->svlan_id != 0xffff) {
+                       svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+                       *svlan_tci = htons(pkt_dev->svlan_id);
+                       *svlan_tci |= pkt_dev->svlan_p << 5;
+                       *svlan_tci |= pkt_dev->svlan_cfi << 4;
+                       svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+                       *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+               }
+               vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+               *vlan_tci = htons(pkt_dev->vlan_id);
+               *vlan_tci |= pkt_dev->vlan_p << 5;
+               *vlan_tci |= pkt_dev->vlan_cfi << 4;
+               vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+               *vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
+       }
+
        iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
        udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 
@@ -2124,7 +2375,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
        /* Eth + IPh + UDPh + mpls */
        datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
-                 pkt_dev->nr_labels*sizeof(u32);
+                 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
        if (datalen < sizeof(struct pktgen_hdr))
                datalen = sizeof(struct pktgen_hdr);
 
@@ -2136,7 +2387,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        iph->ihl = 5;
        iph->version = 4;
        iph->ttl = 32;
-       iph->tos = 0;
+       iph->tos = pkt_dev->tos;
        iph->protocol = IPPROTO_UDP;    /* UDP */
        iph->saddr = pkt_dev->cur_saddr;
        iph->daddr = pkt_dev->cur_daddr;
@@ -2146,7 +2397,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        iph->check = 0;
        iph->check = ip_fast_csum((void *)iph, iph->ihl);
        skb->protocol = protocol;
-       skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
+       skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
+               VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
        skb->nh.iph = iph;
@@ -2218,7 +2470,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
                pgh->tv_sec = htonl(timestamp.tv_sec);
                pgh->tv_usec = htonl(timestamp.tv_usec);
        }
-       pkt_dev->seq_num++;
 
        return skb;
 }
@@ -2402,17 +2653,26 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        struct pktgen_hdr *pgh = NULL;
        __be16 protocol = __constant_htons(ETH_P_IPV6);
        __be32 *mpls;
+       __be16 *vlan_tci = NULL;                 /* Encapsulates priority and VLAN ID */
+       __be16 *vlan_encapsulated_proto = NULL;  /* packet type ID field (or len) for VLAN tag */
+       __be16 *svlan_tci = NULL;                /* Encapsulates priority and SVLAN ID */
+       __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
 
        if (pkt_dev->nr_labels)
                protocol = __constant_htons(ETH_P_MPLS_UC);
 
+       if (pkt_dev->vlan_id != 0xffff)
+               protocol = __constant_htons(ETH_P_8021Q);
+
        /* Update any of the values, used when we're incrementing various
         * fields.
         */
        mod_cur_headers(pkt_dev);
 
        skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
-                       pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
+                       pkt_dev->nr_labels*sizeof(u32) +
+                       VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
+                       GFP_ATOMIC);
        if (!skb) {
                sprintf(pkt_dev->result, "No memory");
                return NULL;
@@ -2425,16 +2685,34 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
        if (pkt_dev->nr_labels)
                mpls_push(mpls, pkt_dev);
+
+       if (pkt_dev->vlan_id != 0xffff) {
+               if(pkt_dev->svlan_id != 0xffff) {
+                       svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+                       *svlan_tci = htons(pkt_dev->svlan_id);
+                       *svlan_tci |= pkt_dev->svlan_p << 5;
+                       *svlan_tci |= pkt_dev->svlan_cfi << 4;
+                       svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+                       *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+               }
+               vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
+               *vlan_tci = htons(pkt_dev->vlan_id);
+               *vlan_tci |= pkt_dev->vlan_p << 5;
+               *vlan_tci |= pkt_dev->vlan_cfi << 4;
+               vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
+               *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
+       }
+
        iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
        udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 
        memcpy(eth, pkt_dev->hh, 12);
-       *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6);
+       *(u16 *) & eth[12] = protocol;
 
        /* Eth + IPh + UDPh + mpls */
        datalen = pkt_dev->cur_pkt_size - 14 -
                  sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
-                 pkt_dev->nr_labels*sizeof(u32);
+                 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
 
        if (datalen < sizeof(struct pktgen_hdr)) {
                datalen = sizeof(struct pktgen_hdr);
@@ -2450,6 +2728,11 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 
        *(u32 *) iph = __constant_htonl(0x60000000);    /* Version + flow */
 
+       if (pkt_dev->traffic_class) {
+               /* Version + traffic class + flow (0) */
+               *(u32 *)iph |= htonl(0x60000000 | (pkt_dev->traffic_class << 20));
+       }
+
        iph->hop_limit = 32;
 
        iph->payload_len = htons(sizeof(struct udphdr) + datalen);
@@ -2458,7 +2741,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
        ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
 
-       skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
+       skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
+               VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
        skb->protocol = protocol;
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
@@ -2531,7 +2815,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
                pgh->tv_sec = htonl(timestamp.tv_sec);
                pgh->tv_usec = htonl(timestamp.tv_usec);
        }
-       pkt_dev->seq_num++;
+       /* pkt_dev->seq_num++; FF: you really mean this? */
 
        return skb;
 }
@@ -3177,6 +3461,13 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
        pkt_dev->udp_dst_min = 9;
        pkt_dev->udp_dst_max = 9;
 
+       pkt_dev->vlan_p = 0;
+       pkt_dev->vlan_cfi = 0;
+       pkt_dev->vlan_id = 0xffff;
+       pkt_dev->svlan_p = 0;
+       pkt_dev->svlan_cfi = 0;
+       pkt_dev->svlan_id = 0xffff;
+
        strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
 
        if (!pktgen_setup_dev(pkt_dev)) {
index d8e25e08cb7e7b725b3cc5cfb6e34cdf67a11532..221e4038216b8da1e61a67b32087eb146b02af3c 100644 (file)
@@ -562,7 +562,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
        if (err < 0)
-               goto errout;
+               return err;
 
        ifm = nlmsg_data(nlh);
        if (ifm->ifi_index >= 0) {
index 2682490777dec6ceea515596d11f6c7117910147..94c5d761c830e3a156501b9e0320ec16929d5564 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Authors:
  *     net_random Alan Cox
- *     net_ratelimit Andy Kleen
+ *     net_ratelimit Andi Kleen
  *     in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project
  *
  *     Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
index 66be29b6f508484b180fecf63356d09667bc90c1..bf692c1c116f69a1384d7124c03212ee2d504ebb 100644 (file)
@@ -50,7 +50,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        struct dccp_sock *dp = dccp_sk(sk);
        const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
        struct rtable *rt;
-       u32 daddr, nexthop;
+       __be32 daddr, nexthop;
        int tmp;
        int err;
 
index 43863933f27f92dc0c6f09556dfee953fab08704..4bd78c8cfb26fe9f229813613a14b0548de3a4d1 100644 (file)
@@ -223,7 +223,7 @@ static int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
  */
 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
 {
-       unsigned short type = hh->hh_type;
+       __be16 type = hh->hh_type;
        struct ethhdr *eth;
        struct net_device *dev = neigh->dev;
 
index fdd89e37b9aaccfd17532352822b3140a6b61578..edcf0932ac6de06a96c0dc9699d662cf5539a140 100644 (file)
@@ -996,7 +996,7 @@ static int inet_sk_reselect_saddr(struct sock *sk)
        struct rtable *rt;
        __u32 old_saddr = inet->saddr;
        __u32 new_saddr;
-       __u32 daddr = inet->daddr;
+       __be32 daddr = inet->daddr;
 
        if (inet->opt && inet->opt->srr)
                daddr = inet->opt->faddr;
@@ -1043,7 +1043,7 @@ int inet_sk_rebuild_header(struct sock *sk)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
-       u32 daddr;
+       __be32 daddr;
        int err;
 
        /* Route is OK, nothing to do. */
@@ -1342,10 +1342,10 @@ static int __init inet_init(void)
        rc = 0;
 out:
        return rc;
-out_unregister_tcp_proto:
-       proto_unregister(&tcp_prot);
 out_unregister_udp_proto:
        proto_unregister(&udp_prot);
+out_unregister_tcp_proto:
+       proto_unregister(&tcp_prot);
        goto out;
 }
 
index c8a3723bc001b0a744d382a4a353c2c902a28ddd..cfe5c84742865c56c0e6b40702bdf54b14f4f752 100644 (file)
@@ -234,7 +234,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev)
 
 static int arp_constructor(struct neighbour *neigh)
 {
-       u32 addr = *(u32*)neigh->primary_key;
+       __be32 addr = *(__be32*)neigh->primary_key;
        struct net_device *dev = neigh->dev;
        struct in_device *in_dev;
        struct neigh_parms *parms;
@@ -330,10 +330,10 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
 
 static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
 {
-       u32 saddr = 0;
+       __be32 saddr = 0;
        u8  *dst_ha = NULL;
        struct net_device *dev = neigh->dev;
-       u32 target = *(u32*)neigh->primary_key;
+       __be32 target = *(__be32*)neigh->primary_key;
        int probes = atomic_read(&neigh->probes);
        struct in_device *in_dev = in_dev_get(dev);
 
@@ -385,7 +385,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
 }
 
 static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
-                     u32 sip, u32 tip)
+                     __be32 sip, __be32 tip)
 {
        int scope;
 
@@ -420,7 +420,7 @@ static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
        return !inet_confirm_addr(dev, sip, tip, scope);
 }
 
-static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
+static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
 {
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,
                                                 .saddr = tip } } };
@@ -449,7 +449,7 @@ static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
  *     is allowed to use this function, it is scheduled to be removed. --ANK
  */
 
-static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, struct net_device * dev)
+static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev)
 {
        switch (addr_hint) {
        case RTN_LOCAL:
@@ -470,7 +470,7 @@ static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, s
 int arp_find(unsigned char *haddr, struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
-       u32 paddr;
+       __be32 paddr;
        struct neighbour *n;
 
        if (!skb->dst) {
@@ -511,7 +511,7 @@ int arp_bind_neighbour(struct dst_entry *dst)
        if (dev == NULL)
                return -EINVAL;
        if (n == NULL) {
-               u32 nexthop = ((struct rtable*)dst)->rt_gateway;
+               __be32 nexthop = ((struct rtable*)dst)->rt_gateway;
                if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
                        nexthop = 0;
                n = __neigh_lookup_errno(
@@ -560,8 +560,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
  *     Create an arp packet. If (dest_hw == NULL), we create a broadcast
  *     message.
  */
-struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
-                          struct net_device *dev, u32 src_ip,
+struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+                          struct net_device *dev, __be32 src_ip,
                           unsigned char *dest_hw, unsigned char *src_hw,
                           unsigned char *target_hw)
 {
@@ -675,8 +675,8 @@ void arp_xmit(struct sk_buff *skb)
 /*
  *     Create and send an arp packet.
  */
-void arp_send(int type, int ptype, u32 dest_ip, 
-             struct net_device *dev, u32 src_ip, 
+void arp_send(int type, int ptype, __be32 dest_ip,
+             struct net_device *dev, __be32 src_ip,
              unsigned char *dest_hw, unsigned char *src_hw,
              unsigned char *target_hw)
 {
@@ -710,7 +710,7 @@ static int arp_process(struct sk_buff *skb)
        unsigned char *arp_ptr;
        struct rtable *rt;
        unsigned char *sha, *tha;
-       u32 sip, tip;
+       __be32 sip, tip;
        u16 dev_type = dev->type;
        int addr_type;
        struct neighbour *n;
@@ -969,13 +969,13 @@ out_of_mem:
 
 static int arp_req_set(struct arpreq *r, struct net_device * dev)
 {
-       u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+       __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
        struct neighbour *neigh;
        int err;
 
        if (r->arp_flags&ATF_PUBL) {
-               u32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
-               if (mask && mask != 0xFFFFFFFF)
+               __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
+               if (mask && mask != htonl(0xFFFFFFFF))
                        return -EINVAL;
                if (!dev && (r->arp_flags & ATF_COM)) {
                        dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data);
@@ -1063,7 +1063,7 @@ static unsigned arp_state_to_flags(struct neighbour *neigh)
 
 static int arp_req_get(struct arpreq *r, struct net_device *dev)
 {
-       u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+       __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
        struct neighbour *neigh;
        int err = -ENXIO;
 
@@ -1084,13 +1084,13 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
 static int arp_req_delete(struct arpreq *r, struct net_device * dev)
 {
        int err;
-       u32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+       __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
        struct neighbour *neigh;
 
        if (r->arp_flags & ATF_PUBL) {
-               u32 mask =
+               __be32 mask =
                       ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
-               if (mask == 0xFFFFFFFF)
+               if (mask == htonl(0xFFFFFFFF))
                        return pneigh_delete(&arp_tbl, &ip, dev);
                if (mask == 0) {
                        if (dev == NULL) {
index e6ce0b3ba62a49ed8aef7ae0c6f4541a67a3d53d..a8e2e879a64764c31bbcc2626cb6779a5aba04fb 100644 (file)
@@ -474,6 +474,7 @@ doi_add_failure_rlock:
 /**
  * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
  * @doi: the DOI value
+ * @audit_secid: the LSM secid to use in the audit message
  * @callback: the DOI cleanup/free callback
  *
  * Description:
@@ -483,7 +484,9 @@ doi_add_failure_rlock:
  * success and negative values on failure.
  *
  */
-int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
+int cipso_v4_doi_remove(u32 doi,
+                       struct netlbl_audit *audit_info,
+                       void (*callback) (struct rcu_head * head))
 {
        struct cipso_v4_doi *doi_def;
        struct cipso_v4_domhsh_entry *dom_iter;
@@ -502,7 +505,8 @@ int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
                spin_unlock(&cipso_v4_doi_list_lock);
                list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
                        if (dom_iter->valid)
-                               netlbl_domhsh_remove(dom_iter->domain);
+                               netlbl_domhsh_remove(dom_iter->domain,
+                                                    audit_info);
                cipso_v4_cache_invalidate();
                rcu_read_unlock();
 
index ec5da4fbd9f43d84fd961de6e855455591e49311..7b068a891953aae4d9e377438319815c3439259b 100644 (file)
@@ -25,7 +25,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        struct inet_sock *inet = inet_sk(sk);
        struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
        struct rtable *rt;
-       u32 saddr;
+       __be32 saddr;
        int oif;
        int err;
 
index 8e8d1f17d77a7c29009fbcbc760a290259d5afc2..7602c79a389bece923dc5dfd8b00b524690d8d85 100644 (file)
@@ -224,7 +224,7 @@ static void inetdev_destroy(struct in_device *in_dev)
        call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
 }
 
-int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
+int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
 {
        rcu_read_lock();
        for_primary_ifa(in_dev) {
@@ -429,8 +429,8 @@ struct in_device *inetdev_by_index(int ifindex)
 
 /* Called only from RTNL semaphored context. No locks. */
 
-struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix,
-                                   u32 mask)
+struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
+                                   __be32 mask)
 {
        ASSERT_RTNL();
 
@@ -467,7 +467,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
        for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
             ifap = &ifa->ifa_next) {
                if (tb[IFA_LOCAL] &&
-                   ifa->ifa_local != nla_get_u32(tb[IFA_LOCAL]))
+                   ifa->ifa_local != nla_get_be32(tb[IFA_LOCAL]))
                        continue;
 
                if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
@@ -475,7 +475,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
 
                if (tb[IFA_ADDRESS] &&
                    (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
-                   !inet_ifa_match(nla_get_u32(tb[IFA_ADDRESS]), ifa)))
+                   !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
                        continue;
 
                __inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).pid);
@@ -540,14 +540,14 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
        ifa->ifa_scope = ifm->ifa_scope;
        ifa->ifa_dev = in_dev;
 
-       ifa->ifa_local = nla_get_u32(tb[IFA_LOCAL]);
-       ifa->ifa_address = nla_get_u32(tb[IFA_ADDRESS]);
+       ifa->ifa_local = nla_get_be32(tb[IFA_LOCAL]);
+       ifa->ifa_address = nla_get_be32(tb[IFA_ADDRESS]);
 
        if (tb[IFA_BROADCAST])
-               ifa->ifa_broadcast = nla_get_u32(tb[IFA_BROADCAST]);
+               ifa->ifa_broadcast = nla_get_be32(tb[IFA_BROADCAST]);
 
        if (tb[IFA_ANYCAST])
-               ifa->ifa_anycast = nla_get_u32(tb[IFA_ANYCAST]);
+               ifa->ifa_anycast = nla_get_be32(tb[IFA_ANYCAST]);
 
        if (tb[IFA_LABEL])
                nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
@@ -805,7 +805,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
                        break;
                ret = 0;
                if (ifa->ifa_mask != sin->sin_addr.s_addr) {
-                       u32 old_mask = ifa->ifa_mask;
+                       __be32 old_mask = ifa->ifa_mask;
                        inet_del_ifa(in_dev, ifap, 0);
                        ifa->ifa_mask = sin->sin_addr.s_addr;
                        ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
@@ -876,9 +876,9 @@ out:
        return done;
 }
 
-u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
+__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
 {
-       u32 addr = 0;
+       __be32 addr = 0;
        struct in_device *in_dev;
 
        rcu_read_lock();
@@ -927,11 +927,11 @@ out:
        return addr;
 }
 
-static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
-                             u32 local, int scope)
+static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
+                             __be32 local, int scope)
 {
        int same = 0;
-       u32 addr = 0;
+       __be32 addr = 0;
 
        for_ifa(in_dev) {
                if (!addr &&
@@ -971,9 +971,9 @@ static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
  * - local: address, 0=autoselect the local address
  * - scope: maximum allowed scope value for the local address
  */
-u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope)
+__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
 {
-       u32 addr = 0;
+       __be32 addr = 0;
        struct in_device *in_dev;
 
        if (dev) {
@@ -1138,16 +1138,16 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
        ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
 
        if (ifa->ifa_address)
-               NLA_PUT_U32(skb, IFA_ADDRESS, ifa->ifa_address);
+               NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address);
 
        if (ifa->ifa_local)
-               NLA_PUT_U32(skb, IFA_LOCAL, ifa->ifa_local);
+               NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local);
 
        if (ifa->ifa_broadcast)
-               NLA_PUT_U32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
+               NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
 
        if (ifa->ifa_anycast)
-               NLA_PUT_U32(skb, IFA_ANYCAST, ifa->ifa_anycast);
+               NLA_PUT_BE32(skb, IFA_ANYCAST, ifa->ifa_anycast);
 
        if (ifa->ifa_label[0])
                NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
index cfb527c060e48e4235063591a349ae91e7bb263a..9c399a70dd5d5962f3e47ad9e82cae0ae8b46c7b 100644 (file)
@@ -122,7 +122,7 @@ static void fib_flush(void)
  *     Find the first device with a given source address.
  */
 
-struct net_device * ip_dev_find(u32 addr)
+struct net_device * ip_dev_find(__be32 addr)
 {
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result res;
@@ -146,7 +146,7 @@ out:
        return dev;
 }
 
-unsigned inet_addr_type(u32 addr)
+unsigned inet_addr_type(__be32 addr)
 {
        struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result       res;
@@ -180,8 +180,8 @@ unsigned inet_addr_type(u32 addr)
    - check, that packet arrived from expected physical interface.
  */
 
-int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
-                       struct net_device *dev, u32 *spec_dst, u32 *itag)
+int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+                       struct net_device *dev, __be32 *spec_dst, u32 *itag)
 {
        struct in_device *in_dev;
        struct flowi fl = { .nl_u = { .ip4_u =
@@ -253,7 +253,7 @@ e_inval:
 
 #ifndef CONFIG_IP_NOSIOCRT
 
-static inline u32 sk_extract_addr(struct sockaddr *addr)
+static inline __be32 sk_extract_addr(struct sockaddr *addr)
 {
        return ((struct sockaddr_in *) addr)->sin_addr.s_addr;
 }
@@ -273,7 +273,7 @@ static int put_rtax(struct nlattr *mx, int len, int type, u32 value)
 static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
                                 struct fib_config *cfg)
 {
-       u32 addr;
+       __be32 addr;
        int plen;
 
        memset(cfg, 0, sizeof(*cfg));
@@ -292,7 +292,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
        plen = 32;
        addr = sk_extract_addr(&rt->rt_dst);
        if (!(rt->rt_flags & RTF_HOST)) {
-               u32 mask = sk_extract_addr(&rt->rt_genmask);
+               __be32 mask = sk_extract_addr(&rt->rt_genmask);
 
                if (rt->rt_genmask.sa_family != AF_INET) {
                        if (mask || rt->rt_genmask.sa_family)
@@ -499,22 +499,22 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
        nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
                switch (attr->nla_type) {
                case RTA_DST:
-                       cfg->fc_dst = nla_get_u32(attr);
+                       cfg->fc_dst = nla_get_be32(attr);
                        break;
                case RTA_SRC:
-                       cfg->fc_src = nla_get_u32(attr);
+                       cfg->fc_src = nla_get_be32(attr);
                        break;
                case RTA_OIF:
                        cfg->fc_oif = nla_get_u32(attr);
                        break;
                case RTA_GATEWAY:
-                       cfg->fc_gw = nla_get_u32(attr);
+                       cfg->fc_gw = nla_get_be32(attr);
                        break;
                case RTA_PRIORITY:
                        cfg->fc_priority = nla_get_u32(attr);
                        break;
                case RTA_PREFSRC:
-                       cfg->fc_prefsrc = nla_get_u32(attr);
+                       cfg->fc_prefsrc = nla_get_be32(attr);
                        break;
                case RTA_METRICS:
                        cfg->fc_mx = nla_data(attr);
@@ -627,8 +627,7 @@ out:
    only when netlink is already locked.
  */
 
-static void fib_magic(int cmd, int type, u32 dst, int dst_len,
-                     struct in_ifaddr *ifa)
+static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
 {
        struct fib_table *tb;
        struct fib_config cfg = {
@@ -667,9 +666,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
        struct in_device *in_dev = ifa->ifa_dev;
        struct net_device *dev = in_dev->dev;
        struct in_ifaddr *prim = ifa;
-       u32 mask = ifa->ifa_mask;
-       u32 addr = ifa->ifa_local;
-       u32 prefix = ifa->ifa_address&mask;
+       __be32 mask = ifa->ifa_mask;
+       __be32 addr = ifa->ifa_local;
+       __be32 prefix = ifa->ifa_address&mask;
 
        if (ifa->ifa_flags&IFA_F_SECONDARY) {
                prim = inet_ifa_byprefix(in_dev, prefix, mask);
@@ -685,7 +684,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
                return;
 
        /* Add broadcast address, if it is explicitly assigned. */
-       if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF)
+       if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
                fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
 
        if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
@@ -707,8 +706,8 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
        struct net_device *dev = in_dev->dev;
        struct in_ifaddr *ifa1;
        struct in_ifaddr *prim = ifa;
-       u32 brd = ifa->ifa_address|~ifa->ifa_mask;
-       u32 any = ifa->ifa_address&ifa->ifa_mask;
+       __be32 brd = ifa->ifa_address|~ifa->ifa_mask;
+       __be32 any = ifa->ifa_address&ifa->ifa_mask;
 #define LOCAL_OK       1
 #define BRD_OK         2
 #define BRD0_OK                4
index 88133b383dc586cc95ee0c482cc019f8db4730b4..107bb6cbb0b370be0f8e10b0d434a432fbc3ebdd 100644 (file)
@@ -51,7 +51,7 @@ static kmem_cache_t *fn_alias_kmem __read_mostly;
 struct fib_node {
        struct hlist_node       fn_hash;
        struct list_head        fn_alias;
-       u32                     fn_key;
+       __be32                  fn_key;
 };
 
 struct fn_zone {
@@ -64,7 +64,7 @@ struct fn_zone {
 #define FZ_HASHMASK(fz)                ((fz)->fz_hashmask)
 
        int                     fz_order;       /* Zone order           */
-       u32                     fz_mask;
+       __be32                  fz_mask;
 #define FZ_MASK(fz)            ((fz)->fz_mask)
 };
 
@@ -77,7 +77,7 @@ struct fn_hash {
        struct fn_zone  *fn_zone_list;
 };
 
-static inline u32 fn_hash(u32 key, struct fn_zone *fz)
+static inline u32 fn_hash(__be32 key, struct fn_zone *fz)
 {
        u32 h = ntohl(key)>>(32 - fz->fz_order);
        h ^= (h>>20);
@@ -87,7 +87,7 @@ static inline u32 fn_hash(u32 key, struct fn_zone *fz)
        return h;
 }
 
-static inline u32 fz_key(u32 dst, struct fn_zone *fz)
+static inline __be32 fz_key(__be32 dst, struct fn_zone *fz)
 {
        return dst & FZ_MASK(fz);
 }
@@ -254,7 +254,7 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                struct hlist_head *head;
                struct hlist_node *node;
                struct fib_node *f;
-               u32 k = fz_key(flp->fl4_dst, fz);
+               __be32 k = fz_key(flp->fl4_dst, fz);
 
                head = &fz->fz_hash[fn_hash(k, fz)];
                hlist_for_each_entry(f, node, head, fn_hash) {
@@ -365,7 +365,7 @@ static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
 }
 
 /* Return the node in FZ matching KEY. */
-static struct fib_node *fib_find_node(struct fn_zone *fz, u32 key)
+static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
 {
        struct hlist_head *head = &fz->fz_hash[fn_hash(key, fz)];
        struct hlist_node *node;
@@ -387,7 +387,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
        struct fn_zone *fz;
        struct fib_info *fi;
        u8 tos = cfg->fc_tos;
-       u32 key;
+       __be32 key;
        int err;
 
        if (cfg->fc_dst_len > 32)
@@ -541,7 +541,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
        struct fib_node *f;
        struct fib_alias *fa, *fa_to_delete;
        struct fn_zone *fz;
-       u32 key;
+       __be32 key;
 
        if (cfg->fc_dst_len > 32)
                return -EINVAL;
@@ -966,7 +966,7 @@ static void fib_seq_stop(struct seq_file *seq, void *v)
        read_unlock(&fib_hash_lock);
 }
 
-static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
+static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
 {
        static const unsigned type2flags[RTN_MAX + 1] = {
                [7] = RTF_REJECT, [8] = RTF_REJECT,
@@ -975,7 +975,7 @@ static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
 
        if (fi && fi->fib_nh->nh_gw)
                flags |= RTF_GATEWAY;
-       if (mask == 0xFFFFFFFF)
+       if (mask == htonl(0xFFFFFFFF))
                flags |= RTF_HOST;
        flags |= RTF_UP;
        return flags;
@@ -991,7 +991,7 @@ static int fib_seq_show(struct seq_file *seq, void *v)
 {
        struct fib_iter_state *iter;
        char bf[128];
-       u32 prefix, mask;
+       __be32 prefix, mask;
        unsigned flags;
        struct fib_node *f;
        struct fib_alias *fa;
index fd6f7769f8ab7fd0278fe1f65b02a677db44b688..0e8b70bad4e194b6f4a3968acb127b2387b6c2fe 100644 (file)
@@ -20,16 +20,16 @@ struct fib_alias {
 /* Exported by fib_semantics.c */
 extern int fib_semantic_match(struct list_head *head,
                              const struct flowi *flp,
-                             struct fib_result *res, __u32 zone, __u32 mask,
+                             struct fib_result *res, __be32 zone, __be32 mask,
                                int prefixlen);
 extern void fib_release_info(struct fib_info *);
 extern struct fib_info *fib_create_info(struct fib_config *cfg);
 extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
 extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
-                        u32 tb_id, u8 type, u8 scope, u32 dst,
+                        u32 tb_id, u8 type, u8 scope, __be32 dst,
                         int dst_len, u8 tos, struct fib_info *fi,
                         unsigned int);
-extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
                      int dst_len, u32 tb_id, struct nl_info *info);
 extern struct fib_alias *fib_find_alias(struct list_head *fah,
                                        u8 tos, u32 prio);
index 52b2adae4f2230ae2af02f7a51efab6ab9516615..0852b9cd065a27bad02c3759c2262fcebf08405e 100644 (file)
@@ -40,10 +40,10 @@ struct fib4_rule
        u8                      dst_len;
        u8                      src_len;
        u8                      tos;
-       u32                     src;
-       u32                     srcmask;
-       u32                     dst;
-       u32                     dstmask;
+       __be32                  src;
+       __be32                  srcmask;
+       __be32                  dst;
+       __be32                  dstmask;
 #ifdef CONFIG_IP_ROUTE_FWMARK
        u32                     fwmark;
        u32                     fwmask;
@@ -150,8 +150,8 @@ void fib_select_default(const struct flowi *flp, struct fib_result *res)
 static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
        struct fib4_rule *r = (struct fib4_rule *) rule;
-       u32 daddr = fl->fl4_dst;
-       u32 saddr = fl->fl4_src;
+       __be32 daddr = fl->fl4_dst;
+       __be32 saddr = fl->fl4_src;
 
        if (((saddr ^ r->src) & r->srcmask) ||
            ((daddr ^ r->dst) & r->dstmask))
@@ -215,10 +215,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
        }
 
        if (tb[FRA_SRC])
-               rule4->src = nla_get_u32(tb[FRA_SRC]);
+               rule4->src = nla_get_be32(tb[FRA_SRC]);
 
        if (tb[FRA_DST])
-               rule4->dst = nla_get_u32(tb[FRA_DST]);
+               rule4->dst = nla_get_be32(tb[FRA_DST]);
 
 #ifdef CONFIG_IP_ROUTE_FWMARK
        if (tb[FRA_FWMARK]) {
@@ -277,10 +277,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
                return 0;
 #endif
 
-       if (tb[FRA_SRC] && (rule4->src != nla_get_u32(tb[FRA_SRC])))
+       if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC])))
                return 0;
 
-       if (tb[FRA_DST] && (rule4->dst != nla_get_u32(tb[FRA_DST])))
+       if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST])))
                return 0;
 
        return 1;
@@ -305,10 +305,10 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
 #endif
 
        if (rule4->dst_len)
-               NLA_PUT_U32(skb, FRA_DST, rule4->dst);
+               NLA_PUT_BE32(skb, FRA_DST, rule4->dst);
 
        if (rule4->src_len)
-               NLA_PUT_U32(skb, FRA_SRC, rule4->src);
+               NLA_PUT_BE32(skb, FRA_SRC, rule4->src);
 
 #ifdef CONFIG_NET_CLS_ROUTE
        if (rule4->tclassid)
index 2ead09543f68899bef4ef584fd2c029d9e8b7df9..884d176e0082f3a230b9fa360ba4dc37518f2cb9 100644 (file)
@@ -203,7 +203,7 @@ static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
        unsigned int val = fi->fib_nhs;
 
        val ^= fi->fib_protocol;
-       val ^= fi->fib_prefsrc;
+       val ^= (__force u32)fi->fib_prefsrc;
        val ^= fi->fib_priority;
 
        return (val ^ (val >> 7) ^ (val >> 12)) & mask;
@@ -248,7 +248,7 @@ static inline unsigned int fib_devindex_hashfn(unsigned int val)
    Used only by redirect accept routine.
  */
 
-int ip_fib_check_default(u32 gw, struct net_device *dev)
+int ip_fib_check_default(__be32 gw, struct net_device *dev)
 {
        struct hlist_head *head;
        struct hlist_node *node;
@@ -273,7 +273,7 @@ int ip_fib_check_default(u32 gw, struct net_device *dev)
        return -1;
 }
 
-void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
               int dst_len, u32 tb_id, struct nl_info *info)
 {
        struct sk_buff *skb;
@@ -374,7 +374,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
                        struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
 
                        nla = nla_find(attrs, attrlen, RTA_GATEWAY);
-                       nh->nh_gw = nla ? nla_get_u32(nla) : 0;
+                       nh->nh_gw = nla ? nla_get_be32(nla) : 0;
 #ifdef CONFIG_NET_CLS_ROUTE
                        nla = nla_find(attrs, attrlen, RTA_FLOW);
                        nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
@@ -427,7 +427,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
                        struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
 
                        nla = nla_find(attrs, attrlen, RTA_GATEWAY);
-                       if (nla && nla_get_u32(nla) != nh->nh_gw)
+                       if (nla && nla_get_be32(nla) != nh->nh_gw)
                                return 1;
 #ifdef CONFIG_NET_CLS_ROUTE
                        nla = nla_find(attrs, attrlen, RTA_FLOW);
@@ -568,11 +568,11 @@ out:
        return 0;
 }
 
-static inline unsigned int fib_laddr_hashfn(u32 val)
+static inline unsigned int fib_laddr_hashfn(__be32 val)
 {
        unsigned int mask = (fib_hash_size - 1);
 
-       return (val ^ (val >> 7) ^ (val >> 14)) & mask;
+       return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
 }
 
 static struct hlist_head *fib_hash_alloc(int bytes)
@@ -847,7 +847,7 @@ failure:
 
 /* Note! fib_semantic_match intentionally uses  RCU list functions. */
 int fib_semantic_match(struct list_head *head, const struct flowi *flp,
-                      struct fib_result *res, __u32 zone, __u32 mask, 
+                      struct fib_result *res, __be32 zone, __be32 mask,
                        int prefixlen)
 {
        struct fib_alias *fa;
@@ -914,8 +914,7 @@ out_fill_res:
        res->fi = fa->fa_info;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
        res->netmask = mask;
-       res->network = zone &
-               (0xFFFFFFFF >> (32 - prefixlen));
+       res->network = zone & inet_make_mask(prefixlen);
 #endif
        atomic_inc(&res->fi->fib_clntref);
        return 0;
@@ -923,13 +922,13 @@ out_fill_res:
 
 /* Find appropriate source address to this destination */
 
-u32 __fib_res_prefsrc(struct fib_result *res)
+__be32 __fib_res_prefsrc(struct fib_result *res)
 {
        return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
 }
 
 int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
-                 u32 tb_id, u8 type, u8 scope, u32 dst, int dst_len, u8 tos,
+                 u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos,
                  struct fib_info *fi, unsigned int flags)
 {
        struct nlmsghdr *nlh;
@@ -952,7 +951,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
        rtm->rtm_protocol = fi->fib_protocol;
 
        if (rtm->rtm_dst_len)
-               NLA_PUT_U32(skb, RTA_DST, dst);
+               NLA_PUT_BE32(skb, RTA_DST, dst);
 
        if (fi->fib_priority)
                NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority);
@@ -961,11 +960,11 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                goto nla_put_failure;
 
        if (fi->fib_prefsrc)
-               NLA_PUT_U32(skb, RTA_PREFSRC, fi->fib_prefsrc);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, fi->fib_prefsrc);
 
        if (fi->fib_nhs == 1) {
                if (fi->fib_nh->nh_gw)
-                       NLA_PUT_U32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
+                       NLA_PUT_BE32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
 
                if (fi->fib_nh->nh_oif)
                        NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
@@ -993,7 +992,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                        rtnh->rtnh_ifindex = nh->nh_oif;
 
                        if (nh->nh_gw)
-                               NLA_PUT_U32(skb, RTA_GATEWAY, nh->nh_gw);
+                               NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw);
 #ifdef CONFIG_NET_CLS_ROUTE
                        if (nh->nh_tclassid)
                                NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
@@ -1018,7 +1017,7 @@ nla_put_failure:
    - device went down -> we must shutdown all nexthops going via it.
  */
 
-int fib_sync_down(u32 local, struct net_device *dev, int force)
+int fib_sync_down(__be32 local, struct net_device *dev, int force)
 {
        int ret = 0;
        int scope = RT_SCOPE_NOWHERE;
index 9c3ff6ba6e218e45c351c22f1eb8ff188442a509..d17990ec724f68d30fa6987e8c61fd7dc21fdd5d 100644 (file)
@@ -1834,7 +1834,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
        int i, s_i;
        struct fib_alias *fa;
 
-       u32 xkey = htonl(key);
+       __be32 xkey = htonl(key);
 
        s_i = cb->args[4];
        i = 0;
@@ -2281,7 +2281,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
 
        if (IS_TNODE(n)) {
                struct tnode *tn = (struct tnode *) n;
-               t_key prf = ntohl(MASK_PFX(tn->key, tn->pos));
+               __be32 prf = htonl(MASK_PFX(tn->key, tn->pos));
 
                if (!NODE_PARENT(n)) {
                        if (iter->trie == trie_local)
@@ -2297,7 +2297,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
        } else {
                struct leaf *l = (struct leaf *) n;
                int i;
-               u32 val = ntohl(l->key);
+               __be32 val = htonl(l->key);
 
                seq_indent(seq, iter->depth);
                seq_printf(seq, "  |-- %d.%d.%d.%d\n", NIPQUAD(val));
@@ -2360,7 +2360,7 @@ static struct file_operations fib_trie_fops = {
        .release = seq_release_private,
 };
 
-static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
+static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
 {
        static unsigned type2flags[RTN_MAX + 1] = {
                [7] = RTF_REJECT, [8] = RTF_REJECT,
@@ -2369,7 +2369,7 @@ static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
 
        if (fi && fi->fib_nh->nh_gw)
                flags |= RTF_GATEWAY;
-       if (mask == 0xFFFFFFFF)
+       if (mask == htonl(0xFFFFFFFF))
                flags |= RTF_HOST;
        flags |= RTF_UP;
        return flags;
@@ -2403,7 +2403,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
        for (i=32; i>=0; i--) {
                struct leaf_info *li = find_leaf_info(l, i);
                struct fib_alias *fa;
-               u32 mask, prefix;
+               __be32 mask, prefix;
 
                if (!li)
                        continue;
index c2ad07e48ab4f97ad77af0a99fbd7202b7f048e4..b39a37a4754506c436b17a0be5bf3c2a6165f26e 100644 (file)
@@ -104,7 +104,7 @@ struct icmp_bxm {
 
        struct {
                struct icmphdr icmph;
-               __u32          times[3];
+               __be32         times[3];
        } data;
        int head_len;
        struct ip_options replyopts;
@@ -381,7 +381,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
        struct inet_sock *inet = inet_sk(sk);
        struct ipcm_cookie ipc;
        struct rtable *rt = (struct rtable *)skb->dst;
-       u32 daddr;
+       __be32 daddr;
 
        if (ip_options_echo(&icmp_param->replyopts, skb))
                return;
@@ -430,14 +430,14 @@ out_unlock:
  *                     MUST reply to only the first fragment.
  */
 
-void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
+void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 {
        struct iphdr *iph;
        int room;
        struct icmp_bxm icmp_param;
        struct rtable *rt = (struct rtable *)skb_in->dst;
        struct ipcm_cookie ipc;
-       u32 saddr;
+       __be32 saddr;
        u8  tos;
 
        if (!rt)
@@ -895,7 +895,7 @@ static void icmp_address_reply(struct sk_buff *skb)
        if (in_dev->ifa_list &&
            IN_DEV_LOG_MARTIANS(in_dev) &&
            IN_DEV_FORWARD(in_dev)) {
-               u32 _mask, *mp;
+               __be32 _mask, *mp;
 
                mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask);
                BUG_ON(mp == NULL);
index 58be8227b0cb95975ef5eae527b4de88e352dd08..6eee71647b7c92f5fdcb69f43c68ce37c3b59cee 100644 (file)
                time_before(jiffies, (in_dev)->mr_v2_seen)))
 
 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
-static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr);
+static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
 static void igmpv3_clear_delrec(struct in_device *in_dev);
 static int sf_setstate(struct ip_mc_list *pmc);
 static void sf_markstate(struct ip_mc_list *pmc);
 #endif
 static void ip_mc_clear_src(struct ip_mc_list *pmc);
-static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-                        int sfcount, __u32 *psfsrc, int delta);
+static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+                        int sfcount, __be32 *psfsrc, int delta);
 
 static void ip_ma_put(struct ip_mc_list *im)
 {
@@ -426,7 +426,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
        first = 1;
        psf_prev = NULL;
        for (psf=*psf_list; psf; psf=psf_next) {
-               u32 *psrc;
+               __be32 *psrc;
 
                psf_next = psf->sf_next;
 
@@ -439,7 +439,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
                if (isquery)
                        psf->sf_gsresp = 0;
 
-               if (AVAILABLE(skb) < sizeof(u32) +
+               if (AVAILABLE(skb) < sizeof(__be32) +
                    first*sizeof(struct igmpv3_grec)) {
                        if (truncate && !first)
                                break;   /* truncate these */
@@ -455,7 +455,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
                        skb = add_grhead(skb, pmc, type, &pgr);
                        first = 0;
                }
-               psrc = (u32 *)skb_put(skb, sizeof(u32));
+               psrc = (__be32 *)skb_put(skb, sizeof(__be32));
                *psrc = psf->sf_inaddr;
                scount++; stotal++;
                if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
@@ -630,8 +630,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
        struct igmphdr *ih;
        struct rtable *rt;
        struct net_device *dev = in_dev->dev;
-       u32     group = pmc ? pmc->multiaddr : 0;
-       u32     dst;
+       __be32  group = pmc ? pmc->multiaddr : 0;
+       __be32  dst;
 
        if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
                return igmpv3_send_report(in_dev, pmc);
@@ -748,7 +748,7 @@ static void igmp_timer_expire(unsigned long data)
 }
 
 /* mark EXCLUDE-mode sources */
-static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
 {
        struct ip_sf_list *psf;
        int i, scount;
@@ -775,7 +775,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
        return 1;
 }
 
-static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
 {
        struct ip_sf_list *psf;
        int i, scount;
@@ -803,7 +803,7 @@ static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
        return 1;
 }
 
-static void igmp_heard_report(struct in_device *in_dev, u32 group)
+static void igmp_heard_report(struct in_device *in_dev, __be32 group)
 {
        struct ip_mc_list *im;
 
@@ -828,7 +828,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
        struct igmphdr          *ih = skb->h.igmph;
        struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
        struct ip_mc_list       *im;
-       u32                     group = ih->group;
+       __be32                  group = ih->group;
        int                     max_delay;
        int                     mark = 0;
 
@@ -862,7 +862,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                ih3 = (struct igmpv3_query *) skb->h.raw;
                if (ih3->nsrcs) {
                        if (!pskb_may_pull(skb, sizeof(struct igmpv3_query) 
-                                          + ntohs(ih3->nsrcs)*sizeof(__u32)))
+                                          + ntohs(ih3->nsrcs)*sizeof(__be32)))
                                return;
                        ih3 = (struct igmpv3_query *) skb->h.raw;
                }
@@ -985,7 +985,7 @@ drop:
  *     Add a filter to a device
  */
 
-static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
+static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
 {
        char buf[MAX_ADDR_LEN];
        struct net_device *dev = in_dev->dev;
@@ -1005,7 +1005,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
  *     Remove a filter from a device
  */
 
-static void ip_mc_filter_del(struct in_device *in_dev, u32 addr)
+static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
 {
        char buf[MAX_ADDR_LEN];
        struct net_device *dev = in_dev->dev;
@@ -1055,7 +1055,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
        spin_unlock_bh(&in_dev->mc_tomb_lock);
 }
 
-static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr)
+static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr)
 {
        struct ip_mc_list *pmc, *pmc_prev;
        struct ip_sf_list *psf, *psf_next;
@@ -1193,7 +1193,7 @@ static void igmp_group_added(struct ip_mc_list *im)
  *     A socket has joined a multicast group on device dev.
  */
 
-void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
+void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 {
        struct ip_mc_list *im;
 
@@ -1252,7 +1252,7 @@ out:
  *     A socket has left a multicast group on device dev
  */
 
-void ip_mc_dec_group(struct in_device *in_dev, u32 addr)
+void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
 {
        struct ip_mc_list *i, **ip;
        
@@ -1402,7 +1402,7 @@ int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF;
 
 
 static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
-       __u32 *psfsrc)
+       __be32 *psfsrc)
 {
        struct ip_sf_list *psf, *psf_prev;
        int rv = 0;
@@ -1450,8 +1450,8 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
 #define igmp_ifc_event(x)      do { } while (0)
 #endif
 
-static int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-                        int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+                        int sfcount, __be32 *psfsrc, int delta)
 {
        struct ip_mc_list *pmc;
        int     changerec = 0;
@@ -1517,7 +1517,7 @@ out_unlock:
  * Add multicast single-source filter to the interface list
  */
 static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
-       __u32 *psfsrc, int delta)
+       __be32 *psfsrc, int delta)
 {
        struct ip_sf_list *psf, *psf_prev;
 
@@ -1623,8 +1623,8 @@ static int sf_setstate(struct ip_mc_list *pmc)
 /*
  * Add multicast source filter list to the interface list
  */
-static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-                        int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+                        int sfcount, __be32 *psfsrc, int delta)
 {
        struct ip_mc_list *pmc;
        int     isexclude;
@@ -1717,7 +1717,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
 int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
 {
        int err;
-       u32 addr = imr->imr_multiaddr.s_addr;
+       __be32 addr = imr->imr_multiaddr.s_addr;
        struct ip_mc_socklist *iml=NULL, *i;
        struct in_device *in_dev;
        struct inet_sock *inet = inet_sk(sk);
@@ -1791,7 +1791,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
        struct inet_sock *inet = inet_sk(sk);
        struct ip_mc_socklist *iml, **imlp;
        struct in_device *in_dev;
-       u32 group = imr->imr_multiaddr.s_addr;
+       __be32 group = imr->imr_multiaddr.s_addr;
        u32 ifindex;
        int ret = -EADDRNOTAVAIL;
 
@@ -1829,7 +1829,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
 {
        int err;
        struct ip_mreqn imr;
-       u32 addr = mreqs->imr_multiaddr;
+       __be32 addr = mreqs->imr_multiaddr;
        struct ip_mc_socklist *pmc;
        struct in_device *in_dev = NULL;
        struct inet_sock *inet = inet_sk(sk);
@@ -1883,7 +1883,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
                rv = !0;
                for (i=0; i<psl->sl_count; i++) {
                        rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
-                               sizeof(__u32));
+                               sizeof(__be32));
                        if (rv == 0)
                                break;
                }
@@ -1935,7 +1935,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
        rv = 1; /* > 0 for insert logic below if sl_count is 0 */
        for (i=0; i<psl->sl_count; i++) {
                rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
-                       sizeof(__u32));
+                       sizeof(__be32));
                if (rv == 0)
                        break;
        }
@@ -1960,7 +1960,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
 {
        int err = 0;
        struct ip_mreqn imr;
-       u32 addr = msf->imsf_multiaddr;
+       __be32 addr = msf->imsf_multiaddr;
        struct ip_mc_socklist *pmc;
        struct in_device *in_dev;
        struct inet_sock *inet = inet_sk(sk);
@@ -2044,7 +2044,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
 {
        int err, len, count, copycount;
        struct ip_mreqn imr;
-       u32 addr = msf->imsf_multiaddr;
+       __be32 addr = msf->imsf_multiaddr;
        struct ip_mc_socklist *pmc;
        struct in_device *in_dev;
        struct inet_sock *inet = inet_sk(sk);
@@ -2103,7 +2103,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
 {
        int err, i, count, copycount;
        struct sockaddr_in *psin;
-       u32 addr;
+       __be32 addr;
        struct ip_mc_socklist *pmc;
        struct inet_sock *inet = inet_sk(sk);
        struct ip_sf_socklist *psl;
@@ -2156,7 +2156,7 @@ done:
 /*
  * check if a multicast source filter allows delivery for a given <src,dst,intf>
  */
-int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif)
+int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct ip_mc_socklist *pmc;
@@ -2216,7 +2216,7 @@ void ip_mc_drop_socket(struct sock *sk)
        rtnl_unlock();
 }
 
-int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr, u16 proto)
+int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto)
 {
        struct ip_mc_list *im;
        struct ip_sf_list *psf;
index 07204391d083bb11fb12d6f09576a8102e9cfbbd..96bbe2a0aa1b05e41fcd144e3b11a61b17d854ba 100644 (file)
@@ -39,7 +39,7 @@ int sysctl_local_port_range[2] = { 1024, 4999 };
 int inet_csk_bind_conflict(const struct sock *sk,
                           const struct inet_bind_bucket *tb)
 {
-       const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
+       const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
        struct sock *sk2;
        struct hlist_node *node;
        int reuse = sk->sk_reuse;
@@ -52,7 +52,7 @@ int inet_csk_bind_conflict(const struct sock *sk,
                     sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
                        if (!reuse || !sk2->sk_reuse ||
                            sk2->sk_state == TCP_LISTEN) {
-                               const u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+                               const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
                                if (!sk2_rcv_saddr || !sk_rcv_saddr ||
                                    sk2_rcv_saddr == sk_rcv_saddr)
                                        break;
@@ -342,10 +342,10 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
 
 EXPORT_SYMBOL_GPL(inet_csk_route_req);
 
-static inline u32 inet_synq_hash(const u32 raddr, const u16 rport,
+static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
                                 const u32 rnd, const u16 synq_hsize)
 {
-       return jhash_2words(raddr, (u32)rport, rnd) & (synq_hsize - 1);
+       return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1);
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -356,8 +356,8 @@ static inline u32 inet_synq_hash(const u32 raddr, const u16 rport,
 
 struct request_sock *inet_csk_search_req(const struct sock *sk,
                                         struct request_sock ***prevp,
-                                        const __u16 rport, const __u32 raddr,
-                                        const __u32 laddr)
+                                        const __be16 rport, const __be32 raddr,
+                                        const __be32 laddr)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
index 492858e6faf0140fee625d8f966093c57c141773..77761ac4f7bb0589bc22d89127e3d64abb14c65a 100644 (file)
@@ -36,8 +36,8 @@
 static const struct inet_diag_handler **inet_diag_table;
 
 struct inet_diag_entry {
-       u32 *saddr;
-       u32 *daddr;
+       __be32 *saddr;
+       __be32 *daddr;
        u16 sport;
        u16 dport;
        u16 family;
@@ -294,7 +294,7 @@ out:
        return err;
 }
 
-static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
+static int bitstring_match(const __be32 *a1, const __be32 *a2, int bits)
 {
        int words = bits >> 5;
 
@@ -305,8 +305,8 @@ static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
                        return 0;
        }
        if (bits) {
-               __u32 w1, w2;
-               __u32 mask;
+               __be32 w1, w2;
+               __be32 mask;
 
                w1 = a1[words];
                w2 = a2[words];
@@ -352,7 +352,7 @@ static int inet_diag_bc_run(const void *bc, int len,
                case INET_DIAG_BC_S_COND:
                case INET_DIAG_BC_D_COND: {
                        struct inet_diag_hostcond *cond;
-                       u32 *addr;
+                       __be32 *addr;
 
                        cond = (struct inet_diag_hostcond *)(op + 1);
                        if (cond->port != -1 &&
index fb296c9a7f3fe385aeebbf5d5cc521360335fa8d..244c4f445c7d55779a99fe301152c2241bbcacd7 100644 (file)
@@ -125,7 +125,7 @@ EXPORT_SYMBOL(inet_listen_wlock);
  * wildcarded during the search since they can never be otherwise.
  */
 static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
-                                             const u32 daddr,
+                                             const __be32 daddr,
                                              const unsigned short hnum,
                                              const int dif)
 {
@@ -137,7 +137,7 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
                const struct inet_sock *inet = inet_sk(sk);
 
                if (inet->num == hnum && !ipv6_only_sock(sk)) {
-                       const __u32 rcv_saddr = inet->rcv_saddr;
+                       const __be32 rcv_saddr = inet->rcv_saddr;
                        int score = sk->sk_family == PF_INET ? 1 : 0;
 
                        if (rcv_saddr) {
@@ -163,7 +163,7 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
 
 /* Optimize the common listener case. */
 struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
-                                   const u32 daddr, const unsigned short hnum,
+                                   const __be32 daddr, const unsigned short hnum,
                                    const int dif)
 {
        struct sock *sk = NULL;
@@ -197,11 +197,11 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
 {
        struct inet_hashinfo *hinfo = death_row->hashinfo;
        struct inet_sock *inet = inet_sk(sk);
-       u32 daddr = inet->rcv_saddr;
-       u32 saddr = inet->daddr;
+       __be32 daddr = inet->rcv_saddr;
+       __be32 saddr = inet->daddr;
        int dif = sk->sk_bound_dev_if;
        INET_ADDR_COOKIE(acookie, saddr, daddr)
-       const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+       const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
        unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
        struct sock *sk2;
index a675602ef2953acf12d33096657c8bb09689a4af..2b1a54b59c48c4f2a65d6f8838bbcfd567a71183 100644 (file)
@@ -163,7 +163,7 @@ static void unlink_from_unused(struct inet_peer *p)
        for (u = peer_root; u != peer_avl_empty; ) {            \
                if (daddr == u->v4daddr)                        \
                        break;                                  \
-               if (daddr < u->v4daddr)                         \
+               if ((__force __u32)daddr < (__force __u32)u->v4daddr)   \
                        v = &u->avl_left;                       \
                else                                            \
                        v = &u->avl_right;                      \
@@ -368,7 +368,7 @@ static int cleanup_once(unsigned long ttl)
 }
 
 /* Called with or without local BH being disabled. */
-struct inet_peer *inet_getpeer(__u32 daddr, int create)
+struct inet_peer *inet_getpeer(__be32 daddr, int create)
 {
        struct inet_peer *p, *n;
        struct inet_peer **stack[PEER_MAXDEPTH], ***stackptr;
index 165d72859ddf4cbe7d49bb49ecafb739b0001806..74046efdf875804ee4bd60f20636b2aa1d09e7bf 100644 (file)
@@ -77,9 +77,9 @@ struct ipq {
        struct hlist_node list;
        struct list_head lru_list;      /* lru list member                      */
        u32             user;
-       u32             saddr;
-       u32             daddr;
-       u16             id;
+       __be32          saddr;
+       __be32          daddr;
+       __be16          id;
        u8              protocol;
        u8              last_in;
 #define COMPLETE               4
@@ -123,9 +123,10 @@ static __inline__ void ipq_unlink(struct ipq *ipq)
        write_unlock(&ipfrag_lock);
 }
 
-static unsigned int ipqhashfn(u16 id, u32 saddr, u32 daddr, u8 prot)
+static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
 {
-       return jhash_3words((u32)id << 16 | prot, saddr, daddr,
+       return jhash_3words((__force u32)id << 16 | prot,
+                           (__force u32)saddr, (__force u32)daddr,
                            ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
 }
 
@@ -387,8 +388,8 @@ out_nomem:
 static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
 {
        __be16 id = iph->id;
-       __u32 saddr = iph->saddr;
-       __u32 daddr = iph->daddr;
+       __be32 saddr = iph->saddr;
+       __be32 daddr = iph->daddr;
        __u8 protocol = iph->protocol;
        unsigned int hash;
        struct ipq *qp;
index e7437c0913266cf5431e83bce781ebd22e2bb044..8dabbfc312674bd574df7f69f2a5646146723c18 100644 (file)
@@ -38,7 +38,7 @@
  */
 
 void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
-                           u32 daddr, struct rtable *rt, int is_frag) 
+                           __be32 daddr, struct rtable *rt, int is_frag)
 {
        unsigned char * iph = skb->nh.raw;
 
@@ -57,7 +57,7 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
                        ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
                if (opt->ts_needtime) {
                        struct timeval tv;
-                       __u32 midtime;
+                       __be32 midtime;
                        do_gettimeofday(&tv);
                        midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
                        memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4);
@@ -91,7 +91,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
        unsigned char *sptr, *dptr;
        int soffset, doffset;
        int     optlen;
-       u32     daddr;
+       __be32  daddr;
 
        memset(dopt, 0, sizeof(struct ip_options));
 
@@ -148,7 +148,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
                                        dopt->ts_needtime = 0;
 
                                        if (soffset + 8 <= optlen) {
-                                               __u32 addr;
+                                               __be32 addr;
 
                                                memcpy(&addr, sptr+soffset-1, 4);
                                                if (inet_addr_type(addr) != RTN_LOCAL) {
@@ -165,7 +165,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
        }
        if (sopt->srr) {
                unsigned char * start = sptr+sopt->srr;
-               u32 faddr;
+               __be32 faddr;
 
                optlen  = start[1];
                soffset = start[2];
@@ -362,7 +362,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                goto error;
                        }
                        if (optptr[2] <= optlen) {
-                               __u32 * timeptr = NULL;
+                               __be32 *timeptr = NULL;
                                if (optptr[2]+3 > optptr[1]) {
                                        pp_ptr = optptr + 2;
                                        goto error;
@@ -371,7 +371,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                      case IPOPT_TS_TSONLY:
                                        opt->ts = optptr - iph;
                                        if (skb) 
-                                               timeptr = (__u32*)&optptr[optptr[2]-1];
+                                               timeptr = (__be32*)&optptr[optptr[2]-1];
                                        opt->ts_needtime = 1;
                                        optptr[2] += 4;
                                        break;
@@ -383,7 +383,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                        opt->ts = optptr - iph;
                                        if (skb) {
                                                memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4);
-                                               timeptr = (__u32*)&optptr[optptr[2]+3];
+                                               timeptr = (__be32*)&optptr[optptr[2]+3];
                                        }
                                        opt->ts_needaddr = 1;
                                        opt->ts_needtime = 1;
@@ -396,12 +396,12 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                        }
                                        opt->ts = optptr - iph;
                                        {
-                                               u32 addr;
+                                               __be32 addr;
                                                memcpy(&addr, &optptr[optptr[2]-1], 4);
                                                if (inet_addr_type(addr) == RTN_UNICAST)
                                                        break;
                                                if (skb)
-                                                       timeptr = (__u32*)&optptr[optptr[2]+3];
+                                                       timeptr = (__be32*)&optptr[optptr[2]+3];
                                        }
                                        opt->ts_needtime = 1;
                                        optptr[2] += 8;
@@ -415,10 +415,10 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                }
                                if (timeptr) {
                                        struct timeval tv;
-                                       __u32  midtime;
+                                       __be32  midtime;
                                        do_gettimeofday(&tv);
                                        midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
-                                       memcpy(timeptr, &midtime, sizeof(__u32));
+                                       memcpy(timeptr, &midtime, sizeof(__be32));
                                        opt->is_changed = 1;
                                }
                        } else {
@@ -607,7 +607,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
 {
        struct ip_options *opt = &(IPCB(skb)->opt);
        int srrspace, srrptr;
-       u32 nexthop;
+       __be32 nexthop;
        struct iphdr *iph = skb->nh.iph;
        unsigned char * optptr = skb->nh.raw + opt->srr;
        struct rtable *rt = (struct rtable*)skb->dst;
index 97aee76fb7463d41bdaac364907b37cf4f6b25dd..fc195a44fc2e1800d0ba5e32fedc9019d29562f2 100644 (file)
@@ -118,7 +118,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
  *
  */
 int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
-                         u32 saddr, u32 daddr, struct ip_options *opt)
+                         __be32 saddr, __be32 daddr, struct ip_options *opt)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct rtable *rt = (struct rtable *)skb->dst;
@@ -306,7 +306,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
        /* Make sure we can route this packet. */
        rt = (struct rtable *)__sk_dst_check(sk, 0);
        if (rt == NULL) {
-               u32 daddr;
+               __be32 daddr;
 
                /* Use correct destination address if we have options. */
                daddr = inet->daddr;
@@ -1340,7 +1340,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
                char                    data[40];
        } replyopts;
        struct ipcm_cookie ipc;
-       u32 daddr;
+       __be32 daddr;
        struct rtable *rt = (struct rtable*)skb->dst;
 
        if (ip_options_echo(&replyopts.opt, skb))
index 2d05c4133d3e350b7940c737ecf4055b4f197a24..4b132953bcc2a7ceb3a00d6232f9069d2baf98b5 100644 (file)
@@ -254,7 +254,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
 }
 
 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
-                  u16 port, u32 info, u8 *payload)
+                  __be16 port, u32 info, u8 *payload)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct sock_exterr_skb *serr;
@@ -283,7 +283,7 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
                kfree_skb(skb);
 }
 
-void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
+void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 info)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct sock_exterr_skb *serr;
index 17342430a843bc20781590c79f210564221905b4..2017d36024d48d61816bd52e82bf67f4c196479d 100644 (file)
@@ -183,7 +183,7 @@ out_ok:
 
 static void ipcomp4_err(struct sk_buff *skb, u32 info)
 {
-       u32 spi;
+       __be32 spi;
        struct iphdr *iph = (struct iphdr *)skb->data;
        struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
        struct xfrm_state *x;
index ba49588da2424f70e4d6fa483839db279b30890e..97cfa97c8abbfe8fba81b8bbcbc2ff3960ce3db4 100644 (file)
@@ -462,7 +462,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
        return 0;
 }
 
-static struct mfc_cache *ipmr_cache_find(__u32 origin, __u32 mcastgrp)
+static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp)
 {
        int line=MFC_HASH(mcastgrp,origin);
        struct mfc_cache *c;
@@ -1097,7 +1097,7 @@ static struct notifier_block ip_mr_notifier={
  *     important for multicast video.
  */
  
-static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr)
+static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
 {
        struct iphdr *iph = (struct iphdr *)skb_push(skb,sizeof(struct iphdr));
 
index 87b83813cf2c2f12f4a43fba75385c7e979c16d5..8832eb517d5200355356eb0281b4f4cc6be8cb61 100644 (file)
@@ -115,9 +115,9 @@ static inline void ct_write_unlock_bh(unsigned key)
 /*
  *     Returns hash value for IPVS connection entry
  */
-static unsigned int ip_vs_conn_hashkey(unsigned proto, __u32 addr, __u16 port)
+static unsigned int ip_vs_conn_hashkey(unsigned proto, __be32 addr, __be16 port)
 {
-       return jhash_3words(addr, port, proto, ip_vs_conn_rnd)
+       return jhash_3words((__force u32)addr, (__force u32)port, proto, ip_vs_conn_rnd)
                & IP_VS_CONN_TAB_MASK;
 }
 
@@ -188,7 +188,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
  *     d_addr, d_port: pkt dest address (load balancer)
  */
 static inline struct ip_vs_conn *__ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
 {
        unsigned hash;
        struct ip_vs_conn *cp;
@@ -215,7 +215,7 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
 }
 
 struct ip_vs_conn *ip_vs_conn_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
 {
        struct ip_vs_conn *cp;
 
@@ -234,7 +234,7 @@ struct ip_vs_conn *ip_vs_conn_in_get
 
 /* Get reference to connection template */
 struct ip_vs_conn *ip_vs_ct_in_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
 {
        unsigned hash;
        struct ip_vs_conn *cp;
@@ -274,7 +274,7 @@ struct ip_vs_conn *ip_vs_ct_in_get
  *     d_addr, d_port: pkt dest address (foreign host)
  */
 struct ip_vs_conn *ip_vs_conn_out_get
-(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port)
+(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port)
 {
        unsigned hash;
        struct ip_vs_conn *cp, *ret=NULL;
@@ -324,7 +324,7 @@ void ip_vs_conn_put(struct ip_vs_conn *cp)
 /*
  *     Fill a no_client_port connection with a client port number
  */
-void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __u16 cport)
+void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)
 {
        if (ip_vs_conn_unhash(cp)) {
                spin_lock(&cp->lock);
@@ -508,10 +508,10 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
                /*
                 * Invalidate the connection template
                 */
-               if (ct->vport != 65535) {
+               if (ct->vport != htons(0xffff)) {
                        if (ip_vs_conn_unhash(ct)) {
-                               ct->dport = 65535;
-                               ct->vport = 65535;
+                               ct->dport = htons(0xffff);
+                               ct->vport = htons(0xffff);
                                ct->cport = 0;
                                ip_vs_conn_hash(ct);
                        }
@@ -596,8 +596,8 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
  *     Create a new connection entry and hash it into the ip_vs_conn_tab
  */
 struct ip_vs_conn *
-ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
-              __u32 daddr, __u16 dport, unsigned flags,
+ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport,
+              __be32 daddr, __be16 dport, unsigned flags,
               struct ip_vs_dest *dest)
 {
        struct ip_vs_conn *cp;
index 3f47ad8e1cad1c7f8165b6e5c003a3f919711e4a..6dee03935f786076448f7f1573abc2c806ff12f0 100644 (file)
@@ -209,14 +209,14 @@ int ip_vs_make_skb_writable(struct sk_buff **pskb, int writable_len)
 static struct ip_vs_conn *
 ip_vs_sched_persist(struct ip_vs_service *svc,
                    const struct sk_buff *skb,
-                   __u16 ports[2])
+                   __be16 ports[2])
 {
        struct ip_vs_conn *cp = NULL;
        struct iphdr *iph = skb->nh.iph;
        struct ip_vs_dest *dest;
        struct ip_vs_conn *ct;
-       __u16  dport;    /* destination port to forward */
-       __u32  snet;     /* source network of the client, after masking */
+       __be16  dport;   /* destination port to forward */
+       __be32  snet;    /* source network of the client, after masking */
 
        /* Mask saddr with the netmask to adjust template granularity */
        snet = iph->saddr & svc->netmask;
@@ -383,7 +383,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
        struct ip_vs_conn *cp = NULL;
        struct iphdr *iph = skb->nh.iph;
        struct ip_vs_dest *dest;
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
 
        pptr = skb_header_pointer(skb, iph->ihl*4,
                                  sizeof(_ports), _ports);
@@ -446,7 +446,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
                struct ip_vs_protocol *pp)
 {
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
        struct iphdr *iph = skb->nh.iph;
 
        pptr = skb_header_pointer(skb, iph->ihl*4,
@@ -576,7 +576,7 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
        /* the TCP/UDP port */
        if (IPPROTO_TCP == ciph->protocol || IPPROTO_UDP == ciph->protocol) {
-               __u16 *ports = (void *)ciph + ciph->ihl*4;
+               __be16 *ports = (void *)ciph + ciph->ihl*4;
 
                if (inout)
                        ports[1] = cp->vport;
@@ -775,7 +775,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
                if (sysctl_ip_vs_nat_icmp_send &&
                    (pp->protocol == IPPROTO_TCP ||
                     pp->protocol == IPPROTO_UDP)) {
-                       __u16 _ports[2], *pptr;
+                       __be16 _ports[2], *pptr;
 
                        pptr = skb_header_pointer(skb, ihl,
                                                  sizeof(_ports), _ports);
index 6a28fafe910c2a6ef858a900e688c682d9c470d5..f261616e460218b5379340ba77ba6f4b6ce48506 100644 (file)
@@ -283,7 +283,7 @@ static atomic_t ip_vs_nullsvc_counter = ATOMIC_INIT(0);
  *     Returns hash value for virtual service
  */
 static __inline__ unsigned
-ip_vs_svc_hashkey(unsigned proto, __u32 addr, __u16 port)
+ip_vs_svc_hashkey(unsigned proto, __be32 addr, __be16 port)
 {
        register unsigned porth = ntohs(port);
 
@@ -365,7 +365,7 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc)
  *     Get service by {proto,addr,port} in the service table.
  */
 static __inline__ struct ip_vs_service *
-__ip_vs_service_get(__u16 protocol, __u32 vaddr, __u16 vport)
+__ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport)
 {
        unsigned hash;
        struct ip_vs_service *svc;
@@ -410,7 +410,7 @@ static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark)
 }
 
 struct ip_vs_service *
-ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport)
+ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
 {
        struct ip_vs_service *svc;
 
@@ -480,7 +480,7 @@ __ip_vs_unbind_svc(struct ip_vs_dest *dest)
 /*
  *     Returns hash value for real service
  */
-static __inline__ unsigned ip_vs_rs_hashkey(__u32 addr, __u16 port)
+static __inline__ unsigned ip_vs_rs_hashkey(__be32 addr, __be16 port)
 {
        register unsigned porth = ntohs(port);
 
@@ -531,7 +531,7 @@ static int ip_vs_rs_unhash(struct ip_vs_dest *dest)
  *     Lookup real service by <proto,addr,port> in the real service table.
  */
 struct ip_vs_dest *
-ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport)
+ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport)
 {
        unsigned hash;
        struct ip_vs_dest *dest;
@@ -562,7 +562,7 @@ ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport)
  *     Lookup destination by {addr,port} in the given service
  */
 static struct ip_vs_dest *
-ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
 {
        struct ip_vs_dest *dest;
 
@@ -591,7 +591,7 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
  *  scheduling.
  */
 static struct ip_vs_dest *
-ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
 {
        struct ip_vs_dest *dest, *nxt;
 
@@ -773,8 +773,8 @@ static int
 ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
 {
        struct ip_vs_dest *dest;
-       __u32 daddr = udest->addr;
-       __u16 dport = udest->port;
+       __be32 daddr = udest->addr;
+       __be16 dport = udest->port;
        int ret;
 
        EnterFunction(2);
@@ -879,8 +879,8 @@ static int
 ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
 {
        struct ip_vs_dest *dest;
-       __u32 daddr = udest->addr;
-       __u16 dport = udest->port;
+       __be32 daddr = udest->addr;
+       __be16 dport = udest->port;
 
        EnterFunction(2);
 
@@ -991,8 +991,8 @@ static int
 ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest)
 {
        struct ip_vs_dest *dest;
-       __u32 daddr = udest->addr;
-       __u16 dport = udest->port;
+       __be32 daddr = udest->addr;
+       __be16 dport = udest->port;
 
        EnterFunction(2);
 
index 9fee19c4c6179958f5ea5eb39c4a550e67b314ee..502111fba87284ae6fe11ab944d3720a0b6b8a02 100644 (file)
@@ -66,7 +66,7 @@ struct ip_vs_dh_bucket {
 /*
  *     Returns hash value for IPVS DH entry
  */
-static inline unsigned ip_vs_dh_hashkey(__u32 addr)
+static inline unsigned ip_vs_dh_hashkey(__be32 addr)
 {
        return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK;
 }
@@ -76,7 +76,7 @@ static inline unsigned ip_vs_dh_hashkey(__u32 addr)
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __u32 addr)
+ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr)
 {
        return (tbl[ip_vs_dh_hashkey(addr)]).dest;
 }
index 37fafb1fbcff378b09c0b67449bada0bb5fddc0c..e433cb0ff894b19899f30788ea824b14fa237873 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/ip.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
+#include <asm/unaligned.h>
 
 #include <net/ip_vs.h>
 
@@ -44,8 +45,8 @@
  * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper
  * First port is set to the default port.
  */
-static int ports[IP_VS_APP_MAX_PORTS] = {21, 0};
-module_param_array(ports, int, NULL, 0);
+static unsigned short ports[IP_VS_APP_MAX_PORTS] = {21, 0};
+module_param_array(ports, ushort, NULL, 0);
 MODULE_PARM_DESC(ports, "Ports to monitor for FTP control commands");
 
 
@@ -74,7 +75,7 @@ ip_vs_ftp_done_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
  */
 static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
                                  const char *pattern, size_t plen, char term,
-                                 __u32 *addr, __u16 *port,
+                                 __be32 *addr, __be16 *port,
                                  char **start, char **end)
 {
        unsigned char p[6];
@@ -114,8 +115,8 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
        if (i != 5)
                return -1;
 
-       *addr = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
-       *port = (p[5]<<8) | p[4];
+       *addr = get_unaligned((__be32 *)p);
+       *port = get_unaligned((__be16 *)(p + 4));
        return 1;
 }
 
@@ -140,8 +141,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
        struct tcphdr *th;
        char *data, *data_limit;
        char *start, *end;
-       __u32 from;
-       __u16 port;
+       __be32 from;
+       __be16 port;
        struct ip_vs_conn *n_cp;
        char buf[24];           /* xxx.xxx.xxx.xxx,ppp,ppp\000 */
        unsigned buf_len;
@@ -199,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
                from = n_cp->vaddr;
                port = n_cp->vport;
                sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from),
-                       port&255, (port>>8)&255);
+                       ntohs(port)&255, (ntohs(port)>>8)&255);
                buf_len = strlen(buf);
 
                /*
@@ -243,8 +244,8 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
        struct tcphdr *th;
        char *data, *data_start, *data_limit;
        char *start, *end;
-       __u32 to;
-       __u16 port;
+       __be32 to;
+       __be16 port;
        struct ip_vs_conn *n_cp;
 
        /* no diff required for incoming packets */
@@ -365,12 +366,6 @@ static int __init ip_vs_ftp_init(void)
        for (i=0; i<IP_VS_APP_MAX_PORTS; i++) {
                if (!ports[i])
                        continue;
-               if (ports[i] < 0 || ports[i] > 0xffff) {
-                       IP_VS_WARNING("ip_vs_ftp: Ignoring invalid "
-                                     "configuration port[%d] = %d\n",
-                                     i, ports[i]);
-                       continue;
-               }
                ret = register_ip_vs_app_inc(app, app->protocol, ports[i]);
                if (ret)
                        break;
index 6e5cb92a5c83b114d4751093f13e6691c323a15f..524751e031de5203c12735d0aaa3c588dce675cd 100644 (file)
@@ -87,7 +87,7 @@ static int sysctl_ip_vs_lblc_expiration = 24*60*60*HZ;
  */
 struct ip_vs_lblc_entry {
        struct list_head        list;
-       __u32                   addr;           /* destination IP address */
+       __be32                  addr;           /* destination IP address */
        struct ip_vs_dest       *dest;          /* real server (cache) */
        unsigned long           lastuse;        /* last used time */
 };
@@ -160,7 +160,7 @@ static struct ctl_table_header * sysctl_header;
  *      IP address to a server.
  */
 static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_new(__u32 daddr, struct ip_vs_dest *dest)
+ip_vs_lblc_new(__be32 daddr, struct ip_vs_dest *dest)
 {
        struct ip_vs_lblc_entry *en;
 
@@ -195,7 +195,7 @@ static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
 /*
  *     Returns hash value for IPVS LBLC entry
  */
-static inline unsigned ip_vs_lblc_hashkey(__u32 addr)
+static inline unsigned ip_vs_lblc_hashkey(__be32 addr)
 {
        return (ntohl(addr)*2654435761UL) & IP_VS_LBLC_TAB_MASK;
 }
@@ -234,7 +234,7 @@ ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
  *  Get ip_vs_lblc_entry associated with supplied parameters.
  */
 static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __u32 addr)
+ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
 {
        unsigned hash;
        struct ip_vs_lblc_entry *en;
index 32ba37ba72d855cadbd92979df7edf1734f388ca..08990192b6eccbd5ec9e0abc06ac161b1491432c 100644 (file)
@@ -276,7 +276,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
  */
 struct ip_vs_lblcr_entry {
        struct list_head        list;
-       __u32                   addr;           /* destination IP address */
+       __be32                   addr;           /* destination IP address */
        struct ip_vs_dest_set   set;            /* destination server set */
        unsigned long           lastuse;        /* last used time */
 };
@@ -348,7 +348,7 @@ static struct ctl_table_header * sysctl_header;
  *      new/free a ip_vs_lblcr_entry, which is a mapping of a destination
  *      IP address to a server.
  */
-static inline struct ip_vs_lblcr_entry *ip_vs_lblcr_new(__u32 daddr)
+static inline struct ip_vs_lblcr_entry *ip_vs_lblcr_new(__be32 daddr)
 {
        struct ip_vs_lblcr_entry *en;
 
@@ -381,7 +381,7 @@ static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en)
 /*
  *     Returns hash value for IPVS LBLCR entry
  */
-static inline unsigned ip_vs_lblcr_hashkey(__u32 addr)
+static inline unsigned ip_vs_lblcr_hashkey(__be32 addr)
 {
        return (ntohl(addr)*2654435761UL) & IP_VS_LBLCR_TAB_MASK;
 }
@@ -420,7 +420,7 @@ ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
  *  Get ip_vs_lblcr_entry associated with supplied parameters.
  */
 static inline struct ip_vs_lblcr_entry *
-ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __u32 addr)
+ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr)
 {
        unsigned hash;
        struct ip_vs_lblcr_entry *en;
index 867d4e9c6594c3a62eb70475d6b2c26cfe74c2ca..c4528b5c800d04a257f2d806ed6414378b98ea31 100644 (file)
@@ -176,7 +176,7 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
                        pp->name, NIPQUAD(ih->saddr),
                        NIPQUAD(ih->daddr));
        else {
-               __u16 _ports[2], *pptr
+               __be16 _ports[2], *pptr
 ;
                pptr = skb_header_pointer(skb, offset + ih->ihl*4,
                                          sizeof(_ports), _ports);
index 820e8318d10df06be7412054814838b41e6ad17d..bfe779e74590e14be21af29fa35c6a54551ec231 100644 (file)
@@ -29,7 +29,7 @@ static struct ip_vs_conn *
 tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
 
        pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
        if (pptr == NULL)
@@ -50,7 +50,7 @@ static struct ip_vs_conn *
 tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                 const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
 
        pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
        if (pptr == NULL)
@@ -112,12 +112,12 @@ tcp_conn_schedule(struct sk_buff *skb,
 
 
 static inline void
-tcp_fast_csum_update(struct tcphdr *tcph, u32 oldip, u32 newip,
-                    u16 oldport, u16 newport)
+tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
+                    __be16 oldport, __be16 newport)
 {
        tcph->check =
                ip_vs_check_diff(~oldip, newip,
-                                ip_vs_check_diff(oldport ^ 0xFFFF,
+                                ip_vs_check_diff(oldport ^ htonl(0xFFFF),
                                                  newport, tcph->check));
 }
 
index 90c8166c0ec129a5c84aa449876ef4139bab9e48..54aa7603591f5c3e9091cb341d6ae4aab4bcd96f 100644 (file)
@@ -29,7 +29,7 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
        struct ip_vs_conn *cp;
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
 
        pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
        if (pptr == NULL)
@@ -54,7 +54,7 @@ udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                 const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
        struct ip_vs_conn *cp;
-       __u16 _ports[2], *pptr;
+       __be16 _ports[2], *pptr;
 
        pptr = skb_header_pointer(skb, skb->nh.iph->ihl*4,
                                  sizeof(_ports), _ports);
@@ -117,15 +117,15 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 
 static inline void
-udp_fast_csum_update(struct udphdr *uhdr, u32 oldip, u32 newip,
-                    u16 oldport, u16 newport)
+udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
+                    __be16 oldport, __be16 newport)
 {
        uhdr->check =
                ip_vs_check_diff(~oldip, newip,
-                                ip_vs_check_diff(oldport ^ 0xFFFF,
+                                ip_vs_check_diff(oldport ^ htonl(0xFFFF),
                                                  newport, uhdr->check));
        if (!uhdr->check)
-               uhdr->check = 0xFFFF;
+               uhdr->check = htonl(0xFFFF);
 }
 
 static int
@@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb,
                                                cp->protocol,
                                                (*pskb)->csum);
                if (udph->check == 0)
-                       udph->check = 0xFFFF;
+                       udph->check = htonl(0xFFFF);
                IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
                          pp->name, udph->check,
                          (char*)&(udph->check) - (char*)udph);
index 7775e6cc68be3a4597dc94b4d5ab0fc5e928a614..338668f88fe286a9b9c3cfaa05e32c7c334b01ea 100644 (file)
@@ -63,7 +63,7 @@ struct ip_vs_sh_bucket {
 /*
  *     Returns hash value for IPVS SH entry
  */
-static inline unsigned ip_vs_sh_hashkey(__u32 addr)
+static inline unsigned ip_vs_sh_hashkey(__be32 addr)
 {
        return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK;
 }
@@ -73,7 +73,7 @@ static inline unsigned ip_vs_sh_hashkey(__u32 addr)
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __u32 addr)
+ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr)
 {
        return (tbl[ip_vs_sh_hashkey(addr)]).dest;
 }
index 1bca714bda3d63c244afea44b39a9d26bb0814a9..6ab57d72b615b32ff875a52c0b5ad7a58db3c2d4 100644 (file)
@@ -48,16 +48,16 @@ struct ip_vs_sync_conn {
 
        /* Protocol, addresses and port numbers */
        __u8                    protocol;       /* Which protocol (TCP/UDP) */
-       __u16                   cport;
-       __u16                   vport;
-       __u16                   dport;
-       __u32                   caddr;          /* client address */
-       __u32                   vaddr;          /* virtual address */
-       __u32                   daddr;          /* destination address */
+       __be16                  cport;
+       __be16                  vport;
+       __be16                  dport;
+       __be32                  caddr;          /* client address */
+       __be32                  vaddr;          /* virtual address */
+       __be32                  daddr;          /* destination address */
 
        /* Flags and state transition */
-       __u16                   flags;          /* status flags */
-       __u16                   state;          /* state info */
+       __be16                  flags;          /* status flags */
+       __be16                  state;          /* state info */
 
        /* The sequence options start here */
 };
@@ -464,7 +464,7 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
 static int bind_mcastif_addr(struct socket *sock, char *ifname)
 {
        struct net_device *dev;
-       u32 addr;
+       __be32 addr;
        struct sockaddr_in sin;
 
        if ((dev = __dev_get_by_name(ifname)) == NULL)
index 52c12e9edbbc48a2d6d5bb47f76585a976709ef9..e1f77bd7c9a52a940036c4b8a633c29a74d3e8e2 100644 (file)
@@ -232,7 +232,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
        /* check if it is a connection of no-client-port */
        if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) {
-               __u16 _pt, *p;
+               __be16 _pt, *p;
                p = skb_header_pointer(skb, iph->ihl*4, sizeof(_pt), &_pt);
                if (p == NULL)
                        goto tx_error;
index d25ec4ae09e55ca2d9e0eb6d8dbc38de10b7849c..92b04823e034292328be4cf92c2891ce8e05b9fd 100644 (file)
@@ -60,8 +60,8 @@ struct multipath_dest {
        struct list_head        list;
 
        const struct fib_nh     *nh_info;
-       __u32                   netmask;
-       __u32                   network;
+       __be32                  netmask;
+       __be32                  network;
        unsigned char           prefixlen;
 
        struct rcu_head         rcu;
@@ -76,7 +76,7 @@ struct multipath_route {
        struct list_head        list;
 
        int                     oif;
-       __u32                   gw;
+       __be32                  gw;
        struct list_head        dests;
 
        struct rcu_head         rcu;
@@ -128,8 +128,8 @@ static unsigned char __multipath_lookup_weight(const struct flowi *fl,
 
        /* find state entry for destination */
        list_for_each_entry_rcu(d, &target_route->dests, list) {
-               __u32 targetnetwork = fl->fl4_dst & 
-                       (0xFFFFFFFF >> (32 - d->prefixlen));
+               __be32 targetnetwork = fl->fl4_dst &
+                       inet_make_mask(d->prefixlen);
 
                if ((targetnetwork & d->netmask) == d->network) {
                        weight = d->nh_info->nh_weight;
@@ -217,8 +217,8 @@ static void wrandom_select_route(const struct flowi *flp,
        *rp = decision;
 }
 
-static void wrandom_set_nhinfo(__u32 network,
-                              __u32 netmask,
+static void wrandom_set_nhinfo(__be32 network,
+                              __be32 netmask,
                               unsigned char prefixlen,
                               const struct fib_nh *nh)
 {
index f88347de21a9927a2877b11b0cf31d39979b6763..5ac15379a0cfd15d76c0f7c06145d8da58ba6049 100644 (file)
@@ -128,8 +128,8 @@ EXPORT_SYMBOL(ip_nat_decode_session);
  */
 
 struct ip_rt_info {
-       u_int32_t daddr;
-       u_int32_t saddr;
+       __be32 daddr;
+       __be32 saddr;
        u_int8_t tos;
 };
 
index 85f0d73ebfb4cd19fccfea105819b95dcf7e42f0..17e1a687ab4553e76f53a40029c4f87599d49df9 100644 (file)
@@ -80,7 +80,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
 {
        char *arpptr = (char *)(arphdr + 1);
        char *src_devaddr, *tgt_devaddr;
-       u32 src_ipaddr, tgt_ipaddr;
+       __be32 src_ipaddr, tgt_ipaddr;
        int i, ret;
 
 #define FWINV(bool,invflg) ((bool) ^ !!(arpinfo->invflags & invflg))
index 0a7bd7f04061f89b55f1e2b7a596f5b0b17ca15f..6c7383a8e42b940c355005091876de8b6396c6c7 100644 (file)
@@ -155,11 +155,11 @@ static int help(struct sk_buff **pskb,
                exp->tuple.dst.protonum = IPPROTO_TCP;
                exp->tuple.dst.u.tcp.port = htons(port);
 
-               exp->mask.src.ip = 0xFFFFFFFF;
+               exp->mask.src.ip = htonl(0xFFFFFFFF);
                exp->mask.src.u.tcp.port = 0;
-               exp->mask.dst.ip = 0xFFFFFFFF;
+               exp->mask.dst.ip = htonl(0xFFFFFFFF);
                exp->mask.dst.protonum = 0xFF;
-               exp->mask.dst.u.tcp.port = 0xFFFF;
+               exp->mask.dst.u.tcp.port = htons(0xFFFF);
 
                if (ip_nat_amanda_hook)
                        ret = ip_nat_amanda_hook(pskb, ctinfo, off - dataoff,
index c432b31636091133650ebfea5a04241443e3b59c..143c4668538b40203063e2c6c741b395a0bf3fef 100644 (file)
@@ -149,8 +149,8 @@ static unsigned int ip_conntrack_hash_rnd;
 static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
                            unsigned int size, unsigned int rnd)
 {
-       return (jhash_3words(tuple->src.ip,
-                            (tuple->dst.ip ^ tuple->dst.protonum),
+       return (jhash_3words((__force u32)tuple->src.ip,
+                            ((__force u32)tuple->dst.ip ^ tuple->dst.protonum),
                             (tuple->src.u.all | (tuple->dst.u.all << 16)),
                             rnd) % size);
 }
@@ -1169,9 +1169,9 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
 int ip_ct_port_tuple_to_nfattr(struct sk_buff *skb,
                               const struct ip_conntrack_tuple *tuple)
 {
-       NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t),
+       NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(__be16),
                &tuple->src.u.tcp.port);
-       NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t),
+       NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(__be16),
                &tuple->dst.u.tcp.port);
        return 0;
 
@@ -1186,9 +1186,9 @@ int ip_ct_port_nfattr_to_tuple(struct nfattr *tb[],
                return -EINVAL;
 
        t->src.u.tcp.port =
-               *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
+               *(__be16 *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
        t->dst.u.tcp.port =
-               *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
+               *(__be16 *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
 
        return 0;
 }
index 1d18c863f064d67fbba87db04c01020327c2025c..93dcf960662f66232fbbce45f7131f76fe1a5e34 100644 (file)
@@ -425,8 +425,8 @@ static int help(struct sk_buff **pskb,
        exp->tuple.src.u.tcp.port = 0; /* Don't care. */
        exp->tuple.dst.protonum = IPPROTO_TCP;
        exp->mask = ((struct ip_conntrack_tuple)
-               { { 0xFFFFFFFF, { 0 } },
-                 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+               { { htonl(0xFFFFFFFF), { 0 } },
+                 { htonl(0xFFFFFFFF), { .tcp = { htons(0xFFFF) } }, 0xFF }});
 
        exp->expectfn = NULL;
        exp->flags = 0;
@@ -488,7 +488,7 @@ static int __init ip_conntrack_ftp_init(void)
        for (i = 0; i < ports_c; i++) {
                ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
                ftp[i].tuple.dst.protonum = IPPROTO_TCP;
-               ftp[i].mask.src.u.tcp.port = 0xFFFF;
+               ftp[i].mask.src.u.tcp.port = htons(0xFFFF);
                ftp[i].mask.dst.protonum = 0xFF;
                ftp[i].max_expected = 1;
                ftp[i].timeout = 5 * 60; /* 5 minutes */
index 9a39e2969712701d0ab45b9bb0dcd1d3c6ccf0e6..7b7441202bfd6e14505142a6b0d270c77f73042f 100644 (file)
@@ -49,11 +49,11 @@ MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
 int (*set_h245_addr_hook) (struct sk_buff ** pskb,
                           unsigned char **data, int dataoff,
                           H245_TransportAddress * addr,
-                          u_int32_t ip, u_int16_t port);
+                          __be32 ip, u_int16_t port);
 int (*set_h225_addr_hook) (struct sk_buff ** pskb,
                           unsigned char **data, int dataoff,
                           TransportAddress * addr,
-                          u_int32_t ip, u_int16_t port);
+                          __be32 ip, u_int16_t port);
 int (*set_sig_addr_hook) (struct sk_buff ** pskb,
                          struct ip_conntrack * ct,
                          enum ip_conntrack_info ctinfo,
@@ -209,7 +209,7 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
 
 /****************************************************************************/
 static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr,
-                        u_int32_t * ip, u_int16_t * port)
+                        __be32 * ip, u_int16_t * port)
 {
        unsigned char *p;
 
@@ -232,7 +232,7 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        u_int16_t rtp_port;
        struct ip_conntrack_expect *rtp_exp;
@@ -254,10 +254,10 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
        rtp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
        rtp_exp->tuple.dst.u.udp.port = htons(rtp_port);
        rtp_exp->tuple.dst.protonum = IPPROTO_UDP;
-       rtp_exp->mask.src.ip = 0xFFFFFFFF;
+       rtp_exp->mask.src.ip = htonl(0xFFFFFFFF);
        rtp_exp->mask.src.u.udp.port = 0;
-       rtp_exp->mask.dst.ip = 0xFFFFFFFF;
-       rtp_exp->mask.dst.u.udp.port = 0xFFFF;
+       rtp_exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       rtp_exp->mask.dst.u.udp.port = htons(0xFFFF);
        rtp_exp->mask.dst.protonum = 0xFF;
        rtp_exp->flags = 0;
 
@@ -271,10 +271,10 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
        rtcp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
        rtcp_exp->tuple.dst.u.udp.port = htons(rtp_port + 1);
        rtcp_exp->tuple.dst.protonum = IPPROTO_UDP;
-       rtcp_exp->mask.src.ip = 0xFFFFFFFF;
+       rtcp_exp->mask.src.ip = htonl(0xFFFFFFFF);
        rtcp_exp->mask.src.u.udp.port = 0;
-       rtcp_exp->mask.dst.ip = 0xFFFFFFFF;
-       rtcp_exp->mask.dst.u.udp.port = 0xFFFF;
+       rtcp_exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       rtcp_exp->mask.dst.u.udp.port = htons(0xFFFF);
        rtcp_exp->mask.dst.protonum = 0xFF;
        rtcp_exp->flags = 0;
 
@@ -325,7 +325,7 @@ static int expect_t120(struct sk_buff **pskb,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp = NULL;
 
@@ -342,10 +342,10 @@ static int expect_t120(struct sk_buff **pskb,
        exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = IP_CT_EXPECT_PERMANENT;    /* Accept multiple channels */
 
@@ -626,7 +626,7 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new,
 
 /****************************************************************************/
 int get_h225_addr(unsigned char *data, TransportAddress * addr,
-                 u_int32_t * ip, u_int16_t * port)
+                 __be32 * ip, u_int16_t * port)
 {
        unsigned char *p;
 
@@ -648,7 +648,7 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp = NULL;
 
@@ -665,10 +665,10 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
        exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = 0;
 
@@ -709,7 +709,7 @@ static int expect_callforwarding(struct sk_buff **pskb,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp = NULL;
 
@@ -751,10 +751,10 @@ static int expect_callforwarding(struct sk_buff **pskb,
        exp->tuple.dst.ip = ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = 0;
 
@@ -791,7 +791,7 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret;
        int i;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
 
        DEBUGP("ip_ct_q931: Setup\n");
@@ -1188,7 +1188,7 @@ static unsigned char *get_udp_data(struct sk_buff **pskb, int *datalen)
 
 /****************************************************************************/
 static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
-                                              u_int32_t ip, u_int16_t port)
+                                              __be32 ip, u_int16_t port)
 {
        struct ip_conntrack_expect *exp;
        struct ip_conntrack_tuple tuple;
@@ -1228,7 +1228,7 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        int i;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp;
 
@@ -1251,10 +1251,10 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
        exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = gkrouted_only ? 0xFFFFFFFF : 0;
+       exp->mask.src.ip = gkrouted_only ? htonl(0xFFFFFFFF) : 0;
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = IP_CT_EXPECT_PERMANENT;    /* Accept multiple calls */
 
@@ -1307,7 +1307,7 @@ static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp;
 
@@ -1333,10 +1333,10 @@ static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
        exp->tuple.dst.ip = ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_UDP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = 0;
        exp->expectfn = ip_conntrack_ras_expect;
@@ -1477,7 +1477,7 @@ static int process_arq(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
 
        DEBUGP("ip_ct_ras: ARQ\n");
@@ -1513,7 +1513,7 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp;
 
@@ -1538,10 +1538,10 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
        exp->tuple.dst.ip = ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = IP_CT_EXPECT_PERMANENT;
        exp->expectfn = ip_conntrack_q931_expect;
@@ -1581,7 +1581,7 @@ static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
        struct ip_conntrack_expect *exp = NULL;
 
@@ -1598,10 +1598,10 @@ static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
        exp->tuple.dst.ip = ip;
        exp->tuple.dst.u.tcp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_TCP;
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.tcp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.tcp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.tcp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
        exp->flags = IP_CT_EXPECT_PERMANENT;
        exp->expectfn = ip_conntrack_q931_expect;
index fb0aee691721444ddb8551ca0460d8fcd8cbec1e..a2af5e0c7f9938b25f91618478fd8081220909a6 100644 (file)
@@ -242,10 +242,10 @@ exp_gre(struct ip_conntrack *ct,
        exp_orig->tuple.dst.u.gre.key = callid;
        exp_orig->tuple.dst.protonum = IPPROTO_GRE;
 
-       exp_orig->mask.src.ip = 0xffffffff;
+       exp_orig->mask.src.ip = htonl(0xffffffff);
        exp_orig->mask.src.u.all = 0;
        exp_orig->mask.dst.u.gre.key = htons(0xffff);
-       exp_orig->mask.dst.ip = 0xffffffff;
+       exp_orig->mask.dst.ip = htonl(0xffffffff);
        exp_orig->mask.dst.protonum = 0xff;
 
        exp_orig->master = ct;
index 44889075f3b2df3ed85807fb87cd5bc536e679aa..75f7c3db16196d3fbdd585defabca1771067fe9b 100644 (file)
@@ -218,7 +218,8 @@ static int help(struct sk_buff **pskb,
                                    IPPROTO_TCP }});
                        exp->mask = ((struct ip_conntrack_tuple)
                                { { 0, { 0 } },
-                                 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+                                 { htonl(0xFFFFFFFF),
+                                       { .tcp = { htons(0xFFFF) } }, 0xFF }});
                        exp->expectfn = NULL;
                        exp->flags = 0;
                        if (ip_nat_irc_hook)
@@ -266,7 +267,7 @@ static int __init ip_conntrack_irc_init(void)
                hlpr = &irc_helpers[i];
                hlpr->tuple.src.u.tcp.port = htons(ports[i]);
                hlpr->tuple.dst.protonum = IPPROTO_TCP;
-               hlpr->mask.src.u.tcp.port = 0xFFFF;
+               hlpr->mask.src.u.tcp.port = htons(0xFFFF);
                hlpr->mask.dst.protonum = 0xFF;
                hlpr->max_expected = max_dcc_channels;
                hlpr->timeout = dcc_timeout;
index 3d0b438783db0a71787a87a6815d182025e9f535..a1d6a89f64aa44b140eaa46473562f89508ec7c9 100644 (file)
@@ -48,7 +48,7 @@ static int help(struct sk_buff **pskb,
        struct iphdr *iph = (*pskb)->nh.iph;
        struct rtable *rt = (struct rtable *)(*pskb)->dst;
        struct in_device *in_dev;
-       u_int32_t mask = 0;
+       __be32 mask = 0;
 
        /* we're only interested in locally generated packets */
        if ((*pskb)->sk == NULL)
@@ -78,12 +78,12 @@ static int help(struct sk_buff **pskb,
                goto out;
 
        exp->tuple                = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
-       exp->tuple.src.u.udp.port = ntohs(NMBD_PORT);
+       exp->tuple.src.u.udp.port = htons(NMBD_PORT);
 
        exp->mask.src.ip          = mask;
-       exp->mask.src.u.udp.port  = 0xFFFF;
-       exp->mask.dst.ip          = 0xFFFFFFFF;
-       exp->mask.dst.u.udp.port  = 0xFFFF;
+       exp->mask.src.u.udp.port  = htons(0xFFFF);
+       exp->mask.dst.ip          = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.udp.port  = htons(0xFFFF);
        exp->mask.dst.protonum    = 0xFF;
 
        exp->expectfn             = NULL;
@@ -115,7 +115,7 @@ static struct ip_conntrack_helper helper = {
                .src = {
                        .u = {
                                .udp = {
-                                       .port   = 0xFFFF,
+                                       .port   = __constant_htons(0xFFFF),
                                }
                        }
                },
index 52eddea27e93706b2cca87c1923fd901b6146276..53b6dffea6c2174fcf49f30e7844010c015a3772 100644 (file)
@@ -78,8 +78,8 @@ ctnetlink_dump_tuples_ip(struct sk_buff *skb,
 {
        struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
        
-       NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
-       NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
+       NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(__be32), &tuple->src.ip);
+       NFA_PUT(skb, CTA_IP_V4_DST, sizeof(__be32), &tuple->dst.ip);
 
        NFA_NEST_END(skb, nest_parms);
 
@@ -110,7 +110,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
 static inline int
 ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
-       u_int32_t status = htonl((u_int32_t) ct->status);
+       __be32 status = htonl((u_int32_t) ct->status);
        NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
        return 0;
 
@@ -122,7 +122,7 @@ static inline int
 ctnetlink_dump_timeout(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
        long timeout_l = ct->timeout.expires - jiffies;
-       u_int32_t timeout;
+       __be32 timeout;
 
        if (timeout_l < 0)
                timeout = 0;
@@ -192,13 +192,13 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
 {
        enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
        struct nfattr *nest_count = NFA_NEST(skb, type);
-       u_int32_t tmp;
+       __be32 tmp;
 
        tmp = htonl(ct->counters[dir].packets);
-       NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
+       NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(__be32), &tmp);
 
        tmp = htonl(ct->counters[dir].bytes);
-       NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+       NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(__be32), &tmp);
 
        NFA_NEST_END(skb, nest_count);
 
@@ -215,9 +215,9 @@ nfattr_failure:
 static inline int
 ctnetlink_dump_mark(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
-       u_int32_t mark = htonl(ct->mark);
+       __be32 mark = htonl(ct->mark);
 
-       NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
+       NFA_PUT(skb, CTA_MARK, sizeof(__be32), &mark);
        return 0;
 
 nfattr_failure:
@@ -230,8 +230,8 @@ nfattr_failure:
 static inline int
 ctnetlink_dump_id(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
-       u_int32_t id = htonl(ct->id);
-       NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
+       __be32 id = htonl(ct->id);
+       NFA_PUT(skb, CTA_ID, sizeof(__be32), &id);
        return 0;
 
 nfattr_failure:
@@ -241,9 +241,9 @@ nfattr_failure:
 static inline int
 ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
-       u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
+       __be32 use = htonl(atomic_read(&ct->ct_general.use));
        
-       NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
+       NFA_PUT(skb, CTA_USE, sizeof(__be32), &use);
        return 0;
 
 nfattr_failure:
@@ -457,8 +457,8 @@ out:
 }
 
 static const size_t cta_min_ip[CTA_IP_MAX] = {
-       [CTA_IP_V4_SRC-1]       = sizeof(u_int32_t),
-       [CTA_IP_V4_DST-1]       = sizeof(u_int32_t),
+       [CTA_IP_V4_SRC-1]       = sizeof(__be32),
+       [CTA_IP_V4_DST-1]       = sizeof(__be32),
 };
 
 static inline int
@@ -475,11 +475,11 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
 
        if (!tb[CTA_IP_V4_SRC-1])
                return -EINVAL;
-       tuple->src.ip = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
+       tuple->src.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
 
        if (!tb[CTA_IP_V4_DST-1])
                return -EINVAL;
-       tuple->dst.ip = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
+       tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
 
        DEBUGP("leaving\n");
 
@@ -602,8 +602,8 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
 }
 
 static const size_t cta_min_nat[CTA_NAT_MAX] = {
-       [CTA_NAT_MINIP-1]       = sizeof(u_int32_t),
-       [CTA_NAT_MAXIP-1]       = sizeof(u_int32_t),
+       [CTA_NAT_MINIP-1]       = sizeof(__be32),
+       [CTA_NAT_MAXIP-1]       = sizeof(__be32),
 };
 
 static inline int
@@ -623,12 +623,12 @@ ctnetlink_parse_nat(struct nfattr *nat,
                return -EINVAL;
 
        if (tb[CTA_NAT_MINIP-1])
-               range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
+               range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
 
        if (!tb[CTA_NAT_MAXIP-1])
                range->max_ip = range->min_ip;
        else
-               range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
+               range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
 
        if (range->min_ip)
                range->flags |= IP_NAT_RANGE_MAP_IPS;
@@ -663,11 +663,11 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
 }
 
 static const size_t cta_min[CTA_MAX] = {
-       [CTA_STATUS-1]          = sizeof(u_int32_t),
-       [CTA_TIMEOUT-1]         = sizeof(u_int32_t),
-       [CTA_MARK-1]            = sizeof(u_int32_t),
-       [CTA_USE-1]             = sizeof(u_int32_t),
-       [CTA_ID-1]              = sizeof(u_int32_t)
+       [CTA_STATUS-1]          = sizeof(__be32),
+       [CTA_TIMEOUT-1]         = sizeof(__be32),
+       [CTA_MARK-1]            = sizeof(__be32),
+       [CTA_USE-1]             = sizeof(__be32),
+       [CTA_ID-1]              = sizeof(__be32)
 };
 
 static int
@@ -706,7 +706,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        ct = tuplehash_to_ctrack(h);
        
        if (cda[CTA_ID-1]) {
-               u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
+               u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1]));
                if (ct->id != id) {
                        ip_conntrack_put(ct);
                        return -ENOENT;
@@ -808,7 +808,7 @@ static inline int
 ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[])
 {
        unsigned long d;
-       unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
+       unsigned status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1]));
        d = ct->status ^ status;
 
        if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -903,7 +903,7 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[])
 static inline int
 ctnetlink_change_timeout(struct ip_conntrack *ct, struct nfattr *cda[])
 {
-       u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+       u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
        
        if (!del_timer(&ct->timeout))
                return -ETIME;
@@ -966,7 +966,7 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
 
 #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK-1])
-               ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+               ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
        DEBUGP("all done\n");
@@ -989,7 +989,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
 
        if (!cda[CTA_TIMEOUT-1])
                goto err;
-       ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+       ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
 
        ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
        ct->status |= IPS_CONFIRMED;
@@ -1006,7 +1006,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
 
 #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK-1])
-               ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+               ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
        ct->helper = ip_conntrack_helper_find_get(rtuple);
@@ -1138,8 +1138,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                           const struct ip_conntrack_expect *exp)
 {
        struct ip_conntrack *master = exp->master;
-       u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ);
-       u_int32_t id = htonl(exp->id);
+       __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
+       __be32 id = htonl(exp->id);
 
        if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
                goto nfattr_failure;
@@ -1150,8 +1150,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                                 CTA_EXPECT_MASTER) < 0)
                goto nfattr_failure;
        
-       NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
-       NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
+       NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(__be32), &timeout);
+       NFA_PUT(skb, CTA_EXPECT_ID, sizeof(__be32), &id);
 
        return 0;
        
@@ -1272,8 +1272,8 @@ out:
 }
 
 static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
-       [CTA_EXPECT_TIMEOUT-1]          = sizeof(u_int32_t),
-       [CTA_EXPECT_ID-1]               = sizeof(u_int32_t)
+       [CTA_EXPECT_TIMEOUT-1]          = sizeof(__be32),
+       [CTA_EXPECT_ID-1]               = sizeof(__be32)
 };
 
 static int
@@ -1321,7 +1321,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
                return -ENOENT;
 
        if (cda[CTA_EXPECT_ID-1]) {
-               u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+               __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                if (exp->id != ntohl(id)) {
                        ip_conntrack_expect_put(exp);
                        return -ENOENT;
@@ -1375,8 +1375,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        return -ENOENT;
 
                if (cda[CTA_EXPECT_ID-1]) {
-                       u_int32_t id = 
-                               *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+                       __be32 id =
+                               *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                        if (exp->id != ntohl(id)) {
                                ip_conntrack_expect_put(exp);
                                return -ENOENT;
index 09c40ebe3345f0221d0c32934004a9dc6316706a..295b6fa340dbc021e440c77cd92de51c03291164 100644 (file)
@@ -261,7 +261,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
 static int icmp_tuple_to_nfattr(struct sk_buff *skb,
                                const struct ip_conntrack_tuple *t)
 {
-       NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t),
+       NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(__be16),
                &t->src.u.icmp.id);
        NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
                &t->dst.u.icmp.type);
@@ -287,7 +287,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
        tuple->dst.u.icmp.code =
                        *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
        tuple->src.u.icmp.id =
-                       *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
+                       *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
 
        if (tuple->dst.u.icmp.type >= sizeof(invmap)
            || !invmap[tuple->dst.u.icmp.type])
index b908a4842e186d3cf192dd500bc49e9a509db602..2443322e4128ac3f054fabd442cc80713b71dbc5 100644 (file)
@@ -210,7 +210,7 @@ static int sctp_print_conntrack(struct seq_file *s,
 for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0;        \
        offset < skb->len &&                                            \
        (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch));   \
-       offset += (htons(sch->length) + 3) & ~3, count++)
+       offset += (ntohs(sch->length) + 3) & ~3, count++)
 
 /* Some validity checks to make sure the chunks are fine */
 static int do_basic_checks(struct ip_conntrack *conntrack,
index 03ae9a04cb37c39351735394222f5de4b5b967a8..06e4e8a6dd9f88db85452c556d51058025db3dde 100644 (file)
@@ -519,8 +519,8 @@ static void tcp_sack(const struct sk_buff *skb,
 
        /* Fast path for timestamp-only option */
        if (length == TCPOLEN_TSTAMP_ALIGNED*4
-           && *(__u32 *)ptr ==
-               __constant_ntohl((TCPOPT_NOP << 24) 
+           && *(__be32 *)ptr ==
+               __constant_htonl((TCPOPT_NOP << 24)
                                 | (TCPOPT_NOP << 16)
                                 | (TCPOPT_TIMESTAMP << 8)
                                 | TCPOLEN_TIMESTAMP))
@@ -551,7 +551,7 @@ static void tcp_sack(const struct sk_buff *skb,
                                for (i = 0;
                                     i < (opsize - TCPOLEN_SACK_BASE);
                                     i += TCPOLEN_SACK_PERBLOCK) {
-                                       tmp = ntohl(*((u_int32_t *)(ptr+i)+1));
+                                       tmp = ntohl(*((__be32 *)(ptr+i)+1));
                                        
                                        if (after(tmp, *sack))
                                                *sack = tmp;
index 2893e9c748506627f9abce8cec1a32fb576bdd1a..f4f75995a9e4cb9c4941d5ff06b0bed6a017a4da 100644 (file)
@@ -193,7 +193,7 @@ static int skp_digits_len(const char *dptr, const char *limit, int *shift)
 
 /* Simple ipaddr parser.. */
 static int parse_ipaddr(const char *cp,        const char **endp,
-                       u_int32_t *ipaddr, const char *limit)
+                       __be32 *ipaddr, const char *limit)
 {
        unsigned long int val;
        int i, digit = 0;
@@ -227,7 +227,7 @@ static int parse_ipaddr(const char *cp,     const char **endp,
 static int epaddr_len(const char *dptr, const char *limit, int *shift)
 {
        const char *aux = dptr;
-       u_int32_t ip;
+       __be32 ip;
 
        if (parse_ipaddr(dptr, &dptr, &ip, limit) < 0) {
                DEBUGP("ip: %s parse failed.!\n", dptr);
@@ -302,7 +302,7 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
 static int set_expected_rtp(struct sk_buff **pskb,
                            struct ip_conntrack *ct,
                            enum ip_conntrack_info ctinfo,
-                           u_int32_t ipaddr, u_int16_t port,
+                           __be32 ipaddr, u_int16_t port,
                            const char *dptr)
 {
        struct ip_conntrack_expect *exp;
@@ -319,10 +319,10 @@ static int set_expected_rtp(struct sk_buff **pskb,
        exp->tuple.dst.u.udp.port = htons(port);
        exp->tuple.dst.protonum = IPPROTO_UDP;
 
-       exp->mask.src.ip = 0xFFFFFFFF;
+       exp->mask.src.ip = htonl(0xFFFFFFFF);
        exp->mask.src.u.udp.port = 0;
-       exp->mask.dst.ip = 0xFFFFFFFF;
-       exp->mask.dst.u.udp.port = 0xFFFF;
+       exp->mask.dst.ip = htonl(0xFFFFFFFF);
+       exp->mask.dst.u.udp.port = htons(0xFFFF);
        exp->mask.dst.protonum = 0xFF;
 
        exp->expectfn = NULL;
@@ -349,7 +349,7 @@ static int sip_help(struct sk_buff **pskb,
        const char *dptr;
        int ret = NF_ACCEPT;
        int matchoff, matchlen;
-       u_int32_t ipaddr;
+       __be32 ipaddr;
        u_int16_t port;
 
        /* No Data ? */
@@ -439,7 +439,7 @@ static int __init init(void)
 
                sip[i].tuple.dst.protonum = IPPROTO_UDP;
                sip[i].tuple.src.u.udp.port = htons(ports[i]);
-               sip[i].mask.src.u.udp.port = 0xFFFF;
+               sip[i].mask.src.u.udp.port = htons(0xFFFF);
                sip[i].mask.dst.protonum = 0xFF;
                sip[i].max_expected = 2;
                sip[i].timeout = 3 * 60; /* 3 minutes */
index 7e33d3bed5e3831e8b0a57ed06de304e3144b707..fe0b634dd37761fd15d341698cf45c0158485631 100644 (file)
@@ -70,10 +70,10 @@ static int tftp_help(struct sk_buff **pskb,
                        return NF_DROP;
 
                exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
-               exp->mask.src.ip = 0xffffffff;
+               exp->mask.src.ip = htonl(0xffffffff);
                exp->mask.src.u.udp.port = 0;
-               exp->mask.dst.ip = 0xffffffff;
-               exp->mask.dst.u.udp.port = 0xffff;
+               exp->mask.dst.ip = htonl(0xffffffff);
+               exp->mask.dst.u.udp.port = htons(0xffff);
                exp->mask.dst.protonum = 0xff;
                exp->expectfn = NULL;
                exp->flags = 0;
@@ -129,7 +129,7 @@ static int __init ip_conntrack_tftp_init(void)
                tftp[i].tuple.dst.protonum = IPPROTO_UDP;
                tftp[i].tuple.src.u.udp.port = htons(ports[i]);
                tftp[i].mask.dst.protonum = 0xFF;
-               tftp[i].mask.src.u.udp.port = 0xFFFF;
+               tftp[i].mask.src.u.udp.port = htons(0xFFFF);
                tftp[i].max_expected = 1;
                tftp[i].timeout = 5 * 60; /* 5 minutes */
                tftp[i].me = THIS_MODULE;
index 71f3e09cbc84b456f5488d9f7a49b1ba7a7fa819..4b6260a974085f754278d3a727f76f821ac92b7a 100644 (file)
@@ -82,7 +82,7 @@ static inline unsigned int
 hash_by_src(const struct ip_conntrack_tuple *tuple)
 {
        /* Original src, to ensure we map it consistently if poss. */
-       return jhash_3words(tuple->src.ip, tuple->src.u.all,
+       return jhash_3words((__force u32)tuple->src.ip, tuple->src.u.all,
                            tuple->dst.protonum, 0) % ip_nat_htable_size;
 }
 
@@ -190,7 +190,7 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple,
                    const struct ip_conntrack *conntrack,
                    enum ip_nat_manip_type maniptype)
 {
-       u_int32_t *var_ipp;
+       __be32 *var_ipp;
        /* Host order */
        u_int32_t minip, maxip, j;
 
@@ -217,7 +217,7 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple,
         * like this), even across reboots. */
        minip = ntohl(range->min_ip);
        maxip = ntohl(range->max_ip);
-       j = jhash_2words(tuple->src.ip, tuple->dst.ip, 0);
+       j = jhash_2words((__force u32)tuple->src.ip, (__force u32)tuple->dst.ip, 0);
        *var_ipp = htonl(minip + j % (maxip - minip + 1));
 }
 
@@ -534,9 +534,9 @@ int
 ip_nat_port_range_to_nfattr(struct sk_buff *skb, 
                            const struct ip_nat_range *range)
 {
-       NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(u_int16_t),
+       NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16),
                &range->min.tcp.port);
-       NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(u_int16_t),
+       NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16),
                &range->max.tcp.port);
 
        return 0;
@@ -555,7 +555,7 @@ ip_nat_port_nfattr_to_range(struct nfattr *tb[], struct ip_nat_range *range)
        if (tb[CTA_PROTONAT_PORT_MIN-1]) {
                ret = 1;
                range->min.tcp.port = 
-                       *(u_int16_t *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]);
+                       *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]);
        }
        
        if (!tb[CTA_PROTONAT_PORT_MAX-1]) {
@@ -564,7 +564,7 @@ ip_nat_port_nfattr_to_range(struct nfattr *tb[], struct ip_nat_range *range)
        } else {
                ret = 1;
                range->max.tcp.port = 
-                       *(u_int16_t *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]);
+                       *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]);
        }
 
        return ret;
index 3328fc5c5f500e381daa205f111e9319b686b71f..a71c233d8112b9cb9888ab3e3cff4d71ed9061a3 100644 (file)
@@ -34,7 +34,7 @@ MODULE_DESCRIPTION("ftp NAT helper");
 
 static int
 mangle_rfc959_packet(struct sk_buff **pskb,
-                    u_int32_t newip,
+                    __be32 newip,
                     u_int16_t port,
                     unsigned int matchoff,
                     unsigned int matchlen,
@@ -57,7 +57,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
 /* |1|132.235.1.2|6275| */
 static int
 mangle_eprt_packet(struct sk_buff **pskb,
-                  u_int32_t newip,
+                  __be32 newip,
                   u_int16_t port,
                   unsigned int matchoff,
                   unsigned int matchlen,
@@ -79,7 +79,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
 /* |1|132.235.1.2|6275| */
 static int
 mangle_epsv_packet(struct sk_buff **pskb,
-                  u_int32_t newip,
+                  __be32 newip,
                   u_int16_t port,
                   unsigned int matchoff,
                   unsigned int matchlen,
@@ -98,7 +98,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
                                        matchlen, buffer, strlen(buffer));
 }
 
-static int (*mangle[])(struct sk_buff **, u_int32_t, u_int16_t,
+static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
                     unsigned int,
                     unsigned int,
                     struct ip_conntrack *,
@@ -120,7 +120,7 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
                               struct ip_conntrack_expect *exp,
                               u32 *seq)
 {
-       u_int32_t newip;
+       __be32 newip;
        u_int16_t port;
        int dir = CTINFO2DIR(ctinfo);
        struct ip_conntrack *ct = exp->master;
index 7f6a75984f6c7830ea7a4382869a65a1607d035c..3bf858480558fe26b4c93ef515ebcd9721340e65 100644 (file)
@@ -189,7 +189,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
                                                        datalen, 0));
        } else
                tcph->check = nf_proto_csum_update(*pskb,
-                                                  htons(oldlen) ^ 0xFFFF,
+                                                  htons(oldlen) ^ htons(0xFFFF),
                                                   htons(datalen),
                                                   tcph->check, 1);
 
@@ -267,7 +267,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
                        udph->check = -1;
        } else
                udph->check = nf_proto_csum_update(*pskb,
-                                                  htons(oldlen) ^ 0xFFFF,
+                                                  htons(oldlen) ^ htons(0xFFFF),
                                                   htons(datalen),
                                                   udph->check, 1);
        return 1;
@@ -283,27 +283,25 @@ sack_adjust(struct sk_buff *skb,
            struct ip_nat_seq *natseq)
 {
        while (sackoff < sackend) {
-               struct tcp_sack_block *sack;
-               u_int32_t new_start_seq, new_end_seq;
+               struct tcp_sack_block_wire *sack;
+               __be32 new_start_seq, new_end_seq;
 
                sack = (void *)skb->data + sackoff;
                if (after(ntohl(sack->start_seq) - natseq->offset_before,
                          natseq->correction_pos))
-                       new_start_seq = ntohl(sack->start_seq) 
-                                       - natseq->offset_after;
+                       new_start_seq = htonl(ntohl(sack->start_seq)
+                                       - natseq->offset_after);
                else
-                       new_start_seq = ntohl(sack->start_seq) 
-                                       - natseq->offset_before;
-               new_start_seq = htonl(new_start_seq);
+                       new_start_seq = htonl(ntohl(sack->start_seq)
+                                       - natseq->offset_before);
 
                if (after(ntohl(sack->end_seq) - natseq->offset_before,
                          natseq->correction_pos))
-                       new_end_seq = ntohl(sack->end_seq)
-                                     - natseq->offset_after;
+                       new_end_seq = htonl(ntohl(sack->end_seq)
+                                     - natseq->offset_after);
                else
-                       new_end_seq = ntohl(sack->end_seq)
-                                     - natseq->offset_before;
-               new_end_seq = htonl(new_end_seq);
+                       new_end_seq = htonl(ntohl(sack->end_seq)
+                                     - natseq->offset_before);
 
                DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
                        ntohl(sack->start_seq), new_start_seq,
@@ -375,7 +373,8 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
                  enum ip_conntrack_info ctinfo)
 {
        struct tcphdr *tcph;
-       int dir, newseq, newack;
+       int dir;
+       __be32 newseq, newack;
        struct ip_nat_seq *this_way, *other_way;        
 
        dir = CTINFO2DIR(ctinfo);
@@ -388,17 +387,15 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
 
        tcph = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
        if (after(ntohl(tcph->seq), this_way->correction_pos))
-               newseq = ntohl(tcph->seq) + this_way->offset_after;
+               newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
        else
-               newseq = ntohl(tcph->seq) + this_way->offset_before;
-       newseq = htonl(newseq);
+               newseq = htonl(ntohl(tcph->seq) + this_way->offset_before);
 
        if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
                  other_way->correction_pos))
-               newack = ntohl(tcph->ack_seq) - other_way->offset_after;
+               newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after);
        else
-               newack = ntohl(tcph->ack_seq) - other_way->offset_before;
-       newack = htonl(newack);
+               newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
 
        tcph->check = nf_proto_csum_update(*pskb, ~tcph->seq, newseq,
                                           tcph->check, 0);
index 419b878fb467276ac3f885fdae6f1228118591a3..4a7d34466ee2a9485a6ad3082af4b5eb5a6ad618 100644 (file)
 /****************************************************************************/
 static int set_addr(struct sk_buff **pskb,
                    unsigned char **data, int dataoff,
-                   unsigned int addroff, u_int32_t ip, u_int16_t port)
+                   unsigned int addroff, __be32 ip, u_int16_t port)
 {
        enum ip_conntrack_info ctinfo;
        struct ip_conntrack *ct = ip_conntrack_get(*pskb, &ctinfo);
        struct {
-               u_int32_t ip;
-               u_int16_t port;
+               __be32 ip;
+               __be16 port;
        } __attribute__ ((__packed__)) buf;
        struct tcphdr _tcph, *th;
 
@@ -86,7 +86,7 @@ static int set_addr(struct sk_buff **pskb,
 static int set_h225_addr(struct sk_buff **pskb,
                         unsigned char **data, int dataoff,
                         TransportAddress * addr,
-                        u_int32_t ip, u_int16_t port)
+                        __be32 ip, u_int16_t port)
 {
        return set_addr(pskb, data, dataoff, addr->ipAddress.ip, ip, port);
 }
@@ -95,7 +95,7 @@ static int set_h225_addr(struct sk_buff **pskb,
 static int set_h245_addr(struct sk_buff **pskb,
                         unsigned char **data, int dataoff,
                         H245_TransportAddress * addr,
-                        u_int32_t ip, u_int16_t port)
+                        __be32 ip, u_int16_t port)
 {
        return set_addr(pskb, data, dataoff,
                        addr->unicastAddress.iPAddress.network, ip, port);
@@ -110,7 +110,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
        struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        int i;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
 
        for (i = 0; i < count; i++) {
@@ -164,7 +164,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
 {
        int dir = CTINFO2DIR(ctinfo);
        int i;
-       u_int32_t ip;
+       __be32 ip;
        u_int16_t port;
 
        for (i = 0; i < count; i++) {
@@ -433,7 +433,7 @@ static int nat_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
        struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        u_int16_t nated_port = port;
-       u_int32_t ip;
+       __be32 ip;
 
        /* Set expectations for NAT */
        exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
index 2ff5788071237fa968a74dd1d45c7da512472d1e..329fdcd7d7029aa9724930e94416b2431ff1e669 100644 (file)
@@ -51,7 +51,7 @@
 
 #define IP_NAT_PPTP_VERSION "3.0"
 
-#define REQ_CID(req, off)              (*(u_int16_t *)((char *)(req) + (off)))
+#define REQ_CID(req, off)              (*(__be16 *)((char *)(req) + (off)))
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
index ec50cc295317feac7527e22ba21c5d1972492265..3f6efc13ac74e7a20f9a9ecd9bbd9a1d99e5a2c7 100644 (file)
@@ -67,7 +67,7 @@ icmp_manip_pkt(struct sk_buff **pskb,
 
        hdr = (struct icmphdr *)((*pskb)->data + hdroff);
        hdr->checksum = nf_proto_csum_update(*pskb,
-                                            hdr->un.echo.id ^ 0xFFFF,
+                                            hdr->un.echo.id ^ htons(0xFFFF),
                                             tuple->src.u.icmp.id,
                                             hdr->checksum, 0);
        hdr->un.echo.id = tuple->src.u.icmp.id;
index 72a6307bd2db90dde126cabb647cf738b1b1bf0b..12deb13b93b12aee127377cf316c729cd100f8d8 100644 (file)
@@ -24,7 +24,7 @@ tcp_in_range(const struct ip_conntrack_tuple *tuple,
             const union ip_conntrack_manip_proto *min,
             const union ip_conntrack_manip_proto *max)
 {
-       u_int16_t port;
+       __be16 port;
 
        if (maniptype == IP_NAT_MANIP_SRC)
                port = tuple->src.u.tcp.port;
@@ -42,7 +42,7 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
                 const struct ip_conntrack *conntrack)
 {
        static u_int16_t port;
-       u_int16_t *portptr;
+       __be16 *portptr;
        unsigned int range_size, min, i;
 
        if (maniptype == IP_NAT_MANIP_SRC)
@@ -93,8 +93,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
        struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
        struct tcphdr *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
-       u32 oldip, newip;
-       u16 *portptr, newport, oldport;
+       __be32 oldip, newip;
+       __be16 *portptr, newport, oldport;
        int hdrsize = 8; /* TCP connection tracking guarantees this much */
 
        /* this could be a inner header returned in icmp packet; in such
@@ -130,7 +130,7 @@ tcp_manip_pkt(struct sk_buff **pskb,
                return 1;
 
        hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, hdr->check, 1);
-       hdr->check = nf_proto_csum_update(*pskb, oldport ^ 0xFFFF, newport,
+       hdr->check = nf_proto_csum_update(*pskb, oldport ^ htons(0xFFFF), newport,
                                          hdr->check, 0);
        return 1;
 }
index 5da196ae758cf07e6cb09b8ef2629789ec0c8bb0..4bbec7730d18b3fbbec444aee353bf0b07dc41dd 100644 (file)
@@ -24,7 +24,7 @@ udp_in_range(const struct ip_conntrack_tuple *tuple,
             const union ip_conntrack_manip_proto *min,
             const union ip_conntrack_manip_proto *max)
 {
-       u_int16_t port;
+       __be16 port;
 
        if (maniptype == IP_NAT_MANIP_SRC)
                port = tuple->src.u.udp.port;
@@ -42,7 +42,7 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
                 const struct ip_conntrack *conntrack)
 {
        static u_int16_t port;
-       u_int16_t *portptr;
+       __be16 *portptr;
        unsigned int range_size, min, i;
 
        if (maniptype == IP_NAT_MANIP_SRC)
@@ -91,8 +91,8 @@ udp_manip_pkt(struct sk_buff **pskb,
        struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
        struct udphdr *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
-       u32 oldip, newip;
-       u16 *portptr, newport;
+       __be32 oldip, newip;
+       __be16 *portptr, newport;
 
        if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
                return 0;
@@ -118,7 +118,7 @@ udp_manip_pkt(struct sk_buff **pskb,
                hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip,
                                                  hdr->check, 1);
                hdr->check = nf_proto_csum_update(*pskb,
-                                                 *portptr ^ 0xFFFF, newport,
+                                                 *portptr ^ htons(0xFFFF), newport,
                                                  hdr->check, 0);
                if (!hdr->check)
                        hdr->check = -1;
index 7b703839aa58ca78d4b2a73d40f2516198d714b1..a176aa3031e0f37557d100975e6e9ba92f0df4f0 100644 (file)
@@ -119,7 +119,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
 }
 
 /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
-static void warn_if_extra_mangle(u32 dstip, u32 srcip)
+static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
 {
        static int warned = 0;
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
@@ -205,7 +205,7 @@ alloc_null_binding(struct ip_conntrack *conntrack,
           per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
           Use reply in case it's already been mangled (eg local packet).
        */
-       u_int32_t ip
+       __be32 ip
                = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
                   ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
                   : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
@@ -222,7 +222,7 @@ alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
                              struct ip_nat_info *info,
                              unsigned int hooknum)
 {
-       u_int32_t ip
+       __be32 ip
                = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
                   ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
                   : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
index 6ffba63adca230e17ed1345838e49240879a857a..71fc2730a007d5ccdd9f4069c763d4b8bb8f748c 100644 (file)
@@ -60,8 +60,8 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
        char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
        unsigned int bufflen, dataoff;
-       u_int32_t ip;
-       u_int16_t port;
+       __be32 ip;
+       __be16 port;
 
        dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
 
@@ -159,7 +159,7 @@ static int mangle_content_len(struct sk_buff **pskb,
 static unsigned int mangle_sdp(struct sk_buff **pskb,
                               enum ip_conntrack_info ctinfo,
                               struct ip_conntrack *ct,
-                              u_int32_t newip, u_int16_t port,
+                              __be32 newip, u_int16_t port,
                               const char *dptr)
 {
        char buffer[sizeof("nnn.nnn.nnn.nnn")];
@@ -195,7 +195,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
 {
        struct ip_conntrack *ct = exp->master;
        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-       u_int32_t newip;
+       __be32 newip;
        u_int16_t port;
 
        DEBUGP("ip_nat_sdp():\n");
index 18b7fbdccb6126684f67478fa6a7ba1580445b23..168f45fa1898d2ce1094ed2782916e2b67d88c50 100644 (file)
@@ -1211,7 +1211,7 @@ static int snmp_translate(struct ip_conntrack *ct,
                           struct sk_buff **pskb)
 {
        struct iphdr *iph = (*pskb)->nh.iph;
-       struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
+       struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
        u_int16_t udplen = ntohs(udph->len);
        u_int16_t paylen = udplen - sizeof(struct udphdr);
        int dir = CTINFO2DIR(ctinfo);
index 9c577db62047a7255c4ebed0c317050319290865..021395b674639b19f65975732239321a2fd34750 100644 (file)
@@ -191,7 +191,7 @@ ip_nat_in(unsigned int hooknum,
           int (*okfn)(struct sk_buff *))
 {
        unsigned int ret;
-       u_int32_t daddr = (*pskb)->nh.iph->daddr;
+       __be32 daddr = (*pskb)->nh.iph->daddr;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
        if (ret != NF_DROP && ret != NF_STOLEN
index 41589665fc5ddabc128690199ac266bc98494537..7a29d6e7baa7db35c4d71da25889e0e0b83f3a66 100644 (file)
@@ -52,7 +52,7 @@ struct clusterip_config {
        atomic_t entries;                       /* number of entries/rules
                                                 * referencing us */
 
-       u_int32_t clusterip;                    /* the IP address */
+       __be32 clusterip;                       /* the IP address */
        u_int8_t clustermac[ETH_ALEN];          /* the MAC address */
        struct net_device *dev;                 /* device */
        u_int16_t num_total_nodes;              /* total number of nodes */
@@ -119,7 +119,7 @@ clusterip_config_entry_put(struct clusterip_config *c)
 }
 
 static struct clusterip_config *
-__clusterip_config_find(u_int32_t clusterip)
+__clusterip_config_find(__be32 clusterip)
 {
        struct list_head *pos;
 
@@ -136,7 +136,7 @@ __clusterip_config_find(u_int32_t clusterip)
 }
 
 static inline struct clusterip_config *
-clusterip_config_find_get(u_int32_t clusterip, int entry)
+clusterip_config_find_get(__be32 clusterip, int entry)
 {
        struct clusterip_config *c;
 
@@ -166,7 +166,7 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
 }
 
 static struct clusterip_config *
-clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
+clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
                        struct net_device *dev)
 {
        struct clusterip_config *c;
@@ -387,7 +387,7 @@ checkentry(const char *tablename,
                return 0;
 
        }
-       if (e->ip.dmsk.s_addr != 0xffffffff
+       if (e->ip.dmsk.s_addr != htonl(0xffffffff)
            || e->ip.dst.s_addr == 0) {
                printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
                return 0;
@@ -476,9 +476,9 @@ static struct ipt_target clusterip_tgt = {
 /* hardcoded for 48bit ethernet and 32bit ipv4 addresses */
 struct arp_payload {
        u_int8_t src_hw[ETH_ALEN];
-       u_int32_t src_ip;
+       __be32 src_ip;
        u_int8_t dst_hw[ETH_ALEN];
-       u_int32_t dst_ip;
+       __be32 dst_ip;
 } __attribute__ ((packed));
 
 #ifdef CLUSTERIP_DEBUG
index 23f9c7ebe7ebb5992e57dbc9877b36c068ad9262..12a818a2462f2a8caf9f8fea514d401fd1d7311b 100644 (file)
@@ -28,7 +28,7 @@ static inline int
 set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
        struct iphdr *iph = (*pskb)->nh.iph;
-       u_int16_t oldtos;
+       __be16 oldtos;
 
        if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
                if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -37,7 +37,7 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
                oldtos = iph->tos;
                iph->tos &= ~IPT_ECN_IP_MASK;
                iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
-               iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
+               iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
                                            iph->check);
        } 
        return 1;
@@ -48,7 +48,7 @@ static inline int
 set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
        struct tcphdr _tcph, *tcph;
-       u_int16_t oldval;
+       __be16 oldval;
 
        /* Not enought header? */
        tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
@@ -66,15 +66,15 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
                return 0;
        tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4;
 
-       oldval = ((u_int16_t *)tcph)[6];
+       oldval = ((__be16 *)tcph)[6];
        if (einfo->operation & IPT_ECN_OP_SET_ECE)
                tcph->ece = einfo->proto.tcp.ece;
        if (einfo->operation & IPT_ECN_OP_SET_CWR)
                tcph->cwr = einfo->proto.tcp.cwr;
 
        tcph->check = nf_proto_csum_update((*pskb),
-                                          oldval ^ 0xFFFF,
-                                          ((u_int16_t *)tcph)[6],
+                                          oldval ^ htons(0xFFFF),
+                                          ((__be16 *)tcph)[6],
                                           tcph->check, 0);
        return 1;
 }
index bc65168a3437d7793cf4cfed31daa02e8a5dee9f..3dbfcfac8a84db1b46543ebec8ba58865d12edf0 100644 (file)
@@ -70,7 +70,7 @@ masquerade_target(struct sk_buff **pskb,
        const struct ip_nat_multi_range_compat *mr;
        struct ip_nat_range newrange;
        struct rtable *rt;
-       u_int32_t newsrc;
+       __be32 newsrc;
 
        IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
 
index beb2914225ff6e4db3c64a800678a7f6ed4b35a8..58a88f2271081383c81b25c6c2dca4ff3d7ac010 100644 (file)
@@ -58,7 +58,7 @@ target(struct sk_buff **pskb,
 {
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
-       u_int32_t new_ip, netmask;
+       __be32 new_ip, netmask;
        const struct ip_nat_multi_range_compat *mr = targinfo;
        struct ip_nat_range newrange;
 
index f03d43671c6d1e5278bcd263971aac630abef9bf..c0dcfe9d610cd35baa4df884de2b3a0aed8398a7 100644 (file)
@@ -61,7 +61,7 @@ redirect_target(struct sk_buff **pskb,
 {
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
-       u_int32_t newdst;
+       __be32 newdst;
        const struct ip_nat_multi_range_compat *mr = targinfo;
        struct ip_nat_range newrange;
 
index b81821edd893382a20ca9d996a47209fc90f97ec..fd0c05efed8a088ead0dc29ca1e08a05147a9e22 100644 (file)
@@ -104,8 +104,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        struct iphdr *iph = oldskb->nh.iph;
        struct tcphdr _otcph, *oth, *tcph;
        struct rtable *rt;
-       u_int16_t tmp_port;
-       u_int32_t tmp_addr;
+       __be16 tmp_port;
+       __be32 tmp_addr;
        int needs_ack;
        int hh_len;
 
index efbcb119883244bc3273d9a5f31f263ad232a400..b38b13328d739fce3b3fc3a54d312f772501cffc 100644 (file)
@@ -135,7 +135,8 @@ same_target(struct sk_buff **pskb,
 {
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
-       u_int32_t tmpip, aindex, new_ip;
+       u_int32_t tmpip, aindex;
+       __be32 new_ip;
        const struct ipt_same_info *same = targinfo;
        struct ip_nat_range newrange;
        const struct ip_conntrack_tuple *t;
index 4246c4321e5bb74333bc9a1ed1a3fde6929b6510..108b6b76311fea42b48312a217bdf07e42137191 100644 (file)
@@ -42,7 +42,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
        const struct ipt_tcpmss_info *tcpmssinfo = targinfo;
        struct tcphdr *tcph;
        struct iphdr *iph;
-       u_int16_t tcplen, newtotlen, oldval, newmss;
+       u_int16_t tcplen, newmss;
+       __be16 newtotlen, oldval;
        unsigned int i;
        u_int8_t *opt;
 
@@ -97,7 +98,7 @@ ipt_tcpmss_target(struct sk_buff **pskb,
                        opt[i+3] = (newmss & 0x00ff);
 
                        tcph->check = nf_proto_csum_update(*pskb,
-                                                          htons(oldmss)^0xFFFF,
+                                                          htons(oldmss)^htons(0xFFFF),
                                                           htons(newmss),
                                                           tcph->check, 0);
                        return IPT_CONTINUE;
@@ -126,7 +127,7 @@ ipt_tcpmss_target(struct sk_buff **pskb,
        memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
 
        tcph->check = nf_proto_csum_update(*pskb,
-                                          htons(tcplen) ^ 0xFFFF,
+                                          htons(tcplen) ^ htons(0xFFFF),
                                           htons(tcplen + TCPOLEN_MSS),
                                           tcph->check, 1);
        opt[0] = TCPOPT_MSS;
@@ -134,18 +135,18 @@ ipt_tcpmss_target(struct sk_buff **pskb,
        opt[2] = (newmss & 0xff00) >> 8;
        opt[3] = (newmss & 0x00ff);
 
-       tcph->check = nf_proto_csum_update(*pskb, ~0, *((u_int32_t *)opt),
+       tcph->check = nf_proto_csum_update(*pskb, htonl(~0), *((__be32 *)opt),
                                           tcph->check, 0);
 
-       oldval = ((u_int16_t *)tcph)[6];
+       oldval = ((__be16 *)tcph)[6];
        tcph->doff += TCPOLEN_MSS/4;
        tcph->check = nf_proto_csum_update(*pskb,
-                                          oldval ^ 0xFFFF,
-                                          ((u_int16_t *)tcph)[6],
+                                          oldval ^ htons(0xFFFF),
+                                          ((__be16 *)tcph)[6],
                                           tcph->check, 0);
 
        newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS);
-       iph->check = nf_csum_update(iph->tot_len ^ 0xFFFF,
+       iph->check = nf_csum_update(iph->tot_len ^ htons(0xFFFF),
                                    newtotlen, iph->check);
        iph->tot_len = newtotlen;
        return IPT_CONTINUE;
index 471a4c438b0af123ec174e8e51bcae9b27be7695..6b8b14ccc3d3ff9a0fa0610a0e08df6d274cf2ef 100644 (file)
@@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
 {
        const struct ipt_tos_target_info *tosinfo = targinfo;
        struct iphdr *iph = (*pskb)->nh.iph;
-       u_int16_t oldtos;
+       __be16 oldtos;
 
        if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
                if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -38,7 +38,7 @@ target(struct sk_buff **pskb,
                iph = (*pskb)->nh.iph;
                oldtos = iph->tos;
                iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
-               iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
+               iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
                                            iph->check);
        }
        return IPT_CONTINUE;
index 96e79cc6d0f233dd20cb95b4ffc76336a72d2a7d..ac9517d62af0e1d79a3e81da2142e26578d7e269 100644 (file)
@@ -54,8 +54,8 @@ ipt_ttl_target(struct sk_buff **pskb,
        }
 
        if (new_ttl != iph->ttl) {
-               iph->check = nf_csum_update(ntohs((iph->ttl << 8)) ^ 0xFFFF,
-                                           ntohs(new_ttl << 8),
+               iph->check = nf_csum_update(htons((iph->ttl << 8)) ^ htons(0xFFFF),
+                                           htons(new_ttl << 8),
                                            iph->check);
                iph->ttl = new_ttl;
        }
index 893dae210b0482b324329fffc834974c6e61ec32..7b60eb74788b6671617425cd2c2602ffe79fe956 100644 (file)
@@ -22,7 +22,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("iptables addrtype match");
 
-static inline int match_type(u_int32_t addr, u_int16_t mask)
+static inline int match_type(__be32 addr, u_int16_t mask)
 {
        return !!(mask & (1 << inet_addr_type(addr)));
 }
index 4f73a61aa3dd48e6b2bedb2bd9f851819837842d..33ccdbf8e7940b0f37d6d0fe0557b7e633530554 100644 (file)
@@ -50,11 +50,11 @@ static struct file_operations dl_file_ops;
 /* hash table crap */
 
 struct dsthash_dst {
-       u_int32_t src_ip;
-       u_int32_t dst_ip;
+       __be32 src_ip;
+       __be32 dst_ip;
        /* ports have to be consecutive !!! */
-       u_int16_t src_port;
-       u_int16_t dst_port;
+       __be16 src_port;
+       __be16 dst_port;
 };
 
 struct dsthash_ent {
@@ -106,8 +106,10 @@ static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
 static inline u_int32_t
 hash_dst(const struct ipt_hashlimit_htable *ht, const struct dsthash_dst *dst)
 {
-       return (jhash_3words(dst->dst_ip, (dst->dst_port<<16 | dst->src_port), 
-                            dst->src_ip, ht->rnd) % ht->cfg.size);
+       return (jhash_3words((__force u32)dst->dst_ip,
+                           ((__force u32)dst->dst_port<<16 |
+                            (__force u32)dst->src_port),
+                            (__force u32)dst->src_ip, ht->rnd) % ht->cfg.size);
 }
 
 static inline struct dsthash_ent *
@@ -406,7 +408,7 @@ hashlimit_match(const struct sk_buff *skb,
                dst.src_ip = skb->nh.iph->saddr;
        if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
            ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
-               u_int16_t _ports[2], *ports;
+               __be16 _ports[2], *ports;
 
                switch (skb->nh.iph->protocol) {
                case IPPROTO_TCP:
index 32ae8d7ac50654c41ff3288d4be4a996e3ce4a79..126db44e71a8eaa3fd91fa5ba36f8bbd27db46fe 100644 (file)
@@ -50,11 +50,10 @@ MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files");
 MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files");
 MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files");
 
-
 struct recent_entry {
        struct list_head        list;
        struct list_head        lru_list;
-       u_int32_t               addr;
+       __be32                  addr;
        u_int8_t                ttl;
        u_int8_t                index;
        u_int16_t               nstamps;
@@ -85,17 +84,17 @@ static struct file_operations       recent_fops;
 static u_int32_t hash_rnd;
 static int hash_rnd_initted;
 
-static unsigned int recent_entry_hash(u_int32_t addr)
+static unsigned int recent_entry_hash(__be32 addr)
 {
        if (!hash_rnd_initted) {
                get_random_bytes(&hash_rnd, 4);
                hash_rnd_initted = 1;
        }
-       return jhash_1word(addr, hash_rnd) & (ip_list_hash_size - 1);
+       return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1);
 }
 
 static struct recent_entry *
-recent_entry_lookup(const struct recent_table *table, u_int32_t addr, u_int8_t ttl)
+recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl)
 {
        struct recent_entry *e;
        unsigned int h;
@@ -116,7 +115,7 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
 }
 
 static struct recent_entry *
-recent_entry_init(struct recent_table *t, u_int32_t addr, u_int8_t ttl)
+recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl)
 {
        struct recent_entry *e;
 
@@ -178,7 +177,7 @@ ipt_recent_match(const struct sk_buff *skb,
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
        struct recent_entry *e;
-       u_int32_t addr;
+       __be32 addr;
        u_int8_t ttl;
        int ret = info->invert;
 
@@ -406,7 +405,7 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
        struct recent_table *t = pde->data;
        struct recent_entry *e;
        char buf[sizeof("+255.255.255.255")], *c = buf;
-       u_int32_t addr;
+       __be32 addr;
        int add;
 
        if (size > sizeof(buf))
index 79336cb42527387d9708fcdb9c4bd4105ea66767..e62ea2bb9c0ac422f7c77e39aa7f99eba5fa6e3b 100644 (file)
@@ -131,7 +131,7 @@ ipt_local_hook(unsigned int hook,
 {
        unsigned int ret;
        u_int8_t tos;
-       u_int32_t saddr, daddr;
+       __be32 saddr, daddr;
        unsigned long nfmark;
 
        /* root is playing with raw sockets. */
index 0e935b4c87411ab9e697a5255fe0d8b58f9e8eb3..b430cf2a4f6609db27f6ea137e3f18b0281bd442 100644 (file)
@@ -381,8 +381,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        struct ipcm_cookie ipc;
        struct rtable *rt = NULL;
        int free = 0;
-       u32 daddr;
-       u32 saddr;
+       __be32 daddr;
+       __be32 saddr;
        u8  tos;
        int err;
 
index 20ffe8e88c0f0809d28418743fb81fd5cc43bc02..c41ddba02e9d3553dac0f4aca6d7c5c8b9975584 100644 (file)
@@ -261,6 +261,10 @@ static unsigned int rt_hash_code(u32 daddr, u32 saddr)
                & rt_hash_mask);
 }
 
+#define rt_hash(daddr, saddr, idx) \
+       rt_hash_code((__force u32)(__be32)(daddr),\
+                    (__force u32)(__be32)(saddr) ^ ((idx) << 5))
+
 #ifdef CONFIG_PROC_FS
 struct rt_cache_iter_state {
        int bucket;
@@ -1074,7 +1078,7 @@ static void ip_select_fb_ident(struct iphdr *iph)
        u32 salt;
 
        spin_lock_bh(&ip_fb_id_lock);
-       salt = secure_ip_id(ip_fallback_id ^ iph->daddr);
+       salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
        iph->id = htons(salt & 0xFFFF);
        ip_fallback_id = salt;
        spin_unlock_bh(&ip_fb_id_lock);
@@ -1118,13 +1122,13 @@ static void rt_del(unsigned hash, struct rtable *rt)
        spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
-void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
-                   u32 saddr, struct net_device *dev)
+void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
+                   __be32 saddr, struct net_device *dev)
 {
        int i, k;
        struct in_device *in_dev = in_dev_get(dev);
        struct rtable *rth, **rthp;
-       u32  skeys[2] = { saddr, 0 };
+       __be32  skeys[2] = { saddr, 0 };
        int  ikeys[2] = { dev->ifindex, 0 };
        struct netevent_redirect netevent;
 
@@ -1147,8 +1151,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
 
        for (i = 0; i < 2; i++) {
                for (k = 0; k < 2; k++) {
-                       unsigned hash = rt_hash_code(daddr,
-                                                    skeys[i] ^ (ikeys[k] << 5));
+                       unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]);
 
                        rthp=&rt_hash_table[hash].chain;
 
@@ -1260,9 +1263,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
                        ret = NULL;
                } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
                           rt->u.dst.expires) {
-                       unsigned hash = rt_hash_code(rt->fl.fl4_dst,
-                                                    rt->fl.fl4_src ^
-                                                       (rt->fl.oif << 5));
+                       unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+                                               rt->fl.oif);
 #if RT_CACHE_DEBUG >= 1
                        printk(KERN_DEBUG "ip_rt_advice: redirect to "
                                          "%u.%u.%u.%u/%02x dropped\n",
@@ -1397,15 +1399,15 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
        int i;
        unsigned short old_mtu = ntohs(iph->tot_len);
        struct rtable *rth;
-       u32  skeys[2] = { iph->saddr, 0, };
-       u32  daddr = iph->daddr;
+       __be32  skeys[2] = { iph->saddr, 0, };
+       __be32  daddr = iph->daddr;
        unsigned short est_mtu = 0;
 
        if (ipv4_config.no_pmtu_disc)
                return 0;
 
        for (i = 0; i < 2; i++) {
-               unsigned hash = rt_hash_code(daddr, skeys[i]);
+               unsigned hash = rt_hash(daddr, skeys[i], 0);
 
                rcu_read_lock();
                for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -1530,7 +1532,7 @@ static int ip_rt_bug(struct sk_buff *skb)
 
 void ip_rt_get_source(u8 *addr, struct rtable *rt)
 {
-       u32 src;
+       __be32 src;
        struct fib_result res;
 
        if (rt->fl.iif == 0)
@@ -1596,12 +1598,12 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
         rt->rt_type = res->type;
 }
 
-static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                                u8 tos, struct net_device *dev, int our)
 {
        unsigned hash;
        struct rtable *rth;
-       u32 spec_dst;
+       __be32 spec_dst;
        struct in_device *in_dev = in_dev_get(dev);
        u32 itag = 0;
 
@@ -1665,7 +1667,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
        RT_CACHE_STAT_INC(in_slow_mc);
 
        in_dev_put(in_dev);
-       hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5));
+       hash = rt_hash(daddr, saddr, dev->ifindex);
        return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
 
 e_nobufs:
@@ -1681,8 +1683,8 @@ e_inval:
 static void ip_handle_martian_source(struct net_device *dev,
                                     struct in_device *in_dev,
                                     struct sk_buff *skb,
-                                    u32 daddr,
-                                    u32 saddr) 
+                                    __be32 daddr,
+                                    __be32 saddr)
 {
        RT_CACHE_STAT_INC(in_martian_src);
 #ifdef CONFIG_IP_ROUTE_VERBOSE
@@ -1712,7 +1714,7 @@ static void ip_handle_martian_source(struct net_device *dev,
 static inline int __mkroute_input(struct sk_buff *skb, 
                                  struct fib_result* res, 
                                  struct in_device *in_dev, 
-                                 u32 daddr, u32 saddr, u32 tos, 
+                                 __be32 daddr, __be32 saddr, u32 tos,
                                  struct rtable **result) 
 {
 
@@ -1720,7 +1722,8 @@ static inline int __mkroute_input(struct sk_buff *skb,
        int err;
        struct in_device *out_dev;
        unsigned flags = 0;
-       u32 spec_dst, itag;
+       __be32 spec_dst;
+       u32 itag;
 
        /* get a working reference to the output device */
        out_dev = in_dev_get(FIB_RES_DEV(*res));
@@ -1813,7 +1816,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
                                       struct fib_result* res, 
                                       const struct flowi *fl,
                                       struct in_device *in_dev,
-                                      u32 daddr, u32 saddr, u32 tos)
+                                      __be32 daddr, __be32 saddr, u32 tos)
 {
        struct rtable* rth = NULL;
        int err;
@@ -1830,7 +1833,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
                return err;
 
        /* put it into the cache */
-       hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
+       hash = rt_hash(daddr, saddr, fl->iif);
        return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);   
 }
 
@@ -1838,7 +1841,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
                                   struct fib_result* res, 
                                   const struct flowi *fl,
                                   struct in_device *in_dev,
-                                  u32 daddr, u32 saddr, u32 tos)
+                                  __be32 daddr, __be32 saddr, u32 tos)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
        struct rtable* rth = NULL, *rtres;
@@ -1871,7 +1874,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
                        return err;
 
                /* put it into the cache */
-               hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
+               hash = rt_hash(daddr, saddr, fl->iif);
                err = rt_intern_hash(hash, rth, &rtres);
                if (err)
                        return err;
@@ -1901,7 +1904,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
  *     2. IP spoofing attempts are filtered with 100% of guarantee.
  */
 
-static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                               u8 tos, struct net_device *dev)
 {
        struct fib_result res;
@@ -1920,7 +1923,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
        u32             itag = 0;
        struct rtable * rth;
        unsigned        hash;
-       u32             spec_dst;
+       __be32          spec_dst;
        int             err = -EINVAL;
        int             free_res = 0;
 
@@ -1936,7 +1939,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
        if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
                goto martian_source;
 
-       if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
+       if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
                goto brd_input;
 
        /* Accept zero addresses only to limited broadcast;
@@ -2048,7 +2051,7 @@ local_input:
                rth->rt_flags   &= ~RTCF_LOCAL;
        }
        rth->rt_type    = res.type;
-       hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5));
+       hash = rt_hash(daddr, saddr, fl.iif);
        err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
        goto done;
 
@@ -2087,7 +2090,7 @@ martian_source:
        goto e_inval;
 }
 
-int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
+int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                   u8 tos, struct net_device *dev)
 {
        struct rtable * rth;
@@ -2095,7 +2098,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
        int iif = dev->ifindex;
 
        tos &= IPTOS_RT_MASK;
-       hash = rt_hash_code(daddr, saddr ^ (iif << 5));
+       hash = rt_hash(daddr, saddr, iif);
 
        rcu_read_lock();
        for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2169,7 +2172,7 @@ static inline int __mkroute_output(struct rtable **result,
        if (LOOPBACK(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
                return -EINVAL;
 
-       if (fl->fl4_dst == 0xFFFFFFFF)
+       if (fl->fl4_dst == htonl(0xFFFFFFFF))
                res->type = RTN_BROADCAST;
        else if (MULTICAST(fl->fl4_dst))
                res->type = RTN_MULTICAST;
@@ -2293,8 +2296,7 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
        int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
        unsigned hash;
        if (err == 0) {
-               hash = rt_hash_code(oldflp->fl4_dst, 
-                                   oldflp->fl4_src ^ (oldflp->oif << 5));
+               hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif);
                err = rt_intern_hash(hash, rth, rp);
        }
        
@@ -2336,9 +2338,8 @@ static inline int ip_mkroute_output(struct rtable** rp,
                        if (err != 0)
                                goto cleanup;
 
-                       hash = rt_hash_code(oldflp->fl4_dst, 
-                                           oldflp->fl4_src ^
-                                           (oldflp->oif << 5));
+                       hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
+                                       oldflp->oif);
                        err = rt_intern_hash(hash, rth, rp);
 
                        /* forward hop information to multipath impl. */
@@ -2417,7 +2418,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                 */
 
                if (oldflp->oif == 0
-                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF)) {
+                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
                        /* Special hack: user can direct multicasts
                           and limited broadcast via necessary interface
                           without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2454,7 +2455,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        goto out;       /* Wrong error code */
                }
 
-               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF) {
+               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
                        if (!fl.fl4_src)
                                fl.fl4_src = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_LINK);
@@ -2567,7 +2568,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
        unsigned hash;
        struct rtable *rth;
 
-       hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5));
+       hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif);
 
        rcu_read_lock_bh();
        for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2660,11 +2661,11 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
        if (rt->rt_flags & RTCF_NOTIFY)
                r->rtm_flags |= RTM_F_NOTIFY;
 
-       NLA_PUT_U32(skb, RTA_DST, rt->rt_dst);
+       NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
 
        if (rt->fl.fl4_src) {
                r->rtm_src_len = 32;
-               NLA_PUT_U32(skb, RTA_SRC, rt->fl.fl4_src);
+               NLA_PUT_BE32(skb, RTA_SRC, rt->fl.fl4_src);
        }
        if (rt->u.dst.dev)
                NLA_PUT_U32(skb, RTA_OIF, rt->u.dst.dev->ifindex);
@@ -2677,12 +2678,12 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
 #endif
        if (rt->fl.iif)
-               NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_spec_dst);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
        else if (rt->rt_src != rt->fl.fl4_src)
-               NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_src);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
 
        if (rt->rt_dst != rt->rt_gateway)
-               NLA_PUT_U32(skb, RTA_GATEWAY, rt->rt_gateway);
+               NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
 
        if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
                goto nla_put_failure;
@@ -2706,7 +2707,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 
        if (rt->fl.iif) {
 #ifdef CONFIG_IP_MROUTE
-               u32 dst = rt->rt_dst;
+               __be32 dst = rt->rt_dst;
 
                if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
                    ipv4_devconf.mc_forwarding) {
@@ -2740,7 +2741,9 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
        struct rtmsg *rtm;
        struct nlattr *tb[RTA_MAX+1];
        struct rtable *rt = NULL;
-       u32 dst, src, iif;
+       __be32 dst = 0;
+       __be32 src = 0;
+       u32 iif;
        int err;
        struct sk_buff *skb;
 
@@ -2765,8 +2768,8 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
        skb->nh.iph->protocol = IPPROTO_ICMP;
        skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
 
-       src = tb[RTA_SRC] ? nla_get_u32(tb[RTA_SRC]) : 0;
-       dst = tb[RTA_DST] ? nla_get_u32(tb[RTA_DST]) : 0;
+       src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
+       dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
        iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
 
        if (iif) {
index b3def0df14fb81df0057ca9b5c61839f5e432601..3f884cea14ff439651b876ffce4f351289640681 100644 (file)
@@ -935,7 +935,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked;
-       struct tcp_sack_block *sp = (struct tcp_sack_block *)(ptr+2);
+       struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2);
        int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
        int reord = tp->packets_out;
        int prior_fackets;
@@ -2239,13 +2239,12 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
        return acked;
 }
 
-static u32 tcp_usrtt(const struct sk_buff *skb)
+static u32 tcp_usrtt(struct timeval *tv)
 {
-       struct timeval tv, now;
+       struct timeval now;
 
        do_gettimeofday(&now);
-       skb_get_timestamp(skb, &tv);
-       return (now.tv_sec - tv.tv_sec) * 1000000 + (now.tv_usec - tv.tv_usec);
+       return (now.tv_sec - tv->tv_sec) * 1000000 + (now.tv_usec - tv->tv_usec);
 }
 
 /* Remove acknowledged frames from the retransmission queue. */
@@ -2260,6 +2259,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
        u32 pkts_acked = 0;
        void (*rtt_sample)(struct sock *sk, u32 usrtt)
                = icsk->icsk_ca_ops->rtt_sample;
+       struct timeval tv;
 
        while ((skb = skb_peek(&sk->sk_write_queue)) &&
               skb != sk->sk_send_head) {
@@ -2308,8 +2308,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
                                seq_rtt = -1;
                        } else if (seq_rtt < 0) {
                                seq_rtt = now - scb->when;
-                               if (rtt_sample)
-                                       (*rtt_sample)(sk, tcp_usrtt(skb));
+                               skb_get_timestamp(skb, &tv);
                        }
                        if (sacked & TCPCB_SACKED_ACKED)
                                tp->sacked_out -= tcp_skb_pcount(skb);
@@ -2322,8 +2321,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
                        }
                } else if (seq_rtt < 0) {
                        seq_rtt = now - scb->when;
-                       if (rtt_sample)
-                               (*rtt_sample)(sk, tcp_usrtt(skb));
+                       skb_get_timestamp(skb, &tv);
                }
                tcp_dec_pcount_approx(&tp->fackets_out, skb);
                tcp_packets_out_dec(tp, skb);
@@ -2335,6 +2333,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
        if (acked&FLAG_ACKED) {
                tcp_ack_update_rtt(sk, acked, seq_rtt);
                tcp_ack_packets_out(sk, tp);
+               if (rtt_sample && !(acked & FLAG_RETRANS_DATA_ACKED))
+                       (*rtt_sample)(sk, tcp_usrtt(&tv));
 
                if (icsk->icsk_ca_ops->pkts_acked)
                        icsk->icsk_ca_ops->pkts_acked(sk, pkts_acked);
@@ -2629,7 +2629,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
                                switch(opcode) {
                                case TCPOPT_MSS:
                                        if(opsize==TCPOLEN_MSS && th->syn && !estab) {
-                                               u16 in_mss = ntohs(get_unaligned((__u16 *)ptr));
+                                               u16 in_mss = ntohs(get_unaligned((__be16 *)ptr));
                                                if (in_mss) {
                                                        if (opt_rx->user_mss && opt_rx->user_mss < in_mss)
                                                                in_mss = opt_rx->user_mss;
@@ -2657,8 +2657,8 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
                                                if ((estab && opt_rx->tstamp_ok) ||
                                                    (!estab && sysctl_tcp_timestamps)) {
                                                        opt_rx->saw_tstamp = 1;
-                                                       opt_rx->rcv_tsval = ntohl(get_unaligned((__u32 *)ptr));
-                                                       opt_rx->rcv_tsecr = ntohl(get_unaligned((__u32 *)(ptr+4)));
+                                                       opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
+                                                       opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
                                                }
                                        }
                                        break;
@@ -2695,8 +2695,8 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
                return 0;
        } else if (tp->rx_opt.tstamp_ok &&
                   th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) {
-               __u32 *ptr = (__u32 *)(th + 1);
-               if (*ptr == ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+               __be32 *ptr = (__be32 *)(th + 1);
+               if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
                                  | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
                        tp->rx_opt.saw_tstamp = 1;
                        ++ptr;
@@ -3911,10 +3911,10 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 
                /* Check timestamp */
                if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) {
-                       __u32 *ptr = (__u32 *)(th + 1);
+                       __be32 *ptr = (__be32 *)(th + 1);
 
                        /* No? Slow path! */
-                       if (*ptr != ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+                       if (*ptr != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
                                          | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
                                goto slow_path;
 
index 39b1798560824e3ba85dfae375a0a22ca37f135b..c83938b8fcb1201ddf403c6423cd83790397595b 100644 (file)
@@ -159,7 +159,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        struct tcp_sock *tp = tcp_sk(sk);
        struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
        struct rtable *rt;
-       u32 daddr, nexthop;
+       __be32 daddr, nexthop;
        int tmp;
        int err;
 
@@ -734,8 +734,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        struct inet_request_sock *ireq;
        struct tcp_options_received tmp_opt;
        struct request_sock *req;
-       __u32 saddr = skb->nh.iph->saddr;
-       __u32 daddr = skb->nh.iph->daddr;
+       __be32 saddr = skb->nh.iph->saddr;
+       __be32 daddr = skb->nh.iph->daddr;
        __u32 isn = TCP_SKB_CB(skb)->when;
        struct dst_entry *dst = NULL;
 #ifdef CONFIG_SYN_COOKIES
@@ -1763,7 +1763,7 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
 
 static void get_timewait4_sock(struct inet_timewait_sock *tw, char *tmpbuf, int i)
 {
-       unsigned int dest, src;
+       __be32 dest, src;
        __u16 destp, srcp;
        int ttd = tw->tw_ttd - jiffies;
 
index 308fb7e071c56faaebbf742e6fc07cc0ecbabdc8..f0ebaf0e21cbf7276119f8c3886e0d2c1971e139 100644 (file)
@@ -31,8 +31,6 @@
  *   Hung Hing Lun, Mike <hlhung3i@gmail.com>
  * SourceForge project page:
  *   http://tcp-lp-mod.sourceforge.net/
- *
- * Version: $Id: tcp_lp.c,v 1.24 2006/09/05 20:22:53 hswong3i Exp $
  */
 
 #include <linux/module.h>
@@ -164,7 +162,7 @@ static u32 tcp_lp_remote_hz_estimator(struct sock *sk)
 
  out:
        /* record time for successful remote HZ calc */
-       if (rhz > 0)
+       if ((rhz >> 6) > 0)
                lp->flag |= LP_VALID_RHZ;
        else
                lp->flag &= ~LP_VALID_RHZ;
index 061edfae0c29df44ada4e1aec6d055a21eaf7f38..9a253faefc81c9c2f95d82e9cbb7878d677b25a1 100644 (file)
@@ -269,7 +269,7 @@ static u16 tcp_select_window(struct sock *sk)
        return new_win;
 }
 
-static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
+static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
                                         __u32 tstamp)
 {
        if (tp->rx_opt.tstamp_ok) {
@@ -305,7 +305,7 @@ static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
  * MAX_SYN_SIZE to match the new maximum number of options that you
  * can generate.
  */
-static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
                                  int offer_wscale, int wscale, __u32 tstamp,
                                  __u32 ts_recent)
 {
@@ -424,7 +424,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        th->dest                = inet->dport;
        th->seq                 = htonl(tcb->seq);
        th->ack_seq             = htonl(tp->rcv_nxt);
-       *(((__u16 *)th) + 6)    = htons(((tcp_header_size >> 2) << 12) |
+       *(((__be16 *)th) + 6)   = htons(((tcp_header_size >> 2) << 12) |
                                        tcb->flags);
 
        if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
@@ -445,7 +445,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        }
 
        if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
-               tcp_syn_build_options((__u32 *)(th + 1),
+               tcp_syn_build_options((__be32 *)(th + 1),
                                      tcp_advertise_mss(sk),
                                      (sysctl_flags & SYSCTL_FLAG_TSTAMPS),
                                      (sysctl_flags & SYSCTL_FLAG_SACK),
@@ -454,7 +454,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
                                      tcb->when,
                                      tp->rx_opt.ts_recent);
        } else {
-               tcp_build_and_update_options((__u32 *)(th + 1),
+               tcp_build_and_update_options((__be32 *)(th + 1),
                                             tp, tcb->when);
                TCP_ECN_send(sk, tp, skb, tcp_header_size);
        }
@@ -2070,7 +2070,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        th->window = htons(req->rcv_wnd);
 
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
-       tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
+       tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
                              ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale,
                              TCP_SKB_CB(skb)->when,
                              req->ts_recent);
index 77e265d7bb8f8a7a795e552aef4214570a40a7da..6d6142f9c478baa8c85dcf1d174a5a88f66d783a 100644 (file)
@@ -243,8 +243,8 @@ static void udp_v4_unhash(struct sock *sk)
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
-static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport,
-                                         u32 daddr, u16 dport, int dif)
+static struct sock *udp_v4_lookup_longway(__be32 saddr, __be16 sport,
+                                         __be32 daddr, __be16 dport, int dif)
 {
        struct sock *sk, *result = NULL;
        struct hlist_node *node;
@@ -288,8 +288,8 @@ static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport,
        return result;
 }
 
-static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
-                                            u32 daddr, u16 dport, int dif)
+static __inline__ struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
+                                            __be32 daddr, __be16 dport, int dif)
 {
        struct sock *sk;
 
@@ -302,8 +302,8 @@ static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
 }
 
 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
-                                            u16 loc_port, u32 loc_addr,
-                                            u16 rmt_port, u32 rmt_addr,
+                                            __be16 loc_port, __be32 loc_addr,
+                                            __be16 rmt_port, __be32 rmt_addr,
                                             int dif)
 {
        struct hlist_node *node;
@@ -498,7 +498,7 @@ out:
 }
 
 
-static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base)
+static unsigned short udp_check(struct udphdr *uh, int len, __be32 saddr, __be32 daddr, unsigned long base)
 {
        return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
 }
@@ -513,8 +513,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        struct rtable *rt = NULL;
        int free = 0;
        int connected = 0;
-       u32 daddr, faddr, saddr;
-       u16 dport;
+       __be32 daddr, faddr, saddr;
+       __be16 dport;
        u8  tos;
        int err;
        int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
@@ -931,7 +931,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
        int iphlen, len;
   
        __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr);
-       __u32 *udpdata32 = (__u32 *)udpdata;
+       __be32 *udpdata32 = (__be32 *)udpdata;
        __u16 encap_type = up->encap_type;
 
        /* if we're overly short, let UDP handle it */
@@ -1080,7 +1080,7 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
  *     so we don't need to lock the hashes.
  */
 static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
-                                u32 saddr, u32 daddr)
+                                __be32 saddr, __be32 daddr)
 {
        struct sock *sk;
        int dif;
@@ -1121,7 +1121,7 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
  * including udp header and folding it to skb->csum.
  */
 static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
-                            unsigned short ulen, u32 saddr, u32 daddr)
+                            unsigned short ulen, __be32 saddr, __be32 daddr)
 {
        if (uh->check == 0) {
                skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1146,8 +1146,8 @@ int udp_rcv(struct sk_buff *skb)
        struct udphdr *uh;
        unsigned short ulen;
        struct rtable *rt = (struct rtable*)skb->dst;
-       u32 saddr = skb->nh.iph->saddr;
-       u32 daddr = skb->nh.iph->daddr;
+       __be32 saddr = skb->nh.iph->saddr;
+       __be32 daddr = skb->nh.iph->daddr;
        int len = skb->len;
 
        /*
@@ -1563,8 +1563,8 @@ void udp_proc_unregister(struct udp_seq_afinfo *afinfo)
 static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
 {
        struct inet_sock *inet = inet_sk(sp);
-       unsigned int dest = inet->daddr;
-       unsigned int src  = inet->rcv_saddr;
+       __be32 dest = inet->daddr;
+       __be32 src  = inet->rcv_saddr;
        __u16 destp       = ntohs(inet->dport);
        __u16 srcp        = ntohs(inet->sport);
 
index 040e8475f295c1cefcb3350099f57feb08308d56..8655d038364cba364880f8cb9595e94708fe14db 100644 (file)
@@ -23,7 +23,7 @@ int xfrm4_rcv(struct sk_buff *skb)
 
 EXPORT_SYMBOL(xfrm4_rcv);
 
-static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
        switch (nexthdr) {
        case IPPROTO_IPIP:
@@ -55,7 +55,7 @@ drop:
 int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 {
        int err;
-       u32 spi, seq;
+       __be32 spi, seq;
        struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
        struct xfrm_state *x;
        int xfrm_nr = 0;
index eabcd27b176730d83e42ce599e28c7a7e3407e0f..7a7a00147e55c7d63758d2d3bad84884d3b1a4c6 100644 (file)
@@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
 
                case IPPROTO_ESP:
                        if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
-                               u32 *ehdr = (u32 *)xprth;
+                               __be32 *ehdr = (__be32 *)xprth;
 
                                fl->fl_ipsec_spi = ehdr[0];
                        }
@@ -229,7 +229,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
 
                case IPPROTO_AH:
                        if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
-                               u32 *ah_hdr = (u32*)xprth;
+                               __be32 *ah_hdr = (__be32*)xprth;
 
                                fl->fl_ipsec_spi = ah_hdr[1];
                        }
@@ -237,7 +237,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
 
                case IPPROTO_COMP:
                        if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
-                               u16 *ipcomp_hdr = (u16 *)xprth;
+                               __be16 *ipcomp_hdr = (__be16 *)xprth;
 
                                fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
                        }
index fe2034494d0854e7f22d9e40147c4dc16b76bdc4..3cc3df0c6ece97420f79c2a84efca31e1b8cbcd1 100644 (file)
@@ -29,9 +29,9 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
        x->sel.daddr.a4 = fl->fl4_dst;
        x->sel.saddr.a4 = fl->fl4_src;
        x->sel.dport = xfrm_flowi_dport(fl);
-       x->sel.dport_mask = ~0;
+       x->sel.dport_mask = htons(0xffff);
        x->sel.sport = xfrm_flowi_sport(fl);
-       x->sel.sport_mask = ~0;
+       x->sel.sport_mask = htons(0xffff);
        x->sel.prefixlen_d = 32;
        x->sel.prefixlen_s = 32;
        x->sel.proto = fl->proto;
index c18676352397cc11a7adc0961262117681b79ab8..e03c33b2465bc72415c8e27dce382db233959a69 100644 (file)
@@ -1258,8 +1258,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
 {
        const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
        const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
-       u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
-       u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+       __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
+       __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
        int sk_ipv6only = ipv6_only_sock(sk);
        int sk2_ipv6only = inet_v6_ipv6only(sk2);
        int addr_type = ipv6_addr_type(sk_rcv_saddr6);
index bf6e8aff19d4f2fa62a5e18641548bd0a4e2a60b..e94eccb99707991c80409ebce8a157e1beaba3e7 100644 (file)
@@ -246,7 +246,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct sock *sk = sock->sk;
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
-       __u32 v4addr = 0;
+       __be32 v4addr = 0;
        unsigned short snum;
        int addr_type = 0;
        int err = 0;
index d2f3fc990bfaa2a535bf4cbf2f6a4590b66abb71..8accd1fbeeda96d9201d7cbd1f71cd85344c8b51 100644 (file)
@@ -64,7 +64,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
 {
        struct sock *sk;
        const struct hlist_node *node;
-       const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
+       const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
        /* Optimize here for direct hit, only listening connections can
         * have wildcards anyways.
         */
@@ -82,7 +82,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
        sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
                const struct inet_timewait_sock *tw = inet_twsk(sk);
 
-               if(*((__u32 *)&(tw->tw_dport))  == ports        &&
+               if(*((__portpair *)&(tw->tw_dport))     == ports        &&
                   sk->sk_family                == PF_INET6) {
                        const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
@@ -171,7 +171,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
        const struct in6_addr *daddr = &np->rcv_saddr;
        const struct in6_addr *saddr = &np->daddr;
        const int dif = sk->sk_bound_dev_if;
-       const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+       const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
        const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
                                                inet->dport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
@@ -188,7 +188,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
 
                tw = inet_twsk(sk2);
 
-               if(*((__u32 *)&(tw->tw_dport)) == ports          &&
+               if(*((__portpair *)&(tw->tw_dport)) == ports             &&
                   sk2->sk_family              == PF_INET6       &&
                   ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)     &&
                   ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
index ad9c6e824e629e02c8c37a4e17c94ea5dab50b35..a2860e35efd7d68ee67d3839e4b064aa6f3a574e 100644 (file)
@@ -178,7 +178,7 @@ out_ok:
 static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                                int type, int code, int offset, __u32 info)
 {
-       u32 spi;
+       __be32 spi;
        struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
        struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset);
        struct xfrm_state *x;
@@ -234,7 +234,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
 {
        int err = 0;
        struct xfrm_state *t = NULL;
-       u32 spi;
+       __be32 spi;
 
        spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
        if (spi)
index 4f3bb7fcc8b509ac71615e7a8c0f543d95349854..de6b91981b30611b0cd63ea8d14a304b34387c27 100644 (file)
@@ -123,6 +123,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
        struct ipv6hdr *ipv6h;
        struct inet6_protocol *ops;
 
+       if (!(features & NETIF_F_HW_CSUM))
+               features &= ~NETIF_F_SG;
+
        if (unlikely(skb_shinfo(skb)->gso_type &
                     ~(SKB_GSO_UDP |
                       SKB_GSO_DODGY |
index 2546fc9f0a78b14559fc380b365665ad02afaed6..3b6575478fcc381aae64ee2c0d7b2b791d5f1846 100644 (file)
@@ -1237,7 +1237,7 @@ process:
 
        skb->dev = NULL;
 
-       bh_lock_sock(sk);
+       bh_lock_sock_nested(sk);
        ret = 0;
        if (!sock_owned_by_user(sk)) {
 #ifdef CONFIG_NET_DMA
index a40a057890133b13fec3d16fa66d80021f174c96..5c8b7a5688003dcf7c21ca0923be689b42d7cd40 100644 (file)
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
-int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
 {
        int err;
-       u32 seq;
+       __be32 seq;
        struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
        struct xfrm_state *x;
        int xfrm_nr = 0;
index 711bfafb2472dfd5fda8dc04c19a7f536355e64c..9ddaa9d41539fe23ec7df3d5cc9059749348e4ec 100644 (file)
@@ -29,9 +29,9 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
        ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
        ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
        x->sel.dport = xfrm_flowi_dport(fl);
-       x->sel.dport_mask = ~0;
+       x->sel.dport_mask = htons(0xffff);
        x->sel.sport = xfrm_flowi_sport(fl);
-       x->sel.sport_mask = ~0;
+       x->sel.sport_mask = htons(0xffff);
        x->sel.prefixlen_d = 128;
        x->sel.prefixlen_s = 128;
        x->sel.proto = fl->proto;
index 59685ee8f700d9690180560180320064912ceda8..7af227bb1551477730b13097e3490241bebc154b 100644 (file)
@@ -258,7 +258,7 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 static int xfrm6_tunnel_rcv(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = skb->nh.ipv6h;
-       u32 spi;
+       __be32 spi;
 
        spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
        return xfrm6_rcv_spi(skb, spi);
index 17699eeb64d78274481bca74888dfc41313fb548..7e1aea89ef05b60709fcb37e1f5ec531303f0359 100644 (file)
@@ -132,13 +132,14 @@ static void irda_disconnect_indication(void *instance, void *sap,
 
        /* Prevent race conditions with irda_release() and irda_shutdown() */
        if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) {
+               lock_sock(sk);
                sk->sk_state     = TCP_CLOSE;
                sk->sk_err       = ECONNRESET;
                sk->sk_shutdown |= SEND_SHUTDOWN;
 
                sk->sk_state_change(sk);
-               /* Uh-oh... Should use sock_orphan ? */
-                sock_set_flag(sk, SOCK_DEAD);
+                sock_orphan(sk);
+               release_sock(sk);
 
                /* Close our TSAP.
                 * If we leave it open, IrLMP put it back into the list of
@@ -308,7 +309,8 @@ static void irda_connect_response(struct irda_sock *self)
 
        IRDA_ASSERT(self != NULL, return;);
 
-       skb = alloc_skb(64, GFP_ATOMIC);
+       skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+                       GFP_ATOMIC);
        if (skb == NULL) {
                IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
                           __FUNCTION__);
@@ -1212,6 +1214,7 @@ static int irda_release(struct socket *sock)
         if (sk == NULL)
                return 0;
 
+       lock_sock(sk);
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
        sk->sk_state_change(sk);
@@ -1221,6 +1224,7 @@ static int irda_release(struct socket *sock)
 
        sock_orphan(sk);
        sock->sk   = NULL;
+       release_sock(sk);
 
        /* Purge queues (see sock_init_data()) */
        skb_queue_purge(&sk->sk_receive_queue);
@@ -1353,6 +1357,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
        IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(!sock_error(sk), return -1;);
 
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
@@ -1405,6 +1410,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
        IRDA_ASSERT(self != NULL, return -1;);
+       IRDA_ASSERT(!sock_error(sk), return -1;);
 
        if (sock->flags & __SO_ACCEPTCON)
                return(-EINVAL);
index 959874b6451f00cf9edf4ad23343a1cd07e73b5b..c8e0d89ee11fd3e9443767fd875d05372453bcc5 100644 (file)
@@ -81,7 +81,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self,
        
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -115,7 +115,7 @@ static int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
         if (!userdata) {
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
                
index 61128aa05b4015c9fb85027bd1cc870b34a9beec..415cf4eec23b8e86ac69597dd0ffae6e3f953f44 100644 (file)
@@ -345,10 +345,11 @@ static void iriap_disconnect_request(struct iriap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
 
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
        if (tx_skb == NULL) {
-               IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n", 
-                       __FUNCTION__, 64);
+               IRDA_DEBUG(0,
+                          "%s(), Could not allocate an sk_buff of length %d\n",
+                          __FUNCTION__, LMP_MAX_HEADER);
                return;
        }
 
@@ -701,7 +702,7 @@ void iriap_send_ack(struct iriap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
 
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(LMP_MAX_HEADER + 1, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
index da17395df05adab0dab896b9e64f59ff1d4f62ab..99b18dc7a0b7e3b26f8fcd52d7c30bebee14d69d 100644 (file)
@@ -365,7 +365,7 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
 
        switch (event) {
        case IAP_LM_CONNECT_INDICATION:
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
                if (tx_skb == NULL) {
                        IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
                        return;
index 7dd0a2fe1d20dfac9a51b60fc4724c64e8c38b84..9b962f247714f5ec71c02f4b1e9822cd1531955e 100644 (file)
@@ -636,7 +636,8 @@ void irlan_get_provider_info(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = alloc_skb(64, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER,
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -668,7 +669,10 @@ void irlan_open_data_channel(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = alloc_skb(64, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3") +
+                       IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "DIRECT"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -704,7 +708,9 @@ void irlan_close_data_channel(struct irlan_cb *self)
        if (self->client.tsap_ctrl == NULL)
                return;
 
-       skb = alloc_skb(64, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -715,7 +721,7 @@ void irlan_close_data_channel(struct irlan_cb *self)
        
        /* Build frame */
        frame[0] = CMD_CLOSE_DATA_CHAN;
-       frame[1] = 0x01; /* Two parameters */
+       frame[1] = 0x01; /* One parameter */
 
        irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
 
@@ -739,7 +745,11 @@ static void irlan_open_unicast_addr(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);       
        
-       skb = alloc_skb(128, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -777,7 +787,12 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = alloc_skb(128, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BROADCAST") +
+                       /* We may waste one byte here...*/
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -816,7 +831,12 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = alloc_skb(128, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +
+                       /* We may waste one byte here...*/
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "NONE"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
        
@@ -856,7 +876,12 @@ static void irlan_get_unicast_addr(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = alloc_skb(128, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_OPERATION",
+                                                  "DYNAMIC"),
+                       GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -891,7 +916,10 @@ void irlan_get_media_char(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = alloc_skb(64, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3"),
+                       GFP_ATOMIC);
+
        if (!skb)
                return;
 
index 9c0df86044d7d4aaeabe71c0be10667dda723a10..58efde919667fb1a18c7ee0436aa53c6c1185f09 100644 (file)
@@ -296,7 +296,14 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = alloc_skb(128, GFP_ATOMIC);
+       skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
+                       /* Bigger param length comes from CMD_GET_MEDIA_CHAR */
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BORADCAST") +
+                       IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +
+                       IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "HOSTED"),
+                       GFP_ATOMIC);
+
        if (!skb)
                return;
 
@@ -354,8 +361,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
                } else
                        skb->data[1] = 0x02; /* 2 parameters */
                irlan_insert_byte_param(skb, "DATA_CHAN", self->stsap_sel_data);
-               irlan_insert_array_param(skb, "RECONNECT_KEY", "LINUX RULES!",
-                                        12);
+               irlan_insert_string_param(skb, "RECONNECT_KEY", "LINUX RULES!");
                break;
        case CMD_FILTER_OPERATION:
                irlan_filter_request(self, skb);
index ccb983bf0f4a222a8f848a0a8162b327c5d01d8e..dba349c832d02454b8451bbd02aa1935e23d9e15 100644 (file)
@@ -117,7 +117,9 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
        /* Allocate frame */
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct snrm_frame) +
+                          IRLAP_NEGOCIATION_PARAMS_LEN,
+                          GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -136,7 +138,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
         *  If we are establishing a connection then insert QoS paramerters
         */
        if (qos) {
-               skb_put(tx_skb, 9); /* 21 left */
+               skb_put(tx_skb, 9); /* 25 left */
                frame->saddr = cpu_to_le32(self->saddr);
                frame->daddr = cpu_to_le32(self->daddr);
 
@@ -210,7 +212,9 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
        /* Allocate frame */
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct ua_frame) +
+                          IRLAP_NEGOCIATION_PARAMS_LEN,
+                          GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -245,23 +249,23 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
 void irlap_send_dm_frame( struct irlap_cb *self)
 {
        struct sk_buff *tx_skb = NULL;
-       __u8 *frame;
+       struct dm_frame *frame;
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
-       tx_skb = alloc_skb(32, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct dm_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
-       frame = skb_put(tx_skb, 2);
+       frame = (struct dm_frame *)skb_put(tx_skb, 2);
 
        if (self->state == LAP_NDM)
-               frame[0] = CBROADCAST;
+               frame->caddr = CBROADCAST;
        else
-               frame[0] = self->caddr;
+               frame->caddr = self->caddr;
 
-       frame[1] = DM_RSP | PF_BIT;
+       frame->control = DM_RSP | PF_BIT;
 
        irlap_queue_xmit(self, tx_skb);
 }
@@ -275,21 +279,21 @@ void irlap_send_dm_frame( struct irlap_cb *self)
 void irlap_send_disc_frame(struct irlap_cb *self)
 {
        struct sk_buff *tx_skb = NULL;
-       __u8 *frame;
+       struct disc_frame *frame;
 
        IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
-       tx_skb = alloc_skb(16, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct disc_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
-       frame = skb_put(tx_skb, 2);
+       frame = (struct disc_frame *)skb_put(tx_skb, 2);
 
-       frame[0] = self->caddr | CMD_FRAME;
-       frame[1] = DISC_CMD | PF_BIT;
+       frame->caddr = self->caddr | CMD_FRAME;
+       frame->control = DISC_CMD | PF_BIT;
 
        irlap_queue_xmit(self, tx_skb);
 }
@@ -315,7 +319,8 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
        IRDA_ASSERT(discovery != NULL, return;);
 
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct xid_frame) + IRLAP_DISCOVERY_INFO_LEN,
+                          GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -573,18 +578,18 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
 void irlap_send_rr_frame(struct irlap_cb *self, int command)
 {
        struct sk_buff *tx_skb;
-       __u8 *frame;
+       struct rr_frame *frame;
 
-       tx_skb = alloc_skb(16, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct rr_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
-       frame = skb_put(tx_skb, 2);
+       frame = (struct rr_frame *)skb_put(tx_skb, 2);
 
-       frame[0] = self->caddr;
-       frame[0] |= (command) ? CMD_FRAME : 0;
+       frame->caddr = self->caddr;
+       frame->caddr |= (command) ? CMD_FRAME : 0;
 
-       frame[1] = RR | PF_BIT | (self->vr << 5);
+       frame->control = RR | PF_BIT | (self->vr << 5);
 
        irlap_queue_xmit(self, tx_skb);
 }
@@ -598,16 +603,16 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command)
 void irlap_send_rd_frame(struct irlap_cb *self)
 {
        struct sk_buff *tx_skb;
-       __u8 *frame;
+       struct rd_frame *frame;
 
-       tx_skb = alloc_skb(16, GFP_ATOMIC);
+       tx_skb = alloc_skb(sizeof(struct rd_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
-       frame = skb_put(tx_skb, 2);
+       frame = (struct rd_frame *)skb_put(tx_skb, 2);
 
-       frame[0] = self->caddr;
-       frame[1] = RD_RSP | PF_BIT;
+       frame->caddr = self->caddr;
+       frame->caddr = RD_RSP | PF_BIT;
 
        irlap_queue_xmit(self, tx_skb);
 }
@@ -1214,7 +1219,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
        struct test_frame *frame;
        __u8 *info;
 
-       tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC);
+       tx_skb = alloc_skb(cmd->len + sizeof(struct test_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
index c440913dee1468358e76cdef1fef6eeaad3d22a5..5073261b9d0c875d7884cf280866f6b324bb36ba 100644 (file)
@@ -392,7 +392,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
 
        /* Any userdata? */
        if (tx_skb == NULL) {
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
index 42acf1cde737d4e0b992df9a6d469311385db410..3c2e70b77df16375952f1c0bc889f298a588e8a9 100644 (file)
@@ -804,12 +804,12 @@ static inline void irttp_give_credit(struct tsap_cb *self)
                   self->send_credit, self->avail_credit, self->remote_credit);
 
        /* Give credit to peer */
-       tx_skb = alloc_skb(64, GFP_ATOMIC);
+       tx_skb = alloc_skb(TTP_MAX_HEADER, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
        /* Reserve space for LMP, and LAP header */
-       skb_reserve(tx_skb, self->max_header_size);
+       skb_reserve(tx_skb, LMP_MAX_HEADER);
 
        /*
         *  Since we can transmit and receive frames concurrently,
@@ -1093,7 +1093,8 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
 
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+                                  GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -1341,7 +1342,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
 
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+                                  GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -1540,14 +1542,14 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
 
        if (!userdata) {
                struct sk_buff *tx_skb;
-               tx_skb = alloc_skb(64, GFP_ATOMIC);
+               tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
                /*
                 *  Reserve space for MUX and LAP header
                 */
-               skb_reserve(tx_skb, TTP_MAX_HEADER);
+               skb_reserve(tx_skb, LMP_MAX_HEADER);
 
                userdata = tx_skb;
        }
index 83b443ddc72f57c044e7f00f961f7e41d83fc148..ff98e70b0931f8e74cfc14c3d9b9337b50c12e41 100644 (file)
@@ -2140,7 +2140,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
        xp->selector.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
        if (xp->selector.sport)
-               xp->selector.sport_mask = ~0;
+               xp->selector.sport_mask = htons(0xffff);
 
        sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], 
        pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);
@@ -2153,7 +2153,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 
        xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
        if (xp->selector.dport)
-               xp->selector.dport_mask = ~0;
+               xp->selector.dport_mask = htons(0xffff);
 
        sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
        if (sec_ctx != NULL) {
@@ -2243,7 +2243,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
        sel.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
        if (sel.sport)
-               sel.sport_mask = ~0;
+               sel.sport_mask = htons(0xffff);
 
        sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], 
        pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
@@ -2251,7 +2251,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
        sel.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
        if (sel.dport)
-               sel.dport_mask = ~0;
+               sel.dport_mask = htons(0xffff);
 
        sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
        memset(&tmp, 0, sizeof(struct xfrm_policy));
index 4125a55f469f197051963a3f0c3e1f8057084c95..a6ce1d6d5c59a00fced6f8ff82b290c0d3615719 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/socket.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
+#include <linux/audit.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
@@ -162,8 +163,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
        int nla_a_rem;
        int nla_b_rem;
 
-       if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
-           !info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
+       if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
            !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
                return -EINVAL;
 
@@ -344,8 +344,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
        int ret_val;
        struct cipso_v4_doi *doi_def = NULL;
 
-       if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
-           !info->attrs[NLBL_CIPSOV4_A_TAGLST])
+       if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
                return -EINVAL;
 
        doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
@@ -381,21 +380,40 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
 
 {
        int ret_val = -EINVAL;
-       u32 map_type;
+       u32 type;
+       u32 doi;
+       const char *type_str = "(unknown)";
+       struct audit_buffer *audit_buf;
+       struct netlbl_audit audit_info;
 
-       if (!info->attrs[NLBL_CIPSOV4_A_MTYPE])
+       if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
+           !info->attrs[NLBL_CIPSOV4_A_MTYPE])
                return -EINVAL;
 
-       map_type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
-       switch (map_type) {
+       doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
+       type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
+       switch (type) {
        case CIPSO_V4_MAP_STD:
+               type_str = "std";
                ret_val = netlbl_cipsov4_add_std(info);
                break;
        case CIPSO_V4_MAP_PASS:
+               type_str = "pass";
                ret_val = netlbl_cipsov4_add_pass(info);
                break;
        }
 
+       audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
+                                             &audit_info);
+       audit_log_format(audit_buf,
+                        " cipso_doi=%u cipso_type=%s res=%u",
+                        doi,
+                        type_str,
+                        ret_val == 0 ? 1 : 0);
+       audit_log_end(audit_buf);
+
        return ret_val;
 }
 
@@ -653,12 +671,27 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
 static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
 {
        int ret_val = -EINVAL;
-       u32 doi;
+       u32 doi = 0;
+       struct audit_buffer *audit_buf;
+       struct netlbl_audit audit_info;
 
-       if (info->attrs[NLBL_CIPSOV4_A_DOI]) {
-               doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
-               ret_val = cipso_v4_doi_remove(doi, netlbl_cipsov4_doi_free);
-       }
+       if (!info->attrs[NLBL_CIPSOV4_A_DOI])
+               return -EINVAL;
+
+       doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
+       ret_val = cipso_v4_doi_remove(doi,
+                                     &audit_info,
+                                     netlbl_cipsov4_doi_free);
+
+       audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
+                                             &audit_info);
+       audit_log_format(audit_buf,
+                        " cipso_doi=%u res=%u",
+                        doi,
+                        ret_val == 0 ? 1 : 0);
+       audit_log_end(audit_buf);
 
        return ret_val;
 }
index f56d7a8ac7b758dacd86f83442569263b2df9253..af4371d3b459d63bcd756dd5b4f250229198494d 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
+#include <linux/audit.h>
 #include <net/netlabel.h>
 #include <net/cipso_ipv4.h>
 #include <asm/bug.h>
 
 #include "netlabel_mgmt.h"
 #include "netlabel_domainhash.h"
+#include "netlabel_user.h"
 
 struct netlbl_domhsh_tbl {
        struct list_head *tbl;
@@ -186,6 +188,7 @@ int netlbl_domhsh_init(u32 size)
 /**
  * netlbl_domhsh_add - Adds a entry to the domain hash table
  * @entry: the entry to add
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new entry to the domain hash table and handles any updates to the
@@ -193,10 +196,13 @@ int netlbl_domhsh_init(u32 size)
  * negative on failure.
  *
  */
-int netlbl_domhsh_add(struct netlbl_dom_map *entry)
+int netlbl_domhsh_add(struct netlbl_dom_map *entry,
+                     struct netlbl_audit *audit_info)
 {
        int ret_val;
        u32 bkt;
+       struct audit_buffer *audit_buf;
+       char *audit_domain;
 
        switch (entry->type) {
        case NETLBL_NLTYPE_UNLABELED:
@@ -236,6 +242,26 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
                spin_unlock(&netlbl_domhsh_def_lock);
        } else
                ret_val = -EINVAL;
+
+       if (entry->domain != NULL)
+               audit_domain = entry->domain;
+       else
+               audit_domain = "(default)";
+       audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
+       audit_log_format(audit_buf, " nlbl_domain=%s", audit_domain);
+       switch (entry->type) {
+       case NETLBL_NLTYPE_UNLABELED:
+               audit_log_format(audit_buf, " nlbl_protocol=unlbl");
+               break;
+       case NETLBL_NLTYPE_CIPSOV4:
+               audit_log_format(audit_buf,
+                                " nlbl_protocol=cipsov4 cipso_doi=%u",
+                                entry->type_def.cipsov4->doi);
+               break;
+       }
+       audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
+       audit_log_end(audit_buf);
+
        rcu_read_unlock();
 
        if (ret_val != 0) {
@@ -254,6 +280,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
 /**
  * netlbl_domhsh_add_default - Adds the default entry to the domain hash table
  * @entry: the entry to add
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new default entry to the domain hash table and handles any updates
@@ -261,14 +288,16 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
  * negative on failure.
  *
  */
-int netlbl_domhsh_add_default(struct netlbl_dom_map *entry)
+int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
+                             struct netlbl_audit *audit_info)
 {
-       return netlbl_domhsh_add(entry);
+       return netlbl_domhsh_add(entry, audit_info);
 }
 
 /**
  * netlbl_domhsh_remove - Removes an entry from the domain hash table
  * @domain: the domain to remove
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Removes an entry from the domain hash table and handles any updates to the
@@ -276,10 +305,12 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry)
  * negative on failure.
  *
  */
-int netlbl_domhsh_remove(const char *domain)
+int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
 {
        int ret_val = -ENOENT;
        struct netlbl_dom_map *entry;
+       struct audit_buffer *audit_buf;
+       char *audit_domain;
 
        rcu_read_lock();
        if (domain != NULL)
@@ -316,6 +347,18 @@ int netlbl_domhsh_remove(const char *domain)
                        ret_val = -ENOENT;
                spin_unlock(&netlbl_domhsh_def_lock);
        }
+
+       if (entry->domain != NULL)
+               audit_domain = entry->domain;
+       else
+               audit_domain = "(default)";
+       audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
+       audit_log_format(audit_buf,
+                        " nlbl_domain=%s res=%u",
+                        audit_domain,
+                        ret_val == 0 ? 1 : 0);
+       audit_log_end(audit_buf);
+
        if (ret_val == 0)
                call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
 
@@ -326,6 +369,7 @@ remove_return:
 
 /**
  * netlbl_domhsh_remove_default - Removes the default entry from the table
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Removes/resets the default entry for the domain hash table and handles any
@@ -333,9 +377,9 @@ remove_return:
  * success, non-zero on failure.
  *
  */
-int netlbl_domhsh_remove_default(void)
+int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info)
 {
-       return netlbl_domhsh_remove(NULL);
+       return netlbl_domhsh_remove(NULL, audit_info);
 }
 
 /**
index 02af72a7877cb94d553a39998356d6a69d12d156..3689956c34363242007d300b0865c53a0da867d5 100644 (file)
@@ -57,9 +57,11 @@ struct netlbl_dom_map {
 int netlbl_domhsh_init(u32 size);
 
 /* Manipulate the domain hash table */
-int netlbl_domhsh_add(struct netlbl_dom_map *entry);
-int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);
-int netlbl_domhsh_remove_default(void);
+int netlbl_domhsh_add(struct netlbl_dom_map *entry,
+                     struct netlbl_audit *audit_info);
+int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
+                             struct netlbl_audit *audit_info);
+int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
 int netlbl_domhsh_walk(u32 *skip_bkt,
                     u32 *skip_chain,
index 8626c9f678ebbb3434bed1c3e2977e5c28d18824..53c9079ad2c3932404df4fae1cdc5d47fb413dc4 100644 (file)
@@ -87,11 +87,14 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
        struct netlbl_dom_map *entry = NULL;
        size_t tmp_size;
        u32 tmp_val;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
            !info->attrs[NLBL_MGMT_A_PROTOCOL])
                goto add_failure;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (entry == NULL) {
                ret_val = -ENOMEM;
@@ -108,7 +111,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
 
        switch (entry->type) {
        case NETLBL_NLTYPE_UNLABELED:
-               ret_val = netlbl_domhsh_add(entry);
+               ret_val = netlbl_domhsh_add(entry, &audit_info);
                break;
        case NETLBL_NLTYPE_CIPSOV4:
                if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -125,7 +128,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
                        rcu_read_unlock();
                        goto add_failure;
                }
-               ret_val = netlbl_domhsh_add(entry);
+               ret_val = netlbl_domhsh_add(entry, &audit_info);
                rcu_read_unlock();
                break;
        default:
@@ -156,12 +159,15 @@ add_failure:
 static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
 {
        char *domain;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_DOMAIN])
                return -EINVAL;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]);
-       return netlbl_domhsh_remove(domain);
+       return netlbl_domhsh_remove(domain, &audit_info);
 }
 
 /**
@@ -264,10 +270,13 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
        int ret_val = -EINVAL;
        struct netlbl_dom_map *entry = NULL;
        u32 tmp_val;
+       struct netlbl_audit audit_info;
 
        if (!info->attrs[NLBL_MGMT_A_PROTOCOL])
                goto adddef_failure;
 
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (entry == NULL) {
                ret_val = -ENOMEM;
@@ -277,7 +286,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
 
        switch (entry->type) {
        case NETLBL_NLTYPE_UNLABELED:
-               ret_val = netlbl_domhsh_add_default(entry);
+               ret_val = netlbl_domhsh_add_default(entry, &audit_info);
                break;
        case NETLBL_NLTYPE_CIPSOV4:
                if (!info->attrs[NLBL_MGMT_A_CV4DOI])
@@ -294,7 +303,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
                        rcu_read_unlock();
                        goto adddef_failure;
                }
-               ret_val = netlbl_domhsh_add_default(entry);
+               ret_val = netlbl_domhsh_add_default(entry, &audit_info);
                rcu_read_unlock();
                break;
        default:
@@ -322,7 +331,11 @@ adddef_failure:
  */
 static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
 {
-       return netlbl_domhsh_remove_default();
+       struct netlbl_audit audit_info;
+
+       netlbl_netlink_auditinfo(skb, &audit_info);
+
+       return netlbl_domhsh_remove_default(&audit_info);
 }
 
 /**
index 440f5c4e1e2d1c636a1ca125da78467b6db6583d..1833ad233b39f33a7a0d062d24901cade27f8400 100644 (file)
@@ -63,6 +63,34 @@ static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
        [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
 };
 
+/*
+ * Helper Functions
+ */
+
+/**
+ * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag
+ * @value: desired value
+ * @audit_info: NetLabel audit information
+ *
+ * Description:
+ * Set the value of the unlabeled accept flag to @value.
+ *
+ */
+static void netlbl_unlabel_acceptflg_set(u8 value,
+                                        struct netlbl_audit *audit_info)
+{
+       struct audit_buffer *audit_buf;
+       u8 old_val;
+
+       old_val = atomic_read(&netlabel_unlabel_accept_flg);
+       atomic_set(&netlabel_unlabel_accept_flg, value);
+
+       audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
+                                             audit_info);
+       audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val);
+       audit_log_end(audit_buf);
+}
+
 /*
  * NetLabel Command Handlers
  */
@@ -79,18 +107,19 @@ static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
  */
 static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
 {
-       int ret_val = -EINVAL;
        u8 value;
+       struct netlbl_audit audit_info;
 
        if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
                value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
                if (value == 1 || value == 0) {
-                       atomic_set(&netlabel_unlabel_accept_flg, value);
-                       ret_val = 0;
+                       netlbl_netlink_auditinfo(skb, &audit_info);
+                       netlbl_unlabel_acceptflg_set(value, &audit_info);
+                       return 0;
                }
        }
 
-       return ret_val;
+       return -EINVAL;
 }
 
 /**
@@ -229,16 +258,23 @@ int netlbl_unlabel_defconf(void)
 {
        int ret_val;
        struct netlbl_dom_map *entry;
+       struct netlbl_audit audit_info;
+
+       /* Only the kernel is allowed to call this function and the only time
+        * it is called is at bootup before the audit subsystem is reporting
+        * messages so don't worry to much about these values. */
+       security_task_getsecid(current, &audit_info.secid);
+       audit_info.loginuid = 0;
 
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (entry == NULL)
                return -ENOMEM;
        entry->type = NETLBL_NLTYPE_UNLABELED;
-       ret_val = netlbl_domhsh_add_default(entry);
+       ret_val = netlbl_domhsh_add_default(entry, &audit_info);
        if (ret_val != 0)
                return ret_val;
 
-       atomic_set(&netlabel_unlabel_accept_flg, 1);
+       netlbl_unlabel_acceptflg_set(1, &audit_info);
 
        return 0;
 }
index eeb7d768d2bb558c7c963f372ec4b7b585d6b675..98a416381e61251e1986eb176d69492ca2d7a7da 100644 (file)
@@ -32,6 +32,9 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/socket.h>
+#include <linux/audit.h>
+#include <linux/tty.h>
+#include <linux/security.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
@@ -74,3 +77,41 @@ int netlbl_netlink_init(void)
 
        return 0;
 }
+
+/*
+ * NetLabel Audit Functions
+ */
+
+/**
+ * netlbl_audit_start_common - Start an audit message
+ * @type: audit message type
+ * @audit_info: NetLabel audit information
+ *
+ * Description:
+ * Start an audit message using the type specified in @type and fill the audit
+ * message with some fields common to all NetLabel audit messages.  Returns
+ * a pointer to the audit buffer on success, NULL on failure.
+ *
+ */
+struct audit_buffer *netlbl_audit_start_common(int type,
+                                              struct netlbl_audit *audit_info)
+{
+       struct audit_context *audit_ctx = current->audit_context;
+       struct audit_buffer *audit_buf;
+       char *secctx;
+       u32 secctx_len;
+
+       audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
+       if (audit_buf == NULL)
+               return NULL;
+
+       audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid);
+
+       if (audit_info->secid != 0 &&
+           security_secid_to_secctx(audit_info->secid,
+                                    &secctx,
+                                    &secctx_len) == 0)
+               audit_log_format(audit_buf, " subj=%s", secctx);
+
+       return audit_buf;
+}
index 3f9386b917df4bfdf6bb354ac681588dab728b0b..47967ef329640dc700f46ec018f61e0c95c22263 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <linux/capability.h>
+#include <linux/audit.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
 #include <net/netlabel.h>
@@ -71,8 +72,25 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb,
                           NETLBL_PROTO_VERSION);
 }
 
+/**
+ * netlbl_netlink_auditinfo - Fetch the audit information from a NETLINK msg
+ * @skb: the packet
+ * @audit_info: NetLabel audit information
+ */
+static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
+                                           struct netlbl_audit *audit_info)
+{
+       audit_info->secid = NETLINK_CB(skb).sid;
+       audit_info->loginuid = NETLINK_CB(skb).loginuid;
+}
+
 /* NetLabel NETLINK I/O functions */
 
 int netlbl_netlink_init(void);
 
+/* NetLabel Audit Functions */
+
+struct audit_buffer *netlbl_audit_start_common(int type,
+                                             struct netlbl_audit *audit_info);
+
 #endif
index 7e14f14058e991393ca1a75aacc669a516e1906c..37a1840216474d77c2ad534903059bbeb1a840ea 100644 (file)
@@ -401,7 +401,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
        if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
                return skb->len;
 
-       read_lock_bh(&qdisc_tree_lock);
+       read_lock(&qdisc_tree_lock);
        if (!tcm->tcm_parent)
                q = dev->qdisc_sleeping;
        else
@@ -458,7 +458,7 @@ errout:
        if (cl)
                cops->put(q, cl);
 out:
-       read_unlock_bh(&qdisc_tree_lock);
+       read_unlock(&qdisc_tree_lock);
        dev_put(dev);
        return skb->len;
 }
index 86cac49a0531476d716c31c9a195571063bb9117..09fda68c8b39f494f6b5802a99efc34a39cdc030 100644 (file)
@@ -194,7 +194,7 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
        if (handle)
                f->handle = handle;
        else {
-               int i = 0x80000000;
+               unsigned int i = 0x80000000;
                do {
                        if (++head->hgenerator == 0x7FFFFFFF)
                                head->hgenerator = 1;
index a19eff12cf78b9013d66f070153c869f8242b151..0b6489291140f0324c73e8a8ddb0aad716c03593 100644 (file)
@@ -195,14 +195,14 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
 {
        struct Qdisc *q;
 
-       read_lock_bh(&qdisc_tree_lock);
+       read_lock(&qdisc_tree_lock);
        list_for_each_entry(q, &dev->qdisc_list, list) {
                if (q->handle == handle) {
-                       read_unlock_bh(&qdisc_tree_lock);
+                       read_unlock(&qdisc_tree_lock);
                        return q;
                }
        }
-       read_unlock_bh(&qdisc_tree_lock);
+       read_unlock(&qdisc_tree_lock);
        return NULL;
 }
 
@@ -837,7 +837,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
                if (idx > s_idx)
                        s_q_idx = 0;
-               read_lock_bh(&qdisc_tree_lock);
+               read_lock(&qdisc_tree_lock);
                q_idx = 0;
                list_for_each_entry(q, &dev->qdisc_list, list) {
                        if (q_idx < s_q_idx) {
@@ -846,12 +846,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
                        }
                        if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
                                          cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
-                               read_unlock_bh(&qdisc_tree_lock);
+                               read_unlock(&qdisc_tree_lock);
                                goto done;
                        }
                        q_idx++;
                }
-               read_unlock_bh(&qdisc_tree_lock);
+               read_unlock(&qdisc_tree_lock);
        }
 
 done:
@@ -1074,7 +1074,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
        s_t = cb->args[0];
        t = 0;
 
-       read_lock_bh(&qdisc_tree_lock);
+       read_lock(&qdisc_tree_lock);
        list_for_each_entry(q, &dev->qdisc_list, list) {
                if (t < s_t || !q->ops->cl_ops ||
                    (tcm->tcm_parent &&
@@ -1096,7 +1096,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
                        break;
                t++;
        }
-       read_unlock_bh(&qdisc_tree_lock);
+       read_unlock(&qdisc_tree_lock);
 
        cb->args[0] = t;
 
index 6f91518997951cbd13056373f36a98c0f87136b2..88c6a99ce53cfb675c9fb1198ca7f5328be3577e 100644 (file)
    The idea is the following:
    - enqueue, dequeue are serialized via top level device
      spinlock dev->queue_lock.
-   - tree walking is protected by read_lock_bh(qdisc_tree_lock)
+   - tree walking is protected by read_lock(qdisc_tree_lock)
      and this lock is used only in process context.
-   - updates to tree are made under rtnl semaphore or
-     from softirq context (__qdisc_destroy rcu-callback)
-     hence this lock needs local bh disabling.
+   - updates to tree are made only under rtnl semaphore,
+     hence this lock may be made without local bh disabling.
 
    qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
  */
@@ -57,14 +56,14 @@ DEFINE_RWLOCK(qdisc_tree_lock);
 
 void qdisc_lock_tree(struct net_device *dev)
 {
-       write_lock_bh(&qdisc_tree_lock);
+       write_lock(&qdisc_tree_lock);
        spin_lock_bh(&dev->queue_lock);
 }
 
 void qdisc_unlock_tree(struct net_device *dev)
 {
        spin_unlock_bh(&dev->queue_lock);
-       write_unlock_bh(&qdisc_tree_lock);
+       write_unlock(&qdisc_tree_lock);
 }
 
 /* 
@@ -483,20 +482,6 @@ void qdisc_reset(struct Qdisc *qdisc)
 static void __qdisc_destroy(struct rcu_head *head)
 {
        struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
-       struct Qdisc_ops  *ops = qdisc->ops;
-
-#ifdef CONFIG_NET_ESTIMATOR
-       gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
-#endif
-       write_lock(&qdisc_tree_lock);
-       if (ops->reset)
-               ops->reset(qdisc);
-       if (ops->destroy)
-               ops->destroy(qdisc);
-       write_unlock(&qdisc_tree_lock);
-       module_put(ops->owner);
-
-       dev_put(qdisc->dev);
        kfree((char *) qdisc - qdisc->padded);
 }
 
@@ -504,32 +489,23 @@ static void __qdisc_destroy(struct rcu_head *head)
 
 void qdisc_destroy(struct Qdisc *qdisc)
 {
-       struct list_head cql = LIST_HEAD_INIT(cql);
-       struct Qdisc *cq, *q, *n;
+       struct Qdisc_ops  *ops = qdisc->ops;
 
        if (qdisc->flags & TCQ_F_BUILTIN ||
-               !atomic_dec_and_test(&qdisc->refcnt))
+           !atomic_dec_and_test(&qdisc->refcnt))
                return;
 
-       if (!list_empty(&qdisc->list)) {
-               if (qdisc->ops->cl_ops == NULL)
-                       list_del(&qdisc->list);
-               else
-                       list_move(&qdisc->list, &cql);
-       }
-
-       /* unlink inner qdiscs from dev->qdisc_list immediately */
-       list_for_each_entry(cq, &cql, list)
-               list_for_each_entry_safe(q, n, &qdisc->dev->qdisc_list, list)
-                       if (TC_H_MAJ(q->parent) == TC_H_MAJ(cq->handle)) {
-                               if (q->ops->cl_ops == NULL)
-                                       list_del_init(&q->list);
-                               else
-                                       list_move_tail(&q->list, &cql);
-                       }
-       list_for_each_entry_safe(cq, n, &cql, list)
-               list_del_init(&cq->list);
+       list_del(&qdisc->list);
+#ifdef CONFIG_NET_ESTIMATOR
+       gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
+#endif
+       if (ops->reset)
+               ops->reset(qdisc);
+       if (ops->destroy)
+               ops->destroy(qdisc);
 
+       module_put(ops->owner);
+       dev_put(qdisc->dev);
        call_rcu(&qdisc->q_rcu, __qdisc_destroy);
 }
 
@@ -549,15 +525,15 @@ void dev_activate(struct net_device *dev)
                                printk(KERN_INFO "%s: activation failed\n", dev->name);
                                return;
                        }
-                       write_lock_bh(&qdisc_tree_lock);
+                       write_lock(&qdisc_tree_lock);
                        list_add_tail(&qdisc->list, &dev->qdisc_list);
-                       write_unlock_bh(&qdisc_tree_lock);
+                       write_unlock(&qdisc_tree_lock);
                } else {
                        qdisc =  &noqueue_qdisc;
                }
-               write_lock_bh(&qdisc_tree_lock);
+               write_lock(&qdisc_tree_lock);
                dev->qdisc_sleeping = qdisc;
-               write_unlock_bh(&qdisc_tree_lock);
+               write_unlock(&qdisc_tree_lock);
        }
 
        if (!netif_carrier_ok(dev))
index bb3ddd4784b1cebfd4668dc15df844b484b36267..6c058e3660c0c28ec9e6d85cd79f92c94c391539 100644 (file)
@@ -391,7 +391,7 @@ static inline void htb_add_class_to_row(struct htb_sched *q,
 /* If this triggers, it is a bug in this code, but it need not be fatal */
 static void htb_safe_rb_erase(struct rb_node *rb, struct rb_root *root)
 {
-       if (RB_EMPTY_NODE(rb)) {
+       if (!RB_EMPTY_NODE(rb)) {
                WARN_ON(1);
        } else {
                rb_erase(rb, root);
index 03f65de75d88280c0096f4aac8efbbe4330e9383..64f630102532c9e3e95379458bd934902bcf2870 100644 (file)
@@ -218,12 +218,6 @@ int sctp_rcv(struct sk_buff *skb)
                }
        }
 
-       /* SCTP seems to always need a timestamp right now (FIXME) */
-       if (skb->tstamp.off_sec == 0) {
-               __net_timestamp(skb);
-               sock_enable_timestamp(sk); 
-       }
-
        if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
                goto discard_release;
        nf_reset(skb);
@@ -388,7 +382,7 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
                         * pmtu discovery on this transport.
                         */
                        t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
-                       t->param_flags = (t->param_flags & ~SPP_HB) |
+                       t->param_flags = (t->param_flags & ~SPP_PMTUD) |
                                SPP_PMTUD_DISABLE;
                } else {
                        t->pathmtu = pmtu;
index cdc5a393676657691a2421b573235fde8318b0f8..3ef4351dd956ad95649afd568b3a91381a86e730 100644 (file)
@@ -633,7 +633,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
                 * data will fit or delay in hopes of bundling a full
                 * sized packet.
                 */
-               if (len < asoc->pathmtu - packet->overhead) {
+               if (len < asoc->frag_point) {
                        retval = SCTP_XMIT_NAGLE_DELAY;
                        goto finish;
                }
@@ -645,7 +645,13 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
        /* Keep track of how many bytes are in flight to the receiver. */
        asoc->outqueue.outstanding_bytes += datasize;
 
-       /* Update our view of the receiver's rwnd. */
+       /* Update our view of the receiver's rwnd. Include sk_buff overhead
+        * while updating peer.rwnd so that it reduces the chances of a
+        * receiver running out of receive buffer space even when receive
+        * window is still open. This can happen when a sender is sending
+        * sending small messages.
+        */
+       datasize += sizeof(struct sk_buff);
        if (datasize < rwnd)
                rwnd -= datasize;
        else
index 37074a39ecbbfb68939c9cc6b0679e21eba71bb1..739582415bf6d84b98d61235ac6a220b9a01cd34 100644 (file)
@@ -416,7 +416,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                         * (Section 7.2.4)), add the data size of those
                         * chunks to the rwnd.
                         */
-                       q->asoc->peer.rwnd += sctp_data_size(chunk);
+                       q->asoc->peer.rwnd += (sctp_data_size(chunk) +
+                                               sizeof(struct sk_buff));
                        q->outstanding_bytes -= sctp_data_size(chunk);
                        transport->flight_size -= sctp_data_size(chunk);
 
index 7745bdea7817acab1709df3e454785822ac2933a..507dff72c5853508279847672c84dcab460436cf 100644 (file)
@@ -1447,8 +1447,16 @@ no_hmac:
        /* Check to see if the cookie is stale.  If there is already
         * an association, there is no need to check cookie's expiration
         * for init collision case of lost COOKIE ACK.
+        * If skb has been timestamped, then use the stamp, otherwise
+        * use current time.  This introduces a small possibility that
+        * that a cookie may be considered expired, but his would only slow
+        * down the new association establishment instead of every packet.
         */
-       skb_get_timestamp(skb, &tv);
+       if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
+               skb_get_timestamp(skb, &tv);
+       else
+               do_gettimeofday(&tv);
+
        if (!asoc && tv_lt(bear_cookie->expiration, tv)) {
                __u16 len;
                /*
index 79c3e072cf282027f3988c17d90bbc2c6c2143b8..3fe906d6506982f9e1c7a0bdcf6e67b6d2772d58 100644 (file)
@@ -3084,8 +3084,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
         */
        sp->disable_fragments = 0;
 
-       /* Turn on/off any Nagle-like algorithm.  */
-       sp->nodelay           = 1;
+       /* Enable Nagle algorithm by default.  */
+       sp->nodelay           = 0;
 
        /* Enable by default. */
        sp->v4mapped          = 1;
index 55163af3dcaf2cdb4f195fccb39c94442373c624..993ff1a5d945687883c51ffc4a8662c87aa7704a 100644 (file)
@@ -331,8 +331,8 @@ rpcauth_unbindcred(struct rpc_task *task)
        task->tk_msg.rpc_cred = NULL;
 }
 
-u32 *
-rpcauth_marshcred(struct rpc_task *task, u32 *p)
+__be32 *
+rpcauth_marshcred(struct rpc_task *task, __be32 *p)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
 
@@ -342,8 +342,8 @@ rpcauth_marshcred(struct rpc_task *task, u32 *p)
        return cred->cr_ops->crmarshal(task, p);
 }
 
-u32 *
-rpcauth_checkverf(struct rpc_task *task, u32 *p)
+__be32 *
+rpcauth_checkverf(struct rpc_task *task, __be32 *p)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
 
@@ -355,7 +355,7 @@ rpcauth_checkverf(struct rpc_task *task, u32 *p)
 
 int
 rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
-               u32 *data, void *obj)
+               __be32 *data, void *obj)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
 
@@ -369,7 +369,7 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
 
 int
 rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
-               u32 *data, void *obj)
+               __be32 *data, void *obj)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
 
index 6eed3e166ba33ab083c6d831a6b5c33d63b2fede..a6ed2d22a6e6e8017bcd6e1f9816ee2d2fcbbf64 100644 (file)
@@ -826,14 +826,14 @@ out:
 * Marshal credentials.
 * Maybe we should keep a cached credential for performance reasons.
 */
-static u32 *
-gss_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+gss_marshal(struct rpc_task *task, __be32 *p)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
                                                 gc_base);
        struct gss_cl_ctx       *ctx = gss_cred_get_ctx(cred);
-       u32             *cred_len;
+       __be32          *cred_len;
        struct rpc_rqst *req = task->tk_rqstp;
        u32             maj_stat = 0;
        struct xdr_netobj mic;
@@ -894,12 +894,12 @@ gss_refresh(struct rpc_task *task)
        return 0;
 }
 
-static u32 *
-gss_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+gss_validate(struct rpc_task *task, __be32 *p)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
        struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
-       u32             seq;
+       __be32          seq;
        struct kvec     iov;
        struct xdr_buf  verf_buf;
        struct xdr_netobj mic;
@@ -940,13 +940,14 @@ out_bad:
 
 static inline int
 gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
-               kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+               kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
 {
        struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
        struct xdr_buf  integ_buf;
-       u32             *integ_len = NULL;
+       __be32          *integ_len = NULL;
        struct xdr_netobj mic;
-       u32             offset, *q;
+       u32             offset;
+       __be32          *q;
        struct kvec     *iov;
        u32             maj_stat = 0;
        int             status = -EIO;
@@ -1032,13 +1033,13 @@ out:
 
 static inline int
 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
-               kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+               kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj)
 {
        struct xdr_buf  *snd_buf = &rqstp->rq_snd_buf;
        u32             offset;
        u32             maj_stat;
        int             status;
-       u32             *opaque_len;
+       __be32          *opaque_len;
        struct page     **inpages;
        int             first;
        int             pad;
@@ -1095,7 +1096,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 
 static int
 gss_wrap_req(struct rpc_task *task,
-            kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
+            kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
@@ -1132,7 +1133,7 @@ out:
 
 static inline int
 gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
-               struct rpc_rqst *rqstp, u32 **p)
+               struct rpc_rqst *rqstp, __be32 **p)
 {
        struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
        struct xdr_buf integ_buf;
@@ -1169,7 +1170,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 
 static inline int
 gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
-               struct rpc_rqst *rqstp, u32 **p)
+               struct rpc_rqst *rqstp, __be32 **p)
 {
        struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
        u32 offset;
@@ -1198,13 +1199,13 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 
 static int
 gss_unwrap_resp(struct rpc_task *task,
-               kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
+               kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
 {
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
                        gc_base);
        struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
-       u32             *savedp = p;
+       __be32          *savedp = p;
        struct kvec     *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
        int             savedlen = head->iov_len;
        int             status = -EIO;
index 2f312164d6d5611559aabab099e37ef8e55f7459..08601ee4cd7311d45c4a1146386ce22a0d96be76 100644 (file)
@@ -115,7 +115,7 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
        krb5_hdr = ptr - 2;
        msg_start = krb5_hdr + 24;
 
-       *(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
+       *(__be16 *)(krb5_hdr + 2) = htons(ctx->signalg);
        memset(krb5_hdr + 4, 0xff, 4);
 
        if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
index f179415d0c38e2bf4efe0e0cf345b51d009522d7..cc45c1605f80eb7bbc6f2382bb2c3952f0446ec9 100644 (file)
@@ -177,9 +177,9 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
        msg_start = krb5_hdr + 24;
        /* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
 
-       *(u16 *)(krb5_hdr + 2) = htons(kctx->signalg);
+       *(__be16 *)(krb5_hdr + 2) = htons(kctx->signalg);
        memset(krb5_hdr + 4, 0xff, 4);
-       *(u16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
+       *(__be16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
 
        make_confounder(msg_start, blocksize);
 
index 94217ec9e2dd5427a1b12cc559a46e114172e192..638c0b576203bab4fac5c0037cf1881e2c1c32e3 100644 (file)
@@ -607,7 +607,7 @@ svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
 
        if (argv->iov_len < 4)
                return -1;
-       o->len = ntohl(svc_getu32(argv));
+       o->len = svc_getnl(argv);
        l = round_up_to_quad(o->len);
        if (argv->iov_len < l)
                return -1;
@@ -620,17 +620,17 @@ svc_safe_getnetobj(struct kvec *argv, struct xdr_netobj *o)
 static inline int
 svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
 {
-       u32 *p;
+       u8 *p;
 
        if (resv->iov_len + 4 > PAGE_SIZE)
                return -1;
-       svc_putu32(resv, htonl(o->len));
+       svc_putnl(resv, o->len);
        p = resv->iov_base + resv->iov_len;
        resv->iov_len += round_up_to_quad(o->len);
        if (resv->iov_len > PAGE_SIZE)
                return -1;
        memcpy(p, o->data, o->len);
-       memset((u8 *)p + o->len, 0, round_up_to_quad(o->len) - o->len);
+       memset(p + o->len, 0, round_up_to_quad(o->len) - o->len);
        return 0;
 }
 
@@ -640,7 +640,7 @@ svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
  */
 static int
 gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
-                 u32 *rpcstart, struct rpc_gss_wire_cred *gc, u32 *authp)
+                 __be32 *rpcstart, struct rpc_gss_wire_cred *gc, __be32 *authp)
 {
        struct gss_ctx          *ctx_id = rsci->mechctx;
        struct xdr_buf          rpchdr;
@@ -657,7 +657,7 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
        *authp = rpc_autherr_badverf;
        if (argv->iov_len < 4)
                return SVC_DENIED;
-       flavor = ntohl(svc_getu32(argv));
+       flavor = svc_getnl(argv);
        if (flavor != RPC_AUTH_GSS)
                return SVC_DENIED;
        if (svc_safe_getnetobj(argv, &checksum))
@@ -687,9 +687,9 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
 static int
 gss_write_null_verf(struct svc_rqst *rqstp)
 {
-       u32     *p;
+       __be32     *p;
 
-       svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_NULL));
+       svc_putnl(rqstp->rq_res.head, RPC_AUTH_NULL);
        p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
        /* don't really need to check if head->iov_len > PAGE_SIZE ... */
        *p++ = 0;
@@ -701,14 +701,14 @@ gss_write_null_verf(struct svc_rqst *rqstp)
 static int
 gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
 {
-       u32                     xdr_seq;
+       __be32                  xdr_seq;
        u32                     maj_stat;
        struct xdr_buf          verf_data;
        struct xdr_netobj       mic;
-       u32                     *p;
+       __be32                  *p;
        struct kvec             iov;
 
-       svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_GSS));
+       svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
        xdr_seq = htonl(seq);
 
        iov.iov_base = &xdr_seq;
@@ -782,7 +782,7 @@ EXPORT_SYMBOL(svcauth_gss_register_pseudoflavor);
 static inline int
 read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
 {
-       u32     raw;
+       __be32  raw;
        int     status;
 
        status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
@@ -805,7 +805,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
        struct xdr_netobj mic;
        struct xdr_buf integ_buf;
 
-       integ_len = ntohl(svc_getu32(&buf->head[0]));
+       integ_len = svc_getnl(&buf->head[0]);
        if (integ_len & 3)
                goto out;
        if (integ_len > buf->len)
@@ -825,7 +825,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
        maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
        if (maj_stat != GSS_S_COMPLETE)
                goto out;
-       if (ntohl(svc_getu32(&buf->head[0])) != seq)
+       if (svc_getnl(&buf->head[0]) != seq)
                goto out;
        stat = 0;
 out:
@@ -857,7 +857,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
 
        rqstp->rq_sendfile_ok = 0;
 
-       priv_len = ntohl(svc_getu32(&buf->head[0]));
+       priv_len = svc_getnl(&buf->head[0]);
        if (rqstp->rq_deferred) {
                /* Already decrypted last time through! The sequence number
                 * check at out_seq is unnecessary but harmless: */
@@ -895,7 +895,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
        if (maj_stat != GSS_S_COMPLETE)
                return -EINVAL;
 out_seq:
-       if (ntohl(svc_getu32(&buf->head[0])) != seq)
+       if (svc_getnl(&buf->head[0]) != seq)
                return -EINVAL;
        return 0;
 }
@@ -905,7 +905,7 @@ struct gss_svc_data {
        struct rpc_gss_wire_cred        clcred;
        /* pointer to the beginning of the procedure-specific results,
         * which may be encrypted/checksummed in svcauth_gss_release: */
-       u32                             *body_start;
+       __be32                          *body_start;
        struct rsc                      *rsci;
 };
 
@@ -946,7 +946,7 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
  * response here and return SVC_COMPLETE.
  */
 static int
-svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
 {
        struct kvec     *argv = &rqstp->rq_arg.head[0];
        struct kvec     *resv = &rqstp->rq_res.head[0];
@@ -956,8 +956,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
        struct rpc_gss_wire_cred *gc;
        struct rsc      *rsci = NULL;
        struct rsi      *rsip, rsikey;
-       u32             *rpcstart;
-       u32             *reject_stat = resv->iov_base + resv->iov_len;
+       __be32          *rpcstart;
+       __be32          *reject_stat = resv->iov_base + resv->iov_len;
        int             ret;
 
        dprintk("RPC:      svcauth_gss: argv->iov_len = %zd\n",argv->iov_len);
@@ -985,12 +985,12 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
 
        if (argv->iov_len < 5 * 4)
                goto auth_err;
-       crlen = ntohl(svc_getu32(argv));
-       if (ntohl(svc_getu32(argv)) != RPC_GSS_VERSION)
+       crlen = svc_getnl(argv);
+       if (svc_getnl(argv) != RPC_GSS_VERSION)
                goto auth_err;
-       gc->gc_proc = ntohl(svc_getu32(argv));
-       gc->gc_seq = ntohl(svc_getu32(argv));
-       gc->gc_svc = ntohl(svc_getu32(argv));
+       gc->gc_proc = svc_getnl(argv);
+       gc->gc_seq = svc_getnl(argv);
+       gc->gc_svc = svc_getnl(argv);
        if (svc_safe_getnetobj(argv, &gc->gc_ctx))
                goto auth_err;
        if (crlen != round_up_to_quad(gc->gc_ctx.len) + 5 * 4)
@@ -1016,9 +1016,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
        case RPC_GSS_PROC_CONTINUE_INIT:
                if (argv->iov_len < 2 * 4)
                        goto auth_err;
-               if (ntohl(svc_getu32(argv)) != RPC_AUTH_NULL)
+               if (svc_getnl(argv) != RPC_AUTH_NULL)
                        goto auth_err;
-               if (ntohl(svc_getu32(argv)) != 0)
+               if (svc_getnl(argv) != 0)
                        goto auth_err;
                break;
        case RPC_GSS_PROC_DATA:
@@ -1076,14 +1076,14 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
                                goto drop;
                        if (resv->iov_len + 4 > PAGE_SIZE)
                                goto drop;
-                       svc_putu32(resv, rpc_success);
+                       svc_putnl(resv, RPC_SUCCESS);
                        if (svc_safe_putnetobj(resv, &rsip->out_handle))
                                goto drop;
                        if (resv->iov_len + 3 * 4 > PAGE_SIZE)
                                goto drop;
-                       svc_putu32(resv, htonl(rsip->major_status));
-                       svc_putu32(resv, htonl(rsip->minor_status));
-                       svc_putu32(resv, htonl(GSS_SEQ_WIN));
+                       svc_putnl(resv, rsip->major_status);
+                       svc_putnl(resv, rsip->minor_status);
+                       svc_putnl(resv, GSS_SEQ_WIN);
                        if (svc_safe_putnetobj(resv, &rsip->out_token))
                                goto drop;
                        rqstp->rq_client = NULL;
@@ -1093,7 +1093,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
                set_bit(CACHE_NEGATIVE, &rsci->h.flags);
                if (resv->iov_len + 4 > PAGE_SIZE)
                        goto drop;
-               svc_putu32(resv, rpc_success);
+               svc_putnl(resv, RPC_SUCCESS);
                goto complete;
        case RPC_GSS_PROC_DATA:
                *authp = rpcsec_gsserr_ctxproblem;
@@ -1111,8 +1111,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
                                goto auth_err;
                        /* placeholders for length and seq. number: */
                        svcdata->body_start = resv->iov_base + resv->iov_len;
-                       svc_putu32(resv, 0);
-                       svc_putu32(resv, 0);
+                       svc_putnl(resv, 0);
+                       svc_putnl(resv, 0);
                        break;
                case RPC_GSS_SVC_PRIVACY:
                        if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
@@ -1120,8 +1120,8 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
                                goto auth_err;
                        /* placeholders for length and seq. number: */
                        svcdata->body_start = resv->iov_base + resv->iov_len;
-                       svc_putu32(resv, 0);
-                       svc_putu32(resv, 0);
+                       svc_putnl(resv, 0);
+                       svc_putnl(resv, 0);
                        break;
                default:
                        goto auth_err;
@@ -1156,7 +1156,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
        struct xdr_buf integ_buf;
        struct xdr_netobj mic;
        struct kvec *resv;
-       u32 *p;
+       __be32 *p;
        int integ_offset, integ_len;
        int stat = -EINVAL;
 
@@ -1199,7 +1199,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
        mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
        if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
                goto out_err;
-       svc_putu32(resv, htonl(mic.len));
+       svc_putnl(resv, mic.len);
        memset(mic.data + mic.len, 0,
                        round_up_to_quad(mic.len) - mic.len);
        resv->iov_len += XDR_QUADLEN(mic.len) << 2;
@@ -1219,8 +1219,8 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
        struct rpc_gss_wire_cred *gc = &gsd->clcred;
        struct xdr_buf *resbuf = &rqstp->rq_res;
        struct page **inpages = NULL;
-       u32 *p;
-       int offset, *len;
+       __be32 *p, *len;
+       int offset;
        int pad;
 
        p = gsd->body_start;
@@ -1264,7 +1264,7 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
                return -ENOMEM;
        *len = htonl(resbuf->len - offset);
        pad = 3 - ((resbuf->len - offset - 1)&3);
-       p = (u32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
+       p = (__be32 *)(resbuf->tail[0].iov_base + resbuf->tail[0].iov_len);
        memset(p, 0, pad);
        resbuf->tail[0].iov_len += pad;
        resbuf->len += pad;
index 2eccffa96ba1a016208c73de79cebc77a482f94e..3be257dc32b2af4e26a5f1028ac8dc30586b7e28 100644 (file)
@@ -60,8 +60,8 @@ nul_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
 /*
  * Marshal credential.
  */
-static u32 *
-nul_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+nul_marshal(struct rpc_task *task, __be32 *p)
 {
        *p++ = htonl(RPC_AUTH_NULL);
        *p++ = 0;
@@ -81,8 +81,8 @@ nul_refresh(struct rpc_task *task)
        return 0;
 }
 
-static u32 *
-nul_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+nul_validate(struct rpc_task *task, __be32 *p)
 {
        rpc_authflavor_t        flavor;
        u32                     size;
index 74c7406a10549d4a747e376f5b30ae41b0764290..f7f990c9afe2ef805b2ea75e1d9b23dbb7f2d2fc 100644 (file)
@@ -137,12 +137,12 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
  * Marshal credentials.
  * Maybe we should keep a cached credential for performance reasons.
  */
-static u32 *
-unx_marshal(struct rpc_task *task, u32 *p)
+static __be32 *
+unx_marshal(struct rpc_task *task, __be32 *p)
 {
        struct rpc_clnt *clnt = task->tk_client;
        struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
-       u32             *base, *hold;
+       __be32          *base, *hold;
        int             i;
 
        *p++ = htonl(RPC_AUTH_UNIX);
@@ -178,8 +178,8 @@ unx_refresh(struct rpc_task *task)
        return 0;
 }
 
-static u32 *
-unx_validate(struct rpc_task *task, u32 *p)
+static __be32 *
+unx_validate(struct rpc_task *task, __be32 *p)
 {
        rpc_authflavor_t        flavor;
        u32                     size;
index 084a0ad5c64ea0752893f7ddefb95be18384a467..124ff0ceb55b2ee20ce47d6f3358a966de37ddb5 100644 (file)
@@ -60,8 +60,8 @@ static void   call_refreshresult(struct rpc_task *task);
 static void    call_timeout(struct rpc_task *task);
 static void    call_connect(struct rpc_task *task);
 static void    call_connect_status(struct rpc_task *task);
-static u32 *   call_header(struct rpc_task *task);
-static u32 *   call_verify(struct rpc_task *task);
+static __be32 *        call_header(struct rpc_task *task);
+static __be32 *        call_verify(struct rpc_task *task);
 
 
 static int
@@ -782,7 +782,7 @@ call_encode(struct rpc_task *task)
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        unsigned int    bufsiz;
        kxdrproc_t      encode;
-       u32             *p;
+       __be32          *p;
 
        dprintk("RPC: %4d call_encode (status %d)\n", 
                                task->tk_pid, task->tk_status);
@@ -1100,7 +1100,7 @@ call_decode(struct rpc_task *task)
        struct rpc_clnt *clnt = task->tk_client;
        struct rpc_rqst *req = task->tk_rqstp;
        kxdrproc_t      decode = task->tk_msg.rpc_proc->p_decode;
-       u32             *p;
+       __be32          *p;
 
        dprintk("RPC: %4d call_decode (status %d)\n", 
                                task->tk_pid, task->tk_status);
@@ -1197,12 +1197,12 @@ call_refreshresult(struct rpc_task *task)
 /*
  * Call header serialization
  */
-static u32 *
+static __be32 *
 call_header(struct rpc_task *task)
 {
        struct rpc_clnt *clnt = task->tk_client;
        struct rpc_rqst *req = task->tk_rqstp;
-       u32             *p = req->rq_svec[0].iov_base;
+       __be32          *p = req->rq_svec[0].iov_base;
 
        /* FIXME: check buffer size? */
 
@@ -1221,12 +1221,13 @@ call_header(struct rpc_task *task)
 /*
  * Reply header verification
  */
-static u32 *
+static __be32 *
 call_verify(struct rpc_task *task)
 {
        struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
        int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
-       u32     *p = iov->iov_base, n;
+       __be32  *p = iov->iov_base;
+       u32 n;
        int error = -EACCES;
 
        if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) {
@@ -1303,7 +1304,7 @@ call_verify(struct rpc_task *task)
                printk(KERN_WARNING "call_verify: auth check failed\n");
                goto out_garbage;               /* bad verifier, retry */
        }
-       len = p - (u32 *)iov->iov_base - 1;
+       len = p - (__be32 *)iov->iov_base - 1;
        if (len < 0)
                goto out_overflow;
        switch ((n = ntohl(*p++))) {
@@ -1358,12 +1359,12 @@ out_overflow:
        goto out_garbage;
 }
 
-static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
+static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj)
 {
        return 0;
 }
 
-static int rpcproc_decode_null(void *rqstp, u32 *data, void *obj)
+static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj)
 {
        return 0;
 }
index c04609d3476a986e630097998a6eeecb76551870..919d5ba7ca0a206cb40aff51e67ac90bbc4f67b3 100644 (file)
@@ -300,7 +300,7 @@ static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr,
 /*
  * XDR encode/decode functions for PMAP
  */
-static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
+static int xdr_encode_mapping(struct rpc_rqst *req, __be32 *p, struct portmap_args *map)
 {
        dprintk("RPC: xdr_encode_mapping(%u, %u, %u, %u)\n",
                map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port);
@@ -313,13 +313,13 @@ static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args
        return 0;
 }
 
-static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
+static int xdr_decode_port(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
 {
        *portp = (unsigned short) ntohl(*p++);
        return 0;
 }
 
-static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
+static int xdr_decode_bool(struct rpc_rqst *req, __be32 *p, unsigned int *boolp)
 {
        *boolp = (unsigned int) ntohl(*p++);
        return 0;
index b76a227dd3ad9aac842f988874bc66cbb27e4a7b..44b8d9d4c18a7d09e5929688e45eab41cdc60ef8 100644 (file)
@@ -256,11 +256,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        struct kvec *           argv = &rqstp->rq_arg.head[0];
        struct kvec *           resv = &rqstp->rq_res.head[0];
        kxdrproc_t              xdr;
-       u32                     *statp;
-       u32                     dir, prog, vers, proc,
-                               auth_stat, rpc_stat;
+       __be32                  *statp;
+       u32                     dir, prog, vers, proc;
+       __be32                  auth_stat, rpc_stat;
        int                     auth_res;
-       u32                     *accept_statp;
+       __be32                  *accept_statp;
 
        rpc_stat = rpc_success;
 
@@ -284,16 +284,16 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        rqstp->rq_sendfile_ok = 1;
        /* tcp needs a space for the record length... */
        if (rqstp->rq_prot == IPPROTO_TCP)
-               svc_putu32(resv, 0);
+               svc_putnl(resv, 0);
 
        rqstp->rq_xid = svc_getu32(argv);
        svc_putu32(resv, rqstp->rq_xid);
 
-       dir  = ntohl(svc_getu32(argv));
-       vers = ntohl(svc_getu32(argv));
+       dir  = svc_getnl(argv);
+       vers = svc_getnl(argv);
 
        /* First words of reply: */
-       svc_putu32(resv, xdr_one);              /* REPLY */
+       svc_putnl(resv, 1);             /* REPLY */
 
        if (dir != 0)           /* direction != CALL */
                goto err_bad_dir;
@@ -303,11 +303,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        /* Save position in case we later decide to reject: */
        accept_statp = resv->iov_base + resv->iov_len;
 
-       svc_putu32(resv, xdr_zero);             /* ACCEPT */
+       svc_putnl(resv, 0);             /* ACCEPT */
 
-       rqstp->rq_prog = prog = ntohl(svc_getu32(argv));        /* program number */
-       rqstp->rq_vers = vers = ntohl(svc_getu32(argv));        /* version number */
-       rqstp->rq_proc = proc = ntohl(svc_getu32(argv));        /* procedure number */
+       rqstp->rq_prog = prog = svc_getnl(argv);        /* program number */
+       rqstp->rq_vers = vers = svc_getnl(argv);        /* version number */
+       rqstp->rq_proc = proc = svc_getnl(argv);        /* procedure number */
 
        progp = serv->sv_program;
 
@@ -361,7 +361,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
 
        /* Build the reply header. */
        statp = resv->iov_base +resv->iov_len;
-       svc_putu32(resv, rpc_success);          /* RPC_SUCCESS */
+       svc_putnl(resv, RPC_SUCCESS);
 
        /* Bump per-procedure stats counter */
        procp->pc_count++;
@@ -439,10 +439,10 @@ err_bad_dir:
 
 err_bad_rpc:
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, xdr_one);      /* REJECT */
-       svc_putu32(resv, xdr_zero);     /* RPC_MISMATCH */
-       svc_putu32(resv, xdr_two);      /* Only RPCv2 supported */
-       svc_putu32(resv, xdr_two);
+       svc_putnl(resv, 1);     /* REJECT */
+       svc_putnl(resv, 0);     /* RPC_MISMATCH */
+       svc_putnl(resv, 2);     /* Only RPCv2 supported */
+       svc_putnl(resv, 2);
        goto sendit;
 
 err_bad_auth:
@@ -450,15 +450,15 @@ err_bad_auth:
        serv->sv_stats->rpcbadauth++;
        /* Restore write pointer to location of accept status: */
        xdr_ressize_check(rqstp, accept_statp);
-       svc_putu32(resv, xdr_one);      /* REJECT */
-       svc_putu32(resv, xdr_one);      /* AUTH_ERROR */
-       svc_putu32(resv, auth_stat);    /* status */
+       svc_putnl(resv, 1);     /* REJECT */
+       svc_putnl(resv, 1);     /* AUTH_ERROR */
+       svc_putnl(resv, ntohl(auth_stat));      /* status */
        goto sendit;
 
 err_bad_prog:
        dprintk("svc: unknown program %d\n", prog);
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_prog_unavail);
+       svc_putnl(resv, RPC_PROG_UNAVAIL);
        goto sendit;
 
 err_bad_vers:
@@ -466,9 +466,9 @@ err_bad_vers:
        printk("svc: unknown version (%d)\n", vers);
 #endif
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_prog_mismatch);
-       svc_putu32(resv, htonl(progp->pg_lovers));
-       svc_putu32(resv, htonl(progp->pg_hivers));
+       svc_putnl(resv, RPC_PROG_MISMATCH);
+       svc_putnl(resv, progp->pg_lovers);
+       svc_putnl(resv, progp->pg_hivers);
        goto sendit;
 
 err_bad_proc:
@@ -476,7 +476,7 @@ err_bad_proc:
        printk("svc: unknown procedure (%d)\n", proc);
 #endif
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_proc_unavail);
+       svc_putnl(resv, RPC_PROC_UNAVAIL);
        goto sendit;
 
 err_garbage:
@@ -486,6 +486,6 @@ err_garbage:
        rpc_stat = rpc_garbage_args;
 err_bad:
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_stat);
+       svc_putnl(resv, ntohl(rpc_stat));
        goto sendit;
 }
index 5b28c6176806321af56ff3edfe464c7fea297e7d..8f2320aded5c42f645b406cf51539d10228ef055 100644 (file)
@@ -35,14 +35,14 @@ static struct auth_ops      *authtab[RPC_AUTH_MAXFLAVOR] = {
 };
 
 int
-svc_authenticate(struct svc_rqst *rqstp, u32 *authp)
+svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
 {
        rpc_authflavor_t        flavor;
        struct auth_ops         *aops;
 
        *authp = rpc_auth_ok;
 
-       flavor = ntohl(svc_getu32(&rqstp->rq_arg.head[0]));
+       flavor = svc_getnl(&rqstp->rq_arg.head[0]);
 
        dprintk("svc: svc_authenticate (%d)\n", flavor);
 
index 7e5707e2d6b678fcd00cdb439cceb3b71fee0220..1020d54b01d074a7fd8c1d25976a7d9fe800935c 100644 (file)
@@ -145,7 +145,7 @@ static void ip_map_request(struct cache_detail *cd,
 {
        char text_addr[20];
        struct ip_map *im = container_of(h, struct ip_map, h);
-       __u32 addr = im->m_addr.s_addr;
+       __be32 addr = im->m_addr.s_addr;
        
        snprintf(text_addr, 20, "%u.%u.%u.%u",
                 ntohl(addr) >> 24 & 0xff,
@@ -249,10 +249,10 @@ static int ip_map_show(struct seq_file *m,
 
        seq_printf(m, "%s %d.%d.%d.%d %s\n",
                   im->m_class,
-                  htonl(addr.s_addr) >> 24 & 0xff,
-                  htonl(addr.s_addr) >> 16 & 0xff,
-                  htonl(addr.s_addr) >>  8 & 0xff,
-                  htonl(addr.s_addr) >>  0 & 0xff,
+                  ntohl(addr.s_addr) >> 24 & 0xff,
+                  ntohl(addr.s_addr) >> 16 & 0xff,
+                  ntohl(addr.s_addr) >>  8 & 0xff,
+                  ntohl(addr.s_addr) >>  0 & 0xff,
                   dom
                   );
        return 0;
@@ -410,7 +410,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
 }
 
 static int
-svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
 {
        struct kvec     *argv = &rqstp->rq_arg.head[0];
        struct kvec     *resv = &rqstp->rq_res.head[0];
@@ -427,7 +427,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
                *authp = rpc_autherr_badcred;
                return SVC_DENIED;
        }
-       if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) {
+       if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
                dprintk("svc: bad null verf\n");
                *authp = rpc_autherr_badverf;
                return SVC_DENIED;
@@ -441,8 +441,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
                return SVC_DROP; /* kmalloc failure - client must retry */
 
        /* Put NULL verifier */
-       svc_putu32(resv, RPC_AUTH_NULL);
-       svc_putu32(resv, 0);
+       svc_putnl(resv, RPC_AUTH_NULL);
+       svc_putnl(resv, 0);
 
        return SVC_OK;
 }
@@ -472,7 +472,7 @@ struct auth_ops svcauth_null = {
 
 
 static int
-svcauth_unix_accept(struct svc_rqst *rqstp, u32 *authp)
+svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
 {
        struct kvec     *argv = &rqstp->rq_arg.head[0];
        struct kvec     *resv = &rqstp->rq_res.head[0];
@@ -488,31 +488,31 @@ svcauth_unix_accept(struct svc_rqst *rqstp, u32 *authp)
 
        svc_getu32(argv);                       /* length */
        svc_getu32(argv);                       /* time stamp */
-       slen = XDR_QUADLEN(ntohl(svc_getu32(argv)));    /* machname length */
+       slen = XDR_QUADLEN(svc_getnl(argv));    /* machname length */
        if (slen > 64 || (len -= (slen + 3)*4) < 0)
                goto badcred;
-       argv->iov_base = (void*)((u32*)argv->iov_base + slen);  /* skip machname */
+       argv->iov_base = (void*)((__be32*)argv->iov_base + slen);       /* skip machname */
        argv->iov_len -= slen*4;
 
-       cred->cr_uid = ntohl(svc_getu32(argv));         /* uid */
-       cred->cr_gid = ntohl(svc_getu32(argv));         /* gid */
-       slen = ntohl(svc_getu32(argv));                 /* gids length */
+       cred->cr_uid = svc_getnl(argv);         /* uid */
+       cred->cr_gid = svc_getnl(argv);         /* gid */
+       slen = svc_getnl(argv);                 /* gids length */
        if (slen > 16 || (len -= (slen + 2)*4) < 0)
                goto badcred;
        cred->cr_group_info = groups_alloc(slen);
        if (cred->cr_group_info == NULL)
                return SVC_DROP;
        for (i = 0; i < slen; i++)
-               GROUP_AT(cred->cr_group_info, i) = ntohl(svc_getu32(argv));
+               GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
 
-       if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) {
+       if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
                *authp = rpc_autherr_badverf;
                return SVC_DENIED;
        }
 
        /* Put NULL verifier */
-       svc_putu32(resv, RPC_AUTH_NULL);
-       svc_putu32(resv, 0);
+       svc_putnl(resv, RPC_AUTH_NULL);
+       svc_putnl(resv, 0);
 
        return SVC_OK;
 
index 953aff89bcac1cf3399e28cd7b9e6f401070123d..5b0fe1b66a23d5fbed578179268bedc15eae52c2 100644 (file)
@@ -1030,7 +1030,7 @@ svc_tcp_sendto(struct svc_rqst *rqstp)
 {
        struct xdr_buf  *xbufp = &rqstp->rq_res;
        int sent;
-       u32 reclen;
+       __be32 reclen;
 
        /* Set up the first element of the reply kvec.
         * Any other kvecs that may be in use have been taken
@@ -1393,14 +1393,12 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
        if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
                return error;
 
-       if (sin != NULL) {
-               if (type == SOCK_STREAM)
-                       sock->sk->sk_reuse = 1; /* allow address reuse */
-               error = kernel_bind(sock, (struct sockaddr *) sin,
-                                               sizeof(*sin));
-               if (error < 0)
-                       goto bummer;
-       }
+       if (type == SOCK_STREAM)
+               sock->sk->sk_reuse = 1; /* allow address reuse */
+       error = kernel_bind(sock, (struct sockaddr *) sin,
+                                       sizeof(*sin));
+       if (error < 0)
+               goto bummer;
 
        if (protocol == IPPROTO_TCP) {
                if ((error = kernel_listen(sock, 64)) < 0)
index 6ac45103a272343a885a234cdda576dc6b655088..9022eb8b37ed9d05ea2e1bd983747b49b4c0ff7b 100644 (file)
@@ -18,8 +18,8 @@
 /*
  * XDR functions for basic NFS types
  */
-u32 *
-xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj)
+__be32 *
+xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj)
 {
        unsigned int    quadlen = XDR_QUADLEN(obj->len);
 
@@ -29,8 +29,8 @@ xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj)
        return p + XDR_QUADLEN(obj->len);
 }
 
-u32 *
-xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
+__be32 *
+xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj)
 {
        unsigned int    len;
 
@@ -55,7 +55,7 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
  * Returns the updated current XDR buffer position
  *
  */
-u32 *xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int nbytes)
+__be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int nbytes)
 {
        if (likely(nbytes != 0)) {
                unsigned int quadlen = XDR_QUADLEN(nbytes);
@@ -79,21 +79,21 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed);
  *
  * Returns the updated current XDR buffer position
  */
-u32 *xdr_encode_opaque(u32 *p, const void *ptr, unsigned int nbytes)
+__be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int nbytes)
 {
        *p++ = htonl(nbytes);
        return xdr_encode_opaque_fixed(p, ptr, nbytes);
 }
 EXPORT_SYMBOL(xdr_encode_opaque);
 
-u32 *
-xdr_encode_string(u32 *p, const char *string)
+__be32 *
+xdr_encode_string(__be32 *p, const char *string)
 {
        return xdr_encode_array(p, string, strlen(string));
 }
 
-u32 *
-xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen)
+__be32 *
+xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen)
 {
        unsigned int    len;
 
@@ -432,7 +432,7 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
  *      of the buffer length, and takes care of adjusting the kvec
  *      length for us.
  */
-void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
 {
        struct kvec *iov = buf->head;
        int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
@@ -440,8 +440,8 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
        BUG_ON(scratch_len < 0);
        xdr->buf = buf;
        xdr->iov = iov;
-       xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
-       xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
+       xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len);
+       xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len);
        BUG_ON(iov->iov_len > scratch_len);
 
        if (p != xdr->p && p != NULL) {
@@ -465,10 +465,10 @@ EXPORT_SYMBOL(xdr_init_encode);
  * bytes of data. If so, update the total xdr_buf length, and
  * adjust the length of the current kvec.
  */
-uint32_t * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
+__be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
 {
-       uint32_t *p = xdr->p;
-       uint32_t *q;
+       __be32 *p = xdr->p;
+       __be32 *q;
 
        /* align nbytes on the next 32-bit boundary */
        nbytes += 3;
@@ -524,7 +524,7 @@ EXPORT_SYMBOL(xdr_write_pages);
  * @buf: pointer to XDR buffer from which to decode data
  * @p: current pointer inside XDR buffer
  */
-void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
 {
        struct kvec *iov = buf->head;
        unsigned int len = iov->iov_len;
@@ -534,7 +534,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
        xdr->buf = buf;
        xdr->iov = iov;
        xdr->p = p;
-       xdr->end = (uint32_t *)((char *)iov->iov_base + len);
+       xdr->end = (__be32 *)((char *)iov->iov_base + len);
 }
 EXPORT_SYMBOL(xdr_init_decode);
 
@@ -548,10 +548,10 @@ EXPORT_SYMBOL(xdr_init_decode);
  * If so return the current pointer, then update the current
  * pointer position.
  */
-uint32_t * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
+__be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
 {
-       uint32_t *p = xdr->p;
-       uint32_t *q = p + XDR_QUADLEN(nbytes);
+       __be32 *p = xdr->p;
+       __be32 *q = p + XDR_QUADLEN(nbytes);
 
        if (unlikely(q > xdr->end || q < p))
                return NULL;
@@ -599,8 +599,8 @@ void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
         * Position current pointer at beginning of tail, and
         * set remaining message length.
         */
-       xdr->p = (uint32_t *)((char *)iov->iov_base + padding);
-       xdr->end = (uint32_t *)((char *)iov->iov_base + end);
+       xdr->p = (__be32 *)((char *)iov->iov_base + padding);
+       xdr->end = (__be32 *)((char *)iov->iov_base + end);
 }
 EXPORT_SYMBOL(xdr_read_pages);
 
@@ -624,8 +624,8 @@ void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
         */
        if (len > PAGE_CACHE_SIZE - xdr->buf->page_base)
                len = PAGE_CACHE_SIZE - xdr->buf->page_base;
-       xdr->p = (uint32_t *)(kaddr + xdr->buf->page_base);
-       xdr->end = (uint32_t *)((char *)xdr->p + len);
+       xdr->p = (__be32 *)(kaddr + xdr->buf->page_base);
+       xdr->end = (__be32 *)((char *)xdr->p + len);
 }
 EXPORT_SYMBOL(xdr_enter_page);
 
@@ -743,7 +743,7 @@ out:
 int
 xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
 {
-       u32     raw;
+       __be32  raw;
        int     status;
 
        status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
@@ -756,7 +756,7 @@ xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
 int
 xdr_encode_word(struct xdr_buf *buf, int base, u32 obj)
 {
-       u32     raw = htonl(obj);
+       __be32  raw = htonl(obj);
 
        return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
 }
index 1f786f68729d465c8bc7f3fb51b45465a4c89aa2..80857470dc112f15fe18bbd91510e6147243e5e3 100644 (file)
@@ -594,7 +594,7 @@ static void xprt_connect_status(struct rpc_task *task)
  * @xid: RPC XID of incoming reply
  *
  */
-struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
+struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
 {
        struct list_head *pos;
 
@@ -801,7 +801,7 @@ void xprt_reserve(struct rpc_task *task)
        spin_unlock(&xprt->reserve_lock);
 }
 
-static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
+static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)
 {
        return xprt->xid++;
 }
index 9b62923a9c0689fd75569fb494e66604f06ce4e7..28100e01922516045b9530f46df41fadb8738729 100644 (file)
@@ -548,7 +548,8 @@ static void xs_udp_data_ready(struct sock *sk, int len)
        struct rpc_rqst *rovr;
        struct sk_buff *skb;
        int err, repsize, copied;
-       u32 _xid, *xp;
+       u32 _xid;
+       __be32 *xp;
 
        read_lock(&sk->sk_callback_lock);
        dprintk("RPC:      xs_udp_data_ready...\n");
index d3abb0b7dc62190259c941fb28cdfc068d32c1df..6ac4e4f033aca67e1d7178efb4347c98a672aa1b 100644 (file)
@@ -58,10 +58,10 @@ static inline unsigned __xfrm_src_hash(xfrm_address_t *saddr,
 }
 
 static inline unsigned int
-__xfrm_spi_hash(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family,
+__xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family,
                unsigned int hmask)
 {
-       unsigned int h = spi ^ proto;
+       unsigned int h = (__force u32)spi ^ proto;
        switch (family) {
        case AF_INET:
                h ^= __xfrm4_addr_hash(daddr);
index dfc90bb1cf1f53d054c2fc7f15e0b72ed3013f2a..e8198a2c785df7416143c0781bd042f8aba995d2 100644 (file)
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(secpath_dup);
 
 /* Fetch spi and seq from ipsec header */
 
-int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
        int offset, offset_seq;
 
@@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
        case IPPROTO_COMP:
                if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
                        return -EINVAL;
-               *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2)));
+               *spi = htonl(ntohs(*(__be16*)(skb->h.raw + 2)));
                *seq = 0;
                return 0;
        default:
@@ -72,8 +72,8 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
        if (!pskb_may_pull(skb, 16))
                return -EINVAL;
 
-       *spi = *(u32*)(skb->h.raw + offset);
-       *seq = *(u32*)(skb->h.raw + offset_seq);
+       *spi = *(__be32*)(skb->h.raw + offset);
+       *seq = *(__be32*)(skb->h.raw + offset_seq);
        return 0;
 }
 EXPORT_SYMBOL(xfrm_parse_spi);
index 9f63edd39346538252f07a40b5925850e61f1511..f927b7330f025cca4c05ed0dd7157edd2723924e 100644 (file)
@@ -70,7 +70,7 @@ static inline unsigned int xfrm_src_hash(xfrm_address_t *addr,
 }
 
 static inline unsigned int
-xfrm_spi_hash(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family)
+xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
        return __xfrm_spi_hash(daddr, spi, proto, family, xfrm_state_hmask);
 }
@@ -96,9 +96,12 @@ static void xfrm_hash_transfer(struct hlist_head *list,
                                    nhashmask);
                hlist_add_head(&x->bysrc, nsrctable+h);
 
-               h = __xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
-                                   x->props.family, nhashmask);
-               hlist_add_head(&x->byspi, nspitable+h);
+               if (x->id.spi) {
+                       h = __xfrm_spi_hash(&x->id.daddr, x->id.spi,
+                                           x->id.proto, x->props.family,
+                                           nhashmask);
+                       hlist_add_head(&x->byspi, nspitable+h);
+               }
        }
 }
 
@@ -421,7 +424,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
        return 0;
 }
 
-static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family)
+static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
        unsigned int h = xfrm_spi_hash(daddr, spi, proto, family);
        struct xfrm_state *x;
@@ -622,7 +625,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
        h = xfrm_src_hash(&x->props.saddr, x->props.family);
        hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 
-       if (xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY)) {
+       if (x->id.spi) {
                h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
                                  x->props.family);
 
@@ -916,7 +919,7 @@ err:
 EXPORT_SYMBOL(xfrm_state_check);
 
 struct xfrm_state *
-xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
+xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto,
                  unsigned short family)
 {
        struct xfrm_state *x;
@@ -1040,7 +1043,7 @@ u32 xfrm_get_acqseq(void)
 EXPORT_SYMBOL(xfrm_get_acqseq);
 
 void
-xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
+xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi)
 {
        unsigned int h;
        struct xfrm_state *x0;
@@ -1057,10 +1060,10 @@ xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
                x->id.spi = minspi;
        } else {
                u32 spi = 0;
-               minspi = ntohl(minspi);
-               maxspi = ntohl(maxspi);
-               for (h=0; h<maxspi-minspi+1; h++) {
-                       spi = minspi + net_random()%(maxspi-minspi+1);
+               u32 low = ntohl(minspi);
+               u32 high = ntohl(maxspi);
+               for (h=0; h<high-low+1; h++) {
+                       spi = low + net_random()%(high-low+1);
                        x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family);
                        if (x0 == NULL) {
                                x->id.spi = htonl(spi);
@@ -1180,11 +1183,10 @@ static void xfrm_replay_timer_handler(unsigned long data)
        spin_unlock(&x->lock);
 }
 
-int xfrm_replay_check(struct xfrm_state *x, u32 seq)
+int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
 {
        u32 diff;
-
-       seq = ntohl(seq);
+       u32 seq = ntohl(net_seq);
 
        if (unlikely(seq == 0))
                return -EINVAL;
@@ -1206,11 +1208,10 @@ int xfrm_replay_check(struct xfrm_state *x, u32 seq)
 }
 EXPORT_SYMBOL(xfrm_replay_check);
 
-void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
+void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
 {
        u32 diff;
-
-       seq = ntohl(seq);
+       u32 seq = ntohl(net_seq);
 
        if (seq > x->replay.seq) {
                diff = seq - x->replay.seq;
index cb02baa63256ba691501ac65ddea70cadb1112c4..4ab6cbf092256bad17214ae86529de37c93efd95 100644 (file)
@@ -177,6 +177,7 @@ void find_export_symbols(char * filename)
                {
                        fprintf(stderr, "docproc: ");
                        perror(real_filename);
+                       exit(1);
                }
                while(fgets(line, MAXLINESZ, fp)) {
                        char *p;
index 67785df264e511c83550455240f633dc99cc3483..460e5c9cf496c725b830d8f34bc8dcf0bd8bff56 100644 (file)
@@ -93,18 +93,6 @@ config SECURITY_ROOTPLUG
          
          If you are unsure how to answer this question, answer N.
 
-config SECURITY_SECLVL
-       tristate "BSD Secure Levels"
-       depends on SECURITY
-       select CRYPTO
-       select CRYPTO_SHA1
-       help
-         Implements BSD Secure Levels as an LSM.  See
-         <file:Documentation/seclvl.txt> for instructions on how to use this
-         module.
-
-         If you are unsure how to answer this question, answer N.
-
 source security/selinux/Kconfig
 
 endmenu
index 8cbbf2f3670987d47e823b11b27be3b487735698..ef87df2f50a454ac0f9c5aedeb235b347a2706b4 100644 (file)
@@ -16,4 +16,3 @@ obj-$(CONFIG_SECURITY)                        += security.o dummy.o inode.o
 obj-$(CONFIG_SECURITY_SELINUX)         += selinux/built-in.o
 obj-$(CONFIG_SECURITY_CAPABILITIES)    += commoncap.o capability.o
 obj-$(CONFIG_SECURITY_ROOTPLUG)                += commoncap.o root_plug.o
-obj-$(CONFIG_SECURITY_SECLVL)          += seclvl.o
index f50fc298cf801991879bee1de094dd56671562c3..5a5ef5ca7ea97eb9a2ef3901e3faff71fcaefcc6 100644 (file)
@@ -169,7 +169,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
        /* For init, we want to retain the capabilities set
         * in the init_task struct. Thus we skip the usual
         * capability rules */
-       if (current->pid != 1) {
+       if (!is_init(current)) {
                current->cap_permitted = new_permitted;
                current->cap_effective =
                    cap_intersect (new_permitted, bprm->cap_effective);
diff --git a/security/seclvl.c b/security/seclvl.c
deleted file mode 100644 (file)
index 8f62919..0000000
+++ /dev/null
@@ -1,671 +0,0 @@
-/**
- * BSD Secure Levels LSM
- *
- * Maintainers:
- *     Michael A. Halcrow <mike@halcrow.us>
- *     Serge Hallyn <hallyn@cs.wm.edu>
- *
- * Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com>
- * Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2002 International Business Machines <robb@austin.ibm.com>
- * Copyright (c) 2006 Davi E. M. Arnaut <davi.arnaut@gmail.com>
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- */
-
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/security.h>
-#include <linux/netlink.h>
-#include <linux/fs.h>
-#include <linux/namei.h>
-#include <linux/mount.h>
-#include <linux/capability.h>
-#include <linux/time.h>
-#include <linux/proc_fs.h>
-#include <linux/kobject.h>
-#include <linux/crypto.h>
-#include <asm/scatterlist.h>
-#include <linux/scatterlist.h>
-#include <linux/gfp.h>
-#include <linux/sysfs.h>
-
-#define SHA1_DIGEST_SIZE 20
-
-/**
- * Module parameter that defines the initial secure level.
- *
- * When built as a module, it defaults to seclvl 1, which is the
- * behavior of BSD secure levels.  Note that this default behavior
- * wrecks havoc on a machine when the seclvl module is compiled into
- * the kernel. In that case, we default to seclvl 0.
- */
-#ifdef CONFIG_SECURITY_SECLVL_MODULE
-static int initlvl = 1;
-#else
-static int initlvl;
-#endif
-module_param(initlvl, int, 0);
-MODULE_PARM_DESC(initlvl, "Initial secure level (defaults to 1)");
-
-/* Module parameter that defines the verbosity level */
-static int verbosity;
-module_param(verbosity, int, 0);
-MODULE_PARM_DESC(verbosity, "Initial verbosity level (0 or 1; defaults to "
-                "0, which is Quiet)");
-
-/**
- * Optional password which can be passed in to bring seclvl to 0
- * (i.e., for halt/reboot).  Defaults to NULL (the passwd attribute
- * file will not be registered in sysfs).
- *
- * This gets converted to its SHA1 hash when stored.  It's probably
- * not a good idea to use this parameter when loading seclvl from a
- * script; use sha1_passwd instead.
- */
-
-#define MAX_PASSWD_SIZE        32
-static char passwd[MAX_PASSWD_SIZE];
-module_param_string(passwd, passwd, sizeof(passwd), 0);
-MODULE_PARM_DESC(passwd,
-                "Plaintext of password that sets seclvl=0 when written to "
-                "(sysfs mount point)/seclvl/passwd\n");
-
-/**
- * SHA1 hashed version of the optional password which can be passed in
- * to bring seclvl to 0 (i.e., for halt/reboot).  Must be in
- * hexadecimal format (40 characters). Defaults to NULL (the passwd
- * attribute file will not be registered in sysfs).
- *
- * Use the sha1sum utility to generate the SHA1 hash of a password:
- *
- * echo -n "secret" | sha1sum
- */
-#define MAX_SHA1_PASSWD        41
-static char sha1_passwd[MAX_SHA1_PASSWD];
-module_param_string(sha1_passwd, sha1_passwd, sizeof(sha1_passwd), 0);
-MODULE_PARM_DESC(sha1_passwd,
-                "SHA1 hash (40 hexadecimal characters) of password that "
-                "sets seclvl=0 when plaintext password is written to "
-                "(sysfs mount point)/seclvl/passwd\n");
-
-static int hideHash = 1;
-module_param(hideHash, int, 0);
-MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
-                "will return the SHA1-hashed value of the password that "
-                "lowers the secure level to 0.\n");
-
-#define MY_NAME "seclvl"
-
-/**
- * This time-limits log writes to one per second.
- */
-#define seclvl_printk(verb, type, fmt, arg...)                 \
-       do {                                                    \
-               if (verbosity >= verb) {                        \
-                       static unsigned long _prior;            \
-                       unsigned long _now = jiffies;           \
-                       if ((_now - _prior) > HZ) {             \
-                               printk(type "%s: %s: " fmt,     \
-                                       MY_NAME, __FUNCTION__ , \
-                                       ## arg);                \
-                               _prior = _now;                  \
-                       }                                       \
-               }                                               \
-       } while (0)
-
-/**
- * The actual security level.  Ranges between -1 and 2 inclusive.
- */
-static int seclvl;
-
-/**
- * flag to keep track of how we were registered
- */
-static int secondary;
-
-/**
- * Verifies that the requested secure level is valid, given the current
- * secure level.
- */
-static int seclvl_sanity(int reqlvl)
-{
-       if ((reqlvl < -1) || (reqlvl > 2)) {
-               seclvl_printk(1, KERN_WARNING, "Attempt to set seclvl out of "
-                             "range: [%d]\n", reqlvl);
-               return -EINVAL;
-       }
-       if ((seclvl == 0) && (reqlvl == -1))
-               return 0;
-       if (reqlvl < seclvl) {
-               seclvl_printk(1, KERN_WARNING, "Attempt to lower seclvl to "
-                             "[%d]\n", reqlvl);
-               return -EPERM;
-       }
-       return 0;
-}
-
-/**
- * security level advancement rules:
- *   Valid levels are -1 through 2, inclusive.
- *   From -1, stuck.  [ in case compiled into kernel ]
- *   From 0 or above, can only increment.
- */
-static void do_seclvl_advance(void *data, u64 val)
-{
-       int ret;
-       int newlvl = (int)val;
-
-       ret = seclvl_sanity(newlvl);
-       if (ret)
-               return;
-
-       if (newlvl > 2) {
-               seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
-                             "[%d]\n", newlvl);
-               return;
-       }
-       if (seclvl == -1) {
-               seclvl_printk(1, KERN_WARNING, "Not allowed to advance to "
-                             "seclvl [%d]\n", seclvl);
-               return;
-       }
-       seclvl = newlvl;  /* would it be more "correct" to set *data? */
-       return;
-}
-
-static u64 seclvl_int_get(void *data)
-{
-       return *(int *)data;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(seclvl_file_ops, seclvl_int_get, do_seclvl_advance, "%lld\n");
-
-static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
-
-/**
- * Converts a block of plaintext of into its SHA1 hashed value.
- *
- * It would be nice if crypto had a wrapper to do this for us linear
- * people...
- */
-static int
-plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
-{
-       struct hash_desc desc;
-       struct scatterlist sg;
-       int err;
-
-       if (len > PAGE_SIZE) {
-               seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
-                             "characters).  Largest possible is %lu "
-                             "bytes.\n", len, PAGE_SIZE);
-               return -EINVAL;
-       }
-       desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(desc.tfm)) {
-               seclvl_printk(0, KERN_ERR,
-                             "Failed to load transform for SHA1\n");
-               return -EINVAL;
-       }
-       sg_init_one(&sg, (u8 *)plaintext, len);
-       desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-       err = crypto_hash_digest(&desc, &sg, len, hash);
-       crypto_free_hash(desc.tfm);
-       return err;
-}
-
-/**
- * Called whenever the user writes to the sysfs passwd handle to this kernel
- * object.  It hashes the password and compares the hashed results.
- */
-static ssize_t
-passwd_write_file(struct file * file, const char __user * buf,
-                               size_t count, loff_t *ppos)
-{
-       char *p;
-       int len;
-       unsigned char tmp[SHA1_DIGEST_SIZE];
-
-       if (!*passwd && !*sha1_passwd) {
-               seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
-                             "seclvl module, but neither a plain text "
-                             "password nor a SHA1 hashed password was "
-                             "passed in as a module parameter!  This is a "
-                             "bug, since it should not be possible to be in "
-                             "this part of the module; please tell a "
-                             "maintainer about this event.\n");
-               return -EINVAL;
-       }
-
-       if (count >= PAGE_SIZE)
-               return -EINVAL;
-       if (*ppos != 0)
-               return -EINVAL;
-       p = kmalloc(count, GFP_KERNEL);
-       if (!p)
-               return -ENOMEM;
-       len = -EFAULT;
-       if (copy_from_user(p, buf, count))
-               goto out;
-       
-       len = count;
-       /* ``echo "secret" > seclvl/passwd'' includes a newline */
-       if (p[len - 1] == '\n')
-               len--;
-       /* Hash the password, then compare the hashed values */
-       if ((len = plaintext_to_sha1(tmp, p, len))) {
-               seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
-                             "[%d]\n", len);
-               goto out;
-       }
-
-       len = -EPERM;
-       if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE))
-               goto out;
-
-       seclvl_printk(0, KERN_INFO,
-                     "Password accepted; seclvl reduced to 0.\n");
-       seclvl = 0;
-       len = count;
-
-out:
-       kfree (p);
-       return len;
-}
-
-static struct file_operations passwd_file_ops = {
-       .write = passwd_write_file,
-};
-
-/**
- * Explicitely disallow ptrace'ing the init process.
- */
-static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
-{
-       if (seclvl >= 0 && child->pid == 1) {
-               seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
-                             "the init process dissallowed in "
-                             "secure level %d\n", seclvl);
-               return -EPERM;
-       }
-       return 0;
-}
-
-/**
- * Capability checks for seclvl.  The majority of the policy
- * enforcement for seclvl takes place here.
- */
-static int seclvl_capable(struct task_struct *tsk, int cap)
-{
-       int rc = 0;
-
-       /* init can do anything it wants */
-       if (tsk->pid == 1)
-               return 0;
-
-       if (seclvl > 0) {
-               rc = -EPERM;
-
-               if (cap == CAP_LINUX_IMMUTABLE)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to modify "
-                                     "the IMMUTABLE and/or APPEND extended "
-                                     "attribute on a file with the IMMUTABLE "
-                                     "and/or APPEND extended attribute set "
-                                     "denied in seclvl [%d]\n", seclvl);
-               else if (cap == CAP_SYS_RAWIO)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to perform "
-                                     "raw I/O while in secure level [%d] "
-                                     "denied\n", seclvl);
-               else if (cap == CAP_NET_ADMIN)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to perform "
-                                     "network administrative task while "
-                                     "in secure level [%d] denied\n", seclvl);
-               else if (cap == CAP_SETUID)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to setuid "
-                                     "while in secure level [%d] denied\n",
-                                     seclvl);
-               else if (cap == CAP_SETGID)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to setgid "
-                                     "while in secure level [%d] denied\n",
-                                     seclvl);
-               else if (cap == CAP_SYS_MODULE)
-                       seclvl_printk(1, KERN_WARNING, "Attempt to perform "
-                                     "a module operation while in secure "
-                                     "level [%d] denied\n", seclvl);
-               else
-                       rc = 0;
-       }
-
-       if (!rc) {
-               if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0))
-                       rc = -EPERM;
-       }
-
-       if (rc)
-               seclvl_printk(1, KERN_WARNING, "Capability denied\n");
-
-       return rc;
-}
-
-/**
- * Disallow reversing the clock in seclvl > 1
- */
-static int seclvl_settime(struct timespec *tv, struct timezone *tz)
-{
-       if (tv && seclvl > 1) {
-               struct timespec now;
-               now = current_kernel_time();
-               if (tv->tv_sec < now.tv_sec ||
-                   (tv->tv_sec == now.tv_sec && tv->tv_nsec < now.tv_nsec)) {
-                       seclvl_printk(1, KERN_WARNING, "Attempt to decrement "
-                                     "time in secure level %d denied: "
-                                     "current->pid = [%d], "
-                                     "current->group_leader->pid = [%d]\n",
-                                     seclvl, current->pid,
-                                     current->group_leader->pid);
-                       return -EPERM;
-               }               /* if attempt to decrement time */
-       }                       /* if seclvl > 1 */
-       return 0;
-}
-
-/* claim the blockdev to exclude mounters, release on file close */
-static int seclvl_bd_claim(struct inode *inode)
-{
-       int holder;
-       struct block_device *bdev = NULL;
-       dev_t dev = inode->i_rdev;
-       bdev = open_by_devnum(dev, FMODE_WRITE);
-       if (bdev) {
-               if (bd_claim(bdev, &holder)) {
-                       blkdev_put(bdev);
-                       return -EPERM;
-               }
-               /* claimed, mark it to release on close */
-               inode->i_security = current;
-       }
-       return 0;
-}
-
-/* release the blockdev if you claimed it */
-static void seclvl_bd_release(struct inode *inode)
-{
-       if (inode && S_ISBLK(inode->i_mode) && inode->i_security == current) {
-               struct block_device *bdev = inode->i_bdev;
-               if (bdev) {
-                       bd_release(bdev);
-                       blkdev_put(bdev);
-                       inode->i_security = NULL;
-               }
-       }
-}
-
-/**
- * Security for writes to block devices is regulated by this seclvl
- * function.  Deny all writes to block devices in seclvl 2.  In
- * seclvl 1, we only deny writes to *mounted* block devices.
- */
-static int
-seclvl_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
-       if (current->pid != 1 && S_ISBLK(inode->i_mode) && (mask & MAY_WRITE)) {
-               switch (seclvl) {
-               case 2:
-                       seclvl_printk(1, KERN_WARNING, "Write to block device "
-                                     "denied in secure level [%d]\n", seclvl);
-                       return -EPERM;
-               case 1:
-                       if (seclvl_bd_claim(inode)) {
-                               seclvl_printk(1, KERN_WARNING,
-                                             "Write to mounted block device "
-                                             "denied in secure level [%d]\n",
-                                             seclvl);
-                               return -EPERM;
-                       }
-               }
-       }
-       return 0;
-}
-
-/**
- * The SUID and SGID bits cannot be set in seclvl >= 1
- */
-static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
-{
-       if (seclvl > 0) {
-               if (iattr->ia_valid & ATTR_MODE)
-                       if (iattr->ia_mode & S_ISUID ||
-                           iattr->ia_mode & S_ISGID) {
-                               seclvl_printk(1, KERN_WARNING, "Attempt to "
-                                             "modify SUID or SGID bit "
-                                             "denied in seclvl [%d]\n",
-                                             seclvl);
-                               return -EPERM;
-                       }
-       }
-       return 0;
-}
-
-/* release busied block devices */
-static void seclvl_file_free_security(struct file *filp)
-{
-       struct dentry *dentry = filp->f_dentry;
-
-       if (dentry)
-               seclvl_bd_release(dentry->d_inode);
-}
-
-/**
- * Cannot unmount in secure level 2
- */
-static int seclvl_umount(struct vfsmount *mnt, int flags)
-{
-       if (current->pid != 1 && seclvl == 2) {
-               seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
-                             "level %d\n", seclvl);
-               return -EPERM;
-       }
-       return 0;
-}
-
-static struct security_operations seclvl_ops = {
-       .ptrace = seclvl_ptrace,
-       .capable = seclvl_capable,
-       .inode_permission = seclvl_inode_permission,
-       .inode_setattr = seclvl_inode_setattr,
-       .file_free_security = seclvl_file_free_security,
-       .settime = seclvl_settime,
-       .sb_umount = seclvl_umount,
-};
-
-/**
- * Process the password-related module parameters
- */
-static int processPassword(void)
-{
-       int rc = 0;
-       if (*passwd) {
-               char *p;
-
-               if (*sha1_passwd) {
-                       seclvl_printk(0, KERN_ERR, "Error: Both "
-                                     "passwd and sha1_passwd "
-                                     "were set, but they are mutually "
-                                     "exclusive.\n");
-                       return -EINVAL;
-               }
-
-               p = kstrdup(passwd, GFP_KERNEL);
-               if (p == NULL)
-                       return -ENOMEM;
-
-               if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p))))
-                       seclvl_printk(0, KERN_ERR, "Error: SHA1 support not "
-                                     "in kernel\n");
-
-               kfree (p);
-               /* All static data goes to the BSS, which zero's the
-                * plaintext password out for us. */
-       } else if (*sha1_passwd) {      // Base 16
-               int i;
-               i = strlen(sha1_passwd);
-               if (i != (SHA1_DIGEST_SIZE * 2)) {
-                       seclvl_printk(0, KERN_ERR, "Received [%d] bytes; "
-                                     "expected [%d] for the hexadecimal "
-                                     "representation of the SHA1 hash of "
-                                     "the password.\n",
-                                     i, (SHA1_DIGEST_SIZE * 2));
-                       return -EINVAL;
-               }
-               while ((i -= 2) + 2) {
-                       unsigned char tmp;
-                       tmp = sha1_passwd[i + 2];
-                       sha1_passwd[i + 2] = '\0';
-                       hashedPassword[i / 2] = (unsigned char)
-                           simple_strtol(&sha1_passwd[i], NULL, 16);
-                       sha1_passwd[i + 2] = tmp;
-               }
-       }
-       return rc;
-}
-
-/**
- * securityfs registrations
- */
-struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
-
-static int seclvlfs_register(void)
-{
-       int rc = 0;
-
-       dir_ino = securityfs_create_dir("seclvl", NULL);
-
-       if (IS_ERR(dir_ino))
-               return PTR_ERR(dir_ino);
-
-       seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
-                               dir_ino, &seclvl, &seclvl_file_ops);
-       if (IS_ERR(seclvl_ino)) {
-               rc = PTR_ERR(seclvl_ino);
-               goto out_deldir;
-       }
-       if (*passwd || *sha1_passwd) {
-               passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
-                               dir_ino, NULL, &passwd_file_ops);
-               if (IS_ERR(passwd_ino)) {
-                       rc = PTR_ERR(passwd_ino);
-                       goto out_delf;
-               }
-       }
-       return rc;
-
-out_delf:
-       securityfs_remove(seclvl_ino);
-
-out_deldir:
-       securityfs_remove(dir_ino);
-
-       return rc;
-}
-
-static void seclvlfs_unregister(void)
-{
-       securityfs_remove(seclvl_ino);
-
-       if (*passwd || *sha1_passwd)
-               securityfs_remove(passwd_ino);
-
-       securityfs_remove(dir_ino);
-}
-
-/**
- * Initialize the seclvl module.
- */
-static int __init seclvl_init(void)
-{
-       int rc = 0;
-       static char once;
-
-       if (verbosity < 0 || verbosity > 1) {
-               printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 "
-                      "are valid values\n", verbosity);
-               rc = -EINVAL;
-               goto exit;
-       }
-       if (initlvl < -1 || initlvl > 2) {
-               seclvl_printk(0, KERN_ERR, "Error: bad initial securelevel "
-                             "[%d].\n", initlvl);
-               rc = -EINVAL;
-               goto exit;
-       }
-       seclvl = initlvl;
-       if ((rc = processPassword())) {
-               seclvl_printk(0, KERN_ERR, "Error processing the password "
-                             "module parameter(s): rc = [%d]\n", rc);
-               goto exit;
-       }
-
-       if ((rc = seclvlfs_register())) {
-               seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
-               goto exit;
-       }
-       /* register ourselves with the security framework */
-       if (register_security(&seclvl_ops)) {
-               seclvl_printk(0, KERN_ERR,
-                             "seclvl: Failure registering with the "
-                             "kernel.\n");
-               /* try registering with primary module */
-               rc = mod_reg_security(MY_NAME, &seclvl_ops);
-               if (rc) {
-                       seclvl_printk(0, KERN_ERR, "seclvl: Failure "
-                                     "registering with primary security "
-                                     "module.\n");
-                       seclvlfs_unregister();
-                       goto exit;
-               }               /* if primary module registered */
-               secondary = 1;
-       }                       /* if we registered ourselves with the security framework */
-
-       seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n");
-
-       if (once) {
-               once = 1;
-               seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been "
-                               "buggy for ages. Also, be warned that "
-                               "Securelevels are useless.");
-       }
- exit:
-       if (rc)
-               printk(KERN_ERR "seclvl: Error during initialization: rc = "
-                      "[%d]\n", rc);
-       return rc;
-}
-
-/**
- * Remove the seclvl module.
- */
-static void __exit seclvl_exit(void)
-{
-       seclvlfs_unregister();
-
-       if (secondary)
-               mod_unreg_security(MY_NAME, &seclvl_ops);
-       else if (unregister_security(&seclvl_ops))
-               seclvl_printk(0, KERN_INFO,
-                             "seclvl: Failure unregistering with the "
-                             "kernel\n");
-}
-
-module_init(seclvl_init);
-module_exit(seclvl_exit);
-
-MODULE_AUTHOR("Michael A. Halcrow <mike@halcrow.us>");
-MODULE_DESCRIPTION("LSM implementation of the BSD Secure Levels");
-MODULE_LICENSE("GPL");
index e4d81a42fca4205f9faa8962caca88af01d9245d..e9969a2fc8462116a5b8cb256e1e8cbc97a7fd3c 100644 (file)
@@ -398,7 +398,7 @@ static int try_context_mount(struct super_block *sb, void *data)
                /* Standard string-based options. */
                char *p, *options = data;
 
-               while ((p = strsep(&options, ",")) != NULL) {
+               while ((p = strsep(&options, "|")) != NULL) {
                        int token;
                        substring_t args[MAX_OPT_ARGS];
 
@@ -1923,18 +1923,40 @@ static inline void take_option(char **to, char *from, int *first, int len)
        if (!*first) {
                **to = ',';
                *to += 1;
-       }
-       else
+       } else
                *first = 0;
        memcpy(*to, from, len);
        *to += len;
 }
 
+static inline void take_selinux_option(char **to, char *from, int *first, 
+                                      int len)
+{
+       int current_size = 0;
+
+       if (!*first) {
+               **to = '|';
+               *to += 1;
+       }
+       else
+               *first = 0;
+
+       while (current_size < len) {
+               if (*from != '"') {
+                       **to = *from;
+                       *to += 1;
+               }
+               from += 1;
+               current_size += 1;
+       }
+}
+
 static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
 {
        int fnosec, fsec, rc = 0;
        char *in_save, *in_curr, *in_end;
        char *sec_curr, *nosec_save, *nosec;
+       int open_quote = 0;
 
        in_curr = orig;
        sec_curr = copy;
@@ -1956,11 +1978,14 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
        in_save = in_end = orig;
 
        do {
-               if (*in_end == ',' || *in_end == '\0') {
+               if (*in_end == '"')
+                       open_quote = !open_quote;
+               if ((*in_end == ',' && open_quote == 0) ||
+                               *in_end == '\0') {
                        int len = in_end - in_curr;
 
                        if (selinux_option(in_curr, len))
-                               take_option(&sec_curr, in_curr, &fsec, len);
+                               take_selinux_option(&sec_curr, in_curr, &fsec, len);
                        else
                                take_option(&nosec, in_curr, &fnosec, len);
 
@@ -3594,7 +3619,9 @@ static void selinux_sock_graft(struct sock* sk, struct socket *parent)
        struct inode_security_struct *isec = SOCK_INODE(parent)->i_security;
        struct sk_security_struct *sksec = sk->sk_security;
 
-       isec->sid = sksec->sid;
+       if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
+           sk->sk_family == PF_UNIX)
+               isec->sid = sksec->sid;
 
        selinux_netlbl_sock_graft(sk, parent);
 }
index 1f60797afa8a42afa0a52ffdd8506d0a796cf75c..5f6bef57e825023dea13901a119d38bcd1a88c95 100644 (file)
@@ -2,6 +2,7 @@
 #
 
 obj-$(CONFIG_SOUND) += soundcore.o
+obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_DMASOUND) += oss/
 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
@@ -11,4 +12,4 @@ ifeq ($(CONFIG_SND),y)
   obj-y += last.o
 endif
 
-soundcore-objs  := sound_core.o sound_firmware.o
+soundcore-objs  := sound_core.o
index c31b38659221c4bfd4e141f60a6b85f5b89f1b8a..ff6e6fc198a18a2f20cd9276bcee6ce84e66102d 100644 (file)
@@ -258,7 +258,7 @@ au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static unsigned int rates[] = {8000, 11025, 16000, 22050};
 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
-       .count  =  sizeof(rates) / sizeof(rates[0]),
+       .count  = ARRAY_SIZE(rates),
        .list   = rates,
        .mask   = 0,
 };
diff --git a/sound/oss/COPYING b/sound/oss/COPYING
deleted file mode 100644 (file)
index 916d1f0..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-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.
-\f
-  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.
-\f
-  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
-\f
-       Appendix: How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
index 5195bf933cb893dffb481ae646329cc11ce9a46c..3f81b79afbaaa23145d429ce482b39a09ffbed94 100644 (file)
@@ -96,7 +96,7 @@
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 
-#include "cs46xxpm-24.h"
+#include "cs46xxpm.h"
 #include "cs46xx_wrapper-24.h"
 #include "cs461x.h"
 
@@ -389,8 +389,10 @@ static int cs_hardware_init(struct cs_card *card);
 static int cs46xx_powerup(struct cs_card *card, unsigned int type);
 static int cs461x_powerdown(struct cs_card *card, unsigned int type, int suspendflag);
 static void cs461x_clear_serial_FIFOs(struct cs_card *card, int type);
+#ifdef CONFIG_PM
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
 static int cs46xx_resume_tbl(struct pci_dev *pcidev);
+#endif
 
 #if CSDEBUG
 
@@ -5389,8 +5391,10 @@ static struct pci_driver cs46xx_pci_driver = {
        .id_table = cs46xx_pci_tbl,
        .probe    = cs46xx_probe,
        .remove   = __devexit_p(cs46xx_remove),
-       .suspend  = CS46XX_SUSPEND_TBL,
-       .resume   = CS46XX_RESUME_TBL,
+#ifdef CONFIG_PM
+       .suspend  = cs46xx_suspend_tbl,
+       .resume   = cs46xx_resume_tbl,
+#endif
 };
 
 static int __init cs46xx_init_module(void)
@@ -5420,7 +5424,7 @@ static void __exit cs46xx_cleanup_module(void)
 module_init(cs46xx_init_module);
 module_exit(cs46xx_cleanup_module);
 
-#if CS46XX_ACPI_SUPPORT
+#ifdef CONFIG_PM
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state)
 {
        struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
diff --git a/sound/oss/cs46xxpm-24.h b/sound/oss/cs46xxpm-24.h
deleted file mode 100644 (file)
index ad82db8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
-*
-*      "cs46xxpm-24.h" --  Cirrus Logic-Crystal CS46XX linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (pcaudio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-#ifndef __CS46XXPM24_H
-#define __CS46XXPM24_H
-
-#include <linux/pm.h>
-#include "cs46xxpm.h"
-
-
-#define CS46XX_ACPI_SUPPORT 1
-#ifdef CS46XX_ACPI_SUPPORT
-/* 
-* for now (12/22/00) only enable the pm_register PM support.
-* allow these table entries to be null.
-*/
-static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
-static int cs46xx_resume_tbl(struct pci_dev *pcidev);
-#define CS46XX_SUSPEND_TBL cs46xx_suspend_tbl
-#define CS46XX_RESUME_TBL cs46xx_resume_tbl
-#else
-#define CS46XX_SUSPEND_TBL cs46xx_null
-#define CS46XX_RESUME_TBL cs46xx_null
-#endif
-
-#endif
index 2813e4c8e365aafb6bc6b364b671c8d2e4720b10..d4844de0c3b7200aa74cb3cab286c083c80e8d63 100644 (file)
@@ -488,10 +488,6 @@ static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
 static void ali_enable_special_channel(struct trident_state *stat);
 static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card);
 static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card);
-static void ali_restore_regs(struct trident_card *card);
-static void ali_save_regs(struct trident_card *card);
-static int trident_suspend(struct pci_dev *dev, pm_message_t unused);
-static int trident_resume(struct pci_dev *dev);
 static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel);
 static int ali_setup_multi_channels(struct trident_card *card, int chan_nums);
 static unsigned int ali_get_spdif_in_rate(struct trident_card *card);
@@ -507,13 +503,6 @@ static int ali_allocate_other_states_resources(struct trident_state *state,
                                               int chan_nums);
 static void ali_free_other_states_resources(struct trident_state *state);
 
-/* save registers for ALi Power Management */
-static struct ali_saved_registers {
-       unsigned long global_regs[ALI_GLOBAL_REGS];
-       unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
-       unsigned mixer_regs[ALI_MIXER_REGS];
-} ali_registers;
-
 #define seek_offset(dma_ptr, buffer, cnt, offset, copy_count)  do { \
         (dma_ptr) += (offset);   \
        (buffer) += (offset);     \
@@ -3653,6 +3642,14 @@ ali_allocate_other_states_resources(struct trident_state *state, int chan_nums)
        return 0;
 }
 
+#ifdef CONFIG_PM
+/* save registers for ALi Power Management */
+static struct ali_saved_registers {
+       unsigned long global_regs[ALI_GLOBAL_REGS];
+       unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
+       unsigned mixer_regs[ALI_MIXER_REGS];
+} ali_registers;
+
 static void
 ali_save_regs(struct trident_card *card)
 {
@@ -3746,6 +3743,7 @@ trident_resume(struct pci_dev *dev)
        }
        return 0;
 }
+#endif
 
 static struct trident_channel *
 ali_alloc_pcm_channel(struct trident_card *card)
@@ -4616,8 +4614,10 @@ static struct pci_driver trident_pci_driver = {
        .id_table = trident_pci_tbl,
        .probe = trident_probe,
        .remove = __devexit_p(trident_remove),
+#ifdef CONFIG_PM
        .suspend = trident_suspend,
        .resume = trident_resume
+#endif
 };
 
 static int __init
index 62d4d0c812611e22227e064cfd43eb36583f70a4..0b0a016ca6d691563eac593634bc9dbdb3a39a7f 100644 (file)
@@ -551,10 +551,6 @@ int soundcore_open(struct inode *inode, struct file *file)
        return -ENODEV;
 }
 
-extern int mod_firmware_load(const char *, char **);
-EXPORT_SYMBOL(mod_firmware_load);
-
-
 MODULE_DESCRIPTION("Core sound module");
 MODULE_AUTHOR("Alan Cox");
 MODULE_LICENSE("GPL");
index 6ddadfac35adf0fc192a3627d659009456b14898..3a181d4c0dc6d3764f7da6ffdc878bb2023fe440 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
+#include "oss/sound_firmware.h"
 
 static int do_mod_firmware_load(const char *fn, char **fp)
 {
@@ -59,8 +60,7 @@ static int do_mod_firmware_load(const char *fn, char **fp)
  *     value zero on a failure.
  *
  *     Caution: This API is not recommended. Firmware should be loaded via
- *     an ioctl call and a setup application. This function may disappear
- *     in future.
+ *     request_firmware.
  */
  
 int mod_firmware_load(const char *fn, char **fp)
@@ -73,4 +73,6 @@ int mod_firmware_load(const char *fn, char **fp)
        set_fs(fs);
        return r;
 }
+EXPORT_SYMBOL(mod_firmware_load);
 
+MODULE_LICENSE("GPL");
index 8016541ec16d7d766a1e035b061a7038dd95cd87..5a97be689b401b11d057e45ac1d59f2d4b9ad9e4 100644 (file)
@@ -2412,8 +2412,6 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
        CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
 };
 
-#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(struct snd_kcontrol_new))
-
 static int __init snd_dbri_mixer(struct snd_dbri * dbri)
 {
        struct snd_card *card;
@@ -2424,7 +2422,7 @@ static int __init snd_dbri_mixer(struct snd_dbri * dbri)
        card = dbri->card;
        strcpy(card->mixername, card->shortname);
 
-       for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) {
+       for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
                if ((err = snd_ctl_add(card,
                                snd_ctl_new1(&dbri_controls[idx], dbri))) < 0)
                        return err;