Merge branch 'master'
authorJeff Garzik <jgarzik@pobox.com>
Thu, 9 Feb 2006 05:58:59 +0000 (00:58 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Thu, 9 Feb 2006 05:58:59 +0000 (00:58 -0500)
862 files changed:
CREDITS
Documentation/cputopology.txt [new file with mode: 0644]
Documentation/driver-model/overview.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/configfs/configfs_example.c
Documentation/filesystems/ocfs2.txt
Documentation/hwmon/f71805f [new file with mode: 0644]
Documentation/hwmon/it87
Documentation/hwmon/sysfs-interface
Documentation/i2c/busses/i2c-sis69x [deleted file]
Documentation/i2c/busses/i2c-sis96x [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
Documentation/parport-lowlevel.txt
Documentation/pci-error-recovery.txt
Documentation/powerpc/booting-without-of.txt
Documentation/spi/butterfly
Documentation/unshare.txt [new file with mode: 0644]
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.saa7134
Documentation/x86_64/boot-options.txt
MAINTAINERS
Makefile
arch/alpha/kernel/smp.c
arch/arm/Kconfig
arch/arm/configs/at91rm9200dk_defconfig
arch/arm/configs/at91rm9200ek_defconfig
arch/arm/configs/csb337_defconfig
arch/arm/configs/csb637_defconfig
arch/arm/configs/enp2611_defconfig
arch/arm/configs/ixdp2400_defconfig
arch/arm/configs/ixdp2401_defconfig
arch/arm/configs/ixdp2801_defconfig
arch/arm/configs/s3c2410_defconfig
arch/arm/kernel/calls.S
arch/arm/kernel/entry-armv.S
arch/arm/kernel/sys_oabi-compat.c
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-imx/mx1ads.c
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-omap1/board-generic.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-netstar.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/io.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-realview/core.c
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/clock.h
arch/arm/mach-s3c2410/cpu.c
arch/arm/mach-s3c2410/devs.c
arch/arm/mach-s3c2410/gpio.c
arch/arm/mach-s3c2410/s3c2400-gpio.c [new file with mode: 0644]
arch/arm/mach-s3c2410/s3c2410-gpio.c [new file with mode: 0644]
arch/arm/mach-s3c2410/sleep.S
arch/arm/mm/cache-v6.S
arch/arm/mm/proc-xscale.S
arch/arm/oprofile/common.c
arch/arm/plat-omap/sram.c
arch/cris/Makefile
arch/cris/arch-v10/kernel/ptrace.c
arch/cris/kernel/setup.c
arch/i386/Kconfig
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/apic.c
arch/i386/kernel/cpu/amd.c
arch/i386/kernel/cpu/centaur.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cyrix.c
arch/i386/kernel/cpu/intel_cacheinfo.c
arch/i386/kernel/cpu/nexgen.c
arch/i386/kernel/cpu/rise.c
arch/i386/kernel/cpu/transmeta.c
arch/i386/kernel/cpu/umc.c
arch/i386/kernel/nmi.c
arch/i386/kernel/process.c
arch/i386/kernel/syscall_table.S
arch/i386/kernel/traps.c
arch/i386/oprofile/backtrace.c
arch/ia64/Kconfig
arch/ia64/dig/setup.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/head.S
arch/ia64/kernel/sal.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/time.c
arch/ia64/kernel/topology.c
arch/ia64/sn/Makefile
arch/ia64/sn/kernel/Makefile
arch/ia64/sn/kernel/bte.c
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/kernel/irq.c
arch/ia64/sn/kernel/klconflib.c
arch/ia64/sn/kernel/mca.c
arch/ia64/sn/kernel/setup.c
arch/ia64/sn/kernel/sn2/Makefile
arch/ia64/sn/kernel/sn2/sn2_smp.c
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/ia64/sn/kernel/xpc_main.c
arch/ia64/sn/pci/Makefile
arch/ia64/sn/pci/pcibr/Makefile
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/setup.c
arch/m68knommu/kernel/process.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/au1000/common/reset.c
arch/mips/au1000/common/setup.c
arch/mips/cobalt/int-handler.S
arch/mips/cobalt/irq.c
arch/mips/cobalt/reset.c
arch/mips/cobalt/setup.c
arch/mips/configs/ip32_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/ddb5xxx/ddb5074/setup.c
arch/mips/ddb5xxx/ddb5476/setup.c
arch/mips/ddb5xxx/ddb5477/setup.c
arch/mips/dec/setup.c
arch/mips/gt64120/ev64120/setup.c
arch/mips/gt64120/momenco_ocelot/setup.c
arch/mips/ite-boards/generic/it8172_setup.c
arch/mips/jazz/setup.c
arch/mips/jmr3927/rbhma3100/setup.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/genex.S
arch/mips/kernel/process.c
arch/mips/kernel/ptrace32.c
arch/mips/kernel/reset.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/lasat/reset.c
arch/mips/lasat/setup.c
arch/mips/lib-32/dump_tlb.c
arch/mips/math-emu/dp_simple.c
arch/mips/math-emu/sp_simple.c
arch/mips/mips-boards/atlas/atlas_setup.c
arch/mips/mips-boards/generic/reset.c
arch/mips/mips-boards/sead/sead_setup.c
arch/mips/mips-boards/sim/sim_setup.c
arch/mips/mm/c-r4k.c
arch/mips/mm/cache.c
arch/mips/mm/init.c
arch/mips/momentum/jaguar_atx/ja-console.c
arch/mips/momentum/jaguar_atx/setup.c
arch/mips/momentum/ocelot_3/setup.c
arch/mips/momentum/ocelot_c/setup.c
arch/mips/momentum/ocelot_g/setup.c
arch/mips/oprofile/Makefile
arch/mips/oprofile/common.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/pci/Makefile
arch/mips/pci/fixup-cobalt.c
arch/mips/pci/ops-gt64111.c
arch/mips/pci/pci-bcm1480.c
arch/mips/philips/pnx8550/common/platform.c
arch/mips/philips/pnx8550/common/setup.c
arch/mips/pmc-sierra/yosemite/prom.c
arch/mips/pmc-sierra/yosemite/setup.c
arch/mips/sgi-ip22/ip22-reset.c
arch/mips/sgi-ip22/ip22-setup.c
arch/mips/sgi-ip27/ip27-reset.c
arch/mips/sgi-ip32/ip32-reset.c
arch/mips/sgi-ip32/ip32-setup.c
arch/mips/sibyte/cfe/setup.c
arch/mips/sibyte/sb1250/prom.c
arch/mips/sibyte/sb1250/setup.c
arch/mips/sni/setup.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
arch/mips/tx4938/toshiba_rbtx4938/setup.c
arch/mips/vr41xx/common/pmu.c
arch/parisc/Kconfig
arch/parisc/Kconfig.debug
arch/parisc/configs/b180_defconfig
arch/parisc/hpux/entry_hpux.S
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/drivers.c
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/perf.c
arch/parisc/kernel/perf_images.h
arch/parisc/kernel/process.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/signal32.c
arch/parisc/kernel/signal32.h
arch/parisc/kernel/syscall.S
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/traps.c
arch/parisc/math-emu/decode_exc.c
arch/parisc/mm/init.c
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/udbg_16550.c
arch/powerpc/mm/lmb.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/cell/Makefile
arch/powerpc/platforms/chrp/chrp.h
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/chrp/setup.c
arch/powerpc/platforms/chrp/time.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/pseries/eeh_driver.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/dart_iommu.c
arch/ppc/kernel/head_8xx.S
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/platforms/4xx/bamboo.c
arch/ppc/platforms/4xx/bubinga.c
arch/ppc/platforms/4xx/ebony.c
arch/ppc/platforms/4xx/luan.c
arch/ppc/platforms/4xx/ocotea.c
arch/ppc/platforms/4xx/xilinx_ml300.c
arch/ppc/platforms/4xx/yucca.c
arch/ppc/platforms/83xx/mpc834x_sys.c
arch/ppc/platforms/85xx/mpc8540_ads.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/85xx/sbc8560.c
arch/ppc/platforms/85xx/tqm85xx.c
arch/ppc/platforms/chestnut.c
arch/ppc/platforms/ev64260.c
arch/ppc/platforms/radstone_ppc7d.c
arch/ppc/platforms/spruce.c
arch/ppc/syslib/ocp.c
arch/ppc/syslib/ppc83xx_setup.c
arch/ppc/syslib/ppc85xx_setup.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/sys_s390.c
arch/s390/kernel/traps.c
arch/s390/mm/cmm.c
arch/sh/boards/renesas/rts7751r2d/io.c
arch/sh64/kernel/sh_ksyms.c
arch/sparc/kernel/entry.S
arch/sparc/kernel/process.c
arch/sparc/kernel/systbls.S
arch/sparc64/boot/.gitignore [new file with mode: 0644]
arch/sparc64/defconfig
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/systbls.S
arch/sparc64/solaris/systbl.S
arch/um/drivers/chan_user.c
arch/um/drivers/net_kern.c
arch/um/include/registers.h
arch/um/kernel/skas/process.c [deleted file]
arch/um/kernel/um_arch.c
arch/um/os-Linux/drivers/tuntap_user.c
arch/um/os-Linux/skas/mem.c
arch/um/os-Linux/skas/process.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/sys-i386/registers.c
arch/um/os-Linux/sys-x86_64/registers.c
arch/um/sys-x86_64/ptrace_user.c
arch/um/sys-x86_64/user-offsets.c
arch/v850/kernel/simcons.c
arch/x86_64/Kconfig.debug
arch/x86_64/defconfig
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/mce.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/pci-nommu.c
arch/x86_64/kernel/pci-swiotlb.c
arch/x86_64/kernel/pmtimer.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/x8664_ksyms.c
arch/x86_64/lib/clear_page.S
arch/x86_64/lib/copy_page.S
arch/x86_64/lib/copy_user.S
arch/x86_64/lib/memcpy.S
arch/x86_64/lib/memset.S
arch/x86_64/mm/fault.c
arch/x86_64/mm/srat.c
arch/x86_64/pci/mmconfig.c
arch/xtensa/platform-iss/console.c
block/elevator.c
block/ll_rw_blk.c
block/scsi_ioctl.c
crypto/scatterwalk.c
drivers/Makefile
drivers/acpi/processor_idle.c
drivers/base/Makefile
drivers/base/base.h
drivers/base/bus.c
drivers/base/memory.c
drivers/base/power/resume.c
drivers/base/power/shutdown.c
drivers/base/power/suspend.c
drivers/base/power/sysfs.c
drivers/base/sys.c
drivers/base/topology.c [new file with mode: 0644]
drivers/block/Kconfig
drivers/block/cciss.c
drivers/block/pktcdvd.c
drivers/block/umem.c
drivers/cdrom/viocd.c
drivers/char/Kconfig
drivers/char/cyclades.c
drivers/char/drm/ati_pcigart.c
drivers/char/drm/drmP.h
drivers/char/drm/drm_auth.c
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_context.c
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_fops.c
drivers/char/drm/drm_ioctl.c
drivers/char/drm/drm_irq.c
drivers/char/drm/drm_pciids.h
drivers/char/drm/drm_proc.c
drivers/char/drm/drm_stub.c
drivers/char/drm/drm_sysfs.c
drivers/char/drm/drm_vm.c
drivers/char/drm/i810_dma.c
drivers/char/drm/i810_drv.h
drivers/char/drm/i830_dma.c
drivers/char/drm/i830_drv.h
drivers/char/drm/i915_dma.c
drivers/char/drm/i915_drm.h
drivers/char/drm/i915_drv.h
drivers/char/drm/i915_mem.c
drivers/char/drm/radeon_cp.c
drivers/char/drm/savage_bci.c
drivers/char/drm/savage_drv.h
drivers/char/drm/via_dma.c
drivers/char/drm/via_dmablit.c
drivers/char/drm/via_drv.h
drivers/char/drm/via_irq.c
drivers/char/esp.c
drivers/char/ip2/i2cmd.c
drivers/char/ip2main.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/rio/cirrus.h
drivers/char/rio/defaults.h
drivers/char/rio/link.h
drivers/char/rio/list.h
drivers/char/rio/parmmap.h
drivers/char/rio/phb.h
drivers/char/rio/pkt.h
drivers/char/rio/qbuf.h
drivers/char/rio/riotypes.h
drivers/char/rio/rup.h
drivers/char/rio/sam.h
drivers/char/rocket.c
drivers/char/ser_a2232.c
drivers/char/sx.c
drivers/char/tty_io.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/edac/Kconfig
drivers/edac/e752x_edac.c
drivers/edac/edac_mc.c
drivers/edac/i82875p_edac.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/f71805f.c [new file with mode: 0644]
drivers/hwmon/it87.c
drivers/hwmon/lm77.c
drivers/hwmon/w83792d.c
drivers/i2c/algos/i2c-algo-sibyte.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/i2c-core.c
drivers/ide/Kconfig
drivers/ide/ide-disk.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-probe.c
drivers/ide/ide.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it821x.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/sgiioc4.c
drivers/infiniband/core/ucm.c
drivers/isdn/hisax/Kconfig
drivers/isdn/hisax/hisax.h
drivers/isdn/sc/ioctl.c
drivers/macintosh/Kconfig
drivers/macintosh/Makefile
drivers/macintosh/windfarm.h
drivers/macintosh/windfarm_core.c
drivers/macintosh/windfarm_max6690_sensor.c [new file with mode: 0644]
drivers/macintosh/windfarm_pid.c
drivers/macintosh/windfarm_pid.h
drivers/macintosh/windfarm_pm112.c [new file with mode: 0644]
drivers/macintosh/windfarm_pm81.c
drivers/macintosh/windfarm_pm91.c
drivers/macintosh/windfarm_smu_controls.c
drivers/macintosh/windfarm_smu_sat.c [new file with mode: 0644]
drivers/macintosh/windfarm_smu_sensors.c
drivers/md/dm-log.c
drivers/md/md.c
drivers/md/raid0.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6main.c
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/b2c2/flexcop-common.h
drivers/media/dvb/b2c2/flexcop-dma.c
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
drivers/media/dvb/b2c2/flexcop-misc.c
drivers/media/dvb/b2c2/flexcop-pci.c
drivers/media/dvb/b2c2/flexcop-reg.h
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp702x.h
drivers/media/dvb/dvb-usb/vp7045-fe.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/at76c651.c [deleted file]
drivers/media/dvb/frontends/at76c651.h [deleted file]
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/nxt2002.c [deleted file]
drivers/media/dvb/frontends/nxt2002.h [deleted file]
drivers/media/dvb/frontends/nxt200x.c
drivers/media/dvb/frontends/tda80xx.c [deleted file]
drivers/media/dvb/frontends/tda80xx.h [deleted file]
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/video/bttv-driver.c
drivers/media/video/compat_ioctl32.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/stradis.c
drivers/media/video/tda9887.c
drivers/media/video/tuner-core.c
drivers/media/video/tvaudio.c
drivers/media/video/tvp5150.c
drivers/message/i2o/core.h
drivers/message/i2o/i2o_scsi.c
drivers/message/i2o/pci.c
drivers/mmc/Kconfig
drivers/mmc/au1xmmc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_block.c
drivers/mmc/mmci.c
drivers/mmc/pxamci.c
drivers/mmc/wbsd.c
drivers/mtd/chips/Kconfig
drivers/mtd/maps/dc21285.c
drivers/net/3c59x.c
drivers/net/8139too.c
drivers/net/Kconfig
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/e100.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/gianfar_mii.c
drivers/net/hamradio/baycom_par.c
drivers/net/mv643xx_eth.c
drivers/net/ppp_generic.c
drivers/net/r8169.c
drivers/net/sis900.h
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tulip/uli526x.c
drivers/net/wan/dscc4.c
drivers/net/wan/pci200syn.c
drivers/net/wan/wanxl.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/parisc/ccio-dma.c
drivers/parisc/dino.c
drivers/parisc/hppb.c
drivers/parisc/iosapic.c
drivers/parisc/lasi.c
drivers/parisc/lba_pci.c
drivers/parisc/pdc_stable.c
drivers/parisc/sba_iommu.c
drivers/parisc/superio.c
drivers/parisc/wax.c
drivers/parport/Kconfig
drivers/parport/Makefile
drivers/parport/ieee1284.c
drivers/parport/parport_gsc.c
drivers/parport/parport_ip32.c [new file with mode: 0644]
drivers/parport/parport_serial.c
drivers/parport/probe.c
drivers/s390/block/Kconfig
drivers/s390/block/Makefile
drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_eckd.h
drivers/s390/block/dasd_eer.c [new file with mode: 0644]
drivers/s390/block/dasd_int.h
drivers/s390/cio/chsc.h
drivers/scsi/aacraid/commsup.c
drivers/scsi/mac53c94.c
drivers/scsi/scsi.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sg.c
drivers/serial/21285.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/8250_au1x00.c
drivers/serial/8250_pci.c
drivers/serial/Kconfig
drivers/serial/amba-pl010.c
drivers/serial/au1x00_uart.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/dz.c
drivers/serial/imx.c
drivers/serial/ip22zilog.c
drivers/serial/jsm/jsm.h
drivers/serial/jsm/jsm_driver.c
drivers/serial/jsm/jsm_tty.c
drivers/serial/m32r_sio.c
drivers/serial/m32r_sio.h
drivers/serial/mcfserial.c
drivers/serial/mux.c
drivers/serial/pmac_zilog.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_core.c
drivers/serial/serial_lh7a40x.c
drivers/serial/sh-sci.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/v850e_uart.c
drivers/sn/ioc3.c
drivers/spi/Kconfig
drivers/spi/spi_butterfly.c
drivers/tc/tc.c
drivers/telephony/ixj.c
drivers/usb/core/driver.c
drivers/video/backlight/backlight.c
drivers/video/backlight/lcd.c
drivers/video/console/sticore.c
drivers/video/pmag-ba-fb.c
drivers/video/pmagb-b-fb.c
fs/9p/conv.c
fs/9p/mux.c
fs/9p/vfs_inode.c
fs/Kconfig
fs/buffer.c
fs/compat_ioctl.c
fs/configfs/configfs_internal.h
fs/configfs/dir.c
fs/configfs/file.c
fs/configfs/inode.c
fs/configfs/mount.c
fs/configfs/symlink.c
fs/dcache.c
fs/debugfs/file.c
fs/direct-io.c
fs/ext2/acl.c
fs/ext2/ialloc.c
fs/ext2/super.c
fs/ext3/acl.c
fs/fat/file.c
fs/fat/misc.c
fs/fcntl.c
fs/file.c
fs/fuse/dev.c
fs/inotify.c
fs/jbd/transaction.c
fs/jffs/intrep.c
fs/libfs.c
fs/lockd/clntproc.c
fs/namei.c
fs/namespace.c
fs/nfs/direct.c
fs/nfs/nfsroot.c
fs/nfsd/nfs4proc.c
fs/ocfs2/buffer_head_io.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmunlock.c
fs/ocfs2/dlm/userdlm.c
fs/ocfs2/extent_map.c
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/journal.c
fs/ocfs2/ocfs2.h
fs/ocfs2/super.c
fs/ocfs2/sysfile.c
fs/ocfs2/uptodate.c
fs/ocfs2/uptodate.h
fs/proc/proc_misc.c
fs/quota_v2.c
fs/reiserfs/hashes.c
fs/reiserfs/super.c
fs/select.c
fs/super.c
fs/udf/balloc.c
fs/udf/namei.c
fs/ufs/inode.c
fs/ufs/super.c
fs/ufs/truncate.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_iops.c
include/asm-alpha/system.h
include/asm-arm/arch-omap/io.h
include/asm-arm/arch-s3c2410/hardware.h
include/asm-arm/arch-s3c2410/regs-gpio.h
include/asm-arm/checksum.h
include/asm-arm/mutex.h
include/asm-cris/bitops.h
include/asm-frv/bitops.h
include/asm-h8300/bitops.h
include/asm-i386/system.h
include/asm-i386/topology.h
include/asm-i386/unistd.h
include/asm-ia64/ide.h
include/asm-ia64/processor.h
include/asm-ia64/sal.h
include/asm-ia64/sn/bte.h
include/asm-ia64/sn/intr.h
include/asm-ia64/system.h
include/asm-ia64/topology.h
include/asm-m68knommu/hardirq.h
include/asm-mips/abi.h
include/asm-mips/bitops.h
include/asm-mips/byteorder.h
include/asm-mips/cacheflush.h
include/asm-mips/cobalt/cobalt.h [deleted file]
include/asm-mips/cobalt/mach-gt64120.h [deleted file]
include/asm-mips/hazards.h
include/asm-mips/interrupt.h
include/asm-mips/io.h
include/asm-mips/mach-au1x00/au1000.h
include/asm-mips/mach-cobalt/cobalt.h [new file with mode: 0644]
include/asm-mips/mach-cobalt/cpu-feature-overrides.h [new file with mode: 0644]
include/asm-mips/mach-cobalt/mach-gt64120.h [new file with mode: 0644]
include/asm-mips/mach-ip32/cpu-feature-overrides.h
include/asm-mips/r4kcache.h
include/asm-mips/reboot.h
include/asm-mips/string.h
include/asm-mips/thread_info.h
include/asm-mips/tx4927/tx4927.h
include/asm-mips/tx4927/tx4927_pci.h
include/asm-mips/uaccess.h
include/asm-mips/unistd.h
include/asm-parisc/atomic.h
include/asm-parisc/cacheflush.h
include/asm-parisc/compat_ucontext.h
include/asm-parisc/grfioctl.h
include/asm-parisc/pci.h
include/asm-parisc/pgalloc.h
include/asm-parisc/pgtable.h
include/asm-parisc/rt_sigframe.h
include/asm-parisc/unistd.h
include/asm-powerpc/compat.h
include/asm-powerpc/dma-mapping.h
include/asm-powerpc/prom.h
include/asm-powerpc/smu.h
include/asm-powerpc/thread_info.h
include/asm-s390/dasd.h
include/asm-s390/io.h
include/asm-s390/timer.h
include/asm-s390/uaccess.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/asm-v850/bitops.h
include/asm-x86_64/apic.h
include/asm-x86_64/cpufeature.h
include/asm-x86_64/hardirq.h
include/asm-x86_64/ia32_unistd.h
include/asm-x86_64/kexec.h
include/asm-x86_64/numa.h
include/asm-x86_64/proto.h
include/asm-x86_64/system.h
include/asm-x86_64/topology.h
include/asm-x86_64/unistd.h
include/linux/bitops.h
include/linux/configfs.h
include/linux/cpumask.h
include/linux/dcache.h
include/linux/dvb/video.h
include/linux/elevator.h
include/linux/elfcore.h
include/linux/i2c.h
include/linux/i2o.h
include/linux/ide.h
include/linux/ioc3.h
include/linux/jbd.h
include/linux/kbd_kern.h
include/linux/list.h
include/linux/lockd/lockd.h
include/linux/mm.h
include/linux/mmc/mmc.h
include/linux/mmc/protocol.h
include/linux/mtd/map.h
include/linux/namespace.h
include/linux/netfilter_ipv4/ipt_connbytes.h
include/linux/netfilter_ipv4/ipt_policy.h
include/linux/netfilter_ipv6/ip6t_policy.h
include/linux/nodemask.h
include/linux/parport.h
include/linux/pci_ids.h
include/linux/pktcdvd.h
include/linux/quotaops.h
include/linux/rcupdate.h
include/linux/reiserfs_acl.h
include/linux/security.h
include/linux/smp.h
include/linux/sunrpc/auth.h
include/linux/suspend.h
include/linux/tty.h
include/linux/tty_flip.h
include/linux/ufs_fs.h
include/linux/ufs_fs_sb.h
include/linux/videodev2.h
include/net/netfilter/nf_conntrack_l3proto.h
include/net/sctp/structs.h
include/net/sock.h
init/Kconfig
kernel/compat.c
kernel/cpuset.c
kernel/fork.c
kernel/intermodule.c
kernel/kprobes.c
kernel/module.c
kernel/power/console.c
kernel/power/power.h
kernel/power/swsusp.c
kernel/sched.c
kernel/signal.c
kernel/sys.c
kernel/time.c
kernel/timer.c
lib/int_sqrt.c
lib/kobject.c
lib/kobject_uevent.c
lib/spinlock_debug.c
lib/ts_bm.c
mm/hugetlb.c
mm/mempolicy.c
mm/page_alloc.c
mm/slab.c
mm/slob.c
mm/swap.c
net/802/psnap.c
net/Kconfig
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebtables.c
net/core/dev.c
net/core/utils.c
net/dccp/ccids/lib/tfrc_equation.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/multipath_wrandom.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_policy.c
net/ipv4/proc.c
net/ipv4/xfrm4_policy.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/mcast.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_policy.c
net/ipv6/proc.c
net/ipv6/raw.c
net/ipv6/xfrm6_policy.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/sctp/output.c
net/sctp/outqueue.c
net/socket.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_unix.c
net/sunrpc/rpc_pipe.c
net/xfrm/xfrm_policy.c
scripts/kconfig/Makefile
scripts/kconfig/lxdialog/Makefile
scripts/kconfig/lxdialog/check-lxdialog.sh
security/keys/keyctl.c
security/selinux/Kconfig
security/selinux/Makefile
security/selinux/avc.c
security/selinux/hooks.c
sound/arm/aaci.c
sound/oss/dmasound/tas_common.h
sound/oss/emu10k1/recmgr.c
sound/ppc/pmac.c
sound/ppc/tumbler.c

diff --git a/CREDITS b/CREDITS
index 8e577ce4abeb4f44ffcb83a894c66130aebb6a58..6957ef4efab3a2fd60732456e5c515bee68bc57e 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -3101,7 +3101,7 @@ S: Minto, NSW, 2566
 S: Australia
 
 N: Stephen Smalley
-E: sds@epoch.ncsc.mil
+E: sds@tycho.nsa.gov
 D: portions of the Linux Security Module (LSM) framework and security modules
 
 N: Chris Smith
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt
new file mode 100644 (file)
index 0000000..ff280e2
--- /dev/null
@@ -0,0 +1,41 @@
+
+Export cpu topology info by sysfs. Items (attributes) are similar
+to /proc/cpuinfo.
+
+1) /sys/devices/system/cpu/cpuX/topology/physical_package_id:
+represent the physical package id of  cpu X;
+2) /sys/devices/system/cpu/cpuX/topology/core_id:
+represent the cpu core id to cpu X;
+3) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
+represent the thread siblings to cpu X in the same core;
+4) /sys/devices/system/cpu/cpuX/topology/core_siblings:
+represent the thread siblings to cpu X in the same physical package;
+
+To implement it in an architecture-neutral way, a new source file,
+driver/base/topology.c, is to export the 5 attributes.
+
+If one architecture wants to support this feature, it just needs to
+implement 4 defines, typically in file include/asm-XXX/topology.h.
+The 4 defines are:
+#define topology_physical_package_id(cpu)
+#define topology_core_id(cpu)
+#define topology_thread_siblings(cpu)
+#define topology_core_siblings(cpu)
+
+The type of **_id is int.
+The type of siblings is cpumask_t.
+
+To be consistent on all architectures, the 4 attributes should have
+deafult values if their values are unavailable. Below is the rule.
+1) physical_package_id: If cpu has no physical package id, -1 is the
+default value.
+2) core_id: If cpu doesn't support multi-core, its core id is 0.
+3) thread_siblings: Just include itself, if the cpu doesn't support
+HT/multi-thread.
+4) core_siblings: Just include itself, if the cpu doesn't support
+multi-core and HT/Multi-thread.
+
+So be careful when declaring the 4 defines in include/asm-XXX/topology.h.
+
+If an attribute isn't defined on an architecture, it won't be exported.
+
index 44662735cf81822a4387630b7317e98bdb3ab019..ac4a7a737e430207a22be59b2d817b309eefa828 100644 (file)
@@ -1,50 +1,43 @@
 The Linux Kernel Device Model
 
-Patrick Mochel <mochel@osdl.org>
+Patrick Mochel <mochel@digitalimplant.org>
 
-26 August 2002
+Drafted 26 August 2002
+Updated 31 January 2006
 
 
 Overview
 ~~~~~~~~
 
-This driver model is a unification of all the current, disparate driver models
-that are currently in the kernel. It is intended to augment the
+The Linux Kernel Driver Model is a unification of all the disparate driver
+models that were previously used in the kernel. It is intended to augment the
 bus-specific drivers for bridges and devices by consolidating a set of data
 and operations into globally accessible data structures.
 
-Current driver models implement some sort of tree-like structure (sometimes
-just a list) for the devices they control. But, there is no linkage between
-the different bus types.
+Traditional driver models implemented some sort of tree-like structure
+(sometimes just a list) for the devices they control. There wasn't any
+uniformity across the different bus types.
 
-A common data structure can provide this linkage with little overhead: when a
-bus driver discovers a particular device, it can insert it into the global
-tree as well as its local tree. In fact, the local tree becomes just a subset
-of the global tree.
-
-Common data fields can also be moved out of the local bus models into the
-global model. Some of the manipulations of these fields can also be
-consolidated. Most likely, manipulation functions will become a set
-of helper functions, which the bus drivers wrap around to include any
-bus-specific items.
-
-The common device and bridge interface currently reflects the goals of the
-modern PC: namely the ability to do seamless Plug and Play, power management,
-and hot plug. (The model dictated by Intel and Microsoft (read: ACPI) ensures
-us that any device in the system may fit any of these criteria.)
-
-In reality, not every bus will be able to support such operations. But, most
-buses will support a majority of those operations, and all future buses will.
-In other words, a bus that doesn't support an operation is the exception,
-instead of the other way around.
+The current driver model provides a comon, uniform data model for describing
+a bus and the devices that can appear under the bus. The unified bus
+model includes a set of common attributes which all busses carry, and a set
+of common callbacks, such as device discovery during bus probing, bus
+shutdown, bus power management, etc.
 
+The common device and bridge interface reflects the goals of the modern
+computer: namely the ability to do seamless device "plug and play", power
+management, and hot plug. In particular, the model dictated by Intel and
+Microsoft (namely ACPI) ensures that almost every device on almost any bus
+on an x86-compatible system can work within this paradigm.  Of course,
+not every bus is able to support all such operations, although most
+buses support a most of those operations.
 
 
 Downstream Access
 ~~~~~~~~~~~~~~~~~
 
 Common data fields have been moved out of individual bus layers into a common
-data structure. But, these fields must still be accessed by the bus layers,
+data structure. These fields must still be accessed by the bus layers,
 and sometimes by the device-specific drivers.
 
 Other bus layers are encouraged to do what has been done for the PCI layer.
@@ -53,7 +46,7 @@ struct pci_dev now looks like this:
 struct pci_dev {
        ...
 
-       struct device device;
+       struct device dev;
 };
 
 Note first that it is statically allocated. This means only one allocation on
@@ -64,9 +57,9 @@ the two.
 
 The PCI bus layer freely accesses the fields of struct device. It knows about
 the structure of struct pci_dev, and it should know the structure of struct
-device. PCI devices that have been converted generally do not touch the fields
-of struct device. More precisely, device-specific drivers should not touch
-fields of struct device unless there is a strong compelling reason to do so.
+device. Individual PCI device drivers that have been converted the the current
+driver model generally do not and should not touch the fields of struct device,
+unless there is a strong compelling reason to do so.
 
 This abstraction is prevention of unnecessary pain during transitional phases.
 If the name of the field changes or is removed, then every downstream driver
index 4d4897c8ef963284664e23729ca792f302fc464b..b730d765b525b358883c164a7c6ca049cf0258f0 100644 (file)
@@ -162,3 +162,12 @@ What:      pci_module_init(driver)
 When:  January 2007
 Why:   Is replaced by pci_register_driver(pci_driver).
 Who:   Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de>
+
+---------------------------
+
+What:  I2C interface of the it87 driver
+When:  January 2007
+Why:   The ISA interface is faster and should be always available. The I2C
+       probing is also known to cause trouble in at least one case (see
+       bug #5889.)
+Who:   Jean Delvare <khali@linux-fr.org>
index f3c6e4946f983a3e10a8b61ae9b0975440f453fa..3d4713a6c207f9f18eb1aed4ad5f361bc86ed839 100644 (file)
@@ -320,6 +320,7 @@ static struct config_item_type simple_children_type = {
        .ct_item_ops    = &simple_children_item_ops,
        .ct_group_ops   = &simple_children_group_ops,
        .ct_attrs       = simple_children_attrs,
+       .ct_owner       = THIS_MODULE,
 };
 
 static struct configfs_subsystem simple_children_subsys = {
@@ -403,6 +404,7 @@ static struct config_item_type group_children_type = {
        .ct_item_ops    = &group_children_item_ops,
        .ct_group_ops   = &group_children_group_ops,
        .ct_attrs       = group_children_attrs,
+       .ct_owner       = THIS_MODULE,
 };
 
 static struct configfs_subsystem group_children_subsys = {
index f2595caf052e155c2a809bf4a9ae98b94e06802e..4389c684a80a66d402f464a4ecf3ed7a15bda1bb 100644 (file)
@@ -35,6 +35,7 @@ Features which OCFS2 does not support yet:
          be cluster coherent.
        - quotas
        - cluster aware flock
+       - cluster aware lockf
        - Directory change notification (F_NOTIFY)
        - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
        - POSIX ACLs
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f
new file mode 100644 (file)
index 0000000..28c5b7d
--- /dev/null
@@ -0,0 +1,105 @@
+Kernel driver f71805f
+=====================
+
+Supported chips:
+  * Fintek F71805F/FG
+    Prefix: 'f71805f'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Provided by Fintek on request
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Denis Kieft from Barracuda Networks for the donation of a
+test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
+for providing initial documentation.
+
+Thanks to Kris Chen from Fintek for answering technical questions and
+providing additional documentation.
+
+Thanks to Chris Lin from Jetway for providing wiring schematics and
+anwsering technical questions.
+
+
+Description
+-----------
+
+The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring
+capabilities. It can monitor up to 9 voltages (counting its own power
+source), 3 fans and 3 temperature sensors.
+
+This chip also has fan controlling features, using either DC or PWM, in
+three different modes (one manual, two automatic). The driver doesn't
+support these features yet.
+
+The driver assumes that no more than one chip is present, which seems
+reasonable.
+
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
+range is thus from 0 to 2.040 V. Voltage values outside of this range
+need external resistors. An exception is in0, which is used to monitor
+the chip's own power source (+3.3V), and is divided internally by a
+factor 2.
+
+The two LSB of the voltage limit registers are not used (always 0), so
+you can only set the limits in steps of 32 mV (before scaling).
+
+The wirings and resistor values suggested by Fintek are as follow:
+
+        pin                                           expected
+        name    use           R1      R2     divider  raw val.
+
+in0     VCC     VCC3.3V     int.    int.        2.00    1.65 V
+in1     VIN1    VTT1.2V      10K       -        1.00    1.20 V
+in2     VIN2    VRAM        100K    100K        2.00   ~1.25 V (1)
+in3     VIN3    VCHIPSET     47K    100K        1.47    2.24 V (2)
+in4     VIN4    VCC5V       200K     47K        5.25    0.95 V
+in5     VIN5    +12V        200K     20K       11.00    1.05 V
+in6     VIN6    VCC1.5V      10K       -        1.00    1.50 V
+in7     VIN7    VCORE        10K       -        1.00   ~1.40 V (1)
+in8     VIN8    VSB5V       200K     47K        1.00    0.95 V
+
+(1) Depends on your hardware setup.
+(2) Obviously not correct, swapping R1 and R2 would make more sense.
+
+These values can be used as hints at best, as motherboard manufacturers
+are free to use a completely different setup. As a matter of fact, the
+Jetway K8M8MS uses a significantly different setup. You will have to
+find out documentation about your own motherboard, and edit sensors.conf
+accordingly.
+
+Each voltage measured has associated low and high limits, each of which
+triggers an alarm when crossed.
+
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported as 12-bit values from a gated clock
+signal. Speeds down to 366 RPM can be measured. There is no theoretical
+high limit, but values over 6000 RPM seem to cause problem. The effective
+resolution is much lower than you would expect, the step between different
+register values being 10 rather than 1.
+
+The chip assumes 2 pulse-per-revolution fans.
+
+An alarm is triggered if the rotation speed drops below a programmable
+limit or is too low to be measured.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are reported in degrees Celsius. Each temperature measured
+has a high limit, those crossing triggers an alarm. There is an associated
+hysteresis value, below which the temperature has to drop before the
+alarm is cleared.
+
+All temperature channels are external, there is no embedded temperature
+sensor. Each channel can be used for connecting either a thermal diode
+or a thermistor. The driver reports the currently selected mode, but
+doesn't allow changing it. In theory, the BIOS should have configured
+everything properly.
index 7f42e441c645069b3c374859f3b233e872f4578a..9555be1ed99947b88a776fa2b9e6b49e143fde2e 100644 (file)
@@ -9,7 +9,7 @@ Supported chips:
                http://www.ite.com.tw/
   * IT8712F
     Prefix: 'it8712'
-    Addresses scanned: I2C 0x28 - 0x2f
+    Addresses scanned: I2C 0x2d
                        from Super I/O config space (8 I/O ports)
     Datasheet: Publicly available at the ITE website
                http://www.ite.com.tw/
index 764cdc5480e79e7318b9e3139c1cee088e58b92a..a0d0ab24288e6e4842e1aa9ed65261b8b98e5efd 100644 (file)
@@ -179,11 +179,12 @@ temp[1-*]_auto_point[1-*]_temp_hyst
 ****************
 
 temp[1-3]_type Sensor type selection.
-               Integers 1, 2, 3 or thermistor Beta value (3435)
+               Integers 1 to 4 or thermistor Beta value (typically 3435)
                Read/Write.
                1: PII/Celeron Diode
                2: 3904 transistor
                3: thermal diode
+               4: thermistor (default/unknown Beta)
                Not all types are supported by all chips
 
 temp[1-4]_max  Temperature max value.
@@ -261,6 +262,21 @@ alarms             Alarm bitmask.
                of individual bits.
                Bits are defined in kernel/include/sensors.h.
 
+alarms_in      Alarm bitmask relative to in (voltage) channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to in0 and so on
+               Prefered to 'alarms' for newer chips
+
+alarms_fan     Alarm bitmask relative to fan channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to fan1 and so on
+               Prefered to 'alarms' for newer chips
+
+alarms_temp    Alarm bitmask relative to temp (temperature) channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to temp1 and so on
+               Prefered to 'alarms' for newer chips
+
 beep_enable    Beep/interrupt enable
                0 to disable.
                1 to enable.
diff --git a/Documentation/i2c/busses/i2c-sis69x b/Documentation/i2c/busses/i2c-sis69x
deleted file mode 100644 (file)
index b88953d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-Kernel driver i2c-sis96x
-
-Replaces 2.4.x i2c-sis645
-
-Supported adapters:
-  * Silicon Integrated Systems Corp (SiS)
-    Any combination of these host bridges:
-       645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746
-    and these south bridges:
-       961, 962, 963(L) 
-
-Author: Mark M. Hoffman <mhoffman@lightlink.com>
-
-Description
------------
-
-This SMBus only driver is known to work on motherboards with the above
-named chipset combinations. The driver was developed without benefit of a
-proper datasheet from SiS. The SMBus registers are assumed compatible with
-those of the SiS630, although they are located in a completely different
-place. Thanks to Alexander Malysh <amalysh@web.de> for providing the
-SiS630 datasheet (and  driver).
-
-The command "lspci" as root should produce something like these lines:
-
-00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645
-00:02.0 ISA bridge: Silicon Integrated Systems [SiS] 85C503/5513
-00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
-
-or perhaps this...
-
-00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 
-00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961
-00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
-
-(kernel versions later than 2.4.18 may fill in the "Unknown"s)
-
-If you cant see it please look on quirk_sis_96x_smbus
-(drivers/pci/quirks.c) (also if southbridge detection fails)
-
-I suspect that this driver could be made to work for the following SiS
-chipsets as well: 635, and 635T. If anyone owns a board with those chips
-AND is willing to risk crashing & burning an otherwise well-behaved kernel
-in the name of progress... please contact me at <mhoffman@lightlink.com> or
-via the project's mailing list: <lm-sensors@lm-sensors.org>.  Please
-send bug reports and/or success stories as well.
-
-
-TO DOs
-------
-
-* The driver does not support SMBus block reads/writes; I may add them if a
-scenario is found where they're needed.
-
-
-Thank You
----------
-
-Mark D. Studebaker <mdsxyz123@yahoo.com>
- - design hints and bug fixes
-Alexander Maylsh <amalysh@web.de>
- - ditto, plus an important datasheet... almost the one I really wanted
-Hans-Günter Lütke Uphues <hg_lu@t-online.de>
- - patch for SiS735
-Robert Zwerus <arzie@dds.nl>
- - testing for SiS645DX
-Kianusch Sayah Karadji <kianusch@sk-tech.net>
- - patch for SiS645DX/962
-Ken Healy
- - patch for SiS655
-
-To anyone else who has written w/ feedback, thanks!
-
diff --git a/Documentation/i2c/busses/i2c-sis96x b/Documentation/i2c/busses/i2c-sis96x
new file mode 100644 (file)
index 0000000..00a009b
--- /dev/null
@@ -0,0 +1,73 @@
+Kernel driver i2c-sis96x
+
+Replaces 2.4.x i2c-sis645
+
+Supported adapters:
+  * Silicon Integrated Systems Corp (SiS)
+    Any combination of these host bridges:
+       645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746
+    and these south bridges:
+       961, 962, 963(L)
+
+Author: Mark M. Hoffman <mhoffman@lightlink.com>
+
+Description
+-----------
+
+This SMBus only driver is known to work on motherboards with the above
+named chipset combinations. The driver was developed without benefit of a
+proper datasheet from SiS. The SMBus registers are assumed compatible with
+those of the SiS630, although they are located in a completely different
+place. Thanks to Alexander Malysh <amalysh@web.de> for providing the
+SiS630 datasheet (and  driver).
+
+The command "lspci" as root should produce something like these lines:
+
+00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645
+00:02.0 ISA bridge: Silicon Integrated Systems [SiS] 85C503/5513
+00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
+
+or perhaps this...
+
+00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645
+00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961
+00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
+
+(kernel versions later than 2.4.18 may fill in the "Unknown"s)
+
+If you cant see it please look on quirk_sis_96x_smbus
+(drivers/pci/quirks.c) (also if southbridge detection fails)
+
+I suspect that this driver could be made to work for the following SiS
+chipsets as well: 635, and 635T. If anyone owns a board with those chips
+AND is willing to risk crashing & burning an otherwise well-behaved kernel
+in the name of progress... please contact me at <mhoffman@lightlink.com> or
+via the project's mailing list: <lm-sensors@lm-sensors.org>.  Please
+send bug reports and/or success stories as well.
+
+
+TO DOs
+------
+
+* The driver does not support SMBus block reads/writes; I may add them if a
+scenario is found where they're needed.
+
+
+Thank You
+---------
+
+Mark D. Studebaker <mdsxyz123@yahoo.com>
+ - design hints and bug fixes
+Alexander Maylsh <amalysh@web.de>
+ - ditto, plus an important datasheet... almost the one I really wanted
+Hans-Günter Lütke Uphues <hg_lu@t-online.de>
+ - patch for SiS735
+Robert Zwerus <arzie@dds.nl>
+ - testing for SiS645DX
+Kianusch Sayah Karadji <kianusch@sk-tech.net>
+ - patch for SiS645DX/962
+Ken Healy
+ - patch for SiS655
+
+To anyone else who has written w/ feedback, thanks!
+
index 2b7cf19a06adc03435b84a04ae1dee46aae7e9a1..26364d06ae927f0262e4cbccda03d1ad2cca35ba 100644 (file)
@@ -427,6 +427,23 @@ icmp_ignore_bogus_error_responses - BOOLEAN
        will avoid log file clutter.
        Default: FALSE
 
+icmp_errors_use_inbound_ifaddr - BOOLEAN
+
+       If zero, icmp error messages are sent with the primary address of
+       the exiting interface.
+       If non-zero, the message will be sent with the primary address of
+       the interface that received the packet that caused the icmp error.
+       This is the behaviour network many administrators will expect from
+       a router. And it can make debugging complicated network layouts
+       much easier. 
+
+       Note that if no primary address exists for the interface selected,
+       then the primary address of the first non-loopback interface that
+       has one will be used regarldess of this setting.
+
+       Default: 0
+
 igmp_max_memberships - INTEGER
        Change the maximum number of multicast groups we can subscribe to.
        Default: 20
index 1d40008a1926f3ee112707476f2bb23fb4637120..8f2302415eff90b0df7aa655f132f9567ff9ccd7 100644 (file)
@@ -1068,7 +1068,7 @@ SYNOPSIS
 
 struct parport_operations {
        ...
-       void (*write_status) (struct parport *port, unsigned char s);
+       void (*write_control) (struct parport *port, unsigned char s);
        ...
 };
 
@@ -1097,9 +1097,9 @@ SYNOPSIS
 
 struct parport_operations {
        ...
-       void (*frob_control) (struct parport *port,
-                             unsigned char mask,
-                             unsigned char val);
+       unsigned char (*frob_control) (struct parport *port,
+                                      unsigned char mask,
+                                      unsigned char val);
        ...
 };
 
index d089967e4948b730b9f48084172018c2b1efb0f8..634d3e5b575691baaa55167c019cea3875c4920f 100644 (file)
 
                        PCI Error Recovery
                        ------------------
-                         May 31, 2005
-
-               Current document maintainer:
-           Linas Vepstas <linas@austin.ibm.com>
-
-
-Some PCI bus controllers are able to detect certain "hard" PCI errors
-on the bus, such as parity errors on the data and address busses, as
-well as SERR and PERR errors.  These chipsets are then able to disable
-I/O to/from the affected device, so that, for example, a bad DMA
-address doesn't end up corrupting system memory.  These same chipsets
-are also able to reset the affected PCI device, and return it to
-working condition.  This document describes a generic API form
-performing error recovery.
-
-The core idea is that after a PCI error has been detected, there must
-be a way for the kernel to coordinate with all affected device drivers
-so that the pci card can be made operational again, possibly after
-performing a full electrical #RST of the PCI card.  The API below
-provides a generic API for device drivers to be notified of PCI
-errors, and to be notified of, and respond to, a reset sequence.
-
-Preliminary sketch of API, cut-n-pasted-n-modified email from
-Ben Herrenschmidt, circa 5 april 2005
+                        February 2, 2006
+
+                 Current document maintainer:
+             Linas Vepstas <linas@austin.ibm.com>
+
+
+Many PCI bus controllers are able to detect a variety of hardware
+PCI errors on the bus, such as parity errors on the data and address
+busses, as well as SERR and PERR errors.  Some of the more advanced
+chipsets are able to deal with these errors; these include PCI-E chipsets,
+and the PCI-host bridges found on IBM Power4 and Power5-based pSeries
+boxes. A typical action taken is to disconnect the affected device,
+halting all I/O to it.  The goal of a disconnection is to avoid system
+corruption; for example, to halt system memory corruption due to DMA's
+to "wild" addresses. Typically, a reconnection mechanism is also
+offered, so that the affected PCI device(s) are reset and put back
+into working condition. The reset phase requires coordination
+between the affected device drivers and the PCI controller chip.
+This document describes a generic API for notifying device drivers
+of a bus disconnection, and then performing error recovery.
+This API is currently implemented in the 2.6.16 and later kernels.
+
+Reporting and recovery is performed in several steps. First, when
+a PCI hardware error has resulted in a bus disconnect, that event
+is reported as soon as possible to all affected device drivers,
+including multiple instances of a device driver on multi-function
+cards. This allows device drivers to avoid deadlocking in spinloops,
+waiting for some i/o-space register to change, when it never will.
+It also gives the drivers a chance to defer incoming I/O as
+needed.
+
+Next, recovery is performed in several stages. Most of the complexity
+is forced by the need to handle multi-function devices, that is,
+devices that have multiple device drivers associated with them.
+In the first stage, each driver is allowed to indicate what type
+of reset it desires, the choices being a simple re-enabling of I/O
+or requesting a hard reset (a full electrical #RST of the PCI card).
+If any driver requests a full reset, that is what will be done.
+
+After a full reset and/or a re-enabling of I/O, all drivers are
+again notified, so that they may then perform any device setup/config
+that may be required.  After these have all completed, a final
+"resume normal operations" event is sent out.
+
+The biggest reason for choosing a kernel-based implementation rather
+than a user-space implementation was the need to deal with bus
+disconnects of PCI devices attached to storage media, and, in particular,
+disconnects from devices holding the root file system.  If the root
+file system is disconnected, a user-space mechanism would have to go
+through a large number of contortions to complete recovery. Almost all
+of the current Linux file systems are not tolerant of disconnection
+from/reconnection to their underlying block device. By contrast,
+bus errors are easy to manage in the device driver. Indeed, most
+device drivers already handle very similar recovery procedures;
+for example, the SCSI-generic layer already provides significant
+mechanisms for dealing with SCSI bus errors and SCSI bus resets.
+
+
+Detailed Design
+---------------
+Design and implementation details below, based on a chain of
+public email discussions with Ben Herrenschmidt, circa 5 April 2005.
 
 The error recovery API support is exposed to the driver in the form of
 a structure of function pointers pointed to by a new field in struct
-pci_driver. The absence of this pointer in pci_driver denotes an
-"non-aware" driver, behaviour on these is platform dependant.
-Platforms like ppc64 can try to simulate pci hotplug remove/add.
-
-The definition of "pci_error_token" is not covered here. It is based on
-Seto's work on the synchronous error detection. We still need to define
-functions for extracting infos out of an opaque error token. This is
-separate from this API.
+pci_driver. A driver that fails to provide the structure is "non-aware",
+and the actual recovery steps taken are platform dependent.  The
+arch/powerpc implementation will simulate a PCI hotplug remove/add.
 
 This structure has the form:
-
 struct pci_error_handlers
 {
-       int (*error_detected)(struct pci_dev *dev, pci_error_token error);
+       int (*error_detected)(struct pci_dev *dev, enum pci_channel_state);
        int (*mmio_enabled)(struct pci_dev *dev);
-       int (*resume)(struct pci_dev *dev);
        int (*link_reset)(struct pci_dev *dev);
        int (*slot_reset)(struct pci_dev *dev);
+       void (*resume)(struct pci_dev *dev);
 };
 
-A driver doesn't have to implement all of these callbacks. The
-only mandatory one is error_detected(). If a callback is not
-implemented, the corresponding feature is considered unsupported.
-For example, if mmio_enabled() and resume() aren't there, then the
-driver is assumed as not doing any direct recovery and requires
+The possible channel states are:
+enum pci_channel_state {
+       pci_channel_io_normal,  /* I/O channel is in normal state */
+       pci_channel_io_frozen,  /* I/O to channel is blocked */
+       pci_channel_io_perm_failure, /* PCI card is dead */
+};
+
+Possible return values are:
+enum pci_ers_result {
+       PCI_ERS_RESULT_NONE,        /* no result/none/not supported in device driver */
+       PCI_ERS_RESULT_CAN_RECOVER, /* Device driver can recover without slot reset */
+       PCI_ERS_RESULT_NEED_RESET,  /* Device driver wants slot to be reset. */
+       PCI_ERS_RESULT_DISCONNECT,  /* Device has completely failed, is unrecoverable */
+       PCI_ERS_RESULT_RECOVERED,   /* Device driver is fully recovered and operational */
+};
+
+A driver does not have to implement all of these callbacks; however,
+if it implements any, it must implement error_detected(). If a callback
+is not implemented, the corresponding feature is considered unsupported.
+For example, if mmio_enabled() and resume() aren't there, then it
+is assumed that the driver is not doing any direct recovery and requires
 a reset. If link_reset() is not implemented, the card is assumed as
-not caring about link resets, in which case, if recover is supported,
-the core can try recover (but not slot_reset() unless it really did
-reset the slot). If slot_reset() is not supported, link_reset() can
-be called instead on a slot reset.
-
-At first, the call will always be :
-
-       1) error_detected()
-
-       Error detected. This is sent once after an error has been detected. At
-this point, the device might not be accessible anymore depending on the
-platform (the slot will be isolated on ppc64). The driver may already
-have "noticed" the error because of a failing IO, but this is the proper
-"synchronisation point", that is, it gives a chance to the driver to
-cleanup, waiting for pending stuff (timers, whatever, etc...) to
-complete; it can take semaphores, schedule, etc... everything but touch
-the device. Within this function and after it returns, the driver
+not care about link resets. Typically a driver will want to know about
+a slot_reset().
+
+The actual steps taken by a platform to recover from a PCI error
+event will be platform-dependent, but will follow the general
+sequence described below.
+
+STEP 0: Error Event
+-------------------
+PCI bus error is detect by the PCI hardware.  On powerpc, the slot
+is isolated, in that all I/O is blocked: all reads return 0xffffffff,
+all writes are ignored.
+
+
+STEP 1: Notification
+--------------------
+Platform calls the error_detected() callback on every instance of
+every driver affected by the error.
+
+At this point, the device might not be accessible anymore, depending on
+the platform (the slot will be isolated on powerpc). The driver may
+already have "noticed" the error because of a failing I/O, but this
+is the proper "synchronization point", that is, it gives the driver
+a chance to cleanup, waiting for pending stuff (timers, whatever, etc...)
+to complete; it can take semaphores, schedule, etc... everything but
+touch the device. Within this function and after it returns, the driver
 shouldn't do any new IOs. Called in task context. This is sort of a
 "quiesce" point. See note about interrupts at the end of this doc.
 
-       Result codes:
-               - PCIERR_RESULT_CAN_RECOVER:
-                 Driever returns this if it thinks it might be able to recover
+All drivers participating in this system must implement this call.
+The driver must return one of the following result codes:
+               - PCI_ERS_RESULT_CAN_RECOVER:
+                 Driver returns this if it thinks it might be able to recover
                  the HW by just banging IOs or if it wants to be given
-                 a chance to extract some diagnostic informations (see
-                 below).
-               - PCIERR_RESULT_NEED_RESET:
-                 Driver returns this if it thinks it can't recover unless the
-                 slot is reset.
-               - PCIERR_RESULT_DISCONNECT:
-                 Return this if driver thinks it won't recover at all,
-                 (this will detach the driver ? or just leave it
-                 dangling ? to be decided)
-
-So at this point, we have called error_detected() for all drivers
-on the segment that had the error. On ppc64, the slot is isolated. What
-happens now typically depends on the result from the drivers. If all
-drivers on the segment/slot return PCIERR_RESULT_CAN_RECOVER, we would
-re-enable IOs on the slot (or do nothing special if the platform doesn't
-isolate slots) and call 2). If not and we can reset slots, we go to 4),
-if neither, we have a dead slot. If it's an hotplug slot, we might
-"simulate" reset by triggering HW unplug/replug though.
-
->>> Current ppc64 implementation assumes that a device driver will
->>> *not* schedule or semaphore in this routine; the current ppc64
+                 a chance to extract some diagnostic information (see
+                 mmio_enable, below).
+               - PCI_ERS_RESULT_NEED_RESET:
+                 Driver returns this if it can't recover without a hard
+                 slot reset.
+               - PCI_ERS_RESULT_DISCONNECT:
+                 Driver returns this if it doesn't want to recover at all.
+
+The next step taken will depend on the result codes returned by the
+drivers.
+
+If all drivers on the segment/slot return PCI_ERS_RESULT_CAN_RECOVER,
+then the platform should re-enable IOs on the slot (or do nothing in
+particular, if the platform doesn't isolate slots), and recovery
+proceeds to STEP 2 (MMIO Enable).
+
+If any driver requested a slot reset (by returning PCI_ERS_RESULT_NEED_RESET),
+then recovery proceeds to STEP 4 (Slot Reset).
+
+If the platform is unable to recover the slot, the next step
+is STEP 6 (Permanent Failure).
+
+>>> The current powerpc implementation assumes that a device driver will
+>>> *not* schedule or semaphore in this routine; the current powerpc
 >>> implementation uses one kernel thread to notify all devices;
->>> thus, of one device sleeps/schedules, all devices are affected.
+>>> thus, if one device sleeps/schedules, all devices are affected.
 >>> Doing better requires complex multi-threaded logic in the error
 >>> recovery implementation (e.g. waiting for all notification threads
 >>> to "join" before proceeding with recovery.)  This seems excessively
 >>> complex and not worth implementing.
 
->>> The current ppc64 implementation doesn't much care if the device
->>> attempts i/o at this point, or not.  I/O's will fail, returning
+>>> The current powerpc implementation doesn't much care if the device
+>>> attempts I/O at this point, or not.  I/O's will fail, returning
 >>> a value of 0xff on read, and writes will be dropped. If the device
 >>> driver attempts more than 10K I/O's to a frozen adapter, it will
 >>> assume that the device driver has gone into an infinite loop, and
->>> it will panic the the kernel.
+>>> it will panic the the kernel. There doesn't seem to be any other
+>>> way of stopping a device driver that insists on spinning on I/O.
 
-       2) mmio_enabled()
+STEP 2: MMIO Enabled
+-------------------
+The platform re-enables MMIO to the device (but typically not the
+DMA), and then calls the mmio_enabled() callback on all affected
+device drivers.
 
-       This is the "early recovery" call. IOs are allowed again, but DMA is
+This is the "early recovery" call. IOs are allowed again, but DMA is
 not (hrm... to be discussed, I prefer not), with some restrictions. This
 is NOT a callback for the driver to start operations again, only to
 peek/poke at the device, extract diagnostic information, if any, and
 eventually do things like trigger a device local reset or some such,
-but not restart operations. This is sent if all drivers on a segment
-agree that they can try to recover and no automatic link reset was
-performed by the HW. If the platform can't just re-enable IOs without
-a slot reset or a link reset, it doesn't call this callback and goes
-directly to 3) or 4). All IOs should be done _synchronously_ from
-within this callback, errors triggered by them will be returned via
-the normal pci_check_whatever() api, no new error_detected() callback
-will be issued due to an error happening here. However, such an error
-might cause IOs to be re-blocked for the whole segment, and thus
-invalidate the recovery that other devices on the same segment might
-have done, forcing the whole segment into one of the next states,
-that is link reset or slot reset.
-
-       Result codes:
-               - PCIERR_RESULT_RECOVERED
+but not restart operations. This is callback is made if all drivers on
+a segment agree that they can try to recover and if no automatic link reset
+was performed by the HW. If the platform can't just re-enable IOs without
+a slot reset or a link reset, it wont call this callback, and instead
+will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset)
+
+>>> The following is proposed; no platform implements this yet:
+>>> Proposal: All I/O's should be done _synchronously_ from within
+>>> this callback, errors triggered by them will be returned via
+>>> the normal pci_check_whatever() API, no new error_detected()
+>>> callback will be issued due to an error happening here. However,
+>>> such an error might cause IOs to be re-blocked for the whole
+>>> segment, and thus invalidate the recovery that other devices
+>>> on the same segment might have done, forcing the whole segment
+>>> into one of the next states, that is, link reset or slot reset.
+
+The driver should return one of the following result codes:
+               - PCI_ERS_RESULT_RECOVERED
                  Driver returns this if it thinks the device is fully
-                 functionnal and thinks it is ready to start
+                 functional and thinks it is ready to start
                  normal driver operations again. There is no
                  guarantee that the driver will actually be
                  allowed to proceed, as another driver on the
                  same segment might have failed and thus triggered a
                  slot reset on platforms that support it.
 
-               - PCIERR_RESULT_NEED_RESET
+               - PCI_ERS_RESULT_NEED_RESET
                  Driver returns this if it thinks the device is not
                  recoverable in it's current state and it needs a slot
                  reset to proceed.
 
-               - PCIERR_RESULT_DISCONNECT
+               - PCI_ERS_RESULT_DISCONNECT
                  Same as above. Total failure, no recovery even after
                  reset driver dead. (To be defined more precisely)
 
->>> The current ppc64 implementation does not implement this callback.
+The next step taken depends on the results returned by the drivers.
+If all drivers returned PCI_ERS_RESULT_RECOVERED, then the platform
+proceeds to either STEP3 (Link Reset) or to STEP 5 (Resume Operations).
+
+If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform
+proceeds to STEP 4 (Slot Reset)
 
-       3) link_reset()
+>>> The current powerpc implementation does not implement this callback.
 
-       This is called after the link has been reset. This is typically
-a PCI Express specific state at this point and is done whenever a
-non-fatal error has been detected that can be "solved" by resetting
-the link. This call informs the driver of the reset and the driver
-should check if the device appears to be in working condition.
-This function acts a bit like 2) mmio_enabled(), in that the driver
-is not supposed to restart normal driver I/O operations right away.
-Instead, it should just "probe" the device to check it's recoverability
-status. If all is right, then the core will call resume() once all
-drivers have ack'd link_reset().
+
+STEP 3: Link Reset
+------------------
+The platform resets the link, and then calls the link_reset() callback
+on all affected device drivers.  This is a PCI-Express specific state
+and is done whenever a non-fatal error has been detected that can be
+"solved" by resetting the link. This call informs the driver of the
+reset and the driver should check to see if the device appears to be
+in working condition.
+
+The driver is not supposed to restart normal driver I/O operations
+at this point.  It should limit itself to "probing" the device to
+check it's recoverability status. If all is right, then the platform
+will call resume() once all drivers have ack'd link_reset().
 
        Result codes:
-               (identical to mmio_enabled)
+               (identical to STEP 3 (MMIO Enabled)
+
+The platform then proceeds to either STEP 4 (Slot Reset) or STEP 5
+(Resume Operations).
+
+>>> The current powerpc implementation does not implement this callback.
+
+
+STEP 4: Slot Reset
+------------------
+The platform performs a soft or hard reset of the device, and then
+calls the slot_reset() callback.
+
+A soft reset consists of asserting the adapter #RST line and then
+restoring the PCI BAR's and PCI configuration header to a state
+that is equivalent to what it would be after a fresh system
+power-on followed by power-on BIOS/system firmware initialization.
+If the platform supports PCI hotplug, then the reset might be
+performed by toggling the slot electrical power off/on.
 
->>> The current ppc64 implementation does not implement this callback.
+It is important for the platform to restore the PCI config space
+to the "fresh poweron" state, rather than the "last state". After
+a slot reset, the device driver will almost always use its standard
+device initialization routines, and an unusual config space setup
+may result in hung devices, kernel panics, or silent data corruption.
 
-       4) slot_reset()
+This call gives drivers the chance to re-initialize the hardware
+(re-download firmware, etc.).  At this point, the driver may assume
+that he card is in a fresh state and is fully functional. In
+particular, interrupt generation should work normally.
 
-       This is called after the slot has been soft or hard reset by the
-platform.  A soft reset consists of asserting the adapter #RST line
-and then restoring the PCI BARs and PCI configuration header. If the
-platform supports PCI hotplug, then it might instead perform a hard
-reset by toggling power on the slot off/on. This call gives drivers
-the chance to re-initialize the hardware (re-download firmware, etc.),
-but drivers shouldn't restart normal I/O processing operations at
-this point.  (See note about interrupts; interrupts aren't guaranteed
-to be delivered until the resume() callback has been called). If all
-device drivers report success on this callback, the patform will call
-resume() to complete the error handling and let the driver restart
-normal I/O processing.
+Drivers should not yet restart normal I/O processing operations
+at this point.  If all device drivers report success on this
+callback, the platform will call resume() to complete the sequence,
+and let the driver restart normal I/O processing.
 
 A driver can still return a critical failure for this function if
 it can't get the device operational after reset.  If the platform
-previously tried a soft reset, it migh now try a hard reset (power
+previously tried a soft reset, it might now try a hard reset (power
 cycle) and then call slot_reset() again.  It the device still can't
 be recovered, there is nothing more that can be done;  the platform
 will typically report a "permanent failure" in such a case.  The
 device will be considered "dead" in this case.
 
-       Result codes:
-               - PCIERR_RESULT_DISCONNECT
-               Same as above.
+Drivers for multi-function cards will need to coordinate among
+themselves as to which driver instance will perform any "one-shot"
+or global device initialization. For example, the Symbios sym53cxx2
+driver performs device init only from PCI function 0:
 
->>> The current ppc64 implementation does not try a power-cycle reset
->>> if the driver returned PCIERR_RESULT_DISCONNECT. However, it should.
++       if (PCI_FUNC(pdev->devfn) == 0)
++               sym_reset_scsi_bus(np, 0);
 
-       5) resume()
-
-       This is called if all drivers on the segment have returned
-PCIERR_RESULT_RECOVERED from one of the 3 prevous callbacks.
-That basically tells the driver to restart activity, tht everything
-is back and running. No result code is taken into account here. If
-a new error happens, it will restart a new error handling process.
+       Result codes:
+               - PCI_ERS_RESULT_DISCONNECT
+               Same as above.
 
-That's it. I think this covers all the possibilities. The way those
-callbacks are called is platform policy. A platform with no slot reset
-capability for example may want to just "ignore" drivers that can't
+Platform proceeds either to STEP 5 (Resume Operations) or STEP 6 (Permanent
+Failure).
+
+>>> The current powerpc implementation does not currently try a
+>>> power-cycle reset if the driver returned PCI_ERS_RESULT_DISCONNECT.
+>>> However, it probably should.
+
+
+STEP 5: Resume Operations
+-------------------------
+The platform will call the resume() callback on all affected device
+drivers if all drivers on the segment have returned
+PCI_ERS_RESULT_RECOVERED from one of the 3 previous callbacks.
+The goal of this callback is to tell the driver to restart activity,
+that everything is back and running. This callback does not return
+a result code.
+
+At this point, if a new error happens, the platform will restart
+a new error recovery sequence.
+
+STEP 6: Permanent Failure
+-------------------------
+A "permanent failure" has occurred, and the platform cannot recover
+the device.  The platform will call error_detected() with a
+pci_channel_state value of pci_channel_io_perm_failure.
+
+The device driver should, at this point, assume the worst. It should
+cancel all pending I/O, refuse all new I/O, returning -EIO to
+higher layers. The device driver should then clean up all of its
+memory and remove itself from kernel operations, much as it would
+during system shutdown.
+
+The platform will typically notify the system operator of the
+permanent failure in some way.  If the device is hotplug-capable,
+the operator will probably want to remove and replace the device.
+Note, however, not all failures are truly "permanent". Some are
+caused by over-heating, some by a poorly seated card. Many
+PCI error events are caused by software bugs, e.g. DMA's to
+wild addresses or bogus split transactions due to programming
+errors. See the discussion in powerpc/eeh-pci-error-recovery.txt
+for additional detail on real-life experience of the causes of
+software errors.
+
+
+Conclusion; General Remarks
+---------------------------
+The way those callbacks are called is platform policy. A platform with
+no slot reset capability may want to just "ignore" drivers that can't
 recover (disconnect them) and try to let other cards on the same segment
 recover. Keep in mind that in most real life cases, though, there will
 be only one driver per segment.
 
-Now, there is a note about interrupts. If you get an interrupt and your
+Now, a note about interrupts. If you get an interrupt and your
 device is dead or has been isolated, there is a problem :)
-
-After much thinking, I decided to leave that to the platform. That is,
-the recovery API only precies that:
+The current policy is to turn this into a platform policy.
+That is, the recovery API only requires that:
 
  - There is no guarantee that interrupt delivery can proceed from any
 device on the segment starting from the error detection and until the
-restart callback is sent, at which point interrupts are expected to be
+resume callback is sent, at which point interrupts are expected to be
 fully operational.
 
- - There is no guarantee that interrupt delivery is stopped, that is, ad
-river that gets an interrupts after detecting an error, or that detects
-and error within the interrupt handler such that it prevents proper
+ - There is no guarantee that interrupt delivery is stopped, that is,
+a driver that gets an interrupt after detecting an error, or that detects
+an error within the interrupt handler such that it prevents proper
 ack'ing of the interrupt (and thus removal of the source) should just
-return IRQ_NOTHANDLED. It's up to the platform to deal with taht
-condition, typically by masking the irq source during the duration of
+return IRQ_NOTHANDLED. It's up to the platform to deal with that
+condition, typically by masking the IRQ source during the duration of
 the error handling. It is expected that the platform "knows" which
 interrupts are routed to error-management capable slots and can deal
-with temporarily disabling that irq number during error processing (this
+with temporarily disabling that IRQ number during error processing (this
 isn't terribly complex). That means some IRQ latency for other devices
 sharing the interrupt, but there is simply no other way. High end
 platforms aren't supposed to share interrupts between many devices
 anyway :)
 
-
-Revised: 31 May 2005 Linas Vepstas <linas@austin.ibm.com>
+>>> Implementation details for the powerpc platform are discussed in
+>>> the file Documentation/powerpc/eeh-pci-error-recovery.txt
+
+>>> As of this writing, there are six device drivers with patches
+>>> implementing error recovery. Not all of these patches are in
+>>> mainline yet. These may be used as "examples":
+>>>
+>>> drivers/scsi/ipr.c
+>>> drivers/scsi/sym53cxx_2
+>>> drivers/next/e100.c
+>>> drivers/net/e1000
+>>> drivers/net/ixgb
+>>> drivers/net/s2io.c
+
+The End
+-------
index 1284498e847cf00ca166668622156bdffb834760..54e5f9b1536d7eac8765d8317c2ce7c3994c429f 100644 (file)
@@ -880,6 +880,10 @@ address which can extend beyond that limit.
     - device_type : Should be "soc"
     - ranges : Should be defined as specified in 1) to describe the
       translation of SOC addresses for memory mapped SOC registers.
+    - bus-frequency: Contains the bus frequency for the SOC node.
+      Typically, the value of this field is filled in by the boot
+      loader. 
+
 
   Recommended properties:
 
@@ -919,6 +923,7 @@ SOC.
                device_type = "soc";
                ranges = <00000000 e0000000 00100000>
                reg = <e0000000 00003000>;
+               bus-frequency = <0>;
        }
 
 
@@ -1170,6 +1175,8 @@ platforms are moved over to use the flattened-device-tree model.
 
        mdio@24520 {
                reg = <24520 20>;
+               device_type = "mdio"; 
+               compatible = "gianfar";
 
                ethernet-phy@0 {
                        ......
@@ -1317,6 +1324,7 @@ not necessary as they are usually the same as the root node.
                device_type = "soc";
                ranges = <00000000 e0000000 00100000>
                reg = <e0000000 00003000>;
+               bus-frequency = <0>;
 
                mdio@24520 {
                        reg = <24520 20>;
index a2e8c8d90e350d5960647da7cba4c5b8e54424e4..9927af7a629c9a16022fc9cb689ae4f1ee2d91ef 100644 (file)
@@ -12,13 +12,20 @@ You can make this adapter from an old printer cable and solder things
 directly to the Butterfly.  Or (if you have the parts and skills) you
 can come up with something fancier, providing ciruit protection to the
 Butterfly and the printer port, or with a better power supply than two
-signal pins from the printer port.
+signal pins from the printer port.  Or for that matter, you can use
+similar cables to talk to many AVR boards, even a breadboard.
+
+This is more powerful than "ISP programming" cables since it lets kernel
+SPI protocol drivers interact with the AVR, and could even let the AVR
+issue interrupts to them.  Later, your protocol driver should work
+easily with a "real SPI controller", instead of this bitbanger.
 
 
 The first cable connections will hook Linux up to one SPI bus, with the
 AVR and a DataFlash chip; and to the AVR reset line.  This is all you
 need to reflash the firmware, and the pins are the standard Atmel "ISP"
-connector pins (used also on non-Butterfly AVR boards).
+connector pins (used also on non-Butterfly AVR boards).  On the parport
+side this is like "sp12" programming cables.
 
        Signal    Butterfly       Parport (DB-25)
        ------    ---------       ---------------
@@ -40,10 +47,14 @@ by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and
        SELECT  = J400.PB0/nSS  = pin 17/C3,nSELECT
        GND     = J400.GND      = pin 24/GND
 
-The "USI" controller, using J405, can be used for a second SPI bus.  That
-would let you talk to the AVR over SPI, running firmware that makes it act
-as an SPI slave, while letting either Linux or the AVR use the DataFlash.
-There are plenty of spare parport pins to wire this one up, such as:
+Or you could flash firmware making the AVR into an SPI slave (keeping the
+DataFlash in reset) and tweak the spi_butterfly driver to make it bind to
+the driver for your custom SPI-based protocol.
+
+The "USI" controller, using J405, can also be used for a second SPI bus.
+That would let you talk to the AVR using custom SPI-with-USI firmware,
+while letting either Linux or the AVR use the DataFlash.  There are plenty
+of spare parport pins to wire this one up, such as:
 
        Signal    Butterfly       Parport (DB-25)
        ------    ---------       ---------------
diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt
new file mode 100644 (file)
index 0000000..90a5e9e
--- /dev/null
@@ -0,0 +1,295 @@
+
+unshare system call:
+--------------------
+This document describes the new system call, unshare. The document
+provides an overview of the feature, why it is needed, how it can
+be used, its interface specification, design, implementation and
+how it can be tested.
+
+Change Log:
+-----------
+version 0.1  Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006
+
+Contents:
+---------
+       1) Overview
+       2) Benefits
+       3) Cost
+       4) Requirements
+       5) Functional Specification
+       6) High Level Design
+       7) Low Level Design
+       8) Test Specification
+       9) Future Work
+
+1) Overview
+-----------
+Most legacy operating system kernels support an abstraction of threads
+as multiple execution contexts within a process. These kernels provide
+special resources and mechanisms to maintain these "threads". The Linux
+kernel, in a clever and simple manner, does not make distinction
+between processes and "threads". The kernel allows processes to share
+resources and thus they can achieve legacy "threads" behavior without
+requiring additional data structures and mechanisms in the kernel. The
+power of implementing threads in this manner comes not only from
+its simplicity but also from allowing application programmers to work
+outside the confinement of all-or-nothing shared resources of legacy
+threads. On Linux, at the time of thread creation using the clone system
+call, applications can selectively choose which resources to share
+between threads.
+
+unshare system call adds a primitive to the Linux thread model that
+allows threads to selectively 'unshare' any resources that were being
+shared at the time of their creation. unshare was conceptualized by
+Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part
+of the discussion on POSIX threads on Linux.  unshare augments the
+usefulness of Linux threads for applications that would like to control
+shared resources without creating a new process. unshare is a natural
+addition to the set of available primitives on Linux that implement
+the concept of process/thread as a virtual machine.
+
+2) Benefits
+-----------
+unshare would be useful to large application frameworks such as PAM
+where creating a new process to control sharing/unsharing of process
+resources is not possible. Since namespaces are shared by default
+when creating a new process using fork or clone, unshare can benefit
+even non-threaded applications if they have a need to disassociate
+from default shared namespace. The following lists two use-cases
+where unshare can be used.
+
+2.1 Per-security context namespaces
+-----------------------------------
+unshare can be used to implement polyinstantiated directories using
+the kernel's per-process namespace mechanism. Polyinstantiated directories,
+such as per-user and/or per-security context instance of /tmp, /var/tmp or
+per-security context instance of a user's home directory, isolate user
+processes when working with these directories. Using unshare, a PAM
+module can easily setup a private namespace for a user at login.
+Polyinstantiated directories are required for Common Criteria certification
+with Labeled System Protection Profile, however, with the availability
+of shared-tree feature in the Linux kernel, even regular Linux systems
+can benefit from setting up private namespaces at login and
+polyinstantiating /tmp, /var/tmp and other directories deemed
+appropriate by system administrators.
+
+2.2 unsharing of virtual memory and/or open files
+-------------------------------------------------
+Consider a client/server application where the server is processing
+client requests by creating processes that share resources such as
+virtual memory and open files. Without unshare, the server has to
+decide what needs to be shared at the time of creating the process
+which services the request. unshare allows the server an ability to
+disassociate parts of the context during the servicing of the
+request. For large and complex middleware application frameworks, this
+ability to unshare after the process was created can be very
+useful.
+
+3) Cost
+-------
+In order to not duplicate code and to handle the fact that unshare
+works on an active task (as opposed to clone/fork working on a newly
+allocated inactive task) unshare had to make minor reorganizational
+changes to copy_* functions utilized by clone/fork system call.
+There is a cost associated with altering existing, well tested and
+stable code to implement a new feature that may not get exercised
+extensively in the beginning. However, with proper design and code
+review of the changes and creation of an unshare test for the LTP
+the benefits of this new feature can exceed its cost.
+
+4) Requirements
+---------------
+unshare reverses sharing that was done using clone(2) system call,
+so unshare should have a similar interface as clone(2). That is,
+since flags in clone(int flags, void *stack) specifies what should
+be shared, similar flags in unshare(int flags) should specify
+what should be unshared. Unfortunately, this may appear to invert
+the meaning of the flags from the way they are used in clone(2).
+However, there was no easy solution that was less confusing and that
+allowed incremental context unsharing in future without an ABI change.
+
+unshare interface should accommodate possible future addition of
+new context flags without requiring a rebuild of old applications.
+If and when new context flags are added, unshare design should allow
+incremental unsharing of those resources on an as needed basis.
+
+5) Functional Specification
+---------------------------
+NAME
+       unshare - disassociate parts of the process execution context
+
+SYNOPSIS
+       #include <sched.h>
+
+       int unshare(int flags);
+
+DESCRIPTION
+       unshare allows a process to disassociate parts of its execution
+       context that are currently being shared with other processes. Part
+       of execution context, such as the namespace, is shared by default
+       when a new process is created using fork(2), while other parts,
+       such as the virtual memory, open file descriptors, etc, may be
+       shared by explicit request to share them when creating a process
+       using clone(2).
+
+       The main use of unshare is to allow a process to control its
+       shared execution context without creating a new process.
+
+       The flags argument specifies one or bitwise-or'ed of several of
+       the following constants.
+
+       CLONE_FS
+               If CLONE_FS is set, file system information of the caller
+               is disassociated from the shared file system information.
+
+       CLONE_FILES
+               If CLONE_FILES is set, the file descriptor table of the
+               caller is disassociated from the shared file descriptor
+               table.
+
+       CLONE_NEWNS
+               If CLONE_NEWNS is set, the namespace of the caller is
+               disassociated from the shared namespace.
+
+       CLONE_VM
+               If CLONE_VM is set, the virtual memory of the caller is
+               disassociated from the shared virtual memory.
+
+RETURN VALUE
+       On success, zero returned. On failure, -1 is returned and errno is
+
+ERRORS
+       EPERM   CLONE_NEWNS was specified by a non-root process (process
+               without CAP_SYS_ADMIN).
+
+       ENOMEM  Cannot allocate sufficient memory to copy parts of caller's
+               context that need to be unshared.
+
+       EINVAL  Invalid flag was specified as an argument.
+
+CONFORMING TO
+       The unshare() call is Linux-specific and  should  not be used
+       in programs intended to be portable.
+
+SEE ALSO
+       clone(2), fork(2)
+
+6) High Level Design
+--------------------
+Depending on the flags argument, the unshare system call allocates
+appropriate process context structures, populates it with values from
+the current shared version, associates newly duplicated structures
+with the current task structure and releases corresponding shared
+versions. Helper functions of clone (copy_*) could not be used
+directly by unshare because of the following two reasons.
+  1) clone operates on a newly allocated not-yet-active task
+     structure, where as unshare operates on the current active
+     task. Therefore unshare has to take appropriate task_lock()
+     before associating newly duplicated context structures
+  2) unshare has to allocate and duplicate all context structures
+     that are being unshared, before associating them with the
+     current task and releasing older shared structures. Failure
+     do so will create race conditions and/or oops when trying
+     to backout due to an error. Consider the case of unsharing
+     both virtual memory and namespace. After successfully unsharing
+     vm, if the system call encounters an error while allocating
+     new namespace structure, the error return code will have to
+     reverse the unsharing of vm. As part of the reversal the
+     system call will have to go back to older, shared, vm
+     structure, which may not exist anymore.
+
+Therefore code from copy_* functions that allocated and duplicated
+current context structure was moved into new dup_* functions. Now,
+copy_* functions call dup_* functions to allocate and duplicate
+appropriate context structures and then associate them with the
+task structure that is being constructed. unshare system call on
+the other hand performs the following:
+  1) Check flags to force missing, but implied, flags
+  2) For each context structure, call the corresponding unshare
+     helper function to allocate and duplicate a new context
+     structure, if the appropriate bit is set in the flags argument.
+  3) If there is no error in allocation and duplication and there
+     are new context structures then lock the current task structure,
+     associate new context structures with the current task structure,
+     and release the lock on the current task structure.
+  4) Appropriately release older, shared, context structures.
+
+7) Low Level Design
+-------------------
+Implementation of unshare can be grouped in the following 4 different
+items:
+  a) Reorganization of existing copy_* functions
+  b) unshare system call service function
+  c) unshare helper functions for each different process context
+  d) Registration of system call number for different architectures
+
+  7.1) Reorganization of copy_* functions
+       Each copy function such as copy_mm, copy_namespace, copy_files,
+       etc, had roughly two components. The first component allocated
+       and duplicated the appropriate structure and the second component
+       linked it to the task structure passed in as an argument to the copy
+       function. The first component was split into its own function.
+       These dup_* functions allocated and duplicated the appropriate
+       context structure. The reorganized copy_* functions invoked
+       their corresponding dup_* functions and then linked the newly
+       duplicated structures to the task structure with which the
+       copy function was called.
+
+  7.2) unshare system call service function
+       * Check flags
+        Force implied flags. If CLONE_THREAD is set force CLONE_VM.
+        If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is
+        set and signals are also being shared, force CLONE_THREAD. If
+        CLONE_NEWNS is set, force CLONE_FS.
+       * For each context flag, invoke the corresponding unshare_*
+        helper routine with flags passed into the system call and a
+        reference to pointer pointing the new unshared structure
+       * If any new structures are created by unshare_* helper
+        functions, take the task_lock() on the current task,
+        modify appropriate context pointers, and release the
+         task lock.
+       * For all newly unshared structures, release the corresponding
+         older, shared, structures.
+
+  7.3) unshare_* helper functions
+       For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND,
+       and CLONE_THREAD, return -EINVAL since they are not implemented yet.
+       For others, check the flag value to see if the unsharing is
+       required for that structure. If it is, invoke the corresponding
+       dup_* function to allocate and duplicate the structure and return
+       a pointer to it.
+
+  7.4) Appropriately modify architecture specific code to register the
+       the new system call.
+
+8) Test Specification
+---------------------
+The test for unshare should test the following:
+  1) Valid flags: Test to check that clone flags for signal and
+       signal handlers, for which unsharing is not implemented
+       yet, return -EINVAL.
+  2) Missing/implied flags: Test to make sure that if unsharing
+       namespace without specifying unsharing of filesystem, correctly
+       unshares both namespace and filesystem information.
+  3) For each of the four (namespace, filesystem, files and vm)
+       supported unsharing, verify that the system call correctly
+       unshares the appropriate structure. Verify that unsharing
+       them individually as well as in combination with each
+       other works as expected.
+  4) Concurrent execution: Use shared memory segments and futex on
+       an address in the shm segment to synchronize execution of
+       about 10 threads. Have a couple of threads execute execve,
+       a couple _exit and the rest unshare with different combination
+       of flags. Verify that unsharing is performed as expected and
+       that there are no oops or hangs.
+
+9) Future Work
+--------------
+The current implementation of unshare does not allow unsharing of
+signals and signal handlers. Signals are complex to begin with and
+to unshare signals and/or signal handlers of a currently running
+process is even more complex. If in the future there is a specific
+need to allow unsharing of signals and/or signal handlers, it can
+be incrementally added to unshare without affecting legacy
+applications using unshare.
+
index 56e194f1a0b06ec52b4daf6702d52289901bc250..8bea3fbd0548297dcc73193c0d2ed485eda350c4 100644 (file)
@@ -42,4 +42,4 @@
  41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
  43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
- 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50]
+ 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
index cb3a59bbeb172b0aad3a7b95e6a9123482a340ae..8a352597830ffccc1eb942ae0020bfcb08b10ea6 100644 (file)
@@ -1,7 +1,7 @@
   0 -> UNKNOWN/GENERIC
   1 -> Proteus Pro [philips reference design]   [1131:2001,1131:2001]
   2 -> LifeView FlyVIDEO3000                    [5168:0138,4e42:0138]
-  3 -> LifeView FlyVIDEO2000                    [5168:0138]
+  3 -> LifeView/Typhoon FlyVIDEO2000            [5168:0138,4e42:0138]
   4 -> EMPRESS                                  [1131:6752]
   5 -> SKNet Monster TV                         [1131:4e85]
   6 -> Tevion MD 9717
  52 -> AverMedia AverTV/305                     [1461:2108]
  53 -> ASUS TV-FM 7135                          [1043:4845]
  54 -> LifeView FlyTV Platinum FM               [5168:0214,1489:0214]
- 55 -> LifeView FlyDVB-T DUO                    [5168:0502,5168:0306]
+ 55 -> LifeView FlyDVB-T DUO                    [5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  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 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
+ 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus    [5168:0502,4e42:0502]
  61 -> Philips TOUGH DVB-T reference design     [1131:2004]
  62 -> Compro VideoMate TV Gold+II
  63 -> Kworld Xpert TV PVR7134
index 9c5fc15d03d140467abc4714adfededf31af3dc5..153740f460a6cc67713662c2a2cf7b6c50169ebe 100644 (file)
@@ -40,6 +40,18 @@ APICs
    no_timer_check Don't check the IO-APIC timer. This can work around
                 problems with incorrect timer initialization on some boards.
 
+   apicmaintimer Run time keeping from the local APIC timer instead
+                 of using the PIT/HPET interrupt for this. This is useful
+                 when the PIT/HPET interrupts are unreliable.
+
+   noapicmaintimer  Don't do time keeping using the APIC timer.
+                Useful when this option was auto selected, but doesn't work.
+
+   apicpmtimer
+                Do APIC timer calibration using the pmtimer. Implies
+                apicmaintimer. Useful when your PIT timer is totally
+                broken.
+
 Early Console
 
    syntax: earlyprintk=vga
index 42955fe1ffa056df2f412280b7d9e45a17060d31..b22db521cec1eb5735878615f1dc70968a5c9f4e 100644 (file)
@@ -540,7 +540,8 @@ S:  Supported
 
 BTTV VIDEO4LINUX DRIVER
 P:     Mauro Carvalho Chehab
-M:     mchehab@brturbo.com.br
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     video4linux-list@redhat.com
 W:     http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
@@ -557,7 +558,8 @@ S:  Supported
 
 CONFIGFS
 P:     Joel Becker
-M:     Joel Becker <joel.becker@oracle.com>
+M:     joel.becker@oracle.com
+L:     linux-kernel@vger.kernel.org
 S:     Supported
 
 CIRRUS LOGIC GENERIC FBDEV DRIVER
@@ -836,11 +838,12 @@ S:        Maintained
 
 DVB SUBSYSTEM AND DRIVERS
 P:     LinuxTV.org Project
-M:     linux-dvb-maintainer@linuxtv.org
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     linux-dvb@linuxtv.org (subscription required)
 W:     http://linuxtv.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
-S:     Supported
+S:     Maintained
 
 EATA-DMA SCSI DRIVER
 P:     Michael Neuffer
@@ -928,6 +931,12 @@ M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com
 L:     ext3-users@redhat.com
 S:     Maintained
 
+F71805F HARDWARE MONITORING DRIVER
+P:     Jean Delvare
+M:     khali@linux-fr.org
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
 FARSYNC SYNCHRONOUS DRIVER
 P:     Kevin Curtis
 M:     kevin.curtis@farsite.co.uk
@@ -1984,7 +1993,6 @@ M:        philb@gnu.org
 P:     Tim Waugh
 M:     tim@cyberelk.net
 P:     David Campbell
-M:     campbell@torque.net
 P:     Andrea Arcangeli
 M:     andrea@suse.de
 L:     linux-parport@lists.infradead.org
@@ -2298,7 +2306,7 @@ S:        Supported
 
 SELINUX SECURITY MODULE
 P:     Stephen Smalley
-M:     sds@epoch.ncsc.mil
+M:     sds@tycho.nsa.gov
 P:     James Morris
 M:     jmorris@namei.org
 L:     linux-kernel@vger.kernel.org (kernel issues)
@@ -2956,7 +2964,8 @@ S:      Maintained
 
 VIDEO FOR LINUX
 P:     Mauro Carvalho Chehab
-M:     mchehab@brturbo.com.br
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     video4linux-list@redhat.com
 W:     http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
index 252a659896f32c99d96c60dd5ba849e82bd5a17b..a1158d1c051e348b86ba840fe7da5400714b0b72 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 16
-EXTRAVERSION =-rc1
+EXTRAVERSION =-rc2
 NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
@@ -442,7 +442,7 @@ export KBUILD_DEFCONFIG
 config %config: scripts_basic outputmakefile FORCE
        $(Q)mkdir -p include/linux
        $(Q)$(MAKE) $(build)=scripts/kconfig $@
-       $(Q)$(MAKE) .kernelrelease
+       $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
 
 else
 # ===========================================================================
index 4b873527ce1c56d354e86ddabb5825ba3d345f0a..02c2db08114ad66e42876d5e1f2b80c402ec9a84 100644 (file)
@@ -73,9 +73,6 @@ cpumask_t cpu_online_map;
 
 EXPORT_SYMBOL(cpu_online_map);
 
-/* cpus reported in the hwrpb */
-static unsigned long hwrpb_cpu_present_mask __initdata = 0;
-
 int smp_num_probed;            /* Internal processor count */
 int smp_num_cpus = 1;          /* Number that came online.  */
 
@@ -442,7 +439,7 @@ setup_smp(void)
                        if ((cpu->flags & 0x1cc) == 0x1cc) {
                                smp_num_probed++;
                                /* Assume here that "whami" == index */
-                               hwrpb_cpu_present_mask |= (1UL << i);
+                               cpu_set(i, cpu_possible_map);
                                cpu->pal_revision = boot_cpu_palrev;
                        }
 
@@ -453,12 +450,12 @@ setup_smp(void)
                }
        } else {
                smp_num_probed = 1;
-               hwrpb_cpu_present_mask = (1UL << boot_cpuid);
+               cpu_set(boot_cpuid, cpu_possible_map);
        }
        cpu_present_mask = cpumask_of_cpu(boot_cpuid);
 
        printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
-              smp_num_probed, hwrpb_cpu_present_mask);
+              smp_num_probed, cpu_possible_map.bits[0]);
 }
 
 /*
@@ -467,8 +464,6 @@ setup_smp(void)
 void __init
 smp_prepare_cpus(unsigned int max_cpus)
 {
-       int cpu_count, i;
-
        /* Take care of some initial bookkeeping.  */
        memset(ipi_data, 0, sizeof(ipi_data));
 
@@ -486,19 +481,7 @@ smp_prepare_cpus(unsigned int max_cpus)
 
        printk(KERN_INFO "SMP starting up secondaries.\n");
 
-       cpu_count = 1;
-       for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) {
-               if (i == boot_cpuid)
-                       continue;
-
-               if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
-                       continue;
-
-               cpu_set(i, cpu_possible_map);
-               cpu_count++;
-       }
-
-       smp_num_cpus = cpu_count;
+       smp_num_cpus = smp_num_probed;
 }
 
 void __devinit
index 5959e36c3b4c52ba2eaeaedf8afe9ecced20c3f2..15dc1a0dffbb6f2e048c837860bedf4b0c868779 100644 (file)
@@ -10,9 +10,9 @@ config ARM
        default y
        help
          The ARM series is a line of low-power-consumption RISC chip designs
-         licensed by ARM ltd and targeted at embedded applications and
+         licensed by ARM Ltd and targeted at embedded applications and
          handhelds such as the Compaq IPAQ.  ARM-based PCs are no longer
-         manufactured, but  legacy ARM-based PC hardware remains popular in
+         manufactured, but legacy ARM-based PC hardware remains popular in
          Europe.  There is an ARM Linux project with a web page at
          <http://www.arm.linux.org.uk/>.
 
@@ -69,6 +69,9 @@ config GENERIC_ISA_DMA
 config FIQ
        bool
 
+config ARCH_MTD_XIP
+       bool
+
 source "init/Kconfig"
 
 menu "System Type"
@@ -81,45 +84,62 @@ config ARCH_CLPS7500
        bool "Cirrus-CL-PS7500FE"
        select TIMER_ACORN
        select ISA
+       help
+         Support for the Cirrus Logic PS7500FE system-on-a-chip.
 
 config ARCH_CLPS711X
        bool "CLPS711x/EP721x-based"
+       help
+         Support for Cirrus Logic 711x/721x based boards.
 
 config ARCH_CO285
        bool "Co-EBSA285"
        select FOOTBRIDGE
        select FOOTBRIDGE_ADDIN
+       help
+         Support for Intel's EBSA285 companion chip.
 
 config ARCH_EBSA110
        bool "EBSA-110"
        select ISA
        help
          This is an evaluation board for the StrongARM processor available
-         from Digital. It has limited hardware on-board, including an onboard
+         from Digital. It has limited hardware on-board, including an
          Ethernet interface, two PCMCIA sockets, two serial ports and a
          parallel port.
 
 config ARCH_FOOTBRIDGE
        bool "FootBridge"
        select FOOTBRIDGE
+       help
+         Support for systems based on the DC21285 companion chip
+         ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
 config ARCH_INTEGRATOR
        bool "Integrator"
        select ARM_AMBA
        select ICST525
+       help
+         Support for ARM's Integrator platform.
 
 config ARCH_IOP3XX
        bool "IOP3xx-based"
        select PCI
+       help
+         Support for Intel's IOP3XX (XScale) family of processors.
 
 config ARCH_IXP4XX
        bool "IXP4xx-based"
        select DMABOUNCE
        select PCI
+       help
+         Support for Intel's IXP4XX (XScale) family of processors.
 
 config ARCH_IXP2000
        bool "IXP2400/2800-based"
        select PCI
+       help
+         Support for Intel's IXP2400/2800 (XScale) family of processors.
 
 config ARCH_L7200
        bool "LinkUp-L7200"
@@ -136,6 +156,9 @@ config ARCH_L7200
 
 config ARCH_PXA
        bool "PXA2xx-based"
+       select ARCH_MTD_XIP
+       help
+         Support for Intel's PXA2XX processor line.
 
 config ARCH_RPC
        bool "RiscPC"
@@ -152,19 +175,25 @@ config ARCH_SA1100
        bool "SA1100-based"
        select ISA
        select ARCH_DISCONTIGMEM_ENABLE
+       select ARCH_MTD_XIP
+       help
+         Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
        bool "Samsung S3C2410"
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
-         the Samsung SMDK2410 development board (and derviatives).
+         the Samsung SMDK2410 development board (and derivatives).
 
 config ARCH_SHARK
        bool "Shark"
        select ISA
        select ISA_DMA
        select PCI
+       help
+         Support for the StrongARM based Digital DNARD machine, also known
+         as "Shark" (<http://www.shark-linux.de/shark.html>).
 
 config ARCH_LH7A40X
        bool "Sharp LH7A40X"
@@ -176,6 +205,8 @@ config ARCH_LH7A40X
 
 config ARCH_OMAP
        bool "TI OMAP"
+       help
+         Support for TI's OMAP platform (OMAP1 and OMAP2).
 
 config ARCH_VERSATILE
        bool "Versatile"
@@ -194,6 +225,8 @@ config ARCH_REALVIEW
 
 config ARCH_IMX
        bool "IMX"
+       help
+         Support for Motorola's i.MX family of processors (MX1, MXL).
 
 config ARCH_H720X
        bool "Hynix-HMS720x-based"
@@ -210,8 +243,8 @@ config ARCH_AAEC2000
 config ARCH_AT91RM9200
        bool "AT91RM9200"
        help
-         Say Y here if you intend to run this kernel on an AT91RM9200-based
-         board.
+         Say Y here if you intend to run this kernel on an Atmel
+         AT91RM9200-based board.
 
 endchoice
 
@@ -417,8 +450,8 @@ config AEABI
          To use this you need GCC version 4.0.0 or later.
 
 config OABI_COMPAT
-       bool "Allow old ABI binaries to run with this kernel"
-       depends on AEABI
+       bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+       depends on AEABI && EXPERIMENTAL
        default y
        help
          This option preserves the old syscall interface along with the
index 5cdd13acf8ff14242d73895e6dfa7719cf40a566..1fe73d1988880354336a84f641aaaf66126a97ac 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
index 20838ccf1da7f91948531c3e0cf2a9a27d7a1c08..b7d934cdb1b735a1b28847afef231268f7b98bff 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
index 885a3184830ad6d08a4ecedc24cef9d671bad7f6..94bd9932a4027eb465dc5262d68f7f226c761f84 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
index 95a96a5462a0c8077426ee9b68018331dfd01156..1519124c550106c282dedb8ac12024e097a030bb 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
index 9592e3925c7925906a7bca0399db015ee374ff0d..5fdaf3ce9d5665be169d08b4493b3904a7d5a238 100644 (file)
@@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index d9d6bb86a6fa3829702cd02b1aad1a374cb37614..c67fc449a11f154582faf8d01f27f5eb6929d199 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index 2dc9d499c7d787dac9deea92b918c4f09c4506f5..60d66e82c51f454357d2739f82e2860d34c9a314 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index ea8f4b478fa3f91fa2eb761f7007e27b9503e651..f54f3dcc5b33f4a39b0c201f262929bb4180ef37 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index 1964ccd8a71f7fbd9a039fe2982d590e9c132d89..6695b07cf1ba91cd3121314381d501a92421912d 100644 (file)
@@ -1,11 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Sun Nov 13 17:41:24 2005
+# Linux kernel version: 2.6.16-rc2
+# Mon Feb  6 11:17:23 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 
@@ -28,27 +27,31 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT 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_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=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_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -102,6 +105,7 @@ CONFIG_ARCH_S3C2410=y
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
 
 #
 # S3C24XX Implementations
@@ -160,7 +164,6 @@ CONFIG_CPU_TLB_V4WBI=y
 # Bus support
 #
 CONFIG_ISA=y
-CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -172,6 +175,7 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_PREEMPT is not set
 # CONFIG_NO_IDLE_HZ is not set
+# CONFIG_AEABI is not set
 # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -214,6 +218,8 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
 #
@@ -259,6 +265,11 @@ CONFIG_TCP_CONG_BIC=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -276,7 +287,6 @@ CONFIG_TCP_CONG_BIC=y
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -299,6 +309,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
 #
 # Memory Technology Devices (MTD)
 #
@@ -412,8 +427,6 @@ CONFIG_PARPORT_1284=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -502,7 +515,6 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
@@ -607,11 +619,11 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_DIGIEPCA is not set
-# CONFIG_ESPSERIAL is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -625,6 +637,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -687,6 +700,7 @@ CONFIG_S3C2410_RTC=y
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
@@ -730,6 +744,12 @@ CONFIG_SENSORS_EEPROM=m
 # 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
+
 #
 # Hardware Monitoring support
 #
@@ -863,6 +883,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
@@ -897,6 +918,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -965,6 +987,7 @@ CONFIG_SOLARIS_X86_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
 
 #
@@ -1020,12 +1043,13 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+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_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1034,6 +1058,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
index d058e7c125681bccc28228f225d22525306925a7..8c3035d5ffc9c28c7c6ae416397b6341184c203b 100644 (file)
                CALL(sys_mq_getsetattr)
 /* 280 */      CALL(sys_waitid)
                CALL(sys_socket)
-               CALL(sys_bind)
-               CALL(sys_connect)
+               CALL(ABI(sys_bind, sys_oabi_bind))
+               CALL(ABI(sys_connect, sys_oabi_connect))
                CALL(sys_listen)
 /* 285 */      CALL(sys_accept)
                CALL(sys_getsockname)
                CALL(sys_getpeername)
                CALL(sys_socketpair)
                CALL(sys_send)
-/* 290 */      CALL(sys_sendto)
+/* 290 */      CALL(ABI(sys_sendto, sys_oabi_sendto))
                CALL(sys_recv)
                CALL(sys_recvfrom)
                CALL(sys_shutdown)
                CALL(sys_setsockopt)
 /* 295 */      CALL(sys_getsockopt)
-               CALL(sys_sendmsg)
+               CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
                CALL(sys_recvmsg)
                CALL(ABI(sys_semop, sys_oabi_semop))
                CALL(sys_semget)
index d401d908c46361264452bd925ffd1ca3c5c1a3c5..964cd717506bc0bec97f3526206e20cc78a82546 100644 (file)
@@ -333,9 +333,13 @@ __pabt_svc:
                                        @ from the exception stack
 
 #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
        @ make sure our user space atomic helper is aborted
        cmp     r2, #TASK_SIZE
        bichs   r3, r3, #PSR_Z_BIT
+#endif
 #endif
 
        @
@@ -705,7 +709,12 @@ __kuser_memory_barrier:                            @ 0xffff0fa0
  * The C flag is also set if *ptr was changed to allow for assembly
  * optimization in the calling code.
  *
- * Note: this routine already includes memory barriers as needed.
+ * Notes:
+ *
+ *    - This routine already includes memory barriers as needed.
+ *
+ *    - A failure might be transient, i.e. it is possible, although unlikely,
+ *      that "failure" be returned even if *ptr == oldval.
  *
  * For example, a user space atomic_add implementation could look like this:
  *
@@ -756,12 +765,18 @@ __kuser_cmpxchg:                          @ 0xffff0fc0
         * exception happening just after the str instruction which would
         * clear the Z flag although the exchange was done.
         */
+#ifdef CONFIG_MMU
        teq     ip, ip                  @ set Z flag
        ldr     ip, [r2]                @ load current val
        add     r3, r2, #1              @ prepare store ptr
        teqeq   ip, r0                  @ compare with oldval if still allowed
        streq   r1, [r3, #-1]!          @ store newval if still allowed
        subs    r0, r2, r3              @ if r2 == r3 the str occured
+#else
+#warning "NPTL on non MMU needs fixing"
+       mov     r0, #-1
+       adds    r0, r0, #0
+#endif
        mov     pc, lr
 
 #else
index eafa8e5284af36641cc03dd189bf5ae19352c250..9d4b76409c6446a99173a160d6e4a4349a015dd3 100644 (file)
  *   struct sembuf loses its padding with EABI.  Since arrays of them are
  *   used they have to be copyed to remove the padding. Compatibility wrappers
  *   provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ *
+ *   struct sockaddr_un loses its padding with EABI.  Since the size of the
+ *   structure is used as a validation test in unix_mkname(), we need to
+ *   change the length argument to 110 whenever it is 112.  Compatibility
+ *   wrappers provided below.
  */
 
 #include <linux/syscalls.h>
@@ -67,6 +77,7 @@
 #include <linux/fcntl.h>
 #include <linux/eventpoll.h>
 #include <linux/sem.h>
+#include <linux/socket.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 
@@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
                return sys_ipc(call, first, second, third, ptr, fifth);
        }
 }
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+                               size_t len, unsigned flags,
+                               struct sockaddr __user *addr,
+                               int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+       struct sockaddr __user *addr;
+       int msg_namelen;
+       sa_family_t sa_family;
+       if (msg &&
+           get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+           msg_namelen == 112 &&
+           get_user(addr, &msg->msg_name) == 0 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+       {
+               /*
+                * HACK ALERT: there is a limit to how much backward bending
+                * we should do for what is actually a transitional
+                * compatibility layer.  This already has known flaws with
+                * a few ioctls that we don't intend to fix.  Therefore
+                * consider this blatent hack as another one... and take care
+                * to run for cover.  In most cases it will "just work fine".
+                * If it doesn't, well, tough.
+                */
+               put_user(110, &msg->msg_namelen);
+       }
+       return sys_sendmsg(fd, msg, flags);
+}
+
index 0793dcf54f2e51dd30be757962db1483824a1d9d..0e2b641268ad172d4f4a481fbeba0918dbe4a170 100644 (file)
@@ -24,6 +24,8 @@ config ARCH_CEIVA
 
 config ARCH_CLEP7312
        bool "CLEP7312"
+       help
+         Boards based on the Cirrus Logic 7212/7312 chips.
 
 config ARCH_EDB7211
        bool "EDB7211"
index dc31e3fd6c5725ed823664018202962d2dec7ad3..8ab1b040288c0621b76ec338e04da435842ded65 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/mach/arch.h>
 #include <linux/interrupt.h>
 #include "generic.h"
-#include <asm/serial.h>
 
 static struct resource cs89x0_resources[] = {
        [0] = {
index 9e5a13bb39d01f4b173e7f2159e88b55c36356af..52fac89e95b59c28701cfdbedfee0519820cf1af 100644 (file)
@@ -106,6 +106,7 @@ static void __init enp2611_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 static inline int enp2611_pci_valid_device(struct pci_bus *bus,
index 7c782403042a4e523780119c9ab1907c58aa07d0..09101271298e0fa54ee93956555db25983da33d1 100644 (file)
@@ -68,6 +68,7 @@ void __init ixdp2400_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys)
index 10f06606d460a0b291a6cc6dfddebdbc0cd8d5ed..150519fb38ec9bf729689c76d908db56d58fe840 100644 (file)
@@ -212,6 +212,7 @@ void __init ixdp2x01_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 #define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
@@ -299,7 +300,9 @@ struct hw_pci ixdp2x01_pci __initdata = {
 
 int __init ixdp2x01_pci_init(void)
 {
-       pci_common_init(&ixdp2x01_pci);
+       if (machine_is_ixdp2401() || machine_is_ixdp2801())
+               pci_common_init(&ixdp2x01_pci);
+
        return 0;
 }
 
index bdc20b51b076a137d94c257b799e36724557b8d8..a177e78b2b878c141a034a6d3efa26aaca456bcd 100644 (file)
@@ -30,6 +30,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
 }
 
@@ -104,7 +105,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
index 9533c36a92df2e6cf57e5b24664b1ff10bcd640d..89f0cc74a5197a28d521c7714750dcaf21a6f963 100644 (file)
@@ -128,6 +128,7 @@ static void __init h2_init_smc91x(void)
 
 static void __init h2_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h2_init_smc91x();
@@ -194,7 +195,7 @@ static void __init h2_init(void)
 
 static void __init h2_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H2, "TI-H2")
index d665efc1c34423025a050e9c124fa858e4a12246..d9f3862659967e4322c7edbe1e9172e0ed10c564 100644 (file)
@@ -203,6 +203,7 @@ static void __init h3_init_smc91x(void)
 
 void h3_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h3_init_smc91x();
@@ -210,7 +211,7 @@ void h3_init_irq(void)
 
 static void __init h3_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
index 652f37c7f9063addf813f4a6d8eb50a2142aeb29..a04e4332915e63810f5ae9e85613b2e5a69f8777 100644 (file)
@@ -181,6 +181,7 @@ static void __init innovator_init_smc91x(void)
 
 void innovator_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -285,7 +286,7 @@ static void __init innovator_init(void)
 
 static void __init innovator_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap1510()) {
index 58f783930d45486536d5c08c6b7212175693e2a3..60d5f8a3339c0f370ae4269428bcaad952b9727c 100644 (file)
@@ -65,6 +65,7 @@ static struct omap_board_config_kernel netstar_config[] = {
 
 static void __init netstar_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 }
@@ -108,7 +109,7 @@ static void __init netstar_init(void)
 
 static void __init netstar_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 #define MACHINE_PANICED                1
index e5d126e8f2764aa4db2ab733c1e64b187855f64c..543fa136106d8bfacac4d2b495f6410720318850 100644 (file)
@@ -169,6 +169,7 @@ static void __init osk_init_cf(void)
 
 static void __init osk_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        osk_init_smc91x();
@@ -269,7 +270,7 @@ static void __init osk_init(void)
 
 static void __init osk_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_OSK, "TI-OSK")
index 67fada207622f826349cbe784c91e727a255c9e5..e488f723677546059707e70df696eb9321104f76 100644 (file)
@@ -34,6 +34,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
 }
 
@@ -72,7 +73,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
index 88708a0c52a25b0915b60e0828a3f6327e838840..3913a3cc0ce6cb4f255652e6991e52ffe9cf8c8c 100644 (file)
@@ -144,6 +144,7 @@ static void __init perseus2_init_smc91x(void)
 
 void omap_perseus2_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        perseus2_init_smc91x();
@@ -160,7 +161,7 @@ static struct map_desc omap_perseus2_io_desc[] __initdata = {
 
 static void __init omap_perseus2_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
        iotable_init(omap_perseus2_io_desc,
                     ARRAY_SIZE(omap_perseus2_io_desc));
 
index 959b4b847c871c57185ecd1d37d365d6588cb8f6..bfd5fdd1a875937e1fec38f8ba1edfd1b9ee41c4 100644 (file)
@@ -162,6 +162,7 @@ static struct omap_board_config_kernel voiceblue_config[] = {
 
 static void __init voiceblue_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 }
@@ -206,7 +207,7 @@ static void __init voiceblue_init(void)
 
 static void __init voiceblue_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 #define MACHINE_PANICED                1
index a7a19f75b9e1ad119434cb001c96d5c4a79b28f2..82d556be79c51d24418c7da9198f91ccba5986d6 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
+#include <asm/tlb.h>
 #include <asm/mach/map.h>
 #include <asm/io.h>
 #include <asm/arch/mux.h>
@@ -83,15 +84,24 @@ static struct map_desc omap16xx_io_desc[] __initdata = {
 };
 #endif
 
-static int initialized = 0;
-
-static void __init _omap_map_io(void)
+/*
+ * Maps common IO regions for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_map_common_io(void)
 {
-       initialized = 1;
-
-       /* We have to initialize the IO space mapping before we can run
-        * cpu_is_omapxxx() macros. */
        iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+
+       /* Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but we must also do it here because of the CPU
+        * revision check below.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+
+       /* We want to check CPU revision early for cpu_is_omapxxxx() macros.
+        * IO space mapping must be initialized before we can do that.
+        */
        omap_check_revision();
 
 #ifdef CONFIG_ARCH_OMAP730
@@ -111,7 +121,14 @@ static void __init _omap_map_io(void)
 #endif
 
        omap_sram_init();
+}
 
+/*
+ * Common low-level hardware init for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_init_common_hw()
+{
        /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
         * on a Posted Write in the TIPB Bridge".
         */
@@ -121,16 +138,7 @@ static void __init _omap_map_io(void)
        /* Must init clocks early to assure that timer interrupt works
         */
        omap1_clk_init();
-}
 
-/*
- * This should only get called from board specific init
- */
-void __init omap_map_common_io(void)
-{
-       if (!initialized) {
-               _omap_map_io();
-               omap1_mux_init();
-       }
+       omap1_mux_init();
 }
 
index b937123e5c65dc7c093a3a296d6bb09a2d599131..eaecbf422d8c825eb49f8b8c373d9914c3cfb598 100644 (file)
@@ -33,6 +33,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap2_init_common_hw();
        omap_init_irq();
 }
 
@@ -64,7 +65,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
index c3c35d40378a511ac07b76251001c2d14d07c0b2..a300d634d8a5949709355c092be8e78853dfbede 100644 (file)
@@ -136,6 +136,7 @@ static inline void __init h4_init_smc91x(void)
 
 static void __init omap_h4_init_irq(void)
 {
+       omap2_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h4_init_smc91x();
@@ -181,7 +182,7 @@ static void __init omap_h4_init(void)
 
 static void __init omap_h4_map_io(void)
 {
-       omap_map_common_io();
+       omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
index b41b1efaa2cf9088e30fe8fe9ee1d4dda6fd46c7..3baa70819f24fb20d6a0024e035946c5e8c49534 100644 (file)
@@ -44,7 +44,7 @@ unsigned int get_clk_frequency_khz( int info)
 
        /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
        asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
-       t  = clkcfg & (1 << 1);
+       t  = clkcfg & (1 << 0);
        ht = clkcfg & (1 << 2);
        b  = clkcfg & (1 << 3);
 
index 4a222f59f2cf0aaeb5c20aa8507b39a22371467e..4303d988c4bf3fa621d070718bf591766c686595 100644 (file)
@@ -182,7 +182,7 @@ static const struct icst307_params realview_oscvco_params = {
 static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
 {
        void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-       void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
+       void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
        u32 val;
 
        val = readl(sys_osc) & ~0x7ffff;
index b4f1e051c768a4dc06d583cdc52da5445e9fb190..1217bf00309c7049d508d90c2c2614b662a705e2 100644 (file)
@@ -10,9 +10,13 @@ obj-m                        :=
 obj-n                  :=
 obj-                   :=
 
+# S3C2400 support files
+obj-$(CONFIG_CPU_S3C2400)  += s3c2400-gpio.o
+
 # S3C2410 support files
 
 obj-$(CONFIG_CPU_S3C2410)  += s3c2410.o
+obj-$(CONFIG_CPU_S3C2410)  += s3c2410-gpio.o
 obj-$(CONFIG_S3C2410_DMA)  += dma.o
 
 # Power Management support
@@ -25,6 +29,7 @@ obj-$(CONFIG_PM_SIMTEC)          += pm-simtec.o
 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
 
 # bast extras
 
index af2f3d52b61b8e235c2a3cc37e2db9dcd32783e1..08489efdaf0639670ecc9db5576e280ebb691b92 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/mutex.h>
 
 #include <asm/hardware.h>
-#include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -59,22 +58,18 @@ static DEFINE_MUTEX(clocks_mutex);
 void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
 {
        unsigned long clkcon;
-       unsigned long flags;
-
-       local_irq_save(flags);
 
        clkcon = __raw_readl(S3C2410_CLKCON);
-       clkcon &= ~clocks;
 
        if (enable)
                clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
 
        /* ensure none of the special function bits set */
        clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
 
        __raw_writel(clkcon, S3C2410_CLKCON);
-
-       local_irq_restore(flags);
 }
 
 /* enable and disable calls for use with the clk struct */
@@ -138,16 +133,32 @@ void clk_put(struct clk *clk)
 
 int clk_enable(struct clk *clk)
 {
-       if (IS_ERR(clk))
+       if (IS_ERR(clk) || clk == NULL)
                return -EINVAL;
 
-       return (clk->enable)(clk, 1);
+       clk_enable(clk->parent);
+
+       mutex_lock(&clocks_mutex);
+
+       if ((clk->usage++) == 0)
+               (clk->enable)(clk, 1);
+
+       mutex_unlock(&clocks_mutex);
+       return 0;
 }
 
 void clk_disable(struct clk *clk)
 {
-       if (!IS_ERR(clk))
+       if (IS_ERR(clk) || clk == NULL)
+               return;
+
+       mutex_lock(&clocks_mutex);
+
+       if ((--clk->usage) == 0)
                (clk->enable)(clk, 0);
+
+       mutex_unlock(&clocks_mutex);
+       clk_disable(clk->parent);
 }
 
 
@@ -361,6 +372,14 @@ int s3c24xx_register_clock(struct clk *clk)
        if (clk->enable == NULL)
                clk->enable = clk_null_enable;
 
+       /* if this is a standard clock, set the usage state */
+
+       if (clk->ctrlbit) {
+               unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
+
+               clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
+       }
+
        /* add to the list of available clocks */
 
        mutex_lock(&clocks_mutex);
@@ -402,6 +421,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
         * the LCD clock if it is not needed.
        */
 
+       mutex_lock(&clocks_mutex);
+
        s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
@@ -409,6 +430,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
        s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
 
+       mutex_unlock(&clocks_mutex);
+
        /* assume uart clocks are correctly setup */
 
        /* register our clocks */
index 177d5c8decf74306bbf5eb874840507fd5557b2c..eb5c95d1e7f255491a1bff88f7745a43572afe41 100644 (file)
@@ -16,6 +16,7 @@ struct clk {
        struct clk           *parent;
        const char           *name;
        int                   id;
+       int                   usage;
        unsigned long         rate;
        unsigned long         ctrlbit;
        int                 (*enable)(struct clk *, int enable);
index 687fe371369d5e42d01fe5fb988b6f536e86b0f5..00a379334b60b2d325da1a8614a4c3e69e38ebaf 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "cpu.h"
 #include "clock.h"
+#include "s3c2400.h"
 #include "s3c2410.h"
 #include "s3c2440.h"
 
@@ -55,6 +56,7 @@ struct cpu_table {
 
 /* table of supported CPUs */
 
+static const char name_s3c2400[]  = "S3C2400";
 static const char name_s3c2410[]  = "S3C2410";
 static const char name_s3c2440[]  = "S3C2440";
 static const char name_s3c2410a[] = "S3C2410A";
@@ -96,7 +98,16 @@ static struct cpu_table cpu_ids[] __initdata = {
                .init_uarts     = s3c2440_init_uarts,
                .init           = s3c2440_init,
                .name           = name_s3c2440a
-       }
+       },
+       {
+               .idcode         = 0x0,   /* S3C2400 doesn't have an idcode */
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2400_map_io,
+               .init_clocks    = s3c2400_init_clocks,
+               .init_uarts     = s3c2400_init_uarts,
+               .init           = s3c2400_init,
+               .name           = name_s3c2400
+       },
 };
 
 /* minimal IO mapping */
@@ -148,12 +159,15 @@ static struct cpu_table *cpu;
 
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
-       unsigned long idcode;
+       unsigned long idcode = 0x0;
 
        /* initialise the io descriptors we need for initialisation */
        iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
 
+#ifndef CONFIG_CPU_S3C2400
        idcode = __raw_readl(S3C2410_GSTATUS1);
+#endif
+
        cpu = s3c_lookup_cpu(idcode);
 
        if (cpu == NULL) {
index b8d994a24d1c18173252feedadceb562449a2a23..0a47d38789a57467678b7a4e971b3c4b4e43bdb8 100644 (file)
@@ -275,6 +275,11 @@ static struct resource s3c_adc_resource[] = {
        },
        [1] = {
                .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start = IRQ_ADC,
                .end   = IRQ_ADC,
                .flags = IORESOURCE_IRQ,
        }
index 23ea3d5fa09c1be9bcc9084c1c8203b72b7c80c4..cd39e86845848ec6a515383fef3c6d4bda3ac114 100644 (file)
@@ -31,6 +31,7 @@
  *     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
  */
 
 
@@ -48,7 +49,7 @@
 
 void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
 {
-       void __iomem *base = S3C2410_GPIO_BASE(pin);
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
        unsigned long mask;
        unsigned long con;
        unsigned long flags;
@@ -95,7 +96,7 @@ EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
 
 unsigned int s3c2410_gpio_getcfg(unsigned int pin)
 {
-       void __iomem *base = S3C2410_GPIO_BASE(pin);
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
        unsigned long mask;
 
        if (pin < S3C2410_GPIO_BANKB) {
@@ -111,7 +112,7 @@ EXPORT_SYMBOL(s3c2410_gpio_getcfg);
 
 void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
 {
-       void __iomem *base = S3C2410_GPIO_BASE(pin);
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
        unsigned long offs = S3C2410_GPIO_OFFSET(pin);
        unsigned long flags;
        unsigned long up;
@@ -133,7 +134,7 @@ EXPORT_SYMBOL(s3c2410_gpio_pullup);
 
 void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
 {
-       void __iomem *base = S3C2410_GPIO_BASE(pin);
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
        unsigned long offs = S3C2410_GPIO_OFFSET(pin);
        unsigned long flags;
        unsigned long dat;
@@ -152,7 +153,7 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin);
 
 unsigned int s3c2410_gpio_getpin(unsigned int pin)
 {
-       void __iomem *base = S3C2410_GPIO_BASE(pin);
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
        unsigned long offs = S3C2410_GPIO_OFFSET(pin);
 
        return __raw_readl(base + 0x04) & (1<< offs);
@@ -166,70 +167,13 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
        unsigned long misccr;
 
        local_irq_save(flags);
-       misccr = __raw_readl(S3C2410_MISCCR);
+       misccr = __raw_readl(S3C24XX_MISCCR);
        misccr &= ~clear;
        misccr ^= change;
-       __raw_writel(misccr, S3C2410_MISCCR);
+       __raw_writel(misccr, S3C24XX_MISCCR);
        local_irq_restore(flags);
 
        return misccr;
 }
 
 EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-       if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23)
-               return -1;      /* not valid interrupts */
-
-       if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
-               return -1;      /* not valid pin */
-
-       if (pin < S3C2410_GPF4)
-               return (pin - S3C2410_GPF0) + IRQ_EINT0;
-
-       if (pin < S3C2410_GPG0)
-               return (pin - S3C2410_GPF4) + IRQ_EINT4;
-
-       return (pin - S3C2410_GPG0) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
-
-int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
-                          unsigned int config)
-{
-       void __iomem *reg = S3C2410_EINFLT0;
-       unsigned long flags;
-       unsigned long val;
-
-       if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
-               return -1;
-
-       config &= 0xff;
-
-       pin -= S3C2410_GPG8_EINT16;
-       reg += pin & ~3;
-
-       local_irq_save(flags);
-
-       /* update filter width and clock source */
-
-       val = __raw_readl(reg);
-       val &= ~(0xff << ((pin & 3) * 8));
-       val |= config << ((pin & 3) * 8);
-       __raw_writel(val, reg);
-
-       /* update filter enable */
-
-       val = __raw_readl(S3C2410_EXTINT2);
-       val &= ~(1 << ((pin * 4) + 3));
-       val |= on << ((pin * 4) + 3);
-       __raw_writel(val, S3C2410_EXTINT2);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2410/s3c2400-gpio.c
new file mode 100644 (file)
index 0000000..5127f39
--- /dev/null
@@ -0,0 +1,45 @@
+/* linux/arch/arm/mach-s3c2410/gpio.c
+ *
+ * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
+ *
+ * S3C2400 GPIO 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
+ *
+ * Changelog
+ *     15-Jan-2006  LCVR  Splitted from gpio.c, adding support for the S3C2400
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-gpio.h>
+
+int s3c2400_gpio_getirq(unsigned int pin)
+{
+       if (pin < S3C2410_GPE0 || pin > S3C2400_GPE7_EINT7)
+               return -1;  /* not valid interrupts */
+
+       return (pin - S3C2410_GPE0) + IRQ_EINT0;
+}
+
+EXPORT_SYMBOL(s3c2400_gpio_getirq);
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
new file mode 100644 (file)
index 0000000..d5e1cae
--- /dev/null
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-s3c2410/gpio.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 GPIO 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
+ *
+ * Changelog
+ *     15-Jan-2006  LCVR  Splitted from gpio.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-gpio.h>
+
+int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+                          unsigned int config)
+{
+       void __iomem *reg = S3C2410_EINFLT0;
+       unsigned long flags;
+       unsigned long val;
+
+       if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
+               return -1;
+
+       config &= 0xff;
+
+       pin -= S3C2410_GPG8_EINT16;
+       reg += pin & ~3;
+
+       local_irq_save(flags);
+
+       /* update filter width and clock source */
+
+       val = __raw_readl(reg);
+       val &= ~(0xff << ((pin & 3) * 8));
+       val |= config << ((pin & 3) * 8);
+       __raw_writel(val, reg);
+
+       /* update filter enable */
+
+       val = __raw_readl(S3C2410_EXTINT2);
+       val &= ~(1 << ((pin * 4) + 3));
+       val |= on << ((pin * 4) + 3);
+       __raw_writel(val, S3C2410_EXTINT2);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
+
+int s3c2410_gpio_getirq(unsigned int pin)
+{
+       if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23)
+               return -1;      /* not valid interrupts */
+
+       if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
+               return -1;      /* not valid pin */
+
+       if (pin < S3C2410_GPF4)
+               return (pin - S3C2410_GPF0) + IRQ_EINT0;
+
+       if (pin < S3C2410_GPG0)
+               return (pin - S3C2410_GPF4) + IRQ_EINT4;
+
+       return (pin - S3C2410_GPG0) + IRQ_EINT8;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getirq);
index e9a055b779b7f1158c1759ebd7cecab08e4a2ab7..832fb86a03b430343dd26e9e5be83168ab644c17 100644 (file)
@@ -72,7 +72,7 @@ ENTRY(s3c2410_cpu_suspend)
        @@ prepare cpu to sleep
 
        ldr     r4, =S3C2410_REFRESH
-       ldr     r5, =S3C2410_MISCCR
+       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)
index 72966d90e956b88ed001605c332128efa081ee58..d921c1024ae0821963125a2f637a825123124f7d 100644 (file)
@@ -92,22 +92,16 @@ ENTRY(v6_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v6_coherent_user_range)
-       bic     r0, r0, #CACHE_LINE_SIZE - 1
-1:
+
 #ifdef HARVARD_CACHE
-       mcr     p15, 0, r0, c7, c10, 1          @ clean D line
+       bic     r0, r0, #CACHE_LINE_SIZE - 1
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D line
        mcr     p15, 0, r0, c7, c5, 1           @ invalidate I line
-#endif
-       mcr     p15, 0, r0, c7, c5, 7           @ invalidate BTB entry
-       add     r0, r0, #BTB_FLUSH_SIZE
-       mcr     p15, 0, r0, c7, c5, 7           @ invalidate BTB entry
-       add     r0, r0, #BTB_FLUSH_SIZE
-       mcr     p15, 0, r0, c7, c5, 7           @ invalidate BTB entry
-       add     r0, r0, #BTB_FLUSH_SIZE
-       mcr     p15, 0, r0, c7, c5, 7           @ invalidate BTB entry
-       add     r0, r0, #BTB_FLUSH_SIZE
+       add     r0, r0, #CACHE_LINE_SIZE
        cmp     r0, r1
        blo     1b
+#endif
+       mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
 #ifdef HARVARD_CACHE
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
index 861b35947280fcc78897c01df1e3c9a8dc0da265..2d3823ec315384e5bc117184b8ae33f5d6fa0e51 100644 (file)
@@ -241,7 +241,15 @@ ENTRY(xscale_flush_user_cache_range)
  *     it also trashes the mini I-cache used by JTAG debuggers.
  */
 ENTRY(xscale_coherent_kern_range)
-       /* FALLTHROUGH */
+       bic     r0, r0, #CACHELINESIZE - 1
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, #CACHELINESIZE
+       cmp     r0, r1
+       blo     1b
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
+       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write (& Fill) Buffer
+       mov     pc, lr
 
 /*
  *     coherent_user_range(start, end)
@@ -252,18 +260,16 @@ ENTRY(xscale_coherent_kern_range)
  *
  *     - start  - virtual start address
  *     - end    - virtual end address
- *
- *     Note: single I-cache line invalidation isn't used here since
- *     it also trashes the mini I-cache used by JTAG debuggers.
  */
 ENTRY(xscale_coherent_user_range)
        bic     r0, r0, #CACHELINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       mcr     p15, 0, r0, c7, c5, 1           @ Invalidate I cache entry
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
        mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
+       mcr     p15, 0, r0, c7, c5, 6           @ Invalidate BTB
        mcr     p15, 0, r0, c7, c10, 4          @ Drain Write (& Fill) Buffer
        mov     pc, lr
 
index 1415930ceee1a0908d32d540fb8867a1975cdedc..6f8bc1f0e6a11a9eae95968f7356ed5a2b895a78 100644 (file)
@@ -137,8 +137,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        if (spec) {
                init_MUTEX(&op_arm_sem);
 
-               if (spec->init() < 0)
-                       return -ENODEV;
+               ret = spec->init();
+               if (ret < 0)
+                       return ret;
 
                op_arm_model = spec;
                init_driverfs();
index 792f66375830d11b607fffe69daa6a8945414144..ee82763b02b8f18ba66690bd10d26c1bb965f813 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 
 #include <asm/mach/map.h>
+#include <asm/tlb.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
@@ -95,6 +96,14 @@ void __init omap_map_sram(void)
               omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
               omap_sram_io_desc[0].length);
 
+       /*
+        * Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but since we're called from map_io(), we
+        * must do it here.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+
        /*
         * Looks like we need to preserve some bootloader code at the
         * beginning of SRAM for jumping to flash for reboot to work...
index ea65d585cf5ece14111068da24094a3ebeea9c1a..ee114699ef8e917e4cc51610511529ec68ce900a 100644 (file)
@@ -119,7 +119,7 @@ $(SRC_ARCH)/.links:
        @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
        @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
        @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
+       @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
        @touch $@
 
 # Create link to sub arch includes
index f214f74f264e43a65415d490a640ae31364a94de..961c0d58ded4a52ca5313e0ef94e62f8d0adf126 100644 (file)
@@ -202,18 +202,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        int i;
                        unsigned long tmp;
                        
+                       ret = 0;
                        for (i = 0; i <= PT_MAX; i++) {
                                tmp = get_reg(child, i);
                                
                                if (put_user(tmp, datap)) {
                                        ret = -EFAULT;
-                                       goto out_tsk;
+                                       break;
                                }
                                
                                data += sizeof(long);
                        }
 
-                       ret = 0;
                        break;
                }
 
@@ -222,10 +222,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        int i;
                        unsigned long tmp;
                        
+                       ret = 0;
                        for (i = 0; i <= PT_MAX; i++) {
                                if (get_user(tmp, datap)) {
                                        ret = -EFAULT;
-                                       goto out_tsk;
+                                       break;
                                }
                                
                                if (i == PT_DCCR) {
@@ -237,7 +238,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                                data += sizeof(long);
                        }
                        
-                       ret = 0;
                        break;
                }
 
index d11206e467ab3e9d8ec1cf7f82b62cb7423ec6bf..1ba57efff60d5efb96194a7bd0f88f81fa9a58a5 100644 (file)
@@ -24,7 +24,6 @@
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 
 extern int root_mountflags;
index d86c865a7cd22b1d1892e03d3473b45767539677..0afec8566e7bd750743910580c06093481e29daa 100644 (file)
@@ -442,6 +442,7 @@ config HIGHMEM4G
 
 config HIGHMEM64G
        bool "64GB"
+       depends on X86_CMPXCHG64
        help
          Select this if you have a 32-bit processor and more than 4
          gigabytes of physical RAM.
index f21fa0d4482f4f5d91d31047c5c402433bb7e8b5..79577f0ace98847ee39a4f7ad4c9842f3ea88ec6 100644 (file)
@@ -248,10 +248,17 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
 
        acpi_table_print_madt_entry(header);
 
-       /* Register even disabled CPUs for cpu hotplug */
-
-       x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
+       /* Record local apic id only when enabled */
+       if (processor->flags.enabled)
+               x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 
+       /*
+        * We need to register disabled CPU as well to permit
+        * counting disabled CPUs. This allows us to size
+        * cpus_possible_map more accurately, to permit
+        * to not preallocating memory for all NR_CPUS
+        * when we use CPU hotplug.
+        */
        mp_register_lapic(processor->id,        /* APIC ID */
                          processor->flags.enabled);    /* Enabled? */
 
index acd3f1e34ca6661c331edd0f0369e93da7a744b3..f39e09ef64ecba8655752362e6cda92e18c5e90f 100644 (file)
@@ -75,8 +75,10 @@ void ack_bad_irq(unsigned int irq)
         * holds up an irq slot - in excessive cases (when multiple
         * unexpected vectors occur) that might lock up the APIC
         * completely.
+        * But only ack when the APIC is enabled -AK
         */
-       ack_APIC_irq();
+       if (cpu_has_apic)
+               ack_APIC_irq();
 }
 
 void __init apic_intr_init(void)
@@ -1303,6 +1305,7 @@ int __init APIC_init_uniprocessor (void)
        if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                        boot_cpu_physical_apicid);
+               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
                return -1;
        }
 
index 333578a4e91afcf768a5dc35e10188a76c06591f..0810f81f2a05d154cf0bc8bcd4885129eef831d8 100644 (file)
@@ -282,3 +282,11 @@ int __init amd_init_cpu(void)
 }
 
 //early_arch_initcall(amd_init_cpu);
+
+static int __init amd_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_AMD] = NULL;
+       return 0;
+}
+
+late_initcall(amd_exit_cpu);
index 0dd92a23d62206e9d0fe0e59976c39872dee8ada..f52669ecb93fd549f40878971f0c16c860a43ed2 100644 (file)
@@ -470,3 +470,11 @@ int __init centaur_init_cpu(void)
 }
 
 //early_arch_initcall(centaur_init_cpu);
+
+static int __init centaur_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_CENTAUR] = NULL;
+       return 0;
+}
+
+late_initcall(centaur_exit_cpu);
index 15aee26ec2b6308be3d9e9f7e0e47f120be11fe1..7eb9213734a321614ea6da6837ccd1bbbdf1dd85 100644 (file)
@@ -44,6 +44,7 @@ static void default_init(struct cpuinfo_x86 * c)
 
 static struct cpu_dev default_cpu = {
        .c_init = default_init,
+       .c_vendor = "Unknown",
 };
 static struct cpu_dev * this_cpu = &default_cpu;
 
@@ -150,6 +151,7 @@ static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 {
        char *v = c->x86_vendor_id;
        int i;
+       static int printed;
 
        for (i = 0; i < X86_VENDOR_NUM; i++) {
                if (cpu_devs[i]) {
@@ -159,10 +161,17 @@ static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
                                c->x86_vendor = i;
                                if (!early)
                                        this_cpu = cpu_devs[i];
-                               break;
+                               return;
                        }
                }
        }
+       if (!printed) {
+               printed++;
+               printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n");
+               printk(KERN_ERR "CPU: Your system may be unstable.\n");
+       }
+       c->x86_vendor = X86_VENDOR_UNKNOWN;
+       this_cpu = &default_cpu;
 }
 
 
index 75015975d0386a47cd48439d4eefa66cb2bcb75c..00f2e058797cffd8019b08ecfb1fdbdc3215e7a1 100644 (file)
@@ -345,7 +345,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
 /*
  * Handle National Semiconductor branded processors
  */
-static void __devinit init_nsc(struct cpuinfo_x86 *c)
+static void __init init_nsc(struct cpuinfo_x86 *c)
 {
        /* There may be GX1 processors in the wild that are branded
         * NSC and not Cyrix.
@@ -444,6 +444,14 @@ int __init cyrix_init_cpu(void)
 
 //early_arch_initcall(cyrix_init_cpu);
 
+static int __init cyrix_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_CYRIX] = NULL;
+       return 0;
+}
+
+late_initcall(cyrix_exit_cpu);
+
 static struct cpu_dev nsc_cpu_dev __initdata = {
        .c_vendor       = "NSC",
        .c_ident        = { "Geode by NSC" },
@@ -458,3 +466,11 @@ int __init nsc_init_cpu(void)
 }
 
 //early_arch_initcall(nsc_init_cpu);
+
+static int __init nsc_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_NSC] = NULL;
+       return 0;
+}
+
+late_initcall(nsc_exit_cpu);
index af591c73345fa4120e6716b37e262b35e12754af..ffe58cee0c488241b3a03a838064eba3df182395 100644 (file)
@@ -152,6 +152,7 @@ static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le
        return 0;
 }
 
+/* will only be called once; __init is safe here */
 static int __init find_num_cache_leaves(void)
 {
        unsigned int            eax, ebx, ecx, edx;
index 30898a260a5cd8c86c2b2b339d43bf0f0f2bfd81..ad87fa58058d574c7eaa431b2497f82ff60156a8 100644 (file)
@@ -61,3 +61,11 @@ int __init nexgen_init_cpu(void)
 }
 
 //early_arch_initcall(nexgen_init_cpu);
+
+static int __init nexgen_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_NEXGEN] = NULL;
+       return 0;
+}
+
+late_initcall(nexgen_exit_cpu);
index 8602425628ca7b0f5066fb16ad2e0713421e7829..d08d5a2811c83cb85d05c697293985b86c86de42 100644 (file)
@@ -51,3 +51,11 @@ int __init rise_init_cpu(void)
 }
 
 //early_arch_initcall(rise_init_cpu);
+
+static int __init rise_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_RISE] = NULL;
+       return 0;
+}
+
+late_initcall(rise_exit_cpu);
index fc426380366bcbbd131e7e2d7f508f2f2ca1349c..bdbeb77f4e22fa9e7f6636cf03c03e8bb59c4dd6 100644 (file)
@@ -84,7 +84,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c)
 #endif
 }
 
-static void transmeta_identify(struct cpuinfo_x86 * c)
+static void __init transmeta_identify(struct cpuinfo_x86 * c)
 {
        u32 xlvl;
        generic_identify(c);
@@ -111,3 +111,11 @@ int __init transmeta_init_cpu(void)
 }
 
 //early_arch_initcall(transmeta_init_cpu);
+
+static int __init transmeta_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_TRANSMETA] = NULL;
+       return 0;
+}
+
+late_initcall(transmeta_exit_cpu);
index 264fcad559d5ccecba710dbaaee5376913964b52..2cd988f6dc556c4bd5f415f93de77d12c1b5e8cf 100644 (file)
@@ -31,3 +31,11 @@ int __init umc_init_cpu(void)
 }
 
 //early_arch_initcall(umc_init_cpu);
+
+static int __init umc_exit_cpu(void)
+{
+       cpu_devs[X86_VENDOR_UMC] = NULL;
+       return 0;
+}
+
+late_initcall(umc_exit_cpu);
index d661703ac1cb713db7327de628e4f7f5b09efcb1..63f39a7e2c96b0e3db1ce48ab73696e95db60a0c 100644 (file)
@@ -138,7 +138,7 @@ static int __init check_nmi_watchdog(void)
        if (nmi_watchdog == NMI_LOCAL_APIC)
                smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for_each_cpu(cpu)
                prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
        local_irq_enable();
        mdelay((10*1000)/nmi_hz); // wait 10 ticks
index 2185377fdde118424aaa36b3b3d8c36498373161..0480454ebffa6808d09735ecb3bf85232c1400ac 100644 (file)
@@ -297,8 +297,10 @@ void show_regs(struct pt_regs * regs)
 
        if (user_mode(regs))
                printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-       printk(" EFLAGS: %08lx    %s  (%s)\n",
-              regs->eflags, print_tainted(), system_utsname.release);
+       printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
+              regs->eflags, print_tainted(), system_utsname.release,
+              (int)strcspn(system_utsname.version, " "),
+              system_utsname.version);
        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
                regs->eax,regs->ebx,regs->ecx,regs->edx);
        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
index 1b665928336bd547c166e6aff4a11b4d786bf620..5a8b3fb6d27bed1728326ecc606afa94307a378c 100644 (file)
@@ -309,3 +309,4 @@ ENTRY(sys_call_table)
        .long sys_faccessat
        .long sys_pselect6
        .long sys_ppoll
+       .long sys_unshare               /* 310 */
index 0aaebf3e1cfa321a6b20f6ade450063f3554e0f7..b814dbdcc91e58b06c140ff1a099f223c2212768 100644 (file)
@@ -166,7 +166,8 @@ static void show_trace_log_lvl(struct task_struct *task,
                stack = (unsigned long*)context->previous_esp;
                if (!stack)
                        break;
-               printk(KERN_EMERG " =======================\n");
+               printk(log_lvl);
+               printk(" =======================\n");
        }
 }
 
@@ -239,9 +240,11 @@ void show_registers(struct pt_regs *regs)
        }
        print_modules();
        printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
-                       "EFLAGS: %08lx   (%s) \n",
+                       "EFLAGS: %08lx   (%s %.*s) \n",
                smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-               print_tainted(), regs->eflags, system_utsname.release);
+               print_tainted(), regs->eflags, system_utsname.release,
+               (int)strcspn(system_utsname.version, " "),
+               system_utsname.version);
        print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
        printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
index 21654be3f73f6409a6d33aa8de16b0a9f5f57244..acc18138fb2269de1f9fd7c29390f3c6b779b56c 100644 (file)
@@ -49,7 +49,9 @@ dump_backtrace(struct frame_head * head)
  * |    stack    |
  * --------------- saved regs->ebp value if valid (frame_head address)
  * .             .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * --------------- saved regs->rsp value if x86_64
+ * |             |
+ * --------------- struct pt_regs * stored on stack if 32-bit
  * |             |
  * .             .
  * |             |
@@ -57,13 +59,26 @@ dump_backtrace(struct frame_head * head)
  * |             |
  * |             | \/ Lower addresses
  *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) ebp values
+ * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
+ * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
+ * exceptions use special stacks, maintained by the interrupt stack table
+ * (IST). These stacks are set up in trap_init() in
+ * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
+ * to the kernel stack; instead, it points to some location on the NMI
+ * stack. On the other hand, regs->rsp is the stack pointer saved when the
+ * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
+ * processor does not save %esp on the kernel stack when interrupts occur
+ * in the kernel mode.
  */
 #ifdef CONFIG_FRAME_POINTER
 static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
 {
        unsigned long headaddr = (unsigned long)head;
+#ifdef CONFIG_X86_64
+       unsigned long stack = (unsigned long)regs->rsp;
+#else
        unsigned long stack = (unsigned long)regs;
+#endif
        unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
 
        return headaddr > stack && headaddr < stack_base;
index 199eeaf0f4e3829267b6de3ebf4efdedbaa4d68c..845cd0902a5008e91e696109154f53d0ecab8cd2 100644 (file)
@@ -194,7 +194,6 @@ config IA64_L1_CACHE_SHIFT
        default "7" if MCKINLEY
        default "6" if ITANIUM
 
-# align cache-sensitive data to 64 bytes
 config IA64_CYCLONE
        bool "Cyclone (EXA) Time Source support"
        help
@@ -374,6 +373,9 @@ config IA64_PALINFO
          To use this option, you have to ensure that the "/proc file system
          support" (CONFIG_PROC_FS) is enabled, too.
 
+config SGI_SN
+       def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
+
 source "drivers/firmware/Kconfig"
 
 source "fs/Kconfig.binfmt"
index d58003f1ad024835ed89002f85d535514e7e18b8..c9104bfff667cafcc5e15af27b9beae9813f20a3 100644 (file)
 #include <asm/machvec.h>
 #include <asm/system.h>
 
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-char drive_info[4*16];
-
 void __init
 dig_setup (char **cmdline_p)
 {
index c485a3b32ba8ba4a31ce380635441ab4e3ff1729..9990320b6f9a7ee7edad9c41f988a4681c7e2018 100644 (file)
@@ -410,24 +410,16 @@ efi_init (void)
        efi_config_table_t *config_tables;
        efi_char16_t *c16;
        u64 efi_desc_size;
-       char *cp, *end, vendor[100] = "unknown";
+       char *cp, vendor[100] = "unknown";
        extern char saved_command_line[];
        int i;
 
        /* it's too early to be able to use the standard kernel command line support... */
        for (cp = saved_command_line; *cp; ) {
                if (memcmp(cp, "mem=", 4) == 0) {
-                       cp += 4;
-                       mem_limit = memparse(cp, &end);
-                       if (end != cp)
-                               break;
-                       cp = end;
+                       mem_limit = memparse(cp + 4, &cp);
                } else if (memcmp(cp, "max_addr=", 9) == 0) {
-                       cp += 9;
-                       max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
-                       if (end != cp)
-                               break;
-                       cp = end;
+                       max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
                } else {
                        while (*cp != ' ' && *cp)
                                ++cp;
@@ -458,7 +450,7 @@ efi_init (void)
        /* Show what we know for posterity */
        c16 = __va(efi.systab->fw_vendor);
        if (c16) {
-               for (i = 0;i < (int) sizeof(vendor) && *c16; ++i)
+               for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i)
                        vendor[i] = *c16++;
                vendor[i] = '\0';
        }
index fbc7ea35dd5789fab0d15f0a2e7ac1e28b1b99c2..f1778a84ea61b95487ba5ee3f0fe01161cfe1c00 100644 (file)
@@ -352,6 +352,7 @@ start_ap:
        mov ar.rsc=0            // place RSE in enforced lazy mode
        ;;
        loadrs                  // clear the dirty partition
+       mov IA64_KR(PER_CPU_DATA)=r0    // clear physical per-CPU base
        ;;
        mov ar.bspstore=r2      // establish the new RSE stack
        ;;
index acc0f132f86cda4fd43af9e11942fe1bfb32cd19..056f7a6eedc793a9e5867f79918118f40d30f123 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
+#include <asm/delay.h>
 #include <asm/page.h>
 #include <asm/sal.h>
 #include <asm/pal.h>
@@ -214,6 +215,78 @@ chk_nointroute_opt(void)
 static void __init sal_desc_ap_wakeup(void *p) { }
 #endif
 
+/*
+ * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading
+ * cr.ivr, but it never writes cr.eoi.  This leaves any interrupt marked as
+ * "in-service" and masks other interrupts of equal or lower priority.
+ *
+ * HP internal defect reports: F1859, F2775, F3031.
+ */
+static int sal_cache_flush_drops_interrupts;
+
+static void __init
+check_sal_cache_flush (void)
+{
+       unsigned long flags, itv;
+       int cpu;
+       u64 vector;
+
+       cpu = get_cpu();
+       local_irq_save(flags);
+
+       /*
+        * Schedule a timer interrupt, wait until it's reported, and see if
+        * SAL_CACHE_FLUSH drops it.
+        */
+       itv = ia64_get_itv();
+       BUG_ON((itv & (1 << 16)) == 0);
+
+       ia64_set_itv(IA64_TIMER_VECTOR);
+       ia64_set_itm(ia64_get_itc() + 1000);
+
+       while (!ia64_get_irr(IA64_TIMER_VECTOR))
+               cpu_relax();
+
+       ia64_sal_cache_flush(3);
+
+       if (ia64_get_irr(IA64_TIMER_VECTOR)) {
+               vector = ia64_get_ivr();
+               ia64_eoi();
+               WARN_ON(vector != IA64_TIMER_VECTOR);
+       } else {
+               sal_cache_flush_drops_interrupts = 1;
+               printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; "
+                       "PAL_CACHE_FLUSH will be used instead\n");
+               ia64_eoi();
+       }
+
+       ia64_set_itv(itv);
+       local_irq_restore(flags);
+       put_cpu();
+}
+
+s64
+ia64_sal_cache_flush (u64 cache_type)
+{
+       struct ia64_sal_retval isrv;
+
+       if (sal_cache_flush_drops_interrupts) {
+               unsigned long flags;
+               u64 progress;
+               s64 rc;
+
+               progress = 0;
+               local_irq_save(flags);
+               rc = ia64_pal_cache_flush(cache_type,
+                       PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL);
+               local_irq_restore(flags);
+               return rc;
+       }
+
+       SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
+       return isrv.status;
+}
+
 void __init
 ia64_sal_init (struct ia64_sal_systab *systab)
 {
@@ -262,6 +335,8 @@ ia64_sal_init (struct ia64_sal_systab *systab)
                }
                p += SAL_DESC_SIZE(*p);
        }
+
+       check_sal_cache_flush();
 }
 
 int
index c0766575a3a2113a56792623dc16a64752263239..35f7835294a38bc10bff199ec3c6e8d78f4485b6 100644 (file)
@@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS];
 EXPORT_SYMBOL(__per_cpu_offset);
 #endif
 
+extern void ia64_setup_printk_clock(void);
+
 DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
 DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
 DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
@@ -445,6 +447,8 @@ setup_arch (char **cmdline_p)
        /* process SAL system table: */
        ia64_sal_init(efi.sal_systab);
 
+       ia64_setup_printk_clock();
+
 #ifdef CONFIG_SMP
        cpu_physical_id(0) = hard_smp_processor_id();
 
index 028a2b95936c1fa48ca316921c65b1023b9e1585..a094ec49ccfab6fe8822771f9335def7a51cacf8 100644 (file)
@@ -278,3 +278,30 @@ udelay (unsigned long usecs)
        }
 }
 EXPORT_SYMBOL(udelay);
+
+static unsigned long long ia64_itc_printk_clock(void)
+{
+       if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
+               return sched_clock();
+       return 0;
+}
+
+static unsigned long long ia64_default_printk_clock(void)
+{
+       return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
+               (1000000000/HZ);
+}
+
+unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
+
+unsigned long long printk_clock(void)
+{
+       return ia64_printk_clock();
+}
+
+void __init
+ia64_setup_printk_clock(void)
+{
+       if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
+               ia64_printk_clock = ia64_itc_printk_clock;
+}
index 706b7734e191efbc51112ae4adea0bbeb4d93e19..6e5eea19fa672bb0199f997e0888fc91d98ad77c 100644 (file)
@@ -71,31 +71,33 @@ static int __init topology_init(void)
        int i, err = 0;
 
 #ifdef CONFIG_NUMA
-       sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
+       sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
        if (!sysfs_nodes) {
                err = -ENOMEM;
                goto out;
        }
-       memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES);
 
-       /* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */
-       for_each_online_node(i)
+       /*
+        * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
+        */
+       for_each_online_node(i) {
                if ((err = register_node(&sysfs_nodes[i], i, 0)))
                        goto out;
+       }
 #endif
 
-       sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
+       sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
        if (!sysfs_cpus) {
                err = -ENOMEM;
                goto out;
        }
-       memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS);
 
-       for_each_present_cpu(i)
+       for_each_present_cpu(i) {
                if((err = arch_register_cpu(i)))
                        goto out;
+       }
 out:
        return err;
 }
 
-__initcall(topology_init);
+subsys_initcall(topology_init);
index a269f6d84c29d92e77e4edf44dcba9b29e2fe180..79a7df02e8120f0302151a579fa499b09cf3d785 100644 (file)
@@ -9,6 +9,4 @@
 # Makefile for the sn ia64 subplatform
 #
 
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
-
 obj-y += kernel/ pci/
index 4351c4ff984582470403bfe4333e8f693be5dde2..3e9b4eea74185a32d3ea235d040213936996848f 100644 (file)
@@ -7,6 +7,8 @@
 # Copyright (C) 1999,2001-2005 Silicon Graphics, Inc.  All Rights Reserved.
 #
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y                          += setup.o bte.o bte_error.o irq.o mca.o idle.o \
                                   huberror.o io_init.o iomv.o klconflib.o sn2/
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
index dd73c0cb754b4051214f113bf0bad237b684148a..1f11db470d90e97d76cc07c3f8321ad617a47783 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/config.h>
@@ -186,18 +186,13 @@ retry_bteop:
 
        /* Initialize the notification to a known value. */
        *bte->most_rcnt_na = BTE_WORD_BUSY;
-       notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na));
+       notif_phys_addr = (u64)bte->most_rcnt_na;
 
-       if (is_shub2()) {
-               src = SH2_TIO_PHYS_TO_DMA(src);
-               dest = SH2_TIO_PHYS_TO_DMA(dest);
-               notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
-       }
        /* Set the source and destination registers */
-       BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
-       BTE_SRC_STORE(bte, TO_PHYS(src));
-       BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest))));
-       BTE_DEST_STORE(bte, TO_PHYS(dest));
+       BTE_PRINTKV(("IBSA = 0x%lx)\n", src));
+       BTE_SRC_STORE(bte, src);
+       BTE_PRINTKV(("IBDA = 0x%lx)\n", dest));
+       BTE_DEST_STORE(bte, dest);
 
        /* Set the notification register */
        BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
index a4c78152b3366568edf0949935765a11a63a355f..d7e4d79e16a8d425747d45abed163a124c98b6da 100644 (file)
@@ -208,7 +208,7 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
  * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
  *     each node in the system.
  */
-static void sn_fixup_ionodes(void)
+static void __init sn_fixup_ionodes(void)
 {
        struct sn_flush_device_kernel *sn_flush_device_kernel;
        struct sn_flush_device_kernel *dev_entry;
@@ -467,6 +467,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
                pcidev_info->pdi_sn_irq_info = NULL;
                kfree(sn_irq_info);
        }
+
+       /*
+        * MSI currently not supported on altix.  Remove this when
+        * the MSI abstraction patches are integrated into the kernel
+        * (sometime after 2.6.16 releases)
+        */
+       dev->no_msi = 1;
 }
 
 /*
index ec37084bdc17486bcbe8d593166e7639df44be65..74d87d903d5d9928aa1bbaaaad282df6a2269062 100644 (file)
@@ -5,11 +5,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/irq.h>
 #include <linux/spinlock.h>
+#include <linux/init.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
@@ -76,17 +77,15 @@ static void sn_enable_irq(unsigned int irq)
 
 static void sn_ack_irq(unsigned int irq)
 {
-       u64 event_occurred, mask = 0;
+       u64 event_occurred, mask;
 
        irq = irq & 0xff;
-       event_occurred =
-           HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
+       event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
        mask = event_occurred & SH_ALL_INT_MASK;
-       HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
-             mask);
+       HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
        __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
 
-       move_irq(irq);
+       move_native_irq(irq);
 }
 
 static void sn_end_irq(unsigned int irq)
@@ -219,9 +218,8 @@ static void register_intr_pda(struct sn_irq_info *sn_irq_info)
                pdacpu(cpu)->sn_last_irq = irq;
        }
 
-       if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) {
+       if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq)
                pdacpu(cpu)->sn_first_irq = irq;
-       }
 }
 
 static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
@@ -289,7 +287,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
        list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
        spin_unlock(&sn_irq_info_lock);
 
-       (void)register_intr_pda(sn_irq_info);
+       register_intr_pda(sn_irq_info);
 }
 
 void sn_irq_unfixup(struct pci_dev *pci_dev)
@@ -419,7 +417,7 @@ void sn_lb_int_war_check(void)
        rcu_read_unlock();
 }
 
-void sn_irq_lh_init(void)
+void __init sn_irq_lh_init(void)
 {
        int i;
 
@@ -434,5 +432,4 @@ void sn_irq_lh_init(void)
 
                INIT_LIST_HEAD(sn_irq_lh[i]);
        }
-
 }
index 0f11a3299cd2724c31d60b2a053e2d86239c83e8..87682b48ef836f7c21bf667a232bc8b8fd544985 100644 (file)
@@ -78,31 +78,30 @@ format_module_id(char *buffer, moduleid_t m, int fmt)
        position = MODULE_GET_BPOS(m);
 
        if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
-           /* Brief module number format, eg. 002c15 */
+               /* Brief module number format, eg. 002c15 */
 
-           /* Decompress the rack number */
-           *buffer++ = '0' + RACK_GET_CLASS(rack);
-           *buffer++ = '0' + RACK_GET_GROUP(rack);
-           *buffer++ = '0' + RACK_GET_NUM(rack);
+               /* Decompress the rack number */
+               *buffer++ = '0' + RACK_GET_CLASS(rack);
+               *buffer++ = '0' + RACK_GET_GROUP(rack);
+               *buffer++ = '0' + RACK_GET_NUM(rack);
 
-           /* Add the brick type */
-           *buffer++ = brickchar;
+               /* Add the brick type */
+               *buffer++ = brickchar;
        }
        else if (fmt == MODULE_FORMAT_LONG) {
-           /* Fuller hwgraph format, eg. rack/002/bay/15 */
+               /* Fuller hwgraph format, eg. rack/002/bay/15 */
 
-           strcpy(buffer, "rack" "/");  buffer += strlen(buffer);
+               strcpy(buffer, "rack" "/");  buffer += strlen(buffer);
 
-           *buffer++ = '0' + RACK_GET_CLASS(rack);
-           *buffer++ = '0' + RACK_GET_GROUP(rack);
-           *buffer++ = '0' + RACK_GET_NUM(rack);
+               *buffer++ = '0' + RACK_GET_CLASS(rack);
+               *buffer++ = '0' + RACK_GET_GROUP(rack);
+               *buffer++ = '0' + RACK_GET_NUM(rack);
 
-           strcpy(buffer, "/" "bay" "/");  buffer += strlen(buffer);
+               strcpy(buffer, "/" "bay" "/");  buffer += strlen(buffer);
        }
 
        /* Add the bay position, using at least two digits */
        if (position < 10)
-           *buffer++ = '0';
+               *buffer++ = '0';
        sprintf(buffer, "%d", position);
-
 }
index 9ab684d1bb552ae963379a5b4afb91beed33d4da..3db62f24596ca6e76d9756d3c4e96ee9b630d443 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
@@ -137,7 +137,8 @@ int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdat
 
 static int __init sn_salinfo_init(void)
 {
-       salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
+       if (ia64_platform_is("sn2"))
+               salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
        return 0;
 }
 
index e510dce9971f53647863cb2a081702e91dabac07..48645ac120fc3d0b8b7855de1f0d965b5694a2d4 100644 (file)
@@ -67,6 +67,7 @@ extern unsigned long last_time_offset;
 extern void (*ia64_mark_idle) (int);
 extern void snidle(int);
 extern unsigned char acpi_kbd_controller_present;
+extern unsigned long long (*ia64_printk_clock)(void);
 
 unsigned long sn_rtc_cycles_per_second;
 EXPORT_SYMBOL(sn_rtc_cycles_per_second);
@@ -124,20 +125,6 @@ struct screen_info sn_screen_info = {
        .orig_video_points = 16
 };
 
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-#ifdef CONFIG_IA64_GENERIC
-extern char drive_info[4 * 16];
-#else
-char drive_info[4 * 16];
-#endif
-
 /*
  * This routine can only be used during init, since
  * smp_boot_data is an init data structure.
@@ -209,7 +196,7 @@ void __init early_sn_setup(void)
 }
 
 extern int platform_intr_list[];
-static int __initdata shub_1_1_found = 0;
+static int __initdata shub_1_1_found;
 
 /*
  * sn_check_for_wars
@@ -372,6 +359,16 @@ sn_scan_pcdp(void)
        }
 }
 
+static unsigned long sn2_rtc_initial;
+
+static unsigned long long ia64_sn2_printk_clock(void)
+{
+       unsigned long rtc_now = rtc_time();
+
+       return (rtc_now - sn2_rtc_initial) *
+               (1000000000 / sn_rtc_cycles_per_second);
+}
+
 /**
  * sn_setup - SN platform setup routine
  * @cmdline_p: kernel command line
@@ -386,6 +383,7 @@ void __init sn_setup(char **cmdline_p)
        u32 version = sn_sal_rev();
        extern void sn_cpu_init(void);
 
+       sn2_rtc_initial = rtc_time();
        ia64_sn_plat_set_error_handling_features();     // obsolete
        ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
        ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
@@ -437,19 +435,6 @@ void __init sn_setup(char **cmdline_p)
         */
        build_cnode_tables();
 
-       /*
-        * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
-        * support here so we don't have to listen to failed keyboard probe
-        * messages.
-        */
-       if (version <= 0x0209 && acpi_kbd_controller_present) {
-               printk(KERN_INFO "Disabling legacy keyboard support as prom "
-                      "is too old and doesn't provide FADT\n");
-               acpi_kbd_controller_present = 0;
-       }
-
-       printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
-
        status =
            ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
                               &drift);
@@ -463,6 +448,21 @@ void __init sn_setup(char **cmdline_p)
 
        platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
 
+       ia64_printk_clock = ia64_sn2_printk_clock;
+
+       /*
+        * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
+        * support here so we don't have to listen to failed keyboard probe
+        * messages.
+        */
+       if (version <= 0x0209 && acpi_kbd_controller_present) {
+               printk(KERN_INFO "Disabling legacy keyboard support as prom "
+                      "is too old and doesn't provide FADT\n");
+               acpi_kbd_controller_present = 0;
+       }
+
+       printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
+
        /*
         * we set the default root device to /dev/hda
         * to make simulation easy
@@ -578,13 +578,17 @@ void __init sn_cpu_init(void)
                        sn_prom_type = 2;
                else
                        sn_prom_type = 1;
-               printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+               printk(KERN_INFO "Running on medusa with %s PROM\n",
+                      (sn_prom_type == 1) ? "real" : "fake");
        }
 
        memset(pda, 0, sizeof(pda));
-       if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
-                               &sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
-                               &sn_coherency_id, &sn_region_size))
+       if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2,
+                               &sn_hub_info->nasid_bitmask,
+                               &sn_hub_info->nasid_shift,
+                               &sn_system_size, &sn_sharing_domain_size,
+                               &sn_partition_id, &sn_coherency_id,
+                               &sn_region_size))
                BUG();
        sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
 
@@ -716,7 +720,8 @@ void __init build_cnode_tables(void)
        for_each_online_node(node) {
                kl_config_hdr_t *klgraph_header;
                nasid = cnodeid_to_nasid(node);
-               if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
+               klgraph_header = ia64_sn_get_klconfig_addr(nasid);
+               if (klgraph_header == NULL)
                        BUG();
                brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
                while (brd) {
@@ -734,7 +739,7 @@ nasid_slice_to_cpuid(int nasid, int slice)
 {
        long cpu;
 
-       for (cpu=0; cpu < NR_CPUS; cpu++)
+       for (cpu = 0; cpu < NR_CPUS; cpu++)
                if (cpuid_to_nasid(cpu) == nasid &&
                                        cpuid_to_slice(cpu) == slice)
                        return cpu;
index 170bde4549da8f6191726c099fe7c88483377f31..99e1776932347937745c0fafbb3ed7ad9fdb5ace 100644 (file)
@@ -9,5 +9,7 @@
 # sn2 specific kernel files
 #
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
         prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
index 471bbaa65d1b66b2762d0882aab345764bf0cdc7..f153a4c35c70b206cbcbb450de72feb943d3be16 100644 (file)
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -46,104 +46,28 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats);
 
 static  __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
 
-void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0,
-       volatile unsigned long *, unsigned long data1);
+void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long,
+       volatile unsigned long *, unsigned long);
 
-#ifdef DEBUG_PTC
 /*
- * ptctest:
- *
- *     xyz - 3 digit hex number:
- *             x - Force PTC purges to use shub:
- *                     0 - no force
- *                     1 - force
- *             y - interupt enable
- *                     0 - disable interrupts
- *                     1 - leave interuupts enabled
- *             z - type of lock:
- *                     0 - global lock
- *                     1 - node local lock
- *                     2 - no lock
- *
- *     Note: on shub1, only ptctest == 0 is supported. Don't try other values!
+ * Note: some is the following is captured here to make degugging easier
+ * (the macros make more sense if you see the debug patch - not posted)
  */
-
-static unsigned int sn2_ptctest = 0;
-
-static int __init ptc_test(char *str)
-{
-       get_option(&str, &sn2_ptctest);
-       return 1;
-}
-__setup("ptctest=", ptc_test);
-
-static inline int ptc_lock(unsigned long *flagp)
-{
-       unsigned long opt = sn2_ptctest & 255;
-
-       switch (opt) {
-       case 0x00:
-               spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
-               break;
-       case 0x01:
-               spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp);
-               break;
-       case 0x02:
-               local_irq_save(*flagp);
-               break;
-       case 0x10:
-               spin_lock(&sn2_global_ptc_lock);
-               break;
-       case 0x11:
-               spin_lock(&sn_nodepda->ptc_lock);
-               break;
-       case 0x12:
-               break;
-       default:
-               BUG();
-       }
-       return opt;
-}
-
-static inline void ptc_unlock(unsigned long flags, int opt)
-{
-       switch (opt) {
-       case 0x00:
-               spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
-               break;
-       case 0x01:
-               spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags);
-               break;
-       case 0x02:
-               local_irq_restore(flags);
-               break;
-       case 0x10:
-               spin_unlock(&sn2_global_ptc_lock);
-               break;
-       case 0x11:
-               spin_unlock(&sn_nodepda->ptc_lock);
-               break;
-       case 0x12:
-               break;
-       default:
-               BUG();
-       }
-}
-#else
-
 #define sn2_ptctest    0
+#define local_node_uses_ptc_ga(sh1)    ((sh1) ? 1 : 0)
+#define max_active_pio(sh1)            ((sh1) ? 32 : 7)
+#define reset_max_active_on_deadlock() 1
+#define PTC_LOCK(sh1)                  ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
 
-static inline int ptc_lock(unsigned long *flagp)
+static inline void ptc_lock(int sh1, unsigned long *flagp)
 {
-       spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
-       return 0;
+       spin_lock_irqsave(PTC_LOCK(sh1), *flagp);
 }
 
-static inline void ptc_unlock(unsigned long flags, int opt)
+static inline void ptc_unlock(int sh1, unsigned long flags)
 {
-       spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+       spin_unlock_irqrestore(PTC_LOCK(sh1), flags);
 }
-#endif
 
 struct ptc_stats {
        unsigned long ptc_l;
@@ -151,27 +75,30 @@ struct ptc_stats {
        unsigned long shub_ptc_flushes;
        unsigned long nodes_flushed;
        unsigned long deadlocks;
+       unsigned long deadlocks2;
        unsigned long lock_itc_clocks;
        unsigned long shub_itc_clocks;
        unsigned long shub_itc_clocks_max;
+       unsigned long shub_ptc_flushes_not_my_mm;
 };
 
 static inline unsigned long wait_piowc(void)
 {
-       volatile unsigned long *piows, zeroval;
-       unsigned long ws;
+       volatile unsigned long *piows;
+       unsigned long zeroval, ws;
 
        piows = pda->pio_write_status_addr;
        zeroval = pda->pio_write_status_val;
        do {
                cpu_relax();
        } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
-       return ws;
+       return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
 }
 
 void sn_tlb_migrate_finish(struct mm_struct *mm)
 {
-       if (mm == current->mm)
+       /* flush_tlb_mm is inefficient if more than 1 users of mm */
+       if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1)
                flush_tlb_mm(mm);
 }
 
@@ -201,12 +128,14 @@ void
 sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
                     unsigned long end, unsigned long nbits)
 {
-       int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
-       int mymm = (mm == current->active_mm && current->mm);
+       int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
+       int mymm = (mm == current->active_mm && mm == current->mm);
+       int use_cpu_ptcga;
        volatile unsigned long *ptc0, *ptc1;
-       unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
+       unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0;
        short nasids[MAX_NUMNODES], nix;
        nodemask_t nodes_flushed;
+       int active, max_active, deadlock;
 
        nodes_clear(nodes_flushed);
        i = 0;
@@ -267,41 +196,56 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
        
 
        mynasid = get_nasid();
+       use_cpu_ptcga = local_node_uses_ptc_ga(shub1);
+       max_active = max_active_pio(shub1);
 
        itc = ia64_get_itc();
-       opt = ptc_lock(&flags);
+       ptc_lock(shub1, &flags);
        itc2 = ia64_get_itc();
+
        __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
        __get_cpu_var(ptcstats).shub_ptc_flushes++;
        __get_cpu_var(ptcstats).nodes_flushed += nix;
+       if (!mymm)
+                __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++;
 
+       if (use_cpu_ptcga && !mymm) {
+               old_rr = ia64_get_rr(start);
+               ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8));
+               ia64_srlz_d();
+       }
+
+       wait_piowc();
        do {
                if (shub1)
                        data1 = start | (1UL << SH1_PTC_1_START_SHFT);
                else
                        data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
-               for (i = 0; i < nix; i++) {
+               deadlock = 0;
+               active = 0;
+               for (ibegin = 0, i = 0; i < nix; i++) {
                        nasid = nasids[i];
-                       if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) {
+                       if (use_cpu_ptcga && unlikely(nasid == mynasid)) {
                                ia64_ptcga(start, nbits << 2);
                                ia64_srlz_i();
                        } else {
                                ptc0 = CHANGE_NASID(nasid, ptc0);
                                if (ptc1)
                                        ptc1 = CHANGE_NASID(nasid, ptc1);
-                               pio_atomic_phys_write_mmrs(ptc0, data0, ptc1,
-                                                          data1);
-                               flushed = 1;
+                               pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+                               active++;
+                       }
+                       if (active >= max_active || i == (nix - 1)) {
+                               if ((deadlock = wait_piowc())) {
+                                       sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1);
+                                       if (reset_max_active_on_deadlock())
+                                               max_active = 1;
+                               }
+                               active = 0;
+                               ibegin = i + 1;
                        }
                }
-               if (flushed
-                   && (wait_piowc() &
-                               (SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) {
-                       sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1);
-               }
-
                start += (1UL << nbits);
-
        } while (start < end);
 
        itc2 = ia64_get_itc() - itc2;
@@ -309,7 +253,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
        if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max)
                __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2;
 
-       ptc_unlock(flags, opt);
+       if (old_rr) {
+               ia64_set_rr(start, old_rr);
+               ia64_srlz_d();
+       }
+
+       ptc_unlock(shub1, flags);
 
        preempt_enable();
 }
@@ -321,27 +270,30 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
  * TLB flush transaction.  The recovery sequence is somewhat tricky & is
  * coded in assembly language.
  */
-void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
+void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
        volatile unsigned long *ptc1, unsigned long data1)
 {
-       extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
+       extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
                volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
        short nasid, i;
-       unsigned long *piows, zeroval;
+       unsigned long *piows, zeroval, n;
 
        __get_cpu_var(ptcstats).deadlocks++;
 
        piows = (unsigned long *) pda->pio_write_status_addr;
        zeroval = pda->pio_write_status_val;
 
-       for (i=0; i < nix; i++) {
+
+       for (i=ib; i <= ie; i++) {
                nasid = nasids[i];
-               if (!(sn2_ptctest & 3) && nasid == mynasid)
+               if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid)
                        continue;
                ptc0 = CHANGE_NASID(nasid, ptc0);
                if (ptc1)
                        ptc1 = CHANGE_NASID(nasid, ptc1);
-               sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+
+               n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+               __get_cpu_var(ptcstats).deadlocks2 += n;
        }
 
 }
@@ -452,20 +404,22 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data)
        cpu = *(loff_t *) data;
 
        if (!cpu) {
-               seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n");
+               seq_printf(file,
+                          "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n");
                seq_printf(file, "# ptctest %d\n", sn2_ptctest);
        }
 
        if (cpu < NR_CPUS && cpu_online(cpu)) {
                stat = &per_cpu(ptcstats, cpu);
-               seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
+               seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
                                stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
                                stat->deadlocks,
                                1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
                                1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
-                               1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec);
+                               1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec,
+                               stat->shub_ptc_flushes_not_my_mm,
+                               stat->deadlocks2);
        }
-
        return 0;
 }
 
@@ -476,7 +430,7 @@ static struct seq_operations sn2_ptc_seq_ops = {
        .show = sn2_ptc_seq_show
 };
 
-int sn2_ptc_proc_open(struct inode *inode, struct file *file)
+static int sn2_ptc_proc_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &sn2_ptc_seq_ops);
 }
index 19b54fbcd7eaf790c7136571b81f79e2ae1dc1a0..70db21f3df215afb95140b8fbbef00e06eabf4c6 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
  *
  * SGI Altix topology and hardware performance monitoring API.
  * Mark Goodwin <markgw@sgi.com>. 
@@ -973,6 +973,9 @@ static int __devinit sn_hwperf_misc_register_init(void)
 {
        int e;
 
+       if (!ia64_platform_is("sn2"))
+               return 0;
+
        sn_hwperf_init();
 
        /*
index c75f8aeefc2b432e5a2a2d2f6d01ade7089aff3a..9cd460dfe27ef71b0e0a1517114b54812b490c54 100644 (file)
@@ -575,18 +575,21 @@ xpc_activate_partition(struct xpc_partition *part)
 
        spin_lock_irqsave(&part->act_lock, irq_flags);
 
-       pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
-
        DBUG_ON(part->act_state != XPC_P_INACTIVE);
 
-       if (pid > 0) {
-               part->act_state = XPC_P_ACTIVATION_REQ;
-               XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
-       } else {
-               XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
-       }
+       part->act_state = XPC_P_ACTIVATION_REQ;
+       XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
 
        spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+       pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
+
+       if (unlikely(pid <= 0)) {
+               spin_lock_irqsave(&part->act_lock, irq_flags);
+               part->act_state = XPC_P_INACTIVE;
+               XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+               spin_unlock_irqrestore(&part->act_lock, irq_flags);
+       }
 }
 
 
index 321576b1b425f8916858c875058326148216fa8f..c6946784a6a81aaae694ea84513c3ff6770d2aad 100644 (file)
@@ -7,4 +7,6 @@
 #
 # Makefile for the sn pci general routines.
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
index 1850c4a94c414d578e34df6bb4ad595b84b7e237..3b403ea456f9264292da6961d3213dc0f51d0659 100644 (file)
@@ -7,5 +7,7 @@
 #
 # Makefile for the sn2 io routines.
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y                          +=  pcibr_dma.o pcibr_reg.o \
                                    pcibr_ate.o pcibr_provider.o
index dbc8a392105fba65faa118e5c4670b8a806c6b1a..be8b711367ec5d7bde44d77cbd9beb189c11d9e2 100644 (file)
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 EXPORT_SYMBOL(dump_fpu);
index c2e4dccf01121fff0895cc590166e63e682741ad..d742037a7ccb86d19cd390f455c7dcd5f6d66c80 100644 (file)
 extern void init_mmu(void);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)  \
-       || defined(CONFIG_BLK_DEV_IDE_MODULE)                   \
-       || defined(CONFIG_BLK_DEV_HD_MODULE)
-struct drive_info_struct { char dummy[32]; } drive_info;
-#endif
-
 extern char _end[];
 
 /*
index 99bf43824795e0004b2850413ac3c84450f21362..63c117dae0c32ba2a4e3c0f3a9879f344c0ad091 100644 (file)
 
 asmlinkage void ret_from_fork(void);
 
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 /*
  * The idle loop on an m68knommu..
index c3e852e9953e12824cc0d401bc9a2796fd44894e..767de847b4abd3ac15c703e929a3e68ee4d34007 100644 (file)
@@ -595,6 +595,7 @@ config SGI_IP32
        select SYS_HAS_CPU_R5000
        select SYS_HAS_CPU_R10000 if BROKEN
        select SYS_HAS_CPU_RM7000
+       select SYS_HAS_CPU_NEVADA
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        help
index 2a9f2ef27b294aebe1d781921fc805d7fcfc9d76..6a57407df1bcd1627c86e22de5f3228ad488c9d9 100644 (file)
@@ -53,14 +53,17 @@ CROSS_COMPILE               := $(tool-prefix)
 endif
 
 CHECKFLAGS-y                           += -D__linux__ -D__mips__ \
+                                          -D_MIPS_SZINT=32 \
                                           -D_ABIO32=1 \
                                           -D_ABIN32=2 \
                                           -D_ABI64=3
 CHECKFLAGS-$(CONFIG_32BIT)             += -D_MIPS_SIM=_ABIO32 \
                                           -D_MIPS_SZLONG=32 \
+                                          -D_MIPS_SZPTR=32 \
                                           -D__PTRDIFF_TYPE__=int
 CHECKFLAGS-$(CONFIG_64BIT)             += -m64 -D_MIPS_SIM=_ABI64 \
                                           -D_MIPS_SZLONG=64 \
+                                          -D_MIPS_SZPTR=64 \
                                           -D__PTRDIFF_TYPE__="long int"
 CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN)    += -D__MIPSEB__
 CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__
@@ -166,79 +169,97 @@ echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_i
 #
 cflags-$(CONFIG_CPU_R3000)     += \
                        $(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
+CHECKFLAGS-$(CONFIG_CPU_R3000) += -D_MIPS_ISA=_MIPS_ISA_MIPS1
 
 cflags-$(CONFIG_CPU_TX39XX)    += \
                        $(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
+CHECKFLAGS-$(CONFIG_CPU_TX39XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS1
 
 cflags-$(CONFIG_CPU_R6000)     += \
                        $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R6000) += -D_MIPS_ISA=_MIPS_ISA_MIPS2
 
 cflags-$(CONFIG_CPU_R4300)     += \
                        $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R4300) += -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_VR41XX)    += \
                        $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_VR41XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_R4X00)     += \
                        $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R4X00) += -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_TX49XX)    += \
                        $(call set_gccflags,r4600,mips3,r4600,mips3,mips2)  \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_TX49XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_MIPS32_R1) += \
                        $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS32_R1)     += -D_MIPS_ISA=_MIPS_ISA_MIPS32
 
 cflags-$(CONFIG_CPU_MIPS32_R2) += \
                        $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS32_R2)     += -D_MIPS_ISA=_MIPS_ISA_MIPS32
 
 cflags-$(CONFIG_CPU_MIPS64_R1) += \
                        $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS64_R1)     += -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_MIPS64_R2) += \
                        $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS64_R2)     += -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_R5000)     += \
                        $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R5000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_R5432)     += \
                        $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R5432) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_NEVADA)    += \
                        $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
                        -Wa,--trap
-#                      $(call cc-option,-mmad)
+CHECKFLAGS-$(CONFIG_CPU_NEVADA)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_RM7000)    += \
                        $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_RM7000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_RM9000)    += \
                        $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_RM9000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 
 cflags-$(CONFIG_CPU_SB1)       += \
                        $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_SB1)   += -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_R8000)     += \
                        $(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R8000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_R10000)    += \
                        $(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \
                        -Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R10000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 ifdef CONFIG_CPU_SB1
 ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -369,7 +390,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
 # Cobalt Server
 #
 core-$(CONFIG_MIPS_COBALT)     += arch/mips/cobalt/
-cflags-$(CONFIG_MIPS_COBALT)   += -Iinclude/asm-mips/cobalt
+cflags-$(CONFIG_MIPS_COBALT)   += -Iinclude/asm-mips/mach-cobalt
 load-$(CONFIG_MIPS_COBALT)     += 0xffffffff80080000
 
 #
index 65b84db800e4d63ff65d94ebc38df9a47e000fd1..4ffccedf5967dcf4326e2074e339976ddda8ee8c 100644 (file)
@@ -151,7 +151,7 @@ void au1000_restart(char *command)
        }
 
        set_c0_status(ST0_BEV | ST0_ERL);
-       set_c0_config(CONF_CM_UNCACHED);
+       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
        flush_cache_all();
        write_c0_wired(0);
 
index 08c8c855cc9cbf5fc3ceb0ba34bd378eadc2e306..eb155c071aa61c372f5455a0525f2f347cf18832 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -125,7 +126,7 @@ void __init plat_setup(void)
 #endif
        _machine_restart = au1000_restart;
        _machine_halt = au1000_halt;
-       _machine_power_off = au1000_power_off;
+       pm_power_off = au1000_power_off;
        board_time_init = au1xxx_time_init;
        board_timer_setup = au1xxx_timer_setup;
 
index f92608e8d84fe858ad8f110da15bb6056a169c66..e75d5e3ca86807c81a805cbdad5d61a7d34a4dbe 100644 (file)
@@ -8,7 +8,7 @@
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 
index 0d90851f925ea6fecadbb6d0f968c64846b1472f..f9a108820d6e2d1245eb64ac942df5418fba03e0 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/gt64120.h>
 #include <asm/ptrace.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern void cobalt_handle_int(void);
 
index 805a0e88507b5b0b8b4cec03f5f389edb13c68f5..753dfccae6fa090df4dfb5a6a1abcb53552c7050 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/mipsregs.h>
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 void cobalt_machine_halt(void)
 {
index d358a118fa318190790babe629cdd1ed3509cbd1..b9713a7230536aeaf098d82538c092f34d26ae8c 100644 (file)
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
  *
  */
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/pm.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 
@@ -25,7 +26,7 @@
 #include <asm/gt64120.h>
 #include <asm/serial.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
@@ -99,7 +100,7 @@ void __init plat_setup(void)
 
        _machine_restart = cobalt_machine_restart;
        _machine_halt = cobalt_machine_halt;
-       _machine_power_off = cobalt_machine_power_off;
+       pm_power_off = cobalt_machine_power_off;
 
        board_timer_setup = cobalt_timer_setup;
 
@@ -139,7 +140,7 @@ void __init plat_setup(void)
                uart.type       = PORT_UNKNOWN;
                uart.uartclk    = 18432000;
                uart.irq        = COBALT_SERIAL_IRQ;
-               uart.flags      = STD_COM_FLAGS;
+               uart.flags      = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
                uart.iobase     = 0xc800000;
                uart.iotype     = UPIO_PORT;
 
index 967e7acd8e1f5e4efbf79b5ad3cd334ff3c980a5..a34db6e82b27c07cd123bba3a86b11882f281f18 100644 (file)
@@ -102,6 +102,7 @@ CONFIG_CPU_R5000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
 CONFIG_SYS_HAS_CPU_RM7000=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
index dee44606164c85e86b67a1892ba842b9563a3981..c02becab850bce471bf1f7a241589e45c26ea633 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:00 2005
+# Linux kernel version: 2.6.16-rc2
+# Fri Feb  3 17:14:27 2006
 #
 CONFIG_MIPS=y
 
@@ -147,26 +147,27 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL is not set
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SHMEM is not set
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -266,11 +267,7 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -323,7 +320,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=y
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -366,24 +363,16 @@ CONFIG_NETDEVICES=y
 #
 # PHY device support
 #
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
+# CONFIG_MII is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
@@ -479,6 +468,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -517,6 +507,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -591,12 +587,15 @@ CONFIG_DUMMY_CONSOLE=y
 # SN Devices
 #
 
+#
+# EDAC - error detection and reporting (RAS)
+#
+
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -677,6 +676,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -690,31 +690,7 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
 #
 # Cryptographic options
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Hardware crypto devices
@@ -724,8 +700,6 @@ CONFIG_CRYPTO_CRC32C=y
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
+# CONFIG_LIBCRC32C is not set
index 11535be265b9db8b33e0403521ac384cb7601094..91456b068c2ef34cfe9a70d774745f53152846bf 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/ide.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
@@ -95,7 +96,7 @@ void __init plat_setup(void)
 
        _machine_restart = ddb_machine_restart;
        _machine_halt = ddb_machine_halt;
-       _machine_power_off = ddb_machine_power_off;
+       pm_power_off = ddb_machine_power_off;
 
        ddb_out32(DDB_BAR0, 0);
 
index f4e480a74edfc33c2f44b70e222fb9f028fa1db5..c902adef5942c21d7488f7ee75ab760bc9bc90a8 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
@@ -133,7 +134,7 @@ void __init plat_setup(void)
 
        _machine_restart = ddb_machine_restart;
        _machine_halt = ddb_machine_halt;
-       _machine_power_off = ddb_machine_power_off;
+       pm_power_off = ddb_machine_power_off;
 
        /* request io port/mem resources  */
        if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
index 81163353c4a839b18252ea16e8d26981e14a6603..2f566034cc44a3b112ac9a9381feb52296531c97 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/major.h>
 #include <linux/kdev_t.h>
 #include <linux/root_dev.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -182,7 +183,7 @@ void __init plat_setup(void)
 
        _machine_restart = ddb_machine_restart;
        _machine_halt = ddb_machine_halt;
-       _machine_power_off = ddb_machine_power_off;
+       pm_power_off = ddb_machine_power_off;
 
        /* setup resource limits */
        ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
index 9ef54fe1feaaef707df1355bd7c253505538ffae..7c1ca8f6330e0e33a69f6de58758effbe017be69 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/pm.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -158,7 +159,7 @@ void __init plat_setup(void)
 
        _machine_restart = dec_machine_restart;
        _machine_halt = dec_machine_halt;
-       _machine_power_off = dec_machine_power_off;
+       pm_power_off = dec_machine_power_off;
 
        ioport_resource.start = ~0UL;
        ioport_resource.end = 0UL;
index 98b5a96cc0391378d17601181d02e623b39b6cf1..6d859d1e7a2d0308ff45cab6a48b4f2ed7eee9d0 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/timex.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/page.h>
 #include <asm/io.h>
@@ -73,7 +75,7 @@ void __init plat_setup(void)
 {
        _machine_restart = galileo_machine_restart;
        _machine_halt = galileo_machine_halt;
-       _machine_power_off = galileo_machine_power_off;
+       pm_power_off = galileo_machine_power_off;
 
        board_time_init = gt64120_time_init;
        set_io_port_base(KSEG1);
index 0d07c33112d01a922430d16b9f6b55f19174f9de..20b65d3d2151579149daca9a978429a7d3374a1e 100644 (file)
@@ -4,7 +4,7 @@
  * BRIEF MODULE DESCRIPTION
  * Momentum Computer Ocelot (CP7000) - board dependent boot routines
  *
- * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 1996, 1997, 2001, 06  Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2000 RidgeRun, Inc.
  * Copyright (C) 2001 Red Hat, Inc.
  * Copyright (C) 2002 Momentum Computer
@@ -47,6 +47,8 @@
 #include <linux/pci.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+#include <linux/pm.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -159,7 +161,7 @@ void __init plat_setup(void)
 
        _machine_restart = momenco_ocelot_restart;
        _machine_halt = momenco_ocelot_halt;
-       _machine_power_off = momenco_ocelot_power_off;
+       pm_power_off = momenco_ocelot_power_off;
 
        /*
         * initrd_start = (ulong)ocelot_initrd_start;
index 062429dd7ca0a96b5a7ddc990722a3509eb511bf..fc73c8d69df7cd2a3a18f8c191662695ce17deac 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/major.h>
 #include <linux/kdev_t.h>
 #include <linux/root_dev.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/time.h>
@@ -125,7 +126,7 @@ void __init plat_setup(void)
 
        _machine_restart = it8172_restart;
        _machine_halt = it8172_halt;
-       _machine_power_off = it8172_power_off;
+       pm_power_off = it8172_power_off;
 
        /*
         * IO/MEM resources.
index 044df9d4ab7cc8e4282a54f6e467cfe3fdc7d69f..4036dc4345515fd1c251d96c0a63012ad10b8898 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/ide.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
@@ -79,7 +81,7 @@ void __init plat_setup(void)
 
        _machine_restart = jazz_machine_restart;
        _machine_halt = jazz_machine_halt;
-       _machine_power_off = jazz_machine_power_off;
+       pm_power_off = jazz_machine_power_off;
 
 #warning "Somebody should check if screen_info is ok for Jazz."
 
index 4763957df8fc8d5a23e2e98bd89eecc6343f8d1d..9359cc4134946cb6c5fb99b1bd33c6343f47d3f4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/ioport.h>
 #include <linux/param.h>       /* for HZ */
 #include <linux/delay.h>
+#include <linux/pm.h>
 #ifdef CONFIG_SERIAL_TXX9
 #include <linux/tty.h>
 #include <linux/serial.h>
@@ -211,7 +212,7 @@ void __init plat_setup(void)
 
        _machine_restart = jmr3927_machine_restart;
        _machine_halt = jmr3927_machine_halt;
-       _machine_power_off = jmr3927_machine_power_off;
+       pm_power_off = jmr3927_machine_power_off;
 
        /*
         * IO/MEM resources.
index fac48ad27b3425b21494313820d1a156d4f1bfe4..292f8b243a5e6a83539d8d6b82ab3f9349e4e089 100644 (file)
@@ -2,8 +2,8 @@
  * Processor capabilities determination functions.
  *
  * Copyright (C) xxxx  the Anonymous
+ * Copyright (C) 1994 - 2006 Ralf Baechle
  * Copyright (C) 2003, 2004  Maciej W. Rozycki
- * Copyright (C) 1994 - 2003 Ralf Baechle
  * Copyright (C) 2001, 2004  MIPS Inc.
  *
  * This program is free software; you can redistribute it and/or
@@ -641,10 +641,9 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
        switch (c->processor_id & 0xff00) {
        case PRID_IMP_SB1:
                c->cputype = CPU_SB1;
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
                /* FPU in pass1 is known to have issues. */
-               c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
-#endif
+               if ((c->processor_id & 0xff) < 0x20)
+                       c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
                break;
        case PRID_IMP_SB1A:
                c->cputype = CPU_SB1A;
index aa18a8b7b38086e091956422a7deb0f935c6de29..13f22d1d0e8b7fe119ca0294e257567bf693359a 100644 (file)
@@ -233,11 +233,11 @@ NESTED(except_vec_nmi, 0, sp)
 NESTED(nmi_handler, PT_SIZE, sp)
        .set    push
        .set    noat
-       .set    mips3
        SAVE_ALL
        move    a0, sp
        jal     nmi_exception_handler
        RESTORE_ALL
+       .set    mips3
        eret
        .set    pop
        END(nmi_handler)
index fa98f10d0132262da989f9110a46c2b9ddbb6bd5..5232fc752935385a7346c7d9702eebd425106c85 100644 (file)
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2004 Thiemo Seufer
  */
@@ -58,8 +59,8 @@ ATTRIB_NORET void cpu_idle(void)
        }
 }
 
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern void do_signal(struct pt_regs *regs);
+extern void do_signal32(struct pt_regs *regs);
 
 /*
  * Native o32 and N64 ABI without DSP ASE
index 0c82b25d8c6d17c087f5c3ec0c704052dbd22bd3..0d5cf97af727e3c39fd6c3e3fa965979c2a517bf 100644 (file)
@@ -88,7 +88,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                ret = -EIO;
                if (copied != sizeof(tmp))
                        break;
-               ret = put_user(tmp, (unsigned int *) (unsigned long) data);
+               ret = put_user(tmp, (unsigned int __user *) (unsigned long) data);
                break;
        }
 
@@ -174,8 +174,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                case FPC_EIR: { /* implementation / version register */
                        unsigned int flags;
 
-                       if (!cpu_has_fpu)
+                       if (!cpu_has_fpu) {
+                               tmp = 0;
                                break;
+                       }
 
                        preempt_disable();
                        if (cpu_has_mipsmt) {
@@ -194,15 +196,18 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        preempt_enable();
                        break;
                }
-               case DSP_BASE ... DSP_BASE + 5:
+               case DSP_BASE ... DSP_BASE + 5: {
+                       dspreg_t *dregs;
+
                        if (!cpu_has_dsp) {
                                tmp = 0;
                                ret = -EIO;
                                goto out_tsk;
                        }
-                       dspreg_t *dregs = __get_dsp_regs(child);
+                       dregs = __get_dsp_regs(child);
                        tmp = (unsigned long) (dregs[addr - DSP_BASE]);
                        break;
+               }
                case DSP_CONTROL:
                        if (!cpu_has_dsp) {
                                tmp = 0;
@@ -216,7 +221,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        ret = -EIO;
                        goto out_tsk;
                }
-               ret = put_user(tmp, (unsigned *) (unsigned long) data);
+               ret = put_user(tmp, (unsigned __user *) (unsigned long) data);
                break;
        }
 
@@ -304,15 +309,18 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        else
                                child->thread.fpu.soft.fcr31 = data;
                        break;
-               case DSP_BASE ... DSP_BASE + 5:
+               case DSP_BASE ... DSP_BASE + 5: {
+                       dspreg_t *dregs;
+
                        if (!cpu_has_dsp) {
                                ret = -EIO;
                                break;
                        }
 
-                       dspreg_t *dregs = __get_dsp_regs(child);
+                       dregs = __get_dsp_regs(child);
                        dregs[addr - DSP_BASE] = data;
                        break;
+               }
                case DSP_CONTROL:
                        if (!cpu_has_dsp) {
                                ret = -EIO;
index 5e37df3111ad4b33a98d33a235a5669940b9d346..621037db22904ed85f15ee0204007e6bade30e0d 100644 (file)
@@ -3,17 +3,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 by Ralf Baechle
+ * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 #include <linux/types.h>
 #include <linux/reboot.h>
-#include <asm/reboot.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
+#include <asm/reboot.h>
 
 /*
  * Urgs ...  Too many MIPS machines to handle this in a generic way.
@@ -22,23 +21,22 @@ EXPORT_SYMBOL(pm_power_off);
  */
 void (*_machine_restart)(char *command);
 void (*_machine_halt)(void);
-void (*_machine_power_off)(void);
+void (*pm_power_off)(void);
 
 void machine_restart(char *command)
 {
-       _machine_restart(command);
+       if (_machine_restart)
+               _machine_restart(command);
 }
 
 void machine_halt(void)
 {
-       _machine_halt();
+       if (_machine_halt)
+               _machine_halt();
 }
 
 void machine_power_off(void)
 {
        if (pm_power_off)
                pm_power_off();
-
-       _machine_power_off();
 }
-
index 1d855112bac254bac6328f243f22591e537a57ab..986a9cf230673010e6f9ae678798d74de0a51474 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+
 #include <asm/mipsmtregs.h>
 #include <asm/bitops.h>
 #include <asm/cpu.h>
index a42e0e8caa7b229292954bd2e1a33fb1865ce307..d7c4a38ed5aee4f226aaf10513414086dc250687 100644 (file)
@@ -617,6 +617,23 @@ einval:    li      v0, -EINVAL
        sys     sys_inotify_init        0
        sys     sys_inotify_add_watch   3       /* 4285 */
        sys     sys_inotify_rm_watch    2
+       sys     sys_migrate_pages       4
+       sys     sys_openat              4
+       sys     sys_mkdirat             3
+       sys     sys_mknodat             4       /* 4290 */
+       sys     sys_fchownat            5
+       sys     sys_futimesat           3
+       sys     sys_newfstatat          4
+       sys     sys_unlinkat            3
+       sys     sys_renameat            4       /* 4295 */
+       sys     sys_linkat              4
+       sys     sys_symlinkat           3
+       sys     sys_readlinkat          4
+       sys     sys_fchmodat            3
+       sys     sys_faccessat           3       /* 4300 */
+       sys     sys_pselect6            6
+       sys     sys_ppoll               5
+       sys     sys_unshare             1
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index 47bfbd416709cadb1e4fa96a0b32c20b026e80be..98bf25df56f39f28d0b55c9192bf33b6761a952e 100644 (file)
@@ -443,3 +443,20 @@ sys_call_table:
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch
        PTR     sys_inotify_rm_watch            /* 5245 */
+       PTR     sys_migrate_pages
+       PTR     sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat
+       PTR     sys_fchownat                    /* 5250 */
+       PTR     sys_futimesat
+       PTR     sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat
+       PTR     sys_linkat                      /* 5255 */
+       PTR     sys_symlinkat
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat
+       PTR     sys_pselect6                    /* 5260 */
+       PTR     sys_ppoll
+       PTR     sys_unshare
index b465ced1758f7a49f35cd085b2289162a7fa3037..bc4980cefc8bc5bd7631b6fd6b8c19fc9cc11f36 100644 (file)
@@ -369,3 +369,20 @@ EXPORT(sysn32_call_table)
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch
        PTR     sys_inotify_rm_watch
+       PTR     sys_migrate_pages               /* 6250 */
+       PTR     sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat
+       PTR     sys_fchownat
+       PTR     sys_futimesat                   /* 6255 */
+       PTR     sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat
+       PTR     sys_linkat
+       PTR     sys_symlinkat                   /* 6260 */
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat
+       PTR     sys_pselect6
+       PTR     sys_ppoll                       /* 6265 */
+       PTR     sys_unshare
index 3d338ca7eeeb1ca82529f03268cb0f6bf54999ce..5b0414018c9a14802fee22fe8ed2994835912a4b 100644 (file)
@@ -491,4 +491,21 @@ sys_call_table:
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch           /* 4285 */
        PTR     sys_inotify_rm_watch
+       PTR     sys_migrate_pages
+       PTR     compat_sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat                     /* 4290 */
+       PTR     sys_fchownat
+       PTR     compat_sys_futimesat
+       PTR     compat_sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat                    /* 4295 */
+       PTR     sys_linkat
+       PTR     sys_symlinkat
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat                   /* 4300 */
+       PTR     sys_pselect6
+       PTR     sys_ppoll
+       PTR     sys_unshare
        .size   sys_call_table,.-sys_call_table
index 0f66ae5838b99d27fd842416027812dfc4202c2b..0fbc492d24b4a50f97bf2249e2e0905f171ab4e3 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/config.h>
 
 static inline int
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
        int err = 0;
 
@@ -82,7 +82,7 @@ out:
 }
 
 static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
        unsigned int used_math;
        unsigned long treg;
@@ -157,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 /*
  * Determine which stack to use..
  */
-static inline void *
+static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 {
        unsigned long sp;
@@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
        if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
                sp = current->sas_ss_sp + current->sas_ss_size;
 
-       return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
+       return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
 }
 
 static inline int install_sigtramp(unsigned int __user *tramp,
index 7d1800fe70382dbb37650bf00b65c4cf5a86c1fe..c974cc9b30eb73bae60e0329df1ff425887c4b05 100644 (file)
@@ -39,8 +39,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -50,7 +48,7 @@ save_static_function(sys_sigsuspend);
 __attribute_used__ noinline static int
 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       sigset_t saveset, newset;
+       sigset_t newset;
        sigset_t __user *uset;
 
        uset = (sigset_t __user *) regs.regs[4];
@@ -59,19 +57,15 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
        spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
+       current->saved_sigmask = current->blocked;
        current->blocked = newset;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       regs.regs[2] = EINTR;
-       regs.regs[7] = 1;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, &regs))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 #endif
 
@@ -79,7 +73,7 @@ save_static_function(sys_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       sigset_t saveset, newset;
+       sigset_t newset;
        sigset_t __user *unewset;
        size_t sigsetsize;
 
@@ -94,19 +88,15 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
        spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
+       current->saved_sigmask = current->blocked;
        current->blocked = newset;
         recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       regs.regs[2] = EINTR;
-       regs.regs[7] = 1;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, &regs))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
@@ -199,10 +189,10 @@ save_static_function(sys_sigreturn);
 __attribute_used__ noinline static void
 _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct sigframe *frame;
+       struct sigframe __user *frame;
        sigset_t blocked;
 
-       frame = (struct sigframe *) regs.regs[29];
+       frame = (struct sigframe __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
        if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
@@ -236,11 +226,11 @@ save_static_function(sys_rt_sigreturn);
 __attribute_used__ noinline static void
 _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct rt_sigframe *frame;
+       struct rt_sigframe __user *frame;
        sigset_t set;
        stack_t st;
 
-       frame = (struct rt_sigframe *) regs.regs[29];
+       frame = (struct rt_sigframe __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
        if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -259,7 +249,7 @@ _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs.regs[29]);
+       do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 
        /*
         * Don't let your children do this ...
@@ -279,7 +269,7 @@ badframe:
 int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        int signr, sigset_t *set)
 {
-       struct sigframe *frame;
+       struct sigframe __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -315,18 +305,18 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->regs[31]);
 #endif
-        return 1;
+        return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 #endif
 
 int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        int signr, sigset_t *set, siginfo_t *info)
 {
-       struct rt_sigframe *frame;
+       struct rt_sigframe __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -340,7 +330,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
-       err |= __put_user(0, &frame->rs_uc.uc_link);
+       err |= __put_user(NULL, &frame->rs_uc.uc_link);
        err |= __put_user((void *)current->sas_ss_sp,
                          &frame->rs_uc.uc_stack.ss_sp);
        err |= __put_user(sas_ss_flags(regs->regs[29]),
@@ -375,11 +365,11 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
@@ -393,7 +383,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
                regs->regs[2] = EINTR;
                break;
        case ERESTARTSYS:
-               if(!(ka->sa.sa_flags & SA_RESTART)) {
+               if (!(ka->sa.sa_flags & SA_RESTART)) {
                        regs->regs[2] = EINTR;
                        break;
                }
@@ -420,9 +410,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
        return ret;
 }
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+void do_signal(struct pt_regs *regs)
 {
        struct k_sigaction ka;
+       sigset_t *oldset;
        siginfo_t info;
        int signr;
 
@@ -432,17 +423,31 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
         * if so.
         */
        if (!user_mode(regs))
-               return 1;
+               return;
 
        if (try_to_freeze())
                goto no_signal;
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
 
+
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0)
-               return handle_signal(signr, &info, &ka, oldset, regs);
+       if (signr > 0) {
+               /* Whee!  Actually deliver the signal.  */
+               if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+                       /*
+                        * A signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TIF_RESTORE_SIGMASK flag.
+                        */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               }
+       }
 
 no_signal:
        /*
@@ -463,18 +468,25 @@ no_signal:
                        regs->cp0_epc -= 4;
                }
        }
-       return 0;
+
+       /*
+        * If there's no signal to deliver, we just put the saved sigmask
+        * back
+        */
+       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+       }
 }
 
 /*
  * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
+ * - triggered by the TIF_WORK_MASK flags
  */
-asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
+asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
        __u32 thread_info_flags)
 {
        /* deal with pending signal delivery */
-       if (thread_info_flags & _TIF_SIGPENDING) {
-               current->thread.abi->do_signal(oldset, regs);
-       }
+       if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+               current->thread.abi->do_signal(regs);
 }
index 98b185bbc947c0576851787a78836927f5b9d65e..da3271e1fdac096e9cab303cddd6ece3d9f50f5f 100644 (file)
@@ -144,7 +144,7 @@ struct ucontext32 {
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
-static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
+static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
 {
        int err = 0;
 
@@ -269,7 +269,7 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
                        return -EFAULT;
                err |= __get_user(handler, &act->sa_handler);
-               new_ka.sa.sa_handler = (void*)(s64)handler;
+               new_ka.sa.sa_handler = (void __user *)(s64)handler;
                err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
                err |= __get_user(mask, &act->sa_mask.sig[0]);
                if (err)
@@ -299,8 +299,8 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
 
 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
 {
-       const stack32_t *uss = (const stack32_t *) regs.regs[4];
-       stack32_t *uoss = (stack32_t *) regs.regs[5];
+       const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
+       stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
        unsigned long usp = regs.regs[29];
        stack_t kss, koss;
        int ret, err = 0;
@@ -319,7 +319,8 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
        }
 
        set_fs (KERNEL_DS);
-       ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
+       ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
+                            uoss ? (stack_t __user *)&koss : NULL, usp);
        set_fs (old_fs);
 
        if (!ret && uoss) {
@@ -335,7 +336,7 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
        return ret;
 }
 
-static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
+static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc)
 {
        u32 used_math;
        int err = 0;
@@ -420,7 +421,7 @@ struct rt_sigframe32 {
 #endif
 };
 
-int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
        int err;
 
@@ -455,7 +456,7 @@ int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
                        err |= __put_user(from->si_uid, &to->si_uid);
                        break;
                case __SI_FAULT >> 16:
-                       err |= __put_user((long)from->si_addr, &to->si_addr);
+                       err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
                        break;
                case __SI_POLL >> 16:
                        err |= __put_user(from->si_band, &to->si_band);
@@ -476,10 +477,10 @@ save_static_function(sys32_sigreturn);
 __attribute_used__ noinline static void
 _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct sigframe *frame;
+       struct sigframe __user *frame;
        sigset_t blocked;
 
-       frame = (struct sigframe *) regs.regs[29];
+       frame = (struct sigframe __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
        if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
@@ -512,13 +513,13 @@ save_static_function(sys32_rt_sigreturn);
 __attribute_used__ noinline static void
 _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct rt_sigframe32 *frame;
+       struct rt_sigframe32 __user *frame;
        mm_segment_t old_fs;
        sigset_t set;
        stack_t st;
        s32 sp;
 
-       frame = (struct rt_sigframe32 *) regs.regs[29];
+       frame = (struct rt_sigframe32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
        if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -546,7 +547,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
           call it and ignore errors.  */
        old_fs = get_fs();
        set_fs (KERNEL_DS);
-       do_sigaltstack(&st, NULL, regs.regs[29]);
+       do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
        set_fs (old_fs);
 
        /*
@@ -564,7 +565,7 @@ badframe:
 }
 
 static inline int setup_sigcontext32(struct pt_regs *regs,
-                                    struct sigcontext32 *sc)
+                                    struct sigcontext32 __user *sc)
 {
        int err = 0;
 
@@ -623,8 +624,9 @@ out:
 /*
  * Determine which stack to use..
  */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-                                size_t frame_size)
+static inline void __user *get_sigframe(struct k_sigaction *ka,
+                                       struct pt_regs *regs,
+                                       size_t frame_size)
 {
        unsigned long sp;
 
@@ -642,13 +644,13 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
        if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
                sp = current->sas_ss_sp + current->sas_ss_size;
 
-       return (void *)((sp - frame_size) & ALMASK);
+       return (void __user *)((sp - frame_size) & ALMASK);
 }
 
 int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        int signr, sigset_t *set)
 {
-       struct sigframe *frame;
+       struct sigframe __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -692,17 +694,17 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->sf_code);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        int signr, sigset_t *set, siginfo_t *info)
 {
-       struct rt_sigframe32 *frame;
+       struct rt_sigframe32 __user *frame;
        int err = 0;
        s32 sp;
 
@@ -763,11 +765,11 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->rs_code);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
@@ -855,7 +857,7 @@ no_signal:
 }
 
 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
-                                 struct sigaction32 *oact,
+                                 struct sigaction32 __user *oact,
                                  unsigned int sigsetsize)
 {
        struct k_sigaction new_sa, old_sa;
@@ -872,7 +874,7 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
                        return -EFAULT;
                err |= __get_user(handler, &act->sa_handler);
-               new_sa.sa.sa_handler = (void*)(s64)handler;
+               new_sa.sa.sa_handler = (void __user *)(s64)handler;
                err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
                err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
                if (err)
@@ -899,7 +901,7 @@ out:
 }
 
 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
-       compat_sigset_t *oset, unsigned int sigsetsize)
+       compat_sigset_t __user *oset, unsigned int sigsetsize)
 {
        sigset_t old_set, new_set;
        int ret;
@@ -909,8 +911,9 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
                return -EFAULT;
 
        set_fs (KERNEL_DS);
-       ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
-                                oset ? &old_set : NULL, sigsetsize);
+       ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
+                                oset ? (sigset_t __user *)&old_set : NULL,
+                                sigsetsize);
        set_fs (old_fs);
 
        if (!ret && oset && put_sigset(&old_set, oset))
@@ -919,7 +922,7 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
        return ret;
 }
 
-asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
+asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
        unsigned int sigsetsize)
 {
        int ret;
@@ -927,7 +930,7 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
        mm_segment_t old_fs = get_fs();
 
        set_fs (KERNEL_DS);
-       ret = sys_rt_sigpending(&set, sigsetsize);
+       ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
        set_fs (old_fs);
 
        if (!ret && put_sigset(&set, uset))
@@ -936,7 +939,7 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
        return ret;
 }
 
-asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
+asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
 {
        siginfo_t info;
        int ret;
@@ -946,7 +949,7 @@ asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
            copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
                return -EFAULT;
        set_fs (KERNEL_DS);
-       ret = sys_rt_sigqueueinfo(pid, sig, &info);
+       ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
        set_fs (old_fs);
        return ret;
 }
index ec61b2670ba6e292abc3a25d410ab383958ffde0..384fc4a639a49653d785c4fd817fff429569b2bb 100644 (file)
@@ -48,6 +48,8 @@
 #define __NR_N32_rt_sigreturn          6211
 #define __NR_N32_restart_syscall       6214
 
+#define DEBUG_SIG 0
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /* IRIX compatible stack_t  */
@@ -83,12 +85,12 @@ save_static_function(sysn32_rt_sigreturn);
 __attribute_used__ noinline static void
 _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct rt_sigframe_n32 *frame;
+       struct rt_sigframe_n32 __user *frame;
        sigset_t set;
        stack_t st;
        s32 sp;
 
-       frame = (struct rt_sigframe_n32 *) regs.regs[29];
+       frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
        if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -114,7 +116,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs.regs[29]);
+       do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 
        /*
         * Don't let your children do this ...
@@ -133,7 +135,7 @@ badframe:
 int setup_rt_frame_n32(struct k_sigaction * ka,
        struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
-       struct rt_sigframe_n32 *frame;
+       struct rt_sigframe_n32 __user *frame;
        int err = 0;
        s32 sp;
 
@@ -184,9 +186,9 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
index 332358430ff5122a3639ccdb8a7ead2e8db03fd7..1da2eeb3ef9ed5194b4c30471ba6e78d5e967de5 100644 (file)
@@ -212,12 +212,12 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
        int error;
        char * filename;
 
-       filename = getname((char *) (long)regs.regs[4]);
+       filename = getname((char __user *) (long)regs.regs[4]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, (char **) (long)regs.regs[5],
-                         (char **) (long)regs.regs[6], &regs);
+       error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
+                         (char __user *__user *) (long)regs.regs[6], &regs);
        putname(filename);
 
 out:
@@ -227,7 +227,7 @@ out:
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname __user * name)
 {
        if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
                return 0;
@@ -237,7 +237,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_olduname(struct oldold_utsname * name)
+asmlinkage int sys_olduname(struct oldold_utsname __user * name)
 {
        int error;
 
@@ -274,7 +274,7 @@ void sys_set_thread_area(unsigned long addr)
 asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
 {
        int     tmp, len;
-       char    *name;
+       char    __user *name;
 
        switch(cmd) {
        case SETNAME: {
@@ -283,7 +283,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
-               name = (char *) arg1;
+               name = (char __user *) arg1;
 
                len = strncpy_from_user(nodename, name, __NEW_UTS_LEN);
                if (len < 0)
@@ -324,7 +324,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
  * This is really horribly ugly.
  */
 asmlinkage int sys_ipc (uint call, int first, int second,
-                       unsigned long third, void *ptr, long fifth)
+                       unsigned long third, void __user *ptr, long fifth)
 {
        int version, ret;
 
@@ -333,24 +333,25 @@ asmlinkage int sys_ipc (uint call, int first, int second,
 
        switch (call) {
        case SEMOP:
-               return sys_semtimedop (first, (struct sembuf *)ptr, second,
-                                      NULL);
+               return sys_semtimedop (first, (struct sembuf __user *)ptr,
+                                      second, NULL);
        case SEMTIMEDOP:
-               return sys_semtimedop (first, (struct sembuf *)ptr, second,
-                                      (const struct timespec __user *)fifth);
+               return sys_semtimedop (first, (struct sembuf __user *)ptr,
+                                      second,
+                                      (const struct timespec __user *)fifth);
        case SEMGET:
                return sys_semget (first, second, third);
        case SEMCTL: {
                union semun fourth;
                if (!ptr)
                        return -EINVAL;
-               if (get_user(fourth.__pad, (void **) ptr))
+               if (get_user(fourth.__pad, (void *__user *) ptr))
                        return -EFAULT;
                return sys_semctl (first, second, third, fourth);
        }
 
        case MSGSND:
-               return sys_msgsnd (first, (struct msgbuf *) ptr,
+               return sys_msgsnd (first, (struct msgbuf __user *) ptr,
                                   second, third);
        case MSGRCV:
                switch (version) {
@@ -360,7 +361,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
                                return -EINVAL;
 
                        if (copy_from_user(&tmp,
-                                          (struct ipc_kludge *) ptr,
+                                          (struct ipc_kludge __user *) ptr,
                                           sizeof (tmp)))
                                return -EFAULT;
                        return sys_msgrcv (first, tmp.msgp, second,
@@ -368,35 +369,38 @@ asmlinkage int sys_ipc (uint call, int first, int second,
                }
                default:
                        return sys_msgrcv (first,
-                                          (struct msgbuf *) ptr,
+                                          (struct msgbuf __user *) ptr,
                                           second, fifth, third);
                }
        case MSGGET:
                return sys_msgget ((key_t) first, second);
        case MSGCTL:
-               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+               return sys_msgctl (first, second,
+                                  (struct msqid_ds __user *) ptr);
 
        case SHMAT:
                switch (version) {
                default: {
                        ulong raddr;
-                       ret = do_shmat (first, (char *) ptr, second, &raddr);
+                       ret = do_shmat (first, (char __user *) ptr, second,
+                                       &raddr);
                        if (ret)
                                return ret;
-                       return put_user (raddr, (ulong *) third);
+                       return put_user (raddr, (ulong __user *) third);
                }
                case 1: /* iBCS2 emulator entry point */
                        if (!segment_eq(get_fs(), get_ds()))
                                return -EINVAL;
-                       return do_shmat (first, (char *) ptr, second, (ulong *) third);
+                       return do_shmat (first, (char __user *) ptr, second,
+                                        (ulong *) third);
                }
        case SHMDT:
-               return sys_shmdt ((char *)ptr);
+               return sys_shmdt ((char __user *)ptr);
        case SHMGET:
                return sys_shmget (first, second, third);
        case SHMCTL:
                return sys_shmctl (first, second,
-                                  (struct shmid_ds *) ptr);
+                                  (struct shmid_ds __user *) ptr);
        default:
                return -ENOSYS;
        }
index 59a187956de028cc4812a8822aea55fcfa5d68e0..c9d2b5147ca353ccda409983df7aca3a439b4d0a 100644 (file)
@@ -1168,7 +1168,7 @@ void __init per_cpu_trap_init(void)
 #endif
        if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
                status_set |= ST0_XX;
-       change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+       change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
                         status_set);
 
        if (cpu_has_dsp)
index 25cc856d8e7e7ab210b871de0bf5e7c735b171ea..ff699dbb99f730b0a3da89883f96788ee254d160 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/config.h>
+#include <asm/asm-offsets.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips            /* CPP really sucks for this job  */
@@ -64,10 +65,10 @@ SECTIONS
      we can shorten the on-disk segment size.  */
   .sdata     : { *(.sdata) }
 
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __nosave_begin = .;
   .data_nosave : { *(.data.nosave) }
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __nosave_end = .;
 
   . = ALIGN(32);
@@ -76,7 +77,7 @@ SECTIONS
   _edata =  .;                 /* End of data section */
 
   /* will be freed after init */
-  . = ALIGN(4096);             /* Init code and data */
+  . = ALIGN(_PAGE_SIZE);               /* Init code and data */
   __init_begin = .;
   .init.text : {
        _sinittext = .;
@@ -105,7 +106,7 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
   __initramfs_end = .;
@@ -113,7 +114,7 @@ SECTIONS
   __per_cpu_start = .;
   .data.percpu  : { *(.data.percpu) }
   __per_cpu_end = .;
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __init_end = .;
   /* freed after init ends here */
 
index 8d7d7a454f9a4e6f439042422842fa87d313419b..181bf68175fccf18255c81079928e56d6b8df83f 100644 (file)
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/pm.h>
+
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/lasat/lasat.h>
+
 #include "picvue.h"
 #include "prom.h"
 
@@ -63,5 +66,5 @@ void lasat_reboot_setup(void)
 {
        _machine_restart = lasat_machine_restart;
        _machine_halt = lasat_machine_halt;
-       _machine_power_off = lasat_machine_halt;
+       pm_power_off = lasat_machine_halt;
 }
index dcd819d57dae4f39688ded7193970f3ed29100c4..83eb08b7a07290b9eb9ff942e13742a6714cfebd 100644 (file)
@@ -134,8 +134,8 @@ void __init serial_init(void)
 
        memset(&s, 0, sizeof(s));
 
-       s.flags = STD_COM_FLAGS;
-       s.iotype = SERIAL_IO_MEM;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+       s.iotype = UPIO_MEM;
 
        if (mips_machtype == MACH_LASAT_100) {
                s.uartclk = LASAT_BASE_BAUD_100 * 16;
index 46519f4331ebb62bf7498a028445a6de9580d843..c49a925d01690e38c8a16e6fefdbb020799391a4 100644 (file)
@@ -158,29 +158,26 @@ void dump_list_process(struct task_struct *t, void *address)
        printk("task->mm             == %8p\n", t->mm);
        //printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
 
-       if (addr > KSEG0)
+       if (addr > KSEG0) {
                page_dir = pgd_offset_k(0);
-       else if (t->mm) {
-               page_dir = pgd_offset(t->mm, 0);
-               printk("page_dir == %08x\n", (unsigned int) page_dir);
-       } else
-               printk("Current thread has no mm\n");
-
-       if (addr > KSEG0)
                pgd = pgd_offset_k(addr);
-       else if (t->mm) {
+       } else if (t->mm) {
+               page_dir = pgd_offset(t->mm, 0);
                pgd = pgd_offset(t->mm, addr);
-               printk("pgd == %08x, ", (unsigned int) pgd);
-               pud = pud_offset(pgd, addr);
-               printk("pud == %08x, ", (unsigned int) pud);
+       } else {
+               printk("Current thread has no mm\n");
+               return;
+       }
+       printk("page_dir == %08x\n", (unsigned int) page_dir);
+       printk("pgd == %08x, ", (unsigned int) pgd);
+       pud = pud_offset(pgd, addr);
+       printk("pud == %08x, ", (unsigned int) pud);
 
-               pmd = pmd_offset(pud, addr);
-               printk("pmd == %08x, ", (unsigned int) pmd);
+       pmd = pmd_offset(pud, addr);
+       printk("pmd == %08x, ", (unsigned int) pmd);
 
-               pte = pte_offset(pmd, addr);
-               printk("pte == %08x, ", (unsigned int) pte);
-       } else
-               printk("Current thread has no mm\n");
+       pte = pte_offset(pmd, addr);
+       printk("pte == %08x, ", (unsigned int) pte);
 
        page = *pte;
 #ifdef CONFIG_64BIT_PHYS_ADDR
index 495c1ac942985ec0f1a051ca6fd9ff15af0b442f..1c555e6c6a9f8efdf20203b77a629c22e369af80 100644 (file)
@@ -48,16 +48,22 @@ ieee754dp ieee754dp_neg(ieee754dp x)
        CLEARCX;
        FLUSHXDP;
 
+       /*
+        * Invert the sign ALWAYS to prevent an endless recursion on
+        * pow() in libc.
+        */
+       /* quick fix up */
+       DPSIGN(x) ^= 1;
+
        if (xc == IEEE754_CLASS_SNAN) {
+               ieee754dp y = ieee754dp_indef();
                SETCX(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+               DPSIGN(y) = DPSIGN(x);
+               return ieee754dp_nanxcpt(y, "neg");
        }
 
        if (ieee754dp_isnan(x)) /* but not infinity */
                return ieee754dp_nanxcpt(x, "neg", x);
-
-       /* quick fix up */
-       DPSIGN(x) ^= 1;
        return x;
 }
 
index c809830dffb473f50a6d017f7927491c1049b20b..770f0f4677cd5a8c542f670396872afc1cba4d69 100644 (file)
@@ -48,16 +48,22 @@ ieee754sp ieee754sp_neg(ieee754sp x)
        CLEARCX;
        FLUSHXSP;
 
+       /*
+        * Invert the sign ALWAYS to prevent an endless recursion on
+        * pow() in libc.
+        */
+       /* quick fix up */
+       SPSIGN(x) ^= 1;
+
        if (xc == IEEE754_CLASS_SNAN) {
+               ieee754sp y = ieee754sp_indef();
                SETCX(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef(), "neg");
+               SPSIGN(y) = SPSIGN(x);
+               return ieee754sp_nanxcpt(y, "neg");
        }
 
        if (ieee754sp_isnan(x)) /* but not infinity */
                return ieee754sp_nanxcpt(x, "neg", x);
-
-       /* quick fix up */
-       SPSIGN(x) ^= 1;
        return x;
 }
 
index 625843b30bedfa7d876d3bb0cdb4e87989ba11a9..873cf3141a31961002fef869527c4ed98bbac000 100644 (file)
@@ -82,8 +82,8 @@ static void __init serial_init(void)
 #endif
        s.irq = ATLASINT_UART;
        s.uartclk = ATLAS_BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-       s.iotype = SERIAL_IO_PORT;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
+       s.iotype = UPIO_PORT;
        s.regshift = 3;
 
        if (early_serial_setup(&s) != 0) {
index 9fdec743bd9581cebe958ea07b1bb56b142f85b8..7213c395fb6bc4752af4bbfb2cb3a4ab023c7b8f 100644 (file)
@@ -23,6 +23,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/pm.h>
 
 #include <asm/io.h>
 #include <asm/reboot.h>
@@ -65,9 +66,9 @@ void mips_reboot_setup(void)
        _machine_restart = mips_machine_restart;
        _machine_halt = mips_machine_halt;
 #if defined(CONFIG_MIPS_ATLAS)
-       _machine_power_off = atlas_machine_power_off;
+       pm_power_off = atlas_machine_power_off;
 #endif
 #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD)
-       _machine_power_off = mips_machine_halt;
+       pm_power_off = mips_machine_halt;
 #endif
 }
index f966bc161dfaa06a6b08037e799f0ab8f5c05856..4266ce445174e4bd67866f3aa783b7a8b6b4b1be 100644 (file)
@@ -71,8 +71,8 @@ static void __init serial_init(void)
 #endif
        s.irq = MIPSCPU_INT_BASE + MIPSCPU_INT_UART0;
        s.uartclk = SEAD_BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-       s.iotype = 0;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
+       s.iotype = UPIO_PORT;
        s.regshift = 3;
 
        if (early_serial_setup(&s) != 0) {
index 485d5a58d9cf7cfd39727f6fb0c40f0bc3bc7b7c..a2fd62997ca3c3b9ee7337d3622834761b2ccb88 100644 (file)
@@ -88,8 +88,8 @@ static void __init serial_init(void)
         but poll for now */
        s.irq =  0;
        s.uartclk = BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
-       s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+       s.iotype = UPIO_PORT;
        s.regshift = 0;
        s.timeout = 4;
 
index 422b55fab07ab5b5dfb82341a3380b55696da902..e51c38cef88e82465493e425c8d5dc9c7d57cbdb 100644 (file)
@@ -464,8 +464,8 @@ static void r4k_flush_data_cache_page(unsigned long addr)
 }
 
 struct flush_icache_range_args {
-       unsigned long __user start;
-       unsigned long __user end;
+       unsigned long start;
+       unsigned long end;
 };
 
 static inline void local_r4k_flush_icache_range(void *args)
@@ -528,8 +528,7 @@ static inline void local_r4k_flush_icache_range(void *args)
        }
 }
 
-static void r4k_flush_icache_range(unsigned long __user start,
-       unsigned long __user end)
+static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
        struct flush_icache_range_args args;
 
index 314701a66b13ab8b5ff31668cfcf8739eb7efc2e..591c22b080e427edc681248508b86ffc3a3fecb7 100644 (file)
@@ -25,8 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
        unsigned long end);
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
        unsigned long pfn);
-void (*flush_icache_range)(unsigned long __user start,
-       unsigned long __user end);
+void (*flush_icache_range)(unsigned long start, unsigned long end);
 void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* MIPS specific cache operations */
@@ -53,7 +52,7 @@ EXPORT_SYMBOL(_dma_cache_inv);
  * We could optimize the case where the cache argument is not BCACHE but
  * that seems very atypical use ...
  */
-asmlinkage int sys_cacheflush(unsigned long __user addr,
+asmlinkage int sys_cacheflush(unsigned long addr,
        unsigned long bytes, unsigned int cache)
 {
        if (bytes == 0)
index 4ee91c9a556fed7f53dfb534cfc8d474392952a7..0ff9a348b84317b2c915de9aeb485839fb1ff1ce 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
+#include <linux/proc_fs.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
@@ -200,6 +201,11 @@ static inline int page_is_ram(unsigned long pagenr)
        return 0;
 }
 
+static struct kcore_list kcore_mem, kcore_vmalloc;
+#ifdef CONFIG_64BIT
+static struct kcore_list kcore_kseg0;
+#endif
+
 void __init mem_init(void)
 {
        unsigned long codesize, reservedpages, datasize, initsize;
@@ -249,6 +255,16 @@ void __init mem_init(void)
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
+#ifdef CONFIG_64BIT
+       if ((unsigned long) &_text > (unsigned long) CKSEG0)
+               /* The -4 is a hack so that user tools don't have to handle
+                  the overflow.  */
+               kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4);
+#endif
+       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
+       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
+                  VMALLOC_END-VMALLOC_START);
+
        printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
               "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
index da6e1ed34db16e4a1f87ceb14f7efb7055caa1cf..2292d0ec47fc27aadfe255499214293f81ea5622 100644 (file)
@@ -93,7 +93,7 @@ static void inline ja_console_probe(void)
        up.uartclk      = JAGUAR_ATX_UART_CLK;
        up.regshift     = 2;
        up.iotype       = UPIO_MEM;
-       up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       up.flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        up.line         = 0;
 
        if (early_serial_setup(&up))
index bab192ddc1850b81957094058d240369523736fc..301d67226d72e4caa9cbb379cddb8b6c5d852927 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/pci.h>
 #include <linux/swap.h>
 #include <linux/ioport.h>
+#include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
@@ -365,7 +366,7 @@ void __init plat_setup(void)
 
        _machine_restart = momenco_jaguar_restart;
        _machine_halt = momenco_jaguar_halt;
-       _machine_power_off = momenco_jaguar_power_off;
+       pm_power_off = momenco_jaguar_power_off;
 
        /*
         * initrd_start = (ulong)jaguar_initrd_start;
index c9b7ff8148ec3cd3bd12c312ddebff2e2682cf97..f95677f4f06f7e0c1be3e7c3849ada251257836d 100644 (file)
@@ -57,6 +57,8 @@
 #include <linux/timex.h>
 #include <linux/bootmem.h>
 #include <linux/mv643xx.h>
+#include <linux/pm.h>
+
 #include <asm/time.h>
 #include <asm/page.h>
 #include <asm/bootinfo.h>
@@ -321,7 +323,7 @@ void __init plat_setup(void)
 
        _machine_restart = momenco_ocelot_restart;
        _machine_halt = momenco_ocelot_halt;
-       _machine_power_off = momenco_ocelot_power_off;
+       pm_power_off = momenco_ocelot_power_off;
 
        /* Wired TLB entries */
        setup_wired_tlb_entries();
index 2755c1547473b5a0ca42956ca75066231f5da96e..15998d8a934198fce955dc33d18e64169ab41999 100644 (file)
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -236,7 +238,7 @@ void __init plat_setup(void)
 
        _machine_restart = momenco_ocelot_restart;
        _machine_halt = momenco_ocelot_halt;
-       _machine_power_off = momenco_ocelot_power_off;
+       pm_power_off = momenco_ocelot_power_off;
 
        /*
         * initrd_start = (ulong)ocelot_initrd_start;
index 6336751391c397ff7d7026d43812b7211b4b9829..fed4e8eee116bc0a4555a20d6f64091304246d74 100644 (file)
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -169,7 +171,7 @@ void __init plat_setup(void)
 
        _machine_restart = momenco_ocelot_restart;
        _machine_halt = momenco_ocelot_halt;
-       _machine_power_off = momenco_ocelot_power_off;
+       pm_power_off = momenco_ocelot_power_off;
 
        /*
         * initrd_start = (ulong)ocelot_initrd_start;
index 354261d37d62e5e09bfc136f117e9394ef32a833..0a50aad5bbe47f54fdc578020a9cfc84b08e6b0c 100644 (file)
@@ -12,4 +12,5 @@ oprofile-y                            := $(DRIVER_OBJS) common.o
 
 oprofile-$(CONFIG_CPU_MIPS32)          += op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_MIPS64)          += op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_SB1)             += op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_RM9000)          += op_model_rm9000.o
index 53f9889b30eda3c278cf4664e463a793e36e9948..935dd851f480c0065c37d4275c71f40b663aab5b 100644 (file)
@@ -79,6 +79,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        case CPU_20KC:
        case CPU_24K:
        case CPU_25KF:
+       case CPU_34K:
+       case CPU_SB1:
+       case CPU_SB1A:
                lmodel = &op_model_mipsxx;
                break;
 
index 1d1eee407faf971a86b8f63b543aae90957d8ddd..95d488ca075473be4d4e0a3e0d032a0c413eaf27 100644 (file)
@@ -201,10 +201,21 @@ static int __init mipsxx_init(void)
                op_model_mipsxx.cpu_type = "mips/25K";
                break;
 
+#ifndef CONFIG_SMP
+       case CPU_34K:
+               op_model_mipsxx.cpu_type = "mips/34K";
+               break;
+#endif
+
        case CPU_5KC:
                op_model_mipsxx.cpu_type = "mips/5K";
                break;
 
+       case CPU_SB1:
+       case CPU_SB1A:
+               op_model_mipsxx.cpu_type = "mips/sb1";
+               break;
+
        default:
                printk(KERN_ERR "Profiling unsupported for this CPU\n");
 
index 741e67c9195ade12e0e94e581fd42985a3ef91e3..16205b587338a400f54455420be0ef7cdb90fd57 100644 (file)
@@ -46,6 +46,7 @@ obj-$(CONFIG_PMC_YOSEMITE)    += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
 obj-$(CONFIG_SGI_IP27)         += pci-ip27.o
 obj-$(CONFIG_SGI_IP32)         += fixup-ip32.o ops-mace.o pci-ip32.o
 obj-$(CONFIG_SIBYTE_SB1250)    += fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM112X)   += fixup-sb1250.o pci-sb1250.o
 obj-$(CONFIG_SIBYTE_BCM1x80)   += pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM200_PCI)    += fixup-sni.o ops-sni.o
 obj-$(CONFIG_TANBAC_TB0219)    += fixup-tb0219.o
index 909292f50d06114794379d61ae92bd2b1792dba8..75a01e7648985c2cf20a84b5f76a4b13c03e6d43 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/io.h>
 #include <asm/gt64120.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern int cobalt_board_id;
 
@@ -52,7 +52,7 @@ static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
        if (lt < 64)
                pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
@@ -69,7 +69,7 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
         * host bridge.
         */
        pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 
        /*
         * The code described by the comment below has been removed
index c1807934768d499d9f27a27aa27b551316720cca..13de45940b1995c6eeeb881617f3b9a796f2d15c 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/io.h>
 #include <asm/gt64120.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 /*
  * Device 31 on the GT64111 is used to generate PCI special
index f194b4e4f86aa86cd9ac90f9eb63f6526e5def73..ca975e7d32ffba36d5b5d0ec68c3314464d6d902 100644 (file)
@@ -234,11 +234,9 @@ static int __init bcm1480_pcibios_init(void)
 
        /* turn on ExpMemEn */
        cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
-       printk("PCIFeatureCtrl = %x\n", cmdreg);
        WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
                        cmdreg | 0x10);
        cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
-       printk("PCIFeatureCtrl = %x\n", cmdreg);
 
        /*
         * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
index 8aa9bd65b45e2f929c80ae3b7c113f9e4627bc3f..a592260fd6735b8a902e6939ddbd7826dcd0dec1 100644 (file)
@@ -66,28 +66,28 @@ struct ip3106_port ip3106_ports[] = {
        [0] = {
                .port   = {
                        .type           = PORT_IP3106,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .membase        = (void __iomem *)PNX8550_UART_PORT0,
                        .mapbase        = PNX8550_UART_PORT0,
                        .irq            = PNX8550_UART_INT(0),
                        .uartclk        = 3692300,
                        .fifosize       = 16,
                        .ops            = &ip3106_pops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
        },
        [1] = {
                .port   = {
                        .type           = PORT_IP3106,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .membase        = (void __iomem *)PNX8550_UART_PORT1,
                        .mapbase        = PNX8550_UART_PORT1,
                        .irq            = PNX8550_UART_INT(1),
                        .uartclk        = 3692300,
                        .fifosize       = 16,
                        .ops            = &ip3106_pops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
        },
index ee6bf72094f66724be771e0796224ae3409ab31a..0d8a77619391d702a85af054bdff218553576b7e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/serial_ip3106.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -90,7 +91,7 @@ void __init plat_setup(void)
 
         _machine_restart = pnx8550_machine_restart;
         _machine_halt = pnx8550_machine_halt;
-        _machine_power_off = pnx8550_machine_power_off;
+        pm_power_off = pnx8550_machine_power_off;
 
        board_time_init = pnx8550_time_init;
        board_timer_setup = pnx8550_timer_setup;
index 555bfacf76475975a3d6e24792c48a1321234b29..165275c00cbb9c8fb42ebf9cbf64807725f67c95 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 
 #include <asm/io.h>
@@ -92,7 +93,7 @@ void __init prom_init(void)
        /* Callbacks for halt, restart */
        _machine_restart = (void (*)(char *)) prom_exit;
        _machine_halt = prom_halt;
-       _machine_power_off = prom_halt;
+       pm_power_off = prom_halt;
 
        debug_vectors = cv;
        arcs_cmdline[0] = '\0';
index 059755b5ed576b7c4c1560a9479dad1e50dc1eda..8bce711575decce5d40bd5c68909cf28b8a7fa98 100644 (file)
@@ -185,7 +185,7 @@ static void __init py_uart_setup(void)
        up.uartclk      = TITAN_UART_CLK;
        up.regshift     = 0;
        up.iotype       = UPIO_MEM;
-       up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       up.flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        up.line         = 0;
 
        if (early_serial_setup(&up))
index 214ffd2e98a332dad828755ea2f4da9619dee12c..92a3b3c15ed3a5ddf57760b44910c6b4cbf86a52 100644 (file)
@@ -3,8 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 2001, 03, 05, 06 by Ralf Baechle
  */
+#include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/ds1286.h>
 #include <linux/module.h>
@@ -12,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/timer.h>
 
 #include <asm/io.h>
@@ -41,28 +43,10 @@ static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
 
 #define MACHINE_PANICED                1
 #define MACHINE_SHUTTING_DOWN  2
-static int machine_state = 0;
 
-static void sgi_machine_restart(char *command) __attribute__((noreturn));
-static void sgi_machine_halt(void) __attribute__((noreturn));
-static void sgi_machine_power_off(void) __attribute__((noreturn));
+static int machine_state;
 
-static void sgi_machine_restart(char *command)
-{
-       if (machine_state & MACHINE_SHUTTING_DOWN)
-               sgi_machine_power_off();
-       sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
-       while (1);
-}
-
-static void sgi_machine_halt(void)
-{
-       if (machine_state & MACHINE_SHUTTING_DOWN)
-               sgi_machine_power_off();
-       ArcEnterInteractiveMode();
-}
-
-static void sgi_machine_power_off(void)
+static void ATTRIB_NORET sgi_machine_power_off(void)
 {
        unsigned int tmp;
 
@@ -84,6 +68,21 @@ static void sgi_machine_power_off(void)
        }
 }
 
+static void ATTRIB_NORET sgi_machine_restart(char *command)
+{
+       if (machine_state & MACHINE_SHUTTING_DOWN)
+               sgi_machine_power_off();
+       sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+       while (1);
+}
+
+static void ATTRIB_NORET sgi_machine_halt(void)
+{
+       if (machine_state & MACHINE_SHUTTING_DOWN)
+               sgi_machine_power_off();
+       ArcEnterInteractiveMode();
+}
+
 static void power_timeout(unsigned long data)
 {
        sgi_machine_power_off();
@@ -95,7 +94,7 @@ static void blink_timeout(unsigned long data)
        sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF);
        sgioc->reset = sgi_ioc_reset;
 
-       mod_timer(&blink_timer, jiffies+data);
+       mod_timer(&blink_timer, jiffies + data);
 }
 
 static void debounce(unsigned long data)
@@ -103,7 +102,7 @@ static void debounce(unsigned long data)
        del_timer(&debounce_timer);
        if (sgint->istat1 & SGINT_ISTAT1_PWR) {
                /* Interrupt still being sent. */
-               debounce_timer.expires = jiffies + 5; /* 0.05s  */
+               debounce_timer.expires = jiffies + (HZ / 20); /* 0.05s  */
                add_timer(&debounce_timer);
 
                sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR |
@@ -151,7 +150,7 @@ static inline void volume_up_button(unsigned long data)
                indy_volume_button(1);
 
        if (sgint->istat1 & SGINT_ISTAT1_PWR) {
-               volume_timer.expires = jiffies + 1;
+               volume_timer.expires = jiffies + (HZ / 100);
                add_timer(&volume_timer);
        }
 }
@@ -164,7 +163,7 @@ static inline void volume_down_button(unsigned long data)
                indy_volume_button(-1);
 
        if (sgint->istat1 & SGINT_ISTAT1_PWR) {
-               volume_timer.expires = jiffies + 1;
+               volume_timer.expires = jiffies + (HZ / 100);
                add_timer(&volume_timer);
        }
 }
@@ -199,14 +198,14 @@ static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs)
        if (!(buttons & SGIOC_PANEL_VOLUPINTR)) {
                init_timer(&volume_timer);
                volume_timer.function = volume_up_button;
-               volume_timer.expires = jiffies + 1;
+               volume_timer.expires = jiffies + (HZ / 100);
                add_timer(&volume_timer);
        }
        /* Volume down button was pressed */
        if (!(buttons & SGIOC_PANEL_VOLDNINTR)) {
                init_timer(&volume_timer);
                volume_timer.function = volume_down_button;
-               volume_timer.expires = jiffies + 1;
+               volume_timer.expires = jiffies + (HZ / 100);
                add_timer(&volume_timer);
        }
 
@@ -234,7 +233,7 @@ static int __init reboot_setup(void)
 {
        _machine_restart = sgi_machine_restart;
        _machine_halt = sgi_machine_halt;
-       _machine_power_off = sgi_machine_power_off;
+       pm_power_off = sgi_machine_power_off;
 
        request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
        init_timer(&blink_timer);
index 5e59b4c8876bab8ff24f97ee2c41fce5910a42b5..7018e1833e85dd7ab577c9f43b1bcaa48c7f42c5 100644 (file)
@@ -56,6 +56,7 @@ extern void ip22_time_init(void) __init;
 void __init plat_setup(void)
 {
        char *ctype;
+       char *cserial;
 
        board_be_init = ip22_be_init;
        ip22_time_init();
@@ -81,9 +82,14 @@ void __init plat_setup(void)
        /* ARCS console environment variable is set to "g?" for
         * graphics console, it is set to "d" for the first serial
         * line and "d2" for the second serial line.
+        *
+        * Need to check if the case is 'g' but no keyboard:
+        * (ConsoleIn/Out = serial)
         */
        ctype = ArcGetEnvironmentVariable("console");
-       if (ctype && *ctype == 'd') {
+       cserial = ArcGetEnvironmentVariable("ConsoleOut");
+
+       if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) {
                static char options[8];
                char *baud = ArcGetEnvironmentVariable("dbaud");
                if (baud)
@@ -91,7 +97,7 @@ void __init plat_setup(void)
                add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0,
                                      baud ? options : NULL);
        } else if (!ctype || *ctype != 'g') {
-               /* Use ARC if we don't want serial ('d') or Newport ('g'). */
+               /* Use ARC if we don't want serial ('d') or graphics ('g'). */
                prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
                add_preferred_console("arc", 0, NULL);
        }
index 2e16be94c78bb402e54e42998d4094f1910ba2d5..4322db57d3c15e9eb53f91fbe741ecb7f5577b1c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Reset an IP27.
  *
- * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2000, 06 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
@@ -15,6 +15,7 @@
 #include <linux/smp.h>
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
+#include <linux/pm.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -77,5 +78,5 @@ void ip27_reboot_setup(void)
 {
        _machine_restart = ip27_machine_restart;
        _machine_halt = ip27_machine_halt;
-       _machine_power_off = ip27_machine_power_off;
+       pm_power_off = ip27_machine_power_off;
 }
index 88e1f52059ff6a45c1d461cffb42302377bbe4e2..0c948008b02382f7ef37b21f38af7be2787538a3 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/ds17287rtc.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/irq.h>
@@ -188,7 +189,7 @@ static __init int ip32_reboot_setup(void)
 
        _machine_restart = ip32_machine_restart;
        _machine_halt = ip32_machine_halt;
-       _machine_power_off = ip32_machine_power_off;
+       pm_power_off = ip32_machine_power_off;
 
        init_timer(&blink_timer);
        blink_timer.function = blink_timeout;
index d10a269aeae1c05693b0a98246967ef398e3948f..2c38770b1e1bcf0a5750af1d3dd96604cc7a42bd 100644 (file)
@@ -66,11 +66,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
-extern int early_serial_setup(struct uart_port *port);
-
-#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
-#define BASE_BAUD (1843200 / 16)
-
 #endif /* CONFIG_SERIAL_8250 */
 
 /* An arbitrary time; this can be decreased if reliability looks good */
@@ -110,8 +105,8 @@ void __init plat_setup(void)
                o2_serial[0].type       = PORT_16550A;
                o2_serial[0].line       = 0;
                o2_serial[0].irq        = MACEISA_SERIAL1_IRQ;
-               o2_serial[0].flags      = STD_COM_FLAGS;
-               o2_serial[0].uartclk    = BASE_BAUD * 16;
+               o2_serial[0].flags      = UPF_SKIP_TEST;
+               o2_serial[0].uartclk    = 1843200;
                o2_serial[0].iotype     = UPIO_MEM;
                o2_serial[0].membase    = (char *)&mace->isa.serial1;
                o2_serial[0].fifosize   = 14;
@@ -121,8 +116,8 @@ void __init plat_setup(void)
                o2_serial[1].type       = PORT_16550A;
                o2_serial[1].line       = 1;
                o2_serial[1].irq        = MACEISA_SERIAL2_IRQ;
-               o2_serial[1].flags      = STD_COM_FLAGS;
-               o2_serial[1].uartclk    = BASE_BAUD * 16;
+               o2_serial[1].flags      = UPF_SKIP_TEST;
+               o2_serial[1].uartclk    = 1843200;
                o2_serial[1].iotype     = UPIO_MEM;
                o2_serial[1].membase    = (char *)&mace->isa.serial2;
                o2_serial[1].fifosize   = 14;
index 7a2c7a8510d421593d487233ea1834740fa0d9ed..ea308029450e581ef65978af5d58056f7f2af0f0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 
 #include <asm/bootinfo.h>
@@ -248,7 +249,7 @@ void __init prom_init(void)
 
        _machine_restart   = cfe_linux_restart;
        _machine_halt      = cfe_linux_halt;
-       _machine_power_off = cfe_linux_halt;
+       pm_power_off = cfe_linux_halt;
 
        /*
         * Check if a loader was used; if NOT, the 4 arguments are
index de62ab0f55a25091be2e24b249bc27ade2a9f675..742043f8d755626f7f42afc3b5c5d864ac983f2c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 #include <linux/initrd.h>
+#include <linux/pm.h>
 
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
@@ -79,7 +80,7 @@ void __init prom_init(void)
 {
        _machine_restart   = (void (*)(char *))prom_linux_exit;
        _machine_halt      = prom_linux_exit;
-       _machine_power_off = prom_linux_exit;
+       pm_power_off = prom_linux_exit;
 
        strcpy(arcs_cmdline, "root=/dev/ram0 ");
 
index df2e266c700ce3d797684227765a24e4cbed7344..fde4751c84fe6335108eb4eda4fab5566f6d1834 100644 (file)
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/string.h>
@@ -42,7 +43,7 @@ static inline int setup_bcm112x(void);
 
 /* Setup code likely to be common to all SiByte platforms */
 
-static inline int sys_rev_decode(void)
+static int __init sys_rev_decode(void)
 {
        int ret = 0;
 
@@ -74,7 +75,7 @@ static inline int sys_rev_decode(void)
        return ret;
 }
 
-static inline int setup_bcm1250(void)
+static int __init setup_bcm1250(void)
 {
        int ret = 0;
 
@@ -120,7 +121,7 @@ static inline int setup_bcm1250(void)
        return ret;
 }
 
-static inline int setup_bcm112x(void)
+static int __init setup_bcm112x(void)
 {
        int ret = 0;
 
@@ -146,7 +147,7 @@ static inline int setup_bcm112x(void)
        return ret;
 }
 
-void sb1250_setup(void)
+void __init sb1250_setup(void)
 {
        uint64_t sys_rev;
        int plldiv;
@@ -169,31 +170,42 @@ void sb1250_setup(void)
                    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
        prom_printf("Board type: %s\n", get_system_type());
 
-       switch(war_pass) {
+       switch (war_pass) {
        case K_SYS_REVISION_BCM1250_PASS1:
 #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
-               prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+               prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
+                           "and the kernel doesn't have the proper "
+                           "workarounds compiled in. @@@@\n");
                bad_config = 1;
 #endif
                break;
        case K_SYS_REVISION_BCM1250_PASS2:
                /* Pass 2 - easiest as default for now - so many numbers */
-#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
-               prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
+    !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
+               prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the "
+                           "kernel doesn't have the proper workarounds "
+                           "compiled in. @@@@\n");
                bad_config = 1;
 #endif
 #ifdef CONFIG_CPU_HAS_PREFETCH
-               prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board.  @@@@\n");
+               prom_printf("@@@@ Prefetches may be enabled in this kernel, "
+                           "but are buggy on this board.  @@@@\n");
                bad_config = 1;
 #endif
                break;
        case K_SYS_REVISION_BCM1250_PASS2_2:
 #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
-               prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+               prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the "
+                           "kernel doesn't have the proper workarounds "
+                           "compiled in. @@@@\n");
                bad_config = 1;
 #endif
-#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH)
-               prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n");
+#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
+    !defined(CONFIG_CPU_HAS_PREFETCH)
+               prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is "
+                           "conservatively configured for an 'A' stepping. "
+                           "@@@@\n");
 #endif
                break;
        default:
index 262c856807090d81cbd167f1bf63bd635f261b90..1141fcd13a59f266d067a624d328b7eab9c76535 100644 (file)
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 98, 2000, 03, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
  */
 #include <linux/config.h>
 #include <linux/eisa.h>
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
+#include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/console.h>
 #include <linux/fb.h>
@@ -189,7 +190,7 @@ void __init plat_setup(void)
 
        _machine_restart = sni_machine_restart;
        _machine_halt = sni_machine_halt;
-       _machine_power_off = sni_machine_power_off;
+       pm_power_off = sni_machine_power_off;
 
        sni_display_setup();
 
index e4d095d3e19293eb4769e79fb8a73471fef6a5a6..e19e2be70f76ef3209b8562b672037369be9fc35 100644 (file)
@@ -60,7 +60,6 @@ void __init prom_init_cmdline(void)
 
 void __init prom_init(void)
 {
-       const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES;
        extern int tx4927_get_mem_size(void);
        extern char* toshiba_name;
        int msize;
@@ -69,12 +68,13 @@ void __init prom_init(void)
 
        mips_machgroup = MACH_GROUP_TOSHIBA;
 
-       if ((read_c0_prid() & 0xff) == PRID_REV_TX4927)
+       if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) {
                mips_machtype = MACH_TOSHIBA_RBTX4927;
-       else
+               toshiba_name  = "TX4927";
+       } else {
                mips_machtype = MACH_TOSHIBA_RBTX4937;
-
-        toshiba_name = toshiba_name_list[mips_machtype];
+               toshiba_name  = "TX4937";
+       }
 
        msize = tx4927_get_mem_size();
        add_memory_region(0, msize << 20, BOOT_MEM_RAM);
index 990fcb294babb0392ebf591a02371297eb947b61..2ad6401d2af465d8d1b1aeebaedc2088fd41fe2d 100644 (file)
@@ -53,6 +53,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/timex.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/page.h>
 #include <asm/io.h>
@@ -537,19 +539,10 @@ void tx4927_pci_setup(void)
        TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
                                       "0x%08lx=mips_io_port_base",
                                       mips_io_port_base);
-
-       TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
-                                      "setup pci_io_resource  to 0x%08lx 0x%08lx\n",
-                                      pci_io_resource.start,
-                                      pci_io_resource.end);
-       TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
-                                      "setup pci_mem_resource to 0x%08lx 0x%08lx\n",
-                                      pci_mem_resource.start,
-                                      pci_mem_resource.end);
-
        if (!called) {
                printk
-                   ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+                   ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+                    toshiba_name,
                     (unsigned short) (tx4927_pcicptr->pciid >> 16),
                     (unsigned short) (tx4927_pcicptr->pciid & 0xffff),
                     (unsigned short) (tx4927_pcicptr->pciccrev & 0xff),
@@ -562,21 +555,52 @@ void tx4927_pci_setup(void)
               (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : "");
        if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) {
                int pciclk = 0;
-               switch ((unsigned long) tx4927_ccfgptr->
-                       ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
-               case TX4927_CCFG_PCIDIVMODE_2_5:
-                       pciclk = tx4927_cpu_clock * 2 / 5;
-                       break;
-               case TX4927_CCFG_PCIDIVMODE_3:
-                       pciclk = tx4927_cpu_clock / 3;
-                       break;
-               case TX4927_CCFG_PCIDIVMODE_5:
-                       pciclk = tx4927_cpu_clock / 5;
-                       break;
-               case TX4927_CCFG_PCIDIVMODE_6:
-                       pciclk = tx4927_cpu_clock / 6;
-                       break;
-               }
+               if (mips_machtype == MACH_TOSHIBA_RBTX4937)
+                       switch ((unsigned long) tx4927_ccfgptr->
+                               ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
+                       case TX4937_CCFG_PCIDIVMODE_4:
+                               pciclk = tx4927_cpu_clock / 4;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_4_5:
+                               pciclk = tx4927_cpu_clock * 2 / 9;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_5:
+                               pciclk = tx4927_cpu_clock / 5;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_5_5:
+                               pciclk = tx4927_cpu_clock * 2 / 11;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_8:
+                               pciclk = tx4927_cpu_clock / 8;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_9:
+                               pciclk = tx4927_cpu_clock / 9;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_10:
+                               pciclk = tx4927_cpu_clock / 10;
+                               break;
+                       case TX4937_CCFG_PCIDIVMODE_11:
+                               pciclk = tx4927_cpu_clock / 11;
+                               break;
+                       }
+
+               else
+                       switch ((unsigned long) tx4927_ccfgptr->
+                               ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+                       case TX4927_CCFG_PCIDIVMODE_2_5:
+                               pciclk = tx4927_cpu_clock * 2 / 5;
+                               break;
+                       case TX4927_CCFG_PCIDIVMODE_3:
+                               pciclk = tx4927_cpu_clock / 3;
+                               break;
+                       case TX4927_CCFG_PCIDIVMODE_5:
+                               pciclk = tx4927_cpu_clock / 5;
+                               break;
+                       case TX4927_CCFG_PCIDIVMODE_6:
+                               pciclk = tx4927_cpu_clock / 6;
+                               break;
+                       }
+
                printk("Internal(%dMHz)", pciclk / 1000000);
        } else {
                int pciclk = 0;
@@ -814,24 +838,40 @@ void __init toshiba_rbtx4927_setup(void)
                                       ":ResetRoutines\n");
        _machine_restart = toshiba_rbtx4927_restart;
        _machine_halt = toshiba_rbtx4927_halt;
-       _machine_power_off = toshiba_rbtx4927_power_off;
+       pm_power_off = toshiba_rbtx4927_power_off;
 
 #ifdef CONFIG_PCI
 
        /* PCIC */
        /*
           * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
-          * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1).
+          *
+          * For TX4927:
+          * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
           * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
           * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
           * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
           * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
           * i.e. S9[3]: ON (83MHz), OFF (100MHz)
+          *
+          * For TX4937:
+          * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
+          * PCIDIVMODE[10] is 0.
+          * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
+          * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
+          * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
+          * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
+          * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
+          * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
+          *
         */
        TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
-                                      "ccfg is %lx, DIV is %x\n",
-                                      (unsigned long) tx4927_ccfgptr->
-                                      ccfg, TX4927_CCFG_PCIDIVMODE_MASK);
+                                      "ccfg is %lx, PCIDIVMODE is %x\n",
+                                      (unsigned long) tx4927_ccfgptr->ccfg,
+                                      (unsigned long) tx4927_ccfgptr->ccfg &
+                                      (mips_machtype == MACH_TOSHIBA_RBTX4937 ?
+                                       TX4937_CCFG_PCIDIVMODE_MASK :
+                                       TX4927_CCFG_PCIDIVMODE_MASK));
 
        TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
                                       "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n",
@@ -842,20 +882,30 @@ void __init toshiba_rbtx4927_setup(void)
                                       (unsigned long) tx4927_ccfgptr->
                                       ccfg & TX4927_CCFG_PCIXARB);
 
-       TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
-                                      "PCIDIVMODE is %lx\n",
-                                      (unsigned long) tx4927_ccfgptr->
-                                      ccfg & TX4927_CCFG_PCIDIVMODE_MASK);
-
-       switch ((unsigned long) tx4927_ccfgptr->
-               ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
-       case TX4927_CCFG_PCIDIVMODE_2_5:
-       case TX4927_CCFG_PCIDIVMODE_5:
-               tx4927_cpu_clock = 166000000;   /* 166MHz */
-               break;
-       default:
-               tx4927_cpu_clock = 200000000;   /* 200MHz */
-       }
+       if (mips_machtype == MACH_TOSHIBA_RBTX4937)
+               switch ((unsigned long)tx4927_ccfgptr->
+                       ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
+               case TX4937_CCFG_PCIDIVMODE_8:
+               case TX4937_CCFG_PCIDIVMODE_4:
+                       tx4927_cpu_clock = 266666666;   /* 266MHz */
+                       break;
+               case TX4937_CCFG_PCIDIVMODE_9:
+               case TX4937_CCFG_PCIDIVMODE_4_5:
+                       tx4927_cpu_clock = 300000000;   /* 300MHz */
+                       break;
+               default:
+                       tx4927_cpu_clock = 333333333;   /* 333MHz */
+               }
+       else
+               switch ((unsigned long)tx4927_ccfgptr->
+                       ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+               case TX4927_CCFG_PCIDIVMODE_2_5:
+               case TX4927_CCFG_PCIDIVMODE_5:
+                       tx4927_cpu_clock = 166666666;   /* 166MHz */
+                       break;
+               default:
+                       tx4927_cpu_clock = 200000000;   /* 200MHz */
+               }
 
        /* CCFG */
        /* enable Timeout BusError */
index 9f1dcc8ca5a3590f73f09166540d8f28820b0839..5c7ace982a4958eb9951a3d740f1b91426a131cc 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
+
 #include <asm/wbflush.h>
 #include <asm/reboot.h>
 #include <asm/irq.h>
@@ -1003,7 +1005,7 @@ void __init toshiba_rbtx4938_setup(void)
 
        _machine_restart = rbtx4938_machine_restart;
        _machine_halt = rbtx4938_machine_halt;
-       _machine_power_off = rbtx4938_machine_power_off;
+       pm_power_off = rbtx4938_machine_power_off;
 
        *rbtx4938_led_ptr = 0xff;
        printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
index 02bf4f7d06baa02803d6694d40275e6c384d856d..5e469796413f2add994c487618647f43c805c324 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 
@@ -114,7 +115,7 @@ static int __init vr41xx_pmu_init(void)
 
        _machine_restart = vr41xx_restart;
        _machine_halt = vr41xx_halt;
-       _machine_power_off = vr41xx_power_off;
+       pm_power_off = vr41xx_power_off;
 
        return 0;
 }
index e77a06e9621ec54278ed6c440866e5e9205031c4..7c914a4c67c3e928b20f44a1acc6ffa90e05a95d 100644 (file)
@@ -149,14 +149,20 @@ config HOTPLUG_CPU
        default y if SMP
        select HOTPLUG
 
+config ARCH_SELECT_MEMORY_MODEL
+       def_bool y
+       depends on 64BIT
+
 config ARCH_DISCONTIGMEM_ENABLE
-       bool "Discontiguous memory support (EXPERIMENTAL)"
-       depends on 64BIT && EXPERIMENTAL
-       help
-         Say Y to support efficient handling of discontiguous physical memory,
-         for architectures which are either NUMA (Non-Uniform Memory Access)
-         or have huge holes in the physical address space for other reasons.
-         See <file:Documentation/vm/numa> for more.
+       def_bool y
+       depends on 64BIT
+
+config ARCH_FLATMEM_ENABLE
+       def_bool y
+
+config ARCH_DISCONTIGMEM_DEFAULT
+       def_bool y
+       depends on ARCH_DISCONTIGMEM_ENABLE
 
 source "kernel/Kconfig.hz"
 source "mm/Kconfig"
index 8caaed187a1fa11d3781a78368934d059b74e8e5..9166bd1172675c2cbadd1c80de98042005e6c30b 100644 (file)
@@ -11,4 +11,14 @@ config DEBUG_RWLOCK
           too many attempts.  If you suspect a rwlock problem or a kernel
           hacker asks for this option then say Y.  Otherwise say N.
 
+config DEBUG_RODATA
+       bool "Write protect kernel read-only data structures"
+       depends on DEBUG_KERNEL
+       help
+         Mark the kernel read-only data as write-protected in the pagetables,
+         in order to catch accidental (and incorrect) writes to such const
+         data. This option may have a slight performance impact because a
+         portion of the kernel code won't be covered by a TLB anymore.
+         If in doubt, say "N".
+
 endmenu
index 8819e7e6ae3f0fec766e0590454fe0a52e2e1d01..37e98241ce4b7a245cb5ae229e0defe5118ac5df 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc5-pa1
-# Fri Oct 21 23:06:10 2005
+# Linux kernel version: 2.6.16-rc1-pa0
+# Tue Jan 17 08:21:01 2006
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -29,8 +29,6 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT 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_INITRAMFS_SOURCE=""
@@ -38,8 +36,10 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -48,8 +48,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -57,9 +59,27 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
+#
+# Block layer
+#
+
+#
+# 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"
+
 #
 # Processor type and features
 #
@@ -77,6 +97,7 @@ CONFIG_HZ=250
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_PREEMPT is not set
 # CONFIG_HPUX is not set
 
@@ -84,8 +105,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # Bus options (PCI, PCMCIA, EISA, GSC, ISA)
 #
 CONFIG_GSC=y
-# CONFIG_HPPB is not set
-# CONFIG_IOMMU_CCIO is not set
+CONFIG_HPPB=y
+CONFIG_IOMMU_CCIO=y
 CONFIG_GSC_LASI=y
 CONFIG_GSC_WAX=y
 CONFIG_EISA=y
@@ -165,8 +186,11 @@ CONFIG_IPV6=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -205,6 +229,7 @@ CONFIG_STANDALONE=y
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
 # CONFIG_PARPORT_SERIAL is not set
+CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
 # CONFIG_PARPORT_1284 is not set
 
@@ -230,14 +255,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE 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=y
 
 #
@@ -281,6 +298,7 @@ CONFIG_SCSI_SPI_ATTRS=y
 #
 # 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
@@ -313,21 +331,19 @@ CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_ZALON is not set
+CONFIG_SCSI_ZALON=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=40
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
@@ -397,7 +413,7 @@ CONFIG_NETDEVICES=y
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-# CONFIG_LASI_82596 is not set
+CONFIG_LASI_82596=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
@@ -464,6 +480,7 @@ CONFIG_NET_RADIO=y
 # Wireless 802.11b ISA/PCI cards support
 #
 # CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
 
 #
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
@@ -527,7 +544,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_HIL_OLD is not set
-# CONFIG_KEYBOARD_HIL is not set
+CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -535,7 +552,7 @@ CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_LOGIBM is not set
 # CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_HIL is not set
+CONFIG_MOUSE_HIL=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
@@ -549,7 +566,8 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_GSCPS2=y
-# CONFIG_HP_SDC is not set
+CONFIG_HP_SDC=y
+CONFIG_HIL_MLC=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
@@ -569,6 +587,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=13
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -582,11 +601,10 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_MUX is not set
-# CONFIG_PDC_CONSOLE is not set
+CONFIG_SERIAL_MUX=y
+CONFIG_SERIAL_MUX_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -625,6 +643,12 @@ CONFIG_GEN_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -661,7 +685,6 @@ CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
@@ -671,6 +694,7 @@ CONFIG_FB_SOFT_CURSOR=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 CONFIG_FB_STI=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
@@ -683,9 +707,7 @@ CONFIG_FB_STI=y
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -695,6 +717,7 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
@@ -713,7 +736,85 @@ CONFIG_LOGO_PARISC_CLUT224=y
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# GSC devices
+#
+CONFIG_SND_HARMONY=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
@@ -722,6 +823,10 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB is not set
 
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
 #
 # USB Gadget Support
 #
@@ -877,18 +982,23 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+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 is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_IOREMAP is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_RODATA is not set
 
 #
 # Security options
index fa9bf38787e79ceed3a500d4d63f905974df349e..31c8cccfba31a7a478aff8647c36619f70921cd9 100644 (file)
 #include <linux/linkage.h>
 #include <asm/unistd.h>
 
-       .text
-
 #define ENTRY_NAME(_name_) .word _name_
 
+       .section .rodata,"a"
        .align 4
        .export hpux_call_table
        .import hpux_unimplemented_wrapper
index 29b4d61898f2ca0b76e64dda8abcbab7ac48a76e..05273ccced0e56aeb00779111fac12aa62ead419 100644 (file)
@@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
        if ( opcode == 1 ) { /* GETFSIND */     
                len = strlen_user((char *)arg1);
                printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
-               fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+               if (len == 0)
+                       return 0;
+               fsname = (char *) kmalloc(len, GFP_KERNEL);
                if ( !fsname ) {
                        printk(KERN_DEBUG "failed to kmalloc fsname\n");
                        return 0;
                }
 
-               if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+               if ( copy_from_user(fsname, (char *)arg1, len) ) {
                        printk(KERN_DEBUG "failed to copy_from_user fsname\n");
                        kfree(fsname);
                        return 0;
                }
 
+               /* String could be altered by userspace after strlen_user() */
+               fsname[len] = '\0';
+
                printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
                if ( !strcmp(fsname, "hfs") ) {
                        fstype = 0;
index 2d804e2d16d11f64d7482f3d78d36a65fbaf6689..3d569a485a1a6540735f282eb87879705fd4574c 100644 (file)
@@ -408,11 +408,10 @@ static void setup_bus_id(struct parisc_device *padev)
 
 struct parisc_device * create_tree_node(char id, struct device *parent)
 {
-       struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev)
                return NULL;
 
-       memset(dev, 0, sizeof(*dev));
        dev->hw_path = id;
        dev->id.hw_type = HPHW_FAULTY;
 
index f40a777dd388cc4d8b713e39299dba9c034ab7c2..1d00c365f2b157985861c7ec703b4556321d88d3 100644 (file)
@@ -48,9 +48,6 @@ EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strpbrk);
 
-#include <linux/pm.h>
-EXPORT_SYMBOL(pm_power_off);
-
 #include <asm/atomic.h>
 EXPORT_SYMBOL(__xchg8);
 EXPORT_SYMBOL(__xchg32);
index 88cba49c5301fe3209b890b4992731c0ae99d014..79c7db2705fd4b7b475a87af50e09cf57cc62a4a 100644 (file)
  * this makes the boot time much longer than necessary.
  * 20ms seems to work for all the HP PCI implementations to date.
  *
- * XXX: turn into a #defined constant in <asm/pci.h> ?
+ * #define pci_post_reset_delay 50
  */
-int pci_post_reset_delay = 50;
 
-struct pci_port_ops *pci_port;
-struct pci_bios_ops *pci_bios;
+struct pci_port_ops *pci_port __read_mostly;
+struct pci_bios_ops *pci_bios __read_mostly;
 
-int pci_hba_count = 0;
+static int pci_hba_count __read_mostly;
 
 /* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.  */
 #define PCI_HBA_MAX 32
-struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
+static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly;
 
 
 /********************************************************************
@@ -259,8 +258,10 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
 void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                              struct pci_bus_region *region)
 {
+#ifdef CONFIG_64BIT
        struct pci_bus *bus = dev->bus;
        struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+#endif
 
        if (res->flags & IORESOURCE_MEM) {
                res->start = PCI_HOST_ADDR(hba, region->start);
index 11d406cd0b3e73acfd348c3736d6d71a66b7970b..53f861c82f93d5d462144aa0501689152785b359 100644 (file)
@@ -68,20 +68,20 @@ struct rdr_tbl_ent {
 };
 
 static int perf_processor_interface __read_mostly = UNKNOWN_INTF;
-static int perf_enabled __read_mostly = 0;
+static int perf_enabled __read_mostly;
 static spinlock_t perf_lock;
-struct parisc_device *cpu_device __read_mostly = NULL;
+struct parisc_device *cpu_device __read_mostly;
 
 /* RDRs to write for PCX-W */
-static int perf_rdrs_W[] = 
+static const int perf_rdrs_W[] =
        { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
 
 /* RDRs to write for PCX-U */
-static int perf_rdrs_U[] =
+static const int perf_rdrs_U[] =
        { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
 
 /* RDR register descriptions for PCX-W */
-static struct rdr_tbl_ent perf_rdr_tbl_W[] = {
+static const struct rdr_tbl_ent perf_rdr_tbl_W[] = {
        { 19,   1,      8 },   /* RDR 0 */
        { 16,   1,      16 },  /* RDR 1 */
        { 72,   2,      0 },   /* RDR 2 */
@@ -117,7 +117,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_W[] = {
 };
 
 /* RDR register descriptions for PCX-U */
-static struct rdr_tbl_ent perf_rdr_tbl_U[] = {
+static const struct rdr_tbl_ent perf_rdr_tbl_U[] = {
        { 19,   1,      8 },              /* RDR 0 */
        { 32,   1,      16 },             /* RDR 1 */
        { 20,   1,      0 },              /* RDR 2 */
@@ -156,7 +156,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_U[] = {
  * A non-zero write_control in the above tables is a byte offset into
  * this array.
  */
-static uint64_t perf_bitmasks[] = {
+static const uint64_t perf_bitmasks[] = {
        0x0000000000000000ul,     /* first dbl word must be zero */
        0xfdffe00000000000ul,     /* RDR0 bitmask */
        0x003f000000000000ul,     /* RDR1 bitmask */
@@ -173,7 +173,7 @@ static uint64_t perf_bitmasks[] = {
  * Write control bitmasks for Pa-8700 processor given
  * somethings have changed slightly.
  */
-static uint64_t perf_bitmasks_piranha[] = {
+static const uint64_t perf_bitmasks_piranha[] = {
        0x0000000000000000ul,     /* first dbl word must be zero */
        0xfdffe00000000000ul,     /* RDR0 bitmask */
        0x003f000000000000ul,     /* RDR1 bitmask */
@@ -186,7 +186,7 @@ static uint64_t perf_bitmasks_piranha[] = {
        0xfffc000000000000ul
 };
 
-static uint64_t *bitmask_array;   /* array of bitmasks to use */
+static const uint64_t *bitmask_array;   /* array of bitmasks to use */
 
 /******************************************************************************
  * Function Prototypes
@@ -200,7 +200,7 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun
 static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static void perf_start_counters(void);
 static int perf_stop_counters(uint32_t *raddr);
-static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
+static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
 static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer);
 static int perf_rdr_clear(uint32_t rdr_num);
 static int perf_write_image(uint64_t *memaddr);
@@ -444,7 +444,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        uint32_t raddr[4];
        int error = 0;
 
-       lock_kernel();
        switch (cmd) {
 
            case PA_PERF_ON:
@@ -477,8 +476,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        error = -ENOTTY;
        }
 
-       unlock_kernel();
-
        return error;
 }
 
@@ -655,7 +652,7 @@ static int perf_stop_counters(uint32_t *raddr)
  * Retrieve a pointer to the description of what this
  * RDR contains.
  */
-static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
+static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
 {
        if (perf_processor_interface == ONYX_INTF) {
                return &perf_rdr_tbl_U[rdr_num];
@@ -673,7 +670,7 @@ static int perf_rdr_read_ubuf(uint32_t      rdr_num, uint64_t *buffer)
 {
        uint64_t        data, data_mask = 0;
        uint32_t        width, xbits, i;
-       struct rdr_tbl_ent *tentry;
+       const struct rdr_tbl_ent *tentry;
 
        tentry = perf_rdr_get_entry(rdr_num);
        if ((width = tentry->width) == 0)
@@ -721,7 +718,7 @@ static int perf_rdr_read_ubuf(uint32_t      rdr_num, uint64_t *buffer)
  */
 static int perf_rdr_clear(uint32_t     rdr_num)
 {
-       struct rdr_tbl_ent *tentry;
+       const struct rdr_tbl_ent *tentry;
        int32_t         i;
 
        tentry = perf_rdr_get_entry(rdr_num);
@@ -753,10 +750,11 @@ static int perf_write_image(uint64_t *memaddr)
        uint64_t buffer[MAX_RDR_WORDS];
        uint64_t *bptr;
        uint32_t dwords;
-       uint32_t *intrigue_rdr;
-       uint64_t *intrigue_bitmask, tmp64;
+       const uint32_t *intrigue_rdr;
+       const uint64_t *intrigue_bitmask;
+       uint64_t tmp64;
        void __iomem *runway;
-       struct rdr_tbl_ent *tentry;
+       const struct rdr_tbl_ent *tentry;
        int i;
 
        /* Clear out counters */
@@ -830,7 +828,7 @@ static int perf_write_image(uint64_t *memaddr)
  */
 static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer)
 {
-       struct rdr_tbl_ent *tentry;
+       const struct rdr_tbl_ent *tentry;
        int32_t         i;
 
 printk("perf_rdr_write\n");
index d9562fe3f75c1da7f5c39d014210c5f240927943..7fef9644df47bd8fd37a42b2cfcd80d23921cee7 100644 (file)
@@ -25,7 +25,7 @@
 
 #define PCXU_IMAGE_SIZE 584
 
-static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
+static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
 /*
  * CPI:
  *
@@ -2093,7 +2093,7 @@ static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
 };
 #define PCXW_IMAGE_SIZE 576
 
-static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = {
+static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
 /*
  * CPI:     FROM CPI.IDF (Image 0)
  *
index 5da41677e70bd36201d9fd729345664d4c4b6781..e8dea4177113f8a63b1e92bb369b357b816ecebe 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/unwind.h>
 
-static int hlt_counter __read_mostly;
-
-/*
- * Power off function, if any
- */ 
-void (*pm_power_off)(void);
-
-void disable_hlt(void)
-{
-       hlt_counter++;
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-       hlt_counter--;
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
 void default_idle(void)
 {
        barrier();
@@ -102,12 +81,7 @@ void cpu_idle(void)
 }
 
 
-#ifdef __LP64__
-#define COMMAND_GLOBAL  0xfffffffffffe0030UL
-#else
-#define COMMAND_GLOBAL  0xfffe0030
-#endif
-
+#define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
 #define CMD_RESET       5       /* reset any module */
 
 /*
@@ -162,6 +136,7 @@ void machine_halt(void)
        */
 }
 
+void (*chassis_power_off)(void);
 
 /*
  * This routine is called from sys_reboot to actually turn off the
@@ -170,8 +145,8 @@ void machine_halt(void)
 void machine_power_off(void)
 {
        /* If there is a registered power off handler, call it. */
-       if(pm_power_off)
-               pm_power_off();
+       if (chassis_power_off)
+               chassis_power_off();
 
        /* Put the soft power button back under hardware control.
         * If the user had already pressed the power button, the
@@ -187,6 +162,8 @@ void machine_power_off(void)
               KERN_EMERG "Please power this system off now.");
 }
 
+void (*pm_power_off)(void) = machine_power_off;
+EXPORT_SYMBOL(pm_power_off);
 
 /*
  * Create a kernel thread
index 27160e8bf15ba3f31010ab0fa978961043df2140..413292f1a4a36401fda3cc03129574b68e648f09 100644 (file)
@@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                int copied;
 
 #ifdef __LP64__
-               if (is_compat_task(child)) {
+               if (personality(child->personality) == PER_LINUX32) {
                        unsigned int tmp;
 
                        addr &= 0xffffffffL;
@@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        case PTRACE_POKEDATA:
                ret = 0;
 #ifdef __LP64__
-               if (is_compat_task(child)) {
+               if (personality(child->personality) == PER_LINUX32) {
                        unsigned int tmp = (unsigned int)data;
                        DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
                                request == PTRACE_POKETEXT ? "TEXT" : "DATA",
@@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        case PTRACE_PEEKUSR: {
                ret = -EIO;
 #ifdef __LP64__
-               if (is_compat_task(child)) {
+               if (personality(child->personality) == PER_LINUX32) {
                        unsigned int tmp;
 
                        if (addr & (sizeof(int)-1))
@@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        goto out_tsk;
                }
 #ifdef __LP64__
-               if (is_compat_task(child)) {
+               if (personality(child->personality) == PER_LINUX32) {
                        if (addr & (sizeof(int)-1))
                                goto out_tsk;
                        if ((addr = translate_usr_offset(addr)) < 0)
index 3a25a7bd673ece4e11eccfba23a1a63ffb644df1..05767e83cf2dd38f3aaacebd9e61e56349d0088c 100644 (file)
@@ -317,7 +317,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        
        if(personality(current->personality) == PER_LINUX32) {
                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
-               err |= compat_copy_siginfo_to_user(&compat_frame->info, info);
+               err |= copy_siginfo_to_user32(&compat_frame->info, info);
                DBG(1,"SETUP_RT_FRAME: 1\n");
                compat_val = (compat_int_t)current->sas_ss_sp;
                err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
index 0792e20efef383e5002c3a0a151efa4f020c4bce..a6b4231cafa10ece6e0595f3e06f144cdc20b0dd 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 
-#include <asm/compat_signal.h>
 #include <asm/uaccess.h>
 
 #include "signal32.h"
@@ -398,3 +397,104 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __
 
        return err;
 }
+
+int
+copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
+{
+       unsigned long tmp;
+       int err;
+
+       if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
+               return -EFAULT;
+
+       err = __get_user(to->si_signo, &from->si_signo);
+       err |= __get_user(to->si_errno, &from->si_errno);
+       err |= __get_user(to->si_code, &from->si_code);
+
+       if (to->si_code < 0)
+               err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+       else {
+               switch (to->si_code >> 16) {
+                     case __SI_CHLD >> 16:
+                       err |= __get_user(to->si_utime, &from->si_utime);
+                       err |= __get_user(to->si_stime, &from->si_stime);
+                       err |= __get_user(to->si_status, &from->si_status);
+                     default:
+                       err |= __get_user(to->si_pid, &from->si_pid);
+                       err |= __get_user(to->si_uid, &from->si_uid);
+                       break;
+                     case __SI_FAULT >> 16:
+                       err |= __get_user(tmp, &from->si_addr);
+                       to->si_addr = (void __user *) tmp;
+                       break;
+                     case __SI_POLL >> 16:
+                       err |= __get_user(to->si_band, &from->si_band);
+                       err |= __get_user(to->si_fd, &from->si_fd);
+                       break;
+                     case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
+                     case __SI_MESGQ >> 16:
+                       err |= __get_user(to->si_pid, &from->si_pid);
+                       err |= __get_user(to->si_uid, &from->si_uid);
+                       err |= __get_user(to->si_int, &from->si_int);
+                       break;
+               }
+       }
+       return err;
+}
+
+int
+copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
+{
+       unsigned int addr;
+       int err;
+
+       if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
+               return -EFAULT;
+
+       /* If you change siginfo_t structure, please be sure
+          this code is fixed accordingly.
+          It should never copy any pad contained in the structure
+          to avoid security leaks, but must copy the generic
+          3 ints plus the relevant union member.
+          This routine must convert siginfo from 64bit to 32bit as well
+          at the same time.  */
+       err = __put_user(from->si_signo, &to->si_signo);
+       err |= __put_user(from->si_errno, &to->si_errno);
+       err |= __put_user((short)from->si_code, &to->si_code);
+       if (from->si_code < 0)
+               err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+       else {
+               switch (from->si_code >> 16) {
+               case __SI_CHLD >> 16:
+                       err |= __put_user(from->si_utime, &to->si_utime);
+                       err |= __put_user(from->si_stime, &to->si_stime);
+                       err |= __put_user(from->si_status, &to->si_status);
+               default:
+                       err |= __put_user(from->si_pid, &to->si_pid);
+                       err |= __put_user(from->si_uid, &to->si_uid);
+                       break;
+               case __SI_FAULT >> 16:
+                       /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
+                       err |= __put_user(from->_sifields._pad[0], &to->si_addr);
+                       break;
+               case __SI_POLL >> 16:
+                       err |= __put_user(from->si_band, &to->si_band);
+                       err |= __put_user(from->si_fd, &to->si_fd);
+                       break;
+               case __SI_TIMER >> 16:
+                       err |= __put_user(from->si_tid, &to->si_tid);
+                       err |= __put_user(from->si_overrun, &to->si_overrun);
+                       addr = (unsigned long) from->si_ptr;
+                       err |= __put_user(addr, &to->si_ptr);
+                       break;
+               case __SI_RT >> 16:     /* Not generated by the kernel as of now.  */
+               case __SI_MESGQ >> 16:
+                       err |= __put_user(from->si_uid, &to->si_uid);
+                       err |= __put_user(from->si_pid, &to->si_pid);
+                       addr = (unsigned long) from->si_ptr;
+                       err |= __put_user(addr, &to->si_ptr);
+                       break;
+               }
+       }
+       return err;
+}
index 4d1569e717cc9dc08344b118bc6f4461be250c63..e39b38a67a87273cb2217143deadd37a8b56ce8e 100644 (file)
 #define _PARISC64_KERNEL_SIGNAL32_H
 
 #include <linux/compat.h>
-#include <asm/compat_signal.h>
-#include <asm/compat_rt_sigframe.h>
+
+typedef compat_uptr_t compat_sighandler_t;
+
+typedef struct compat_sigaltstack {
+        compat_uptr_t ss_sp;
+        compat_int_t ss_flags;
+        compat_size_t ss_size;
+} compat_stack_t;
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+struct compat_sigaction {
+        compat_sighandler_t sa_handler;
+        compat_uint_t sa_flags;
+        compat_sigset_t sa_mask;               /* mask last for extensibility */
+};
+
+/* 32-bit ucontext as seen from an 64-bit kernel */
+struct compat_ucontext {
+        compat_uint_t uc_flags;
+        compat_uptr_t uc_link;
+        compat_stack_t uc_stack;        /* struct compat_sigaltstack (12 bytes)*/
+        /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */
+        compat_uint_t pad[1];
+        struct compat_sigcontext uc_mcontext;
+        compat_sigset_t uc_sigmask;     /* mask last for extensibility */
+};
 
 /* ELF32 signal handling */
 
@@ -29,6 +55,103 @@ struct k_sigaction32 {
        struct compat_sigaction sa;
 };
 
+typedef struct compat_siginfo {
+        int si_signo;
+        int si_errno;
+        int si_code;
+
+        union {
+                int _pad[((128/sizeof(int)) - 3)];
+
+                /* kill() */
+                struct {
+                        unsigned int _pid;      /* sender's pid */
+                        unsigned int _uid;      /* sender's uid */
+                } _kill;
+
+                /* POSIX.1b timers */
+                struct {
+                        compat_timer_t _tid;            /* timer id */
+                        int _overrun;           /* overrun count */
+                        char _pad[sizeof(unsigned int) - sizeof(int)];
+                        compat_sigval_t _sigval;        /* same as below */
+                        int _sys_private;       /* not to be passed to user */
+                } _timer;
+
+                /* POSIX.1b signals */
+                struct {
+                        unsigned int _pid;      /* sender's pid */
+                        unsigned int _uid;      /* sender's uid */
+                        compat_sigval_t _sigval;
+                } _rt;
+
+                /* SIGCHLD */
+                struct {
+                        unsigned int _pid;      /* which child */
+                        unsigned int _uid;      /* sender's uid */
+                        int _status;            /* exit code */
+                        compat_clock_t _utime;
+                        compat_clock_t _stime;
+                } _sigchld;
+
+                /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+                struct {
+                        unsigned int _addr;     /* faulting insn/memory ref. */
+                } _sigfault;
+
+                /* SIGPOLL */
+                struct {
+                        int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
+                        int _fd;
+                } _sigpoll;
+        } _sifields;
+} compat_siginfo_t;
+
+int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from);
+int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from);
+
+/* In a deft move of uber-hackery, we decide to carry the top half of all
+ * 64-bit registers in a non-portable, non-ABI, hidden structure.
+ * Userspace can read the hidden structure if it *wants* but is never
+ * guaranteed to be in the same place. Infact the uc_sigmask from the
+ * ucontext_t structure may push the hidden register file downards
+ */
+struct compat_regfile {
+        /* Upper half of all the 64-bit registers that were truncated
+           on a copy to a 32-bit userspace */
+        compat_int_t rf_gr[32];
+        compat_int_t rf_iasq[2];
+        compat_int_t rf_iaoq[2];
+        compat_int_t rf_sar;
+};
+
+#define COMPAT_SIGRETURN_TRAMP 4
+#define COMPAT_SIGRESTARTBLOCK_TRAMP 5
+#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
+                               COMPAT_SIGRESTARTBLOCK_TRAMP)
+
+struct compat_rt_sigframe {
+        /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c
+                Secondary to that it must protect the ERESTART_RESTARTBLOCK
+                trampoline we left on the stack (we were bad and didn't
+                change sp so we could run really fast.) */
+        compat_uint_t tramp[COMPAT_TRAMP_SIZE];
+        compat_siginfo_t info;
+        struct compat_ucontext uc;
+        /* Hidden location of truncated registers, *must* be last. */
+        struct compat_regfile regs;
+};
+
+/*
+ * The 32-bit ABI wants at least 48 bytes for a function call frame:
+ * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of
+ * which Linux/parisc uses is sp-20 for the saved return pointer...)
+ * Then, the stack pointer must be rounded to a cache line (64 bytes).
+ */
+#define SIGFRAME32              64
+#define FUNCTIONCALLFRAME32     48
+#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
+
 void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
 void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
 int do_sigaltstack32 (const compat_stack_t __user *uss32, 
index d66163492890203d86a51523f8cab035873d2d13..af88afef41bdc029d446e43038d3dd4578b7b18e 100644 (file)
@@ -650,6 +650,8 @@ end_linux_gateway_page:
 #define LWS_ENTRY(_name_) .word  (lws_##_name_ - linux_gateway_page)
 #endif
 
+       .section .rodata,"a"
+
        .align 4096
        /* Light-weight-syscall table */
        /* Start of lws table. */
index 32cbc04893241797cda2603b8f2d57d2394655af..51d2480627d1847d32926008df85f6c741ff931f 100644 (file)
        ENTRY_SAME(keyctl)
        ENTRY_SAME(ioprio_set)
        ENTRY_SAME(ioprio_get)
+       ENTRY_SAME(inotify_init)
+       ENTRY_SAME(inotify_add_watch)   /* 270 */
+       ENTRY_SAME(inotify_rm_watch)
+       ENTRY_COMP(pselect6)
+       ENTRY_COMP(ppoll)
+       ENTRY_SAME(migrate_pages)
+       ENTRY_COMP(openat)              /* 275 */
+       ENTRY_SAME(mkdirat)
+       ENTRY_SAME(mknodat)
+       ENTRY_SAME(fchownat)
+       ENTRY_COMP(futimesat)
+       ENTRY_COMP(newfstatat)          /* 280 */
+       ENTRY_SAME(unlinkat)
+       ENTRY_SAME(renameat)
+       ENTRY_SAME(linkat)
+       ENTRY_SAME(symlinkat)
+       ENTRY_SAME(readlinkat)          /* 285 */
+       ENTRY_SAME(fchmodat)
+       ENTRY_SAME(faccessat)
        /* Nothing yet */
 
index 15914f0235a05d34e320309ca1f7cb60c77fcd6b..ff200608c851d5ef948908ff8b1b38f6fe2e56f2 100644 (file)
@@ -193,10 +193,9 @@ void show_stack(struct task_struct *task, unsigned long *s)
 
 HERE:
                asm volatile ("copy %%r30, %0" : "=r"(sp));
-               r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
+               r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL);
                if (!r)
                        return;
-               memset(r, 0, sizeof(struct pt_regs));
                r->iaoq[0] = (unsigned long)&&HERE;
                r->gr[2] = (unsigned long)__builtin_return_address(0);
                r->gr[30] = sp;
index f84f2586672b97441fa6fa30b414bb04581132ea..66c8a9f6a27eba49f17798873e97419a6104c282 100644 (file)
@@ -337,6 +337,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[])
                }
                break;
          case INVALIDEXCEPTION:
+         case OPC_2E_INVALIDEXCEPTION:
                update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
                return SIGNALCODE(SIGFPE, FPE_FLTINV);
          case DIVISIONBYZEROEXCEPTION:
index 720287d46e55616891a9aa8245db2e50efc6d1cd..7847ca13d6c2933b2be345e8d73a9ffd3d1229db 100644 (file)
@@ -371,17 +371,11 @@ static void __init setup_bootmem(void)
 
 void free_initmem(void)
 {
-       /* FIXME: */
-#if 0
-       printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n",
-                       (&__init_end - &__init_begin) >> 10);
-       return;
-#else
        unsigned long addr;
        
        printk(KERN_INFO "Freeing unused kernel memory: ");
 
-#if 1
+#ifdef CONFIG_DEBUG_KERNEL
        /* Attempt to catch anyone trying to execute code here
         * by filling the page with BRK insns.
         * 
@@ -414,9 +408,21 @@ void free_initmem(void)
        pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
        
        printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10);
-#endif
 }
 
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void)
+{
+       extern char __start_rodata, __end_rodata;
+       /* rodata memory was already mapped with KERNEL_RO access rights by
+           pagetable_init() and map_pages(). No need to do additional stuff here */
+       printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+               (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
+}
+#endif
+
+
 /*
  * Just an arbitrary offset to serve as a "hole" between mapping areas
  * (between top of physical memory and a potential pcxl dma mapping
@@ -477,11 +483,6 @@ void __init mem_init(void)
 
 }
 
-int do_check_pgt_cache(int low, int high)
-{
-       return 0;
-}
-
 unsigned long *empty_zero_page __read_mostly;
 
 void show_mem(void)
@@ -690,7 +691,7 @@ static void __init pagetable_init(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_end && initrd_end > mem_limit) {
-               printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
+               printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
                map_pages(initrd_start, __pa(initrd_start),
                        initrd_end - initrd_start, PAGE_KERNEL);
        }
@@ -792,8 +793,6 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
 EXPORT_SYMBOL(map_hpux_gateway_page);
 #endif
 
-extern void flush_tlb_all_local(void);
-
 void __init paging_init(void)
 {
        int i;
@@ -802,7 +801,7 @@ void __init paging_init(void)
        pagetable_init();
        gateway_init();
        flush_cache_all_local(); /* start with known state */
-       flush_tlb_all_local();
+       flush_tlb_all_local(NULL);
 
        for (i = 0; i < npmem_ranges; i++) {
                unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
@@ -993,7 +992,7 @@ void flush_tlb_all(void)
            do_recycle++;
        }
        spin_unlock(&sid_lock);
-       on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
+       on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
        if (do_recycle) {
            spin_lock(&sid_lock);
            recycle_sids(recycle_ndirty,recycle_dirty_array);
index e4362dfa37fba2e1971167c23d1a6c613152062e..340730fb8c9110608c8a47b5eb35724170e10d69 100644 (file)
@@ -66,7 +66,7 @@ _GLOBAL(load_up_fpu)
 #else
        ld      r4,PACACURRENT(r13)
        addi    r5,r4,THREAD            /* Get THREAD */
-       l     r4,THREAD_FPEXC_MODE(r5)
+       lwz     r4,THREAD_FPEXC_MODE(r5)
        ori     r12,r12,MSR_FP
        or      r12,r12,r4
        std     r12,_MSR(r1)
index 3082684663428bffc0483a1995dc78b69cc3cc7d..41565962939473dd96d5b4404dfdaca456cbd69f 100644 (file)
@@ -749,11 +749,12 @@ iSeries_secondary_smp_loop:
 
        .globl decrementer_iSeries_masked
 decrementer_iSeries_masked:
+       /* We may not have a valid TOC pointer in here. */
        li      r11,1
        ld      r12,PACALPPACAPTR(r13)
        stb     r11,LPPACADECRINT(r12)
-       LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
-       lwz     r12,ADDROFF(tb_ticks_per_jiffy)(r12)
+       LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
+       lwz     r12,0(r12)
        mtspr   SPRN_DEC,r12
        /* fall through */
 
index 4d9b4388918ba5f52f91c7e6b5efa26ec79a0db2..946f3219fd29fc2b79c789cd423e9ecd129db154 100644 (file)
@@ -334,9 +334,6 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 
        spin_unlock_irqrestore(&(tbl->it_lock), flags);
 
-       /* Make sure updates are seen by hardware */
-       mb();
-
        DBG("mapped %d elements:\n", outcount);
 
        /* For the sake of iommu_unmap_sg, we clear out the length in the
@@ -347,6 +344,10 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                outs->dma_address = DMA_ERROR_CODE;
                outs->dma_length = 0;
        }
+
+       /* Make sure updates are seen by hardware */
+       mb();
+
        return outcount;
 
  failure:
@@ -358,6 +359,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                        npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
                                >> PAGE_SHIFT;
                        __iommu_free(tbl, vaddr, npages);
+                       s->dma_address = DMA_ERROR_CODE;
+                       s->dma_length = 0;
                }
        }
        spin_unlock_irqrestore(&(tbl->it_lock), flags);
index d50c8df0183e524283ea966ccc728b4b1025676e..294832a7e0a6598c7eb92093ff60216941f2203f 100644 (file)
@@ -491,7 +491,12 @@ void __init finish_device_tree(void)
        size = 16;
        finish_node(allnodes, &size, 1);
        size -= 16;
-       end = start = (unsigned long) __va(lmb_alloc(size, 128));
+
+       if (0 == size)
+               end = start = 0;
+       else
+               end = start = (unsigned long)__va(lmb_alloc(size, 128));
+
        finish_node(allnodes, &end, 0);
        BUG_ON(end != start + size);
 
@@ -1398,8 +1403,8 @@ struct device_node *of_find_node_by_name(struct device_node *from,
 
        read_lock(&devtree_lock);
        np = from ? from->allnext : allnodes;
-       for (; np != 0; np = np->allnext)
-               if (np->name != 0 && strcasecmp(np->name, name) == 0
+       for (; np != NULL; np = np->allnext)
+               if (np->name != NULL && strcasecmp(np->name, name) == 0
                    && of_node_get(np))
                        break;
        if (from)
@@ -1917,3 +1922,30 @@ int prom_update_property(struct device_node *np,
 
        return 0;
 }
+
+#ifdef CONFIG_KEXEC
+/* We may have allocated the flat device tree inside the crash kernel region
+ * in prom_init. If so we need to move it out into regular memory. */
+void kdump_move_device_tree(void)
+{
+       unsigned long start, end;
+       struct boot_param_header *new;
+
+       start = __pa((unsigned long)initial_boot_params);
+       end = start + initial_boot_params->totalsize;
+
+       if (end < crashk_res.start || start > crashk_res.end)
+               return;
+
+       new = (struct boot_param_header*)
+               __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
+
+       memcpy(new, initial_boot_params, initial_boot_params->totalsize);
+
+       initial_boot_params = new;
+
+       DBG("Flat device tree blob moved to %p\n", initial_boot_params);
+
+       /* XXX should we unreserve the old DT? */
+}
+#endif /* CONFIG_KEXEC */
index 7881ec96ef117ff3a02580c95c236771e0593a73..ec7153f4d47c2b6d6d0bcef7c241bc15692e2b18 100644 (file)
@@ -2098,6 +2098,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        prom_init_stdout();
 
+       /* Bail if this is a kdump kernel. */
+       if (PHYSICAL_START > 0)
+               prom_panic("Error: You can't boot a kdump kernel from OF!\n");
+
        /*
         * Check for an initrd
         */
index a8099c806150618e34dab60d7f7df036aa9eed29..3934c227549b07a1f08ba59c86ac497ce6c0a45f 100644 (file)
@@ -465,8 +465,10 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
        if (parent == NULL)
                return NULL;
        bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci"))
+       if (strcmp(bus->name, "pci")) {
+               of_node_put(parent);
                return NULL;
+       }
        bus->count_cells(dev, &na, &ns);
        of_node_put(parent);
        if (!OF_CHECK_COUNTS(na, ns))
index 7fe4a5c944c9655e60c126ce1dabe0fe9027d0fb..b5b2add7ad1ef26d374a14a01f55d3ef3c4990cd 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
+#include <asm/hvcall.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
 #include <asm/page.h>
@@ -565,6 +566,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
 #ifdef CONFIG_PPC_PSERIES
 static void rtas_percpu_suspend_me(void *info)
 {
+       int i;
        long rc;
        long flags;
        struct rtas_suspend_me_data *data =
@@ -587,18 +589,16 @@ static void rtas_percpu_suspend_me(void *info)
 
        if (rc == H_Continue) {
                data->waiting = 0;
-               rtas_call(ibm_suspend_me_token, 0, 1,
-                         data->args->args);
+               data->args->args[data->args->nargs] =
+                       rtas_call(ibm_suspend_me_token, 0, 1, NULL);
+               for_each_cpu(i)
+                       plpar_hcall_norets(H_PROD,i);
        } else {
                data->waiting = -EBUSY;
                printk(KERN_ERR "Error on H_Join hypervisor call\n");
        }
 
 out:
-       /* before we restore interrupts, make sure we don't
-        * generate a spurious soft lockup errors
-        */
-       touch_softlockup_watchdog();
        local_irq_restore(flags);
        return;
 }
index 50500093c97f686995039f6826b9569f535a3506..aaf384c3f04a62eca2bbe497bdfd0b80e905b265 100644 (file)
@@ -672,8 +672,7 @@ static void rtas_flash_firmware(int reboot_type)
 static void remove_flash_pde(struct proc_dir_entry *dp)
 {
        if (dp) {
-               if (dp->data != NULL)
-                       kfree(dp->data);
+               kfree(dp->data);
                dp->owner = NULL;
                remove_proc_entry(dp->name, dp->parent);
        }
index e29b275e09e01a9400f12d99f9322b81ed845ef2..a717dff695ef28f09302c1690b13c921ac09dc02 100644 (file)
@@ -398,6 +398,9 @@ void __init setup_system(void)
 {
        DBG(" -> setup_system()\n");
 
+#ifdef CONFIG_KEXEC
+       kdump_move_device_tree();
+#endif
        /*
         * Unflatten the device-tree passed by prom_init or kexec
         */
index c6d0595da6b5d74755d2eb8be8804672c862eae7..bd837b5dbf06cd5992ca4129bead41135f13b040 100644 (file)
@@ -142,11 +142,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
        return 0;
 }
 
-static inline compat_uptr_t to_user_ptr(void *kp)
-{
-       return (compat_uptr_t)(u64)kp;
-}
-
+#define to_user_ptr(p)         ptr_to_compat(p)
 #define from_user_ptr(p)       compat_ptr(p)
 
 static inline int save_general_regs(struct pt_regs *regs,
@@ -213,8 +209,8 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
        return 0;
 }
 
-#define to_user_ptr(p)         (p)
-#define from_user_ptr(p)       (p)
+#define to_user_ptr(p)         ((unsigned long)(p))
+#define from_user_ptr(p)       ((void __user *)(p))
 
 static inline int save_general_regs(struct pt_regs *regs,
                struct mcontext __user *frame)
@@ -526,7 +522,7 @@ long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
 
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
        if (!ret && oact) {
-               ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+               ret = put_user(to_user_ptr(old_ka.sa.sa_handler), &oact->sa_handler);
                ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
                ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
        }
@@ -675,8 +671,8 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo
 int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
                      int r6, int r7, int r8, struct pt_regs *regs)
 {
-       stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
-       stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
+       stack_32_t __user * newstack = compat_ptr(__new);
+       stack_32_t __user * oldstack = compat_ptr(__old);
        stack_t uss, uoss;
        int ret;
        mm_segment_t old_fs;
@@ -708,7 +704,7 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
        set_fs(old_fs);
        /* Copy the stack information to the user output buffer */
        if (!ret && oldstack  &&
-               (put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
+               (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) ||
                 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
                 __put_user(uoss.ss_size, &oldstack->ss_size)))
                return -EFAULT;
index b3193116e686c7047db7f76f085776064f625591..497a5d3df359e5911b61110632b79ee540ff3095 100644 (file)
@@ -60,8 +60,8 @@ struct rt_sigframe {
        struct ucontext uc;
        unsigned long _unused[2];
        unsigned int tramp[TRAMP_SIZE];
-       struct siginfo *pinfo;
-       void *puc;
+       struct siginfo __user *pinfo;
+       void __user *puc;
        struct siginfo info;
        /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
        char abigap[288];
index c8458c531b255f3dbb97b94b5023ead71b6f5193..13595a64f013a2c1b31f2ce0d7cf86be2b1c3ae9 100644 (file)
@@ -540,6 +540,9 @@ int __devinit start_secondary(void *unused)
        if (smp_ops->take_timebase)
                smp_ops->take_timebase();
 
+       if (system_state > SYSTEM_BOOTING)
+               per_cpu(last_jiffy, cpu) = get_tb();
+
        spin_lock(&call_lock);
        cpu_set(cpu, cpu_online_map);
        spin_unlock(&call_lock);
index c4a294d657b92c23eee484902e6a963e4e0f3ab5..1886045a2fd8f8744f743fa9a88d5c8011f74af5 100644 (file)
@@ -612,10 +612,10 @@ void __init generic_calibrate_decr(void)
 
        ppc_tb_freq = DEFAULT_TB_FREQ;          /* hardcoded default */
        node_found = 0;
-       if (cpu != 0) {
+       if (cpu) {
                fp = (unsigned int *)get_property(cpu, "timebase-frequency",
                                                  NULL);
-               if (fp != 0) {
+               if (fp) {
                        node_found = 1;
                        ppc_tb_freq = *fp;
                }
@@ -626,10 +626,10 @@ void __init generic_calibrate_decr(void)
 
        ppc_proc_freq = DEFAULT_PROC_FREQ;
        node_found = 0;
-       if (cpu != 0) {
+       if (cpu) {
                fp = (unsigned int *)get_property(cpu, "clock-frequency",
                                                  NULL);
-               if (fp != 0) {
+               if (fp) {
                        node_found = 1;
                        ppc_proc_freq = *fp;
                }
index 2da65a9c93f636df3004ee6047a302cabcef09f0..5d29dcca523c113e62e9a6332552c145fbe01270 100644 (file)
@@ -144,7 +144,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
 }
 
 #ifdef CONFIG_PPC_MAPLE
-void udbg_maple_real_putc(unsigned char c)
+void udbg_maple_real_putc(char c)
 {
        if (udbg_comport) {
                while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
index 9584608fd7688a4b0a8200cc4224f8c9a2a03a14..bbe3eac918e8001338aa84ba2ede420ec2478b20 100644 (file)
@@ -197,6 +197,8 @@ long __init lmb_reserve(unsigned long base, unsigned long size)
 {
        struct lmb_region *_rgn = &(lmb.reserved);
 
+       BUG_ON(0 == size);
+
        return lmb_add_region(_rgn, base, size);
 }
 
@@ -227,6 +229,8 @@ unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
        long i, j;
        unsigned long base = 0;
 
+       BUG_ON(0 == size);
+
 #ifdef CONFIG_PPC32
        /* On 32-bit, make sure we allocate lowmem */
        if (max_addr == LMB_ALLOC_ANYWHERE)
index 15aac0d78dfa7bd9c1a7de3ab6c4f15fdefe2e9a..550517c2dd42babc88c7064763556b5851467dd4 100644 (file)
@@ -435,17 +435,12 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
        clear_page(page);
 
-       if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-               return;
        /*
         * We shouldnt have to do this, but some versions of glibc
         * require it (ld.so assumes zero filled pages are icache clean)
         * - Anton
         */
-
-       /* avoid an atomic op if possible */
-       if (test_bit(PG_arch_1, &pg->flags))
-               clear_bit(PG_arch_1, &pg->flags);
+       flush_dcache_page(pg);
 }
 EXPORT_SYMBOL(clear_user_page);
 
@@ -469,12 +464,7 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
                return;
 #endif
 
-       if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-               return;
-
-       /* avoid an atomic op if possible */
-       if (test_bit(PG_arch_1, &pg->flags))
-               clear_bit(PG_arch_1, &pg->flags);
+       flush_dcache_page(pg);
 }
 
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
index 16031b565be4d2c0c7ba91fba9404dbc297e15bc..3b998a393e3f762d2b2cc4ccca54f9355519330f 100644 (file)
@@ -2,7 +2,7 @@ obj-y                   += interrupt.o iommu.o setup.o spider-pic.o
 obj-y                  += pervasive.o
 
 obj-$(CONFIG_SMP)      += smp.o
-obj-$(CONFIG_SPU_FS)   += spufs/ spu-base.o
+obj-$(CONFIG_SPU_FS)   += spu-base.o spufs/
 
 spu-base-y             += spu_base.o spu_priv1.o
 
index 3a2057fa314a67af49204112e0a8dd7c70eecd40..814f54742e0f73295cd96da171b34ea611e215d1 100644 (file)
@@ -5,7 +5,6 @@
 extern void chrp_nvram_init(void);
 extern void chrp_get_rtc_time(struct rtc_time *);
 extern int chrp_set_rtc_time(struct rtc_time *);
-extern void chrp_calibrate_decr(void);
 extern long chrp_time_init(void);
 
 extern void chrp_find_bridges(void);
index 00c52f27ef4f87f3d445eee09c6cd8d8fb916c3c..8ef279ad36ad15ddbd5500835b1580fb04134955 100644 (file)
@@ -204,9 +204,11 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
        struct device_node *root = find_path_device("/");
        struct device_node *rtas;
 
+       of_node_get(root);
        rtas = of_find_node_by_name (root, "rtas");
        if (rtas) {
                hose->ops = &rtas_pci_ops;
+               of_node_put(rtas);
        } else {
                printk ("RTAS supporting Pegasos OF not found, please upgrade"
                        " your firmware\n");
index 2dc87aa5962fe8e1b264506bc7f00fef59897bd6..e1fadbf49150d333b780ef3b2b6f757fd6db020c 100644 (file)
@@ -506,7 +506,7 @@ void __init chrp_init(void)
        ppc_md.halt           = rtas_halt;
 
        ppc_md.time_init      = chrp_time_init;
-       ppc_md.calibrate_decr = chrp_calibrate_decr;
+       ppc_md.calibrate_decr = generic_calibrate_decr;
 
        /* this may get overridden with rtas routines later... */
        ppc_md.set_rtc_time   = chrp_set_rtc_time;
index 36a0f97bb7b13143dee6bf88cf1818bbb95f446f..78df2e7ca88a1c9d5edc76e54ad7f9102420dd2e 100644 (file)
@@ -167,24 +167,3 @@ void chrp_get_rtc_time(struct rtc_time *tm)
        tm->tm_mon = mon;
        tm->tm_year = year;
 }
-
-
-void __init chrp_calibrate_decr(void)
-{
-       struct device_node *cpu;
-       unsigned int freq, *fp;
-
-       /*
-        * The cpu node should have a timebase-frequency property
-        * to tell us the rate at which the decrementer counts.
-        */
-       freq = 16666000;                /* hardcoded default */
-       cpu = find_type_devices("cpu");
-       if (cpu != 0) {
-               fp = (unsigned int *)
-                       get_property(cpu, "timebase-frequency", NULL);
-               if (fp != 0)
-                       freq = *fp;
-       }
-       ppc_tb_freq = freq;
-}
index 535c802b369fbe945dd8de334e86a910aaffb1f4..87eb6bb7f0e72a406baf9d129476d4e2cd4c5f6c 100644 (file)
@@ -1052,8 +1052,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus);
 
-extern int pmac_i2c_match_adapter(struct device_node *dev,
-                                 struct i2c_adapter *adapter)
+int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
 {
        struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev);
 
index f671ed2539013ed8f7299f4c2bb974489dc697c2..de3f30e6b3330d8287cb3499213342c049aea17d 100644 (file)
@@ -136,14 +136,14 @@ static void __init fixup_bus_range(struct device_node *bridge)
        |(((unsigned int)(off)) & 0xFCUL) \
        |1UL)
 
-static unsigned long macrisc_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
                                               u8 bus, u8 dev_fn, u8 offset)
 {
        unsigned int caddr;
 
        if (bus == hose->first_busno) {
                if (dev_fn < (11 << 3))
-                       return 0;
+                       return NULL;
                caddr = MACRISC_CFA0(dev_fn, offset);
        } else
                caddr = MACRISC_CFA1(bus, dev_fn, offset);
@@ -154,14 +154,14 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose,
        } while (in_le32(hose->cfg_addr) != caddr);
 
        offset &= has_uninorth ? 0x07 : 0x03;
-       return ((unsigned long)hose->cfg_data) + offset;
+       return hose->cfg_data + offset;
 }
 
 static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
                                      int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -177,13 +177,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -193,7 +193,7 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
                                       int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -209,16 +209,16 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -348,25 +348,23 @@ static int u3_ht_skip_device(struct pci_controller *hose,
                + (((unsigned int)bus) << 16) \
                + 0x01000000UL)
 
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
                                             u8 bus, u8 devfn, u8 offset)
 {
        if (bus == hose->first_busno) {
                /* For now, we don't self probe U3 HT bridge */
                if (PCI_SLOT(devfn) == 0)
-                       return 0;
-               return ((unsigned long)hose->cfg_data) +
-                       U3_HT_CFA0(devfn, offset);
+                       return NULL;
+               return hose->cfg_data + U3_HT_CFA0(devfn, offset);
        } else
-               return ((unsigned long)hose->cfg_data) +
-                       U3_HT_CFA1(bus, devfn, offset);
+               return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
 }
 
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -400,13 +398,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -416,7 +414,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -442,16 +440,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32((u32 __iomem *)addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -476,7 +474,7 @@ static struct pci_ops u3_ht_pci_ops =
         |(((unsigned int)(off)) & 0xfcU)       \
         |1UL)
 
-static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
                                        u8 bus, u8 dev_fn, int offset)
 {
        unsigned int caddr;
@@ -492,14 +490,14 @@ static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
        } while (in_le32(hose->cfg_addr) != caddr);
 
        offset &= 0x03;
-       return ((unsigned long)hose->cfg_data) + offset;
+       return hose->cfg_data + offset;
 }
 
 static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
                               int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -515,13 +513,13 @@ static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -531,7 +529,7 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -547,16 +545,16 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -773,8 +771,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
         * the reg address cell, we shall fix that by killing struct
         * reg_property and using some accessor functions instead
         */
-       hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
-                                                          0x02000000);
+       hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
        /*
         * /ht node doesn't expose a "ranges" property, so we "remove"
index 89c4c36361610749e401f5cb1cf96712a70ba4ad..1955462f4082fa01cb19785dd5b60a5c00cf592f 100644 (file)
@@ -82,8 +82,6 @@
 
 #undef SHOW_GATWICK_IRQS
 
-unsigned char drive_info;
-
 int ppc_override_l2cr = 0;
 int ppc_override_l2cr_value;
 int has_l2cache = 0;
index 6373372932ba16b2253ea252207c93684cc46f81..e3cbba49fd6e83466be3074294e543ccc576e768 100644 (file)
@@ -333,7 +333,7 @@ void handle_eeh_events (struct eeh_event *event)
                rc = eeh_reset_device(frozen_pdn, NULL);
                if (rc)
                        goto hard_fail;
-               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+               pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
        }
 
        /* If all devices reported they can proceed, the re-enable PIO */
@@ -342,11 +342,11 @@ void handle_eeh_events (struct eeh_event *event)
                rc = eeh_reset_device(frozen_pdn, NULL);
                if (rc)
                        goto hard_fail;
-               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+               pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
        }
 
        /* Tell all device drivers that they can resume operations */
-       pci_walk_bus(frozen_bus, eeh_report_resume, 0);
+       pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
 
        return;
        
@@ -367,7 +367,7 @@ hard_fail:
        eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
 
        /* Notify all devices that they're about to go down. */
-       pci_walk_bus(frozen_bus, eeh_report_failure, 0);
+       pci_walk_bus(frozen_bus, eeh_report_failure, NULL);
 
        /* Shut down the device drivers for good. */
        pcibios_remove_pci_devices(frozen_bus);
index da6cebaf72cda275fc1b9bb7613b7fe3efa97cbb..9edeca83f43463e3ca5e0d1fba5fbc829bdd262e 100644 (file)
@@ -585,7 +585,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
 {
        /* Don't risk a hypervisor call if we're crashing */
-       if (!crash_shutdown) {
+       if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
                unsigned long vpa = __pa(get_lppaca());
 
                if (unregister_vpa(hard_smp_processor_id(), vpa)) {
index 977de9db87547635f61dffff982684c674a0b531..6298264efe36110bdc8318001180d3d8eb751fba 100644 (file)
@@ -59,7 +59,7 @@ static unsigned long dart_tablesize;
 static u32 *dart_vbase;
 
 /* Mapped base address for the dart */
-static unsigned int *__iomem dart;
+static unsigned int __iomem *dart;
 
 /* Dummy val that entries are set to when unused */
 static unsigned int dart_emptyval;
index 3e6ca7f5843ff43575b2f5e5fe834b60bf3f03dd..c1e89ad0684da8894aff0a326929e0676c4dd888 100644 (file)
@@ -810,13 +810,16 @@ initial_mmu:
        mtspr   SPRN_MD_TWC, r9
        li      r11, MI_BOOTINIT        /* Create RPN for address 0 */
        addis   r11, r11, 0x0080        /* Add 8M */
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r11
+
+       addi    r10, r10, 0x0100
+       mtspr   SPRN_MD_CTR, r10
 
        addis   r8, r8, 0x0080          /* Add 8M */
        mtspr   SPRN_MD_EPN, r8
        mtspr   SPRN_MD_TWC, r9
        addis   r11, r11, 0x0080        /* Add 8M */
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r11
 #endif
 
        /* Since the cache is enabled according to the information we
index 3a6e4bcb3c53b568d54f7e773c2b9548d2ac6d7b..15bd9b448a488bc6004775923fb365e331f6c2b8 100644 (file)
@@ -186,11 +186,15 @@ EXPORT_SYMBOL(flush_tlb_kernel_range);
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(_tlbie);
 #ifdef CONFIG_ALTIVEC
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_altivec);
+#endif
 EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_SPE
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_spe);
+#endif
 EXPORT_SYMBOL(giveup_spe);
 #endif /* CONFIG_SPE */
 #ifdef CONFIG_SMP
index 159b228eca1edb83b31ac35cf83ba2ff7bb55417..0ec53f04933871548acdbb2925037caa73a4a32a 100644 (file)
@@ -332,8 +332,8 @@ bamboo_early_serial_map(void)
        port.irq = 0;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 8110f55668c5508979919f5c2b060edb0d0d1b67..ce48a4f08cbbc62966ebeb68fea7a4b369b0e852 100644 (file)
@@ -97,8 +97,8 @@ bubinga_early_serial_map(void)
        port.irq = ACTING_UART0_INT;
        port.uartclk = uart_clock;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 64ebae19cdbb103faa168a110842dddf35168a45..9a828b623417d3c3fc0890a18792dca6b75f055b 100644 (file)
@@ -225,8 +225,8 @@ ebony_early_serial_map(void)
        port.irq = 0;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index d810b736d9bf5efa933a1e672484bca7f660d239..21d29132aebd97456c20f062724d9b827d701441 100644 (file)
@@ -279,8 +279,8 @@ luan_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 73b2c98158f64ccc0016c3f7e03c13cafc15d478..4f355b6acab2b29214543dc641ef863eb410321c 100644 (file)
@@ -248,8 +248,8 @@ ocotea_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 0b1b77d986bfd6b94d26f11a822179963281fe85..e90d97f64f76c1a2d0e3e3978110fe210051869c 100644 (file)
@@ -95,8 +95,8 @@ ml300_early_serial_map(void)
                port.irq = old_ports[i].irq;
                port.uartclk = old_ports[i].baud_base * 16;
                port.regshift = old_ports[i].iomem_reg_shift;
-               port.iotype = SERIAL_IO_MEM;
-               port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+               port.iotype = UPIO_MEM;
+               port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
                port.line = i;
 
                if (early_serial_setup(&port) != 0) {
index e60f4bd437ec2c1b69053c2578067fb506d09299..b065b8babcd3054ae95c795f6b01c4ccb244021f 100644 (file)
@@ -305,8 +305,8 @@ yucca_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 012e1e652c03ed6e039e0c56254fe913f8d1ffbb..1a659bbc18609239950c1cf4d500914aa7d722f4 100644 (file)
@@ -301,14 +301,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                struct uart_port p;
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500);
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600);
                p.uartclk = binfo->bi_busfreq;
 
index 2eceb1e6f4eb956c5266be833f7b810ae42500cd..408d64f18e1a7e797e99923a432be28285a4cb2c 100644 (file)
@@ -162,14 +162,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                          binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index b332ebae6bd3018296b047ebbdc0146db653f48f..1801ab392e2223a278d1c84a0bf48d47fcfcf164 100644 (file)
@@ -534,14 +534,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                                binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index e777ba824aa90c00d25453df347f72415aa0f2e1..8a72221f816c879ec565e3c2f5c954f0626fea73 100644 (file)
@@ -64,7 +64,7 @@ sbc8560_early_serial_map(void)
        uart_req.irq = MPC85xx_IRQ_EXT9;
        uart_req.flags = STD_COM_FLAGS;
        uart_req.uartclk = BASE_BAUD * 16;
-        uart_req.iotype = SERIAL_IO_MEM;
+        uart_req.iotype = UPIO_MEM;
         uart_req.mapbase = UARTA_ADDR;
         uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE);
        uart_req.type = PORT_16650;
index b436f4d0a3fa753e2a1b54764dbcab0b0150a26f..a5e38ba6273216232dd56a9debd98b4eee62406a 100644 (file)
@@ -346,14 +346,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                          binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index 48a4a510d598c812ad36896aba2ce629acdc2628..aefcc0e7be57295a296fe9ace9dd4e171eb0c260 100644 (file)
@@ -116,7 +116,7 @@ chestnut_early_serial_map(void)
        port.uartclk = BASE_BAUD * 16;
        port.irq = UART0_INT;
        port.flags = STD_COM_FLAGS | UPF_IOREMAP;
-       port.iotype = SERIAL_IO_MEM;
+       port.iotype = UPIO_MEM;
        port.mapbase = CHESTNUT_UART0_IO_BASE;
        port.regshift = 0;
 
index 32358b3fb23654a09ece544b62a9d88b17450013..ffde8f6f6302ff798f90f2384dca3f7df3d20a00 100644 (file)
@@ -330,7 +330,7 @@ ev64260_early_serial_map(void)
                port.irq = EV64260_UART_0_IRQ;
                port.uartclk = BASE_BAUD * 16;
                port.regshift = 2;
-               port.iotype = SERIAL_IO_MEM;
+               port.iotype = UPIO_MEM;
                port.flags = STD_COM_FLAGS;
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
index 708b8739ecdd97e1fd2d5eaed73f5e475bd6e8f6..872c0a3ba3c798b2e1297da971d517ee30ed023a 100644 (file)
@@ -100,7 +100,7 @@ static void __init ppc7d_early_serial_map(void)
        serial_req.uartclk = UART_CLK;
        serial_req.irq = 4;
        serial_req.flags = STD_COM_FLAGS;
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.membase = (u_char *) PPC7D_SERIAL_0;
 
        gen550_init(0, &serial_req);
index 5ad70d357cb9895bad5697563e7d39b208809e8b..69e1de7971f2d47a5d992b6bbb4a47fcd8ccf6dd 100644 (file)
@@ -176,8 +176,8 @@ spruce_early_serial_map(void)
        memset(&serial_req, 0, sizeof(serial_req));
        serial_req.uartclk = uart_clk;
        serial_req.irq = UART0_INT;
-       serial_req.flags = ASYNC_BOOT_AUTOCONF;
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.flags = UPF_BOOT_AUTOCONF;
+       serial_req.iotype = UPIO_MEM;
        serial_req.membase = (u_char *)UART0_IO_BASE;
        serial_req.regshift = 0;
 
index ab34b1d6072f6e350c0dfd930c848702ce710157..2fe28ded2c6096080be6bd0665135466dfc1e089 100644 (file)
@@ -189,8 +189,8 @@ ocp_device_resume(struct device *dev)
 struct bus_type ocp_bus_type = {
        .name = "ocp",
        .match = ocp_device_match,
-       .probe = ocp_driver_probe,
-       .remove = ocp_driver_remove,
+       .probe = ocp_device_probe,
+       .remove = ocp_device_remove,
        .suspend = ocp_device_suspend,
        .resume = ocp_device_resume,
 };
index 1b5fe9e398d405b353d68018dbf1641b2ae37e6c..7bada82527a892257b9f6f0c13834b4ef851faca 100644 (file)
@@ -108,7 +108,7 @@ mpc83xx_early_serial_map(void)
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        memset(&serial_req, 0, sizeof (serial_req));
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.mapbase = pdata[0].mapbase;
        serial_req.membase = pdata[0].membase;
        serial_req.regshift = 0;
index 1a47ff4b831d3d75e33eca61669c3fe869ea79cd..e4dda43fdaa7bb99e3ff2ca032aa924171b73f95 100644 (file)
@@ -90,7 +90,7 @@ mpc85xx_early_serial_map(void)
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        memset(&serial_req, 0, sizeof (serial_req));
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.mapbase = pdata[0].mapbase;
        serial_req.membase = pdata[0].membase;
        serial_req.regshift = 0;
index bf9a7a361b3490b892a40aea7c78edb083a0d12c..cc20f0e3a7d300f26cc1607a0a6b92c39d576fe1 100644 (file)
 #define SET_STAT_UID(stat, uid)                (stat).st_uid = high2lowuid(uid)
 #define SET_STAT_GID(stat, gid)                (stat).st_gid = high2lowgid(gid)
 
-asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
 {
        return sys_chown(filename, low2highuid(user), low2highgid(group));
 }
 
-asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
 {
        return sys_lchown(filename, low2highuid(user), low2highgid(group));
 }
@@ -141,7 +141,7 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
                low2highuid(suid));
 }
 
-asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
+asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
 {
        int retval;
 
@@ -158,7 +158,7 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
                low2highgid(sgid));
 }
 
-asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
+asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
 {
        int retval;
 
@@ -179,7 +179,7 @@ asmlinkage long sys32_setfsgid16(u16 gid)
        return sys_setfsgid((gid_t)gid);
 }
 
-static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
+static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
 {
        int i;
        u16 group;
@@ -193,7 +193,7 @@ static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
        return 0;
 }
 
-static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
+static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
 {
        int i;
        u16 group;
@@ -207,7 +207,7 @@ static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
        return 0;
 }
 
-asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
 {
        int i;
 
@@ -231,7 +231,7 @@ out:
        return i;
 }
 
-asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
 {
        struct group_info *group_info;
        int retval;
@@ -278,14 +278,14 @@ asmlinkage long sys32_getegid16(void)
 
 /* 32-bit timeval and related flotsam.  */
 
-static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
+static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
        return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
                (__get_user(o->tv_sec, &i->tv_sec) ||
                 __get_user(o->tv_usec, &i->tv_usec)));
 }
 
-static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
        return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
                (__put_user(i->tv_sec, &o->tv_sec) ||
@@ -341,7 +341,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
        return -ENOSYS;
 }
 
-asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
        if ((int)high < 0)
                return -EINVAL;
@@ -357,7 +357,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
                return sys_ftruncate(fd, (high << 32) | low);
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
        int err;
 
@@ -591,7 +591,7 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
 
 extern struct timezone sys_tz;
 
-asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        if (tv) {
                struct timeval ktv;
@@ -606,7 +606,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *t
        return 0;
 }
 
-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
 {
        long usec;
 
@@ -620,7 +620,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
        return 0;
 }
 
-asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        struct timespec kts;
        struct timezone ktz;
@@ -645,7 +645,7 @@ asmlinkage long sys32_pause(void)
        return -ERESTARTNOHAND;
 }
 
-asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
+asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
        if ((compat_ssize_t) count < 0)
@@ -653,7 +653,7 @@ asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
        return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf,
+asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
        if ((compat_ssize_t) count < 0)
@@ -666,7 +666,7 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun
        return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
 }
 
-asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count)
+asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -686,7 +686,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size
 }
 
 asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
-                               compat_loff_t *offset, s32 count)
+                               compat_loff_t __user *offset, s32 count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -722,7 +722,7 @@ struct timex32 {
 
 extern int do_adjtimex(struct timex *);
 
-asmlinkage long sys32_adjtimex(struct timex32 *utp)
+asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
 {
        struct timex txc;
        int ret;
@@ -789,12 +789,13 @@ struct __sysctl_args32 {
        u32 __unused[4];
 };
 
-asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
+asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 {
        struct __sysctl_args32 tmp;
        int error;
-       size_t oldlen, *oldlenp = NULL;
-       unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+       size_t oldlen;
+       size_t __user *oldlenp = NULL;
+       unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
 
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
@@ -806,20 +807,20 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
                   basically copy the whole sysctl.c here, and
                   glibc's __sysctl uses rw memory for the structure
                   anyway.  */
-               if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
-                   put_user(oldlen, (size_t *)addr))
+               if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) ||
+                   put_user(oldlen, (size_t __user *)addr))
                        return -EFAULT;
-               oldlenp = (size_t *)addr;
+               oldlenp = (size_t __user *)addr;
        }
 
        lock_kernel();
-       error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
-                         oldlenp, (void *)A(tmp.newval), tmp.newlen);
+       error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval),
+                         oldlenp, compat_ptr(tmp.newval), tmp.newlen);
        unlock_kernel();
        if (oldlenp) {
                if (!error) {
-                       if (get_user(oldlen, (size_t *)addr) ||
-                           put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+                       if (get_user(oldlen, (size_t __user *)addr) ||
+                           put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
                                error = -EFAULT;
                }
                copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
@@ -853,7 +854,7 @@ struct stat64_emu31 {
        unsigned long   st_ino;
 };     
 
-static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
 {
        struct stat64_emu31 tmp;
 
@@ -877,7 +878,7 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
        return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
 }
 
-asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_stat(filename, &stat);
@@ -886,7 +887,7 @@ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
        return ret;
 }
 
-asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_lstat(filename, &stat);
@@ -895,7 +896,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
        return ret;
 }
 
-asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_fstat(fd, &stat);
@@ -952,7 +953,7 @@ out:
 
 
 asmlinkage unsigned long
-old32_mmap(struct mmap_arg_struct_emu31 *arg)
+old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
 {
        struct mmap_arg_struct_emu31 a;
        int error = -EFAULT;
@@ -970,7 +971,7 @@ out:
 }
 
 asmlinkage long 
-sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
+sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
 {
        struct mmap_arg_struct_emu31 a;
        int error = -EFAULT;
@@ -982,7 +983,7 @@ out:
        return error;
 }
 
-asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
 {
        if ((compat_ssize_t) count < 0)
                return -EINVAL; 
@@ -990,7 +991,7 @@ asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
        return sys_read(fd, buf, count);
 }
 
-asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 {
        if ((compat_ssize_t) count < 0)
                return -EINVAL; 
@@ -1002,12 +1003,12 @@ asmlinkage long sys32_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-       int *parent_tidptr, *child_tidptr;
+       int __user *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3] & 0xffffffffUL;
         newsp = regs.orig_gpr2 & 0x7fffffffUL;
-       parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL);
-       child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
+       parent_tidptr = compat_ptr(regs.gprs[4]);
+       child_tidptr = compat_ptr(regs.gprs[5]);
         if (!newsp)
                 newsp = regs.gprs[15];
         return do_fork(clone_flags, newsp, &regs, 0,
index 6e27ac68ec3f01060093a7fb98b3ff0899f7f0ca..83b33fe1923c0bbd53da91beadf66bdff8e964c4 100644 (file)
@@ -1486,7 +1486,7 @@ sys_inotify_rm_watch_wrapper:
 
        .globl compat_sys_openat_wrapper
 compat_sys_openat_wrapper:
-       lgfr    %r2,%r2                 # int
+       llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # const char *
        lgfr    %r4,%r4                 # int
        lgfr    %r5,%r5                 # int
@@ -1518,14 +1518,14 @@ sys_fchownat_wrapper:
 
        .globl compat_sys_futimesat_wrapper
 compat_sys_futimesat_wrapper:
-       lgfr    %r2,%r2                 # int
+       llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # char *
        llgtr   %r4,%r4                 # struct timeval *
        jg      compat_sys_futimesat
 
        .globl compat_sys_newfstatat_wrapper
 compat_sys_newfstatat_wrapper:
-       lgfr    %r2,%r2                 # int
+       llgfr   %r2,%r2                 # unsigned int
        llgtr   %r3,%r3                 # char *
        llgtr   %r4,%r4                 # struct stat *
        lgfr    %r5,%r5                 # int
index 6a63553493c57922bdab3196afdb1d3da265161b..e351780bb660cab9ef1dbc503799969edb175eb1 100644 (file)
@@ -122,8 +122,8 @@ out:
 #ifndef CONFIG_64BIT
 struct sel_arg_struct {
        unsigned long n;
-       fd_set *inp, *outp, *exp;
-       struct timeval *tvp;
+       fd_set __user *inp, *outp, *exp;
+       struct timeval __user *tvp;
 };
 
 asmlinkage long old_select(struct sel_arg_struct __user *arg)
index 5d21e9e6e7b4505fc6647aaa039222a44197de85..a46793beeddda592d70797ed79fc4c462477f1d6 100644 (file)
@@ -486,7 +486,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                info.si_signo = signal;
                info.si_errno = 0;
                info.si_code = ILL_ILLOPC;
-               info.si_addr = (void *) location;
+               info.si_addr = (void __user *) location;
                do_trap(interruption_code, signal,
                        "illegal operation", regs, &info);
        }
index 2d5cb1385753249e1d9b282a5b947563f36dc520..b075ab499d058d38a0a0378b519e1336d9177a60 100644 (file)
@@ -42,8 +42,8 @@ static volatile long cmm_timed_pages_target = 0;
 static long cmm_timeout_pages = 0;
 static long cmm_timeout_seconds = 0;
 
-static struct cmm_page_array *cmm_page_list = 0;
-static struct cmm_page_array *cmm_timed_page_list = 0;
+static struct cmm_page_array *cmm_page_list = NULL;
+static struct cmm_page_array *cmm_timed_page_list = NULL;
 
 static unsigned long cmm_thread_active = 0;
 static struct work_struct cmm_thread_starter;
@@ -259,7 +259,7 @@ static struct ctl_table cmm_table[];
 
 static int
 cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
-                 void *buffer, size_t *lenp, loff_t *ppos)
+                 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[16], *p;
        long pages;
@@ -300,7 +300,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
 
 static int
 cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
-                   void *buffer, size_t *lenp, loff_t *ppos)
+                   void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[64], *p;
        long pages, seconds;
@@ -419,7 +419,7 @@ cmm_init (void)
 #ifdef CONFIG_CMM_IUCV
        smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
 #endif
-       INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0);
+       INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL);
        init_waitqueue_head(&cmm_thread_wait);
        init_timer(&cmm_timer);
        return 0;
index c46f9154cfd573e57e7ed339a55de39c27406fd7..123abbbc91e0c0b4dcec41827ed9a7c92814508f 100644 (file)
@@ -216,24 +216,26 @@ void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
 {
        volatile __u8 *bp;
        volatile __u16 *p;
+       unsigned char *s = addr;
 
        if (CHECK_AX88796L_PORT(port)) {
                p = (volatile unsigned short *)port88796l(port, 0);
-               while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+               while (count--) *s++ = *p & 0xff;
        } else if (PXSEG(port))
-               while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
+               while (count--) *s++ = *(volatile unsigned char *)port;
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                bp = (__u8 *)PCI_IOMAP(port);
-               while (count--) *((volatile unsigned char *) addr)++ = *bp;
+               while (count--) *s++ = *bp;
        } else {
                p = (volatile unsigned short *)port2adr(port);
-               while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+               while (count--) *s++ = *p & 0xff;
        }
 }
 
 void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
 {
        volatile __u16 *p;
+       __u16 *s = addr;
 
        if (CHECK_AX88796L_PORT(port))
                p = (volatile unsigned short *)port88796l(port, 1);
@@ -243,7 +245,7 @@ void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
                p = (volatile unsigned short *)PCI_IOMAP(port);
        else
                p = (volatile unsigned short *)port2adr(port);
-       while (count--) *((__u16 *) addr)++ = *p;
+       while (count--) *s++ = *p;
 }
 
 void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
@@ -252,8 +254,9 @@ void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
                maybebadio(insl, port);
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+               __u32 *s = addr;
 
-               while (count--) *((__u32 *) addr)++ = *p;
+               while (count--) *s++ = *p;
        } else
                maybebadio(insl, port);
 }
@@ -262,24 +265,26 @@ void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
 {
        volatile __u8 *bp;
        volatile __u16 *p;
+       const __u8 *s = addr;
 
        if (CHECK_AX88796L_PORT(port)) {
                p = (volatile unsigned short *)port88796l(port, 0);
-               while (count--) *p = *((unsigned char *) addr)++;
+               while (count--) *p = *s++;
        } else if (PXSEG(port))
-               while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
+               while (count--) *(volatile unsigned char *)port = *s++;
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                bp = (__u8 *)PCI_IOMAP(port);
-               while (count--) *bp = *((volatile unsigned char *) addr)++;
+               while (count--) *bp = *s++;
        } else {
                p = (volatile unsigned short *)port2adr(port);
-               while (count--) *p = *((unsigned char *) addr)++;
+               while (count--) *p = *s++;
        }
 }
 
 void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
 {
        volatile __u16 *p;
+       const __u16 *s = addr;
 
        if (CHECK_AX88796L_PORT(port))
                p = (volatile unsigned short *)port88796l(port, 1);
@@ -289,7 +294,7 @@ void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
                p = (volatile unsigned short *)PCI_IOMAP(port);
        else
                p = (volatile unsigned short *)port2adr(port);
-       while (count--) *p = *((__u16 *) addr)++;
+       while (count--) *p = *s++;
 }
 
 void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
@@ -298,8 +303,9 @@ void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
                maybebadio(outsl, port);
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+               const __u32 *s = addr;
 
-               while (count--) *p = *((__u32 *) addr)++;
+               while (count--) *p = *s++;
        } else
                maybebadio(outsl, port);
 }
index 472b450e61be5384bdd9211c8d485796e73f33b3..de29c45f23a7278ee01fb2930d3afc20d1cbed6e 100644 (file)
 
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
-#if 0
-/* Not yet - there's no declaration of drive_info anywhere. */
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(iounmap);
index 267ec8f6fb585a8d5763f1eea412102686c2bbc3..887f6a160c589a31c066055965c970922372d62b 100644 (file)
@@ -38,7 +38,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV    save    %sp, -STACKFRAME_SZ, %sp
index fbb05a452e51552590e01d7da2e1af7c617d8a47..118cac84a0f5445ab9a57a831321706946e004c4 100644 (file)
@@ -54,7 +54,7 @@ void (*pm_idle)(void);
  * This is done via auxio, but could be used as a fallback
  * handler when auxio is not present-- unused for now...
  */
-void (*pm_power_off)(void);
+void (*pm_power_off)(void) = machine_power_off;
 
 /*
  * sysctl - toggle power-off restriction for serial console 
index 6877ae4cd1d9c75d58ba45072dd6e645fb658d4a..c0314705d73a15654639abfb6d33c627dbc55e55 100644 (file)
@@ -78,7 +78,7 @@ sys_call_table:
 /*280*/        .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
 /*285*/        .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
 /*290*/        .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-/*295*/        .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+/*295*/        .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #ifdef CONFIG_SUNOS_EMUL
        /* Now the SunOS syscall table. */
@@ -190,5 +190,6 @@ sunos_sys_table:
 /*290*/        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
+       .long sunos_nosys
 
 #endif
diff --git a/arch/sparc64/boot/.gitignore b/arch/sparc64/boot/.gitignore
new file mode 100644 (file)
index 0000000..36356f9
--- /dev/null
@@ -0,0 +1,4 @@
+image
+tftpboot.img
+vmlinux.aout
+piggyback
index 9ceddad0fb494ae4e6c82630ef8171e706115c51..069d49777b2a365516d62b0019d58d00e8a9eef1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Wed Jan 18 13:41:02 2006
+# Linux kernel version: 2.6.16-rc2
+# Tue Feb  7 17:47:18 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -23,7 +23,6 @@ CONFIG_HZ=250
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -31,7 +30,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 #
 CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -155,6 +154,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -224,6 +224,11 @@ CONFIG_IP_DCCP_TFRC_LIB=m
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 CONFIG_VLAN_8021Q=m
@@ -233,11 +238,6 @@ CONFIG_VLAN_8021Q=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -657,6 +657,7 @@ CONFIG_SERIAL_SUNSU_CONSOLE=y
 CONFIG_SERIAL_SUNSAB=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 
@@ -765,6 +766,7 @@ CONFIG_HWMON=y
 # 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
@@ -1117,6 +1119,10 @@ CONFIG_USB_HIDDEV=y
 # SN Devices
 #
 
+#
+# EDAC - error detection and reporting (RAS)
+#
+
 #
 # Misc Linux/SPARC drivers
 #
index 12911e7463f22c3b94830fc5d3d3577ff2b91670..a73553ae7e53b76d04d979227bee32f26a9ddd91 100644 (file)
@@ -25,7 +25,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
        .text
        .align          32
index 2881faf36635c522d247e8bc6953c7efce8a3248..5928b3c33e2721d659c0e4b9c9b90a55eaf4101b 100644 (file)
@@ -79,7 +79,7 @@ sys_call_table32:
 /*280*/        .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat
 /*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-       .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
+       .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
 
 #endif /* CONFIG_COMPAT */
 
@@ -148,7 +148,7 @@ sys_call_table:
 /*280*/        .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
 /*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-       .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+       .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -261,4 +261,5 @@ sunos_sys_table:
 /*290*/        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
+       .word sunos_nosys
 #endif
index d25667eeae10f6563ee269990ecd6b305c5cd4ae..7043ca18caf91b2bed67ab6ad14b53a58bcc0915 100644 (file)
@@ -283,32 +283,3 @@ solaris_sys_table:
        .word solaris_unimplemented     /*                      253     */
        .word solaris_unimplemented     /*                      254     */
        .word solaris_unimplemented     /*                      255     */
-       .word solaris_unimplemented     /*                      256     */
-       .word solaris_unimplemented     /*                      257     */
-       .word solaris_unimplemented     /*                      258     */
-       .word solaris_unimplemented     /*                      259     */
-       .word solaris_unimplemented     /*                      260     */
-       .word solaris_unimplemented     /*                      261     */
-       .word solaris_unimplemented     /*                      262     */
-       .word solaris_unimplemented     /*                      263     */
-       .word solaris_unimplemented     /*                      264     */
-       .word solaris_unimplemented     /*                      265     */
-       .word solaris_unimplemented     /*                      266     */
-       .word solaris_unimplemented     /*                      267     */
-       .word solaris_unimplemented     /*                      268     */
-       .word solaris_unimplemented     /*                      269     */
-       .word solaris_unimplemented     /*                      270     */
-       .word solaris_unimplemented     /*                      271     */
-       .word solaris_unimplemented     /*                      272     */
-       .word solaris_unimplemented     /*                      273     */
-       .word solaris_unimplemented     /*                      274     */
-       .word solaris_unimplemented     /*                      275     */
-       .word solaris_unimplemented     /*                      276     */
-       .word solaris_unimplemented     /*                      277     */
-       .word solaris_unimplemented     /*                      278     */
-       .word solaris_unimplemented     /*                      279     */
-       .word solaris_unimplemented     /*                      280     */
-       .word solaris_unimplemented     /*                      281     */
-       .word solaris_unimplemented     /*                      282     */
-       .word solaris_unimplemented     /*                      283     */
-
index 5d50d4a44abf4879220e045b9eaecf0d48d8f9d7..2f880cb167a582f5f10be75d4647facd1f82e274 100644 (file)
@@ -9,6 +9,7 @@
 #include <termios.h>
 #include <string.h>
 #include <signal.h>
+#include <sched.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -73,7 +74,6 @@ static void winch_handler(int sig)
 struct winch_data {
        int pty_fd;
        int pipe_fd;
-       int close_me;
 };
 
 static int winch_thread(void *arg)
@@ -84,7 +84,6 @@ static int winch_thread(void *arg)
        int count, err;
        char c = 1;
 
-       os_close_file(data->close_me);
        pty_fd = data->pty_fd;
        pipe_fd = data->pipe_fd;
        count = os_write_file(pipe_fd, &c, sizeof(c));
@@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
        }
 
        data = ((struct winch_data) { .pty_fd           = fd,
-                                     .pipe_fd          = fds[1],
-                                     .close_me         = fds[0] } );
-       err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+                                     .pipe_fd          = fds[1] } );
+       /* CLONE_FILES so this thread doesn't hold open files which are open
+        * now, but later closed.  This is a problem with /dev/net/tun.
+        */
+       err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
        if(err < 0){
                printk("fork of winch_thread failed - errno = %d\n", errno);
                goto out_close;
        }
 
-       os_close_file(fds[1]);
        *fd_out = fds[0];
        n = os_read_file(fds[0], &c, sizeof(c));
        if(n != sizeof(c)){
@@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
                printk("read failed, err = %d\n", -n);
                printk("fd %d will not support SIGWINCH\n", fd);
                 err = -EINVAL;
-               goto out_close1;
+               goto out_close;
        }
        return err ;
 
  out_close:
        os_close_file(fds[1]);
- out_close1:
        os_close_file(fds[0]);
  out:
        return err;
index 8ebb2241ad4263ef2fd1cac2e472d66671862cd7..8c7279bb353bc52848b4e930000af5cd98376b7e 100644 (file)
@@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev)
                             SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
        if(err != 0){
                printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
-               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
-               lp->fd = -1;
                err = -ENETUNREACH;
+               goto out_close;
        }
 
        lp->tl.data = (unsigned long) &lp->user;
@@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev)
         */
        while((err = uml_net_rx(dev)) > 0) ;
 
- out:
        spin_unlock(&lp->lock);
-       return(err);
+
+       spin_lock(&opened_lock);
+       list_add(&lp->list, &opened);
+       spin_unlock(&opened_lock);
+
+       return 0;
+out_close:
+       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+       lp->fd = -1;
+out:
+       spin_unlock(&lp->lock);
+       return err;
 }
 
 static int uml_net_close(struct net_device *dev)
@@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev)
        if(lp->close != NULL)
                (*lp->close)(lp->fd, &lp->user);
        lp->fd = -1;
-       list_del(&lp->list);
 
        spin_unlock(&lp->lock);
+
+       spin_lock(&opened_lock);
+       list_del(&lp->list);
+       spin_unlock(&opened_lock);
+
        return 0;
 }
 
@@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac,
        if (device->have_mac)
                set_ether_mac(dev, device->mac);
 
-       spin_lock(&opened_lock);
-       list_add(&lp->list, &opened);
-       spin_unlock(&opened_lock);
-
-       return(0);
+       return 0;
 }
 
 static struct uml_net *find_device(int n)
index 4892e5fcef07dce7170c70ce85a9f4e3ad867d92..83b688ca198fb3c0e01f8e8acd2b55a5c50f19c6 100644 (file)
@@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
 extern void save_registers(int pid, union uml_pt_regs *regs);
 extern void restore_registers(int pid, union uml_pt_regs *regs);
 extern void init_registers(int pid);
-extern void get_safe_registers(unsigned long * regs);
+extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs);
 extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
 
 #endif
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
deleted file mode 100644 (file)
index eea1c9c..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-/* 
- * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <sched.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <asm/unistd.h>
-#include <asm/types.h>
-#include "user.h"
-#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "skas.h"
-#include "stub-data.h"
-#include "mm_id.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/stub.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "skas_ptrace.h"
-#include "chan_user.h"
-#include "registers.h"
-#include "mem.h"
-#include "uml-config.h"
-#include "process.h"
-
-int is_skas_winch(int pid, int fd, void *data)
-{
-        if(pid != os_getpgrp())
-               return(0);
-
-       register_winch_irq(-1, fd, -1, data);
-       return(1);
-}
-
-void wait_stub_done(int pid, int sig, char * fname)
-{
-        int n, status, err;
-
-        do {
-                if ( sig != -1 ) {
-                        err = ptrace(PTRACE_CONT, pid, 0, sig);
-                        if(err)
-                                panic("%s : continue failed, errno = %d\n",
-                                      fname, errno);
-                }
-                sig = 0;
-
-                CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-        } while((n >= 0) && WIFSTOPPED(status) &&
-                ((WSTOPSIG(status) == SIGVTALRM) ||
-                /* running UML inside a detached screen can cause
-                 * SIGWINCHes
-                 */
-                (WSTOPSIG(status) == SIGWINCH)));
-
-        if((n < 0) || !WIFSTOPPED(status) ||
-           (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
-               unsigned long regs[HOST_FRAME_SIZE];
-               if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
-                       printk("Failed to get registers from stub, "
-                              "errno = %d\n", errno);
-               else {
-                       int i;
-
-                       printk("Stub registers -\n");
-                       for(i = 0; i < HOST_FRAME_SIZE; i++)
-                               printk("\t%d - %lx\n", i, regs[i]);
-               }
-                panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
-                      "pid = %d, n = %d, errno = %d, status = 0x%x\n",
-                      fname, pid, n, errno, status);
-        }
-}
-
-void get_skas_faultinfo(int pid, struct faultinfo * fi)
-{
-        int err;
-
-        if(ptrace_faultinfo){
-                err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
-                if(err)
-                        panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
-                              "errno = %d\n", errno);
-
-                /* Special handling for i386, which has different structs */
-                if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
-                        memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
-                               sizeof(struct faultinfo) -
-                               sizeof(struct ptrace_faultinfo));
-        }
-        else {
-                wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
-
-                /* faultinfo is prepared by the stub-segv-handler at start of
-                 * the stub stack page. We just have to copy it.
-                 */
-                memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
-        }
-}
-
-static void handle_segv(int pid, union uml_pt_regs * regs)
-{
-        get_skas_faultinfo(pid, &regs->skas.faultinfo);
-        segv(regs->skas.faultinfo, 0, 1, NULL);
-}
-
-/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
-static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
-{
-       int err, status;
-
-       /* Mark this as a syscall */
-       UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
-
-       if (!local_using_sysemu)
-       {
-               err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
-               if(err < 0)
-                       panic("handle_trap - nullifying syscall failed errno = %d\n",
-                             errno);
-
-               err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
-               if(err < 0)
-                       panic("handle_trap - continuing to end of syscall failed, "
-                             "errno = %d\n", errno);
-
-               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-               if((err < 0) || !WIFSTOPPED(status) ||
-                  (WSTOPSIG(status) != SIGTRAP + 0x80))
-                       panic("handle_trap - failed to wait at end of syscall, "
-                             "errno = %d, status = %d\n", errno, status);
-       }
-
-       handle_syscall(regs);
-}
-
-extern int __syscall_stub_start;
-int stub_code_fd = -1;
-__u64 stub_code_offset;
-
-static int userspace_tramp(void *stack)
-{
-       void *addr;
-
-       ptrace(PTRACE_TRACEME, 0, 0, 0);
-
-       init_new_thread_signals(1);
-       enable_timer();
-
-       if(!proc_mm){
-               /* This has a pte, but it can't be mapped in with the usual
-                * tlb_flush mechanism because this is part of that mechanism
-                */
-               addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
-                             PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
-                             stub_code_fd, stub_code_offset);
-               if(addr == MAP_FAILED){
-                       printk("mapping stub code failed, errno = %d\n",
-                              errno);
-                       exit(1);
-               }
-
-               if(stack != NULL){
-                       int fd;
-                       __u64 offset;
-
-                       fd = phys_mapping(to_phys(stack), &offset);
-                       addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
-                                   PROT_READ | PROT_WRITE,
-                                   MAP_FIXED | MAP_SHARED, fd, offset);
-                       if(addr == MAP_FAILED){
-                               printk("mapping stub stack failed, "
-                                      "errno = %d\n", errno);
-                               exit(1);
-                       }
-               }
-       }
-       if(!ptrace_faultinfo){
-               unsigned long v = UML_CONFIG_STUB_CODE +
-                                 (unsigned long) stub_segv_handler -
-                                 (unsigned long) &__syscall_stub_start;
-
-               set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
-               set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
-                           SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
-                           SIGUSR1, -1);
-       }
-
-       os_stop_process(os_getpid());
-       return(0);
-}
-
-/* Each element set once, and only accessed by a single processor anyway */
-#undef NR_CPUS
-#define NR_CPUS 1
-int userspace_pid[NR_CPUS];
-
-int start_userspace(unsigned long stub_stack)
-{
-       void *stack;
-       unsigned long sp;
-       int pid, status, n, flags;
-
-       if ( stub_code_fd == -1 )
-               stub_code_fd = phys_mapping(to_phys(&__syscall_stub_start),
-                                           &stub_code_offset);
-
-       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(stack == MAP_FAILED)
-               panic("start_userspace : mmap failed, errno = %d", errno);
-       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-
-       flags = CLONE_FILES | SIGCHLD;
-       if(proc_mm) flags |= CLONE_VM;
-       pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
-       if(pid < 0)
-               panic("start_userspace : clone failed, errno = %d", errno);
-
-       do {
-               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-               if(n < 0)
-                       panic("start_userspace : wait failed, errno = %d", 
-                             errno);
-       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
-
-       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
-               panic("start_userspace : expected SIGSTOP, got status = %d",
-                     status);
-
-       if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
-               panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
-                     errno);
-
-       if(munmap(stack, PAGE_SIZE) < 0)
-               panic("start_userspace : munmap failed, errno = %d\n", errno);
-
-       return(pid);
-}
-
-void userspace(union uml_pt_regs *regs)
-{
-       int err, status, op, pid = userspace_pid[0];
-       int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
-
-       while(1){
-               restore_registers(pid, regs);
-
-               /* Now we set local_using_sysemu to be used for one loop */
-               local_using_sysemu = get_using_sysemu();
-
-               op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
-
-               err = ptrace(op, pid, 0, 0);
-               if(err)
-                       panic("userspace - could not resume userspace process, "
-                             "pid=%d, ptrace operation = %d, errno = %d\n",
-                             op, errno);
-
-               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-               if(err < 0)
-                       panic("userspace - waitpid failed, errno = %d\n", 
-                             errno);
-
-               regs->skas.is_user = 1;
-               save_registers(pid, regs);
-               UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
-
-               if(WIFSTOPPED(status)){
-                       switch(WSTOPSIG(status)){
-                       case SIGSEGV:
-                                if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
-                                        user_signal(SIGSEGV, regs, pid);
-                                else handle_segv(pid, regs);
-                               break;
-                       case SIGTRAP + 0x80:
-                               handle_trap(pid, regs, local_using_sysemu);
-                               break;
-                       case SIGTRAP:
-                               relay_signal(SIGTRAP, regs);
-                               break;
-                       case SIGIO:
-                       case SIGVTALRM:
-                       case SIGILL:
-                       case SIGBUS:
-                       case SIGFPE:
-                       case SIGWINCH:
-                                user_signal(WSTOPSIG(status), regs, pid);
-                               break;
-                       default:
-                               printk("userspace - child stopped with signal "
-                                      "%d\n", WSTOPSIG(status));
-                       }
-                       pid = userspace_pid[0];
-                       interrupt_end();
-
-                       /* Avoid -ERESTARTSYS handling in host */
-                       PT_SYSCALL_NR(regs->skas.regs) = -1;
-               }
-       }
-}
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
-
-
-int copy_context_skas0(unsigned long new_stack, int pid)
-{
-       int err;
-       unsigned long regs[MAX_REG_NR];
-       unsigned long current_stack = current_stub_stack();
-       struct stub_data *data = (struct stub_data *) current_stack;
-       struct stub_data *child_data = (struct stub_data *) new_stack;
-       __u64 new_offset;
-       int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
-
-       /* prepare offset and fd of child's stack as argument for parent's
-        * and child's mmap2 calls
-        */
-       *data = ((struct stub_data) { .offset   = MMAP_OFFSET(new_offset),
-                                     .fd       = new_fd,
-                                     .timer    = ((struct itimerval)
-                                                  { { 0, 1000000 / hz() },
-                                                    { 0, 1000000 / hz() }})});
-       get_safe_registers(regs);
-
-       /* Set parent's instruction pointer to start of clone-stub */
-       regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
-                               (unsigned long) stub_clone_handler -
-                               (unsigned long) &__syscall_stub_start;
-       regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
-               sizeof(void *);
-       err = ptrace_setregs(pid, regs);
-       if(err < 0)
-               panic("copy_context_skas0 : PTRACE_SETREGS failed, "
-                     "pid = %d, errno = %d\n", pid, errno);
-
-       /* set a well known return code for detection of child write failure */
-       child_data->err = 12345678;
-
-       /* Wait, until parent has finished its work: read child's pid from
-        * parent's stack, and check, if bad result.
-        */
-       wait_stub_done(pid, 0, "copy_context_skas0");
-
-       pid = data->err;
-       if(pid < 0)
-               panic("copy_context_skas0 - stub-parent reports error %d\n",
-                     pid);
-
-       /* Wait, until child has finished too: read child's result from
-        * child's stack and check it.
-        */
-       wait_stub_done(pid, -1, "copy_context_skas0");
-       if (child_data->err != UML_CONFIG_STUB_DATA)
-               panic("copy_context_skas0 - stub-child reports error %d\n",
-                     child_data->err);
-
-       if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
-                  (void *)PTRACE_O_TRACESYSGOOD) < 0)
-               panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
-                     "errno = %d\n", errno);
-
-       return pid;
-}
-
-/*
- * This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
- * the stub-pages. Thus, we map them using /proc/mm-fd
- */
-void map_stub_pages(int fd, unsigned long code,
-                   unsigned long data, unsigned long stack)
-{
-       struct proc_mm_op mmop;
-       int n;
-
-       mmop = ((struct proc_mm_op) { .op        = MM_MMAP,
-                                     .u         =
-                                     { .mmap    =
-                                       { .addr    = code,
-                                         .len     = PAGE_SIZE,
-                                         .prot    = PROT_EXEC,
-                                         .flags   = MAP_FIXED | MAP_PRIVATE,
-                                         .fd      = stub_code_fd,
-                                         .offset  = stub_code_offset
-       } } });
-       n = os_write_file(fd, &mmop, sizeof(mmop));
-       if(n != sizeof(mmop))
-               panic("map_stub_pages : /proc/mm map for code failed, "
-                     "err = %d\n", -n);
-
-       if ( stack ) {
-               __u64 map_offset;
-               int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
-               mmop = ((struct proc_mm_op)
-                               { .op        = MM_MMAP,
-                                 .u         =
-                                 { .mmap    =
-                                   { .addr    = data,
-                                     .len     = PAGE_SIZE,
-                                     .prot    = PROT_READ | PROT_WRITE,
-                                     .flags   = MAP_FIXED | MAP_SHARED,
-                                     .fd      = map_fd,
-                                     .offset  = map_offset
-               } } });
-               n = os_write_file(fd, &mmop, sizeof(mmop));
-               if(n != sizeof(mmop))
-                       panic("map_stub_pages : /proc/mm map for data failed, "
-                             "err = %d\n", -n);
-       }
-}
-
-void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
-               void (*handler)(int))
-{
-       unsigned long flags;
-       sigjmp_buf switch_buf, fork_buf;
-
-       *switch_buf_ptr = &switch_buf;
-       *fork_buf_ptr = &fork_buf;
-
-       /* Somewhat subtle - siglongjmp restores the signal mask before doing
-        * the longjmp.  This means that when jumping from one stack to another
-        * when the target stack has interrupts enabled, an interrupt may occur
-        * on the source stack.  This is bad when starting up a process because
-        * it's not supposed to get timer ticks until it has been scheduled.
-        * So, we disable interrupts around the sigsetjmp to ensure that
-        * they can't happen until we get back here where they are safe.
-        */
-       flags = get_signals();
-       block_signals();
-       if(sigsetjmp(fork_buf, 1) == 0)
-               new_thread_proc(stack, handler);
-
-       remove_sigstack();
-
-       set_signals(flags);
-}
-
-void thread_wait(void *sw, void *fb)
-{
-       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
-
-       *switch_buf = &buf;
-       fork_buf = fb;
-       if(sigsetjmp(buf, 1) == 0)
-               siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
-}
-
-void switch_threads(void *me, void *next)
-{
-       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
-       
-       *me_ptr = &my_buf;
-       if(sigsetjmp(my_buf, 1) == 0)
-               siglongjmp(*next_buf, 1);
-}
-
-static sigjmp_buf initial_jmpbuf;
-
-/* XXX Make these percpu */
-static void (*cb_proc)(void *arg);
-static void *cb_arg;
-static sigjmp_buf *cb_back;
-
-int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
-{
-       sigjmp_buf **switch_buf = switch_buf_ptr;
-       int n;
-
-       set_handler(SIGWINCH, (__sighandler_t) sig_handler,
-                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
-                   SIGVTALRM, -1);
-
-       *fork_buf_ptr = &initial_jmpbuf;
-       n = sigsetjmp(initial_jmpbuf, 1);
-        switch(n){
-        case INIT_JMP_NEW_THREAD:
-                new_thread_proc((void *) stack, new_thread_handler);
-                break;
-        case INIT_JMP_REMOVE_SIGSTACK:
-                remove_sigstack();
-                break;
-        case INIT_JMP_CALLBACK:
-               (*cb_proc)(cb_arg);
-               siglongjmp(*cb_back, 1);
-                break;
-        case INIT_JMP_HALT:
-               kmalloc_ok = 0;
-               return(0);
-        case INIT_JMP_REBOOT:
-               kmalloc_ok = 0;
-               return(1);
-        default:
-                panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
-       }
-       siglongjmp(**switch_buf, 1);
-}
-
-void initial_thread_cb_skas(void (*proc)(void *), void *arg)
-{
-       sigjmp_buf here;
-
-       cb_proc = proc;
-       cb_arg = arg;
-       cb_back = &here;
-
-       block_signals();
-       if(sigsetjmp(here, 1) == 0)
-               siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
-       unblock_signals();
-
-       cb_proc = NULL;
-       cb_arg = NULL;
-       cb_back = NULL;
-}
-
-void halt_skas(void)
-{
-       block_signals();
-       siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
-}
-
-void reboot_skas(void)
-{
-       block_signals();
-       siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
-}
-
-void switch_mm_skas(struct mm_id *mm_idp)
-{
-       int err;
-
-#warning need cpu pid in switch_mm_skas
-       if(proc_mm){
-               err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
-                            mm_idp->u.mm_fd);
-               if(err)
-                       panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
-                             "errno = %d\n", errno);
-       }
-       else userspace_pid[0] = mm_idp->u.pid;
-}
-
-/*
- * 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 e2d3ca445ef57388f848f79174135757f34f7c36..27cdf91644224cb90f3775ac37b6fa5eacda6e62 100644 (file)
@@ -193,6 +193,24 @@ __uml_setup("root=", uml_root_setup,
 "        root=/dev/ubd5\n\n"
 );
 
+#ifndef CONFIG_MODE_TT
+
+static int __init no_skas_debug_setup(char *line, int *add)
+{
+       printf("'debug' is not necessary to gdb UML in skas mode - run \n");
+       printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n");
+       printf("doesn't work as expected\n");
+
+       return 0;
+}
+
+__uml_setup("debug", no_skas_debug_setup,
+"debug\n"
+"    this flag is not needed to run gdb on UML in skas mode\n\n"
+);
+
+#endif
+
 #ifdef CONFIG_SMP
 static int __init uml_ncpus_setup(char *line, int *add)
 {
index 52945338b64d503ea13c0d20ad4d45ba607e53f5..87c3aa0252db5530190d0ac0837dfe8ec55d3aa6 100644 (file)
@@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
                return(-EINVAL);
        }
        *fd_out = ((int *) CMSG_DATA(cmsg))[0];
+       os_set_exec_close(*fd_out, 1);
        return(0);
 }
 
@@ -137,7 +138,8 @@ static int tuntap_open(void *data)
                return(err);
 
        if(pri->fixed_config){
-               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
+               pri->fd = os_open_file("/dev/net/tun",
+                                      of_cloexec(of_rdwr(OPENFLAGS())), 0);
                if(pri->fd < 0){
                        printk("Failed to open /dev/net/tun, err = %d\n",
                               -pri->fd);
index 9890e9090f584dc125d82d0a65889690ad257567..fbb080c2fc261afdf70640e7a00e0c6a951d31ac 100644 (file)
@@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
 
        multi_count++;
 
-       get_safe_registers(regs);
+       get_safe_registers(regs, NULL);
        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
                ((unsigned long) &batch_syscall_stub -
                 (unsigned long) &__syscall_stub_start);
index 120a21c5883f615c508cf5b418cc124f51453fcb..bbf34cb91ce18cbea3e088aea56fe6d6edffdff4 100644 (file)
@@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs)
                }
        }
 }
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
 
 int copy_context_skas0(unsigned long new_stack, int pid)
 {
        int err;
-       unsigned long regs[MAX_REG_NR];
+       unsigned long regs[HOST_FRAME_SIZE];
+       unsigned long fp_regs[HOST_FP_SIZE];
        unsigned long current_stack = current_stub_stack();
        struct stub_data *data = (struct stub_data *) current_stack;
        struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
                                      .timer    = ((struct itimerval)
                                                    { { 0, 1000000 / hz() },
                                                      { 0, 1000000 / hz() }})});
-       get_safe_registers(regs);
+       get_safe_registers(regs, fp_regs);
 
        /* Set parent's instruction pointer to start of clone-stub */
        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
@@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
                panic("copy_context_skas0 : PTRACE_SETREGS failed, "
                      "pid = %d, errno = %d\n", pid, errno);
 
+       err = ptrace_setfpregs(pid, fp_regs);
+       if(err < 0)
+               panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
+                     "pid = %d, errno = %d\n", pid, errno);
+
        /* set a well known return code for detection of child write failure */
        child_data->err = 12345678;
 
@@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
        set_signals(flags);
 }
 
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
+
 void thread_wait(void *sw, void *fb)
 {
        sigjmp_buf buf, **switch_buf = sw, *fork_buf;
index 6c5b17ed59e1170baca1f67854211d2c127e869a..829d6b0d8b02496821ff14a0a7c869192383368a 100644 (file)
@@ -49,6 +49,7 @@ static int ptrace_child(void *arg)
        int pid = os_getpid(), ppid = getppid();
        int sc_result;
 
+       change_sig(SIGWINCH, 0);
        if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
                perror("ptrace");
                os_kill_process(pid, 0);
index aee4812333c6ebebb6b821ebb92ac28820fcaf34..7a6f6b99ceff29d94fcc6ac0ba0ec5e6ea04e37b 100644 (file)
@@ -122,9 +122,12 @@ void init_registers(int pid)
                      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+       if(fp_regs != NULL)
+               memcpy(fp_regs, exec_fp_regs,
+                      HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
index 4b638dfb52b07b73cbf7cb450513417510c5bb8e..001941fa1a1ec6d59f0f39c669dc796fad01530d 100644 (file)
@@ -70,9 +70,12 @@ void init_registers(int pid)
                      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+       if(fp_regs != NULL)
+               memcpy(fp_regs, exec_fp_regs,
+                      HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
index 12e404c6fa467f5789c5dbe66e41a60ddb722e6e..b5f9c33e311e1b17bfdaf798365d299d0e9585a1 100644 (file)
@@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs)
        return(0);
 }
 
+int ptrace_setfpregs(long pid, unsigned long *regs)
+{
+       if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
+               return -errno;
+       return 0;
+}
+
 void ptrace_pokeuser(unsigned long addr, unsigned long data)
 {
        panic("ptrace_pokeuser");
index 5a585bfbb8c2148101f1195be7b70cdf6f054e5b..7bd54a921cf791028f26b9b5258096d8a2206328 100644 (file)
@@ -57,7 +57,7 @@ void foo(void)
 #endif
 
        DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
-       DEFINE(HOST_FP_SIZE, 0);
+       DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
        DEFINE(HOST_XFP_SIZE, 0);
        DEFINE_LONGS(HOST_RBX, RBX);
        DEFINE_LONGS(HOST_RCX, RCX);
index 7f0efaa025c9ba99fe2e130ac502824ae70ffcc5..3975aa02cef83df866a58085bb384715c87a3423 100644 (file)
@@ -117,6 +117,7 @@ late_initcall(simcons_tty_init);
    tty driver.  */
 void simcons_poll_tty (struct tty_struct *tty)
 {
+       char buf[32];   /* Not the nicest way to do it but I need it correct first */
        int flip = 0, send_break = 0;
        struct pollfd pfd;
        pfd.fd = 0;
@@ -124,21 +125,15 @@ void simcons_poll_tty (struct tty_struct *tty)
 
        if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) {
                if (pfd.revents & POLLIN) {
-                       int left = TTY_FLIPBUF_SIZE - tty->flip.count;
-
-                       if (left > 0) {
-                               unsigned char *buf = tty->flip.char_buf_ptr;
-                               int rd = V850_SIM_SYSCALL (read, 0, buf, left);
-
-                               if (rd > 0) {
-                                       tty->flip.count += rd;
-                                       tty->flip.char_buf_ptr += rd;
-                                       memset (tty->flip.flag_buf_ptr, 0, rd);
-                                       tty->flip.flag_buf_ptr += rd;
-                                       flip = 1;
-                               } else
-                                       send_break = 1;
-                       }
+                       /* Real block hardware knows the transfer size before
+                          transfer so the new tty buffering doesn't try to handle
+                          this rather weird simulator specific case well */
+                       int rd = V850_SIM_SYSCALL (read, 0, buf, 32);
+                       if (rd > 0) {
+                               tty_insert_flip_string(tty, buf, rd);
+                               flip = 1;
+                       } else
+                               send_break = 1;
                } else if (pfd.revents & POLLERR)
                        send_break = 1;
        }
index fcb06a50fdd2c6e7b05b57704c4ad504e98b40cc..ea31b4c62105cfc808ce0278bee31228dd0bab23 100644 (file)
@@ -2,13 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config INIT_DEBUG
-       bool "Debug __init statements"
-       depends on DEBUG_KERNEL
-       help
-         Fill __init and __initdata at the end of boot. This helps debugging
-         illegal uses of __init and __initdata after initialization.
-
 config DEBUG_RODATA
        bool "Write protect kernel read-only data structures"
        depends on DEBUG_KERNEL
index 09a3eb743315313b4770ce37982893a09fe4bbbe..56832929a54398279bcd4f218b264d12dd793e10 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-git12
-# Mon Jan 16 13:09:08 2006
+# Linux kernel version: 2.6.16-rc1-git2
+# Thu Jan 19 10:05:21 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -310,6 +310,11 @@ CONFIG_IPV6=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -319,11 +324,6 @@ CONFIG_IPV6=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -1097,6 +1097,12 @@ CONFIG_USB_MON=y
 # SN Devices
 #
 
+#
+# EDAC - error detection and reporting (RAS)
+#
+# CONFIG_EDAC is not set
+# CONFIG_EDAC_POLL is not set
+
 #
 # Firmware Drivers
 #
@@ -1290,6 +1296,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_INIT_DEBUG=y
 # CONFIG_DEBUG_RODATA is not set
index 067c0f47bd0d75baadbcfc4330519eb798826c48..ada4535d0161d785d1d3b5121630cb9189dc0afc 100644 (file)
@@ -685,6 +685,9 @@ ia32_sys_call_table:
        .quad sys_readlinkat            /* 305 */
        .quad sys_fchmodat
        .quad sys_faccessat
+       .quad sys_ni_syscall            /* pselect6 for now */
+       .quad sys_ni_syscall            /* ppoll for now */
+       .quad sys_unshare               /* 310 */
 ia32_syscall_end:              
        .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
                .quad ni_syscall
index 5d3c5b07b8db1271407e2ddaf26e909e70473109..6147770b43471be8b5fd721cde035af84aaf0184 100644 (file)
 #include <asm/mach_apic.h>
 #include <asm/nmi.h>
 #include <asm/idle.h>
+#include <asm/proto.h>
+#include <asm/timex.h>
 
 int apic_verbosity;
+int apic_runs_main_timer;
+int apic_calibrate_pmtmr __initdata;
 
 int disable_apic_timer __initdata;
 
@@ -68,6 +72,26 @@ int get_maxlvt(void)
        return maxlvt;
 }
 
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+       printk("unexpected IRQ trap at vector %02x\n", irq);
+       /*
+        * Currently unexpected vectors happen only on SMP and APIC.
+        * We _must_ ack these because every local APIC has only N
+        * irq slots per priority level, and a 'hanging, unacked' IRQ
+        * holds up an irq slot - in excessive cases (when multiple
+        * unexpected vectors occur) that might lock up the APIC
+        * completely.
+        * But don't ack when the APIC is disabled. -AK
+        */
+       if (!disable_apic)
+               ack_APIC_irq();
+}
+
 void clear_local_APIC(void)
 {
        int maxlvt;
@@ -702,9 +726,17 @@ static void setup_APIC_timer(unsigned int clocks)
                        c2 |= inb_p(0x40) << 8;
                } while (c2 - c1 < 300);
        }
-
        __setup_APIC_LVTT(clocks);
-
+       /* Turn off PIT interrupt if we use APIC timer as main timer.
+          Only works with the PM timer right now
+          TBD fix it for HPET too. */
+       if (vxtime.mode == VXTIME_PMTMR &&
+               smp_processor_id() == boot_cpu_id &&
+               apic_runs_main_timer == 1 &&
+               !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) {
+               stop_timer_interrupt();
+               apic_runs_main_timer++;
+       }
        local_irq_restore(flags);
 }
 
@@ -735,14 +767,27 @@ static int __init calibrate_APIC_clock(void)
        __setup_APIC_LVTT(1000000000);
 
        apic_start = apic_read(APIC_TMCCT);
-       rdtscl(tsc_start);
-
-       do {
+#ifdef CONFIG_X86_PM_TIMER
+       if (apic_calibrate_pmtmr && pmtmr_ioport) {
+               pmtimer_wait(5000);  /* 5ms wait */
                apic = apic_read(APIC_TMCCT);
-               rdtscl(tsc);
-       } while ((tsc - tsc_start) < TICK_COUNT && (apic - apic_start) < TICK_COUNT);
+               result = (apic_start - apic) * 1000L / 5;
+       } else
+#endif
+       {
+               rdtscl(tsc_start);
+
+               do {
+                       apic = apic_read(APIC_TMCCT);
+                       rdtscl(tsc);
+               } while ((tsc - tsc_start) < TICK_COUNT &&
+                               (apic - apic_start) < TICK_COUNT);
+
+               result = (apic_start - apic) * 1000L * cpu_khz /
+                                       (tsc - tsc_start);
+       }
+       printk("result %d\n", result);
 
-       result = (apic_start - apic) * 1000L * cpu_khz / (tsc - tsc_start);
 
        printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
                result / 1000 / 1000, result / 1000 % 1000);
@@ -872,6 +917,8 @@ void smp_local_timer_interrupt(struct pt_regs *regs)
 #ifdef CONFIG_SMP
        update_process_times(user_mode(regs));
 #endif
+       if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id)
+               main_timer_handler(regs);
        /*
         * We take the 'long' return path, and there every subsystem
         * grabs the appropriate locks (kernel lock/ irq lock).
@@ -924,7 +971,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
  * multi-chassis. Use available data to take a good guess.
  * If in doubt, go HPET.
  */
-__init int oem_force_hpet_timer(void)
+__cpuinit int oem_force_hpet_timer(void)
 {
        int i, clusters, zeros;
        unsigned id;
@@ -1081,10 +1128,34 @@ static __init int setup_nolapic(char *str)
 
 static __init int setup_noapictimer(char *str) 
 { 
+       if (str[0] != ' ' && str[0] != 0)
+               return -1;
        disable_apic_timer = 1;
        return 0;
 } 
 
+static __init int setup_apicmaintimer(char *str)
+{
+       apic_runs_main_timer = 1;
+       nohpet = 1;
+       return 0;
+}
+__setup("apicmaintimer", setup_apicmaintimer);
+
+static __init int setup_noapicmaintimer(char *str)
+{
+       apic_runs_main_timer = -1;
+       return 0;
+}
+__setup("noapicmaintimer", setup_noapicmaintimer);
+
+static __init int setup_apicpmtimer(char *s)
+{
+       apic_calibrate_pmtmr = 1;
+       return setup_apicmaintimer(NULL);
+}
+__setup("apicpmtimer", setup_apicpmtimer);
+
 /* dummy parsing: see setup.c */
 
 __setup("disableapic", setup_disableapic); 
index dbdba56e8faad4fa77fa1b87f212c309b201ffd7..b150c87a08c6b3131909d8af5b567699e58ce098 100644 (file)
@@ -499,7 +499,9 @@ ENTRY(stub_rt_sigreturn)
        movq %gs:pda_irqstackptr,%rax
        cmoveq %rax,%rsp /*todo This needs CFI annotation! */
        pushq %rdi                      # save old stack        
+#ifndef CONFIG_DEBUG_INFO
        CFI_ADJUST_CFA_OFFSET   8
+#endif
        call \func
        .endm
 
@@ -509,7 +511,9 @@ ENTRY(common_interrupt)
        /* 0(%rsp): oldrsp-ARGOFFSET */
 ret_from_intr:
        popq  %rdi
+#ifndef CONFIG_DEBUG_INFO
        CFI_ADJUST_CFA_OFFSET   -8
+#endif
        cli     
        decl %gs:pda_irqcount
 #ifdef CONFIG_DEBUG_INFO
@@ -922,7 +926,7 @@ KPROBE_ENTRY(debug)
        .previous .text
 
        /* runs on exception stack */   
-ENTRY(nmi)
+KPROBE_ENTRY(nmi)
        INTR_FRAME
        pushq $-1
        CFI_ADJUST_CFA_OFFSET 8
@@ -969,6 +973,7 @@ paranoid_schedule:
        cli
        jmp paranoid_userspace
        CFI_ENDPROC
+       .previous .text
 
 KPROBE_ENTRY(int3)
        INTR_FRAME
index 1a5060b434b8a8858d2be94d3aaa2eb05c4e32fd..4282d72b2a260e28c2aa2c9c272b8b8ef8621d7b 100644 (file)
@@ -304,6 +304,14 @@ void __init check_ioapic(void)
 #endif
                                        /* RED-PEN skip them on mptables too? */
                                        return;
+                               case PCI_VENDOR_ID_ATI:
+                                       if (apic_runs_main_timer != 0)
+                                               break;
+                                       printk(KERN_INFO
+            "ATI board detected. Using APIC/PM timer.\n");
+                                       apic_runs_main_timer = 1;
+                                       nohpet = 1;
+                                       return;
                                } 
 
                                /* No multi-function device? */
index 13a2eada6c9520e2e32d38e278f6e57e8c06cd53..b8b9529fa89e0db08b90cc6d6bea4da6fa7e0afb 100644 (file)
@@ -380,7 +380,7 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
  */
 void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
-       static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
+       static cpumask_t mce_cpus = CPU_MASK_NONE;
 
        mce_cpu_quirks(c); 
 
index 5fae6f0cd9947d16cc5530777268c80d36490a0b..8be407a1f62d11db0c06fc73cb4e0208037e986d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sysdev.h>
 #include <linux/nmi.h>
 #include <linux/sysctl.h>
+#include <linux/kprobes.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -468,7 +469,7 @@ void touch_nmi_watchdog (void)
        touch_softlockup_watchdog();
 }
 
-void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
+void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
 {
        int sum;
        int touched = 0;
@@ -512,14 +513,14 @@ void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
        }
 }
 
-static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
+static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu)
 {
        return 0;
 }
  
 static nmi_callback_t nmi_callback = dummy_nmi_callback;
  
-asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
+asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
        int cpu = safe_smp_processor_id();
 
index 2f5d8328e2b9452b52d3ffe168eea428e8ccc8d8..4ed391edd47abc6df903240d374c2c87863aec4a 100644 (file)
@@ -107,6 +107,9 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
                                goto again;
                        }
 
+                       /* Let low level make its own zone decisions */
+                       gfp &= ~(GFP_DMA32|GFP_DMA);
+
                        if (dma_ops->alloc_coherent)
                                return dma_ops->alloc_coherent(dev, size,
                                                           dma_handle, gfp);
index c37fc7726ba6704a5ff02a2ca6f32463f2420d8d..2fe23a6c361bbfa77524472027e47680b2bf05b4 100644 (file)
@@ -457,9 +457,12 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 error:
        flush_gart(NULL);
        gart_unmap_sg(dev, sg, nents, dir);
-       /* When it was forced try again unforced */
-       if (force_iommu) 
-               return dma_map_sg_nonforce(dev, sg, nents, dir);
+       /* When it was forced or merged try again in a dumb way */
+       if (force_iommu || iommu_merge) {
+               out = dma_map_sg_nonforce(dev, sg, nents, dir);
+               if (out > 0)
+                       return out;
+       }
        if (panic_on_overflow)
                panic("dma_map_sg: overflow on %lu pages\n", pages);
        iommu_full(dev, pages << PAGE_SHIFT, dir);
@@ -642,9 +645,18 @@ static int __init pci_iommu_init(void)
            (no_agp && init_k8_gatt(&info) < 0)) {
                no_iommu = 1;
                no_iommu_init();
+               printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
+               if (end_pfn > MAX_DMA32_PFN) {
+                       printk(KERN_ERR "WARNING more than 4GB of memory "
+                                       "but IOMMU not compiled in.\n"
+                              KERN_ERR "WARNING 32bit PCI may malfunction.\n"
+                              KERN_ERR "You might want to enable "
+                                       "CONFIG_GART_IOMMU\n");
+               }
                return -1;
        }
 
+       printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
        aper_size = info.aper_size * 1024 * 1024;       
        iommu_size = check_iommu_size(info.aper_base, aper_size); 
        iommu_pages = iommu_size >> PAGE_SHIFT; 
@@ -718,7 +730,6 @@ static int __init pci_iommu_init(void)
                     
        flush_gart(NULL);
 
-       printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
        dma_ops = &gart_dma_ops;
 
        return 0;
index e415649751950d142c6c72c4ba9e2a4bc73a06d7..44adcc2d5e5be43299d8f640161c6ec50658c285 100644 (file)
@@ -88,12 +88,5 @@ void __init no_iommu_init(void)
 {
        if (dma_ops)
                return;
-       printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
        dma_ops = &nommu_dma_ops;
-       if (end_pfn > MAX_DMA32_PFN) {
-               printk(KERN_ERR
-                      "WARNING more than 4GB of memory but IOMMU not compiled in.\n"
-                      KERN_ERR "WARNING 32bit PCI may malfunction.\n"
-                      KERN_ERR "You might want to enable CONFIG_GART_IOMMU\n");
-       }
 }
index 3569a25ad7fb748d559efa73af1cb5a4d0562d5a..990ed67896f2ff514cc6283a65fea24fa00adcf1 100644 (file)
@@ -35,8 +35,8 @@ void pci_swiotlb_init(void)
            (end_pfn > MAX_DMA32_PFN || force_iommu))
               swiotlb = 1;
        if (swiotlb) {
-               swiotlb_init();
                printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
+               swiotlb_init();
                dma_ops = &swiotlb_dma_ops;
        }
 }
index feb5f108dd26e8a193232046f8ee976293bf0acb..5c51d10408a677695c9f2d2d8cd0e5d69571c760 100644 (file)
@@ -80,6 +80,31 @@ int pmtimer_mark_offset(void)
        return lost - 1;
 }
 
+static unsigned pmtimer_wait_tick(void)
+{
+       u32 a, b;
+       for (a = b = inl(pmtmr_ioport) & ACPI_PM_MASK;
+            a == b;
+            b = inl(pmtmr_ioport) & ACPI_PM_MASK)
+               ;
+       return b;
+}
+
+/* note: wait time is rounded up to one tick */
+void pmtimer_wait(unsigned us)
+{
+       u32 a, b;
+       a = pmtimer_wait_tick();
+       do {
+               b = inl(pmtmr_ioport);
+       } while (cyc2us(b - a) < us);
+}
+
+void pmtimer_resume(void)
+{
+       last_pmtmr_tick = inl(pmtmr_ioport);
+}
+
 unsigned int do_gettimeoffset_pm(void)
 {
        u32 now, offset, delta = 0;
index 8ded407e4a9419fd5bcd57dea91e5ef42ad0d41a..22a05dec81a224491b4a5bf859507e1fa7b11966 100644 (file)
@@ -516,8 +516,10 @@ out:
  * This could still be optimized: 
  * - fold all the options into a flag word and test it with a single test.
  * - could test fs/gs bitsliced
+ *
+ * Kprobes not supported here. Set the probe on schedule instead.
  */
-struct task_struct *
+__kprobes struct task_struct *
 __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
        struct thread_struct *prev = &prev_p->thread,
index 28895c03cb11e537c2ba422a991f0d6bf4f87c5a..9435ab7d6fb83131a6efd4b24a9d6cd7621a76fd 100644 (file)
@@ -94,7 +94,6 @@ unsigned long saved_video_mode;
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 struct sys_desc_table_struct {
        unsigned short length;
@@ -572,7 +571,6 @@ void __init setup_arch(char **cmdline_p)
        unsigned long kernel_end;
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-       drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
        edid_info = EDID_INFO;
        saved_video_mode = SAVED_VIDEO_MODE;
@@ -741,7 +739,7 @@ void __init setup_arch(char **cmdline_p)
        e820_setup_gap();
 
 #ifdef CONFIG_GART_IOMMU
-       iommu_hole_init();
+       iommu_hole_init();
 #endif
 
 #ifdef CONFIG_VT
@@ -877,6 +875,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
        int r;
+       unsigned level;
 
 #ifdef CONFIG_SMP
        unsigned long value;
@@ -899,6 +898,11 @@ static int __init init_amd(struct cpuinfo_x86 *c)
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
        clear_bit(0*32+31, &c->x86_capability);
        
+       /* On C+ stepping K8 rep microcode works well for copy/memset */
+       level = cpuid_eax(1);
+       if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
+               set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
+
        r = get_model_name(c);
        if (!r) { 
                switch (c->x86) { 
index a28756ef7cef972dcfd8fff90b1f8a7a19ff5e4a..67e4e28f4df8d79d9b97d76b7e2ec0fbf794f5e1 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/nmi.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/numa.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -890,6 +891,7 @@ do_rest:
        if (boot_error) {
                cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
                clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+               clear_node_cpumask(cpu); /* was set by numa_add_cpu */
                cpu_clear(cpu, cpu_present_map);
                cpu_clear(cpu, cpu_possible_map);
                x86_cpu_to_apicid[cpu] = BAD_APICID;
@@ -1187,6 +1189,7 @@ void remove_cpu_from_maps(void)
        cpu_clear(cpu, cpu_callout_map);
        cpu_clear(cpu, cpu_callin_map);
        clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+       clear_node_cpumask(cpu);
 }
 
 int __cpu_disable(void)
index f8c47c688443a612c0d328240d4491dbb456a44b..dba7237be5c1c2b2b2e8ae28a5ca5a5ecf34aa65 100644 (file)
@@ -51,7 +51,7 @@ extern int using_apic_timer;
 DEFINE_SPINLOCK(rtc_lock);
 DEFINE_SPINLOCK(i8253_lock);
 
-static int nohpet __initdata = 0;
+int nohpet __initdata = 0;
 static int notsc __initdata = 0;
 
 #undef HPET_HACK_ENABLE_DANGEROUS
@@ -345,7 +345,7 @@ static noinline void handle_lost_ticks(int lost, struct pt_regs *regs)
 #endif
 }
 
-static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void main_timer_handler(struct pt_regs *regs)
 {
        static unsigned long rtc_update = 0;
        unsigned long tsc;
@@ -458,12 +458,17 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
  
        write_sequnlock(&xtime_lock);
+}
 
+static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       if (apic_runs_main_timer > 1)
+               return IRQ_HANDLED;
+       main_timer_handler(regs);
 #ifdef CONFIG_X86_LOCAL_APIC
        if (using_apic_timer)
                smp_send_timer_broadcast_ipi();
 #endif
-
        return IRQ_HANDLED;
 }
 
@@ -743,7 +748,7 @@ static __init int late_hpet_init(void)
         * Timer0 and Timer1 is used by platform.
         */
        hd.hd_phys_address = vxtime.hpet_address;
-       hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE);
+       hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
        hd.hd_nirqs = ntimer;
        hd.hd_flags = HPET_DATA_PLATFORM;
        hpet_reserve_timer(&hd, 0);
@@ -843,17 +848,43 @@ static int hpet_reenable(void)
        return hpet_timer_stop_set_go(hpet_tick);
 }
 
-void __init pit_init(void)
+#define PIT_MODE 0x43
+#define PIT_CH0  0x40
+
+static void __init __pit_init(int val, u8 mode)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&i8253_lock, flags);
-       outb_p(0x34, 0x43);             /* binary, mode 2, LSB/MSB, ch 0 */
-       outb_p(LATCH & 0xff, 0x40);     /* LSB */
-       outb_p(LATCH >> 8, 0x40);       /* MSB */
+       outb_p(mode, PIT_MODE);
+       outb_p(val & 0xff, PIT_CH0);    /* LSB */
+       outb_p(val >> 8, PIT_CH0);      /* MSB */
        spin_unlock_irqrestore(&i8253_lock, flags);
 }
 
+void __init pit_init(void)
+{
+       __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
+}
+
+void __init pit_stop_interrupt(void)
+{
+       __pit_init(0, 0x30); /* mode 0 */
+}
+
+void __init stop_timer_interrupt(void)
+{
+       char *name;
+       if (vxtime.hpet_address) {
+               name = "HPET";
+               hpet_timer_stop_set_go(0);
+       } else {
+               name = "PIT";
+               pit_stop_interrupt();
+       }
+       printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
+}
+
 int __init time_setup(char *str)
 {
        report_lost_ticks = 1;
@@ -932,7 +963,7 @@ void __init time_init(void)
  * Make an educated guess if the TSC is trustworthy and synchronized
  * over all CPUs.
  */
-__init int unsynchronized_tsc(void)
+__cpuinit int unsynchronized_tsc(void)
 {
 #ifdef CONFIG_SMP
        if (oem_force_hpet_timer())
@@ -1016,9 +1047,21 @@ static int timer_resume(struct sys_device *dev)
        write_seqlock_irqsave(&xtime_lock,flags);
        xtime.tv_sec = sec;
        xtime.tv_nsec = 0;
+       if (vxtime.mode == VXTIME_HPET) {
+               if (hpet_use_timer)
+                       vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
+               else
+                       vxtime.last = hpet_readl(HPET_COUNTER);
+#ifdef CONFIG_X86_PM_TIMER
+       } else if (vxtime.mode == VXTIME_PMTMR) {
+               pmtimer_resume();
+#endif
+       } else
+               vxtime.last_tsc = get_cycles_sync();
        write_sequnlock_irqrestore(&xtime_lock,flags);
        jiffies += sleep_length;
        wall_jiffies += sleep_length;
+       monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
        touch_softlockup_watchdog();
        return 0;
 }
index 8bb0aeda78b91fcb70c7aa9544b3fc2e03543860..ee1b2da9e5e7d168de7de4053eaaed737dd4c3e9 100644 (file)
@@ -372,7 +372,7 @@ void out_of_line_bug(void)
 static DEFINE_SPINLOCK(die_lock);
 static int die_owner = -1;
 
-unsigned long oops_begin(void)
+unsigned __kprobes long oops_begin(void)
 {
        int cpu = safe_smp_processor_id();
        unsigned long flags;
@@ -391,7 +391,7 @@ unsigned long oops_begin(void)
        return flags;
 }
 
-void oops_end(unsigned long flags)
+void __kprobes oops_end(unsigned long flags)
 { 
        die_owner = -1;
        bust_spinlocks(0);
@@ -400,7 +400,7 @@ void oops_end(unsigned long flags)
                panic("Oops");
 }
 
-void __die(const char * str, struct pt_regs * regs, long err)
+void __kprobes __die(const char * str, struct pt_regs * regs, long err)
 {
        static int die_counter;
        printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
@@ -432,7 +432,7 @@ void die(const char * str, struct pt_regs * regs, long err)
        do_exit(SIGSEGV); 
 }
 
-void die_nmi(char *str, struct pt_regs *regs)
+void __kprobes die_nmi(char *str, struct pt_regs *regs)
 {
        unsigned long flags = oops_begin();
 
@@ -575,7 +575,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
        }
 }
 
-static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+mem_parity_error(unsigned char reason, struct pt_regs * regs)
 {
        printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
        printk("You probably have a hardware problem with your RAM chips\n");
@@ -585,7 +586,8 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
        outb(reason, 0x61);
 }
 
-static void io_check_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+io_check_error(unsigned char reason, struct pt_regs * regs)
 {
        printk("NMI: IOCK error (debug interrupt?)\n");
        show_registers(regs);
@@ -598,7 +600,8 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs)
        outb(reason, 0x61);
 }
 
-static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 {      printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
        printk("Dazed and confused, but trying to continue\n");
        printk("Do you have a strange power saving mode enabled?\n");
@@ -606,7 +609,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 
 /* Runs on IST stack. This code must keep interrupts off all the time.
    Nested NMIs are prevented by the CPU. */
-asmlinkage void default_do_nmi(struct pt_regs *regs)
+asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
 {
        unsigned char reason = 0;
        int cpu;
@@ -658,7 +661,7 @@ asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
 /* Help handler running on IST stack to switch back to user stack
    for scheduling or signal handling. The actual stack switch is done in
    entry.S */
-asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs)
+asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 {
        struct pt_regs *regs = eregs;
        /* Did already sync */
index b0eed1faf740c582c3eb4202a70d426ec98dca4b..74db0062d4a2cac4a0e832424969c5cb91d72fda 100644 (file)
@@ -172,13 +172,15 @@ SECTIONS
   . = ALIGN(4096);
   __initramfs_start = .;
   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
-  __initramfs_end = .; 
-  . = ALIGN(32);
+  __initramfs_end = .;
+  /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+
+   complain */
+  . = ALIGN(4096);     
+  __init_end = .;      
+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   __per_cpu_start = .;
   .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
-  . = ALIGN(4096);
-  __init_end = .;
 
   . = ALIGN(4096);
   __nosave_begin = .;
index b614d54d2ae46f2f1b02a410117740698c4aa4f8..3496abc8d372eb1dfe57297d032f670c2d839af9 100644 (file)
@@ -39,11 +39,6 @@ extern void __write_lock_failed(rwlock_t *rw);
 extern void __read_lock_failed(rwlock_t *rw);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 //EXPORT_SYMBOL(dump_fpu);
index 43d9fa136180f7376d6e45e0803fdd290c3a3ac7..1f81b79b796cc04e47ef0f22b98a79174b51279c 100644 (file)
@@ -5,8 +5,46 @@
        .globl clear_page
        .p2align 4
 clear_page:
+       xorl   %eax,%eax
+       movl   $4096/64,%ecx
+       .p2align 4
+.Lloop:
+       decl    %ecx
+#define PUT(x) movq %rax,x*8(%rdi)
+       movq %rax,(%rdi)
+       PUT(1)
+       PUT(2)
+       PUT(3)
+       PUT(4)
+       PUT(5)
+       PUT(6)
+       PUT(7)
+       leaq    64(%rdi),%rdi
+       jnz     .Lloop
+       nop
+       ret
+clear_page_end:
+
+       /* Some CPUs run faster using the string instructions.
+          It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+       .section .altinstructions,"a"
+       .align 8
+       .quad  clear_page
+       .quad  clear_page_c
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  clear_page_end-clear_page
+       .byte  clear_page_c_end-clear_page_c
+       .previous
+
+       .section .altinstr_replacement,"ax"
+clear_page_c:
        movl $4096/8,%ecx
        xorl %eax,%eax
        rep 
        stosq
        ret
+clear_page_c_end:
+       .previous
index 621a19769406c2f25dbd4b04bc578027e6c03958..8fa19d96a7eefde6b7d591fba46705486055818f 100644 (file)
@@ -8,7 +8,94 @@
        .globl copy_page
        .p2align 4
 copy_page:
+       subq    $3*8,%rsp
+       movq    %rbx,(%rsp)
+       movq    %r12,1*8(%rsp)
+       movq    %r13,2*8(%rsp)
+
+       movl    $(4096/64)-5,%ecx
+       .p2align 4
+.Loop64:
+       dec     %rcx
+
+       movq        (%rsi), %rax
+       movq      8 (%rsi), %rbx
+       movq     16 (%rsi), %rdx
+       movq     24 (%rsi), %r8
+       movq     32 (%rsi), %r9
+       movq     40 (%rsi), %r10
+       movq     48 (%rsi), %r11
+       movq     56 (%rsi), %r12
+
+       prefetcht0 5*64(%rsi)
+
+       movq     %rax,    (%rdi)
+       movq     %rbx,  8 (%rdi)
+       movq     %rdx, 16 (%rdi)
+       movq     %r8,  24 (%rdi)
+       movq     %r9,  32 (%rdi)
+       movq     %r10, 40 (%rdi)
+       movq     %r11, 48 (%rdi)
+       movq     %r12, 56 (%rdi)
+
+       leaq    64 (%rsi), %rsi
+       leaq    64 (%rdi), %rdi
+
+       jnz     .Loop64
+
+       movl    $5,%ecx
+       .p2align 4
+.Loop2:
+       decl   %ecx
+
+       movq        (%rsi), %rax
+       movq      8 (%rsi), %rbx
+       movq     16 (%rsi), %rdx
+       movq     24 (%rsi), %r8
+       movq     32 (%rsi), %r9
+       movq     40 (%rsi), %r10
+       movq     48 (%rsi), %r11
+       movq     56 (%rsi), %r12
+
+       movq     %rax,    (%rdi)
+       movq     %rbx,  8 (%rdi)
+       movq     %rdx, 16 (%rdi)
+       movq     %r8,  24 (%rdi)
+       movq     %r9,  32 (%rdi)
+       movq     %r10, 40 (%rdi)
+       movq     %r11, 48 (%rdi)
+       movq     %r12, 56 (%rdi)
+
+       leaq    64(%rdi),%rdi
+       leaq    64(%rsi),%rsi
+
+       jnz     .Loop2
+
+       movq    (%rsp),%rbx
+       movq    1*8(%rsp),%r12
+       movq    2*8(%rsp),%r13
+       addq    $3*8,%rsp
+       ret
+
+       /* Some CPUs run faster using the string copy instructions.
+          It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+       .section .altinstructions,"a"
+       .align 8
+       .quad  copy_page
+       .quad  copy_page_c
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  copy_page_c_end-copy_page_c
+       .byte  copy_page_c_end-copy_page_c
+       .previous
+
+       .section .altinstr_replacement,"ax"
+copy_page_c:
        movl $4096/8,%ecx
        rep 
        movsq 
        ret
+copy_page_c_end:
+       .previous
index 79422b6559c33008dfb485ebf1638d5dfd71f973..f64569b83b548605c51d9ff6d31f4542eb9b59f9 100644 (file)
@@ -4,9 +4,12 @@
  * Functions to copy from and to user space.           
  */             
 
+#define FIX_ALIGNMENT 1
+
        #include <asm/current.h>
        #include <asm/asm-offsets.h>
        #include <asm/thread_info.h>
+       #include <asm/cpufeature.h>
 
 /* Standard copy_to_user with segment limit checking */                
        .globl copy_to_user
@@ -18,7 +21,23 @@ copy_to_user:
        jc  bad_to_user
        cmpq threadinfo_addr_limit(%rax),%rcx
        jae bad_to_user
-       jmp copy_user_generic
+2:
+       .byte 0xe9      /* 32bit jump */
+       .long .Lcug-1f
+1:
+
+       .section .altinstr_replacement,"ax"
+3:     .byte 0xe9                      /* replacement jmp with 8 bit immediate */
+       .long copy_user_generic_c-1b    /* offset */
+       .previous
+       .section .altinstructions,"a"
+       .align 8
+       .quad  2b
+       .quad  3b
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  5
+       .byte  5
+       .previous
 
 /* Standard copy_from_user with segment limit checking */      
        .globl copy_from_user
@@ -53,44 +72,230 @@ bad_to_user:
  * rsi source
  * rdx count
  *
- * Only 4GB of copy is supported. This shouldn't be a problem
- * because the kernel normally only writes from/to page sized chunks
- * even if user space passed a longer buffer.
- * And more would be dangerous because both Intel and AMD have
- * errata with rep movsq > 4GB. If someone feels the need to fix
- * this please consider this.
- *
  * Output:             
  * eax uncopied bytes or 0 if successful.
  */
-
        .globl copy_user_generic
+       .p2align 4
 copy_user_generic:
+       .byte 0x66,0x66,0x90    /* 5 byte nop for replacement jump */
+       .byte 0x66,0x90
+1:
+       .section .altinstr_replacement,"ax"
+2:     .byte 0xe9                   /* near jump with 32bit immediate */
+       .long copy_user_generic_c-1b /* offset */
+       .previous
+       .section .altinstructions,"a"
+       .align 8
+       .quad  copy_user_generic
+       .quad  2b
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  5
+       .byte  5
+       .previous
+.Lcug:
+       pushq %rbx
+       xorl %eax,%eax          /*zero for the exception handler */
+
+#ifdef FIX_ALIGNMENT
+       /* check for bad alignment of destination */
+       movl %edi,%ecx
+       andl $7,%ecx
+       jnz  .Lbad_alignment
+.Lafter_bad_alignment:
+#endif
+
+       movq %rdx,%rcx
+
+       movl $64,%ebx
+       shrq $6,%rdx
+       decq %rdx
+       js   .Lhandle_tail
+
+       .p2align 4
+.Lloop:
+.Ls1:  movq (%rsi),%r11
+.Ls2:  movq 1*8(%rsi),%r8
+.Ls3:  movq 2*8(%rsi),%r9
+.Ls4:  movq 3*8(%rsi),%r10
+.Ld1:  movq %r11,(%rdi)
+.Ld2:  movq %r8,1*8(%rdi)
+.Ld3:  movq %r9,2*8(%rdi)
+.Ld4:  movq %r10,3*8(%rdi)
+
+.Ls5:  movq 4*8(%rsi),%r11
+.Ls6:  movq 5*8(%rsi),%r8
+.Ls7:  movq 6*8(%rsi),%r9
+.Ls8:  movq 7*8(%rsi),%r10
+.Ld5:  movq %r11,4*8(%rdi)
+.Ld6:  movq %r8,5*8(%rdi)
+.Ld7:  movq %r9,6*8(%rdi)
+.Ld8:  movq %r10,7*8(%rdi)
+
+       decq %rdx
+
+       leaq 64(%rsi),%rsi
+       leaq 64(%rdi),%rdi
+
+       jns  .Lloop
+
+       .p2align 4
+.Lhandle_tail:
+       movl %ecx,%edx
+       andl $63,%ecx
+       shrl $3,%ecx
+       jz   .Lhandle_7
+       movl $8,%ebx
+       .p2align 4
+.Lloop_8:
+.Ls9:  movq (%rsi),%r8
+.Ld9:  movq %r8,(%rdi)
+       decl %ecx
+       leaq 8(%rdi),%rdi
+       leaq 8(%rsi),%rsi
+       jnz .Lloop_8
+
+.Lhandle_7:
+       movl %edx,%ecx
+       andl $7,%ecx
+       jz   .Lende
+       .p2align 4
+.Lloop_1:
+.Ls10: movb (%rsi),%bl
+.Ld10: movb %bl,(%rdi)
+       incq %rdi
+       incq %rsi
+       decl %ecx
+       jnz .Lloop_1
+
+.Lende:
+       popq %rbx
+       ret
+
+#ifdef FIX_ALIGNMENT
+       /* align destination */
+       .p2align 4
+.Lbad_alignment:
+       movl $8,%r9d
+       subl %ecx,%r9d
+       movl %r9d,%ecx
+       cmpq %r9,%rdx
+       jz   .Lhandle_7
+       js   .Lhandle_7
+.Lalign_1:
+.Ls11: movb (%rsi),%bl
+.Ld11: movb %bl,(%rdi)
+       incq %rsi
+       incq %rdi
+       decl %ecx
+       jnz .Lalign_1
+       subq %r9,%rdx
+       jmp .Lafter_bad_alignment
+#endif
+
+       /* table sorted by exception address */
+       .section __ex_table,"a"
+       .align 8
+       .quad .Ls1,.Ls1e
+       .quad .Ls2,.Ls2e
+       .quad .Ls3,.Ls3e
+       .quad .Ls4,.Ls4e
+       .quad .Ld1,.Ls1e
+       .quad .Ld2,.Ls2e
+       .quad .Ld3,.Ls3e
+       .quad .Ld4,.Ls4e
+       .quad .Ls5,.Ls5e
+       .quad .Ls6,.Ls6e
+       .quad .Ls7,.Ls7e
+       .quad .Ls8,.Ls8e
+       .quad .Ld5,.Ls5e
+       .quad .Ld6,.Ls6e
+       .quad .Ld7,.Ls7e
+       .quad .Ld8,.Ls8e
+       .quad .Ls9,.Le_quad
+       .quad .Ld9,.Le_quad
+       .quad .Ls10,.Le_byte
+       .quad .Ld10,.Le_byte
+#ifdef FIX_ALIGNMENT
+       .quad .Ls11,.Lzero_rest
+       .quad .Ld11,.Lzero_rest
+#endif
+       .quad .Le5,.Le_zero
+       .previous
+
+       /* compute 64-offset for main loop. 8 bytes accuracy with error on the
+          pessimistic side. this is gross. it would be better to fix the
+          interface. */
+       /* eax: zero, ebx: 64 */
+.Ls1e:         addl $8,%eax
+.Ls2e:         addl $8,%eax
+.Ls3e:         addl $8,%eax
+.Ls4e:         addl $8,%eax
+.Ls5e:         addl $8,%eax
+.Ls6e:         addl $8,%eax
+.Ls7e:         addl $8,%eax
+.Ls8e:         addl $8,%eax
+       addq %rbx,%rdi  /* +64 */
+       subq %rax,%rdi  /* correct destination with computed offset */
+
+       shlq $6,%rdx    /* loop counter * 64 (stride length) */
+       addq %rax,%rdx  /* add offset to loopcnt */
+       andl $63,%ecx   /* remaining bytes */
+       addq %rcx,%rdx  /* add them */
+       jmp .Lzero_rest
+
+       /* exception on quad word loop in tail handling */
+       /* ecx: loopcnt/8, %edx: length, rdi: correct */
+.Le_quad:
+       shll $3,%ecx
+       andl $7,%edx
+       addl %ecx,%edx
+       /* edx: bytes to zero, rdi: dest, eax:zero */
+.Lzero_rest:
+       movq %rdx,%rcx
+.Le_byte:
+       xorl %eax,%eax
+.Le5:  rep
+       stosb
+       /* when there is another exception while zeroing the rest just return */
+.Le_zero:
+       movq %rdx,%rax
+       jmp .Lende
+
+       /* Some CPUs run faster using the string copy instructions.
+          This is also a lot simpler. Use them when possible.
+          Patch in jmps to this code instead of copying it fully
+          to avoid unwanted aliasing in the exception tables. */
+
+ /* rdi        destination
+  * rsi source
+  * rdx count
+  *
+  * Output:
+  * eax uncopied bytes or 0 if successfull.
+  *
+  * Only 4GB of copy is supported. This shouldn't be a problem
+  * because the kernel normally only writes from/to page sized chunks
+  * even if user space passed a longer buffer.
+  * And more would be dangerous because both Intel and AMD have
+  * errata with rep movsq > 4GB. If someone feels the need to fix
+  * this please consider this.
+   */
+copy_user_generic_c:
        movl %edx,%ecx
        shrl $3,%ecx
        andl $7,%edx    
-       jz   5f
 1:     rep 
        movsq 
        movl %edx,%ecx
-       xor %eax,%eax
 2:     rep
        movsb
+4:     movl %ecx,%eax
        ret
-       /* align here? */
-5:     xorl %eax,%eax
-6:     rep movsq
-       ret
-
-       .section .fixup,"ax"
 3:     lea (%rdx,%rcx,8),%rax
        ret
-4:     movl %ecx,%eax
-       ret
-       .previous
 
        .section __ex_table,"a"
        .quad 1b,3b
        .quad 2b,4b
-       .quad 6b,4b
        .previous
index 92dd80544602053fc245b5112bd55f7184315e2e..5554948b55549e2c7837264ce9bcae6b552e5a94 100644 (file)
@@ -11,8 +11,6 @@
  * 
  * Output:
  * rax original destination
- * 
- * TODO: check best memcpy for PSC
  */    
 
        .globl __memcpy
        .p2align 4
 __memcpy:
 memcpy:                
+       pushq %rbx
+       movq %rdi,%rax
+
+       movl %edx,%ecx
+       shrl $6,%ecx
+       jz .Lhandle_tail
+
+       .p2align 4
+.Lloop_64:
+       decl %ecx
+
+       movq (%rsi),%r11
+       movq 8(%rsi),%r8
+
+       movq %r11,(%rdi)
+       movq %r8,1*8(%rdi)
+
+       movq 2*8(%rsi),%r9
+       movq 3*8(%rsi),%r10
+
+       movq %r9,2*8(%rdi)
+       movq %r10,3*8(%rdi)
+
+       movq 4*8(%rsi),%r11
+       movq 5*8(%rsi),%r8
+
+       movq %r11,4*8(%rdi)
+       movq %r8,5*8(%rdi)
+
+       movq 6*8(%rsi),%r9
+       movq 7*8(%rsi),%r10
+
+       movq %r9,6*8(%rdi)
+       movq %r10,7*8(%rdi)
+
+       leaq 64(%rsi),%rsi
+       leaq 64(%rdi),%rdi
+       jnz  .Lloop_64
+
+.Lhandle_tail:
+       movl %edx,%ecx
+       andl $63,%ecx
+       shrl $3,%ecx
+       jz   .Lhandle_7
+       .p2align 4
+.Lloop_8:
+       decl %ecx
+       movq (%rsi),%r8
+       movq %r8,(%rdi)
+       leaq 8(%rdi),%rdi
+       leaq 8(%rsi),%rsi
+       jnz  .Lloop_8
+
+.Lhandle_7:
+       movl %edx,%ecx
+       andl $7,%ecx
+       jz .Lende
+       .p2align 4
+.Lloop_1:
+       movb (%rsi),%r8b
+       movb %r8b,(%rdi)
+       incq %rdi
+       incq %rsi
+       decl %ecx
+       jnz .Lloop_1
+
+.Lende:
+       popq %rbx
+       ret
+.Lfinal:
+
+       /* Some CPUs run faster using the string copy instructions.
+          It is also a lot simpler. Use this when possible */
+
+       .section .altinstructions,"a"
+       .align 8
+       .quad  memcpy
+       .quad  memcpy_c
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  .Lfinal-memcpy
+       .byte  memcpy_c_end-memcpy_c
+       .previous
+
+       .section .altinstr_replacement,"ax"
+ /* rdi        destination
+  * rsi source
+  * rdx count
+  */
+memcpy_c:
        movq %rdi,%rax
        movl %edx,%ecx
        shrl $3,%ecx
@@ -30,3 +117,5 @@ memcpy:
        rep
        movsb
        ret
+memcpy_c_end:
+       .previous
index 2aa48f24ed1e48974680b5354ede86e826d5f0a4..ad397f2c7de8fa7c73185793ba973bdfaed39b0b 100644 (file)
        .p2align 4
 memset:        
 __memset:
+       movq %rdi,%r10
+       movq %rdx,%r11
+
+       /* expand byte value  */
+       movzbl %sil,%ecx
+       movabs $0x0101010101010101,%rax
+       mul    %rcx             /* with rax, clobbers rdx */
+
+       /* align dst */
+       movl  %edi,%r9d
+       andl  $7,%r9d
+       jnz  .Lbad_alignment
+.Lafter_bad_alignment:
+
+       movl %r11d,%ecx
+       shrl $6,%ecx
+       jz       .Lhandle_tail
+
+       .p2align 4
+.Lloop_64:
+       decl   %ecx
+       movq  %rax,(%rdi)
+       movq  %rax,8(%rdi)
+       movq  %rax,16(%rdi)
+       movq  %rax,24(%rdi)
+       movq  %rax,32(%rdi)
+       movq  %rax,40(%rdi)
+       movq  %rax,48(%rdi)
+       movq  %rax,56(%rdi)
+       leaq  64(%rdi),%rdi
+       jnz    .Lloop_64
+
+       /* Handle tail in loops. The loops should be faster than hard
+          to predict jump tables. */
+       .p2align 4
+.Lhandle_tail:
+       movl    %r11d,%ecx
+       andl    $63&(~7),%ecx
+       jz              .Lhandle_7
+       shrl    $3,%ecx
+       .p2align 4
+.Lloop_8:
+       decl   %ecx
+       movq  %rax,(%rdi)
+       leaq  8(%rdi),%rdi
+       jnz    .Lloop_8
+
+.Lhandle_7:
+       movl    %r11d,%ecx
+       andl    $7,%ecx
+       jz      .Lende
+       .p2align 4
+.Lloop_1:
+       decl    %ecx
+       movb    %al,(%rdi)
+       leaq    1(%rdi),%rdi
+       jnz     .Lloop_1
+
+.Lende:
+       movq    %r10,%rax
+       ret
+
+.Lbad_alignment:
+       cmpq $7,%r11
+       jbe     .Lhandle_7
+       movq %rax,(%rdi)        /* unaligned store */
+       movq $8,%r8
+       subq %r9,%r8
+       addq %r8,%rdi
+       subq %r8,%r11
+       jmp .Lafter_bad_alignment
+
+       /* Some CPUs run faster using the string instructions.
+          It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+       .section .altinstructions,"a"
+       .align 8
+       .quad  memset
+       .quad  memset_c
+       .byte  X86_FEATURE_REP_GOOD
+       .byte  memset_c_end-memset_c
+       .byte  memset_c_end-memset_c
+       .previous
+
+       .section .altinstr_replacement,"ax"
+ /* rdi        destination
+  * rsi value
+  * rdx count
+  */
+memset_c:
        movq %rdi,%r9
        movl %edx,%r8d
        andl $7,%r8d            
@@ -29,3 +121,5 @@ __memset:
        stosb
        movq %r9,%rax
        ret
+memset_c_end:
+       .previous
index 26eac194064b8a2851705db6cfa3bd1bd5bc5e8a..2e7c3c8ffe035d0981b29fd052da25cb86e21d41 100644 (file)
@@ -33,7 +33,6 @@
 #include <asm/proto.h>
 #include <asm/kdebug.h>
 #include <asm-generic/sections.h>
-#include <asm/kdebug.h>
 
 /* Page fault error code bits */
 #define PF_PROT        (1<<0)          /* or no page found */
@@ -157,8 +156,8 @@ void dump_pagetable(unsigned long address)
 
        pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); 
        pgd += pgd_index(address);
-       printk("PGD %lx ", pgd_val(*pgd));
        if (bad_address(pgd)) goto bad;
+       printk("PGD %lx ", pgd_val(*pgd));
        if (!pgd_present(*pgd)) goto ret; 
 
        pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address);
index 8b7f85608fa8d64f44bcd4b578a3f6b81887073c..cd25300726fc7ac184009b3cf926f758eeb4c1bb 100644 (file)
@@ -26,6 +26,10 @@ static nodemask_t nodes_found __initdata;
 static struct node nodes[MAX_NUMNODES] __initdata;
 static u8 pxm2node[256] = { [0 ... 255] = 0xff };
 
+/* Too small nodes confuse the VM badly. Usually they result
+   from BIOS bugs. */
+#define NODE_MIN_SIZE (4*1024*1024)
+
 static int node_to_pxm(int n);
 
 int pxm_to_node(int pxm)
@@ -131,7 +135,12 @@ void __init
 acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
 {
        int pxm, node;
-       if (srat_disabled() || pa->flags.enabled == 0)
+       if (srat_disabled())
+               return;
+       if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) {                bad_srat();
+               return;
+       }
+       if (pa->flags.enabled == 0)
                return;
        pxm = pa->proximity_domain;
        node = setup_node(pxm);
@@ -155,8 +164,16 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
        int node, pxm;
        int i;
 
-       if (srat_disabled() || ma->flags.enabled == 0)
+       if (srat_disabled())
+               return;
+       if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) {
+               bad_srat();
                return;
+       }
+       if (ma->flags.enabled == 0)
+               return;
+       start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
+       end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
        pxm = ma->proximity_domain;
        node = setup_node(pxm);
        if (node < 0) {
@@ -164,8 +181,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
                bad_srat();
                return;
        }
-       start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
-       end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
        /* It is fine to add this area to the nodes data it will be used later*/
        if (ma->flags.hot_pluggable == 1)
                printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n",
@@ -223,6 +238,16 @@ static int nodes_cover_memory(void)
        return 1;
 }
 
+static void unparse_node(int node)
+{
+       int i;
+       node_clear(node, nodes_parsed);
+       for (i = 0; i < MAX_LOCAL_APIC; i++) {
+               if (apicid_to_node[i] == node)
+                       apicid_to_node[i] = NUMA_NO_NODE;
+       }
+}
+
 void __init acpi_numa_arch_fixup(void) {}
 
 /* Use the information discovered above to actually set up the nodes. */
@@ -230,16 +255,16 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
 {
        int i;
 
-       if (acpi_numa <= 0)
-               return -1;
-
        /* First clean up the node list */
-       for_each_node_mask(i, nodes_parsed) {
+       for (i = 0; i < MAX_NUMNODES; i++) {
                cutoff_node(i, start, end);
-               if (nodes[i].start == nodes[i].end)
-                       node_clear(i, nodes_parsed);
+               if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE)
+                       unparse_node(i);
        }
 
+       if (acpi_numa <= 0)
+               return -1;
+
        if (!nodes_cover_memory()) {
                bad_srat();
                return -1;
index 00d4ddbf980ccdddf23153f3e2758ac72ef90f9a..18f371fe37f89639f06ba4e24f876ea9854fd003 100644 (file)
@@ -46,10 +46,10 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)
        if (pci_mmcfg_config_num == 1 &&
                cfg->pci_segment_group_number == 0 &&
                (cfg->start_bus_number | cfg->end_bus_number) == 0)
-               return cfg->base_address;
+               return pci_mmcfg_virt[0].virt;
 
        /* Fall back to type 0 */
-       return 0;
+       return NULL;
 }
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
index 4fbddf92a921e9d0c32b33e259c5a5f1026c72a2..94fdfe474ac1c1fe36284f0d4b6cced12bf3d520 100644 (file)
@@ -128,9 +128,7 @@ static void rs_poll(unsigned long priv)
 
        while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){
                __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0);
-               tty->flip.count++;
-               *tty->flip.char_buf_ptr++ = c;
-               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+               tty_insert_flip_char(tty, c, TTY_NORMAL);
                i++;
        }
 
index 96a61e029ce5e7858d2e024c08eff817b5a998d6..24b702d649a953977cafb7125ca1b81d73947cc3 100644 (file)
@@ -293,7 +293,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
 
        rq->flags &= ~REQ_STARTED;
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
 static void elv_drain_elevator(request_queue_t *q)
@@ -310,40 +310,11 @@ static void elv_drain_elevator(request_queue_t *q)
        }
 }
 
-void __elv_add_request(request_queue_t *q, struct request *rq, int where,
-                      int plug)
+void elv_insert(request_queue_t *q, struct request *rq, int where)
 {
        struct list_head *pos;
        unsigned ordseq;
 
-       if (q->ordcolor)
-               rq->flags |= REQ_ORDERED_COLOR;
-
-       if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
-               /*
-                * toggle ordered color
-                */
-               q->ordcolor ^= 1;
-
-               /*
-                * barriers implicitly indicate back insertion
-                */
-               if (where == ELEVATOR_INSERT_SORT)
-                       where = ELEVATOR_INSERT_BACK;
-
-               /*
-                * this request is scheduling boundary, update end_sector
-                */
-               if (blk_fs_request(rq)) {
-                       q->end_sector = rq_end_sector(rq);
-                       q->boundary_rq = rq;
-               }
-       } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
-               where = ELEVATOR_INSERT_BACK;
-
-       if (plug)
-               blk_plug_device(q);
-
        rq->q = q;
 
        switch (where) {
@@ -424,6 +395,42 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
        }
 }
 
+void __elv_add_request(request_queue_t *q, struct request *rq, int where,
+                      int plug)
+{
+       if (q->ordcolor)
+               rq->flags |= REQ_ORDERED_COLOR;
+
+       if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+               /*
+                * toggle ordered color
+                */
+               if (blk_barrier_rq(rq))
+                       q->ordcolor ^= 1;
+
+               /*
+                * barriers implicitly indicate back insertion
+                */
+               if (where == ELEVATOR_INSERT_SORT)
+                       where = ELEVATOR_INSERT_BACK;
+
+               /*
+                * this request is scheduling boundary, update
+                * end_sector
+                */
+               if (blk_fs_request(rq)) {
+                       q->end_sector = rq_end_sector(rq);
+                       q->boundary_rq = rq;
+               }
+       } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
+               where = ELEVATOR_INSERT_BACK;
+
+       if (plug)
+               blk_plug_device(q);
+
+       elv_insert(q, rq, where);
+}
+
 void elv_add_request(request_queue_t *q, struct request *rq, int where,
                     int plug)
 {
index f9fc07efd2da995d933fda955895175ec1e5012d..03d9c82b0fe7911fd6e922f746249795ccb80d46 100644 (file)
@@ -454,7 +454,7 @@ static void queue_flush(request_queue_t *q, unsigned which)
        rq->end_io = end_io;
        q->prepare_flush_fn(q, rq);
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 }
 
 static inline struct request *start_ordered(request_queue_t *q,
@@ -490,7 +490,7 @@ static inline struct request *start_ordered(request_queue_t *q,
        else
                q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 
        if (q->ordered & QUEUE_ORDERED_PREFLUSH) {
                queue_flush(q, QUEUE_ORDERED_PREFLUSH);
@@ -508,7 +508,7 @@ static inline struct request *start_ordered(request_queue_t *q,
 
 int blk_do_ordered(request_queue_t *q, struct request **rqp)
 {
-       struct request *rq = *rqp, *allowed_rq;
+       struct request *rq = *rqp;
        int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
 
        if (!q->ordseq) {
@@ -532,32 +532,26 @@ int blk_do_ordered(request_queue_t *q, struct request **rqp)
                }
        }
 
+       /*
+        * Ordered sequence in progress
+        */
+
+       /* Special requests are not subject to ordering rules. */
+       if (!blk_fs_request(rq) &&
+           rq != &q->pre_flush_rq && rq != &q->post_flush_rq)
+               return 1;
+
        if (q->ordered & QUEUE_ORDERED_TAG) {
+               /* Ordered by tag.  Blocking the next barrier is enough. */
                if (is_barrier && rq != &q->bar_rq)
                        *rqp = NULL;
-               return 1;
-       }
-
-       switch (blk_ordered_cur_seq(q)) {
-       case QUEUE_ORDSEQ_PREFLUSH:
-               allowed_rq = &q->pre_flush_rq;
-               break;
-       case QUEUE_ORDSEQ_BAR:
-               allowed_rq = &q->bar_rq;
-               break;
-       case QUEUE_ORDSEQ_POSTFLUSH:
-               allowed_rq = &q->post_flush_rq;
-               break;
-       default:
-               allowed_rq = NULL;
-               break;
+       } else {
+               /* Ordered by draining.  Wait for turn. */
+               WARN_ON(blk_ordered_req_seq(rq) < blk_ordered_cur_seq(q));
+               if (blk_ordered_req_seq(rq) > blk_ordered_cur_seq(q))
+                       *rqp = NULL;
        }
 
-       if (rq != allowed_rq &&
-           (blk_fs_request(rq) || rq == &q->pre_flush_rq ||
-            rq == &q->post_flush_rq))
-               *rqp = NULL;
-
        return 1;
 }
 
@@ -3453,7 +3447,7 @@ int __init blk_dev_init(void)
        iocontext_cachep = kmem_cache_create("blkdev_ioc",
                        sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL);
 
-       for (i = 0; i < NR_CPUS; i++)
+       for_each_cpu(i)
                INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
 
        open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
index cc72210687eb4f3a75e17ce39a46bfd2b4e70fa9..24f7af9d0abc226b2630f8e227ce05ffa8f1ff0e 100644 (file)
@@ -310,6 +310,8 @@ static int sg_io(struct file *file, request_queue_t *q,
        if (!rq->timeout)
                rq->timeout = BLK_DEFAULT_TIMEOUT;
 
+       rq->retries = 0;
+
        start_time = jiffies;
 
        /* ignore return value. All information is passed back to caller
@@ -427,6 +429,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
        rq->data = buffer;
        rq->data_len = bytes;
        rq->flags |= REQ_BLOCK_PC;
+       rq->retries = 0;
 
        blk_execute_rq(q, bd_disk, rq, 0);
        err = rq->errors & 0xff;        /* only 8 bit SCSI status */
index 47ac90e615f49f1ffd490662a9006d7171e38079..2953e2cc56f08c1af4fce898b991ad8e26011311 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
-#include <asm/bug.h>
 #include <asm/scatterlist.h>
 #include "internal.h"
 #include "scatterwalk.h"
index 619dd964c51cd549e906414cef6dc1d0a7f3cdea..5c69b86db6247a3f776ce8bde0ede999fdc274d6 100644 (file)
@@ -69,7 +69,7 @@ obj-$(CONFIG_EISA)            += eisa/
 obj-$(CONFIG_CPU_FREQ)         += cpufreq/
 obj-$(CONFIG_MMC)              += mmc/
 obj-$(CONFIG_INFINIBAND)       += infiniband/
-obj-$(CONFIG_SGI_IOC4)         += sn/
+obj-$(CONFIG_SGI_SN)           += sn/
 obj-y                          += firmware/
 obj-$(CONFIG_CRYPTO)           += crypto/
 obj-$(CONFIG_SUPERH)           += sh/
index be2dae52f6fa47a6b74dbca63c47a553236cfd27..eb730a80952c6bc58c0cf3b0be80b9daf4aaf993 100644 (file)
@@ -94,7 +94,9 @@ static int set_max_cstate(struct dmi_system_id *id)
        return 0;
 }
 
-static struct dmi_system_id __initdata processor_power_dmi_table[] = {
+/* Actually this shouldn't be __cpuinitdata, would be better to fix the
+   callers to only run once -AK */
+static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
        { set_max_cstate, "IBM ThinkPad R40e", {
          DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
          DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
@@ -899,7 +901,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
                case ACPI_STATE_C3:
                        acpi_processor_power_verify_c3(pr, cx);
 #ifdef ARCH_APICTIMER_STOPS_ON_C3
-                       if (c->x86_vendor == X86_VENDOR_INTEL) {
+                       if (cx->valid && c->x86_vendor == X86_VENDOR_INTEL) {
                                on_each_cpu(switch_APIC_timer_to_ipi,
                                                &mask, 1, 1);
                        }
index f12898d53078e9d4fbe21123e4283c8044387cc2..e99471d3232bb6d3fc70a33263986e2908d8751d 100644 (file)
@@ -8,6 +8,7 @@ obj-y                   += power/
 obj-$(CONFIG_FW_LOADER)        += firmware_class.o
 obj-$(CONFIG_NUMA)     += node.o
 obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
+obj-$(CONFIG_SMP)      += topology.o
 
 ifeq ($(CONFIG_DEBUG_DRIVER),y)
 EXTRA_CFLAGS += -DDEBUG
index e3b548d46cff829a34f0f0646afe2dc706b9b90b..5735b38582d0381872e9fda2198f2bc10147b913 100644 (file)
@@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *);
 extern void driver_detach(struct device_driver * drv);
 extern int driver_probe_device(struct device_driver *, struct device *);
 
+extern void sysdev_shutdown(void);
+extern int sysdev_suspend(pm_message_t state);
+extern int sysdev_resume(void);
+
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
        return container_of(obj, struct class_device, kobj);
index 29f6af554e715ed408f0f23e8da838284dbc9dc7..c3141565d59d503250fce52deddbd4df74ffe9ac 100644 (file)
@@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = {
 decl_subsys(bus, &ktype_bus, NULL);
 
 
+#ifdef CONFIG_HOTPLUG
+
 /* Manually detach a device from its associated driver. */
 static int driver_helper(struct device *dev, void *data)
 {
@@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv,
 }
 static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
 
+#endif
 
 static struct device * next_device(struct klist_iter * i)
 {
index d1a05224627ed36aec464213ac302e8c5494982b..105a0d61eb1f37dbe1bf51ef9ecfcb27098e947c 100644 (file)
@@ -303,7 +303,7 @@ static int block_size_init(void)
  */
 #ifdef CONFIG_ARCH_MEMORY_PROBE
 static ssize_t
-memory_probe_store(struct class *class, const char __user *buf, size_t count)
+memory_probe_store(struct class *class, const char *buf, size_t count)
 {
        u64 phys_addr;
        int ret;
index 0a7aa07b9a2a600cc9b52992b8e0f0d44216af17..317edbf0feca6b383fb95980968c28b9947e2970 100644 (file)
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_resume(void);
-
 
 /**
  *     resume_device - Restore state for one device.
index c2475f3134eae05e8d625af83a79afb210d07712..8826a5b6673eb9e4dfae4bb0d0b53126b77e4119 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "../base.h"
 #include "power.h"
 
 #define to_dev(node) container_of(node, struct device, kobj.entry)
@@ -28,7 +29,6 @@ extern struct subsystem devices_subsys;
  * they only get one called once when interrupts are disabled.
  */
 
-extern int sysdev_shutdown(void);
 
 /**
  * device_shutdown - call ->shutdown() on each device to shutdown.
index 50501764d0508a6493256380df820eb35b8c96e1..8660779fb288b3a29b1401b110ec2bd3289dfc15 100644 (file)
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_suspend(pm_message_t state);
-
 /*
  * The entries in the dpm_active list are in a depth first order, simply
  * because children are guaranteed to be discovered after parents, and
index f3a0c562bcb53ff019aa8db27cfd40860a1a6335..40d7242a07c18325b18539076b6a3918bb9e87ec 100644 (file)
 
 static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
-       return sprintf(buf, "%u\n", dev->power.power_state.event);
+       if (dev->power.power_state.event)
+               return sprintf(buf, "2\n");
+       else
+               return sprintf(buf, "0\n");
 }
 
 static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
 {
        pm_message_t state;
-       char * rest;
-       int error = 0;
+       int error = -EINVAL;
 
-       state.event = simple_strtoul(buf, &rest, 10);
-       if (*rest)
-               return -EINVAL;
-       if (state.event)
+       state.event = PM_EVENT_SUSPEND;
+       /* Older apps expected to write "3" here - confused with PCI D3 */
+       if ((n == 1) && !strcmp(buf, "3"))
                error = dpm_runtime_suspend(dev, state);
-       else
+
+       if ((n == 1) && !strcmp(buf, "2"))
+               error = dpm_runtime_suspend(dev, state);
+
+       if ((n == 1) && !strcmp(buf, "0")) {
                dpm_runtime_resume(dev);
+               error = 0;
+       }
+
        return error ? error : n;
 }
 
index 66ed8f2fece5009082d4e994622fcb5acc49f82e..6fc23ab127bd52abd01f10eb55136a7c3057a12b 100644 (file)
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "base.h"
+
 extern struct subsystem devices_subsys;
 
 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
new file mode 100644 (file)
index 0000000..915810f
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * driver/base/topology.c - Populate sysfs with cpu topology information
+ *
+ * Written by: Zhang Yanmin, Intel Corporation
+ *
+ * Copyright (C) 2006, Intel Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  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/sysdev.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+
+#define define_one_ro(_name)           \
+static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
+
+#define define_id_show_func(name)                              \
+static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+{                                                              \
+       unsigned int cpu = dev->id;                             \
+       return sprintf(buf, "%d\n", topology_##name(cpu));      \
+}
+
+#define define_siblings_show_func(name)                                        \
+static ssize_t show_##name(struct sys_device *dev, char *buf)          \
+{                                                                      \
+       ssize_t len = -1;                                               \
+       unsigned int cpu = dev->id;                                     \
+       len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu));  \
+       return (len + sprintf(buf + len, "\n"));                        \
+}
+
+#ifdef topology_physical_package_id
+define_id_show_func(physical_package_id);
+define_one_ro(physical_package_id);
+#define ref_physical_package_id_attr   &attr_physical_package_id.attr,
+#else
+#define ref_physical_package_id_attr
+#endif
+
+#ifdef topology_core_id
+define_id_show_func(core_id);
+define_one_ro(core_id);
+#define ref_core_id_attr               &attr_core_id.attr,
+#else
+#define ref_core_id_attr
+#endif
+
+#ifdef topology_thread_siblings
+define_siblings_show_func(thread_siblings);
+define_one_ro(thread_siblings);
+#define ref_thread_siblings_attr       &attr_thread_siblings.attr,
+#else
+#define ref_thread_siblings_attr
+#endif
+
+#ifdef topology_core_siblings
+define_siblings_show_func(core_siblings);
+define_one_ro(core_siblings);
+#define ref_core_siblings_attr         &attr_core_siblings.attr,
+#else
+#define ref_core_siblings_attr
+#endif
+
+static struct attribute *default_attrs[] = {
+       ref_physical_package_id_attr
+       ref_core_id_attr
+       ref_thread_siblings_attr
+       ref_core_siblings_attr
+       NULL
+};
+
+static struct attribute_group topology_attr_group = {
+       .attrs = default_attrs,
+       .name = "topology"
+};
+
+/* Add/Remove cpu_topology interface for CPU device */
+static int __cpuinit topology_add_dev(struct sys_device * sys_dev)
+{
+       sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
+       return 0;
+}
+
+static int __cpuinit topology_remove_dev(struct sys_device * sys_dev)
+{
+       sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
+       return 0;
+}
+
+static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,
+               unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long)hcpu;
+       struct sys_device *sys_dev;
+
+       sys_dev = get_cpu_sysdev(cpu);
+       switch (action) {
+       case CPU_ONLINE:
+               topology_add_dev(sys_dev);
+               break;
+       case CPU_DEAD:
+               topology_remove_dev(sys_dev);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block topology_cpu_notifier =
+{
+       .notifier_call = topology_cpu_callback,
+};
+
+static int __cpuinit topology_sysfs_init(void)
+{
+       int i;
+
+       for_each_online_cpu(i) {
+               topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE,
+                               (void *)(long)i);
+       }
+
+       register_cpu_notifier(&topology_cpu_notifier);
+
+       return 0;
+}
+
+device_initcall(topology_sysfs_init);
+
index 139cbba76180bcba6076c40bc30fce7c7d1deb41..8b133167740768c6ac96071a356a7c8fd1046ac6 100644 (file)
@@ -433,12 +433,12 @@ config CDROM_PKTCDVD_BUFFERS
          This controls the maximum number of active concurrent packets. More
          concurrent packets can increase write performance, but also require
          more memory. Each concurrent packet will require approximately 64Kb
-         of non-swappable kernel memory, memory which will be allocated at
-         pktsetup time.
+         of non-swappable kernel memory, memory which will be allocated when
+         a disc is opened for writing.
 
 config CDROM_PKTCDVD_WCACHE
-       bool "Enable write caching"
-       depends on CDROM_PKTCDVD
+       bool "Enable write caching (EXPERIMENTAL)"
+       depends on CDROM_PKTCDVD && EXPERIMENTAL
        help
          If enabled, write caching will be set for the CD-R/W device. For now
          this option is dangerous unless the CD-RW media is known good, as we
index 12d7b9bdfa93b62ae0664255d2ca7b34b911841c..0d65394707dbd5653057cfe1dbca6c94fdd98c47 100644 (file)
@@ -2183,6 +2183,7 @@ static void cciss_softirq_done(struct request *rq)
 {
        CommandList_struct *cmd = rq->completion_data;
        ctlr_info_t *h = hba[cmd->ctlr];
+       unsigned long flags;
        u64bit temp64;
        int i, ddir;
 
@@ -2205,10 +2206,10 @@ static void cciss_softirq_done(struct request *rq)
        printk("Done with %p\n", rq);
 #endif /* CCISS_DEBUG */ 
 
-       spin_lock_irq(&h->lock);
+       spin_lock_irqsave(&h->lock, flags);
        end_that_request_last(rq, rq->errors);
        cmd_free(h, cmd,1);
-       spin_unlock_irq(&h->lock);
+       spin_unlock_irqrestore(&h->lock, flags);
 }
 
 /* checks the status of the job and calls complete buffers to mark all 
index 93affeeef7bd3675009f1edc885684824bad633f..4e7dbcc425ff69d7f1f3c851e47d7ed5c60351b6 100644 (file)
@@ -43,8 +43,6 @@
  *
  *************************************************************************/
 
-#define VERSION_CODE   "v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com"
-
 #include <linux/pktcdvd.h>
 #include <linux/config.h>
 #include <linux/module.h>
@@ -131,7 +129,7 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
 /*
  * Allocate a packet_data struct
  */
-static struct packet_data *pkt_alloc_packet_data(void)
+static struct packet_data *pkt_alloc_packet_data(int frames)
 {
        int i;
        struct packet_data *pkt;
@@ -140,11 +138,12 @@ static struct packet_data *pkt_alloc_packet_data(void)
        if (!pkt)
                goto no_pkt;
 
-       pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
+       pkt->frames = frames;
+       pkt->w_bio = pkt_bio_alloc(frames);
        if (!pkt->w_bio)
                goto no_bio;
 
-       for (i = 0; i < PAGES_PER_PACKET; i++) {
+       for (i = 0; i < frames / FRAMES_PER_PAGE; i++) {
                pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
                if (!pkt->pages[i])
                        goto no_page;
@@ -152,7 +151,7 @@ static struct packet_data *pkt_alloc_packet_data(void)
 
        spin_lock_init(&pkt->lock);
 
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < frames; i++) {
                struct bio *bio = pkt_bio_alloc(1);
                if (!bio)
                        goto no_rd_bio;
@@ -162,14 +161,14 @@ static struct packet_data *pkt_alloc_packet_data(void)
        return pkt;
 
 no_rd_bio:
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < frames; i++) {
                struct bio *bio = pkt->r_bios[i];
                if (bio)
                        bio_put(bio);
        }
 
 no_page:
-       for (i = 0; i < PAGES_PER_PACKET; i++)
+       for (i = 0; i < frames / FRAMES_PER_PAGE; i++)
                if (pkt->pages[i])
                        __free_page(pkt->pages[i]);
        bio_put(pkt->w_bio);
@@ -186,12 +185,12 @@ static void pkt_free_packet_data(struct packet_data *pkt)
 {
        int i;
 
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < pkt->frames; i++) {
                struct bio *bio = pkt->r_bios[i];
                if (bio)
                        bio_put(bio);
        }
-       for (i = 0; i < PAGES_PER_PACKET; i++)
+       for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++)
                __free_page(pkt->pages[i]);
        bio_put(pkt->w_bio);
        kfree(pkt);
@@ -206,17 +205,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd)
        list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) {
                pkt_free_packet_data(pkt);
        }
+       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
 }
 
 static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
 {
        struct packet_data *pkt;
 
-       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
-       INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
-       spin_lock_init(&pd->cdrw.active_list_lock);
+       BUG_ON(!list_empty(&pd->cdrw.pkt_free_list));
+
        while (nr_packets > 0) {
-               pkt = pkt_alloc_packet_data();
+               pkt = pkt_alloc_packet_data(pd->settings.size >> 2);
                if (!pkt) {
                        pkt_shrink_pktlist(pd);
                        return 0;
@@ -951,7 +950,7 @@ try_next_bio:
 
        pd->current_sector = zone + pd->settings.size;
        pkt->sector = zone;
-       pkt->frames = pd->settings.size >> 2;
+       BUG_ON(pkt->frames != pd->settings.size >> 2);
        pkt->write_size = 0;
 
        /*
@@ -1639,7 +1638,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
        pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
        if (pd->settings.size == 0) {
                printk("pktcdvd: detected zero packet size!\n");
-               pd->settings.size = 128;
+               return -ENXIO;
        }
        if (pd->settings.size > PACKET_MAX_SECTORS) {
                printk("pktcdvd: packet size is too big\n");
@@ -1987,8 +1986,14 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
        if ((ret = pkt_set_segment_merging(pd, q)))
                goto out_unclaim;
 
-       if (write)
+       if (write) {
+               if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
+                       printk("pktcdvd: not enough memory for buffers\n");
+                       ret = -ENOMEM;
+                       goto out_unclaim;
+               }
                printk("pktcdvd: %lukB available on disc\n", lba << 1);
+       }
 
        return 0;
 
@@ -2014,6 +2019,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
        pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
        bd_release(pd->bdev);
        blkdev_put(pd->bdev);
+
+       pkt_shrink_pktlist(pd);
 }
 
 static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
@@ -2379,12 +2386,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        /* This is safe, since we have a reference from open(). */
        __module_get(THIS_MODULE);
 
-       if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
-               printk("pktcdvd: not enough memory for buffers\n");
-               ret = -ENOMEM;
-               goto out_mem;
-       }
-
        pd->bdev = bdev;
        set_blocksize(bdev, CD_FRAMESIZE);
 
@@ -2395,7 +2396,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        if (IS_ERR(pd->cdrw.thread)) {
                printk("pktcdvd: can't start kernel thread\n");
                ret = -ENOMEM;
-               goto out_thread;
+               goto out_mem;
        }
 
        proc = create_proc_entry(pd->name, 0, pkt_proc);
@@ -2406,8 +2407,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
        return 0;
 
-out_thread:
-       pkt_shrink_pktlist(pd);
 out_mem:
        blkdev_put(bdev);
        /* This is safe: open() is still holding a reference. */
@@ -2503,6 +2502,10 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
                goto out_mem;
        pd->disk = disk;
 
+       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
+       INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
+       spin_lock_init(&pd->cdrw.active_list_lock);
+
        spin_lock_init(&pd->lock);
        spin_lock_init(&pd->iosched.lock);
        sprintf(pd->name, "pktcdvd%d", idx);
@@ -2567,8 +2570,6 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
 
        blkdev_put(pd->bdev);
 
-       pkt_shrink_pktlist(pd);
-
        remove_proc_entry(pd->name, pkt_proc);
        DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
 
@@ -2678,7 +2679,6 @@ static int __init pkt_init(void)
 
        pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
 
-       DPRINTK("pktcdvd: %s\n", VERSION_CODE);
        return 0;
 
 out:
index a3614e6a68d0b95e5c8c8904e3014af3f1b7db0c..4ada1268b40d1abda498b2eddf9ed6caa830a665 100644 (file)
@@ -882,7 +882,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i
               card->card_number, dev->bus->number, dev->devfn);
 
        if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) &&
-           !pci_set_dma_mask(dev, 0xffffffffLL)) {
+           pci_set_dma_mask(dev, 0xffffffffLL)) {
                printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards);
                return  -ENOMEM;
        }
index 193446e6a08a80f4232cd13fcd50526c37de1914..e276172595528282fd07467ea5cc360dd9ac7fd6 100644 (file)
@@ -42,8 +42,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-#include <asm/bug.h>
-
 #include <asm/vio.h>
 #include <asm/scatterlist.h>
 #include <asm/iseries/hv_types.h>
index 4c67727d75b146f50fb8e0b368334af711cca314..05ba410682a34db47c55e973e4391c43c601f3f6 100644 (file)
@@ -222,7 +222,7 @@ config SYNCLINKMP
 
 config SYNCLINK_GT
        tristate "SyncLink GT/AC support"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && PCI
        help
          Support for SyncLink GT and SyncLink AC families of
          synchronous and asynchronous serial adapters
index 39c61a71176e0f0eec82a7cb432dba91cd965fdb..cc7acf877dc0ff92c4b55b1d2314ac4f0461e306 100644 (file)
@@ -1233,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                             }
                              info->idle_stats.recv_idle = jiffies;
                         }
-                        schedule_delayed_work(&tty->buf.work, 1);
+                       tty_schedule_flip(tty);
                     }
                     /* end of service */
                     cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
@@ -1606,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info,
            }
 #endif
            info->idle_stats.recv_idle = jiffies;
-           schedule_delayed_work(&tty->buf.work, 1);
+           tty_schedule_flip(tty);
        }
        /* Update rx_get */
        cy_writel(&buf_ctrl->rx_get, new_rx_get);
@@ -1809,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
        if(delta_count)
            cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
        if(special_count)
-           schedule_delayed_work(&tty->buf.work, 1);
+           tty_schedule_flip(tty);
     }
 }
 
index 5485382cadec8cc361293569bba79a985687f97e..bd7be09ea53df24a7bea3301f579d18902fa79bb 100644 (file)
@@ -59,17 +59,16 @@ static void *drm_ati_alloc_pcigart_table(void)
        int i;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
+       address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
+                                  ATI_PCIGART_TABLE_ORDER);
        if (address == 0UL) {
-               return 0;
+               return NULL;
        }
 
        page = virt_to_page(address);
 
-       for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
-               get_page(page);
+       for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
                SetPageReserved(page);
-       }
 
        DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
        return (void *)address;
@@ -83,10 +82,8 @@ static void drm_ati_free_pcigart_table(void *address)
 
        page = virt_to_page((unsigned long)address);
 
-       for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
-               __put_page(page);
+       for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
                ClearPageReserved(page);
-       }
 
        free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER);
 }
@@ -127,7 +124,7 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
        if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
            && gart_info->addr) {
                drm_ati_free_pcigart_table(gart_info->addr);
-               gart_info->addr = 0;
+               gart_info->addr = NULL;
        }
 
        return 1;
@@ -168,7 +165,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
                if (bus_address == 0) {
                        DRM_ERROR("unable to map PCIGART pages!\n");
                        drm_ati_free_pcigart_table(address);
-                       address = 0;
+                       address = NULL;
                        goto done;
                }
        } else {
index 54b561e694862ef6924ef08f61ba2ad520c18a8f..107df9fdba4e539337e50cd7855e23e56fcbc1be 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/smp_lock.h>    /* For (un)lock_kernel */
 #include <linux/mm.h>
 #include <linux/cdev.h>
+#include <linux/mutex.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h>       /* For pte_wrprotect */
 #endif
@@ -623,7 +624,7 @@ typedef struct drm_device {
        /** \name Locks */
        /*@{ */
        spinlock_t count_lock;          /**< For inuse, drm_device::open_count, drm_device::buf_use */
-       struct semaphore struct_sem;    /**< For others */
+       struct mutex struct_mutex;      /**< For others */
        /*@} */
 
        /** \name Usage Counters */
@@ -658,7 +659,7 @@ typedef struct drm_device {
        /*@{ */
        drm_ctx_list_t *ctxlist;        /**< Linked list of context handles */
        int ctx_count;                  /**< Number of context handles */
-       struct semaphore ctxlist_sem;   /**< For ctxlist */
+       struct mutex ctxlist_mutex;     /**< For ctxlist */
 
        drm_map_t **context_sareas;         /**< per-context SAREA's */
        int max_context;
@@ -979,7 +980,7 @@ extern int drm_put_head(drm_head_t * head);
 extern unsigned int drm_debug;
 extern unsigned int drm_cards_limit;
 extern drm_head_t **drm_heads;
-extern struct drm_sysfs_class *drm_class;
+extern struct class *drm_class;
 extern struct proc_dir_entry *drm_proc_root;
 
                                /* Proc support (drm_proc.h) */
@@ -1010,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
 extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
 
                               /* sysfs support (drm_sysfs.c) */
-struct drm_sysfs_class;
-extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
-                                               char *name);
-extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
-extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
+extern struct class *drm_sysfs_create(struct module *owner, char *name);
+extern void drm_sysfs_destroy(struct class *cs);
+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);
 
index a47b502bc7cc8fdcefa19688fbe9c16e7eaf3525..2a37586a7ee8d4e7ca856723f27be808e6649005 100644 (file)
@@ -56,7 +56,7 @@ static int drm_hash_magic(drm_magic_t magic)
  * \param magic magic number.
  *
  * Searches in drm_device::magiclist within all files with the same hash key
- * the one with matching magic number, while holding the drm_device::struct_sem
+ * the one with matching magic number, while holding the drm_device::struct_mutex
  * lock.
  */
 static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
@@ -65,14 +65,14 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
        drm_magic_entry_t *pt;
        int hash = drm_hash_magic(magic);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
                if (pt->magic == magic) {
                        retval = pt->priv;
                        break;
                }
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return retval;
 }
 
@@ -85,7 +85,7 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
  *
  * Creates a drm_magic_entry structure and appends to the linked list
  * associated the magic number hash key in drm_device::magiclist, while holding
- * the drm_device::struct_sem lock.
+ * the drm_device::struct_mutex lock.
  */
 static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
                         drm_magic_t magic)
@@ -104,7 +104,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
        entry->priv = priv;
        entry->next = NULL;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (dev->magiclist[hash].tail) {
                dev->magiclist[hash].tail->next = entry;
                dev->magiclist[hash].tail = entry;
@@ -112,7 +112,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
                dev->magiclist[hash].head = entry;
                dev->magiclist[hash].tail = entry;
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        return 0;
 }
@@ -124,7 +124,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
  * \param magic magic number.
  *
  * Searches and unlinks the entry in drm_device::magiclist with the magic
- * number hash key, while holding the drm_device::struct_sem lock.
+ * number hash key, while holding the drm_device::struct_mutex lock.
  */
 static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
 {
@@ -135,7 +135,7 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
        DRM_DEBUG("%d\n", magic);
        hash = drm_hash_magic(magic);
 
-       down(&dev->struct_sem);
+       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) {
@@ -147,11 +147,11 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
                        if (prev) {
                                prev->next = pt->next;
                        }
-                       up(&dev->struct_sem);
+                       mutex_unlock(&dev->struct_mutex);
                        return 0;
                }
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
 
index 1db12dcb6802f8e52b7622a415d6072d6c4f00f6..e2637b4d51def2a20db9ddc4e14e4a2e07c6800e 100644 (file)
@@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
        memset(list, 0, sizeof(*list));
        list->map = map;
 
-       down(&dev->struct_sem);
+       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_sem protects the increment */
+       /* 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);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        *maplist = list;
        return 0;
@@ -392,9 +392,9 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
 {
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm_rmmap_locked(dev, map);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        return ret;
 }
@@ -423,7 +423,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
                return -EFAULT;
        }
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        list_for_each(list, &dev->maplist->head) {
                drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
 
@@ -439,7 +439,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
         * find anything.
         */
        if (list == (&dev->maplist->head)) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
 
@@ -448,13 +448,13 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
 
        /* Register and framebuffer maps are permanent */
        if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return 0;
        }
 
        ret = drm_rmmap_locked(dev, map);
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        return ret;
 }
@@ -566,16 +566,16 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_inc(&dev->buf_alloc);
        spin_unlock(&dev->count_lock);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        entry = &dma->bufs[order];
        if (entry->buf_count) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM; /* May only call once for each order */
        }
 
        if (count < 0 || count > 4096) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -EINVAL;
        }
@@ -583,7 +583,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
                                   DRM_MEM_BUFS);
        if (!entry->buflist) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -616,7 +616,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
                        /* Set count correctly so we free the proper amount. */
                        entry->buf_count = count;
                        drm_cleanup_buf_error(dev, entry);
-                       up(&dev->struct_sem);
+                       mutex_unlock(&dev->struct_mutex);
                        atomic_dec(&dev->buf_alloc);
                        return -ENOMEM;
                }
@@ -638,7 +638,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        if (!temp_buflist) {
                /* Free the entry because it isn't valid */
                drm_cleanup_buf_error(dev, entry);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -656,7 +656,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
        DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        request->count = entry->buf_count;
        request->size = size;
@@ -722,16 +722,16 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_inc(&dev->buf_alloc);
        spin_unlock(&dev->count_lock);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        entry = &dma->bufs[order];
        if (entry->buf_count) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM; /* May only call once for each order */
        }
 
        if (count < 0 || count > 4096) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -EINVAL;
        }
@@ -739,7 +739,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
        entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
                                   DRM_MEM_BUFS);
        if (!entry->buflist) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -750,7 +750,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
        if (!entry->seglist) {
                drm_free(entry->buflist,
                         count * sizeof(*entry->buflist), DRM_MEM_BUFS);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -766,7 +766,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
                         count * sizeof(*entry->buflist), DRM_MEM_BUFS);
                drm_free(entry->seglist,
                         count * sizeof(*entry->seglist), DRM_MEM_SEGS);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -790,7 +790,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
                        drm_free(temp_pagelist,
                                 (dma->page_count + (count << page_order))
                                 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
-                       up(&dev->struct_sem);
+                       mutex_unlock(&dev->struct_mutex);
                        atomic_dec(&dev->buf_alloc);
                        return -ENOMEM;
                }
@@ -831,7 +831,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
                                          (count << page_order))
                                         * sizeof(*dma->pagelist),
                                         DRM_MEM_PAGES);
-                               up(&dev->struct_sem);
+                               mutex_unlock(&dev->struct_mutex);
                                atomic_dec(&dev->buf_alloc);
                                return -ENOMEM;
                        }
@@ -853,7 +853,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
                drm_free(temp_pagelist,
                         (dma->page_count + (count << page_order))
                         * sizeof(*dma->pagelist), DRM_MEM_PAGES);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -878,7 +878,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
        dma->page_count += entry->seg_count << page_order;
        dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        request->count = entry->buf_count;
        request->size = size;
@@ -948,16 +948,16 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_inc(&dev->buf_alloc);
        spin_unlock(&dev->count_lock);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        entry = &dma->bufs[order];
        if (entry->buf_count) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM; /* May only call once for each order */
        }
 
        if (count < 0 || count > 4096) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -EINVAL;
        }
@@ -965,7 +965,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
                                   DRM_MEM_BUFS);
        if (!entry->buflist) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -999,7 +999,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
                        /* Set count correctly so we free the proper amount. */
                        entry->buf_count = count;
                        drm_cleanup_buf_error(dev, entry);
-                       up(&dev->struct_sem);
+                       mutex_unlock(&dev->struct_mutex);
                        atomic_dec(&dev->buf_alloc);
                        return -ENOMEM;
                }
@@ -1022,7 +1022,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        if (!temp_buflist) {
                /* Free the entry because it isn't valid */
                drm_cleanup_buf_error(dev, entry);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -1040,7 +1040,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
        DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        request->count = entry->buf_count;
        request->size = size;
@@ -1110,16 +1110,16 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_inc(&dev->buf_alloc);
        spin_unlock(&dev->count_lock);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        entry = &dma->bufs[order];
        if (entry->buf_count) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM; /* May only call once for each order */
        }
 
        if (count < 0 || count > 4096) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -EINVAL;
        }
@@ -1127,7 +1127,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
                                   DRM_MEM_BUFS);
        if (!entry->buflist) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -1160,7 +1160,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
                        /* Set count correctly so we free the proper amount. */
                        entry->buf_count = count;
                        drm_cleanup_buf_error(dev, entry);
-                       up(&dev->struct_sem);
+                       mutex_unlock(&dev->struct_mutex);
                        atomic_dec(&dev->buf_alloc);
                        return -ENOMEM;
                }
@@ -1182,7 +1182,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        if (!temp_buflist) {
                /* Free the entry because it isn't valid */
                drm_cleanup_buf_error(dev, entry);
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                atomic_dec(&dev->buf_alloc);
                return -ENOMEM;
        }
@@ -1200,7 +1200,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
        DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        request->count = entry->buf_count;
        request->size = size;
index f8425452694957d6c74a2955eac8e3abc8310f03..83094c73da67abff05ab809bb76f0b0dd39c7e3f 100644 (file)
@@ -53,7 +53,7 @@
  * \param ctx_handle context handle.
  *
  * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
- * in drm_device::context_sareas, while holding the drm_device::struct_sem
+ * in drm_device::context_sareas, while holding the drm_device::struct_mutex
  * lock.
  */
 void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
@@ -64,10 +64,10 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
                goto failed;
 
        if (ctx_handle < DRM_MAX_CTXBITMAP) {
-               down(&dev->struct_sem);
+               mutex_lock(&dev->struct_mutex);
                clear_bit(ctx_handle, dev->ctx_bitmap);
                dev->context_sareas[ctx_handle] = NULL;
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return;
        }
       failed:
@@ -83,7 +83,7 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
  *
  * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
  * drm_device::context_sareas to accommodate the new entry while holding the
- * drm_device::struct_sem lock.
+ * drm_device::struct_mutex lock.
  */
 static int drm_ctxbitmap_next(drm_device_t * dev)
 {
@@ -92,7 +92,7 @@ static int drm_ctxbitmap_next(drm_device_t * dev)
        if (!dev->ctx_bitmap)
                return -1;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
        if (bit < DRM_MAX_CTXBITMAP) {
                set_bit(bit, dev->ctx_bitmap);
@@ -113,7 +113,7 @@ static int drm_ctxbitmap_next(drm_device_t * dev)
                                                         DRM_MEM_MAPS);
                                if (!ctx_sareas) {
                                        clear_bit(bit, dev->ctx_bitmap);
-                                       up(&dev->struct_sem);
+                                       mutex_unlock(&dev->struct_mutex);
                                        return -1;
                                }
                                dev->context_sareas = ctx_sareas;
@@ -126,16 +126,16 @@ static int drm_ctxbitmap_next(drm_device_t * dev)
                                              DRM_MEM_MAPS);
                                if (!dev->context_sareas) {
                                        clear_bit(bit, dev->ctx_bitmap);
-                                       up(&dev->struct_sem);
+                                       mutex_unlock(&dev->struct_mutex);
                                        return -1;
                                }
                                dev->context_sareas[bit] = NULL;
                        }
                }
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return bit;
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return -1;
 }
 
@@ -145,24 +145,24 @@ static int drm_ctxbitmap_next(drm_device_t * dev)
  * \param dev DRM device.
  *
  * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
+ * the drm_device::struct_mutex lock.
  */
 int drm_ctxbitmap_init(drm_device_t * dev)
 {
        int i;
        int temp;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE,
                                                     DRM_MEM_CTXBITMAP);
        if (dev->ctx_bitmap == NULL) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -ENOMEM;
        }
        memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE);
        dev->context_sareas = NULL;
        dev->max_context = -1;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
                temp = drm_ctxbitmap_next(dev);
@@ -178,17 +178,17 @@ int drm_ctxbitmap_init(drm_device_t * dev)
  * \param dev DRM device.
  *
  * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
+ * the drm_device::struct_mutex lock.
  */
 void drm_ctxbitmap_cleanup(drm_device_t * dev)
 {
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (dev->context_sareas)
                drm_free(dev->context_sareas,
                         sizeof(*dev->context_sareas) *
                         dev->max_context, DRM_MEM_MAPS);
        drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 }
 
 /*@}*/
@@ -222,15 +222,15 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
        if (copy_from_user(&request, argp, sizeof(request)))
                return -EFAULT;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (dev->max_context < 0
            || request.ctx_id >= (unsigned)dev->max_context) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
 
        map = dev->context_sareas[request.ctx_id];
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        request.handle = NULL;
        list_for_each_entry(_entry, &dev->maplist->head, head) {
@@ -274,7 +274,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
                           (drm_ctx_priv_map_t __user *) arg, sizeof(request)))
                return -EFAULT;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        list_for_each(list, &dev->maplist->head) {
                r_list = list_entry(list, drm_map_list_t, head);
                if (r_list->map
@@ -282,7 +282,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
                        goto found;
        }
       bad:
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return -EINVAL;
 
       found:
@@ -294,7 +294,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
        if (request.ctx_id >= (unsigned)dev->max_context)
                goto bad;
        dev->context_sareas[request.ctx_id] = map;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return 0;
 }
 
@@ -448,10 +448,10 @@ int drm_addctx(struct inode *inode, struct file *filp,
        ctx_entry->handle = ctx.handle;
        ctx_entry->tag = priv;
 
-       down(&dev->ctxlist_sem);
+       mutex_lock(&dev->ctxlist_mutex);
        list_add(&ctx_entry->head, &dev->ctxlist->head);
        ++dev->ctx_count;
-       up(&dev->ctxlist_sem);
+       mutex_unlock(&dev->ctxlist_mutex);
 
        if (copy_to_user(argp, &ctx, sizeof(ctx)))
                return -EFAULT;
@@ -574,7 +574,7 @@ int drm_rmctx(struct inode *inode, struct file *filp,
                drm_ctxbitmap_free(dev, ctx.handle);
        }
 
-       down(&dev->ctxlist_sem);
+       mutex_lock(&dev->ctxlist_mutex);
        if (!list_empty(&dev->ctxlist->head)) {
                drm_ctx_list_t *pos, *n;
 
@@ -586,7 +586,7 @@ int drm_rmctx(struct inode *inode, struct file *filp,
                        }
                }
        }
-       up(&dev->ctxlist_sem);
+       mutex_unlock(&dev->ctxlist_mutex);
 
        return 0;
 }
index c4fa5a29582b515fadbbd4aa5ec6ab1d98089722..dc6bbe8a18dc762e158ed8084071ddbaf4eb6ce6 100644 (file)
@@ -151,7 +151,7 @@ int drm_lastclose(drm_device_t * dev)
        if (dev->irq_enabled)
                drm_irq_uninstall(dev);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        del_timer(&dev->timer);
 
        /* Clear pid list */
@@ -231,7 +231,7 @@ int drm_lastclose(drm_device_t * dev)
                dev->lock.filp = NULL;
                wake_up_interruptible(&dev->lock.lock_queue);
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        DRM_DEBUG("lastclose completed\n");
        return 0;
index 403f44a1bf016cebe684f8d35719bf3b8d6dbf06..641f7633878c798d660657a5d56a1e1395e9ad38 100644 (file)
@@ -262,7 +262,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
                        goto out_free;
        }
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (!dev->file_last) {
                priv->next = NULL;
                priv->prev = NULL;
@@ -276,7 +276,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
                dev->file_last->next = priv;
                dev->file_last = priv;
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
 #ifdef __alpha__
        /*
@@ -413,7 +413,7 @@ int drm_release(struct inode *inode, struct file *filp)
 
        drm_fasync(-1, filp, 0);
 
-       down(&dev->ctxlist_sem);
+       mutex_lock(&dev->ctxlist_mutex);
        if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
                drm_ctx_list_t *pos, *n;
 
@@ -432,9 +432,9 @@ int drm_release(struct inode *inode, struct file *filp)
                        }
                }
        }
-       up(&dev->ctxlist_sem);
+       mutex_unlock(&dev->ctxlist_mutex);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (priv->remove_auth_on_close == 1) {
                drm_file_t *temp = dev->file_first;
                while (temp) {
@@ -452,7 +452,7 @@ int drm_release(struct inode *inode, struct file *filp)
        } else {
                dev->file_last = priv->prev;
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        if (dev->driver->postclose)
                dev->driver->postclose(dev, priv);
index bcd4e604d3ecd8f9c1c2467218f363e15fcfd331..555f323b8a32c350578b4f75ea04b5a345472c80 100644 (file)
@@ -194,9 +194,9 @@ int drm_getmap(struct inode *inode, struct file *filp,
                return -EFAULT;
        idx = map.offset;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        if (idx < 0) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
 
@@ -209,7 +209,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
                i++;
        }
        if (!r_list || !r_list->map) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
 
@@ -219,7 +219,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
        map.flags = r_list->map->flags;
        map.handle = (void *)(unsigned long)r_list->user_token;
        map.mtrr = r_list->map->mtrr;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        if (copy_to_user(argp, &map, sizeof(map)))
                return -EFAULT;
@@ -253,11 +253,11 @@ int drm_getclient(struct inode *inode, struct file *filp,
        if (copy_from_user(&client, argp, sizeof(client)))
                return -EFAULT;
        idx = client.idx;
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
 
        if (!pt) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
        client.auth = pt->authenticated;
@@ -265,7 +265,7 @@ int drm_getclient(struct inode *inode, struct file *filp,
        client.uid = pt->uid;
        client.magic = pt->magic;
        client.iocs = pt->ioctl_count;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        if (copy_to_user(argp, &client, sizeof(client)))
                return -EFAULT;
@@ -292,7 +292,7 @@ int drm_getstats(struct inode *inode, struct file *filp,
 
        memset(&stats, 0, sizeof(stats));
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
 
        for (i = 0; i < dev->counters; i++) {
                if (dev->types[i] == _DRM_STAT_LOCK)
@@ -305,7 +305,7 @@ int drm_getstats(struct inode *inode, struct file *filp,
 
        stats.count = dev->counters;
 
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
                return -EFAULT;
index b0d4b236e8372f349d1d2eae58fcac8b5ee808eb..611a1173091de92116cb4a018cbd0d473bdadee3 100644 (file)
@@ -98,20 +98,20 @@ static int drm_irq_install(drm_device_t * dev)
        if (dev->irq == 0)
                return -EINVAL;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
 
        /* Driver must have been initialized */
        if (!dev->dev_private) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }
 
        if (dev->irq_enabled) {
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return -EBUSY;
        }
        dev->irq_enabled = 1;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
 
@@ -135,9 +135,9 @@ static int drm_irq_install(drm_device_t * dev)
        ret = request_irq(dev->irq, dev->driver->irq_handler,
                          sh_flags, dev->devname, dev);
        if (ret < 0) {
-               down(&dev->struct_sem);
+               mutex_lock(&dev->struct_mutex);
                dev->irq_enabled = 0;
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
                return ret;
        }
 
@@ -161,10 +161,10 @@ int drm_irq_uninstall(drm_device_t * dev)
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        irq_enabled = dev->irq_enabled;
        dev->irq_enabled = 0;
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 
        if (!irq_enabled)
                return -EINVAL;
index 5b1d3a04458d06bd5af8c81e0c8ef105a30426e1..8fd6357a48da1ae648874cedcb1973d8110afe6d 100644 (file)
@@ -3,6 +3,7 @@
    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_RV350},\
        {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, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {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}, \
        {0, 0, 0}
 
index 6f943e3309ef911e7e4d6e3f968d754697fbaf42..362a270af0f10c53387069b2b7124ce788f23e96 100644 (file)
@@ -258,7 +258,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
 }
 
 /**
- * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
+ * Simply calls _vm_info() while holding the drm_device::struct_mutex lock.
  */
 static int drm_vm_info(char *buf, char **start, off_t offset, int request,
                       int *eof, void *data)
@@ -266,9 +266,9 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
        drm_device_t *dev = (drm_device_t *) data;
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm__vm_info(buf, start, offset, request, eof, data);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return ret;
 }
 
@@ -331,7 +331,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
 }
 
 /**
- * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
+ * Simply calls _queues_info() while holding the drm_device::struct_mutex lock.
  */
 static int drm_queues_info(char *buf, char **start, off_t offset, int request,
                           int *eof, void *data)
@@ -339,9 +339,9 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
        drm_device_t *dev = (drm_device_t *) data;
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm__queues_info(buf, start, offset, request, eof, data);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return ret;
 }
 
@@ -403,7 +403,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
 }
 
 /**
- * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
+ * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock.
  */
 static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
                         int *eof, void *data)
@@ -411,9 +411,9 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
        drm_device_t *dev = (drm_device_t *) data;
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm__bufs_info(buf, start, offset, request, eof, data);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return ret;
 }
 
@@ -459,7 +459,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
 }
 
 /**
- * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
+ * Simply calls _clients_info() while holding the drm_device::struct_mutex lock.
  */
 static int drm_clients_info(char *buf, char **start, off_t offset,
                            int request, int *eof, void *data)
@@ -467,9 +467,9 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
        drm_device_t *dev = (drm_device_t *) data;
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm__clients_info(buf, start, offset, request, eof, data);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return ret;
 }
 
@@ -540,9 +540,9 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int request,
        drm_device_t *dev = (drm_device_t *) data;
        int ret;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        ret = drm__vma_info(buf, start, offset, request, eof, data);
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
        return ret;
 }
 #endif
index 42d766359caa919d6600f7691dc870ef2f8d7ed4..68073e14fdeca3c184dc4a99a36a787295771728 100644 (file)
@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444);
 module_param_named(debug, drm_debug, int, 0600);
 
 drm_head_t **drm_heads;
-struct drm_sysfs_class *drm_class;
+struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
 
 static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
@@ -61,8 +61,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
 
        spin_lock_init(&dev->count_lock);
        init_timer(&dev->timer);
-       sema_init(&dev->struct_sem, 1);
-       sema_init(&dev->ctxlist_sem, 1);
+       mutex_init(&dev->struct_mutex);
+       mutex_init(&dev->ctxlist_mutex);
 
        dev->pdev = pdev;
 
index 68e43ddc16aea44fd927cbc9ae6eb532f7d7eb2a..0b9f98a7eb10b1e2528e763be712f7e56c4c8911 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * drm_sysfs.c - Modifications to drm_sysfs_class.c to support
  *               extra sysfs attribute from DRM. Normal drm_sysfs_class
 #include "drm_core.h"
 #include "drmP.h"
 
-struct drm_sysfs_class {
-       struct class_device_attribute attr;
-       struct class class;
-};
-#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
-
-struct simple_dev {
-       dev_t dev;
-       struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static void release_simple_dev(struct class_device *class_dev)
-{
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
-       kfree(s_dev);
-}
-
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
-       return print_dev_t(buf, s_dev->dev);
-}
-
-static void drm_sysfs_class_release(struct class *class)
-{
-       struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
-       kfree(cs);
-}
-
 /* Display the version of drm_core. This doesn't work right in current design */
 static ssize_t version_show(struct class *dev, char *buf)
 {
@@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
  * Note, the pointer created here is to be destroyed when finished by making a
  * call to drm_sysfs_destroy().
  */
-struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
+struct class *drm_sysfs_create(struct module *owner, char *name)
 {
-       struct drm_sysfs_class *cs;
-       int retval;
-
-       cs = kmalloc(sizeof(*cs), GFP_KERNEL);
-       if (!cs) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(cs, 0x00, sizeof(*cs));
-
-       cs->class.name = name;
-       cs->class.class_release = drm_sysfs_class_release;
-       cs->class.release = release_simple_dev;
-
-       cs->attr.attr.name = "dev";
-       cs->attr.attr.mode = S_IRUGO;
-       cs->attr.attr.owner = owner;
-       cs->attr.show = show_dev;
-       cs->attr.store = NULL;
-
-       retval = class_register(&cs->class);
-       if (retval)
-               goto error;
-       class_create_file(&cs->class, &class_attr_version);
-
-       return cs;
-
-      error:
-       kfree(cs);
-       return ERR_PTR(retval);
+       struct class *class;
+
+       class = class_create(owner, name);
+       if (!class)
+               return class;
+
+       class_create_file(class, &class_attr_version);
+       return class;
 }
 
 /**
@@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
  * Note, the pointer to be destroyed must have been created with a call to
  * drm_sysfs_create().
  */
-void drm_sysfs_destroy(struct drm_sysfs_class *cs)
+void drm_sysfs_destroy(struct class *class)
 {
-       if ((cs == NULL) || (IS_ERR(cs)))
+       if ((class == NULL) || (IS_ERR(class)))
                return;
 
-       class_unregister(&cs->class);
+       class_remove_file(class, &class_attr_version);
+       class_destroy(class);
 }
 
 static ssize_t show_dri(struct class_device *class_device, char *buf)
@@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = {
 
 /**
  * drm_sysfs_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
+ * @cs: pointer to the struct class that this device should be registered to.
  * @dev: the dev_t for the 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
@@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = {
  * class.  A "dev" file will be created, showing the dev_t for the device.  The
  * pointer to the struct class_device will be returned from the call.  Any further
  * sysfs files that might be required can be created using this pointer.
- * Note: the struct drm_sysfs_class passed to this function must have previously been
+ * Note: the struct class passed to this function must have previously been
  * created with a call to drm_sysfs_create().
  */
-struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
-                                         drm_head_t *head)
+struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
 {
-       struct simple_dev *s_dev = NULL;
-       int i, retval;
-
-       if ((cs == NULL) || (IS_ERR(cs))) {
-               retval = -ENODEV;
-               goto error;
-       }
-
-       s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
-       if (!s_dev) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(s_dev, 0x00, sizeof(*s_dev));
-
-       s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
-       s_dev->class_dev.dev = &(head->dev->pdev)->dev;
-       s_dev->class_dev.class = &cs->class;
+       struct class_device *class_dev;
+       int i;
 
-       snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
-       retval = class_device_register(&s_dev->class_dev);
-       if (retval)
-               goto error;
+       class_dev = class_device_create(cs, NULL,
+                                       MKDEV(DRM_MAJOR, head->minor),
+                                       &(head->dev->pdev)->dev,
+                                       "card%d", head->minor);
+       if (!class_dev)
+               return NULL;
 
-       class_device_create_file(&s_dev->class_dev, &cs->attr);
-       class_set_devdata(&s_dev->class_dev, head);
+       class_set_devdata(class_dev, head);
 
        for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
-       return &s_dev->class_dev;
-
-error:
-       kfree(s_dev);
-       return ERR_PTR(retval);
+               class_device_create_file(class_dev, &class_device_attrs[i]);
+       return class_dev;
 }
 
 /**
@@ -192,10 +122,9 @@ error:
  */
 void drm_sysfs_device_remove(struct class_device *class_dev)
 {
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
-       class_device_unregister(&s_dev->class_dev);
+               class_device_remove_file(class_dev, &class_device_attrs[i]);
+       class_device_unregister(class_dev);
 }
index 3f73aa774c80975eee97134a29ac43fb0a7de294..0291cd62c69f2b955db736952fd45dc69f444a09 100644 (file)
@@ -188,7 +188,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
 
        map = vma->vm_private_data;
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
                next = pt->next;
                if (pt->vma->vm_private_data == map)
@@ -248,7 +248,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                }
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 }
 
 /**
@@ -404,12 +404,12 @@ static void drm_vm_open(struct vm_area_struct *vma)
 
        vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
        if (vma_entry) {
-               down(&dev->struct_sem);
+               mutex_lock(&dev->struct_mutex);
                vma_entry->vma = vma;
                vma_entry->next = dev->vmalist;
                vma_entry->pid = current->pid;
                dev->vmalist = vma_entry;
-               up(&dev->struct_sem);
+               mutex_unlock(&dev->struct_mutex);
        }
 }
 
@@ -431,7 +431,7 @@ static void drm_vm_close(struct vm_area_struct *vma)
                  vma->vm_start, vma->vm_end - vma->vm_start);
        atomic_dec(&dev->vma_count);
 
-       down(&dev->struct_sem);
+       mutex_lock(&dev->struct_mutex);
        for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
                if (pt->vma == vma) {
                        if (prev) {
@@ -443,7 +443,7 @@ static void drm_vm_close(struct vm_area_struct *vma)
                        break;
                }
        }
-       up(&dev->struct_sem);
+       mutex_unlock(&dev->struct_mutex);
 }
 
 /**
index cc1b89086876b3f289301685ebb0aefbcd2146a5..ae0aa6d7e0bb74140ca576c89bb4c8bf2fcd5705 100644 (file)
@@ -958,7 +958,7 @@ static int i810_flush_queue(drm_device_t * dev)
 }
 
 /* Must be called with the lock held */
-void i810_reclaim_buffers(drm_device_t * dev, struct file *filp)
+static void i810_reclaim_buffers(drm_device_t * dev, struct file *filp)
 {
        drm_device_dma_t *dma = dev->dma;
        int i;
index a18b80d91920b073fc46f787160ed1fa889bd7c9..e8cf3ff606f0c000c4955ab4d5e463d577b6e381 100644 (file)
@@ -113,8 +113,6 @@ typedef struct drm_i810_private {
 } drm_i810_private_t;
 
                                /* i810_dma.c */
-extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
-
 extern int i810_driver_dma_quiescent(drm_device_t * dev);
 extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
                                               struct file *filp);
index 4fea32aed6d240f493946137a7c06c5b29cada72..163f2cbfe60d2dd4b1c90761f4aaf0a95145db76 100644 (file)
@@ -1239,7 +1239,7 @@ static int i830_flush_queue(drm_device_t * dev)
 }
 
 /* Must be called with the lock held */
-void i830_reclaim_buffers(drm_device_t * dev, struct file *filp)
+static void i830_reclaim_buffers(drm_device_t * dev, struct file *filp)
 {
        drm_device_dma_t *dma = dev->dma;
        int i;
index bf9075b576bddbcaa36cf29e71464e3c3a90a4f3..85bc5be6f91650f9050444cc6accdad9ef9f5e05 100644 (file)
@@ -123,9 +123,6 @@ typedef struct drm_i830_private {
 extern drm_ioctl_desc_t i830_ioctls[];
 extern int i830_max_ioctl;
 
-/* i830_dma.c */
-extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp);
-
 /* i830_irq.c */
 extern int i830_irq_emit(struct inode *inode, struct file *filp,
                         unsigned int cmd, unsigned long arg);
index 9140703da1ba0aac8288ab7258fe05d599a6e491..1ff4c7ca0bff0421ea39e97d9df98883faa4b071 100644 (file)
@@ -344,18 +344,20 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
        int i;
        RING_LOCALS;
 
+       if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
+               return DRM_ERR(EINVAL);
+
+       BEGIN_LP_RING(((dwords+1)&~1));
+
        for (i = 0; i < dwords;) {
                int cmd, sz;
 
                if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
                        return DRM_ERR(EINVAL);
 
-/*             printk("%d/%d ", i, dwords); */
-
                if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
                        return DRM_ERR(EINVAL);
 
-               BEGIN_LP_RING(sz);
                OUT_RING(cmd);
 
                while (++i, --sz) {
@@ -365,9 +367,13 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
                        }
                        OUT_RING(cmd);
                }
-               ADVANCE_LP_RING();
        }
 
+       if (dwords & 1)
+               OUT_RING(0);
+
+       ADVANCE_LP_RING();
+
        return 0;
 }
 
@@ -401,6 +407,21 @@ static int i915_emit_box(drm_device_t * dev,
        return 0;
 }
 
+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++;
+
+       BEGIN_LP_RING(4);
+       OUT_RING(CMD_STORE_DWORD_IDX);
+       OUT_RING(20);
+       OUT_RING(dev_priv->counter);
+       OUT_RING(0);
+       ADVANCE_LP_RING();
+}
+
 static int i915_dispatch_cmdbuffer(drm_device_t * dev,
                                   drm_i915_cmdbuffer_t * cmd)
 {
@@ -429,6 +450,7 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev,
                        return ret;
        }
 
+       i915_emit_breadcrumb(dev);
        return 0;
 }
 
@@ -475,12 +497,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev,
 
        dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(CMD_STORE_DWORD_IDX);
-       OUT_RING(20);
-       OUT_RING(dev_priv->counter);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
+       i915_emit_breadcrumb(dev);
 
        return 0;
 }
@@ -657,7 +674,7 @@ static int i915_getparam(DRM_IOCTL_ARGS)
                value = READ_BREADCRUMB(dev_priv);
                break;
        default:
-               DRM_ERROR("Unkown parameter %d\n", param.param);
+               DRM_ERROR("Unknown parameter %d\n", param.param);
                return DRM_ERR(EINVAL);
        }
 
@@ -742,7 +759,8 @@ drm_ioctl_desc_t i915_ioctls[] = {
        [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH},
        [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
        [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}
+       [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH},
+       [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
index 77412ddac007625637e24aabd38a69f94a690cd3..4cb3da578330b631ff05f1b8882e9124a31ab4ec 100644 (file)
@@ -74,6 +74,30 @@ typedef struct _drm_i915_sarea {
        int pf_active;
        int pf_current_page;    /* which buffer is being displayed? */
        int perf_boxes;         /* performance boxes to be displayed */
+       int width, height;      /* screen size in pixels */
+
+       drm_handle_t front_handle;
+       int front_offset;
+       int front_size;
+
+       drm_handle_t back_handle;
+       int back_offset;
+       int back_size;
+
+       drm_handle_t depth_handle;
+       int depth_offset;
+       int depth_size;
+
+       drm_handle_t tex_handle;
+       int tex_offset;
+       int tex_size;
+       int log_tex_granularity;
+       int pitch;
+       int rotation;           /* 0, 90, 180 or 270 */
+       int rotated_offset;
+       int rotated_size;
+       int rotated_pitch;
+       int virtualX, virtualY;
 } drm_i915_sarea_t;
 
 /* Flags for perf_boxes
@@ -99,6 +123,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_FREE          0x09
 #define DRM_I915_INIT_HEAP     0x0a
 #define DRM_I915_CMDBUFFER     0x0b
+#define DRM_I915_DESTROY_HEAP  0x0c
 
 #define DRM_IOCTL_I915_INIT            DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH           DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -112,6 +137,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_FREE             DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
 #define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
 #define DRM_IOCTL_I915_CMDBUFFER       DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
+#define DRM_IOCTL_I915_DESTROY_HEAP    DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -191,4 +217,11 @@ typedef struct drm_i915_mem_init_heap {
        int start;
 } drm_i915_mem_init_heap_t;
 
+/* Allow memory manager to be torn down and re-initialized (eg on
+ * rotate):
+ */
+typedef struct drm_i915_mem_destroy_heap {
+       int region;
+} drm_i915_mem_destroy_heap_t;
+
 #endif                         /* _I915_DRM_H_ */
index c6c71b45f1013b92949c0a92c800f79a840a358a..7a65666899e49523c5ff55e3d21e8afe01abcd36 100644 (file)
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20051209"
+#define DRIVER_DATE            "20060119"
 
 /* Interface history:
  *
  * 1.1: Original.
  * 1.2: Add Power Management
  * 1.3: Add vblank support
+ * 1.4: Fix cmdbuffer path, add heap destroy
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           3
+#define DRIVER_MINOR           4
 #define DRIVER_PATCHLEVEL      0
 
 typedef struct _drm_i915_ring_buffer {
@@ -123,6 +124,7 @@ extern void i915_driver_irq_uninstall(drm_device_t * dev);
 extern int i915_mem_alloc(DRM_IOCTL_ARGS);
 extern int i915_mem_free(DRM_IOCTL_ARGS);
 extern int i915_mem_init_heap(DRM_IOCTL_ARGS);
+extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS);
 extern void i915_mem_takedown(struct mem_block **heap);
 extern void i915_mem_release(drm_device_t * dev,
                             DRMFILE filp, struct mem_block *heap);
index ba87ff17ff64cfaf123afe895a4b0d6a5a0bc262..52c67324df58953f6b98db130f8f6d05bbaa1dda 100644 (file)
@@ -365,3 +365,34 @@ int i915_mem_init_heap(DRM_IOCTL_ARGS)
 
        return init_heap(heap, initheap.start, initheap.size);
 }
+
+int i915_mem_destroy_heap( DRM_IOCTL_ARGS )
+{
+       DRM_DEVICE;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       drm_i915_mem_destroy_heap_t destroyheap;
+       struct mem_block **heap;
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+               return DRM_ERR(EINVAL);
+       }
+
+       DRM_COPY_FROM_USER_IOCTL( destroyheap, (drm_i915_mem_destroy_heap_t *)data,
+                                 sizeof(destroyheap) );
+
+       heap = get_heap( dev_priv, destroyheap.region );
+       if (!heap) {
+               DRM_ERROR("get_heap failed");
+               return DRM_ERR(EFAULT);
+       }
+       
+       if (!*heap) {
+               DRM_ERROR("heap not initialized?");
+               return DRM_ERR(EFAULT);
+       }
+
+       i915_mem_takedown( heap );
+       return 0;
+}
+
index 915665c7fe7c672bebe54a7f8f73f6d80dc65d29..9bb8ae0c1c2720a31794179364fca10d83c1fb3e 100644 (file)
@@ -1640,7 +1640,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
                if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
                {
                        drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
-                       dev_priv->gart_info.addr = 0;
+                       dev_priv->gart_info.addr = NULL;
                }
        }
        /* only clear to the start of flags */
index 0d426deeefec1992681f43259ea0c55aae4b0cdd..59c7520bf9a2ab9419910ac10c186322d3b6ffc8 100644 (file)
@@ -32,6 +32,8 @@
 #define SAVAGE_EVENT_USEC_TIMEOUT      5000000 /* 5s */
 #define SAVAGE_FREELIST_DEBUG          0
 
+static int savage_do_cleanup_bci(drm_device_t *dev);
+
 static int
 savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n)
 {
@@ -895,7 +897,7 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init)
        return 0;
 }
 
-int savage_do_cleanup_bci(drm_device_t * dev)
+static int savage_do_cleanup_bci(drm_device_t * dev)
 {
        drm_savage_private_t *dev_priv = dev->dev_private;
 
index dd46cb85439c846d03a46ae019f721948d87857a..8f04b3d82292bc0419158f93eeb497c97c578ef3 100644 (file)
@@ -212,7 +212,6 @@ extern int savage_driver_load(drm_device_t *dev, unsigned long chipset);
 extern int savage_driver_firstopen(drm_device_t *dev);
 extern void savage_driver_lastclose(drm_device_t *dev);
 extern int savage_driver_unload(drm_device_t *dev);
-extern int savage_do_cleanup_bci(drm_device_t * dev);
 extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
 
 /* state functions */
index 593c0b8f650a911c51a3558b0ff136780df63bf4..a691ae74129db2db470f843de39ec1199e7a82e1 100644 (file)
@@ -222,7 +222,7 @@ static int via_initialize(drm_device_t * dev,
        return 0;
 }
 
-int via_dma_init(DRM_IOCTL_ARGS)
+static int via_dma_init(DRM_IOCTL_ARGS)
 {
        DRM_DEVICE;
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
@@ -321,7 +321,7 @@ int via_driver_dma_quiescent(drm_device_t * dev)
        return 0;
 }
 
-int via_flush_ioctl(DRM_IOCTL_ARGS)
+static int via_flush_ioctl(DRM_IOCTL_ARGS)
 {
        DRM_DEVICE;
 
@@ -330,7 +330,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS)
        return via_driver_dma_quiescent(dev);
 }
 
-int via_cmdbuffer(DRM_IOCTL_ARGS)
+static int via_cmdbuffer(DRM_IOCTL_ARGS)
 {
        DRM_DEVICE;
        drm_via_cmdbuffer_t cmdbuf;
@@ -375,7 +375,7 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
        return ret;
 }
 
-int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
+static int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
 {
        DRM_DEVICE;
        drm_via_cmdbuffer_t cmdbuf;
@@ -665,7 +665,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
  * User interface to the space and lag functions.
  */
 
-int via_cmdbuf_size(DRM_IOCTL_ARGS)
+static int via_cmdbuf_size(DRM_IOCTL_ARGS)
 {
        DRM_DEVICE;
        drm_via_cmdbuf_size_t d_siz;
index 9d5e027dae0e2b8908bd6550863cbab3ef4fa3ea..b7f17457b4243bb1c18e8dea11b6b7149a22e7fe 100644 (file)
@@ -108,7 +108,7 @@ via_map_blit_for_device(struct pci_dev *pdev,
        int num_desc = 0;
        int cur_line;
        dma_addr_t next = 0 | VIA_DMA_DPR_EC;
-       drm_via_descriptor_t *desc_ptr = 0;
+       drm_via_descriptor_t *desc_ptr = NULL;
 
        if (mode == 1) 
                desc_ptr = vsg->desc_pages[cur_descriptor_page];
@@ -167,7 +167,7 @@ via_map_blit_for_device(struct pci_dev *pdev,
  */
 
 
-void
+static void
 via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) 
 {
        struct page *page;
@@ -581,7 +581,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
        int ret = 0;
        
        vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
-       vsg->bounce_buffer = 0;
+       vsg->bounce_buffer = NULL;
 
        vsg->state = dr_via_sg_init;
 
index aad4f99f540578964013702f310daa67e46e361e..52bcc7b1ba4560065be1a85eb981b15e5a46aea8 100644 (file)
@@ -110,11 +110,6 @@ extern int via_mem_free(DRM_IOCTL_ARGS);
 extern int via_agp_init(DRM_IOCTL_ARGS);
 extern int via_map_init(DRM_IOCTL_ARGS);
 extern int via_decoder_futex(DRM_IOCTL_ARGS);
-extern int via_dma_init(DRM_IOCTL_ARGS);
-extern int via_cmdbuffer(DRM_IOCTL_ARGS);
-extern int via_flush_ioctl(DRM_IOCTL_ARGS);
-extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
-extern int via_cmdbuf_size(DRM_IOCTL_ARGS);
 extern int via_wait_irq(DRM_IOCTL_ARGS);
 extern int via_dma_blit_sync( DRM_IOCTL_ARGS );
 extern int via_dma_blit( DRM_IOCTL_ARGS );
@@ -139,8 +134,6 @@ extern int via_driver_dma_quiescent(drm_device_t * dev);
 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 int via_driver_irq_wait(drm_device_t * dev, unsigned int irq,
-                              int force_sequence, unsigned int *sequence);
 
 extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq);
 extern void via_init_dmablit(drm_device_t *dev);
index 56d7e3daea126d8a2f926cd0e21e5444b4d6c479..6152415644e9b4a327549841df072edd0c45f8e5 100644 (file)
@@ -190,7 +190,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
        return ret;
 }
 
-int
+static int
 via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
                    unsigned int *sequence)
 {
index 3f3ac039f4d9a43eb5146b30b4731019ce697ff6..57539d8f9f7c861770c21843fbe38b1b7097151f 100644 (file)
@@ -359,7 +359,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
                }
        }
 
-       schedule_delayed_work(&tty->buf.work, 1);
+       tty_schedule_flip(tty);
 
        info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
        release_pio_buffer(pio_buf);
@@ -426,7 +426,7 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
                        }
                        tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag);
                }
-               schedule_delayed_work(&tty->buf.work, 1);
+               tty_schedule_flip(tty);
        }
 
        if (dma_bytes != num_bytes) {
index cb8f4198e9a34291b8cd67e41ee0f969741ac0ad..e7af647800b6e50d46a1f9c2479b00f2c1ea01cd 100644 (file)
@@ -139,7 +139,6 @@ static UCHAR ct79[] = { 2, BYP,     0x4F,0                   }; // XMIT_NOW
 //static UCHAR ct86[]={ 2, BTH,     0x56,0                   }; // RCV_ENABLE
 static UCHAR ct87[] = { 1, BYP,     0x57                     }; // HW_TEST
 //static UCHAR ct88[]={ 3, BTH,     0x58,0,0                 }; // RCV_THRESHOLD
-static UCHAR ct89[]={ 1, BYP,     0x59                     }; // DSS_NOW
 //static UCHAR ct90[]={ 3, BYP,     0x5A,0,0                 }; // Set SILO
 //static UCHAR ct91[]={ 2, BYP,     0x5B,0                   }; // timed break
 
index 56e93a5a1e2413fc8477aa354e436ee0d38df202..48fcfba37bfaafd5d0a44a772d8e0182225c07c7 100644 (file)
@@ -2906,65 +2906,16 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
                rc = -EINVAL;
                break;
        case 3:     // Trace device
-               if ( cmd == 1 ) {
-                       rc = put_user(iiSendPendingMail, pIndex++ );
-                       rc = put_user(i2InitChannels, pIndex++ );
-                       rc = put_user(i2QueueNeeds, pIndex++ );
-                       rc = put_user(i2QueueCommands, pIndex++ );
-                       rc = put_user(i2GetStatus, pIndex++ );
-                       rc = put_user(i2Input, pIndex++ );
-                       rc = put_user(i2InputFlush, pIndex++ );
-                       rc = put_user(i2Output, pIndex++ );
-                       rc = put_user(i2FlushOutput, pIndex++ );
-                       rc = put_user(i2DrainWakeup, pIndex++ );
-                       rc = put_user(i2DrainOutput, pIndex++ );
-                       rc = put_user(i2OutputFree, pIndex++ );
-                       rc = put_user(i2StripFifo, pIndex++ );
-                       rc = put_user(i2StuffFifoBypass, pIndex++ );
-                       rc = put_user(i2StuffFifoFlow, pIndex++ );
-                       rc = put_user(i2StuffFifoInline, pIndex++ );
-                       rc = put_user(i2ServiceBoard, pIndex++ );
-                       rc = put_user(serviceOutgoingFifo, pIndex++ );
-                       // rc = put_user(ip2_init, pIndex++ );
-                       rc = put_user(ip2_init_board, pIndex++ );
-                       rc = put_user(find_eisa_board, pIndex++ );
-                       rc = put_user(set_irq, pIndex++ );
-                       rc = put_user(ip2_interrupt, pIndex++ );
-                       rc = put_user(ip2_poll, pIndex++ );
-                       rc = put_user(service_all_boards, pIndex++ );
-                       rc = put_user(do_input, pIndex++ );
-                       rc = put_user(do_status, pIndex++ );
-#ifndef IP2DEBUG_OPEN
-                       rc = put_user(0, pIndex++ );
-#else
-                       rc = put_user(open_sanity_check, pIndex++ );
-#endif
-                       rc = put_user(ip2_open, pIndex++ );
-                       rc = put_user(ip2_close, pIndex++ );
-                       rc = put_user(ip2_hangup, pIndex++ );
-                       rc = put_user(ip2_write, pIndex++ );
-                       rc = put_user(ip2_putchar, pIndex++ );
-                       rc = put_user(ip2_flush_chars, pIndex++ );
-                       rc = put_user(ip2_write_room, pIndex++ );
-                       rc = put_user(ip2_chars_in_buf, pIndex++ );
-                       rc = put_user(ip2_flush_buffer, pIndex++ );
-
-                       //rc = put_user(ip2_wait_until_sent, pIndex++ );
-                       rc = put_user(0, pIndex++ );
-
-                       rc = put_user(ip2_throttle, pIndex++ );
-                       rc = put_user(ip2_unthrottle, pIndex++ );
-                       rc = put_user(ip2_ioctl, pIndex++ );
-                       rc = put_user(0, pIndex++ );
-                       rc = put_user(get_serial_info, pIndex++ );
-                       rc = put_user(set_serial_info, pIndex++ );
-                       rc = put_user(ip2_set_termios, pIndex++ );
-                       rc = put_user(ip2_set_line_discipline, pIndex++ );
-                       rc = put_user(set_params, pIndex++ );
-               } else {
+               /*
+                * akpm: This used to write a whole bunch of function addresses
+                * to userspace, which generated lots of put_user() warnings.
+                * I killed it all.  Just return "success" and don't do
+                * anything.
+                */
+               if (cmd == 1)
+                       rc = 0;
+               else
                        rc = -EINVAL;
-               }
-
                break;
 
        default:
index 0097f06fa67ba0af6852eb033597b7f0f1b08eb1..d745004281d08f372aaa0bdc87f0e231b946651e 100644 (file)
@@ -481,7 +481,7 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
        }
 
        if ((addr->channel == IPMI_BMC_CHANNEL)
-           || (addr->channel >= IPMI_NUM_CHANNELS)
+           || (addr->channel >= IPMI_MAX_CHANNELS)
            || (addr->channel < 0))
                return -EINVAL;
 
@@ -1321,7 +1321,7 @@ static int i_ipmi_request(ipmi_user_t          user,
                unsigned char         ipmb_seq;
                long                  seqid;
 
-               if (addr->channel >= IPMI_NUM_CHANNELS) {
+               if (addr->channel >= IPMI_MAX_CHANNELS) {
                        spin_lock_irqsave(&intf->counter_lock, flags);
                        intf->sent_invalid_commands++;
                        spin_unlock_irqrestore(&intf->counter_lock, flags);
index 6ed213bd702c2dc74c533cd29417a07ff79438ed..e59b638766ef5f02ac3bc6b454699d68c7d0d7af 100644 (file)
@@ -1270,36 +1270,36 @@ static int try_init_port(int intf_num, struct smi_info **new_info)
        return 0;
 }
 
-static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
+static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset)
 {
        return readb((io->addr)+(offset * io->regspacing));
 }
 
-static void mem_outb(struct si_sm_io *io, unsigned int offset,
+static void intf_mem_outb(struct si_sm_io *io, unsigned int offset,
                     unsigned char b)
 {
        writeb(b, (io->addr)+(offset * io->regspacing));
 }
 
-static unsigned char mem_inw(struct si_sm_io *io, unsigned int offset)
+static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset)
 {
        return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift)
                && 0xff;
 }
 
-static void mem_outw(struct si_sm_io *io, unsigned int offset,
+static void intf_mem_outw(struct si_sm_io *io, unsigned int offset,
                     unsigned char b)
 {
        writeb(b << io->regshift, (io->addr)+(offset * io->regspacing));
 }
 
-static unsigned char mem_inl(struct si_sm_io *io, unsigned int offset)
+static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset)
 {
        return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift)
                && 0xff;
 }
 
-static void mem_outl(struct si_sm_io *io, unsigned int offset,
+static void intf_mem_outl(struct si_sm_io *io, unsigned int offset,
                     unsigned char b)
 {
        writel(b << io->regshift, (io->addr)+(offset * io->regspacing));
@@ -1349,16 +1349,16 @@ static int mem_setup(struct smi_info *info)
           upon the register size. */
        switch (info->io.regsize) {
        case 1:
-               info->io.inputb = mem_inb;
-               info->io.outputb = mem_outb;
+               info->io.inputb = intf_mem_inb;
+               info->io.outputb = intf_mem_outb;
                break;
        case 2:
-               info->io.inputb = mem_inw;
-               info->io.outputb = mem_outw;
+               info->io.inputb = intf_mem_inw;
+               info->io.outputb = intf_mem_outw;
                break;
        case 4:
-               info->io.inputb = mem_inl;
-               info->io.outputb = mem_outl;
+               info->io.inputb = intf_mem_inl;
+               info->io.outputb = intf_mem_outl;
                break;
 #ifdef readq
        case 8:
index 217ff09f2fa1697e965082a36b6510894bd6e643..89bd94eb45be10c8962f98e2b26c86c837dfe250 100644 (file)
 #endif
 #define _cirrus_h 1
 
-#ifdef RTA
-#define        TO_UART RX
-#define TO_DRIVER TX
-#endif
-
-#ifdef HOST
-#define        TO_UART TX
-#define TO_DRIVER RX
-#endif
-#ifdef RTA
-/* Miscellaneous defines for CIRRUS addresses and related logic for
-   interrupts etc.
-*/
-#define        MAP(a)          ((short *)(cirrus_base + (a)))
-#define outp(a,b)      (*MAP (a) =(b))
-#define inp(a)         ((*MAP (a)) & 0xff)
-#define        CIRRUS_FIRST    (short*)0x7300
-#define        CIRRUS_SECOND   (short*)0x7200
-#define        CIRRUS_THIRD    (short*)0x7100
-#define        CIRRUS_FOURTH   (short*)0x7000
-#define        PORTS_ON_CIRRUS 4
-#define        CIRRUS_FIFO_SIZE        12
-#define        SPACE           0x20
-#define        TAB             0x09
-#define        LINE_FEED       0x0a
-#define        CARRIAGE_RETURN 0x0d
-#define        BACKSPACE       0x08
-#define        SPACES_IN_TABS  8
-#define        SEND_ESCAPE     0x00
-#define START_BREAK    0x81
-#define        TIMER_TICK      0x82
-#define STOP_BREAK     0x83
-#define BASE(a) ((a) < 4 ? (short*)CIRRUS_FIRST : ((a) < 8 ? (short *)CIRRUS_SECOND : ((a) < 12 ? (short*)CIRRUS_THIRD : (short *)CIRRUS_FOURTH)))
-#define txack1 ((short *)0x7104)
-#define rxack1 ((short *)0x7102)
-#define mdack1  ((short *)0x7106)
-#define txack2  ((short *)0x7006)
-#define rxack2 ((short *)0x7004)
-#define mdack2  ((short *)0x7100)
-#define int_latch       ((short *) 0x7800)
-#define int_status      ((short *) 0x7c00)
-#define tx1_pending     0x20
-#define rx1_pending     0x10
-#define md1_pending     0x40
-#define tx2_pending     0x02
-#define rx2_pending     0x01
-#define md2_pending     0x40
-#define module1_bits   0x07
-#define module1_modern 0x08
-#define module2_bits   0x70
-#define module2_modern 0x80
-#define module_blank   0xf
-#define rs232_d25      0x0
-#define        rs232_rj45      0x1
-#define rs422_d25      0x3
-#define parallel       0x5
-
-#define        CLK0    0x00
-#define CLK1   0x01
-#define CLK2   0x02
-#define CLK3   0x03
-#define CLK4   0x04
-
-#define CIRRUS_REVC    0x42
-#define CIRRUS_REVE    0x44
-
-#define        TURNON  1
-#define TURNOFF 0
-
-/* The list of CIRRUS registers. 
-   NB. These registers are relative values on 8 bit boundaries whereas
-   on the RTA's the CIRRUS registers are on word boundaries. Use pointer
-   arithmetic (short *) to obtain the real addresses required */
-#define ccr    0x05            /* Channel Command Register     */
-#define ier    0x06            /* Interrupt Enable Register    */
-#define cor1   0x08            /* Channel Option Register 1    */
-#define cor2   0x09            /* Channel Option Register 2    */
-#define cor3   0x0a            /* Channel Option Register 3    */
-#define cor4   0x1e            /* Channel Option Register 4    */
-#define        cor5    0x1f            /* Channel Option Register 5    */
-
-#define ccsr   0x0b            /* Channel Control Status Register */
-#define rdcr   0x0e            /* Receive Data Count Register  */
-#define tdcr   0x12            /* Transmit Data Count Register */
-#define mcor1  0x15            /* Modem Change Option Register 1 */
-#define mcor2  0x16            /* Modem Change Option Regsiter 2 */
-
-#define livr   0x18            /* Local Interrupt Vector Register */
-#define schr1  0x1a            /* Special Character Register 1 */
-#define schr2  0x1b            /* Special Character Register 2 */
-#define schr3  0x1c            /* Special Character Register 3 */
-#define schr4  0x1d            /* Special Character Register 4 */
-
-#define rtr    0x20            /* Receive Timer Register */
-#define rtpr   0x21            /* Receive Timeout Period Register */
-#define lnc    0x24            /* Lnext character */
-
-#define rivr   0x43            /* Receive Interrupt Vector Register    */
-#define tivr   0x42            /* Transmit Interrupt Vector Register   */
-#define mivr   0x41            /* Modem Interrupt Vector Register      */
-#define gfrcr  0x40            /* Global Firmware Revision code Reg    */
-#define ricr   0x44            /* Receive Interrupting Channel Reg     */
-#define ticr   0x45            /* Transmit Interrupting Channel Reg    */
-#define micr   0x46            /* Modem Interrupting Channel Register  */
-
-#define gcr    0x4b            /* Global configuration register */
-#define misr    0x4c           /* Modem interrupt status register */
-
-#define rbusr  0x59
-#define tbusr  0x5a
-#define mbusr  0x5b
-
-#define eoir   0x60            /* End Of Interrupt Register */
-#define rdsr   0x62            /* Receive Data / Status Register */
-#define tdr    0x63            /* Transmit Data Register */
-#define svrr   0x67            /* Service Request Register */
-
-#define car    0x68            /* Channel Access Register */
-#define mir    0x69            /* Modem Interrupt Register */
-#define tir    0x6a            /* Transmit Interrupt Register */
-#define rir    0x6b            /* Receive Interrupt Register */
-#define msvr1  0x6c            /* Modem Signal Value Register 1 */
-#define msvr2  0x6d            /* Modem Signal Value Register 2 */
-#define psvr   0x6f            /* Printer Signal Value Register */
-
-#define tbpr   0x72            /* Transmit Baud Rate Period Register */
-#define tcor   0x76            /* Transmit Clock Option Register */
-
-#define rbpr   0x78            /* Receive Baud Rate Period Register */
-#define rber   0x7a            /* Receive Baud Rate Extension Register */
-#define rcor   0x7c            /* Receive Clock Option Register */
-#define ppr    0x7e            /* Prescalar Period Register    */
-
-/* Misc registers used for forcing the 1400 out of its reset woes */
-#define airl   0x6d
-#define airm   0x6e
-#define airh   0x6f
-#define btcr   0x66
-#define mtcr   0x6c
-#define tber   0x74
-
-#endif                         /* #ifdef RTA */
 
 
 /* Bit fields for particular registers */
index 5b600c32ac021a578fb32f75e6bdea2ed89b9a38..d55c2f6a9877ecf7cdb8d8e5f19ce1d61d38c66c 100644 (file)
@@ -45,13 +45,6 @@ static char *_rio_defaults_h_sccs = "@(#)defaults.h  1.1";
 #define MILLISECOND           (int) (1000/64)  /* 15.625 low ticks */
 #define SECOND                (int) 15625      /* Low priority ticks */
 
-#ifdef RTA
-#define RX_LIMIT       (ushort) 3
-#endif
-#ifdef HOST
-#define RX_LIMIT       (ushort) 1
-#endif
-
 #define LINK_TIMEOUT          (int) (POLL_PERIOD / 2)
 
 
index bfba5b0c033e89f871dfe08b3ece5e6de6fba1f7..48d68ca7f825e15a6d390b1d5ef1924ec6d5f4f4 100644 (file)
 /*
 ** LED stuff
 */
-#if defined(RTA)
-#define LED_OFF            ((ushort) 0)        /* LED off */
-#define LED_RED            ((ushort) 1)        /* LED Red */
-#define LED_GREEN          ((ushort) 2)        /* LED Green */
-#define LED_ORANGE         ((ushort) 4)        /* LED Orange */
-#define LED_1TO8_OPEN      ((ushort) 1)        /* Port 1->8 LED on */
-#define LED_9TO16_OPEN     ((ushort) 2)        /* Port 9->16 LED on */
-#define LED_SET_COLOUR(colour) (link->led = (colour))
-#define LED_OR_COLOUR(colour)  (link->led |= (colour))
-#define LED_TIMEOUT(time)    (link->led_timeout = RioTimePlus(RioTime(),(time)))
-#else
 #define LED_SET_COLOUR(colour)
 #define LED_OR_COLOUR(colour)
 #define LED_TIMEOUT(time)
-#endif                         /* RTA */
 
 struct LPB {
        WORD link_number;       /* Link Number */
        Channel_ptr in_ch;      /* Link In Channel */
        Channel_ptr out_ch;     /* Link Out Channel */
-#ifdef RTA
-       uchar stat_led;         /* Port open leds */
-       uchar led;              /* True, light led! */
-#endif
        BYTE attached_serial[4];        /* Attached serial number */
        BYTE attached_host_serial[4];
        /* Serial number of Host who
@@ -144,30 +128,12 @@ struct LPB {
        WORD WaitNoBoot;        /* Secs to hold off booting */
        PKT_ptr add_packet_list;        /* Add packets to here */
        PKT_ptr remove_packet_list;     /* Send packets from here */
-#ifdef RTA
-#ifdef DCIRRUS
-#define    QBUFS_PER_REDIRECT (4 / PKTS_PER_BUFFER + 1)
-#else
-#define    QBUFS_PER_REDIRECT (8 / PKTS_PER_BUFFER + 1)
-#endif
-       PKT_ptr_ptr rd_add;     /* Add a new Packet here */
-       Q_BUF_ptr rd_add_qb;    /* Pointer to the add Q buf */
-       PKT_ptr_ptr rd_add_st_qbb;      /* Pointer to start of the Q's buf */
-       PKT_ptr_ptr rd_add_end_qbb;     /* Pointer to the end of the Q's buf */
-       PKT_ptr_ptr rd_remove;  /* Remove a Packet here */
-       Q_BUF_ptr rd_remove_qb; /* Pointer to the remove Q buf */
-       PKT_ptr_ptr rd_remove_st_qbb;   /* Pointer to the start of the Q buf */
-       PKT_ptr_ptr rd_remove_end_qbb;  /* Pointer to the end of the Q buf */
-       ushort pkts_in_q;       /* Packets in queue */
-#endif
 
        Channel_ptr lrt_fail_chan;      /* Lrt's failure channel */
        Channel_ptr ltt_fail_chan;      /* Ltt's failure channel */
 
-#if defined (HOST) || defined (INKERNEL)
        /* RUP structure for HOST to driver communications */
        struct RUP rup;
-#endif
        struct RUP link_rup;    /* RUP for the link (POLL,
                                   topology etc.) */
        WORD attached_link;     /* Number of attached link */
index 36aad4c9cb3a2539f85074873ca480c921f67262..79b853140ae55f7d04f2a85d9bbd1da4bc9eb204 100644 (file)
@@ -44,8 +44,6 @@ static char *_rio_list_h_sccs = "@(#)list.h   1.9";
 
 #define PKT_IN_USE    0x1
 
-#ifdef INKERNEL
-
 #define ZERO_PTR (ushort) 0x8000
 #define        CaD     PortP->Caddr
 
@@ -54,143 +52,5 @@ static char *_rio_list_h_sccs = "@(#)list.h 1.9";
 ** to by the TxAdd pointer has PKT_IN_USE clear in its address.
 */
 
-#ifndef linux
-#if defined( MIPS ) && !defined( MIPSEISA )
-/* May the shoes of the Devil dance on your grave for creating this */
-#define   can_add_transmit(PacketP,PortP) \
-          (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \
-          & (PKT_IN_USE<<2)))
-
-#elif  defined(MIPSEISA) || defined(nx6000) || \
-       defined(drs6000)  || defined(UWsparc)
-
-#define   can_add_transmit(PacketP,PortP) \
-          (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \
-         & PKT_IN_USE))
-
-#else
-#define   can_add_transmit(PacketP,PortP) \
-          (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,*PortP->TxAdd)) \
-         & PKT_IN_USE))
-#endif
-
-/*
-** To add a packet to the queue, you set the PKT_IN_USE bit in the address,
-** and then move the TxAdd pointer along one position to point to the next
-** packet pointer. You must wrap the pointer from the end back to the start.
-*/
-#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
-#   define add_transmit(PortP)  \
-       WINDW(PortP->TxAdd,RINDW(PortP->TxAdd) | PKT_IN_USE);\
-       if (PortP->TxAdd == PortP->TxEnd)\
-           PortP->TxAdd = PortP->TxStart;\
-       else\
-           PortP->TxAdd++;\
-       WWORD(PortP->PhbP->tx_add , RIO_OFF(CaD,PortP->TxAdd));
-#elif defined(AIX)
-#   define add_transmit(PortP)  \
-       {\
-           register ushort *TxAddP = (ushort *)RIO_PTR(Cad,PortP->TxAddO);\
-           WINDW( TxAddP, RINDW( TxAddP ) | PKT_IN_USE );\
-           if (PortP->TxAddO == PortP->TxEndO )\
-               PortP->TxAddO = PortP->TxStartO;\
-           else\
-               PortP->TxAddO += sizeof(ushort);\
-           WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->tx_add , PortP->TxAddO );\
-       }
-#else
-#   define add_transmit(PortP)  \
-       *PortP->TxAdd |= PKT_IN_USE;\
-       if (PortP->TxAdd == PortP->TxEnd)\
-           PortP->TxAdd = PortP->TxStart;\
-       else\
-           PortP->TxAdd++;\
-       PortP->PhbP->tx_add = RIO_OFF(CaD,PortP->TxAdd);
-#endif
-
-/*
-** can_remove_receive( PacketP, PortP ) returns non-zero if PKT_IN_USE is set
-** for the next packet on the queue. It will also set PacketP to point to the
-** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
-** then can_remove_receive() returns 0.
-*/
-#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
-#   define can_remove_receive(PacketP,PortP) \
-       ((RINDW(PortP->RxRemove) & PKT_IN_USE) ? \
-       (PacketP=(struct PKT *)RIO_PTR(CaD,(RINDW(PortP->RxRemove) & ~PKT_IN_USE))):0)
-#elif defined(AIX)
-#   define can_remove_receive(PacketP,PortP) \
-       ((RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & PKT_IN_USE) ? \
-       (PacketP=(struct PKT *)RIO_PTR(Cad,RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & ~PKT_IN_USE)):0)
-#else
-#   define can_remove_receive(PacketP,PortP) \
-       ((*PortP->RxRemove & PKT_IN_USE) ? \
-       (PacketP=(struct PKT *)RIO_PTR(CaD,(*PortP->RxRemove & ~PKT_IN_USE))):0)
-#endif
-
-
-/*
-** Will God see it within his heart to forgive us for this thing that
-** we have created? To remove a packet from the receive queue you clear
-** its PKT_IN_USE bit, and then bump the pointers. Once the pointers
-** get to the end, they must be wrapped back to the start.
-*/
-#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
-#   define remove_receive(PortP) \
-       WINDW(PortP->RxRemove, (RINDW(PortP->RxRemove) & ~PKT_IN_USE));\
-       if (PortP->RxRemove == PortP->RxEnd)\
-           PortP->RxRemove = PortP->RxStart;\
-       else\
-           PortP->RxRemove++;\
-       WWORD(PortP->PhbP->rx_remove , RIO_OFF(CaD,PortP->RxRemove));
-#elif defined(AIX)
-#   define remove_receive(PortP) \
-    {\
-        register ushort *RxRemoveP = (ushort *)RIO_PTR(Cad,PortP->RxRemoveO);\
-        WINDW( RxRemoveP, RINDW( RxRemoveP ) & ~PKT_IN_USE );\
-        if (PortP->RxRemoveO == PortP->RxEndO)\
-            PortP->RxRemoveO = PortP->RxStartO;\
-        else\
-            PortP->RxRemoveO += sizeof(ushort);\
-        WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->rx_remove, PortP->RxRemoveO );\
-    }
-#else
-#   define remove_receive(PortP) \
-       *PortP->RxRemove &= ~PKT_IN_USE;\
-       if (PortP->RxRemove == PortP->RxEnd)\
-           PortP->RxRemove = PortP->RxStart;\
-       else\
-           PortP->RxRemove++;\
-       PortP->PhbP->rx_remove = RIO_OFF(CaD,PortP->RxRemove);
-#endif
-#endif
-
-
-#else                          /* !IN_KERNEL */
-
-#define ZERO_PTR NULL
-
-
-#ifdef HOST
-/* #define can_remove_transmit(pkt,phb) ((((char*)pkt = (*(char**)(phb->tx_remove))-1) || 1)) && (*phb->u3.s2.tx_remove_ptr & PKT_IN_USE))   */
-#define remove_transmit(phb) *phb->u3.s2.tx_remove_ptr &= ~(ushort)PKT_IN_USE;\
-                             if (phb->tx_remove == phb->tx_end)\
-                                phb->tx_remove = phb->tx_start;\
-                             else\
-                                phb->tx_remove++;
-#define can_add_receive(phb) !(*phb->u4.s2.rx_add_ptr & PKT_IN_USE)
-#define add_receive(pkt,phb) *phb->rx_add = pkt;\
-                             *phb->u4.s2.rx_add_ptr |= PKT_IN_USE;\
-                             if (phb->rx_add == phb->rx_end)\
-                                phb->rx_add = phb->rx_start;\
-                             else\
-                                phb->rx_add++;
-#endif
-#endif
-
-#ifdef RTA
-#define splx(oldspl)    if ((oldspl) == 0) spl0()
-#endif
-
 #endif                         /* ifndef _list.h */
 /*********** end of file ***********/
index fe4e00567065150d84e3aa3cb190caa936acdf21..e24acc1d18440d006b067fec23d06a97c738f5ff 100644 (file)
@@ -78,14 +78,9 @@ struct PARM_MAP {
        WORD idle_count;        /* Idle time counter */
        WORD busy_count;        /* Busy counter */
        WORD idle_control;      /* Control Idle Process */
-#if defined(HOST) || defined(INKERNEL)
        WORD tx_intr;           /* TX interrupt pending */
        WORD rx_intr;           /* RX interrupt pending */
        WORD rup_intr;          /* RUP interrupt pending */
-#endif
-#if defined(RTA)
-       WORD dying_count;       /* Count of processes dead */
-#endif
 };
 
 #endif
index 3baebf8513afe48d27c3803a868c116229a24df6..2663ca0306e2a0567f0d4fa2728e9e4ddb4a8df5 100644 (file)
 #endif
 
 
- /*************************************************
-  * Set the LIMIT values.
-  ************************************************/
-#ifdef RTA
-#define RX_LIMIT       (ushort) 3
-#endif
-#ifdef HOST
-#define RX_LIMIT       (ushort) 1
-#endif
-
-
 /*************************************************
  * Handshake asserted. Deasserted by the LTT(s)
  ************************************************/
 /*************************************************
  * Maximum number of PHB's
  ************************************************/
-#if defined (HOST) || defined (INKERNEL)
 #define MAX_PHB               ((ushort) 128)   /* range 0-127 */
-#else
-#define MAX_PHB               ((ushort) 8)     /* range 0-7 */
-#endif
 
 /*************************************************
  * Defines for the mode fields
  * the start. The pointer tx_add points to a SPACE to put a Packet.
  * The pointer tx_remove points to the next Packet to remove
  *************************************************************************/
-#ifndef INKERNEL
-#define src_unit     u2.s2.unit
-#define src_port     u2.s2.port
-#define dest_unit    u1.s1.unit
-#define dest_port    u1.s1.port
-#endif
-#ifdef HOST
-#define tx_start     u3.s1.tx_start_ptr_ptr
-#define tx_add       u3.s1.tx_add_ptr_ptr
-#define tx_end       u3.s1.tx_end_ptr_ptr
-#define tx_remove    u3.s1.tx_remove_ptr_ptr
-#define rx_start     u4.s1.rx_start_ptr_ptr
-#define rx_add       u4.s1.rx_add_ptr_ptr
-#define rx_end       u4.s1.rx_end_ptr_ptr
-#define rx_remove    u4.s1.rx_remove_ptr_ptr
-#endif
 typedef struct PHB PHB;
 struct PHB {
-#ifdef RTA
-       ushort port;
-#endif
-#ifdef INKERNEL
        WORD source;
-#else
-       union {
-               ushort source;  /* Complete source */
-               struct {
-                       unsigned char unit;     /* Source unit */
-                       unsigned char port;     /* Source port */
-               } s2;
-       } u2;
-#endif
        WORD handshake;
        WORD status;
        NUMBER timeout;         /* Maximum of 1.9 seconds */
        WORD link;              /* Send down this link */
-#ifdef INKERNEL
        WORD destination;
-#else
-       union {
-               ushort destination;     /* Complete destination */
-               struct {
-                       unsigned char unit;     /* Destination unit */
-                       unsigned char port;     /* Destination port */
-               } s1;
-       } u1;
-#endif
-#ifdef RTA
-       ushort tx_pkts_added;
-       ushort tx_pkts_removed;
-       Q_BUF_ptr tx_q_start;   /* Start of the Q list chain */
-       short num_tx_q_bufs;    /* Number of Q buffers in the chain */
-       PKT_ptr_ptr tx_add;     /* Add a new Packet here */
-       Q_BUF_ptr tx_add_qb;    /* Pointer to the add Q buf */
-       PKT_ptr_ptr tx_add_st_qbb;      /* Pointer to start of the Q's buf */
-       PKT_ptr_ptr tx_add_end_qbb;     /* Pointer to the end of the Q's buf */
-       PKT_ptr_ptr tx_remove;  /* Remove a Packet here */
-       Q_BUF_ptr tx_remove_qb; /* Pointer to the remove Q buf */
-       PKT_ptr_ptr tx_remove_st_qbb;   /* Pointer to the start of the Q buf */
-       PKT_ptr_ptr tx_remove_end_qbb;  /* Pointer to the end of the Q buf */
-#endif
-#ifdef INKERNEL
        PKT_ptr_ptr tx_start;
        PKT_ptr_ptr tx_end;
        PKT_ptr_ptr tx_add;
        PKT_ptr_ptr tx_remove;
-#endif
-#ifdef HOST
-       union {
-               struct {
-                       PKT_ptr_ptr tx_start_ptr_ptr;
-                       PKT_ptr_ptr tx_end_ptr_ptr;
-                       PKT_ptr_ptr tx_add_ptr_ptr;
-                       PKT_ptr_ptr tx_remove_ptr_ptr;
-               } s1;
-               struct {
-                       ushort *tx_start_ptr;
-                       ushort *tx_end_ptr;
-                       ushort *tx_add_ptr;
-                       ushort *tx_remove_ptr;
-               } s2;
-       } u3;
-#endif
 
-#ifdef  RTA
-       ushort rx_pkts_added;
-       ushort rx_pkts_removed;
-       Q_BUF_ptr rx_q_start;   /* Start of the Q list chain */
-       short num_rx_q_bufs;    /* Number of Q buffers in the chain */
-       PKT_ptr_ptr rx_add;     /* Add a new Packet here */
-       Q_BUF_ptr rx_add_qb;    /* Pointer to the add Q buf */
-       PKT_ptr_ptr rx_add_st_qbb;      /* Pointer to start of the Q's buf */
-       PKT_ptr_ptr rx_add_end_qbb;     /* Pointer to the end of the Q's buf */
-       PKT_ptr_ptr rx_remove;  /* Remove a Packet here */
-       Q_BUF_ptr rx_remove_qb; /* Pointer to the remove Q buf */
-       PKT_ptr_ptr rx_remove_st_qbb;   /* Pointer to the start of the Q buf */
-       PKT_ptr_ptr rx_remove_end_qbb;  /* Pointer to the end of the Q buf */
-#endif
-#ifdef INKERNEL
        PKT_ptr_ptr rx_start;
        PKT_ptr_ptr rx_end;
        PKT_ptr_ptr rx_add;
        PKT_ptr_ptr rx_remove;
-#endif
-#ifdef HOST
-       union {
-               struct {
-                       PKT_ptr_ptr rx_start_ptr_ptr;
-                       PKT_ptr_ptr rx_end_ptr_ptr;
-                       PKT_ptr_ptr rx_add_ptr_ptr;
-                       PKT_ptr_ptr rx_remove_ptr_ptr;
-               } s1;
-               struct {
-                       ushort *rx_start_ptr;
-                       ushort *rx_end_ptr;
-                       ushort *rx_add_ptr;
-                       ushort *rx_remove_ptr;
-               } s2;
-       } u4;
-#endif
-
-#ifdef RTA                     /* some fields for the remotes */
-       ushort flush_count;     /* Count of write flushes */
-       ushort txmode;          /* Modes for tx */
-       ushort rxmode;          /* Modes for rx */
-       ushort portmode;        /* Generic modes */
-       ushort column;          /* TAB3 column count */
-       ushort tx_subscript;    /* (TX) Subscript into data field */
-       ushort rx_subscript;    /* (RX) Subscript into data field */
-       PKT_ptr rx_incomplete;  /* Hold an incomplete packet here */
-       ushort modem_bits;      /* Modem bits to mask */
-       ushort lastModem;       /* Modem control lines. */
-       ushort addr;            /* Address for sub commands */
-       ushort MonitorTstate;   /* TRUE if monitoring tstop */
-#endif
 
 };
 
index 882fd429ac2ef44494da9787cd0fff1b23db9f34..7011e52e82db51e2a005ece5c9f0363ab59f2b8c 100644 (file)
 #define CONTROL_DATA_WNDW  (DATA_WNDW << 8)
 
 struct PKT {
-#ifdef INKERNEL
        BYTE dest_unit;         /* Destination Unit Id */
        BYTE dest_port;         /* Destination POrt */
        BYTE src_unit;          /* Source Unit Id */
        BYTE src_port;          /* Source POrt */
-#else
-       union {
-               ushort destination;     /* Complete destination */
-               struct {
-                       unsigned char unit;     /* Destination unit */
-                       unsigned char port;     /* Destination port */
-               } s1;
-       } u1;
-       union {
-               ushort source;  /* Complete source */
-               struct {
-                       unsigned char unit;     /* Source unit */
-                       unsigned char port;     /* Source port */
-               } s2;
-       } u2;
-#endif
-#ifdef INKERNEL
        BYTE len;
        BYTE control;
-#else
-       union {
-               ushort control;
-               struct {
-                       unsigned char len;
-                       unsigned char control;
-               } s3;
-       } u3;
-#endif
        BYTE data[PKT_MAX_DATA_LEN];
        /* Actual data :-) */
        WORD csum;              /* C-SUM */
index acd9e8e5307de628a2282aeaf4603aa90a48bda3..391ffc335535f37b6a2b51ec69b0a946278b8c34 100644 (file)
@@ -46,11 +46,7 @@ static char *_rio_qbuf_h_sccs = "@(#)qbuf.h  1.1";
 
 
 
-#ifdef HOST
-#define PKTS_PER_BUFFER    1
-#else
 #define PKTS_PER_BUFFER    (220 / PKT_LENGTH)
-#endif
 
 typedef struct Q_BUF Q_BUF;
 struct Q_BUF {
index 9b67e2468becd51a280d4c3637d656c56b8f991c..46084d5c7e983e21f1068255ddea077ad8584aba 100644 (file)
@@ -43,9 +43,6 @@
 #endif
 #endif
 
-#ifdef INKERNEL
-
-#if !defined(MIPSAT)
 typedef unsigned short NUMBER_ptr;
 typedef unsigned short WORD_ptr;
 typedef unsigned short BYTE_ptr;
@@ -65,69 +62,6 @@ typedef unsigned short RUP_ptr;
 typedef unsigned short short_ptr;
 typedef unsigned short u_short_ptr;
 typedef unsigned short ushort_ptr;
-#else
-/* MIPSAT types */
-typedef char RIO_POINTER[8];
-typedef RIO_POINTER NUMBER_ptr;
-typedef RIO_POINTER WORD_ptr;
-typedef RIO_POINTER BYTE_ptr;
-typedef RIO_POINTER char_ptr;
-typedef RIO_POINTER Channel_ptr;
-typedef RIO_POINTER FREE_LIST_ptr_ptr;
-typedef RIO_POINTER FREE_LIST_ptr;
-typedef RIO_POINTER LPB_ptr;
-typedef RIO_POINTER Process_ptr;
-typedef RIO_POINTER PHB_ptr;
-typedef RIO_POINTER PKT_ptr;
-typedef RIO_POINTER PKT_ptr_ptr;
-typedef RIO_POINTER Q_BUF_ptr;
-typedef RIO_POINTER Q_BUF_ptr_ptr;
-typedef RIO_POINTER ROUTE_STR_ptr;
-typedef RIO_POINTER RUP_ptr;
-typedef RIO_POINTER short_ptr;
-typedef RIO_POINTER u_short_ptr;
-typedef RIO_POINTER ushort_ptr;
-#endif
-
-#else                          /* not INKERNEL */
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-typedef short NUMBER;
-typedef short *NUMBER_ptr;
-typedef unsigned short *WORD_ptr;
-typedef unsigned char *BYTE_ptr;
-typedef unsigned char uchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-typedef unsigned short ERROR;
-typedef unsigned long ID;
-typedef char *char_ptr;
-typedef Channel *Channel_ptr;
-typedef struct FREE_LIST *FREE_LIST_ptr;
-typedef struct FREE_LIST **FREE_LIST_ptr_ptr;
-typedef struct LPB *LPB_ptr;
-typedef struct Process *Process_ptr;
-typedef struct PHB *PHB_ptr;
-typedef struct PKT *PKT_ptr;
-typedef struct PKT **PKT_ptr_ptr;
-typedef struct Q_BUF *Q_BUF_ptr;
-typedef struct Q_BUF **Q_BUF_ptr_ptr;
-typedef struct ROUTE_STR *ROUTE_STR_ptr;
-typedef struct RUP *RUP_ptr;
-typedef short *short_ptr;
-typedef u_short *u_short_ptr;
-typedef ushort *ushort_ptr;
-typedef struct PKT PKT;
-typedef struct LPB LPB;
-typedef struct RUP RUP;
-#endif
-
 
 #endif                         /* __riotypes__ */
 
index 8d44fec91dd5212a1f588c4cc7752865a847d990..f74f67c6f702a72a4c99832c61a267e43feb2636 100644 (file)
 #endif
 #endif
 
-#if defined( HOST ) || defined( INKERNEL )
 #define MAX_RUP          ((short) 16)
-#endif
-#ifdef RTA
-#define MAX_RUP          ((short) 1)
-#endif
 
 #define PKTS_PER_RUP     ((short) 2)   /* They are always used in pairs */
 
index 31494054b21380875a89f42c557bb05c573cf09d..6f754e19015d573432af716360084acc0447c189 100644 (file)
 #endif
 
 
-#if !defined( HOST ) && !defined( INKERNEL )
-#define RTA 1
-#endif
-
 #define NUM_FREE_LIST_UNITS     500
 
 #ifndef FALSE
index 0949dcef06976d8f78a250a0a725f99ce06f8f11..7edc6a4dbdc43f371df3064f68930284889a66a0 100644 (file)
@@ -433,7 +433,7 @@ static void rp_do_receive(struct r_port *info,
                count += ToRecv;
        }
        /*  Push the data up to the tty layer */
-       ld->receive_buf(tty, cbuf, fbuf, count);
+       ld->receive_buf(tty, chead, fhead, count);
 done:
        tty_ldisc_deref(ld);
 }
index 80a5b840e22f646b432ab17cfe259ebd8f4c96a5..fee68cc895f8c770ee844c9507b93a47263f3111 100644 (file)
 
 #include <linux/serial.h>
 #include <linux/generic_serial.h>
+#include <linux/tty_flip.h>
 
 #include "ser_a2232.h"
 #include "ser_a2232fw.h"
index 64bf89cb574f75d105dd4283a8c8c711fc22ae4e..c2490e270f1fc92b280b477eaff5605bbb4b79e6 100644 (file)
@@ -931,7 +931,7 @@ static int sx_set_real_termios (void *ptr)
        case CS6:sx_write_channel_byte (port, hi_mask, 0x3f);break;
        case CS5:sx_write_channel_byte (port, hi_mask, 0x1f);break;
        default:
-               printk (KERN_INFO "sx: Invalid wordsize: %d\n", CFLAG & CSIZE);
+               printk (KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
                break;
        }
 
@@ -958,7 +958,7 @@ static int sx_set_real_termios (void *ptr)
        } else {
                set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
        }
-       sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ", 
+       sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
                    port->gs.tty->termios->c_iflag, 
                    I_OTHER(port->gs.tty));
 
@@ -973,7 +973,7 @@ static int sx_set_real_termios (void *ptr)
        } else {
                clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
        }
-       sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", 
+       sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
                    port->gs.tty->termios->c_oflag, 
                    O_OTHER(port->gs.tty));
        /* port->c_dcd = sx_get_CD (port); */
index eb8b5be4e2494c318e9f4af4195d8cd0b63cede7..076e07c1da38dc441592d8a98d83804d4ff8afea 100644 (file)
@@ -253,6 +253,7 @@ static void tty_buffer_free_all(struct tty_struct *tty)
 
 static void tty_buffer_init(struct tty_struct *tty)
 {
+       spin_lock_init(&tty->buf.lock);
        tty->buf.head = NULL;
        tty->buf.tail = NULL;
        tty->buf.free = NULL;
@@ -266,6 +267,7 @@ static struct tty_buffer *tty_buffer_alloc(size_t size)
        p->used = 0;
        p->size = size;
        p->next = NULL;
+       p->active = 0;
        p->char_buf_ptr = (char *)(p->data);
        p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
 /*     printk("Flip create %p\n", p); */
@@ -312,25 +314,36 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
 
 int tty_buffer_request_room(struct tty_struct *tty, size_t size)
 {
-       struct tty_buffer *b = tty->buf.tail, *n;
-       int left = 0;
+       struct tty_buffer *b, *n;
+       int left;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tty->buf.lock, flags);
 
        /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
           remove this conditional if its worth it. This would be invisible
           to the callers */
-       if(b != NULL)
+       if ((b = tty->buf.tail) != NULL) {
                left = b->size - b->used;
-       if(left >= size)
-               return size;
-       /* This is the slow path - looking for new buffers to use */
-       n = tty_buffer_find(tty, size);
-       if(n == NULL)
-               return left;
-       if(b != NULL)
-               b->next = n;
-       else
-               tty->buf.head = n;
-       tty->buf.tail = n;
+               b->active = 1;
+       } else
+               left = 0;
+
+       if (left < size) {
+               /* This is the slow path - looking for new buffers to use */
+               if ((n = tty_buffer_find(tty, size)) != NULL) {
+                       if (b != NULL) {
+                               b->next = n;
+                               b->active = 0;
+                       } else
+                               tty->buf.head = n;
+                       tty->buf.tail = n;
+                       n->active = 1;
+               } else
+                       size = left;
+       }
+
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
        return size;
 }
 
@@ -396,10 +409,12 @@ EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags);
 int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size)
 {
        int space = tty_buffer_request_room(tty, size);
-       struct tty_buffer *tb = tty->buf.tail;
-       *chars = tb->char_buf_ptr + tb->used;
-       memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
-       tb->used += space;
+       if (likely(space)) {
+               struct tty_buffer *tb = tty->buf.tail;
+               *chars = tb->char_buf_ptr + tb->used;
+               memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+               tb->used += space;
+       }
        return space;
 }
 
@@ -416,10 +431,12 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
 int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size)
 {
        int space = tty_buffer_request_room(tty, size);
-       struct tty_buffer *tb = tty->buf.tail;
-       *chars = tb->char_buf_ptr + tb->used;
-       *flags = tb->flag_buf_ptr + tb->used;
-       tb->used += space;
+       if (likely(space)) {
+               struct tty_buffer *tb = tty->buf.tail;
+               *chars = tb->char_buf_ptr + tb->used;
+               *flags = tb->flag_buf_ptr + tb->used;
+               tb->used += space;
+       }
        return space;
 }
 
@@ -2747,20 +2764,20 @@ static void flush_to_ldisc(void *private_)
                schedule_delayed_work(&tty->buf.work, 1);
                goto out;
        }
-       spin_lock_irqsave(&tty->read_lock, flags);
-       while((tbuf = tty->buf.head) != NULL) {
+       spin_lock_irqsave(&tty->buf.lock, flags);
+       while((tbuf = tty->buf.head) != NULL && !tbuf->active) {
                tty->buf.head = tbuf->next;
                if (tty->buf.head == NULL)
                        tty->buf.tail = NULL;
-               spin_unlock_irqrestore(&tty->read_lock, flags);
+               spin_unlock_irqrestore(&tty->buf.lock, flags);
                /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */
                disc->receive_buf(tty, tbuf->char_buf_ptr,
                                       tbuf->flag_buf_ptr,
                                       tbuf->used);
-               spin_lock_irqsave(&tty->read_lock, flags);
+               spin_lock_irqsave(&tty->buf.lock, flags);
                tty_buffer_free(tty, tbuf);
        }
-       spin_unlock_irqrestore(&tty->read_lock, flags);
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
 out:
        tty_ldisc_deref(disc);
 }
@@ -2852,6 +2869,12 @@ EXPORT_SYMBOL(tty_get_baud_rate);
 
 void tty_flip_buffer_push(struct tty_struct *tty)
 {
+       unsigned long flags;
+       spin_lock_irqsave(&tty->buf.lock, flags);
+       if (tty->buf.tail != NULL)
+               tty->buf.tail->active = 0;
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+
        if (tty->low_latency)
                flush_to_ldisc((void *) tty);
        else
index 951764614ebf66ba4c309f1c978080c57710e9a8..837b1ec3ffe32c640ebbd6f0f39c9ef646c28f60 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -91,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t epx_c3_write(struct file *file, const char *data,
+static ssize_t epx_c3_write(struct file *file, const char __user *data,
                        size_t len, loff_t *ppos)
 {
        /* Refresh the timer. */
@@ -104,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
        int options, retval = -EINVAL;
+       int __user *argp = (void __user *)arg;
        static struct watchdog_info ident = {
                .options                = WDIOF_KEEPALIVEPING |
                                          WDIOF_MAGICCLOSE,
@@ -113,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-               if (copy_to_user((struct watchdog_info *)arg,
-                                &ident, sizeof(ident)))
+               if (copy_to_user(argp, &ident, sizeof(ident)))
                        return -EFAULT;
                return 0;
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               return put_user(0,(int *)arg);
+               return put_user(0, argp);
        case WDIOC_KEEPALIVE:
                epx_c3_pet();
                return 0;
        case WDIOC_GETTIMEOUT:
-               return put_user(WATCHDOG_TIMEOUT,(int *)arg);
-       case WDIOC_SETOPTIONS: {
-               if (get_user(options, (int *)arg))
+               return put_user(WATCHDOG_TIMEOUT, argp);
+       case WDIOC_SETOPTIONS:
+               if (get_user(options, argp))
                        return -EFAULT;
 
                if (options & WDIOS_DISABLECARD) {
@@ -140,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
                }
 
                return retval;
-       }
        default:
                return -ENOIOCTLCMD;
        }
@@ -181,11 +181,14 @@ static int __init watchdog_init(void)
 {
        int ret;
 
+       if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog"))
+               return -EBUSY;
+
        ret = register_reboot_notifier(&epx_c3_notifier);
        if (ret) {
                printk(KERN_ERR PFX "cannot register reboot notifier "
                        "(err=%d)\n", ret);
-               return ret;
+               goto out;
        }
 
        ret = misc_register(&epx_c3_miscdev);
@@ -193,18 +196,23 @@ static int __init watchdog_init(void)
                printk(KERN_ERR PFX "cannot register miscdev on minor=%d "
                        "(err=%d)\n", WATCHDOG_MINOR, ret);
                unregister_reboot_notifier(&epx_c3_notifier);
-               return ret;
+               goto out;
        }
 
        printk(banner);
 
        return 0;
+
+out:
+       release_region(EPXC3_WATCHDOG_CTL_REG, 2);
+       return ret;
 }
 
 static void __exit watchdog_exit(void)
 {
        misc_deregister(&epx_c3_miscdev);
        unregister_reboot_notifier(&epx_c3_notifier);
+       release_region(EPXC3_WATCHDOG_CTL_REG, 2);
 }
 
 module_init(watchdog_init);
index 4819e7fc00ddf1467cc3e61b8835e01c531b6fd0..18a4556511216062c523a988477ffb35520a5ce1 100644 (file)
@@ -11,7 +11,6 @@ menu 'EDAC - error detection and reporting (RAS)'
 config EDAC
        tristate "EDAC core system error reporting"
        depends on X86
-       default y
        help
          EDAC is designed to report errors in the core system.
          These are low-level errors that are reported in the CPU or
@@ -46,7 +45,7 @@ config EDAC_MM_EDAC
 
 config EDAC_AMD76X
        tristate "AMD 76x (760, 762, 768)"
-       depends on EDAC_MM_EDAC  && PCI
+       depends on EDAC_MM_EDAC && PCI && X86_32
        help
          Support for error detection and correction on the AMD 76x
          series of chipsets used with the Athlon processor.
index 770a5a6330798c33873a2d992d29d8d7cb03c138..c454ded2b0600974ad035cece99f5422a5e411a9 100644 (file)
@@ -1039,10 +1039,10 @@ MODULE_DEVICE_TABLE(pci, e752x_pci_tbl);
 
 
 static struct pci_driver e752x_driver = {
-      name: BS_MOD_STR,
-      probe: e752x_init_one,
-      remove: __devexit_p(e752x_remove_one),
-      id_table: e752x_pci_tbl,
+       .name = BS_MOD_STR,
+       .probe = e752x_init_one,
+       .remove = __devexit_p(e752x_remove_one),
+       .id_table = e752x_pci_tbl,
 };
 
 
index 4be9bd0a1267890604b815785a5bf425cd6154fa..b10ee4698b1db95f8b3045fd7fd814648cedfed0 100644 (file)
@@ -14,7 +14,6 @@
 
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
index 009c08fe5d69289153e6719ba89dc2d4e3963cbc..1991f94af7538d568bffd7ecc2faf7aa8e4fac43 100644 (file)
@@ -159,7 +159,7 @@ enum i82875p_chips {
 
 struct i82875p_pvt {
        struct pci_dev *ovrfl_pdev;
-       void *ovrfl_window;
+       void __iomem *ovrfl_window;
 };
 
 
index c58295914365940f88c769f082a9293d6749da34..7230d4e081964e79fb2963273311a17a83e30b85 100644 (file)
@@ -113,6 +113,16 @@ config SENSORS_DS1621
          This driver can also be built as a module.  If so, the module
          will be called ds1621.
 
+config SENSORS_F71805F
+       tristate "Fintek F71805F/FG"
+       depends on HWMON && EXPERIMENTAL
+       help
+         If you say yes here you get support for hardware monitoring
+         features of the Fintek F71805F/FG chips.
+
+         This driver can also be built as a module.  If so, the module
+         will be called f71805f.
+
 config SENSORS_FSCHER
        tristate "FSC Hermes"
        depends on HWMON && I2C && EXPERIMENTAL
index 06d4a1d14105d9f038a6ab78eced7967674a3df3..fbdb8d911a7208979c2152ce5268195c93562245 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)  += adm9240.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_DS1621)   += ds1621.o
+obj-$(CONFIG_SENSORS_F71805F)  += f71805f.o
 obj-$(CONFIG_SENSORS_FSCHER)   += fscher.o
 obj-$(CONFIG_SENSORS_FSCPOS)   += fscpos.o
 obj-$(CONFIG_SENSORS_GL518SM)  += gl518sm.o
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
new file mode 100644 (file)
index 0000000..e029e0a
--- /dev/null
@@ -0,0 +1,908 @@
+/*
+ * 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>
+ *
+ * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
+ * complete hardware monitoring features: voltage, fan and temperature
+ * sensors, and manual and automatic fan speed control.
+ *
+ * This program is free software; 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/err.h>
+#include <asm/io.h>
+
+static struct platform_device *pdev;
+
+#define DRVNAME "f71805f"
+
+/*
+ * Super-I/O constants and functions
+ */
+
+#define F71805F_LD_HWM         0x04
+
+#define SIO_REG_LDSEL          0x07    /* Logical device select */
+#define SIO_REG_DEVID          0x20    /* Device ID (2 bytes) */
+#define SIO_REG_DEVREV         0x22    /* Device revision */
+#define SIO_REG_MANID          0x23    /* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE         0x30    /* Logical device enable */
+#define SIO_REG_ADDR           0x60    /* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID          0x1934
+#define SIO_F71805F_ID         0x0406
+
+static inline int
+superio_inb(int base, int reg)
+{
+       outb(reg, base);
+       return inb(base + 1);
+}
+
+static int
+superio_inw(int base, int reg)
+{
+       int val;
+       outb(reg++, base);
+       val = inb(base + 1) << 8;
+       outb(reg, base);
+       val |= inb(base + 1);
+       return val;
+}
+
+static inline void
+superio_select(int base, int ld)
+{
+       outb(SIO_REG_LDSEL, base);
+       outb(ld, base + 1);
+}
+
+static inline void
+superio_enter(int base)
+{
+       outb(0x87, base);
+       outb(0x87, base);
+}
+
+static inline void
+superio_exit(int base)
+{
+       outb(0xaa, base);
+}
+
+/*
+ * ISA constants
+ */
+
+#define REGION_LENGTH          2
+#define ADDR_REG_OFFSET                0
+#define DATA_REG_OFFSET                1
+
+static struct resource f71805f_resource __initdata = {
+       .flags  = IORESOURCE_IO,
+};
+
+/*
+ * Registers
+ */
+
+/* in nr from 0 to 8 (8-bit values) */
+#define F71805F_REG_IN(nr)             (0x10 + (nr))
+#define F71805F_REG_IN_HIGH(nr)                (0x40 + 2 * (nr))
+#define F71805F_REG_IN_LOW(nr)         (0x41 + 2 * (nr))
+/* fan nr from 0 to 2 (12-bit values, two registers) */
+#define F71805F_REG_FAN(nr)            (0x20 + 2 * (nr))
+#define F71805F_REG_FAN_LOW(nr)                (0x28 + 2 * (nr))
+#define F71805F_REG_FAN_CTRL(nr)       (0x60 + 16 * (nr))
+/* temp nr from 0 to 2 (8-bit values) */
+#define F71805F_REG_TEMP(nr)           (0x1B + (nr))
+#define F71805F_REG_TEMP_HIGH(nr)      (0x54 + 2 * (nr))
+#define F71805F_REG_TEMP_HYST(nr)      (0x55 + 2 * (nr))
+#define F71805F_REG_TEMP_MODE          0x01
+
+#define F71805F_REG_START              0x00
+/* status nr from 0 to 2 */
+#define F71805F_REG_STATUS(nr)         (0x36 + (nr))
+
+/*
+ * Data structures and manipulation thereof
+ */
+
+struct f71805f_data {
+       unsigned short addr;
+       const char *name;
+       struct semaphore lock;
+       struct class_device *class_dev;
+
+       struct semaphore update_lock;
+       char valid;             /* !=0 if following fields are valid */
+       unsigned long last_updated;     /* In jiffies */
+       unsigned long last_limits;      /* In jiffies */
+
+       /* Register values */
+       u8 in[9];
+       u8 in_high[9];
+       u8 in_low[9];
+       u16 fan[3];
+       u16 fan_low[3];
+       u8 fan_enabled;         /* Read once at init time */
+       u8 temp[3];
+       u8 temp_high[3];
+       u8 temp_hyst[3];
+       u8 temp_mode;
+       u8 alarms[3];
+};
+
+static inline long in_from_reg(u8 reg)
+{
+       return (reg * 8);
+}
+
+/* The 2 least significant bits are not used */
+static inline u8 in_to_reg(long val)
+{
+       if (val <= 0)
+               return 0;
+       if (val >= 2016)
+               return 0xfc;
+       return (((val + 16) / 32) << 2);
+}
+
+/* in0 is downscaled by a factor 2 internally */
+static inline long in0_from_reg(u8 reg)
+{
+       return (reg * 16);
+}
+
+static inline u8 in0_to_reg(long val)
+{
+       if (val <= 0)
+               return 0;
+       if (val >= 4032)
+               return 0xfc;
+       return (((val + 32) / 64) << 2);
+}
+
+/* The 4 most significant bits are not used */
+static inline long fan_from_reg(u16 reg)
+{
+       reg &= 0xfff;
+       if (!reg || reg == 0xfff)
+               return 0;
+       return (1500000 / reg);
+}
+
+static inline u16 fan_to_reg(long rpm)
+{
+       /* If the low limit is set below what the chip can measure,
+          store the largest possible 12-bit value in the registers,
+          so that no alarm will ever trigger. */
+       if (rpm < 367)
+               return 0xfff;
+       return (1500000 / rpm);
+}
+
+static inline long temp_from_reg(u8 reg)
+{
+       return (reg * 1000);
+}
+
+static inline u8 temp_to_reg(long val)
+{
+       if (val < 0)
+               val = 0;
+       else if (val > 1000 * 0xff)
+               val = 0xff;
+       return ((val + 500) / 1000);
+}
+
+/*
+ * Device I/O access
+ */
+
+static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
+{
+       u8 val;
+
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       val = inb(data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+
+       return val;
+}
+
+static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
+{
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       outb(val, data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+}
+
+/* It is important to read the MSB first, because doing so latches the
+   value of the LSB, so we are sure both bytes belong to the same value. */
+static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
+{
+       u16 val;
+
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       val = inb(data->addr + DATA_REG_OFFSET) << 8;
+       outb(++reg, data->addr + ADDR_REG_OFFSET);
+       val |= inb(data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+
+       return val;
+}
+
+static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
+{
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       outb(val >> 8, data->addr + DATA_REG_OFFSET);
+       outb(++reg, data->addr + ADDR_REG_OFFSET);
+       outb(val & 0xff, data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+}
+
+static struct f71805f_data *f71805f_update_device(struct device *dev)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       int nr;
+
+       down(&data->update_lock);
+
+       /* Limit registers cache is refreshed after 60 seconds */
+       if (time_after(jiffies, data->last_updated + 60 * HZ)
+        || !data->valid) {
+               for (nr = 0; nr < 9; nr++) {
+                       data->in_high[nr] = f71805f_read8(data,
+                                           F71805F_REG_IN_HIGH(nr));
+                       data->in_low[nr] = f71805f_read8(data,
+                                          F71805F_REG_IN_LOW(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       if (data->fan_enabled & (1 << nr))
+                               data->fan_low[nr] = f71805f_read16(data,
+                                                   F71805F_REG_FAN_LOW(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       data->temp_high[nr] = f71805f_read8(data,
+                                             F71805F_REG_TEMP_HIGH(nr));
+                       data->temp_hyst[nr] = f71805f_read8(data,
+                                             F71805F_REG_TEMP_HYST(nr));
+               }
+               data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
+
+               data->last_limits = jiffies;
+       }
+
+       /* Measurement registers cache is refreshed after 1 second */
+       if (time_after(jiffies, data->last_updated + HZ)
+        || !data->valid) {
+               for (nr = 0; nr < 9; nr++) {
+                       data->in[nr] = f71805f_read8(data,
+                                      F71805F_REG_IN(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       if (data->fan_enabled & (1 << nr))
+                               data->fan[nr] = f71805f_read16(data,
+                                               F71805F_REG_FAN(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       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->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       up(&data->update_lock);
+
+       return data;
+}
+
+/*
+ * Sysfs interface
+ */
+
+static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
+                       char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in[0]));
+}
+
+static ssize_t show_in0_max(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0]));
+}
+
+static ssize_t show_in0_min(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0]));
+}
+
+static ssize_t set_in0_max(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_high[0] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_in0_min(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_low[0] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+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 ssize_t show_in(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in[nr]));
+}
+
+static ssize_t show_in_max(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr]));
+}
+
+static ssize_t show_in_min(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr]));
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute
+                         *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_high[nr] = in_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute
+                         *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_low[nr] = in_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_in(offset)                                       \
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,         \
+               show_in, NULL, offset);                         \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+               show_in_max, set_in_max, offset);               \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+               show_in_min, set_in_min, offset)
+
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
+sysfs_in(7);
+sysfs_in(8);
+
+static ssize_t show_fan(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr]));
+}
+
+static ssize_t show_fan_min(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->fan_low[nr] = fan_to_reg(val);
+       f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_fan(offset)                                      \
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                \
+               show_fan, NULL, offset - 1);                    \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,        \
+               show_fan_min, set_fan_min, offset - 1)
+
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
+
+static ssize_t show_temp(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
+}
+
+static ssize_t show_temp_max(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr]));
+}
+
+static ssize_t show_temp_hyst(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 nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr]));
+}
+
+static ssize_t show_temp_type(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 nr = attr->index;
+
+       /* 3 is diode, 4 is thermistor */
+       return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4);
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute
+                           *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->temp_high[nr] = temp_to_reg(val);
+       f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
+                            *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->temp_hyst[nr] = temp_to_reg(val);
+       f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_temp(offset)                                             \
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,               \
+               show_temp, NULL, offset - 1);                           \
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,       \
+               show_temp_max, set_temp_max, offset - 1);               \
+static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,  \
+               show_temp_hyst, set_temp_hyst, offset - 1);             \
+static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO,                        \
+               show_temp_type, NULL, offset - 1)
+
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+
+static ssize_t show_alarms_in(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", data->alarms[0] |
+                                   ((data->alarms[1] & 0x01) << 8));
+}
+
+static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
+                              *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", data->alarms[2] & 0x07);
+}
+
+static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
+                               *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07);
+}
+
+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 ssize_t show_name(struct device *dev, struct device_attribute
+                        *devattr, char *buf)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+/*
+ * Device registration and initialization
+ */
+
+static void __devinit f71805f_init_device(struct f71805f_data *data)
+{
+       u8 reg;
+       int i;
+
+       reg = f71805f_read8(data, F71805F_REG_START);
+       if ((reg & 0x41) != 0x01) {
+               printk(KERN_DEBUG DRVNAME ": Starting monitoring "
+                      "operations\n");
+               f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40);
+       }
+
+       /* Fan monitoring can be disabled. If it is, we won't be polling
+          the register values, and won't create the related sysfs files. */
+       for (i = 0; i < 3; i++) {
+               reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i));
+               if (!(reg & 0x80))
+                       data->fan_enabled |= (1 << i);
+       }
+}
+
+static int __devinit f71805f_probe(struct platform_device *pdev)
+{
+       struct f71805f_data *data;
+       struct resource *res;
+       int err;
+
+       if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Out of memory\n");
+               goto exit;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       data->addr = res->start;
+       init_MUTEX(&data->lock);
+       data->name = "f71805f";
+       init_MUTEX(&data->update_lock);
+
+       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 */
+       device_create_file(&pdev->dev, &dev_attr_in0_input);
+       device_create_file(&pdev->dev, &dev_attr_in0_max);
+       device_create_file(&pdev->dev, &dev_attr_in0_min);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr);
+       if (data->fan_enabled & (1 << 0)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan1_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan1_min.dev_attr);
+       }
+       if (data->fan_enabled & (1 << 1)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan2_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan2_min.dev_attr);
+       }
+       if (data->fan_enabled & (1 << 2)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan3_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan3_min.dev_attr);
+       }
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_input.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_max_hyst.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_max_hyst.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_max_hyst.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr);
+       device_create_file(&pdev->dev, &dev_attr_alarms_in);
+       device_create_file(&pdev->dev, &dev_attr_alarms_fan);
+       device_create_file(&pdev->dev, &dev_attr_alarms_temp);
+       device_create_file(&pdev->dev, &dev_attr_name);
+
+       return 0;
+
+exit_free:
+       kfree(data);
+exit:
+       return err;
+}
+
+static int __devexit f71805f_remove(struct platform_device *pdev)
+{
+       struct f71805f_data *data = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       hwmon_device_unregister(data->class_dev);
+       kfree(data);
+
+       return 0;
+}
+
+static struct platform_driver f71805f_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = DRVNAME,
+       },
+       .probe          = f71805f_probe,
+       .remove         = __devexit_p(f71805f_remove),
+};
+
+static int __init f71805f_device_add(unsigned short address)
+{
+       int err;
+
+       pdev = platform_device_alloc(DRVNAME, address);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+               goto exit;
+       }
+
+       f71805f_resource.start = address;
+       f71805f_resource.end = address + REGION_LENGTH - 1;
+       f71805f_resource.name = pdev->name;
+       err = platform_device_add_resources(pdev, &f71805f_resource, 1);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device resource addition failed "
+                      "(%d)\n", err);
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto exit_device_put;
+       }
+
+       return 0;
+
+exit_device_put:
+       platform_device_put(pdev);
+exit:
+       return err;
+}
+
+static int __init f71805f_find(int sioaddr, unsigned short *address)
+{
+       int err = -ENODEV;
+       u16 devid;
+
+       superio_enter(sioaddr);
+
+       devid = superio_inw(sioaddr, SIO_REG_MANID);
+       if (devid != SIO_FINTEK_ID)
+               goto exit;
+
+       devid = superio_inw(sioaddr, SIO_REG_DEVID);
+       if (devid != SIO_F71805F_ID) {
+               printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       superio_select(sioaddr, F71805F_LD_HWM);
+       if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
+               printk(KERN_WARNING DRVNAME ": Device not activated, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       *address = superio_inw(sioaddr, SIO_REG_ADDR);
+       if (*address == 0) {
+               printk(KERN_WARNING DRVNAME ": Base address not set, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       err = 0;
+       printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n",
+              *address, superio_inb(sioaddr, SIO_REG_DEVREV));
+
+exit:
+       superio_exit(sioaddr);
+       return err;
+}
+
+static int __init f71805f_init(void)
+{
+       int err;
+       unsigned short address;
+
+       if (f71805f_find(0x2e, &address)
+        && f71805f_find(0x4e, &address))
+               return -ENODEV;
+
+       err = platform_driver_register(&f71805f_driver);
+       if (err)
+               goto exit;
+
+       /* Sets global pdev as a side effect */
+       err = f71805f_device_add(address);
+       if (err)
+               goto exit_driver;
+
+       return 0;
+
+exit_driver:
+       platform_driver_unregister(&f71805f_driver);
+exit:
+       return err;
+}
+
+static void __exit f71805f_exit(void)
+{
+       platform_device_unregister(pdev);
+       platform_driver_unregister(&f71805f_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("F71805F hardware monitoring driver");
+
+module_init(f71805f_init);
+module_exit(f71805f_exit);
index 0da7c9c508c31e2e6de57ae89c0a86eb7d730d72..e87d52c599400c5b3a9ddfd8d498c8278420dba0 100644 (file)
@@ -45,8 +45,7 @@
 
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
-                                       0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 static unsigned short isa_address;
 
 /* Insmod parameters */
@@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
        if ((err = i2c_attach_client(new_client)))
                goto ERROR2;
 
+       if (!is_isa)
+               dev_info(&new_client->dev, "The I2C interface to IT87xxF "
+                        "hardware monitoring chips is deprecated. Please "
+                        "report if you still rely on it.\n");
+
        /* Check PWM configuration */
        enable_pwm_interface = it87_check_pwm(new_client);
 
index a2f420d01fb7151f73d35c62afbdc2c16f1c936e..df9e02aaa70a98703290d079e5b61f1a7b8acbf2 100644 (file)
@@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = {
 
 /* In the temperature registers, the low 3 bits are not part of the
    temperature values; they are the status bits. */
-static inline u16 LM77_TEMP_TO_REG(int temp)
+static inline s16 LM77_TEMP_TO_REG(int temp)
 {
        int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
-       return (u16)((ntemp / 500) * 8);
+       return (ntemp / 500) * 8;
 }
 
-static inline int LM77_TEMP_FROM_REG(u16 reg)
+static inline int LM77_TEMP_FROM_REG(s16 reg)
 {
-       return ((int)reg / 8) * 500;
+       return (reg / 8) * 500;
 }
 
 /* sysfs stuff */
index b176bf0c4c7bda2e1ea966c552f5bf8e2568d898..a2f6bb676235e520202b74481dddb9d47d9b26a6 100644 (file)
@@ -303,10 +303,6 @@ struct w83792d_data {
 static int w83792d_attach_adapter(struct i2c_adapter *adapter);
 static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
 static int w83792d_detach_client(struct i2c_client *client);
-
-static int w83792d_read_value(struct i2c_client *client, u8 register);
-static int w83792d_write_value(struct i2c_client *client, u8 register,
-                               u8 value);
 static struct w83792d_data *w83792d_update_device(struct device *dev);
 
 #ifdef DEBUG
@@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data)
        return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
 }
 
+/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
+   but the driver only accesses registers in bank 0, so we don't have
+   to switch banks and lock access between switches. */
+static inline int w83792d_read_value(struct i2c_client *client, u8 reg)
+{
+       return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int
+w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+       return i2c_smbus_write_byte_data(client, reg, value);
+}
+
 /* following are the sysfs callback functions */
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
                        char *buf)
@@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client)
        return 0;
 }
 
-/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
-   but the driver only accesses registers in bank 0, so we don't have
-   to switch banks and lock access between switches. */
-static int w83792d_read_value(struct i2c_client *client, u8 reg)
-{
-       return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-       return i2c_smbus_write_byte_data(client, reg, value);
-}
-
 static void
 w83792d_init_client(struct i2c_client *client)
 {
index 938848ae162d4451b401abedfb7cbfc5b35d7733..3df3f09995c254806ed8c265eb3dfcb4c8cd08df 100644 (file)
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus);
 #ifdef MODULE
 MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
 MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
-MODULE_PARM(bit_scan, "i");
+module_param(bit_scan, int, 0);
 MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
 MODULE_LICENSE("GPL");
 
index 08d5b8fed2dc5f3440526110d9d5b13106a04174..ff92735c7c85706c2424e3b8445ac30e7d36eaca 100644 (file)
@@ -124,6 +124,7 @@ config I2C_I801
            ICH6
            ICH7
            ESB2
+           ICH8
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
index 1c752ddc10e283494677382963df96d98b076074..8e0f3158215f6bc191864ef5f0a87f49ecc67bbd 100644 (file)
@@ -32,6 +32,7 @@
     ICH6               266A
     ICH7               27DA
     ESB2               269B
+    ICH8               283E
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
        { 0, }
 };
 
index 3e5eba9fcacbdb2955da82e0ab81ad7ba49baaeb..c63025a4c8613744fb1a6e7706e018188391a5b3 100644 (file)
@@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = {
 
 static int __init i2c_parport_init(void)
 {
-       int type_count;
-
-       type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-       if (type < 0 || type >= type_count) {
+       if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
                printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
                type = 0;
        }
-       
+
        if (base == 0) {
                printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE);
                base = DEFAULT_BASE;
@@ -152,7 +149,7 @@ static int __init i2c_parport_init(void)
                release_region(base, 3);
                return -ENODEV;
        }
-       
+
        return 0;
 }
 
index 2854d858fc9b1194dc19deca52b5433eae4ea7c8..7e2e8cd1c14a90d0806d382df0e9b726e34768b2 100644 (file)
@@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = {
 
 static int __init i2c_parport_init(void)
 {
-       int type_count;
-
-       type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-       if (type < 0 || type >= type_count) {
+       if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
                printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
                type = 0;
        }
-       
+
        return parport_register_driver(&i2c_parport_driver);
 }
 
index 86e2234faf80e6ab21fe27165ecd3eeabdb42462..7579f4b256a8c7ed716765adcafb59c7fdb6cfb9 100644 (file)
@@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r
                decode_ISR(isr);
        }
 
-       if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
+       if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
                i2c->isrlog[i2c->irqlogidx++] = isr;
 
        show_state(i2c);
index 0ce58b506046b458edb85cf7bda4472a56920da1..1a2c9ab5d9e326a21a6be05b09cef994c2ed7286 100644 (file)
@@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val
        }
 }
 
+s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
+                                  u8 length, u8 *values)
+{
+       union i2c_smbus_data data;
+
+       if (length > I2C_SMBUS_BLOCK_MAX)
+               length = I2C_SMBUS_BLOCK_MAX;
+       data.block[0] = length;
+       memcpy(data.block + 1, values, length);
+       return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                             I2C_SMBUS_WRITE, command,
+                             I2C_SMBUS_I2C_BLOCK_DATA, &data);
+}
+
 /* Simulate a SMBus command using the i2c protocol 
    No checking of parameters is done!  */
 static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, 
@@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data);
 EXPORT_SYMBOL(i2c_smbus_write_word_data);
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
+EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
index 1c81174595b3ce12db4ee9d8194d29b61d92c67b..d633081fa4c58123bc8769e7439af651039cb415 100644 (file)
@@ -52,9 +52,9 @@ config IDE
 
 if IDE
 
-config IDE_MAX_HWIFS 
+config IDE_MAX_HWIFS
        int "Max IDE interfaces"
-       depends on ALPHA || SUPERH
+       depends on ALPHA || SUPERH || IA64
        default 4
        help
          This is the maximum number of IDE hardware interfaces that will
@@ -162,8 +162,8 @@ config BLK_DEV_IDECS
        tristate "PCMCIA IDE support"
        depends on PCMCIA
        help
-         Support for outboard IDE disks, tape drives, and CD-ROM drives
-         connected through a  PCMCIA card.
+         Support for Compact Flash cards, outboard IDE disks, tape drives,
+         and CD-ROM drives connected through a PCMCIA card.
 
 config BLK_DEV_IDECD
        tristate "Include IDE/ATAPI CDROM support"
@@ -267,7 +267,7 @@ config IDE_TASK_IOCTL
        help
          This is a direct raw access to the media.  It is a complex but
          elegant solution to test and validate the domain of the hardware and
-         perform below the driver data recover if needed.  This is the most
+         perform below the driver data recovery if needed.  This is the most
          basic form of media-forensics.
 
          If you are unsure, say N here.
@@ -525,7 +525,7 @@ config BLK_DEV_CS5520
        tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
        depends on EXPERIMENTAL
        help
-         Include support for PIO tuning an virtual DMA on the Cyrix MediaGX 
+         Include support for PIO tuning and virtual DMA on the Cyrix MediaGX
          5510/5520 chipset. This will automatically be detected and
          configured if found.
 
@@ -662,7 +662,7 @@ config PDC202XX_BURST
 
          It was originally designed for the PDC20246/Ultra33, whose BIOS will
          only setup UDMA on the first two PDC20246 cards.  It has also been
-         used succesfully on a PDC20265/Ultra100, allowing use of UDMA modes
+         used successfully on a PDC20265/Ultra100, allowing use of UDMA modes
          when the PDC20265 BIOS has been disabled (for faster boot up).
 
          Please read the comments at the top of
@@ -673,13 +673,6 @@ config PDC202XX_BURST
 config BLK_DEV_PDC202XX_NEW
        tristate "PROMISE PDC202{68|69|70|71|75|76|77} support"
 
-# FIXME - probably wants to be one for old and for new
-config PDC202XX_FORCE
-       bool "Enable controller even if disabled by BIOS"
-       depends on BLK_DEV_PDC202XX_NEW
-       help
-         Enable the PDC202xx controller even if it has been disabled in the BIOS setup.
-
 config BLK_DEV_SVWKS
        tristate "ServerWorks OSB4/CSB5/CSB6 chipsets support"
        help
@@ -722,7 +715,7 @@ config BLK_DEV_SIS5513
 config BLK_DEV_SLC90E66
        tristate "SLC90E66 chipset support"
        help
-         This driver ensures (U)DMA support for Victroy66 SouthBridges for
+         This driver ensures (U)DMA support for Victory66 SouthBridges for
          SMsC with Intel NorthBridges.  This is an Ultra66 based chipset.
          The nice thing about it is that you can mix Ultra/DMA/PIO devices
          and it will handle timing cycles.  Since this is an improved
@@ -1060,7 +1053,7 @@ config IDEDMA_IVB
          in that mode with an 80c ribbon.
 
          If you are experiencing compatibility or performance problems, you
-         MAY try to answering Y here. However, it does not necessarily solve
+         MAY try to answer Y here. However, it does not necessarily solve
          any of your problems, it could even cause more of them.
 
          It is normally safe to answer Y; however, the default is N.
index ca25f9e3d0f4e6816f6155d0cd00f79dd07509d1..09086b8b6486bd95c336a456a6be49f989ec4afb 100644 (file)
@@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
                if (lba48) {
                        task_ioreg_t tasklets[10];
 
-                       pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+                       pr_debug("%s: LBA=0x%012llx\n", drive->name,
+                                       (unsigned long long)block);
 
                        tasklets[0] = 0;
                        tasklets[1] = 0;
@@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s
 
        pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
                 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
-                block, rq->nr_sectors, (unsigned long)rq->buffer);
+                (unsigned long long)block, rq->nr_sectors,
+                (unsigned long)rq->buffer);
 
        if (hwif->rw_disk)
                hwif->rw_disk(drive, rq);
@@ -776,7 +778,7 @@ static void update_ordered(ide_drive_t *drive)
                         ide_id_has_flush_cache_ext(id));
 
                printk(KERN_INFO "%s: cache flushes %ssupported\n",
-                      drive->name, barrier ? "" : "not");
+                      drive->name, barrier ? "" : "not ");
 
                if (barrier) {
                        ordered = QUEUE_ORDERED_DRAIN_FLUSH;
@@ -889,11 +891,7 @@ static void idedisk_setup (ide_drive_t *drive)
        if (drive->id_read == 0)
                return;
 
-       /*
-        * CompactFlash cards and their brethern look just like hard drives
-        * to us, but they are removable and don't have a doorlock mechanism.
-        */
-       if (drive->removable && !(drive->is_flash)) {
+       if (drive->removable) {
                /*
                 * Removable disks (eg. SYQUEST); ignore 'WD' drives 
                 */
index 8d50df4526a4ec85cf05627e396902af84cf1f57..c01615dec2024f84efba781769a78d341d69a69d 100644 (file)
@@ -55,8 +55,8 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
-int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
-                     int nr_sectors)
+static int __ide_end_request(ide_drive_t *drive, struct request *rq,
+                            int uptodate, int nr_sectors)
 {
        int ret = 1;
 
@@ -91,7 +91,6 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
 
        return ret;
 }
-EXPORT_SYMBOL(__ide_end_request);
 
 /**
  *     ide_end_request         -       complete an IDE I/O
index af7af958ab3e4f83d5df42d8fd783b4bc48e674f..b72dde70840a797f3279021aecd4b080491e2663 100644 (file)
@@ -1243,6 +1243,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
                 */
                if (stat == 0xff)
                        return -ENODEV;
+               touch_softlockup_watchdog();
        }
        return -EBUSY;
 }
index e7425546b4b1786feb0333f71b0aa43b570d1e43..427d1c204174ec39434b15a6fb5bebcbbe40ec06 100644 (file)
@@ -124,45 +124,6 @@ static void ide_disk_init_mult_count(ide_drive_t *drive)
        }
 }
 
-/**
- *     drive_is_flashcard      -       check for compact flash
- *     @drive: drive to check
- *
- *     CompactFlash cards and their brethern pretend to be removable
- *     hard disks, except:
- *             (1) they never have a slave unit, and
- *             (2) they don't have doorlock mechanisms.
- *     This test catches them, and is invoked elsewhere when setting
- *     appropriate config bits.
- *
- *     FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD)
- *     devices, so in linux 2.3.x we should change this to just treat all
- *     PCMCIA  drives this way, and get rid of the model-name tests below
- *     (too big of an interface change for 2.4.x).
- *     At that time, we might also consider parameterizing the timeouts and
- *     retries, since these are MUCH faster than mechanical drives. -M.Lord
- */
-static inline int drive_is_flashcard (ide_drive_t *drive)
-{
-       struct hd_driveid *id = drive->id;
-
-       if (drive->removable) {
-               if (id->config == 0x848a) return 1;     /* CompactFlash */
-               if (!strncmp(id->model, "KODAK ATA_FLASH", 15)  /* Kodak */
-                || !strncmp(id->model, "Hitachi CV", 10)       /* Hitachi */
-                || !strncmp(id->model, "SunDisk SDCFB", 13)    /* old SanDisk */
-                || !strncmp(id->model, "SanDisk SDCFB", 13)    /* SanDisk */
-                || !strncmp(id->model, "HAGIWARA HPC", 12)     /* Hagiwara */
-                || !strncmp(id->model, "LEXAR ATA_FLASH", 15)  /* Lexar */
-                || !strncmp(id->model, "ATA_FLASH", 9))        /* Simple Tech */
-               {
-                       return 1;       /* yes, it is a flash memory card */
-               }
-       }
-       return 0;       /* no, it is not a flash memory card */
-}
-
 /**
  *     do_identify     -       identify a drive
  *     @drive: drive to identify 
@@ -278,13 +239,17 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        /*
         * Not an ATAPI device: looks like a "regular" hard disk
         */
-       if (id->config & (1<<7))
+
+       /*
+        * 0x848a = CompactFlash device
+        * These are *not* removable in Linux definition of the term
+        */
+
+       if ((id->config != 0x848a) && (id->config & (1<<7)))
                drive->removable = 1;
 
-       if (drive_is_flashcard(drive))
-               drive->is_flash = 1;
        drive->media = ide_disk;
-       printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" );
+       printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" );
        QUIRK_LIST(drive);
        return;
 
index afeb02bbb72210b4ee45bbcf6c6ed5e4a0cd416c..b2cc43702f65ab5738e533c4152ba3aa9f90f3e7 100644 (file)
@@ -242,7 +242,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
                drive->name[2]                  = 'a' + (index * MAX_DRIVES) + unit;
                drive->max_failures             = IDE_DEFAULT_MAX_FAILURES;
                drive->using_dma                = 0;
-               drive->is_flash                 = 0;
                drive->vdma                     = 0;
                INIT_LIST_HEAD(&drive->list);
                init_completion(&drive->gendev_rel_comp);
index a21b1e11eef4e5fe0ca849847695b049106fd943..c743e68c33aadca3894017ed2ba1c82cde5cff52 100644 (file)
@@ -262,6 +262,21 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
        else
                pci_set_drvdata(dev, (void *) aec6xxx_34_base);
 
+       /* These are necessary to get AEC6280 Macintosh cards to work */
+       if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
+           (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) {
+               u8 reg49h = 0, reg4ah = 0;
+               /* Clear reset and test bits.  */
+               pci_read_config_byte(dev, 0x49, &reg49h);
+               pci_write_config_byte(dev, 0x49, reg49h & ~0x30);
+               /* Enable chip interrupt output.  */
+               pci_read_config_byte(dev, 0x4a, &reg4ah);
+               pci_write_config_byte(dev, 0x4a, reg4ah & ~0x01);
+               /* Enable burst mode. */
+               pci_read_config_byte(dev, 0x4a, &reg4ah);
+               pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
+       }
+
        return dev->irq;
 }
 
index 7b589d948bf98bce6405196a55444787d4eff920..940bdd4c5784bf80092bac207c75df2352f5c32b 100644 (file)
@@ -1288,6 +1288,10 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
                                goto init_hpt37X_done;
                        }
                }
+               if (!pci_get_drvdata(dev)) {
+                       printk("No Clock Stabilization!!!\n");
+                       return;
+               }
 pll_recal:
                if (adjust & 1)
                        pll -= (adjust >> 1);
index 108fda83fea476bc2ab4d13e96ac3c09e847cd22..38f41b377ff6f322d1ba5a1276ba00d5024fd518 100644 (file)
@@ -733,7 +733,7 @@ static void __devinit it8212_disable_raid(struct pci_dev *dev)
 
        pci_write_config_dword(dev,0x4C, 0x02040204);
        pci_write_config_byte(dev, 0x42, 0x36);
-       pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);
+       pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
 }
 
 static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name)
index fe06ebb0e5bfdd012227f264c636178d30ed8569..acd63173199bbf17acd1a306da2160cda563c511 100644 (file)
@@ -420,9 +420,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .init_hwif      = init_hwif_pdc202new,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
        },{     /* 3 */
                .name           = "PDC20271",
@@ -447,9 +444,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .init_hwif      = init_hwif_pdc202new,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
        },{     /* 6 */
                .name           = "PDC20277",
index ad9d95817f95ec15415bd4f00cd9f3381c9edb88..6f8f8645b02c5666ad4cc336b0a93d8ba6aa7447 100644 (file)
@@ -786,9 +786,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .init_dma       = init_dma_pdc202xx,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
                .extra          = 16,
        },{     /* 1 */
@@ -799,9 +796,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .init_dma       = init_dma_pdc202xx,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
                .extra          = 48,
                .flags          = IDEPCI_FLAG_FORCE_PDC,
@@ -813,9 +807,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .init_dma       = init_dma_pdc202xx,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
                .extra          = 48,
        },{     /* 3 */
@@ -826,9 +817,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .init_dma       = init_dma_pdc202xx,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
                .extra          = 48,
                .flags          = IDEPCI_FLAG_FORCE_PDC,
@@ -840,9 +828,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .init_dma       = init_dma_pdc202xx,
                .channels       = 2,
                .autodma        = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
                .bootable       = OFF_BOARD,
                .extra          = 48,
        }
index b3e77df63cef9ab613e97cf3c2a10c743b8179b8..e9b83e1a30287adf49475ab729b95c7b3d4c380c 100644 (file)
@@ -135,6 +135,7 @@ static u8 piix_ratemask (ide_drive_t *drive)
                case PCI_DEVICE_ID_INTEL_ICH6_19:
                case PCI_DEVICE_ID_INTEL_ICH7_21:
                case PCI_DEVICE_ID_INTEL_ESB2_18:
+               case PCI_DEVICE_ID_INTEL_ICH8_6:
                        mode = 3;
                        break;
                /* UDMA 66 capable */
@@ -449,6 +450,7 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
                case PCI_DEVICE_ID_INTEL_ICH6_19:
                case PCI_DEVICE_ID_INTEL_ICH7_21:
                case PCI_DEVICE_ID_INTEL_ESB2_18:
+               case PCI_DEVICE_ID_INTEL_ICH8_6:
                {
                        unsigned int extra = 0;
                        pci_read_config_dword(dev, 0x54, &extra);
@@ -575,6 +577,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
        /* 21 */ DECLARE_PIIX_DEV("ICH7"),
        /* 22 */ DECLARE_PIIX_DEV("ICH4"),
        /* 23 */ DECLARE_PIIX_DEV("ESB2"),
+       /* 24 */ DECLARE_PIIX_DEV("ICH8M"),
 };
 
 /**
@@ -651,6 +654,7 @@ static struct pci_device_id piix_pci_tbl[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21},
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22},
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23},
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 24},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
index 4ee597d087978c3e64c397849fccab1abeeb36cf..2b286e8651632fcd1f4af7dead2fc67d7a5eefcf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -510,7 +510,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
                                       drive->name);
                                goto use_pio_instead;
                        } else {
-                               u32 xcount, bcount =
+                               u32 bcount =
                                    0x10000 - (cur_addr & 0xffff);
 
                                if (bcount > cur_len)
@@ -525,8 +525,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
                                *table = 0x0;
                                table++;
 
-                               xcount = bcount & 0xffff;
-                               *table = cpu_to_be32(xcount);
+                               *table = cpu_to_be32(bcount);
                                table++;
 
                                cur_addr += bcount;
@@ -680,7 +679,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
                return -EIO;
 
        /* Create /proc/ide entries */
-       create_proc_ide_interfaces(); 
+       create_proc_ide_interfaces();
 
        return 0;
 }
index e95c4293a4967d108ea79c7c1d5166bbaad00999..f6a05965a4e8ab79c3529fa71884c792ea8e8c4e 100644 (file)
@@ -1319,15 +1319,6 @@ static struct class ucm_class = {
        .release = ib_ucm_release_class_dev
 };
 
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-       struct ib_ucm_device *dev;
-       
-       dev = container_of(class_dev, struct ib_ucm_device, class_dev);
-       return print_dev_t(buf, dev->dev.dev);
-}
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
-
 static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
 {
        struct ib_ucm_device *dev;
@@ -1364,14 +1355,12 @@ static void ib_ucm_add_one(struct ib_device *device)
 
        ucm_dev->class_dev.class = &ucm_class;
        ucm_dev->class_dev.dev = device->dma_device;
+       ucm_dev->class_dev.devt = ucm_dev->dev.dev;
        snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
                 ucm_dev->devnum);
        if (class_device_register(&ucm_dev->class_dev))
                goto err_cdev;
 
-       if (class_device_create_file(&ucm_dev->class_dev,
-                                    &class_device_attr_dev))
-               goto err_class;
        if (class_device_create_file(&ucm_dev->class_dev,
                                     &class_device_attr_ibdev))
                goto err_class;
index 0ef560144be3f7ef09dce53dda6c03b3dd67ebfb..6dfc94122dd901232fafa61399a457c3aec5b648 100644 (file)
@@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI
 
 config HISAX_AMD7930
        bool "Am7930 (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && SPARC
+       depends on EXPERIMENTAL && SPARC && BROKEN
        help
          This enables HiSax support for the AMD7930 chips on some SPARCs.
          This code is not finished yet.
index 1b85ce166af8c48b13fe74930d45a66555b7ca63..11fe537e2f6f00b1aaf0d1f5bf0d87894df35fd2 100644 (file)
@@ -216,7 +216,7 @@ struct Layer1 {
 #define GROUP_TEI      127
 #define TEI_SAPI       63
 #define CTRL_SAPI      0
-#define PACKET_NOACK   250
+#define PACKET_NOACK   7
 
 /* Layer2 Flags */
 
index 3314a5a19854239f2bf335102c4e6f1c6dabfa97..94c9afb7017c66791b1eb154bcdf5d53f350b77c 100644 (file)
@@ -71,14 +71,14 @@ int sc_ioctl(int card, scs_ioctl *data)
                /*
                 * Get the SRec from user space
                 */
-               if (copy_from_user(srec, data->dataptr, sizeof(srec))) {
+               if (copy_from_user(srec, data->dataptr, SCIOC_SRECSIZE)) {
                        kfree(rcvmsg);
                        kfree(srec);
                        return -EFAULT;
                }
 
                status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,
-                               0, sizeof(srec), srec, rcvmsg, SAR_TIMEOUT);
+                               0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT);
                kfree(rcvmsg);
                kfree(srec);
 
index 7d4a0ac28c065c2145d4f707c2a339c9ddb7caf4..12ad462737ba59ba55f3b76a6f2e04167524df1b 100644 (file)
@@ -187,6 +187,14 @@ config WINDFARM_PM91
          This driver provides thermal control for the PowerMac9,1
           which is the recent (SMU based) single CPU desktop G5
 
+config WINDFARM_PM112
+       tristate "Support for thermal management on PowerMac11,2"
+       depends on WINDFARM && I2C && PMAC_SMU
+       select I2C_POWERMAC
+       help
+         This driver provides thermal control for the PowerMac11,2
+         which are the recent dual and quad G5 machines using the
+         970MP dual-core processor.
 
 config ANSLCD
        tristate "Support for ANS LCD display"
index f4657aa81fb0474d92f1c525af90015db1d5a6c3..6081acdea404ab0c5ed72cc42ffae385036323de 100644 (file)
@@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91)     += windfarm_smu_controls.o \
                                   windfarm_smu_sensors.o \
                                   windfarm_lm75_sensor.o windfarm_pid.o \
                                   windfarm_cpufreq_clamp.o windfarm_pm91.o
+obj-$(CONFIG_WINDFARM_PM112)   += windfarm_pm112.o windfarm_smu_sat.o \
+                                  windfarm_smu_controls.o \
+                                  windfarm_smu_sensors.o \
+                                  windfarm_max6690_sensor.o \
+                                  windfarm_lm75_sensor.o windfarm_pid.o
index 3f0cb0312ea3113bf897ddfa69e5318816e6857b..7a2482cc26a7a09af070916482c0bf51bee1747a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
+#include <linux/device.h>
 
 /* Display a 16.16 fixed point value */
 #define FIX32TOPRINT(f)        ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
@@ -39,6 +40,7 @@ struct wf_control {
        char                    *name;
        int                     type;
        struct kref             ref;
+       struct device_attribute attr;
 };
 
 #define WF_CONTROL_TYPE_GENERIC                0
@@ -87,6 +89,7 @@ struct wf_sensor {
        struct wf_sensor_ops    *ops;
        char                    *name;
        struct kref             ref;
+       struct device_attribute attr;
 };
 
 /* Same lifetime rules as controls */
index 6c2a471ea6c0fb6b3d7af035a0f5a4ac298d1bc0..bb8d5efe19bfc456e3825459c63ff746a4215963 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/reboot.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/mutex.h>
 
 #include "windfarm.h"
 
 
 static LIST_HEAD(wf_controls);
 static LIST_HEAD(wf_sensors);
-static DECLARE_MUTEX(wf_lock);
+static DEFINE_MUTEX(wf_lock);
 static struct notifier_block *wf_client_list;
 static int wf_client_count;
 static unsigned int wf_overtemp;
 static unsigned int wf_overtemp_counter;
 struct task_struct *wf_thread;
 
+static struct platform_device wf_platform_device = {
+       .name   = "windfarm",
+};
+
 /*
  * Utilities & tick thread
  */
@@ -156,26 +161,67 @@ static void wf_control_release(struct kref *kref)
                kfree(ct);
 }
 
+static ssize_t wf_show_control(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+       s32 val = 0;
+       int err;
+
+       err = ctrl->ops->get_value(ctrl, &val);
+       if (err < 0)
+               return err;
+       return sprintf(buf, "%d\n", val);
+}
+
+/* This is really only for debugging... */
+static ssize_t wf_store_control(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+       int val;
+       int err;
+       char *endp;
+
+       val = simple_strtoul(buf, &endp, 0);
+       while (endp < buf + count && (*endp == ' ' || *endp == '\n'))
+               ++endp;
+       if (endp - buf < count)
+               return -EINVAL;
+       err = ctrl->ops->set_value(ctrl, val);
+       if (err < 0)
+               return err;
+       return count;
+}
+
 int wf_register_control(struct wf_control *new_ct)
 {
        struct wf_control *ct;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(ct, &wf_controls, link) {
                if (!strcmp(ct->name, new_ct->name)) {
                        printk(KERN_WARNING "windfarm: trying to register"
                               " duplicate control %s\n", ct->name);
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return -EEXIST;
                }
        }
        kref_init(&new_ct->ref);
        list_add(&new_ct->link, &wf_controls);
 
+       new_ct->attr.attr.name = new_ct->name;
+       new_ct->attr.attr.owner = THIS_MODULE;
+       new_ct->attr.attr.mode = 0644;
+       new_ct->attr.show = wf_show_control;
+       new_ct->attr.store = wf_store_control;
+       device_create_file(&wf_platform_device.dev, &new_ct->attr);
+
        DBG("wf: Registered control %s\n", new_ct->name);
 
        wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -183,9 +229,9 @@ EXPORT_SYMBOL_GPL(wf_register_control);
 
 void wf_unregister_control(struct wf_control *ct)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_del(&ct->link);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        DBG("wf: Unregistered control %s\n", ct->name);
 
@@ -197,16 +243,16 @@ struct wf_control * wf_find_control(const char *name)
 {
        struct wf_control *ct;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(ct, &wf_controls, link) {
                if (!strcmp(ct->name, name)) {
                        if (wf_get_control(ct))
                                ct = NULL;
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return ct;
                }
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_control);
@@ -246,26 +292,46 @@ static void wf_sensor_release(struct kref *kref)
                kfree(sr);
 }
 
+static ssize_t wf_show_sensor(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr);
+       s32 val = 0;
+       int err;
+
+       err = sens->ops->get_value(sens, &val);
+       if (err < 0)
+               return err;
+       return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val));
+}
+
 int wf_register_sensor(struct wf_sensor *new_sr)
 {
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(sr, &wf_sensors, link) {
                if (!strcmp(sr->name, new_sr->name)) {
                        printk(KERN_WARNING "windfarm: trying to register"
                               " duplicate sensor %s\n", sr->name);
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return -EEXIST;
                }
        }
        kref_init(&new_sr->ref);
        list_add(&new_sr->link, &wf_sensors);
 
+       new_sr->attr.attr.name = new_sr->name;
+       new_sr->attr.attr.owner = THIS_MODULE;
+       new_sr->attr.attr.mode = 0444;
+       new_sr->attr.show = wf_show_sensor;
+       new_sr->attr.store = NULL;
+       device_create_file(&wf_platform_device.dev, &new_sr->attr);
+
        DBG("wf: Registered sensor %s\n", new_sr->name);
 
        wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -273,9 +339,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor);
 
 void wf_unregister_sensor(struct wf_sensor *sr)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_del(&sr->link);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        DBG("wf: Unregistered sensor %s\n", sr->name);
 
@@ -287,16 +353,16 @@ struct wf_sensor * wf_find_sensor(const char *name)
 {
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(sr, &wf_sensors, link) {
                if (!strcmp(sr->name, name)) {
                        if (wf_get_sensor(sr))
                                sr = NULL;
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return sr;
                }
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_sensor);
@@ -329,7 +395,7 @@ int wf_register_client(struct notifier_block *nb)
        struct wf_control *ct;
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        rc = notifier_chain_register(&wf_client_list, nb);
        if (rc != 0)
                goto bail;
@@ -341,19 +407,19 @@ int wf_register_client(struct notifier_block *nb)
        if (wf_client_count == 1)
                wf_start_thread();
  bail:
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return rc;
 }
 EXPORT_SYMBOL_GPL(wf_register_client);
 
 int wf_unregister_client(struct notifier_block *nb)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        notifier_chain_unregister(&wf_client_list, nb);
        wf_client_count++;
        if (wf_client_count == 0)
                wf_stop_thread();
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -361,23 +427,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client);
 
 void wf_set_overtemp(void)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        wf_overtemp++;
        if (wf_overtemp == 1) {
                printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
                wf_overtemp_counter = 0;
                wf_notify(WF_EVENT_OVERTEMP, NULL);
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_set_overtemp);
 
 void wf_clear_overtemp(void)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        WARN_ON(wf_overtemp == 0);
        if (wf_overtemp == 0) {
-               up(&wf_lock);
+               mutex_unlock(&wf_lock);
                return;
        }
        wf_overtemp--;
@@ -385,7 +451,7 @@ void wf_clear_overtemp(void)
                printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
                wf_notify(WF_EVENT_NORMALTEMP, NULL);
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_clear_overtemp);
 
@@ -395,10 +461,6 @@ int wf_is_overtemp(void)
 }
 EXPORT_SYMBOL_GPL(wf_is_overtemp);
 
-static struct platform_device wf_platform_device = {
-       .name   = "windfarm",
-};
-
 static int __init windfarm_core_init(void)
 {
        DBG("wf: core loaded\n");
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
new file mode 100644 (file)
index 0000000..5b9ad6c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Windfarm PowerMac thermal control.  MAX6690 sensor.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/prom.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.1"
+
+/* This currently only exports the external temperature sensor,
+   since that's all the control loops need. */
+
+/* Some MAX6690 register numbers */
+#define MAX6690_INTERNAL_TEMP  0
+#define MAX6690_EXTERNAL_TEMP  1
+
+struct wf_6690_sensor {
+       struct i2c_client       i2c;
+       struct wf_sensor        sens;
+};
+
+#define wf_to_6690(x)  container_of((x), struct wf_6690_sensor, sens)
+#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c)
+
+static int wf_max6690_attach(struct i2c_adapter *adapter);
+static int wf_max6690_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_max6690_driver = {
+       .driver = {
+               .name           = "wf_max6690",
+       },
+       .attach_adapter = wf_max6690_attach,
+       .detach_client  = wf_max6690_detach,
+};
+
+static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
+{
+       struct wf_6690_sensor *max = wf_to_6690(sr);
+       s32 data;
+
+       if (max->i2c.adapter == NULL)
+               return -ENODEV;
+
+       /* chip gets initialized by firmware */
+       data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
+       if (data < 0)
+               return data;
+       *value = data << 16;
+       return 0;
+}
+
+static void wf_max6690_release(struct wf_sensor *sr)
+{
+       struct wf_6690_sensor *max = wf_to_6690(sr);
+
+       if (max->i2c.adapter) {
+               i2c_detach_client(&max->i2c);
+               max->i2c.adapter = NULL;
+       }
+       kfree(max);
+}
+
+static struct wf_sensor_ops wf_max6690_ops = {
+       .get_value      = wf_max6690_get,
+       .release        = wf_max6690_release,
+       .owner          = THIS_MODULE,
+};
+
+static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
+{
+       struct wf_6690_sensor *max;
+       char *name = "u4-temp";
+
+       max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
+       if (max == NULL) {
+               printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
+                      "no memory\n", name);
+               return;
+       }
+
+       max->sens.ops = &wf_max6690_ops;
+       max->sens.name = name;
+       max->i2c.addr = addr >> 1;
+       max->i2c.adapter = adapter;
+       max->i2c.driver = &wf_max6690_driver;
+       strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
+
+       if (i2c_attach_client(&max->i2c)) {
+               printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
+               goto fail;
+       }
+
+       if (wf_register_sensor(&max->sens)) {
+               i2c_detach_client(&max->i2c);
+               goto fail;
+       }
+
+       return;
+
+ fail:
+       kfree(max);
+}
+
+static int wf_max6690_attach(struct i2c_adapter *adapter)
+{
+       struct device_node *busnode, *dev = NULL;
+       struct pmac_i2c_bus *bus;
+       const char *loc;
+       u32 *reg;
+
+       bus = pmac_i2c_adapter_to_bus(adapter);
+       if (bus == NULL)
+               return -ENODEV;
+       busnode = pmac_i2c_get_bus_node(bus);
+
+       while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+               if (!device_is_compatible(dev, "max6690"))
+                       continue;
+               loc = get_property(dev, "hwsensor-location", NULL);
+               reg = (u32 *) get_property(dev, "reg", NULL);
+               if (!loc || !reg)
+                       continue;
+               printk("found max6690, loc=%s reg=%x\n", loc, *reg);
+               if (strcmp(loc, "BACKSIDE"))
+                       continue;
+               wf_max6690_create(adapter, *reg);
+       }
+
+       return 0;
+}
+
+static int wf_max6690_detach(struct i2c_client *client)
+{
+       struct wf_6690_sensor *max = i2c_to_6690(client);
+
+       max->i2c.adapter = NULL;
+       wf_unregister_sensor(&max->sens);
+
+       return 0;
+}
+
+static int __init wf_max6690_sensor_init(void)
+{
+       return i2c_add_driver(&wf_max6690_driver);
+}
+
+static void __exit wf_max6690_sensor_exit(void)
+{
+       i2c_del_driver(&wf_max6690_driver);
+}
+
+module_init(wf_max6690_sensor_init);
+module_exit(wf_max6690_sensor_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
+MODULE_LICENSE("GPL");
index 2e803b368757ed72d4f1b53ad8af10e9a9c7b375..0842432e27ad10b74fefbef8f045323940691e8a 100644 (file)
@@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init);
 
 s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
 {
-       s64     error, integ, deriv, prop;
-       s32     target, sval, adj;
+       s64     integ, deriv, prop;
+       s32     error, target, sval, adj;
        int     i, hlen = st->param.history_len;
 
        /* Calculate error term */
@@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
                integ += st->errors[(st->index + hlen - i) % hlen];
        integ *= st->param.interval;
        integ *= st->param.gr;
-       sval = st->param.tmax - ((integ >> 20) & 0xffffffff);
+       sval = st->param.tmax - (s32)(integ >> 20);
        adj = min(st->param.ttarget, sval);
 
        DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj);
@@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
        deriv *= st->param.gd;
 
        /* Calculate proportional term */
-       prop = (new_temp - adj);
+       prop = st->last_delta = (new_temp - adj);
        prop *= st->param.gp;
 
        DBG("deriv: %lx, prop: %lx\n", deriv, prop);
index a364c2a2499caf0f55dc6b364e0d771c61e8a2ec..bbccc22d42b8f2417fc010b52c5f663d91d8b2ca 100644 (file)
@@ -72,6 +72,7 @@ struct wf_cpu_pid_state {
        int     index;                          /* index of current power */
        int     tindex;                         /* index of current temp */
        s32     target;                         /* current target value */
+       s32     last_delta;                     /* last Tactual - Ttarget */
        s32     powers[WF_PID_MAX_HISTORY];     /* power history buffer */
        s32     errors[WF_PID_MAX_HISTORY];     /* error history buffer */
        s32     temps[2];                       /* temp. history buffer */
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
new file mode 100644 (file)
index 0000000..c2a4e68
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * Windfarm PowerMac thermal control.
+ * Control loops for machines with SMU and PPC970MP processors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+#undef LOTSA_DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)   printk(args)
+#else
+#define DBG(args...)   do { } while(0)
+#endif
+
+#ifdef LOTSA_DEBUG
+#define DBG_LOTS(args...)      printk(args)
+#else
+#define DBG_LOTS(args...)      do { } while(0)
+#endif
+
+/* define this to force CPU overtemp to 60 degree, useful for testing
+ * the overtemp code
+ */
+#undef HACKED_OVERTEMP
+
+/* We currently only handle 2 chips, 4 cores... */
+#define NR_CHIPS       2
+#define NR_CORES       4
+#define NR_CPU_FANS    3 * NR_CHIPS
+
+/* Controls and sensors */
+static struct wf_sensor *sens_cpu_temp[NR_CORES];
+static struct wf_sensor *sens_cpu_power[NR_CORES];
+static struct wf_sensor *hd_temp;
+static struct wf_sensor *slots_power;
+static struct wf_sensor *u4_temp;
+
+static struct wf_control *cpu_fans[NR_CPU_FANS];
+static char *cpu_fan_names[NR_CPU_FANS] = {
+       "cpu-rear-fan-0",
+       "cpu-rear-fan-1",
+       "cpu-front-fan-0",
+       "cpu-front-fan-1",
+       "cpu-pump-0",
+       "cpu-pump-1",
+};
+static struct wf_control *cpufreq_clamp;
+
+/* Second pump isn't required (and isn't actually present) */
+#define CPU_FANS_REQD          (NR_CPU_FANS - 2)
+#define FIRST_PUMP             4
+#define LAST_PUMP              5
+
+/* We keep a temperature history for average calculation of 180s */
+#define CPU_TEMP_HIST_SIZE     180
+
+/* Scale factor for fan speed, *100 */
+static int cpu_fan_scale[NR_CPU_FANS] = {
+       100,
+       100,
+       97,             /* inlet fans run at 97% of exhaust fan */
+       97,
+       100,            /* updated later */
+       100,            /* updated later */
+};
+
+static struct wf_control *backside_fan;
+static struct wf_control *slots_fan;
+static struct wf_control *drive_bay_fan;
+
+/* PID loop state */
+static struct wf_cpu_pid_state cpu_pid[NR_CORES];
+static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
+static int cpu_thist_pt;
+static s64 cpu_thist_total;
+static s32 cpu_all_tmax = 100 << 16;
+static int cpu_last_target;
+static struct wf_pid_state backside_pid;
+static int backside_tick;
+static struct wf_pid_state slots_pid;
+static int slots_started;
+static struct wf_pid_state drive_bay_pid;
+static int drive_bay_tick;
+
+static int nr_cores;
+static int have_all_controls;
+static int have_all_sensors;
+static int started;
+
+static int failure_state;
+#define FAILURE_SENSOR         1
+#define FAILURE_FAN            2
+#define FAILURE_PERM           4
+#define FAILURE_LOW_OVERTEMP   8
+#define FAILURE_HIGH_OVERTEMP  16
+
+/* Overtemp values */
+#define LOW_OVER_AVERAGE       0
+#define LOW_OVER_IMMEDIATE     (10 << 16)
+#define LOW_OVER_CLEAR         ((-10) << 16)
+#define HIGH_OVER_IMMEDIATE    (14 << 16)
+#define HIGH_OVER_AVERAGE      (10 << 16)
+#define HIGH_OVER_IMMEDIATE    (14 << 16)
+
+
+/* Implementation... */
+static int create_cpu_loop(int cpu)
+{
+       int chip = cpu / 2;
+       int core = cpu & 1;
+       struct smu_sdbp_header *hdr;
+       struct smu_sdbp_cpupiddata *piddata;
+       struct wf_cpu_pid_param pid;
+       struct wf_control *main_fan = cpu_fans[0];
+       s32 tmax;
+       int fmin;
+
+       /* Get PID params from the appropriate SAT */
+       hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
+       if (hdr == NULL) {
+               printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
+               return -EINVAL;
+       }
+       piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+       /* Get FVT params to get Tmax; if not found, assume default */
+       hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
+       if (hdr) {
+               struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1];
+               tmax = fvt->maxtemp << 16;
+       } else
+               tmax = 95 << 16;        /* default to 95 degrees C */
+
+       /* We keep a global tmax for overtemp calculations */
+       if (tmax < cpu_all_tmax)
+               cpu_all_tmax = tmax;
+
+       /*
+        * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
+        * 515 for the 2-way.  That appears to be overkill, so for now,
+        * impose a minimum of 750 or 515.
+        */
+       fmin = (nr_cores > 2) ? 750 : 515;
+
+       /* Initialize PID loop */
+       pid.interval = 1;       /* seconds */
+       pid.history_len = piddata->history_len;
+       pid.gd = piddata->gd;
+       pid.gp = piddata->gp;
+       pid.gr = piddata->gr / piddata->history_len;
+       pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8);
+       pid.ttarget = tmax - (piddata->target_temp_delta << 16);
+       pid.tmax = tmax;
+       pid.min = main_fan->ops->get_min(main_fan);
+       pid.max = main_fan->ops->get_max(main_fan);
+       if (pid.min < fmin)
+               pid.min = fmin;
+
+       wf_cpu_pid_init(&cpu_pid[cpu], &pid);
+       return 0;
+}
+
+static void cpu_max_all_fans(void)
+{
+       int i;
+
+       /* We max all CPU fans in case of a sensor error. We also do the
+        * cpufreq clamping now, even if it's supposedly done later by the
+        * generic code anyway, we do it earlier here to react faster
+        */
+       if (cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       for (i = 0; i < NR_CPU_FANS; ++i)
+               if (cpu_fans[i])
+                       wf_control_set_max(cpu_fans[i]);
+}
+
+static int cpu_check_overtemp(s32 temp)
+{
+       int new_state = 0;
+       s32 t_avg, t_old;
+
+       /* First check for immediate overtemps */
+       if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
+               new_state |= FAILURE_LOW_OVERTEMP;
+               if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
+                              " temperature !\n");
+       }
+       if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
+               new_state |= FAILURE_HIGH_OVERTEMP;
+               if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Critical overtemp due to"
+                              " immediate CPU temperature !\n");
+       }
+
+       /* We calculate a history of max temperatures and use that for the
+        * overtemp management
+        */
+       t_old = cpu_thist[cpu_thist_pt];
+       cpu_thist[cpu_thist_pt] = temp;
+       cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
+       cpu_thist_total -= t_old;
+       cpu_thist_total += temp;
+       t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
+
+       DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
+                FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
+
+       /* Now check for average overtemps */
+       if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
+               new_state |= FAILURE_LOW_OVERTEMP;
+               if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Overtemp due to average CPU"
+                              " temperature !\n");
+       }
+       if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
+               new_state |= FAILURE_HIGH_OVERTEMP;
+               if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Critical overtemp due to"
+                              " average CPU temperature !\n");
+       }
+
+       /* Now handle overtemp conditions. We don't currently use the windfarm
+        * overtemp handling core as it's not fully suited to the needs of those
+        * new machine. This will be fixed later.
+        */
+       if (new_state) {
+               /* High overtemp -> immediate shutdown */
+               if (new_state & FAILURE_HIGH_OVERTEMP)
+                       machine_power_off();
+               if ((failure_state & new_state) != new_state)
+                       cpu_max_all_fans();
+               failure_state |= new_state;
+       } else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
+                  (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
+               printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
+               failure_state &= ~FAILURE_LOW_OVERTEMP;
+       }
+
+       return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
+}
+
+static void cpu_fans_tick(void)
+{
+       int err, cpu;
+       s32 greatest_delta = 0;
+       s32 temp, power, t_max = 0;
+       int i, t, target = 0;
+       struct wf_sensor *sr;
+       struct wf_control *ct;
+       struct wf_cpu_pid_state *sp;
+
+       DBG_LOTS(KERN_DEBUG);
+       for (cpu = 0; cpu < nr_cores; ++cpu) {
+               /* Get CPU core temperature */
+               sr = sens_cpu_temp[cpu];
+               err = sr->ops->get_value(sr, &temp);
+               if (err) {
+                       DBG("\n");
+                       printk(KERN_WARNING "windfarm: CPU %d temperature "
+                              "sensor error %d\n", cpu, err);
+                       failure_state |= FAILURE_SENSOR;
+                       cpu_max_all_fans();
+                       return;
+               }
+
+               /* Keep track of highest temp */
+               t_max = max(t_max, temp);
+
+               /* Get CPU power */
+               sr = sens_cpu_power[cpu];
+               err = sr->ops->get_value(sr, &power);
+               if (err) {
+                       DBG("\n");
+                       printk(KERN_WARNING "windfarm: CPU %d power "
+                              "sensor error %d\n", cpu, err);
+                       failure_state |= FAILURE_SENSOR;
+                       cpu_max_all_fans();
+                       return;
+               }
+
+               /* Run PID */
+               sp = &cpu_pid[cpu];
+               t = wf_cpu_pid_run(sp, power, temp);
+
+               if (cpu == 0 || sp->last_delta > greatest_delta) {
+                       greatest_delta = sp->last_delta;
+                       target = t;
+               }
+               DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
+                   cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
+       }
+       DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
+
+       /* Darwin limits decrease to 20 per iteration */
+       if (target < (cpu_last_target - 20))
+               target = cpu_last_target - 20;
+       cpu_last_target = target;
+       for (cpu = 0; cpu < nr_cores; ++cpu)
+               cpu_pid[cpu].target = target;
+
+       /* Handle possible overtemps */
+       if (cpu_check_overtemp(t_max))
+               return;
+
+       /* Set fans */
+       for (i = 0; i < NR_CPU_FANS; ++i) {
+               ct = cpu_fans[i];
+               if (ct == NULL)
+                       continue;
+               err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
+               if (err) {
+                       printk(KERN_WARNING "windfarm: fan %s reports "
+                              "error %d\n", ct->name, err);
+                       failure_state |= FAILURE_FAN;
+                       break;
+               }
+       }
+}
+
+/* Backside/U4 fan */
+static struct wf_pid_param backside_param = {
+       .interval       = 5,
+       .history_len    = 2,
+       .gd             = 48 << 20,
+       .gp             = 5 << 20,
+       .gr             = 0,
+       .itarget        = 64 << 16,
+       .additive       = 1,
+};
+
+static void backside_fan_tick(void)
+{
+       s32 temp;
+       int speed;
+       int err;
+
+       if (!backside_fan || !u4_temp)
+               return;
+       if (!backside_tick) {
+               /* first time; initialize things */
+               backside_param.min = backside_fan->ops->get_min(backside_fan);
+               backside_param.max = backside_fan->ops->get_max(backside_fan);
+               wf_pid_init(&backside_pid, &backside_param);
+               backside_tick = 1;
+       }
+       if (--backside_tick > 0)
+               return;
+       backside_tick = backside_pid.param.interval;
+
+       err = u4_temp->ops->get_value(u4_temp, &temp);
+       if (err) {
+               printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
+                      err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(backside_fan);
+               return;
+       }
+       speed = wf_pid_run(&backside_pid, temp);
+       DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(temp), speed);
+
+       err = backside_fan->ops->set_value(backside_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+/* Drive bay fan */
+static struct wf_pid_param drive_bay_prm = {
+       .interval       = 5,
+       .history_len    = 2,
+       .gd             = 30 << 20,
+       .gp             = 5 << 20,
+       .gr             = 0,
+       .itarget        = 40 << 16,
+       .additive       = 1,
+};
+
+static void drive_bay_fan_tick(void)
+{
+       s32 temp;
+       int speed;
+       int err;
+
+       if (!drive_bay_fan || !hd_temp)
+               return;
+       if (!drive_bay_tick) {
+               /* first time; initialize things */
+               drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
+               drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
+               wf_pid_init(&drive_bay_pid, &drive_bay_prm);
+               drive_bay_tick = 1;
+       }
+       if (--drive_bay_tick > 0)
+               return;
+       drive_bay_tick = drive_bay_pid.param.interval;
+
+       err = hd_temp->ops->get_value(hd_temp, &temp);
+       if (err) {
+               printk(KERN_WARNING "windfarm: drive bay temp sensor "
+                      "error %d\n", err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(drive_bay_fan);
+               return;
+       }
+       speed = wf_pid_run(&drive_bay_pid, temp);
+       DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(temp), speed);
+
+       err = drive_bay_fan->ops->set_value(drive_bay_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+/* PCI slots area fan */
+/* This makes the fan speed proportional to the power consumed */
+static struct wf_pid_param slots_param = {
+       .interval       = 1,
+       .history_len    = 2,
+       .gd             = 0,
+       .gp             = 0,
+       .gr             = 0x1277952,
+       .itarget        = 0,
+       .min            = 1560,
+       .max            = 3510,
+};
+
+static void slots_fan_tick(void)
+{
+       s32 power;
+       int speed;
+       int err;
+
+       if (!slots_fan || !slots_power)
+               return;
+       if (!slots_started) {
+               /* first time; initialize things */
+               wf_pid_init(&slots_pid, &slots_param);
+               slots_started = 1;
+       }
+
+       err = slots_power->ops->get_value(slots_power, &power);
+       if (err) {
+               printk(KERN_WARNING "windfarm: slots power sensor error %d\n",
+                      err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(slots_fan);
+               return;
+       }
+       speed = wf_pid_run(&slots_pid, power);
+       DBG_LOTS("slots PID power=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(power), speed);
+
+       err = slots_fan->ops->set_value(slots_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: slots fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+static void set_fail_state(void)
+{
+       int i;
+
+       if (cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       for (i = 0; i < NR_CPU_FANS; ++i)
+               if (cpu_fans[i])
+                       wf_control_set_max(cpu_fans[i]);
+       if (backside_fan)
+               wf_control_set_max(backside_fan);
+       if (slots_fan)
+               wf_control_set_max(slots_fan);
+       if (drive_bay_fan)
+               wf_control_set_max(drive_bay_fan);
+}
+
+static void pm112_tick(void)
+{
+       int i, last_failure;
+
+       if (!started) {
+               started = 1;
+               for (i = 0; i < nr_cores; ++i) {
+                       if (create_cpu_loop(i) < 0) {
+                               failure_state = FAILURE_PERM;
+                               set_fail_state();
+                               break;
+                       }
+               }
+               DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
+
+#ifdef HACKED_OVERTEMP
+               cpu_all_tmax = 60 << 16;
+#endif
+       }
+
+       /* Permanent failure, bail out */
+       if (failure_state & FAILURE_PERM)
+               return;
+       /* Clear all failure bits except low overtemp which will be eventually
+        * cleared by the control loop itself
+        */
+       last_failure = failure_state;
+       failure_state &= FAILURE_LOW_OVERTEMP;
+       cpu_fans_tick();
+       backside_fan_tick();
+       slots_fan_tick();
+       drive_bay_fan_tick();
+
+       DBG_LOTS("last_failure: 0x%x, failure_state: %x\n",
+                last_failure, failure_state);
+
+       /* Check for failures. Any failure causes cpufreq clamping */
+       if (failure_state && last_failure == 0 && cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       if (failure_state == 0 && last_failure && cpufreq_clamp)
+               wf_control_set_min(cpufreq_clamp);
+
+       /* That's it for now, we might want to deal with other failures
+        * differently in the future though
+        */
+}
+
+static void pm112_new_control(struct wf_control *ct)
+{
+       int i, max_exhaust;
+
+       if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
+               if (wf_get_control(ct) == 0)
+                       cpufreq_clamp = ct;
+       }
+
+       for (i = 0; i < NR_CPU_FANS; ++i) {
+               if (!strcmp(ct->name, cpu_fan_names[i])) {
+                       if (cpu_fans[i] == NULL && wf_get_control(ct) == 0)
+                               cpu_fans[i] = ct;
+                       break;
+               }
+       }
+       if (i >= NR_CPU_FANS) {
+               /* not a CPU fan, try the others */
+               if (!strcmp(ct->name, "backside-fan")) {
+                       if (backside_fan == NULL && wf_get_control(ct) == 0)
+                               backside_fan = ct;
+               } else if (!strcmp(ct->name, "slots-fan")) {
+                       if (slots_fan == NULL && wf_get_control(ct) == 0)
+                               slots_fan = ct;
+               } else if (!strcmp(ct->name, "drive-bay-fan")) {
+                       if (drive_bay_fan == NULL && wf_get_control(ct) == 0)
+                               drive_bay_fan = ct;
+               }
+               return;
+       }
+
+       for (i = 0; i < CPU_FANS_REQD; ++i)
+               if (cpu_fans[i] == NULL)
+                       return;
+
+       /* work out pump scaling factors */
+       max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]);
+       for (i = FIRST_PUMP; i <= LAST_PUMP; ++i)
+               if ((ct = cpu_fans[i]) != NULL)
+                       cpu_fan_scale[i] =
+                               ct->ops->get_max(ct) * 100 / max_exhaust;
+
+       have_all_controls = 1;
+}
+
+static void pm112_new_sensor(struct wf_sensor *sr)
+{
+       unsigned int i;
+
+       if (have_all_sensors)
+               return;
+       if (!strncmp(sr->name, "cpu-temp-", 9)) {
+               i = sr->name[9] - '0';
+               if (sr->name[10] == 0 && i < NR_CORES &&
+                   sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0)
+                       sens_cpu_temp[i] = sr;
+
+       } else if (!strncmp(sr->name, "cpu-power-", 10)) {
+               i = sr->name[10] - '0';
+               if (sr->name[11] == 0 && i < NR_CORES &&
+                   sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0)
+                       sens_cpu_power[i] = sr;
+       } else if (!strcmp(sr->name, "hd-temp")) {
+               if (hd_temp == NULL && wf_get_sensor(sr) == 0)
+                       hd_temp = sr;
+       } else if (!strcmp(sr->name, "slots-power")) {
+               if (slots_power == NULL && wf_get_sensor(sr) == 0)
+                       slots_power = sr;
+       } else if (!strcmp(sr->name, "u4-temp")) {
+               if (u4_temp == NULL && wf_get_sensor(sr) == 0)
+                       u4_temp = sr;
+       } else
+               return;
+
+       /* check if we have all the sensors we need */
+       for (i = 0; i < nr_cores; ++i)
+               if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL)
+                       return;
+
+       have_all_sensors = 1;
+}
+
+static int pm112_wf_notify(struct notifier_block *self,
+                          unsigned long event, void *data)
+{
+       switch (event) {
+       case WF_EVENT_NEW_SENSOR:
+               pm112_new_sensor(data);
+               break;
+       case WF_EVENT_NEW_CONTROL:
+               pm112_new_control(data);
+               break;
+       case WF_EVENT_TICK:
+               if (have_all_controls && have_all_sensors)
+                       pm112_tick();
+       }
+       return 0;
+}
+
+static struct notifier_block pm112_events = {
+       .notifier_call = pm112_wf_notify,
+};
+
+static int wf_pm112_probe(struct device *dev)
+{
+       wf_register_client(&pm112_events);
+       return 0;
+}
+
+static int wf_pm112_remove(struct device *dev)
+{
+       wf_unregister_client(&pm112_events);
+       /* should release all sensors and controls */
+       return 0;
+}
+
+static struct device_driver wf_pm112_driver = {
+       .name = "windfarm",
+       .bus = &platform_bus_type,
+       .probe = wf_pm112_probe,
+       .remove = wf_pm112_remove,
+};
+
+static int __init wf_pm112_init(void)
+{
+       struct device_node *cpu;
+
+       if (!machine_is_compatible("PowerMac11,2"))
+               return -ENODEV;
+
+       /* Count the number of CPU cores */
+       nr_cores = 0;
+       for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
+               ++nr_cores;
+
+       printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
+       driver_register(&wf_pm112_driver);
+       return 0;
+}
+
+static void __exit wf_pm112_exit(void)
+{
+       driver_unregister(&wf_pm112_driver);
+}
+
+module_init(wf_pm112_init);
+module_exit(wf_pm112_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("Thermal control for PowerMac11,2");
+MODULE_LICENSE("GPL");
index eb69a601e765fb6e59d42f43d57ed201443ef07d..f1df6efcbe68337da014579bb71c9407ad1bc0d1 100644 (file)
@@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
        }
 }
 
-
-/*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       ssize_t r;                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val));         \
-       return r;                                               \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       return sprintf(buf, "%d", val);                         \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(sys_fan, fan_system);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-
 /*
  * ****** Setup / Init / Misc ... ******
  *
@@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct)
                return;
 
        if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_cpu_main = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-               }
        }
 
        if (fan_system == NULL && !strcmp(ct->name, "system-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_system = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_sys_fan);
-               }
        }
 
        if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
@@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct)
        }
 
        if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_hd = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-               }
        }
 
        if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp)
@@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr)
                return;
 
        if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-               }
        }
 
        if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-               }
        }
 
        if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_hd_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-               }
        }
 
        if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp)
@@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev)
         * with that except by adding locks all over... I'll do that
         * eventually but heh, who ever rmmod this module anyway ?
         */
-       if (sensor_cpu_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+       if (sensor_cpu_power)
                wf_put_sensor(sensor_cpu_power);
-       }
-       if (sensor_cpu_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+       if (sensor_cpu_temp)
                wf_put_sensor(sensor_cpu_temp);
-       }
-       if (sensor_hd_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+       if (sensor_hd_temp)
                wf_put_sensor(sensor_hd_temp);
-       }
 
        /* Release all controls */
-       if (fan_cpu_main) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+       if (fan_cpu_main)
                wf_put_control(fan_cpu_main);
-       }
-       if (fan_hd) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+       if (fan_hd)
                wf_put_control(fan_hd);
-       }
-       if (fan_system) {
-               device_remove_file(wf_smu_dev, &dev_attr_sys_fan);
+       if (fan_system)
                wf_put_control(fan_system);
-       }
        if (cpufreq_clamp)
                wf_put_control(cpufreq_clamp);
 
index 43243cf7410b3d887802cfce731a55c7a08b7178..0d6372e96d32e9f3a707fafb61af52900ba2a5a0 100644 (file)
@@ -457,45 +457,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
 }
 
 
-/*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       ssize_t r;                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val));         \
-       return r;                                               \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       return sprintf(buf, "%d", val);                         \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-BUILD_SHOW_FUNC_INT(slots_fan, fan_slots);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power);
-
 /*
  * ****** Setup / Init / Misc ... ******
  *
@@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct)
                return;
 
        if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_cpu_main = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-               }
        }
 
        if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) {
@@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct)
        }
 
        if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_hd = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-               }
        }
 
        if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_slots = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_slots_fan);
-               }
        }
 
        if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
@@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr)
                return;
 
        if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-               }
        }
 
        if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-               }
        }
 
        if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_hd_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-               }
        }
 
        if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_slots_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_slots_power);
-               }
        }
 
        if (sensor_cpu_power && sensor_cpu_temp &&
@@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev)
         * with that except by adding locks all over... I'll do that
         * eventually but heh, who ever rmmod this module anyway ?
         */
-       if (sensor_cpu_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+       if (sensor_cpu_power)
                wf_put_sensor(sensor_cpu_power);
-       }
-       if (sensor_cpu_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+       if (sensor_cpu_temp)
                wf_put_sensor(sensor_cpu_temp);
-       }
-       if (sensor_hd_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+       if (sensor_hd_temp)
                wf_put_sensor(sensor_hd_temp);
-       }
-       if (sensor_slots_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_slots_power);
+       if (sensor_slots_power)
                wf_put_sensor(sensor_slots_power);
-       }
 
        /* Release all controls */
-       if (fan_cpu_main) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+       if (fan_cpu_main)
                wf_put_control(fan_cpu_main);
-       }
        if (fan_cpu_second)
                wf_put_control(fan_cpu_second);
        if (fan_cpu_third)
                wf_put_control(fan_cpu_third);
-       if (fan_hd) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+       if (fan_hd)
                wf_put_control(fan_hd);
-       }
-       if (fan_slots) {
-               device_remove_file(wf_smu_dev, &dev_attr_slots_fan);
+       if (fan_slots)
                wf_put_control(fan_slots);
-       }
        if (cpufreq_clamp)
                wf_put_control(cpufreq_clamp);
 
index 4d811600bdab471a16d924f241fd4bd3adfe602f..a9e88edc0c72fe9fc7b950b469f457f18c9b59c5 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "windfarm.h"
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 #undef DEBUG
 
@@ -34,6 +34,8 @@
 #define DBG(args...)   do { } while(0)
 #endif
 
+static int smu_supports_new_fans_ops = 1;
+
 /*
  * SMU fans control object
  */
@@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value)
 
        /* Fill SMU command structure */
        cmd.cmd = SMU_CMD_FAN_COMMAND;
-       cmd.data_len = 14;
+
+       /* The SMU has an "old" and a "new" way of setting the fan speed
+        * Unfortunately, I found no reliable way to know which one works
+        * on a given machine model. After some investigations it appears
+        * that MacOS X just tries the new one, and if it fails fallbacks
+        * to the old ones ... Ugh.
+        */
+ retry:
+       if (smu_supports_new_fans_ops) {
+               buffer[0] = 0x30;
+               buffer[1] = id;
+               *((u16 *)(&buffer[2])) = value;
+               cmd.data_len = 4;
+       } else {
+               if (id > 7)
+                       return -EINVAL;
+               /* Fill argument buffer */
+               memset(buffer, 0, 16);
+               buffer[0] = pwm ? 0x10 : 0x00;
+               buffer[1] = 0x01 << id;
+               *((u16 *)&buffer[2 + id * 2]) = value;
+               cmd.data_len = 14;
+       }
+
        cmd.reply_len = 16;
        cmd.data_buf = cmd.reply_buf = buffer;
        cmd.status = 0;
        cmd.done = smu_done_complete;
        cmd.misc = &comp;
 
-       /* Fill argument buffer */
-       memset(buffer, 0, 16);
-       buffer[0] = pwm ? 0x10 : 0x00;
-       buffer[1] = 0x01 << id;
-       *((u16 *)&buffer[2 + id * 2]) = value;
-
        rc = smu_queue_cmd(&cmd);
        if (rc)
                return rc;
        wait_for_completion(&comp);
+
+       /* Handle fallback (see coment above) */
+       if (cmd.status != 0 && smu_supports_new_fans_ops) {
+               printk(KERN_WARNING "windfarm: SMU failed new fan command "
+                      "falling back to old method\n");
+               smu_supports_new_fans_ops = 0;
+               goto retry;
+       }
+
        return cmd.status;
 }
 
@@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
 
        /* Names used on desktop models */
        if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
-           !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan"))
+           !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") ||
+           !strcmp(l, "CPU A EXHAUST"))
                fct->ctrl.name = "cpu-rear-fan-0";
-       else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1"))
+       else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") ||
+                !strcmp(l, "CPU B EXHAUST"))
                fct->ctrl.name = "cpu-rear-fan-1";
        else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
-                !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan"))
+                !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") ||
+                !strcmp(l, "CPU A INTAKE"))
                fct->ctrl.name = "cpu-front-fan-0";
-       else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1"))
+       else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") ||
+                !strcmp(l, "CPU B INTAKE"))
                fct->ctrl.name = "cpu-front-fan-1";
-       else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan"))
+       else if (!strcmp(l, "CPU A PUMP"))
+               fct->ctrl.name = "cpu-pump-0";
+       else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
+                !strcmp(l, "EXPANSION SLOTS INTAKE"))
                fct->ctrl.name = "slots-fan";
-       else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay"))
+       else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") ||
+                !strcmp(l, "DRIVE BAY A INTAKE"))
                fct->ctrl.name = "drive-bay-fan";
+       else if (!strcmp(l, "BACKSIDE"))
+               fct->ctrl.name = "backside-fan";
 
        /* Names used on iMac models */
        if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
@@ -223,7 +261,8 @@ static int __init smu_controls_init(void)
 
        /* Look for RPM fans */
        for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
-               if (!strcmp(fans->name, "rpm-fans"))
+               if (!strcmp(fans->name, "rpm-fans") ||
+                   device_is_compatible(fans, "smu-rpm-fans"))
                        break;
        for (fan = NULL;
             fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
new file mode 100644 (file)
index 0000000..3a32c59
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Windfarm PowerMac thermal control.  SMU "satellite" controller sensors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Released under the terms of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/semaphore.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)   printk(args)
+#else
+#define DBG(args...)   do { } while(0)
+#endif
+
+/* If the cache is older than 800ms we'll refetch it */
+#define MAX_AGE                msecs_to_jiffies(800)
+
+struct wf_sat {
+       int                     nr;
+       atomic_t                refcnt;
+       struct semaphore        mutex;
+       unsigned long           last_read; /* jiffies when cache last updated */
+       u8                      cache[16];
+       struct i2c_client       i2c;
+       struct device_node      *node;
+};
+
+static struct wf_sat *sats[2];
+
+struct wf_sat_sensor {
+       int             index;
+       int             index2;         /* used for power sensors */
+       int             shift;
+       struct wf_sat   *sat;
+       struct wf_sensor sens;
+};
+
+#define wf_to_sat(c)   container_of(c, struct wf_sat_sensor, sens)
+#define i2c_to_sat(c)  container_of(c, struct wf_sat, i2c)
+
+static int wf_sat_attach(struct i2c_adapter *adapter);
+static int wf_sat_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_sat_driver = {
+       .driver = {
+               .name           = "wf_smu_sat",
+       },
+       .attach_adapter = wf_sat_attach,
+       .detach_client  = wf_sat_detach,
+};
+
+/*
+ * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested
+ * length down to the low-level driver, so we use this, which
+ * works well enough with the SMU i2c driver code...
+ */
+static int sat_read_block(struct i2c_client *client, u8 command,
+                         u8 *values, int len)
+{
+       union i2c_smbus_data data;
+       int err;
+
+       data.block[0] = len;
+       err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                            I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA,
+                            &data);
+       if (!err)
+               memcpy(values, data.block, len);
+       return err;
+}
+
+struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
+                                                 unsigned int *size)
+{
+       struct wf_sat *sat;
+       int err;
+       unsigned int i, len;
+       u8 *buf;
+       u8 data[4];
+
+       /* TODO: Add the resulting partition to the device-tree */
+
+       if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
+               return NULL;
+
+       err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8);
+       if (err) {
+               printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
+               return NULL;
+       }
+
+       len = i2c_smbus_read_word_data(&sat->i2c, 9);
+       if (len < 0) {
+               printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
+               return NULL;
+       }
+       if (len == 0) {
+               printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id);
+               return NULL;
+       }
+
+       len = le16_to_cpu(len);
+       len = (len + 3) & ~3;
+       buf = kmalloc(len, GFP_KERNEL);
+       if (buf == NULL)
+               return NULL;
+
+       for (i = 0; i < len; i += 4) {
+               err = sat_read_block(&sat->i2c, 0xa, data, 4);
+               if (err) {
+                       printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
+                              err);
+                       goto fail;
+               }
+               buf[i] = data[1];
+               buf[i+1] = data[0];
+               buf[i+2] = data[3];
+               buf[i+3] = data[2];
+       }
+#ifdef DEBUG
+       DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id);
+       for (i = 0; i < len; ++i)
+               DBG(" %x", buf[i]);
+       DBG("\n");
+#endif
+
+       if (size)
+               *size = len;
+       return (struct smu_sdbp_header *) buf;
+
+ fail:
+       kfree(buf);
+       return NULL;
+}
+
+/* refresh the cache */
+static int wf_sat_read_cache(struct wf_sat *sat)
+{
+       int err;
+
+       err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16);
+       if (err)
+               return err;
+       sat->last_read = jiffies;
+#ifdef LOTSA_DEBUG
+       {
+               int i;
+               DBG(KERN_DEBUG "wf_sat_get: data is");
+               for (i = 0; i < 16; ++i)
+                       DBG(" %.2x", sat->cache[i]);
+               DBG("\n");
+       }
+#endif
+       return 0;
+}
+
+static int wf_sat_get(struct wf_sensor *sr, s32 *value)
+{
+       struct wf_sat_sensor *sens = wf_to_sat(sr);
+       struct wf_sat *sat = sens->sat;
+       int i, err;
+       s32 val;
+
+       if (sat->i2c.adapter == NULL)
+               return -ENODEV;
+
+       down(&sat->mutex);
+       if (time_after(jiffies, (sat->last_read + MAX_AGE))) {
+               err = wf_sat_read_cache(sat);
+               if (err)
+                       goto fail;
+       }
+
+       i = sens->index * 2;
+       val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift;
+       if (sens->index2 >= 0) {
+               i = sens->index2 * 2;
+               /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */
+               val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4;
+       }
+
+       *value = val;
+       err = 0;
+
+ fail:
+       up(&sat->mutex);
+       return err;
+}
+
+static void wf_sat_release(struct wf_sensor *sr)
+{
+       struct wf_sat_sensor *sens = wf_to_sat(sr);
+       struct wf_sat *sat = sens->sat;
+
+       if (atomic_dec_and_test(&sat->refcnt)) {
+               if (sat->i2c.adapter) {
+                       i2c_detach_client(&sat->i2c);
+                       sat->i2c.adapter = NULL;
+               }
+               if (sat->nr >= 0)
+                       sats[sat->nr] = NULL;
+               kfree(sat);
+       }
+       kfree(sens);
+}
+
+static struct wf_sensor_ops wf_sat_ops = {
+       .get_value      = wf_sat_get,
+       .release        = wf_sat_release,
+       .owner          = THIS_MODULE,
+};
+
+static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
+{
+       struct wf_sat *sat;
+       struct wf_sat_sensor *sens;
+       u32 *reg;
+       char *loc, *type;
+       u8 addr, chip, core;
+       struct device_node *child;
+       int shift, cpu, index;
+       char *name;
+       int vsens[2], isens[2];
+
+       reg = (u32 *) get_property(dev, "reg", NULL);
+       if (reg == NULL)
+               return;
+       addr = *reg;
+       DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
+
+       sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
+       if (sat == NULL)
+               return;
+       sat->nr = -1;
+       sat->node = of_node_get(dev);
+       atomic_set(&sat->refcnt, 0);
+       init_MUTEX(&sat->mutex);
+       sat->i2c.addr = (addr >> 1) & 0x7f;
+       sat->i2c.adapter = adapter;
+       sat->i2c.driver = &wf_sat_driver;
+       strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
+
+       if (i2c_attach_client(&sat->i2c)) {
+               printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
+               goto fail;
+       }
+
+       vsens[0] = vsens[1] = -1;
+       isens[0] = isens[1] = -1;
+       child = NULL;
+       while ((child = of_get_next_child(dev, child)) != NULL) {
+               reg = (u32 *) get_property(child, "reg", NULL);
+               type = get_property(child, "device_type", NULL);
+               loc = get_property(child, "location", NULL);
+               if (reg == NULL || loc == NULL)
+                       continue;
+
+               /* the cooked sensors are between 0x30 and 0x37 */
+               if (*reg < 0x30 || *reg > 0x37)
+                       continue;
+               index = *reg - 0x30;
+
+               /* expect location to be CPU [AB][01] ... */
+               if (strncmp(loc, "CPU ", 4) != 0)
+                       continue;
+               chip = loc[4] - 'A';
+               core = loc[5] - '0';
+               if (chip > 1 || core > 1) {
+                       printk(KERN_ERR "wf_sat_create: don't understand "
+                              "location %s for %s\n", loc, child->full_name);
+                       continue;
+               }
+               cpu = 2 * chip + core;
+               if (sat->nr < 0)
+                       sat->nr = chip;
+               else if (sat->nr != chip) {
+                       printk(KERN_ERR "wf_sat_create: can't cope with "
+                              "multiple CPU chips on one SAT (%s)\n", loc);
+                       continue;
+               }
+
+               if (strcmp(type, "voltage-sensor") == 0) {
+                       name = "cpu-voltage";
+                       shift = 4;
+                       vsens[core] = index;
+               } else if (strcmp(type, "current-sensor") == 0) {
+                       name = "cpu-current";
+                       shift = 8;
+                       isens[core] = index;
+               } else if (strcmp(type, "temp-sensor") == 0) {
+                       name = "cpu-temp";
+                       shift = 10;
+               } else
+                       continue;       /* hmmm shouldn't happen */
+
+               /* the +16 is enough for "cpu-voltage-n" */
+               sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+               if (sens == NULL) {
+                       printk(KERN_ERR "wf_sat_create: couldn't create "
+                              "%s sensor %d (no memory)\n", name, cpu);
+                       continue;
+               }
+               sens->index = index;
+               sens->index2 = -1;
+               sens->shift = shift;
+               sens->sat = sat;
+               atomic_inc(&sat->refcnt);
+               sens->sens.ops = &wf_sat_ops;
+               sens->sens.name = (char *) (sens + 1);
+               snprintf(sens->sens.name, 16, "%s-%d", name, cpu);
+
+               if (wf_register_sensor(&sens->sens)) {
+                       atomic_dec(&sat->refcnt);
+                       kfree(sens);
+               }
+       }
+
+       /* make the power sensors */
+       for (core = 0; core < 2; ++core) {
+               if (vsens[core] < 0 || isens[core] < 0)
+                       continue;
+               cpu = 2 * sat->nr + core;
+               sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+               if (sens == NULL) {
+                       printk(KERN_ERR "wf_sat_create: couldn't create power "
+                              "sensor %d (no memory)\n", cpu);
+                       continue;
+               }
+               sens->index = vsens[core];
+               sens->index2 = isens[core];
+               sens->shift = 0;
+               sens->sat = sat;
+               atomic_inc(&sat->refcnt);
+               sens->sens.ops = &wf_sat_ops;
+               sens->sens.name = (char *) (sens + 1);
+               snprintf(sens->sens.name, 16, "cpu-power-%d", cpu);
+
+               if (wf_register_sensor(&sens->sens)) {
+                       atomic_dec(&sat->refcnt);
+                       kfree(sens);
+               }
+       }
+
+       if (sat->nr >= 0)
+               sats[sat->nr] = sat;
+
+       return;
+
+ fail:
+       kfree(sat);
+}
+
+static int wf_sat_attach(struct i2c_adapter *adapter)
+{
+       struct device_node *busnode, *dev = NULL;
+       struct pmac_i2c_bus *bus;
+
+       bus = pmac_i2c_adapter_to_bus(adapter);
+       if (bus == NULL)
+               return -ENODEV;
+       busnode = pmac_i2c_get_bus_node(bus);
+
+       while ((dev = of_get_next_child(busnode, dev)) != NULL)
+               if (device_is_compatible(dev, "smu-sat"))
+                       wf_sat_create(adapter, dev);
+       return 0;
+}
+
+static int wf_sat_detach(struct i2c_client *client)
+{
+       struct wf_sat *sat = i2c_to_sat(client);
+
+       /* XXX TODO */
+
+       sat->i2c.adapter = NULL;
+       return 0;
+}
+
+static int __init sat_sensors_init(void)
+{
+       int err;
+
+       err = i2c_add_driver(&wf_sat_driver);
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+static void __exit sat_sensors_exit(void)
+{
+       i2c_del_driver(&wf_sat_driver);
+}
+
+module_init(sat_sensors_init);
+/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control");
+MODULE_LICENSE("GPL");
index 1a00d9c75a233cb267c55863cf0c90b4207bf35b..bed25dcf8a1eac74d96bf5a6239439471124c74c 100644 (file)
@@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
            !strcmp(l, "CPU T-Diode")) {
                ads->sens.ops = &smu_cputemp_ops;
                ads->sens.name = "cpu-temp";
+               if (cpudiode == NULL) {
+                       DBG("wf: cpudiode partition (%02x) not found\n",
+                           SMU_SDB_CPUDIODE_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "current-sensor") &&
                   !strcmp(l, "CPU Current")) {
                ads->sens.ops = &smu_cpuamp_ops;
                ads->sens.name = "cpu-current";
+               if (cpuvcp == NULL) {
+                       DBG("wf: cpuvcp partition (%02x) not found\n",
+                           SMU_SDB_CPUVCP_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "voltage-sensor") &&
                   !strcmp(l, "CPU Voltage")) {
                ads->sens.ops = &smu_cpuvolt_ops;
                ads->sens.name = "cpu-voltage";
+               if (cpuvcp == NULL) {
+                       DBG("wf: cpuvcp partition (%02x) not found\n",
+                           SMU_SDB_CPUVCP_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "power-sensor") &&
                   !strcmp(l, "Slots Power")) {
                ads->sens.ops = &smu_slotspow_ops;
@@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
        return NULL;
 }
 
-static int smu_fetch_param_partitions(void)
+static void smu_fetch_param_partitions(void)
 {
        struct smu_sdbp_header *hdr;
 
        /* Get CPU voltage/current/power calibration data */
        hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
-       if (hdr == NULL) {
-               DBG("wf: cpuvcp partition (%02x) not found\n",
-                   SMU_SDB_CPUVCP_ID);
-               return -ENODEV;
+       if (hdr != NULL) {
+               cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
+               /* Keep version around */
+               cpuvcp_version = hdr->version;
        }
-       cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
-       /* Keep version around */
-       cpuvcp_version = hdr->version;
 
        /* Get CPU diode calibration data */
        hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
-       if (hdr == NULL) {
-               DBG("wf: cpudiode partition (%02x) not found\n",
-                   SMU_SDB_CPUDIODE_ID);
-               return -ENODEV;
-       }
-       cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
+       if (hdr != NULL)
+               cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
 
        /* Get slots power calibration data if any */
        hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
@@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void)
        hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
        if (hdr != NULL)
                debugswitches = (u8 *)&hdr[1];
-
-       return 0;
 }
 
 static int __init smu_sensors_init(void)
 {
        struct device_node *smu, *sensors, *s;
        struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;
-       int rc;
 
        if (!smu_present())
                return -ENODEV;
 
        /* Get parameters partitions */
-       rc = smu_fetch_param_partitions();
-       if (rc)
-               return rc;
+       smu_fetch_param_partitions();
 
        smu = of_find_node_by_type(NULL, "smu");
        if (smu == NULL)
index 74039db846baa3eb19c4574c91827f4d58cb9050..d73779a42417f25a1fac190d4bc4907aa939a782 100644 (file)
@@ -545,7 +545,8 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region)
                return 0;
 
        do {
-               *region = find_next_zero_bit((unsigned long *) lc->sync_bits,
+               *region = ext2_find_next_zero_bit(
+                                            (unsigned long *) lc->sync_bits,
                                             lc->region_count,
                                             lc->sync_search);
                lc->sync_search = *region + 1;
index 7145cd150f7b2cac4f00c40f9efef5a36b5fad15..d05e3125d298bd5c7083204d6f24d098e002c66e 100644 (file)
@@ -1024,7 +1024,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                rdev-> sb_size = (rdev->sb_size | bmask)+1;
 
        if (refdev == 0)
-               return 1;
+               ret = 1;
        else {
                __u64 ev1, ev2;
                struct mdp_superblock_1 *refsb = 
@@ -1044,7 +1044,9 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                ev2 = le64_to_cpu(refsb->events);
 
                if (ev1 > ev2)
-                       return 1;
+                       ret = 1;
+               else
+                       ret = 0;
        }
        if (minor_version) 
                rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
@@ -1058,7 +1060,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
 
        if (le32_to_cpu(sb->size) > rdev->size*2)
                return -EINVAL;
-       return 0;
+       return ret;
 }
 
 static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1081,7 +1083,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
                mddev->size = le64_to_cpu(sb->size)/2;
                mddev->events = le64_to_cpu(sb->events);
                mddev->bitmap_offset = 0;
-               mddev->default_bitmap_offset = 1024;
+               mddev->default_bitmap_offset = 1024 >> 9;
                
                mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
                memcpy(mddev->uuid, sb->set_uuid, 16);
@@ -1161,6 +1163,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 
        sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
 
+       sb->raid_disks = cpu_to_le32(mddev->raid_disks);
+       sb->size = cpu_to_le64(mddev->size<<1);
+
        if (mddev->bitmap && mddev->bitmap_file == NULL) {
                sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
                sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
@@ -2686,14 +2691,6 @@ static int do_md_stop(mddev_t * mddev, int ro)
                        set_disk_ro(disk, 1);
        }
 
-       bitmap_destroy(mddev);
-       if (mddev->bitmap_file) {
-               atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
-               fput(mddev->bitmap_file);
-               mddev->bitmap_file = NULL;
-       }
-       mddev->bitmap_offset = 0;
-
        /*
         * Free resources if final stop
         */
@@ -2703,6 +2700,14 @@ static int do_md_stop(mddev_t * mddev, int ro)
                struct gendisk *disk;
                printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
 
+               bitmap_destroy(mddev);
+               if (mddev->bitmap_file) {
+                       atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
+                       fput(mddev->bitmap_file);
+                       mddev->bitmap_file = NULL;
+               }
+               mddev->bitmap_offset = 0;
+
                ITERATE_RDEV(mddev,rdev,tmp)
                        if (rdev->raid_disk >= 0) {
                                char nm[20];
@@ -2939,6 +2944,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
        info.ctime         = mddev->ctime;
        info.level         = mddev->level;
        info.size          = mddev->size;
+       if (info.size != mddev->size) /* overflow */
+               info.size = -1;
        info.nr_disks      = nr;
        info.raid_disks    = mddev->raid_disks;
        info.md_minor      = mddev->md_minor;
@@ -3465,7 +3472,7 @@ static int update_size(mddev_t *mddev, unsigned long size)
                bdev = bdget_disk(mddev->gendisk, 0);
                if (bdev) {
                        mutex_lock(&bdev->bd_inode->i_mutex);
-                       i_size_write(bdev->bd_inode, mddev->array_size << 10);
+                       i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10);
                        mutex_unlock(&bdev->bd_inode->i_mutex);
                        bdput(bdev);
                }
@@ -3485,17 +3492,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks)
        if (mddev->sync_thread)
                return -EBUSY;
        rv = mddev->pers->reshape(mddev, raid_disks);
-       if (!rv) {
-               struct block_device *bdev;
-
-               bdev = bdget_disk(mddev->gendisk, 0);
-               if (bdev) {
-                       mutex_lock(&bdev->bd_inode->i_mutex);
-                       i_size_write(bdev->bd_inode, mddev->array_size << 10);
-                       mutex_unlock(&bdev->bd_inode->i_mutex);
-                       bdput(bdev);
-               }
-       }
        return rv;
 }
 
@@ -3531,7 +3527,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
                )
                return -EINVAL;
        /* Check there is only one change */
-       if (mddev->size != info->size) cnt++;
+       if (info->size >= 0 && mddev->size != info->size) cnt++;
        if (mddev->raid_disks != info->raid_disks) cnt++;
        if (mddev->layout != info->layout) cnt++;
        if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
@@ -3548,7 +3544,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
                else
                        return mddev->pers->reconfig(mddev, info->layout, -1);
        }
-       if (mddev->size != info->size)
+       if (info->size >= 0 && mddev->size != info->size)
                rv = update_size(mddev, info->size);
 
        if (mddev->raid_disks    != info->raid_disks)
index d03f99cf4b7dfa936af326eef8ceb0586709fd5a..678f4dbbea1d5c22082d13fb1afd321465b61f28 100644 (file)
@@ -372,7 +372,7 @@ out_free_conf:
        kfree(conf);
        mddev->private = NULL;
 out:
-       return 1;
+       return -ENOMEM;
 }
 
 static int raid0_stop (mddev_t *mddev)
index 9130d051b474d64c4816644be4bc89d3b397f37a..ab90a6d1202043f7d332fe5f613be414845f1107 100644 (file)
@@ -565,6 +565,8 @@ rb_out:
 
        if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
                atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
+       else
+               disk = -1;
        rcu_read_unlock();
 
        return disk;
index 25976bfb6f9c19b841aa432dff67c0c24a425435..2dba305daf3c887799453caefae8d5a36535de4b 100644 (file)
@@ -350,7 +350,8 @@ static void shrink_stripes(raid5_conf_t *conf)
        while (drop_one_stripe(conf))
                ;
 
-       kmem_cache_destroy(conf->slab_cache);
+       if (conf->slab_cache)
+               kmem_cache_destroy(conf->slab_cache);
        conf->slab_cache = NULL;
 }
 
index f618a53b98bee235cca1160e4d08b16bd955ff0c..cd477ebf2ee44d8b963ec3157a5674300e1e85f5 100644 (file)
@@ -115,7 +115,7 @@ static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh)
                        list_add_tail(&sh->lru, &conf->inactive_list);
                        atomic_dec(&conf->active_stripes);
                        if (!conf->inactive_blocked ||
-                           atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4))
+                           atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4))
                                wake_up(&conf->wait_for_stripe);
                }
        }
@@ -273,7 +273,8 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector
                                conf->inactive_blocked = 1;
                                wait_event_lock_irq(conf->wait_for_stripe,
                                                    !list_empty(&conf->inactive_list) &&
-                                                   (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
+                                                   (atomic_read(&conf->active_stripes)
+                                                    < (conf->max_nr_stripes *3/4)
                                                     || !conf->inactive_blocked),
                                                    conf->device_lock,
                                                    unplug_slaves(conf->mddev);
@@ -302,9 +303,31 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector
        return sh;
 }
 
-static int grow_stripes(raid6_conf_t *conf, int num)
+static int grow_one_stripe(raid6_conf_t *conf)
 {
        struct stripe_head *sh;
+       sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
+       if (!sh)
+               return 0;
+       memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
+       sh->raid_conf = conf;
+       spin_lock_init(&sh->lock);
+
+       if (grow_buffers(sh, conf->raid_disks)) {
+               shrink_buffers(sh, conf->raid_disks);
+               kmem_cache_free(conf->slab_cache, sh);
+               return 0;
+       }
+       /* we just created an active stripe so... */
+       atomic_set(&sh->count, 1);
+       atomic_inc(&conf->active_stripes);
+       INIT_LIST_HEAD(&sh->lru);
+       release_stripe(sh);
+       return 1;
+}
+
+static int grow_stripes(raid6_conf_t *conf, int num)
+{
        kmem_cache_t *sc;
        int devs = conf->raid_disks;
 
@@ -316,45 +339,35 @@ static int grow_stripes(raid6_conf_t *conf, int num)
        if (!sc)
                return 1;
        conf->slab_cache = sc;
-       while (num--) {
-               sh = kmem_cache_alloc(sc, GFP_KERNEL);
-               if (!sh)
-                       return 1;
-               memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
-               sh->raid_conf = conf;
-               spin_lock_init(&sh->lock);
-
-               if (grow_buffers(sh, conf->raid_disks)) {
-                       shrink_buffers(sh, conf->raid_disks);
-                       kmem_cache_free(sc, sh);
+       while (num--)
+               if (!grow_one_stripe(conf))
                        return 1;
-               }
-               /* we just created an active stripe so... */
-               atomic_set(&sh->count, 1);
-               atomic_inc(&conf->active_stripes);
-               INIT_LIST_HEAD(&sh->lru);
-               release_stripe(sh);
-       }
        return 0;
 }
 
-static void shrink_stripes(raid6_conf_t *conf)
+static int drop_one_stripe(raid6_conf_t *conf)
 {
        struct stripe_head *sh;
+       spin_lock_irq(&conf->device_lock);
+       sh = get_free_stripe(conf);
+       spin_unlock_irq(&conf->device_lock);
+       if (!sh)
+               return 0;
+       if (atomic_read(&sh->count))
+               BUG();
+       shrink_buffers(sh, conf->raid_disks);
+       kmem_cache_free(conf->slab_cache, sh);
+       atomic_dec(&conf->active_stripes);
+       return 1;
+}
 
-       while (1) {
-               spin_lock_irq(&conf->device_lock);
-               sh = get_free_stripe(conf);
-               spin_unlock_irq(&conf->device_lock);
-               if (!sh)
-                       break;
-               if (atomic_read(&sh->count))
-                       BUG();
-               shrink_buffers(sh, conf->raid_disks);
-               kmem_cache_free(conf->slab_cache, sh);
-               atomic_dec(&conf->active_stripes);
-       }
-       kmem_cache_destroy(conf->slab_cache);
+static void shrink_stripes(raid6_conf_t *conf)
+{
+       while (drop_one_stripe(conf))
+               ;
+
+       if (conf->slab_cache)
+               kmem_cache_destroy(conf->slab_cache);
        conf->slab_cache = NULL;
 }
 
@@ -1912,6 +1925,74 @@ static void raid6d (mddev_t *mddev)
        PRINTK("--- raid6d inactive\n");
 }
 
+static ssize_t
+raid6_show_stripe_cache_size(mddev_t *mddev, char *page)
+{
+       raid6_conf_t *conf = mddev_to_conf(mddev);
+       if (conf)
+               return sprintf(page, "%d\n", conf->max_nr_stripes);
+       else
+               return 0;
+}
+
+static ssize_t
+raid6_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
+{
+       raid6_conf_t *conf = mddev_to_conf(mddev);
+       char *end;
+       int new;
+       if (len >= PAGE_SIZE)
+               return -EINVAL;
+       if (!conf)
+               return -ENODEV;
+
+       new = simple_strtoul(page, &end, 10);
+       if (!*page || (*end && *end != '\n') )
+               return -EINVAL;
+       if (new <= 16 || new > 32768)
+               return -EINVAL;
+       while (new < conf->max_nr_stripes) {
+               if (drop_one_stripe(conf))
+                       conf->max_nr_stripes--;
+               else
+                       break;
+       }
+       while (new > conf->max_nr_stripes) {
+               if (grow_one_stripe(conf))
+                       conf->max_nr_stripes++;
+               else break;
+       }
+       return len;
+}
+
+static struct md_sysfs_entry
+raid6_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
+                               raid6_show_stripe_cache_size,
+                               raid6_store_stripe_cache_size);
+
+static ssize_t
+stripe_cache_active_show(mddev_t *mddev, char *page)
+{
+       raid6_conf_t *conf = mddev_to_conf(mddev);
+       if (conf)
+               return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
+       else
+               return 0;
+}
+
+static struct md_sysfs_entry
+raid6_stripecache_active = __ATTR_RO(stripe_cache_active);
+
+static struct attribute *raid6_attrs[] =  {
+       &raid6_stripecache_size.attr,
+       &raid6_stripecache_active.attr,
+       NULL,
+};
+static struct attribute_group raid6_attrs_group = {
+       .name = NULL,
+       .attrs = raid6_attrs,
+};
+
 static int run(mddev_t *mddev)
 {
        raid6_conf_t *conf;
@@ -2095,6 +2176,7 @@ static int stop (mddev_t *mddev)
        shrink_stripes(conf);
        kfree(conf->stripe_hashtbl);
        blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
+       sysfs_remove_group(&mddev->kobj, &raid6_attrs_group);
        kfree(conf);
        mddev->private = NULL;
        return 0;
index 2583a865a58e4c7aea3d09b01f832e30689d29ad..2963605c0ecc236c3c95ea7f22595b4c095702a1 100644 (file)
@@ -4,7 +4,7 @@ config DVB_B2C2_FLEXCOP
        select DVB_STV0299
        select DVB_MT352
        select DVB_MT312
-       select DVB_NXT2002
+       select DVB_NXT200X
        select DVB_STV0297
        select DVB_BCM3510
        select DVB_LGDT330X
index 344a3c898460768057e8efdf649ed5b0d937537c..7d7e1613c5a745036e47f9630a5fdf3026ba778c 100644 (file)
@@ -116,11 +116,9 @@ void flexcop_dma_free(struct flexcop_dma *dma);
 
 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
 int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
 int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
 
 /* from flexcop-eeprom.c */
 /* the PCI part uses this call to get the MAC address, the USB part has its own */
index cf4ed1df60862b96a1d5750e2b4d867fdcb8e0df..6f592bc32d22ee136eb12fd0e4150af076370701 100644 (file)
@@ -169,38 +169,3 @@ int flexcop_dma_config_timer(struct flexcop_device *fc,
 }
 EXPORT_SYMBOL(flexcop_dma_config_timer);
 
-/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no,
-               int onoff)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
-
-       deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-       if (no & FC_DMA_1)
-               v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
-
-       if (no & FC_DMA_2)
-               v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
-
-       fc->write_ibi_reg(fc,ctrl_208,v);
-       deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
-
-int flexcop_dma_config_packet_count(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx,
-               u8 packets)
-{
-       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-
-       flexcop_dma_remap(fc,dma_idx,1);
-
-       v.dma_0x4_remap.DMA_maxpackets = packets;
-       fc->write_ibi_reg(fc,r,v);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config_packet_count);
index 0b940e152b7973ceb6db8f504fd7e8f36782b013..390cc3a99ce6525a6cc668f0543f144e8923a788 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "stv0299.h"
 #include "mt352.h"
-#include "nxt2002.h"
+#include "nxt200x.h"
 #include "bcm3510.h"
 #include "stv0297.h"
 #include "mt312.h"
@@ -343,9 +343,10 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = {
        .clock_polarity_flip = 1,
 };
 
-static struct nxt2002_config samsung_tbmv_config = {
+static struct nxt200x_config samsung_tbmv_config = {
        .demod_address    = 0x0a,
-       .request_firmware = flexcop_fe_request_firmware,
+       .pll_address      = 0xc2,
+       .pll_desc         = &dvb_pll_samsung_tbmv,
 };
 
 static struct bcm3510_config air2pc_atsc_first_gen_config = {
@@ -505,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
                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 = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+       if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
                fc->dev_type          = FC_AIR_ATSC2;
                info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
        } else
index 62282d8dbfa82e80048c4838df05dfa44124a7dd..167583bf0621879b1f9deefd1c443646ccbd4771 100644 (file)
@@ -36,14 +36,14 @@ void flexcop_determine_revision(struct flexcop_device *fc)
        /* bus parts have to decide if hw pid filtering is used or not. */
 }
 
-const char *flexcop_revision_names[] = {
+static const char *flexcop_revision_names[] = {
        "Unkown chip",
        "FlexCopII",
        "FlexCopIIb",
        "FlexCopIII",
 };
 
-const char *flexcop_device_names[] = {
+static const char *flexcop_device_names[] = {
        "Unkown device",
        "Air2PC/AirStar 2 DVB-T",
        "Air2PC/AirStar 2 ATSC 1st generation",
@@ -54,7 +54,7 @@ const char *flexcop_device_names[] = {
        "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
 };
 
-const char *flexcop_bus_names[] = {
+static const char *flexcop_bus_names[] = {
        "USB",
        "PCI",
 };
index 2f76eb3fea40c2d81d6a91ad310fd65e14134c8d..9bc40bdcc282e2bd1d25a79e6275aaab0e3ec780 100644 (file)
@@ -161,8 +161,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
                        fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
                u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
 
-               deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
-                               jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+               deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+                               jiffies_to_usecs(jiffies - fc_pci->last_irq),
+                               v.raw, (unsigned long long)cur_addr, cur_pos,
+                               fc_pci->last_dma1_cur_pos);
                fc_pci->last_irq = jiffies;
 
                /* buffer end was reached, restarted from the beginning
index 3153f9513c6319386eeadb753befc05fb48e544a..491f9bd6e1951be8d23463667da4fb5c72972b81 100644 (file)
@@ -16,8 +16,6 @@ typedef enum {
        FLEXCOP_III,
 } flexcop_revision_t;
 
-extern const char *flexcop_revision_names[];
-
 typedef enum {
        FC_UNK = 0,
        FC_AIR_DVB,
@@ -34,8 +32,6 @@ typedef enum {
        FC_PCI,
 } flexcop_bus_t;
 
-extern const char *flexcop_device_names[];
-
 /* FlexCop IBI Registers */
 #if defined(__LITTLE_ENDIAN)
        #include "flexcop_ibi_value_le.h"
index a04bb61f21f4d17ae365fd3c8402c400b8d5918b..34c3189a1a33980d16cf0c9f997e570d745e6108 100644 (file)
@@ -381,6 +381,23 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
 
 EXPORT_SYMBOL(bt878_device_control);
 
+
+struct cards card_list[] __devinitdata = {
+
+       { 0x01010071, BTTV_BOARD_NEBULA_DIGITV,                 "Nebula Electronics DigiTV" },
+       { 0x07611461, BTTV_BOARD_AVDVBT_761,                    "AverMedia AverTV DVB-T 761" },
+       { 0x001c11bd, BTTV_BOARD_PINNACLESAT,                   "Pinnacle PCTV Sat" },
+       { 0x002611bd, BTTV_BOARD_TWINHAN_DST,                   "Pinnacle PCTV SAT CI" },
+       { 0x00011822, BTTV_BOARD_TWINHAN_DST,                   "Twinhan VisionPlus DVB" },
+       { 0xfc00270f, BTTV_BOARD_TWINHAN_DST,                   "ChainTech digitop DST-1000 DVB-S" },
+       { 0x07711461, BTTV_BOARD_AVDVBT_771,                    "AVermedia AverTV DVB-T 771" },
+       { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE,               "DViCO FusionHDTV DVB-T Lite" },
+       { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE,       "DViCO FusionHDTV 5 Lite" },
+       { 0x20007063, BTTV_BOARD_PC_HDTV,                       "pcHDTV HD-2000 TV"},
+       { 0, -1, NULL }
+};
+
+
 /***********************/
 /* PCI device handling */
 /***********************/
@@ -388,18 +405,41 @@ EXPORT_SYMBOL(bt878_device_control);
 static int __devinit bt878_probe(struct pci_dev *dev,
                                 const struct pci_device_id *pci_id)
 {
-       int result;
+       int result = 0, has_dvb = 0, i;
        unsigned char lat;
        struct bt878 *bt;
 #if defined(__powerpc__)
        unsigned int cmd;
 #endif
+       unsigned int cardid;
+       unsigned short id;
+       struct cards *dvb_cards;
 
        printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
               bt878_num);
        if (pci_enable_device(dev))
                return -EIO;
 
+       pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id);
+       cardid = id << 16;
+       pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id);
+       cardid |= id;
+
+       for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) {
+               if (cardid == dvb_cards->pci_id) {
+                       printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n",
+                               __func__, cardid, dvb_cards->name);
+                       has_dvb = 1;
+               }
+       }
+
+       if (!has_dvb) {
+               printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid);
+               result = -EINVAL;
+
+               goto fail0;
+       }
+
        bt = &bt878[bt878_num];
        bt->dev = dev;
        bt->nr = bt878_num;
@@ -416,6 +456,8 @@ static int __devinit bt878_probe(struct pci_dev *dev,
 
        pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+
+
        printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
               bt878_num, bt->id, bt->revision, dev->bus->number,
               PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
index a73baf00ca3907206a40725cdd8fd674a5f3b6d9..9faf93770d08f3e5c6cdd3ddf2b70d86eaa17b20 100644 (file)
 
 #define BT878_RISC_SYNC_MASK   (1 << 15)
 
+
+#define BTTV_BOARD_UNKNOWN                 0x00
+#define BTTV_BOARD_PINNACLESAT             0x5e
+#define BTTV_BOARD_NEBULA_DIGITV           0x68
+#define BTTV_BOARD_PC_HDTV                 0x70
+#define BTTV_BOARD_TWINHAN_DST             0x71
+#define BTTV_BOARD_AVDVBT_771              0x7b
+#define BTTV_BOARD_AVDVBT_761              0x7c
+#define BTTV_BOARD_DVICO_DVBT_LITE         0x80
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+
+struct cards {
+       __u32 pci_id;
+       __u16 card_id;
+       char  *name;
+};
+
 extern int bt878_num;
 
 struct bt878 {
index 90a69d343b79833c429263e22b9faf4c57b689a1..d3df12039b066dcc4bf83a9dd174489baa1f9262 100644 (file)
@@ -83,12 +83,18 @@ config DVB_USB_UMT_010
          Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
 
 config DVB_USB_CXUSB
-       tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+       tristate "Conexant USB2.0 hybrid reference design support"
        depends on DVB_USB
        select DVB_CX22702
+       select DVB_LGDT330X
+       select DVB_MT352
        help
-         Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
-         only the DVB-T part is supported.
+         Say Y here to support the Conexant USB2.0 hybrid reference design.
+         Currently, only DVB and ATSC modes are supported, analog mode
+         shall be added in the future. Devices that require this module:
+
+         Medion MD95700 hybrid USB2.0 device.
+         DViCO FusionHDTV (Bluebird) USB2.0 devices
 
 config DVB_USB_DIGITV
        tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
index a7fb06f4cd3498f9f8cf25dbe305dc639474e497..f327fac1688e744555eb6b345773de22c9708352 100644 (file)
@@ -184,7 +184,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
        return 0;
 }
 
-struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
+static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
        { 0xfe, 0x02, KEY_TV },
        { 0xfe, 0x0e, KEY_MP3 },
        { 0xfe, 0x1a, KEY_DVD },
@@ -234,7 +234,7 @@ struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
 
 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 {
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
        static u8 reset []         = { RESET,      0x80 };
        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
        static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
@@ -255,7 +255,7 @@ static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 
 static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
 {      /* used in both lgz201 and th7579 */
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
        static u8 reset []         = { RESET,      0x80 };
        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
        static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
@@ -273,7 +273,7 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
        return 0;
 }
 
-struct cx22702_config cxusb_cx22702_config = {
+static struct cx22702_config cxusb_cx22702_config = {
        .demod_address = 0x63,
 
        .output_mode = CX22702_PARALLEL_OUTPUT,
@@ -282,13 +282,13 @@ struct cx22702_config cxusb_cx22702_config = {
        .pll_set  = dvb_usb_pll_set_i2c,
 };
 
-struct lgdt330x_config cxusb_lgdt330x_config = {
+static struct lgdt330x_config cxusb_lgdt330x_config = {
        .demod_address = 0x0e,
        .demod_chip    = LGDT3303,
        .pll_set       = dvb_usb_pll_set_i2c,
 };
 
-struct mt352_config cxusb_dee1601_config = {
+static struct mt352_config cxusb_dee1601_config = {
        .demod_address = 0x0f,
        .demod_init    = cxusb_dee1601_demod_init,
        .pll_set       = dvb_usb_pll_set,
index e6c55c9c9417d2afe8bf67a0b906c0342548f56c..caa1346e3063076c74b5a17dcc1e5f905a254a9a 100644 (file)
@@ -175,11 +175,13 @@ static int digitv_probe(struct usb_interface *intf,
        if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
                u8 b[4] = { 0 };
 
-               b[0] = 1;
-               digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+               if (d != NULL) { /* do that only when the firmware is loaded */
+                       b[0] = 1;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
 
-               b[0] = 0;
-               digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+                       b[0] = 0;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+               }
        }
        return ret;
 }
@@ -194,7 +196,7 @@ static struct dvb_usb_properties digitv_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-digitv-01.fw",
+       .firmware = "dvb-usb-digitv-02.fw",
 
        .size_of_priv     = 0,
 
@@ -229,6 +231,7 @@ static struct dvb_usb_properties digitv_properties = {
                        { &digitv_table[0], NULL },
                        { NULL },
                },
+               { NULL },
        }
 };
 
index 130ea7f21f5e62eb27331a3d6bfcef03c0b18939..12ebaf8bddca177d5e00ce1a5feae105a948dcee 100644 (file)
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
                  .cold_ids = { &dtt200u_usb_table[0], NULL },
                  .warm_ids = { &dtt200u_usb_table[1], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
                  .cold_ids = { &dtt200u_usb_table[2], NULL },
                  .warm_ids = { &dtt200u_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index 8535895819fb5e1d8d72bdadbdd6f07ace87fe97..9222b0a81f748646f82eda2ec382e16af1d2db7d 100644 (file)
@@ -24,6 +24,9 @@ static struct usb_cypress_controller cypress[] = {
        { .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+                              int *pos);
+
 /*
  * load a firmware packet to the device
  */
@@ -112,7 +115,8 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties
        return ret;
 }
 
-int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+                              int *pos)
 {
        u8 *b = (u8 *) &fw->data[*pos];
        int data_offs = 4;
@@ -142,5 +146,3 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
 
        return *pos;
 }
-EXPORT_SYMBOL(dvb_usb_get_hexline);
-
index dd568396e594819aa0fba7e90bec3b7137605e86..5e5d21ad93c984d7f4ee387326adb4c43a76589b 100644 (file)
@@ -341,7 +341,6 @@ struct hexline {
        u8 data[255];
        u8 chk;
 };
-extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *);
 extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
 
 #endif
index afa00fdb5ec0c3686fb3a6e1c49f6ac7ff3dfa9b..4a95eca81c5cc28bef8354bbeca4ad5d6d1d6774 100644 (file)
@@ -53,7 +53,8 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
        return ret;
 }
 
-int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
 {
        deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
        debug_dump(b,blen,deb_xfer);
@@ -88,7 +89,8 @@ unlock:
        return ret;
 }
 
-int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
+static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
+                               int olen, u8 *i, int ilen, int msec)
 {
        u8 bout[olen+2];
        u8 bin[ilen+1];
index a808d48e7bf24092ac6be65c6996c3582c42b354..c2f97f96c21fc1feae79ac7caa455cb641d1e8f0 100644 (file)
@@ -101,8 +101,6 @@ extern int dvb_usb_vp702x_debug;
 extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
-extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
 extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
 
 #endif
index 5242cca5db4a2a7ca4e9213cb450401a82cbbfcb..9999336aeeb6797aaa0a6c8be91d3fbde1aafe9d 100644 (file)
 
 struct vp7045_fe_state {
        struct dvb_frontend fe;
+       struct dvb_frontend_ops ops;
+
        struct dvb_usb_device *d;
 };
 
-
 static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
 {
        struct vp7045_fe_state *state = fe->demodulator_priv;
@@ -150,7 +151,8 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
                goto error;
 
        s->d = d;
-       s->fe.ops = &vp7045_fe_ops;
+       memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.ops = &s->ops;
        s->fe.demodulator_priv = s;
 
        goto success;
index 028204956bb007ba31684552c20b844af5459f36..3835235b68dff0f18793c0b711af42c3160ed6cd 100644 (file)
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
                  .cold_ids = { &vp7045_usb_table[2], NULL },
                  .warm_ids = { &vp7045_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index db3a8b40031eaa379edaaa066f5d0423860a5b91..76b6a2aef32f481f316d22d9d3c42096b15b239c 100644 (file)
@@ -28,12 +28,6 @@ config DVB_TDA8083
        help
          A DVB-S tuner module. Say Y when you want to support this frontend.
 
-config DVB_TDA80XX
-       tristate "Philips TDA8044 or TDA8083 based"
-       depends on DVB_CORE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
 config DVB_MT312
        tristate "Zarlink MT312 based"
        depends on DVB_CORE
@@ -139,12 +133,6 @@ config DVB_DIB3000MC
 comment "DVB-C (cable) frontends"
        depends on DVB_CORE
 
-config DVB_ATMEL_AT76C651
-       tristate "Atmel AT76C651 based"
-       depends on DVB_CORE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
 config DVB_VES1820
        tristate "VLSI VES1820 based"
        depends on DVB_CORE
@@ -166,18 +154,6 @@ config DVB_STV0297
 comment "ATSC (North American/Korean Terresterial DTV) frontends"
        depends on DVB_CORE
 
-config DVB_NXT2002
-       tristate "Nxt2002 based"
-       depends on DVB_CORE
-       select FW_LOADER
-       help
-         An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the command
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
-         download/extract it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
 config DVB_NXT200X
        tristate "Nextwave NXT2002/NXT2004 based"
        depends on DVB_CORE
index 615ec830e1c911d8c1adb28b93f73b51259e4bcd..1af769cd90c021d16d2e3e969306c0df4f508f8d 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
 obj-$(CONFIG_DVB_SP8870) += sp8870.o
 obj-$(CONFIG_DVB_CX22700) += cx22700.o
-obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
 obj-$(CONFIG_DVB_CX24110) += cx24110.o
 obj-$(CONFIG_DVB_TDA8083) += tda8083.o
 obj-$(CONFIG_DVB_L64781) += l64781.o
@@ -22,10 +21,8 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
-obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
 obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
 obj-$(CONFIG_DVB_OR51211) += or51211.o
 obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
deleted file mode 100644 (file)
index 8e0f4b3..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.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; 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.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include "dvb_frontend.h"
-#include "at76c651.h"
-
-
-struct at76c651_state {
-
-       struct i2c_adapter* i2c;
-
-       struct dvb_frontend_ops ops;
-
-       const struct at76c651_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* revision of the chip */
-       u8 revision;
-
-       /* last QAM value set */
-       u8 qam;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "at76c651: " args); \
-       } while (0)
-
-
-#if ! defined(__powerpc__)
-static __inline__ int __ilog2(unsigned long x)
-{
-       int i;
-
-       if (x == 0)
-               return -1;
-
-       for (i = 0; x != 0; i++)
-               x >>= 1;
-
-       return i - 1;
-}
-#endif
-
-static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg =
-               { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error "
-                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       __FUNCTION__, reg, data, ret);
-
-       msleep(10);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
-{
-       int ret;
-       u8 val;
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
-
-       return val;
-}
-
-static int at76c651_reset(struct at76c651_state* state)
-{
-       return at76c651_writereg(state, 0x07, 0x01);
-}
-
-static void at76c651_disable_interrupts(struct at76c651_state* state)
-{
-       at76c651_writereg(state, 0x0b, 0x00);
-}
-
-static int at76c651_set_auto_config(struct at76c651_state *state)
-{
-       /*
-        * Autoconfig
-        */
-
-       at76c651_writereg(state, 0x06, 0x01);
-
-       /*
-        * Performance optimizations, should be done after autoconfig
-        */
-
-       at76c651_writereg(state, 0x10, 0x06);
-       at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
-       at76c651_writereg(state, 0x15, 0x28);
-       at76c651_writereg(state, 0x20, 0x09);
-       at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
-       at76c651_writereg(state, 0x30, 0x90);
-       if (state->qam == 5)
-               at76c651_writereg(state, 0x35, 0x2A);
-
-       /*
-        * Initialize A/D-converter
-        */
-
-       if (state->revision == 0x11) {
-               at76c651_writereg(state, 0x2E, 0x38);
-               at76c651_writereg(state, 0x2F, 0x13);
-       }
-
-       at76c651_disable_interrupts(state);
-
-       /*
-        * Restart operation
-        */
-
-       at76c651_reset(state);
-
-       return 0;
-}
-
-static void at76c651_set_bbfreq(struct at76c651_state* state)
-{
-       at76c651_writereg(state, 0x04, 0x3f);
-       at76c651_writereg(state, 0x05, 0xee);
-}
-
-static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
-{
-       u8 exponent;
-       u32 mantissa;
-
-       if (symbol_rate > 9360000)
-               return -EINVAL;
-
-       /*
-        * FREF = 57800 kHz
-        * exponent = 10 + floor (log2(symbol_rate / FREF))
-        * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
-        */
-
-       exponent = __ilog2((symbol_rate << 4) / 903125);
-       mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
-
-       at76c651_writereg(state, 0x00, mantissa >> 13);
-       at76c651_writereg(state, 0x01, mantissa >> 5);
-       at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
-
-       return 0;
-}
-
-static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
-{
-       switch (qam) {
-       case QPSK:
-               state->qam = 0x02;
-               break;
-       case QAM_16:
-               state->qam = 0x04;
-               break;
-       case QAM_32:
-               state->qam = 0x05;
-               break;
-       case QAM_64:
-               state->qam = 0x06;
-               break;
-       case QAM_128:
-               state->qam = 0x07;
-               break;
-       case QAM_256:
-               state->qam = 0x08;
-               break;
-#if 0
-       case QAM_512:
-               state->qam = 0x09;
-               break;
-       case QAM_1024:
-               state->qam = 0x0A;
-               break;
-#endif
-       default:
-               return -EINVAL;
-
-       }
-
-       return at76c651_writereg(state, 0x03, state->qam);
-}
-
-static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
-{
-       u8 feciqinv = at76c651_readreg(state, 0x60);
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               feciqinv |= 0x02;
-               feciqinv &= 0xFE;
-               break;
-
-       case INVERSION_ON:
-               feciqinv |= 0x03;
-               break;
-
-       case INVERSION_AUTO:
-               feciqinv &= 0xFC;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return at76c651_writereg(state, 0x60, feciqinv);
-}
-
-static int at76c651_set_parameters(struct dvb_frontend* fe,
-                                  struct dvb_frontend_parameters *p)
-{
-       int ret;
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       at76c651_writereg(state, 0x0c, 0xc3);
-       state->config->pll_set(fe, p);
-       at76c651_writereg(state, 0x0c, 0xc2);
-
-       if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
-               return ret;
-
-       if ((ret = at76c651_set_inversion(state, p->inversion)))
-               return ret;
-
-       return at76c651_set_auto_config(state);
-}
-
-static int at76c651_set_defaults(struct dvb_frontend* fe)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       at76c651_set_symbol_rate(state, 6900000);
-       at76c651_set_qam(state, QAM_64);
-       at76c651_set_bbfreq(state);
-       at76c651_set_auto_config(state);
-
-       if (state->config->pll_init) {
-               at76c651_writereg(state, 0x0c, 0xc3);
-               state->config->pll_init(fe);
-               at76c651_writereg(state, 0x0c, 0xc2);
-       }
-
-       return 0;
-}
-
-static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-       u8 sync;
-
-       /*
-        * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
-        */
-       sync = at76c651_readreg(state, 0x80);
-       *status = 0;
-
-       if (sync & (0x04 | 0x10))       /* AGC1 || TIM */
-               *status |= FE_HAS_SIGNAL;
-       if (sync & 0x10)                /* TIM */
-               *status |= FE_HAS_CARRIER;
-       if (sync & 0x80)                /* FEC */
-               *status |= FE_HAS_VITERBI;
-       if (sync & 0x40)                /* CAR */
-               *status |= FE_HAS_SYNC;
-       if ((sync & 0xF0) == 0xF0)      /* TIM && EQU && CAR && FEC */
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
-       *ber |= at76c651_readreg(state, 0x82) << 8;
-       *ber |= at76c651_readreg(state, 0x83);
-       *ber *= 10;
-
-       return 0;
-}
-
-static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       u8 gain = ~at76c651_readreg(state, 0x91);
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *snr = 0xFFFF -
-           ((at76c651_readreg(state, 0x8F) << 8) |
-            at76c651_readreg(state, 0x90));
-
-       return 0;
-}
-
-static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *ucblocks = at76c651_readreg(state, 0x82);
-
-       return 0;
-}
-
-static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 50;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void at76c651_release(struct dvb_frontend* fe)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops at76c651_ops;
-
-struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct at76c651_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->qam = 0;
-
-       /* check if the demod is there */
-       if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
-
-       /* finalise state setup */
-       state->i2c = i2c;
-       state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
-       memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops at76c651_ops = {
-
-       .info = {
-               .name = "Atmel AT76C651B DVB-C",
-               .type = FE_QAM,
-               .frequency_min = 48250000,
-               .frequency_max = 863250000,
-               .frequency_stepsize = 62500,
-               /*.frequency_tolerance = */     /* FIXME: 12% of SR */
-               .symbol_rate_min = 0,           /* FIXME */
-               .symbol_rate_max = 9360000,     /* FIXME */
-               .symbol_rate_tolerance = 4000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                   FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                   FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                   FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
-                   FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
-       },
-
-       .release = at76c651_release,
-
-       .init = at76c651_set_defaults,
-
-       .set_frontend = at76c651_set_parameters,
-       .get_tune_settings = at76c651_get_tune_settings,
-
-       .read_status = at76c651_read_status,
-       .read_ber = at76c651_read_ber,
-       .read_signal_strength = at76c651_read_signal_strength,
-       .read_snr = at76c651_read_snr,
-       .read_ucblocks = at76c651_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
-MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
deleted file mode 100644 (file)
index 34054df..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.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; 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.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#ifndef AT76C651_H
-#define AT76C651_H
-
-#include <linux/dvb/frontend.h>
-
-struct at76c651_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* PLL maintenance */
-       int (*pll_init)(struct dvb_frontend* fe);
-       int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-                                           struct i2c_adapter* i2c);
-
-#endif // AT76C651_H
index 1b9934ea5b06c082bf7050eb771193c177895e68..4dcb6050d4fad659f04af92fc82bf23319892f19 100644 (file)
@@ -326,11 +326,11 @@ struct dvb_pll_desc dvb_pll_tuv1236d = {
 };
 EXPORT_SYMBOL(dvb_pll_tuv1236d);
 
-/* Samsung TBMV30111IN
+/* Samsung TBMV30111IN / TBMV30712IN1
  * used in Air2PC ATSC - 2nd generation (nxt2002)
  */
-struct dvb_pll_desc dvb_pll_tbmv30111in = {
-       .name = "Samsung TBMV30111IN",
+struct dvb_pll_desc dvb_pll_samsung_tbmv = {
+       .name = "Samsung TBMV30111IN / TBMV30712IN1",
        .min = 54000000,
        .max = 860000000,
        .count = 6,
@@ -343,7 +343,7 @@ struct dvb_pll_desc dvb_pll_tbmv30111in = {
                { 999999999, 44000000, 166666, 0xfc, 0x02 },
        }
 };
-EXPORT_SYMBOL(dvb_pll_tbmv30111in);
+EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
 
 /*
  * Philips SD1878 Tuner.
index f682c09189b305ac015d45a12c3ea28fe5921273..bb8d4b4eb183fcb8e33228658419a620fabe0b7f 100644 (file)
@@ -38,7 +38,7 @@ extern struct dvb_pll_desc dvb_pll_tded4;
 
 extern struct dvb_pll_desc dvb_pll_tuv1236d;
 extern struct dvb_pll_desc dvb_pll_tdhu2;
-extern struct dvb_pll_desc dvb_pll_tbmv30111in;
+extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
 extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
 
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
deleted file mode 100644 (file)
index 4f263e6..0000000
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
-    Support for B2C2/BBTI Technisat Air2PC - ATSC
-
-    Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
-
-    This program is free software; 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.
-
-*/
-
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
-#define CRC_CCIT_MASK 0x1021
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "nxt2002.h"
-
-struct nxt2002_state {
-
-       struct i2c_adapter* i2c;
-       struct dvb_frontend_ops ops;
-       const struct nxt2002_config* config;
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "nxt2002: " args); \
-       } while (0)
-
-static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
-{
-       /* probbably a much better way or doing this */
-       u8 buf2 [256],x;
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
-
-       buf2[0] = reg;
-       for (x = 0 ; x < len ; x++)
-               buf2[x+1] = buf[x];
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               printk ("%s: i2c write error (addr %02x, err == %i)\n",
-                       __FUNCTION__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
-{
-       u8 reg2 [] = { reg };
-
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
-                       { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
-               printk ("%s: i2c read error (addr %02x, err == %i)\n",
-                       __FUNCTION__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static u16 nxt2002_crc(u16 crc, u8 c)
-{
-
-       u8 i;
-       u16 input = (u16) c & 0xFF;
-
-       input<<=8;
-       for(i=0 ;i<8 ;i++) {
-               if((crc ^ input) & 0x8000)
-                       crc=(crc<<1)^CRC_CCIT_MASK;
-               else
-                       crc<<=1;
-       input<<=1;
-       }
-       return crc;
-}
-
-static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       /* set multi register length */
-       i2c_writebytes(state,0x34,&len,1);
-
-       /* set mutli register register */
-       i2c_writebytes(state,0x35,&reg,1);
-
-       /* send the actual data */
-       i2c_writebytes(state,0x36,data,len);
-
-       /* toggle the multireg write bit*/
-       buf = 0x02;
-       i2c_writebytes(state,0x21,&buf,1);
-
-       i2c_readbytes(state,0x21,&buf,1);
-
-       if ((buf & 0x02) == 0)
-               return 0;
-
-       dprintk("Error writing multireg register %02X\n",reg);
-
-       return 0;
-}
-
-static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-       u8 len2;
-       dprintk("%s\n", __FUNCTION__);
-
-       /* set multi register length */
-       len2 = len & 0x80;
-       i2c_writebytes(state,0x34,&len2,1);
-
-       /* set mutli register register */
-       i2c_writebytes(state,0x35,&reg,1);
-
-       /* send the actual data */
-       i2c_readbytes(state,reg,data,len);
-
-       return 0;
-}
-
-static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
-{
-       u8 buf[2],counter = 0;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf[0] = 0x80;
-       i2c_writebytes(state,0x22,buf,1);
-
-       while (counter < 20) {
-               i2c_readbytes(state,0x31,buf,1);
-               if (buf[0] & 0x40)
-                       return;
-               msleep(10);
-               counter++;
-       }
-
-       dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
-       return;
-}
-
-static void nxt2002_microcontroller_start (struct nxt2002_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf = 0x00;
-       i2c_writebytes(state,0x22,&buf,1);
-}
-
-static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
-{
-       u8 buf,count = 0;
-
-       dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
-
-       dprintk("%s\n", __FUNCTION__);
-       /* stop the micro first */
-       nxt2002_microcontroller_stop(state);
-
-       /* set the i2c transfer speed to the tuner */
-       buf = 0x03;
-       i2c_writebytes(state,0x20,&buf,1);
-
-       /* setup to transfer 4 bytes via i2c */
-       buf = 0x04;
-       i2c_writebytes(state,0x34,&buf,1);
-
-       /* write actual tuner bytes */
-       i2c_writebytes(state,0x36,data,4);
-
-       /* set tuner i2c address */
-       buf = 0xC2;
-       i2c_writebytes(state,0x35,&buf,1);
-
-       /* write UC Opmode to begin transfer */
-       buf = 0x80;
-       i2c_writebytes(state,0x21,&buf,1);
-
-       while (count < 20) {
-               i2c_readbytes(state,0x21,&buf,1);
-               if ((buf & 0x80)== 0x00)
-                       return 0;
-               msleep(100);
-               count++;
-       }
-
-       printk("nxt2002: timeout error writing tuner\n");
-       return 0;
-}
-
-static void nxt2002_agc_reset(struct nxt2002_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf = 0x08;
-       i2c_writebytes(state,0x08,&buf,1);
-
-       buf = 0x00;
-       i2c_writebytes(state,0x08,&buf,1);
-
-       return;
-}
-
-static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 buf[256],written = 0,chunkpos = 0;
-       u16 rambase,position,crc = 0;
-
-       dprintk("%s\n", __FUNCTION__);
-       dprintk("Firmware is %zu bytes\n",fw->size);
-
-       /* Get the RAM base for this nxt2002 */
-       i2c_readbytes(state,0x10,buf,1);
-
-       if (buf[0] & 0x10)
-               rambase = 0x1000;
-       else
-               rambase = 0x0000;
-
-       dprintk("rambase on this nxt2002 is %04X\n",rambase);
-
-       /* Hold the micro in reset while loading firmware */
-       buf[0] = 0x80;
-       i2c_writebytes(state,0x2B,buf,1);
-
-       for (position = 0; position < fw->size ; position++) {
-               if (written == 0) {
-                       crc = 0;
-                       chunkpos = 0x28;
-                       buf[0] = ((rambase + position) >> 8);
-                       buf[1] = (rambase + position) & 0xFF;
-                       buf[2] = 0x81;
-                       /* write starting address */
-                       i2c_writebytes(state,0x29,buf,3);
-               }
-               written++;
-               chunkpos++;
-
-               if ((written % 4) == 0)
-                       i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
-
-               crc = nxt2002_crc(crc,fw->data[position]);
-
-               if ((written == 255) || (position+1 == fw->size)) {
-                       /* write remaining bytes of firmware */
-                       i2c_writebytes(state, chunkpos+4-(written %4),
-                               &fw->data[position-(written %4) + 1],
-                               written %4);
-                       buf[0] = crc << 8;
-                       buf[1] = crc & 0xFF;
-
-                       /* write crc */
-                       i2c_writebytes(state,0x2C,buf,2);
-
-                       /* do a read to stop things */
-                       i2c_readbytes(state,0x2A,buf,1);
-
-                       /* set transfer mode to complete */
-                       buf[0] = 0x80;
-                       i2c_writebytes(state,0x2B,buf,1);
-
-                       written = 0;
-               }
-       }
-
-       printk ("done.\n");
-       return 0;
-};
-
-static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
-                                            struct dvb_frontend_parameters *p)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u32 freq = 0;
-       u16 tunerfreq = 0;
-       u8 buf[4];
-
-       freq = 44000 + ( p->frequency / 1000 );
-
-       dprintk("freq = %d      p->frequency = %d\n",freq,p->frequency);
-
-       tunerfreq = freq * 24/4000;
-
-       buf[0] = (tunerfreq >> 8) & 0x7F;
-       buf[1] = (tunerfreq & 0xFF);
-
-       if (p->frequency <= 214000000) {
-               buf[2] = 0x84 + (0x06 << 3);
-               buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
-       } else if (p->frequency <= 721000000) {
-               buf[2] = 0x84 + (0x07 << 3);
-               buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
-       } else if (p->frequency <= 841000000) {
-               buf[2] = 0x84 + (0x0E << 3);
-               buf[3] = 0x08;
-       } else {
-               buf[2] = 0x84 + (0x0F << 3);
-               buf[3] = 0x02;
-       }
-
-       /* write frequency information */
-       nxt2002_writetuner(state,buf);
-
-       /* reset the agc now that tuning has been completed */
-       nxt2002_agc_reset(state);
-
-       /* set target power level */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-               case QAM_256:
-                               buf[0] = 0x74;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x70;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       i2c_writebytes(state,0x42,buf,1);
-
-       /* configure sdm */
-       buf[0] = 0x87;
-       i2c_writebytes(state,0x57,buf,1);
-
-       /* write sdm1 input */
-       buf[0] = 0x10;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x58,buf,2);
-
-       /* write sdmx input */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-                               buf[0] = 0x68;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x64;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x60;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x5C,buf,2);
-
-       /* write adc power lpf fc */
-       buf[0] = 0x05;
-       i2c_writebytes(state,0x43,buf,1);
-
-       /* write adc power lpf fc */
-       buf[0] = 0x05;
-       i2c_writebytes(state,0x43,buf,1);
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-       /* write kg1 */
-       buf[0] = 0x00;
-       i2c_writebytes(state,0x4D,buf,1);
-
-       /* write sdm12 lpf fc */
-       buf[0] = 0x44;
-       i2c_writebytes(state,0x55,buf,1);
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       i2c_writebytes(state,0x41,buf,1);
-
-       /* write agc ucgp0 */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-                               buf[0] = 0x02;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x03;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x00;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       i2c_writebytes(state,0x30,buf,1);
-
-       /* write agc control reg */
-       buf[0] = 0x00;
-       i2c_writebytes(state,0x41,buf,1);
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x49,buf,2);
-       nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       i2c_writebytes(state,0x41,buf,1);
-
-       nxt2002_microcontroller_start(state);
-
-       /* adjacent channel detection should be done here, but I don't
-       have any stations with this need so I cannot test it */
-
-       return 0;
-}
-
-static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 lock;
-       i2c_readbytes(state,0x31,&lock,1);
-
-       *status = 0;
-       if (lock & 0x20) {
-               *status |= FE_HAS_SIGNAL;
-               *status |= FE_HAS_CARRIER;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-               *status |= FE_HAS_LOCK;
-       }
-       return 0;
-}
-
-static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt2002_readreg_multibyte(state,0xE6,b,3);
-
-       *ber = ((b[0] << 8) + b[1]) * 8;
-
-       return 0;
-}
-
-static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       i2c_writebytes(state,0xA1,b,1);
-
-       /* get multreg val */
-       nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-       temp = (b[0] << 8) | b[1];
-       *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
-
-       return 0;
-}
-
-static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0, temp2;
-       u32 snrdb = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       i2c_writebytes(state,0xA1,b,1);
-
-       /* get multreg val from 0xA6 */
-       nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-       temp = (b[0] << 8) | b[1];
-       temp2 = 0x7FFF - temp;
-
-       /* snr will be in db */
-       if (temp2 > 0x7F00)
-               snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
-       else if (temp2 > 0x7EC0)
-               snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
-       else if (temp2 > 0x7C00)
-               snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
-       else
-               snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
-
-       /* the value reported back from the frontend will be FFFF=32db 0000=0db */
-
-       *snr = snrdb * (0xFFFF/32000);
-
-       return 0;
-}
-
-static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt2002_readreg_multibyte(state,0xE6,b,3);
-       *ucblocks = b[2];
-
-       return 0;
-}
-
-static int nxt2002_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int nxt2002_init(struct dvb_frontend* fe)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret;
-       u8 buf[2];
-
-       if (!state->initialised) {
-               /* request the firmware, this will block until someone uploads it */
-               printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
-               ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
-               printk("nxt2002: Waiting for firmware upload(2)...\n");
-               if (ret) {
-                       printk("nxt2002: no firmware upload (timeout or file not found?)\n");
-                       return ret;
-               }
-
-               ret = nxt2002_load_firmware(fe, fw);
-               if (ret) {
-                       printk("nxt2002: writing firmware to device failed\n");
-                       release_firmware(fw);
-                       return ret;
-               }
-               printk("nxt2002: firmware upload complete\n");
-
-               /* Put the micro into reset */
-               nxt2002_microcontroller_stop(state);
-
-               /* ensure transfer is complete */
-               buf[0]=0;
-               i2c_writebytes(state,0x2B,buf,1);
-
-               /* Put the micro into reset for real this time */
-               nxt2002_microcontroller_stop(state);
-
-               /* soft reset everything (agc,frontend,eq,fec)*/
-               buf[0] = 0x0F;
-               i2c_writebytes(state,0x08,buf,1);
-               buf[0] = 0x00;
-               i2c_writebytes(state,0x08,buf,1);
-
-               /* write agc sdm configure */
-               buf[0] = 0xF1;
-               i2c_writebytes(state,0x57,buf,1);
-
-               /* write mod output format */
-               buf[0] = 0x20;
-               i2c_writebytes(state,0x09,buf,1);
-
-               /* write fec mpeg mode */
-               buf[0] = 0x7E;
-               buf[1] = 0x00;
-               i2c_writebytes(state,0xE9,buf,2);
-
-               /* write mux selection */
-               buf[0] = 0x00;
-               i2c_writebytes(state,0xCC,buf,1);
-
-               state->initialised = 1;
-       }
-
-       return 0;
-}
-
-static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 500;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void nxt2002_release(struct dvb_frontend* fe)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops nxt2002_ops;
-
-struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct nxt2002_state* state = NULL;
-       u8 buf [] = {0,0,0,0,0};
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
-       state->initialised = 0;
-
-       /* Check the first 5 registers to ensure this a revision we can handle */
-
-       i2c_readbytes(state, 0x00, buf, 5);
-       if (buf[0] != 0x04) goto error;         /* device id */
-       if (buf[1] != 0x02) goto error;         /* fab id */
-       if (buf[2] != 0x11) goto error;         /* month */
-       if (buf[3] != 0x20) goto error;         /* year msb */
-       if (buf[4] != 0x00) goto error;         /* year lsb */
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops nxt2002_ops = {
-
-       .info = {
-               .name = "Nextwave nxt2002 VSB/QAM frontend",
-               .type = FE_ATSC,
-               .frequency_min =  54000000,
-               .frequency_max = 860000000,
-               /* stepsize is just a guess */
-               .frequency_stepsize = 166666,
-               .caps = 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_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
-       },
-
-       .release = nxt2002_release,
-
-       .init = nxt2002_init,
-       .sleep = nxt2002_sleep,
-
-       .set_frontend = nxt2002_setup_frontend_parameters,
-       .get_tune_settings = nxt2002_get_tune_settings,
-
-       .read_status = nxt2002_read_status,
-       .read_ber = nxt2002_read_ber,
-       .read_signal_strength = nxt2002_read_signal_strength,
-       .read_snr = nxt2002_read_snr,
-       .read_ucblocks = nxt2002_read_ucblocks,
-
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
-MODULE_AUTHOR("Taylor Jacob");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
deleted file mode 100644 (file)
index 462301f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-   Driver for the Nxt2002 demodulator
-*/
-
-#ifndef NXT2002_H
-#define NXT2002_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct nxt2002_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-                                          struct i2c_adapter* i2c);
-
-#endif // NXT2002_H
index 78d2b93d35b9d7670beab86263fa0dbd46c6be14..9e35353945099f69d073c24996802fa57ab53701 100644 (file)
@@ -1,9 +1,10 @@
 /*
  *    Support for NXT2002 and NXT2004 - VSB/QAM
  *
- *    Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
+ *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
  *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
- *    and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
+ *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.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
@@ -614,7 +615,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write sdm1 input */
        buf[0] = 0x10;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x58, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x58, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x58, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write sdmx input */
        switch (p->u.vsb.modulation) {
@@ -632,7 +643,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
                                break;
        }
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x5C, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x5C, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write adc power lpf fc */
        buf[0] = 0x05;
@@ -648,7 +669,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write accumulator2 input */
        buf[0] = 0x80;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x4B, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write kg1 */
        buf[0] = 0x00;
@@ -714,8 +745,19 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write accumulator2 input */
        buf[0] = 0x80;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x49, buf,2);
-       nxt200x_writebytes(state, 0x4B, buf,2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x49, buf, 2);
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x49, buf, 2);
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write agc control reg */
        buf[0] = 0x04;
@@ -1199,7 +1241,7 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
 MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
+MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(nxt200x_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
deleted file mode 100644 (file)
index d1cabb6..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "tda80xx.h"
-
-enum {
-       ID_TDA8044 = 0x04,
-       ID_TDA8083 = 0x05,
-};
-
-
-struct tda80xx_state {
-
-       struct i2c_adapter* i2c;
-
-       struct dvb_frontend_ops ops;
-
-       /* configuration settings */
-       const struct tda80xx_config* config;
-
-       struct dvb_frontend frontend;
-
-       u32 clk;
-       int afc_loop;
-       struct work_struct worklet;
-       fe_code_rate_t code_rate;
-       fe_spectral_inversion_t spectral_inversion;
-       fe_status_t status;
-       u8 id;
-};
-
-static int debug = 1;
-#define dprintk        if (debug) printk
-
-static u8 tda8044_inittab_pre[] = {
-       0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-       0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
-       0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-       0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
-       0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00
-};
-
-static u8 tda8044_inittab_post[] = {
-       0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-       0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
-       0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-       0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
-       0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00
-};
-
-static u8 tda8083_inittab[] = {
-       0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
-       0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
-       0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
-       0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
-       0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00
-};
-
-static __inline__ u32 tda80xx_div(u32 a, u32 b)
-{
-       return (a + (b / 2)) / b;
-}
-
-static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
-{
-       u32 r;
-
-       while ((r = a % b)) {
-               a = b;
-               b = r;
-       }
-
-       return b;
-}
-
-static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
-{
-       int ret;
-       struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-                         { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (reg %02x, ret == %i)\n",
-                               __FUNCTION__, reg, ret);
-
-       mdelay(10);
-
-       return (ret == 2) ? 0 : -EREMOTEIO;
-}
-
-static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
-{
-       int ret;
-       u8 wbuf[len + 1];
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
-
-       wbuf[0] = reg;
-       memcpy(&wbuf[1], buf, len);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
-
-       mdelay(10);
-
-       return (ret == 1) ? 0 : -EREMOTEIO;
-}
-
-static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
-{
-       u8 val;
-
-       tda80xx_read(state, reg, &val, 1);
-
-       return val;
-}
-
-static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
-{
-       return tda80xx_write(state, reg, &data, 1);
-}
-
-static int tda80xx_set_parameters(struct tda80xx_state* state,
-                                 fe_spectral_inversion_t inversion,
-                                 u32 symbol_rate,
-                                 fe_code_rate_t fec_inner)
-{
-       u8 buf[15];
-       u64 ratio;
-       u32 clk;
-       u32 k;
-       u32 sr = symbol_rate;
-       u32 gcd;
-       u8 scd;
-
-       if (symbol_rate > (state->clk * 3) / 16)
-               scd = 0;
-       else if (symbol_rate > (state->clk * 3) / 32)
-               scd = 1;
-       else if (symbol_rate > (state->clk * 3) / 64)
-               scd = 2;
-       else
-               scd = 3;
-
-       clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-       /*
-        * Viterbi decoder:
-        * Differential decoding off
-        * Spectral inversion unknown
-        * QPSK modulation
-        */
-       if (inversion == INVERSION_ON)
-               buf[0] = 0x60;
-       else if (inversion == INVERSION_OFF)
-               buf[0] = 0x20;
-       else
-               buf[0] = 0x00;
-
-       /*
-        * CLK ratio:
-        * system clock frequency is up to 64 or 96 MHz
-        *
-        * formula:
-        * r = k * clk / symbol_rate
-        *
-        * k:   2^21 for caa 0..3,
-        *      2^20 for caa 4..5,
-        *      2^19 for caa 6..7
-        */
-       if (symbol_rate <= (clk * 3) / 32)
-               k = (1 << 19);
-       else if (symbol_rate <= (clk * 3) / 16)
-               k = (1 << 20);
-       else
-               k = (1 << 21);
-
-       gcd = tda80xx_gcd(clk, sr);
-       clk /= gcd;
-       sr /= gcd;
-
-       gcd = tda80xx_gcd(k, sr);
-       k /= gcd;
-       sr /= gcd;
-
-       ratio = (u64)k * (u64)clk;
-       do_div(ratio, sr);
-
-       buf[1] = ratio >> 16;
-       buf[2] = ratio >> 8;
-       buf[3] = ratio;
-
-       /* nyquist filter roll-off factor 35% */
-       buf[4] = 0x20;
-
-       clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-       /* Anti Alias Filter */
-       if (symbol_rate < (clk * 3) / 64)
-               printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
-       else if (symbol_rate <= clk / 16)
-               buf[4] |= 0x07;
-       else if (symbol_rate <= (clk * 3) / 32)
-               buf[4] |= 0x06;
-       else if (symbol_rate <= clk / 8)
-               buf[4] |= 0x05;
-       else if (symbol_rate <= (clk * 3) / 16)
-               buf[4] |= 0x04;
-       else if (symbol_rate <= clk / 4)
-               buf[4] |= 0x03;
-       else if (symbol_rate <= (clk * 3) / 8)
-               buf[4] |= 0x02;
-       else if (symbol_rate <= clk / 2)
-               buf[4] |= 0x01;
-       else
-               buf[4] |= 0x00;
-
-       /* Sigma Delta converter */
-       buf[5] = 0x00;
-
-       /* FEC: Possible puncturing rates */
-       if (fec_inner == FEC_NONE)
-               buf[6] = 0x00;
-       else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
-               buf[6] = (1 << (8 - fec_inner));
-       else if (fec_inner == FEC_AUTO)
-               buf[6] = 0xff;
-       else
-               return -EINVAL;
-
-       /* carrier lock detector threshold value */
-       buf[7] = 0x30;
-       /* AFC1: proportional part settings */
-       buf[8] = 0x42;
-       /* AFC1: integral part settings */
-       buf[9] = 0x98;
-       /* PD: Leaky integrator SCPC mode */
-       buf[10] = 0x28;
-       /* AFC2, AFC1 controls */
-       buf[11] = 0x30;
-       /* PD: proportional part settings */
-       buf[12] = 0x42;
-       /* PD: integral part settings */
-       buf[13] = 0x99;
-       /* AGC */
-       buf[14] = 0x50 | scd;
-
-       printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
-
-       return tda80xx_write(state, 0x01, buf, sizeof(buf));
-}
-
-static int tda80xx_set_clk(struct tda80xx_state* state)
-{
-       u8 buf[2];
-
-       /* CLK proportional part */
-       buf[0] = (0x06 << 5) | 0x08;    /* CMP[2:0], CSP[4:0] */
-       /* CLK integral part */
-       buf[1] = (0x04 << 5) | 0x1a;    /* CMI[2:0], CSI[4:0] */
-
-       return tda80xx_write(state, 0x17, buf, sizeof(buf));
-}
-
-#if 0
-static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
-{
-       /* a constant value is nonsense here imho */
-       return tda80xx_writereg(state, 0x22, 0xf9);
-}
-#endif
-
-static int tda80xx_close_loop(struct tda80xx_state* state)
-{
-       u8 buf[2];
-
-       /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
-       buf[0] = 0x68;
-       /* AFC1: Loop closed, CAR Feedback: 8192 */
-       buf[1] = 0x70;
-
-       return tda80xx_write(state, 0x0b, buf, sizeof(buf));
-}
-
-static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
-{
-       schedule_work(priv);
-
-       return IRQ_HANDLED;
-}
-
-static void tda80xx_read_status_int(struct tda80xx_state* state)
-{
-       u8 val;
-
-       static const fe_spectral_inversion_t inv_tab[] = {
-               INVERSION_OFF, INVERSION_ON
-       };
-
-       static const fe_code_rate_t fec_tab[] = {
-               FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
-               FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
-       };
-
-       val = tda80xx_readreg(state, 0x02);
-
-       state->status = 0;
-
-       if (val & 0x01) /* demodulator lock */
-               state->status |= FE_HAS_SIGNAL;
-       if (val & 0x02) /* clock recovery lock */
-               state->status |= FE_HAS_CARRIER;
-       if (val & 0x04) /* viterbi lock */
-               state->status |= FE_HAS_VITERBI;
-       if (val & 0x08) /* deinterleaver lock (packet sync) */
-               state->status |= FE_HAS_SYNC;
-       if (val & 0x10) /* derandomizer lock (frame sync) */
-               state->status |= FE_HAS_LOCK;
-       if (val & 0x20) /* frontend can not lock */
-               state->status |= FE_TIMEDOUT;
-
-       if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
-               printk("tda80xx: closing loop\n");
-               tda80xx_close_loop(state);
-               state->afc_loop = 0;
-       }
-
-       if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
-               val = tda80xx_readreg(state, 0x0e);
-               state->code_rate = fec_tab[val & 0x07];
-               if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
-                       state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
-               else
-                       state->spectral_inversion = INVERSION_AUTO;
-       }
-       else {
-               state->code_rate = FEC_AUTO;
-       }
-}
-
-static void tda80xx_worklet(void *priv)
-{
-       struct tda80xx_state *state = priv;
-
-       tda80xx_writereg(state, 0x00, 0x04);
-       enable_irq(state->config->irq);
-
-       tda80xx_read_status_int(state);
-}
-
-static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
-{
-       size_t i;
-
-       for (i = 0; i < 100; i++) {
-               if (tda80xx_readreg(state, 0x02) & 0x80)
-                       break;
-               msleep(10);
-       }
-}
-
-static int tda8044_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-       int ret;
-
-       /*
-        * this function is a mess...
-        */
-
-       if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
-               return ret;
-
-       tda80xx_writereg(state, 0x0f, 0x50);
-#if 1
-       tda80xx_writereg(state, 0x20, 0x8F);            /* FIXME */
-       tda80xx_writereg(state, 0x20, state->config->volt18setting);    /* FIXME */
-       //tda80xx_writereg(state, 0x00, 0x04);
-       tda80xx_writereg(state, 0x00, 0x0C);
-#endif
-       //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
-
-       tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
-
-       if (state->config->pll_init) {
-               tda80xx_writereg(state, 0x1c, 0x80);
-               state->config->pll_init(fe);
-               tda80xx_writereg(state, 0x1c, 0x00);
-       }
-
-       return 0;
-}
-
-static int tda8083_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
-
-       if (state->config->pll_init) {
-               tda80xx_writereg(state, 0x1c, 0x80);
-               state->config->pll_init(fe);
-               tda80xx_writereg(state, 0x1c, 0x00);
-       }
-
-       return 0;
-}
-
-static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               return tda80xx_writereg(state, 0x20, state->config->volt13setting);
-       case SEC_VOLTAGE_18:
-               return tda80xx_writereg(state, 0x20, state->config->volt18setting);
-       case SEC_VOLTAGE_OFF:
-               return tda80xx_writereg(state, 0x20, 0);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               return tda80xx_writereg(state, 0x29, 0x00);
-       case SEC_TONE_ON:
-               return tda80xx_writereg(state, 0x29, 0x80);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (cmd->msg_len > 6)
-               return -EINVAL;
-
-       tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
-       tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
-       tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
-       tda80xx_wait_diseqc_fifo(state);
-
-       return 0;
-}
-
-static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (cmd) {
-       case SEC_MINI_A:
-               tda80xx_writereg(state, 0x29, 0x14);
-               break;
-       case SEC_MINI_B:
-               tda80xx_writereg(state, 0x29, 0x1c);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       tda80xx_wait_diseqc_fifo(state);
-
-       return 0;
-}
-
-static int tda80xx_sleep(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_writereg(state, 0x00, 0x02);    /* enter standby */
-
-       return 0;
-}
-
-static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_writereg(state, 0x1c, 0x80);
-       state->config->pll_set(fe, p);
-       tda80xx_writereg(state, 0x1c, 0x00);
-
-       tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
-       tda80xx_set_clk(state);
-       //tda80xx_set_scpc_freq_offset(state);
-       state->afc_loop = 1;
-
-       return 0;
-}
-
-static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (!state->config->irq)
-               tda80xx_read_status_int(state);
-
-       p->inversion = state->spectral_inversion;
-       p->u.qpsk.fec_inner = state->code_rate;
-
-       return 0;
-}
-
-static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (!state->config->irq)
-               tda80xx_read_status_int(state);
-       *status = state->status;
-
-       return 0;
-}
-
-static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-
-       if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
-               return ret;
-
-       *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
-
-       return 0;
-}
-
-static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       u8 gain = ~tda80xx_readreg(state, 0x01);
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       u8 quality = tda80xx_readreg(state, 0x08);
-       *snr = (quality << 8) | quality;
-
-       return 0;
-}
-
-static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       *ucblocks = tda80xx_readreg(state, 0x0f);
-       if (*ucblocks == 0xff)
-               *ucblocks = 0xffffffff;
-
-       return 0;
-}
-
-static int tda80xx_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch(state->id) {
-       case ID_TDA8044:
-               return tda8044_init(fe);
-
-       case ID_TDA8083:
-               return tda8083_init(fe);
-       }
-       return 0;
-}
-
-static void tda80xx_release(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (state->config->irq)
-               free_irq(state->config->irq, &state->worklet);
-
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda80xx_ops;
-
-struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct tda80xx_state* state = NULL;
-       int ret;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
-       state->spectral_inversion = INVERSION_AUTO;
-       state->code_rate = FEC_AUTO;
-       state->status = 0;
-       state->afc_loop = 0;
-
-       /* check if the demod is there */
-       if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
-       state->id = tda80xx_readreg(state, 0x00);
-
-       switch (state->id) {
-       case ID_TDA8044:
-               state->clk = 96000000;
-               printk("tda80xx: Detected tda8044\n");
-               break;
-
-       case ID_TDA8083:
-               state->clk = 64000000;
-               printk("tda80xx: Detected tda8083\n");
-               break;
-
-       default:
-               goto error;
-       }
-
-       /* setup IRQ */
-       if (state->config->irq) {
-               INIT_WORK(&state->worklet, tda80xx_worklet, state);
-               if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
-                       printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
-                       goto error;
-               }
-       }
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda80xx_ops = {
-
-       .info = {
-               .name = "Philips TDA80xx DVB-S",
-               .type = FE_QPSK,
-               .frequency_min = 500000,
-               .frequency_max = 2700000,
-               .frequency_stepsize = 125,
-               .symbol_rate_min = 4500000,
-               .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_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = tda80xx_release,
-
-       .init = tda80xx_init,
-       .sleep = tda80xx_sleep,
-
-       .set_frontend = tda80xx_set_frontend,
-       .get_frontend = tda80xx_get_frontend,
-
-       .read_status = tda80xx_read_status,
-       .read_ber = tda80xx_read_ber,
-       .read_signal_strength = tda80xx_read_signal_strength,
-       .read_snr = tda80xx_read_snr,
-       .read_ucblocks = tda80xx_read_ucblocks,
-
-       .diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
-       .diseqc_send_burst = tda80xx_send_diseqc_burst,
-       .set_tone = tda80xx_set_tone,
-       .set_voltage = tda80xx_set_voltage,
-};
-
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
-MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
deleted file mode 100644 (file)
index cd639a0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef TDA80XX_H
-#define TDA80XX_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda80xx_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* IRQ to use (0=>no IRQ used) */
-       u32 irq;
-
-       /* Register setting to use for 13v */
-       u8 volt13setting;
-
-       /* Register setting to use for 18v */
-       u8 volt18setting;
-
-       /* PLL maintenance */
-       int (*pll_init)(struct dvb_frontend* fe);
-       int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-                                          struct i2c_adapter* i2c);
-
-#endif // TDA80XX_H
index 27494901975f6f57e6b413731848be7ac2980944..d36369e9e88f4557f2db1cd9c95c66b7f22f2454 100644 (file)
@@ -2329,6 +2329,17 @@ static int frontend_init(struct av7110 *av7110)
                        av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
                        break;
 
+               case 0x0004: // Galaxis DVB-S rev1.3
+                       /* ALPS BSRV2 */
+                       av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops->set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                       }
+                       break;
+
                case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
                        /* Grundig 29504-451 */
                        av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
@@ -2930,6 +2941,7 @@ MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
 MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
 MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
+MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");
 
 static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(fsc,         0x110a, 0x0000),
@@ -2937,13 +2949,13 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(ttt_1_X,     0x13c2, 0x0001),
        MAKE_EXTENSION_PCI(ttc_2_X,     0x13c2, 0x0002),
        MAKE_EXTENSION_PCI(tts_2_X,     0x13c2, 0x0003),
+       MAKE_EXTENSION_PCI(gxs_1_3,     0x13c2, 0x0004),
        MAKE_EXTENSION_PCI(fss,         0x13c2, 0x0006),
        MAKE_EXTENSION_PCI(ttt,         0x13c2, 0x0008),
        MAKE_EXTENSION_PCI(ttc_1_X,     0x13c2, 0x000a),
        MAKE_EXTENSION_PCI(tts_2_3,     0x13c2, 0x000e),
        MAKE_EXTENSION_PCI(tts_1_3se,   0x13c2, 0x1002),
 
-/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
 
index 6ea30df2e823c3dc54cf10699df7d2af4609ac3b..fafd25fab83593e483245f47d17ae175495d9259 100644 (file)
@@ -273,8 +273,6 @@ struct av7110 {
 extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
                       u16 subpid, u16 pcrpid);
 
-extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
-
 extern int av7110_ir_init(struct av7110 *av7110);
 extern void av7110_ir_exit(struct av7110 *av7110);
 
index 9138132ad25f3d10e93f4819e06ba70fe4a3ef22..617e4f6c0ed78154f87a509455abd2f0906ac677 100644 (file)
@@ -155,6 +155,19 @@ static void input_repeat_key(unsigned long data)
 }
 
 
+static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
+{
+       int ret = 0;
+
+       dprintk(4, "%p\n", av7110);
+       if (av7110) {
+               ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+               av7110->ir_config = ir_config;
+       }
+       return ret;
+}
+
+
 static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
                                unsigned long count, void *data)
 {
@@ -187,19 +200,6 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
 }
 
 
-int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
-{
-       int ret = 0;
-
-       dprintk(4, "%p\n", av7110);
-       if (av7110) {
-               ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
-               av7110->ir_config = ir_config;
-       }
-       return ret;
-}
-
-
 static void ir_handler(struct av7110 *av7110, u32 ircom)
 {
        dprintk(4, "ircommand = %08x\n", ircom);
index aa4c4c52188050ac1ff334b87e9dbe1a5a3d14d0..578b20085082a54df29077b2b517e946a30482f0 100644 (file)
@@ -214,7 +214,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                   we can capture, of the first and second field. */
                .vbistart       = { 7,320 },
        },{
-               .v4l2_id        = V4L2_STD_NTSC_M,
+               .v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name           = "NTSC",
                .Fsc            = 28636363,
                .swidth         = 768,
index 297c32ab51e35bdd35bc95c0a39bc0e58096cfe5..840fe0177121190275008fbda829019258236972 100644 (file)
@@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
        if (kp->clipcount > 2048)
                return -EINVAL;
        if (kp->clipcount) {
-               struct v4l2_clip32 *uclips = compat_ptr(up->clips);
-               struct v4l2_clip *kclips;
+               struct v4l2_clip32 __user *uclips;
+               struct v4l2_clip __user *kclips;
                int n = kp->clipcount;
+               compat_caddr_t p;
 
+               if (get_user(p, &up->clips))
+                       return -EFAULT;
+               uclips = compat_ptr(p);
                kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
                kp->clips = kclips;
                while (--n >= 0) {
-                       if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) ||
-                               copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+                       if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+                               return -EFAULT;
+                       if (put_user(n ? kclips + 1 : NULL, &kclips->next))
                                return -EFAULT;
-                       kclips->next = n ? kclips + 1 : 0;
                        uclips += 1;
                        kclips += 1;
                }
        } else
-               kp->clips = 0;
+               kp->clips = NULL;
        return 0;
 }
 
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) ||
-               copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
+       if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
                put_user(kp->field, &up->field) ||
                put_user(kp->chromakey, &up->chromakey) ||
                put_user(kp->clipcount, &up->clipcount))
@@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
 
 static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
+               return -EFAULT;
        return 0;
 }
 
@@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 
 static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_standard)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
+               return -EFAULT;
        return 0;
 
 }
 
 static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_standard)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
+               return -EFAULT;
        return 0;
 }
 
@@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
 
 static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
+               return -EFAULT;
        return 0;
 
 }
 
 static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
+               return -EFAULT;
        return 0;
 }
 
@@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                break;
        case V4L2_MEMORY_USERPTR:
                {
-               unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
+               compat_long_t tmp;
 
-               if(get_user(kp->length, &up->length) ||
-                       get_user(kp->m.userptr, &tmp))
-                               return -EFAULT;
+               if (get_user(kp->length, &up->length) ||
+                   get_user(tmp, &up->m.userptr))
+                       return -EFAULT;
+
+               kp->m.userptr = (unsigned long)compat_ptr(tmp);
                }
                break;
        case V4L2_MEMORY_OVERLAY:
@@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
 
 static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
+               return -EFAULT;
        return 0;
 }
 
 static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_input)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_input)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_input)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
+               return -EFAULT;
        return 0;
 }
 
index c66c2c1f480927b18c047c9fbcc4054868f6ba41..08ffd1f325fcc2c0f8e1c1510ee35396fcabe623 100644 (file)
@@ -220,33 +220,23 @@ static void input_change(struct i2c_client *client)
                cx25840_write(client, 0x808, 0xff);
                cx25840_write(client, 0x80b, 0x10);
        } else if (std & V4L2_STD_NTSC) {
-               /* NTSC */
-               if (state->pvr150_workaround) {
-                       /* Certain Hauppauge PVR150 models have a hardware bug
-                          that causes audio to drop out. For these models the
-                          audio standard must be set explicitly.
-                          To be precise: it affects cards with tuner models
-                          85, 99 and 112 (model numbers from tveeprom). */
-                       if (std == V4L2_STD_NTSC_M_JP) {
-                               /* Japan uses EIAJ audio standard */
-                               cx25840_write(client, 0x808, 0x2f);
-                       } else {
-                               /* Others use the BTSC audio standard */
-                               cx25840_write(client, 0x808, 0x1f);
-                       }
-                       /* South Korea uses the A2-M (aka Zweiton M) audio
-                          standard, and should set 0x808 to 0x3f, but I don't
-                          know how to detect this. */
-               } else if (std == V4L2_STD_NTSC_M_JP) {
+               /* Certain Hauppauge PVR150 models have a hardware bug
+                  that causes audio to drop out. For these models the
+                  audio standard must be set explicitly.
+                  To be precise: it affects cards with tuner models
+                  85, 99 and 112 (model numbers from tveeprom). */
+               int hw_fix = state->pvr150_workaround;
+
+               if (std == V4L2_STD_NTSC_M_JP) {
                        /* Japan uses EIAJ audio standard */
-                       cx25840_write(client, 0x808, 0xf7);
+                       cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
+               } else if (std == V4L2_STD_NTSC_M_KR) {
+                       /* South Korea uses A2 audio standard */
+                       cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
                } else {
                        /* Others use the BTSC audio standard */
-                       cx25840_write(client, 0x808, 0xf6);
+                       cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
                }
-               /* South Korea uses the A2-M (aka Zweiton M) audio standard,
-                  and should set 0x808 to 0xf8, but I don't know how to
-                  detect this. */
                cx25840_write(client, 0x80b, 0x00);
        }
 
@@ -330,17 +320,17 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
        u8 fmt=0;       /* zero is autodetect */
 
        /* First tests should be against specific std */
-       if (std & V4L2_STD_NTSC_M_JP) {
+       if (std == V4L2_STD_NTSC_M_JP) {
                fmt=0x2;
-       } else if (std & V4L2_STD_NTSC_443) {
+       } else if (std == V4L2_STD_NTSC_443) {
                fmt=0x3;
-       } else if (std & V4L2_STD_PAL_M) {
+       } else if (std == V4L2_STD_PAL_M) {
                fmt=0x5;
-       } else if (std & V4L2_STD_PAL_N) {
+       } else if (std == V4L2_STD_PAL_N) {
                fmt=0x6;
-       } else if (std & V4L2_STD_PAL_Nc) {
+       } else if (std == V4L2_STD_PAL_Nc) {
                fmt=0x7;
-       } else if (std & V4L2_STD_PAL_60) {
+       } else if (std == V4L2_STD_PAL_60) {
                fmt=0x8;
        } else {
                /* Then, test against generic ones */
@@ -369,7 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
        }
 
        switch (fmt) {
-       case 0x1: return V4L2_STD_NTSC_M;
+       case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
        case 0x2: return V4L2_STD_NTSC_M_JP;
        case 0x3: return V4L2_STD_NTSC_443;
        case 0x4: return V4L2_STD_PAL;
index 53308911ae6e56165be24601b54f6b3081d49324..e99dfbbf3e95b8b46f62c260a63f9fd8b57a9b22 100644 (file)
@@ -32,6 +32,7 @@ config VIDEO_CX88_DVB
 config VIDEO_CX88_ALSA
        tristate "ALSA DMA audio support"
        depends on VIDEO_CX88 && SND && EXPERIMENTAL
+       select SND_PCM
        ---help---
          This is a video4linux driver for direct (DMA) audio on
          Conexant 2388x based TV cards.
@@ -48,6 +49,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
        default y
        depends on VIDEO_CX88_DVB
        select DVB_MT352
+       select VIDEO_CX88_VP3054
        select DVB_OR51132
        select DVB_CX22702
        select DVB_LGDT330X
@@ -69,6 +71,16 @@ config VIDEO_CX88_DVB_MT352
          This adds DVB-T support for cards based on the
          Connexant 2388x chip and the MT352 demodulator.
 
+config VIDEO_CX88_VP3054
+       tristate "VP-3054 Secondary I2C Bus Support"
+       default m
+       depends on 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_OR51132
        bool "OR51132 ATSC Support"
        default y
index 6e5eaa22619e6fac5199b8395888d33f2d9df002..2b902784facc0d6b1cd5bcb9b6b6420346d14911 100644 (file)
@@ -4,8 +4,9 @@ cx8800-objs     := cx88-video.o cx88-vbi.o
 cx8802-objs    := cx88-mpeg.o
 
 obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
-obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
+obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
+obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
 
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -18,6 +19,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
 extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
 extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
 extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
-extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
+extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
 
 EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
index a2e36a1e5f59065c96b778b965e222bb66b1dd18..2acccd6d49bca63b3b9311ab8a6d014ded33d47c 100644 (file)
@@ -128,7 +128,7 @@ MODULE_PARM_DESC(debug,"enable debug messages");
  * BOARD Specific: Sets audio DMA
  */
 
-int _cx88_start_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
 {
        struct cx88_buffer   *buf = chip->buf;
        struct cx88_core *core=chip->core;
@@ -173,7 +173,7 @@ int _cx88_start_audio_dma(snd_cx88_card_t *chip)
 /*
  * BOARD Specific: Resets audio DMA
  */
-int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
 {
        struct cx88_core *core=chip->core;
        dprintk(1, "Stopping audio DMA\n");
@@ -613,7 +613,7 @@ static snd_kcontrol_new_t snd_cx88_capture_volume = {
  * Only boards with eeprom and byte 1 at eeprom=1 have it
  */
 
-struct pci_device_id cx88_audio_pci_tbl[] = {
+static struct pci_device_id cx88_audio_pci_tbl[] = {
        {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
        {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
        {0, }
index ad2f565f522c009fc16cff2cc9f3d24ceebdc522..1bc999247fdcbd6d9fd3fe3642a4628cac07a522 100644 (file)
@@ -1244,6 +1244,11 @@ struct cx88_subid cx88_subids[] = {
                .subvendor = 0x18ac,
                .subdevice = 0xdb50,
                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
+       },{
+               .subvendor = 0x18ac,
+               .subdevice = 0xdb54,
+               .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
+               /* Re-branded DViCO: DigitalNow DVB-T Dual */
        },{
                .subvendor = 0x18ac,
                .subdevice = 0xdb11,
@@ -1293,6 +1298,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
        switch (tv.model)
        {
        case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
+       case 34519: /* WinTV-PCI-FM */
        case 90002: /* Nova-T-PCI (9002) */
        case 92001: /* Nova-S-Plus (Video and IR) */
        case 92002: /* Nova-S-Plus (Video and IR) */
index 8d6d6a6cf7853226992eaad243526364a0d9fbe5..3720f24a25cf751744c0b389c856f6c5857d884b 100644 (file)
@@ -787,12 +787,14 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
 
 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;
        /* setup fifo + format */
-       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
-       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
+       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
+       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
 
-       cx_write(MO_AUDD_LNGTH,    128); /* fifo bpl size */
-       cx_write(MO_AUDR_LNGTH,    128); /* fifo bpl size */
+       cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
+       cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
 
        /* start dma */
        cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
index da2ad5c4b553e4b99c9a84882b221b5f2847e0e7..165d948624a3f53f9321f2f22b9a73038a118fc8 100644 (file)
@@ -482,6 +482,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        switch (core->board) {
        case CX88_BOARD_DNTV_LIVE_DVB_T:
        case CX88_BOARD_KWORLD_DVB_T:
+       case CX88_BOARD_KWORLD_DVB_T_CX22702:
                ir_codes = ir_codes_dntv_live_dvb_t;
                ir->gpio_addr = MO_GP1_IO;
                ir->mask_keycode = 0x1f;
index dff3893f32fdaa18d940f5309bd18354dbc8b3e5..e5ee8bceb210c19fa606fe7248dbbdbfbbc38d5a 100644 (file)
@@ -139,6 +139,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
 {
        int ret, byte;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
        em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
 
        ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -165,6 +168,9 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
        u8 val;
        int ret;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
        em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
 
        ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -195,7 +201,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
        int ret;
 
        /*usb_control_msg seems to expect a kmalloced buffer */
-       unsigned char *bufs = kmalloc(len, GFP_KERNEL);
+       unsigned char *bufs;
+
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
+       bufs = kmalloc(len, GFP_KERNEL);
 
        em28xx_regdbg("req=%02x reg=%02x:", req, reg);
 
@@ -212,7 +223,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
        ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                              0x0000, reg, bufs, len, HZ);
-       mdelay(5);              /* FIXME: magic number */
+       msleep(5);              /* FIXME: magic number */
        kfree(bufs);
        return ret;
 }
@@ -253,7 +264,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
        if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
                return ret;
        else if (((u8) ret) & 0x01) {
-               em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
+               em28xx_warn ("AC97 command still being executed: not handled properly!\n");
        }
        return 0;
 }
index 0591a705b7a1f9aed6f9f113610c16f7578479f8..6ca8631bc36dc98cf97c65c68bb5f20a1acb3334 100644 (file)
@@ -78,7 +78,7 @@ static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
                ret = dev->em28xx_read_reg(dev, 0x05);
                if (ret == 0x80 + len - 1)
                        return len;
-               mdelay(5);
+               msleep(5);
        }
        em28xx_warn("i2c write timed out\n");
        return -EIO;
@@ -138,7 +138,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
                        return -ENODEV;
                else if (msg == 0x84)
                        return 0;
-               mdelay(5);
+               msleep(5);
        }
        return -ENODEV;
 }
@@ -278,9 +278,9 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
                                                           msgs[i].buf,
                                                           msgs[i].len,
                                                           i == num - 1);
-                       if (rc < 0)
-                               goto err;
                }
+               if (rc < 0)
+                       goto err;
                if (i2c_debug>=2)
                        printk("\n");
        }
index eea304f75176a1ca18e38785defddb8932b61ae4..94a14a2bb6d6cee222172f6cabddbf406d53dc21 100644 (file)
@@ -6,6 +6,9 @@
                      Mauro Carvalho Chehab <mchehab@brturbo.com.br>
                      Sascha Sommer <saschasommer@freenet.de>
 
+       Some parts based on SN9C10x PC Camera Controllers GPL driver made
+               by Luca Risolia <luca.risolia@studio.unibo.it>
+
    This program is free software; 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
index c64718aec9cb84401d874c2445fd8d3cd00fde71..5a35d3b6550d9deb61dcba84b88335c06f0a7dcb 100644 (file)
@@ -136,7 +136,7 @@ struct saa7134_board saa7134_boards[] = {
        },
        [SAA7134_BOARD_FLYVIDEO2000] = {
                /* "TC Wan" <tcwan@cs.usm.my> */
-               .name           = "LifeView FlyVIDEO2000",
+               .name           = "LifeView/Typhoon FlyVIDEO2000",
                .audio_clock    = 0x00200000,
                .tuner_type     = TUNER_LG_PAL_NEW_TAPC,
                .radio_type     = UNSET,
@@ -1884,44 +1884,38 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x000,
                },
        },
-       [SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = {
-               .name           = "Typhoon DVB-T Duo Digital/Analog Cardbus",
+       [SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = {
+               .name           = "LifeView/Typhoon FlyDVB-T Duo Cardbus",
                .audio_clock    = 0x00200000,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .mpeg           = SAA7134_MPEG_DVB,
-               /* .gpiomask       = 0xe000, */
+               .gpiomask       = 0x00200000,
                .inputs         = {{
                        .name = name_tv,
                        .vmux = 1,
                        .amux = TV,
-               /*      .gpio = 0x0000,      */
+                       .gpio = 0x200000,       /* GPIO21=High for TV input */
                        .tv   = 1,
+               },{
+                       .name = name_svideo,    /* S-Video signal on S-Video input */
+                       .vmux = 8,
+                       .amux = LINE2,
                },{
                        .name = name_comp1,     /* Composite signal on S-Video input */
                        .vmux = 0,
                        .amux = LINE2,
-               /*      .gpio = 0x4000,      */
                },{
                        .name = name_comp2,     /* Composite input */
                        .vmux = 3,
                        .amux = LINE2,
-               /*      .gpio = 0x4000,      */
-               },{
-                       .name = name_svideo,    /* S-Video signal on S-Video input */
-                       .vmux = 8,
-                       .amux = LINE2,
-               /*      .gpio = 0x4000,      */
                }},
                .radio = {
                        .name = name_radio,
-                       .amux = LINE2,
-               },
-               .mute = {
-                       .name = name_mute,
-                       .amux = LINE1,
+                       .amux = TV,
+                       .gpio = 0x000000,       /* GPIO21=Low for FM radio antenna */
                },
        },
        [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
@@ -2699,6 +2693,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x5168,
                .subdevice    = 0x0138,
                .driver_data  = SAA7134_BOARD_FLYVIDEO2000,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+               .subvendor    = 0x4e42,         /* Typhoon */
+               .subdevice    = 0x0138,         /* LifeView FlyTV Prime30 OEM */
+               .driver_data  = SAA7134_BOARD_FLYVIDEO2000,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -2935,7 +2935,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x5168,
                .subdevice    = 0x0502,                /* Cardbus version */
-               .driver_data  = SAA7134_BOARD_FLYDVBTDUO,
+               .driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -2980,12 +2980,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subdevice    = 0x1370,        /* cardbus version */
                .driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
 
-       },{     /* Typhoon DVB-T Duo Digital/Analog Cardbus */
+       },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-               .subvendor    = 0x4e42,
-               .subdevice    = 0x0502,
-               .driver_data  = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
+               .subvendor    = 0x4e42,         /* Typhoon */
+               .subdevice    = 0x0502,         /* LifeView LR502 OEM */
+               .driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3206,8 +3206,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
                break;
-       case SAA7134_BOARD_FLYDVBTDUO:
-       case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+       case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
                /* turn the fan on */
                saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
                saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
index 399f9952596c30a64c46abd1162bcd7108a7e6ee..1a536e865277e79c06c541920b57a3b3c5ea6849 100644 (file)
@@ -861,7 +861,7 @@ static int dvb_init(struct saa7134_dev *dev)
                dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
                                                    &dev->i2c_adap);
                break;
-       case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+       case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
                dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
                                                    &dev->i2c_adap);
                break;
index e70eae8d29bbed0bf4cb5ff7b6afb57dacb15079..3261d8bebdd1ce828611708b2ba566fa6d41f6ad 100644 (file)
@@ -185,7 +185,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
 #define SAA7134_BOARD_ADS_INSTANT_TV 58
 #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
-#define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60
+#define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60
 #define SAA7134_BOARD_PHILIPS_TOUGH 61
 #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
 #define SAA7134_BOARD_KWORLD_XPERT 63
index 54fc33011ffb4b1b1b03cea41bea8b04eaa77c46..9d769264a32904c93a18f9f37851eba0ddbfb826 100644 (file)
@@ -2012,7 +2012,6 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
 {
        struct saa7146 *saa = pci_get_drvdata(pdev);
 
-       memset(saa, 0, sizeof(*saa));
        saa->user = 0;
        /* reset the saa7146 */
        saawrite(0xffff0000, SAA7146_MC1);
@@ -2062,16 +2061,16 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
        }
        if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {
                dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-               goto errvid;
+               goto errfree;
        }
        if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {
                dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-               goto erraud;
+               goto errfree;
        }
        /* allocate 81920 byte buffer for clipping */
        if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
                dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);
-               goto errosd;
+               goto errfree;
        }
        /* setup clipping registers */
        saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
@@ -2085,15 +2084,11 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
        I2CBusScan(saa);
 
        return 0;
-errosd:
+errfree:
        vfree(saa->osdbuf);
-       saa->osdbuf = NULL;
-erraud:
        vfree(saa->audbuf);
-       saa->audbuf = NULL;
-errvid:
        vfree(saa->vidbuf);
-       saa->vidbuf = NULL;
+       saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;
 err:
        return -ENOMEM;
 }
index 5815649bdc78e316f3fd40c655530909a3986321..0d54f6c1982bc9e66adce1d68bc2981b20e09608 100644 (file)
@@ -231,7 +231,7 @@ static struct tvnorm tvnorms[] = {
                           cAudioIF_6_5   |
                           cVideoIF_38_90 ),
        },{
-               .std   = V4L2_STD_NTSC_M,
+               .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name  = "NTSC-M",
                .b     = ( cNegativeFmTV  |
                           cQSS           ),
@@ -619,6 +619,11 @@ static int tda9887_fixup_std(struct tda9887 *t)
                        tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
                        t->std = V4L2_STD_NTSC_M_JP;
                        break;
+               case 'k':
+               case 'K':
+                       tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+                       t->std = V4L2_STD_NTSC_M_KR;
+                       break;
                case '-':
                        /* default parameter, do nothing */
                        break;
@@ -876,7 +881,7 @@ static int tda9887_resume(struct device * dev)
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-       .id             = -1, /* FIXME */
+       .id             = I2C_DRIVERID_TDA9887,
        .attach_adapter = tda9887_probe,
        .detach_client  = tda9887_detach,
        .command        = tda9887_command,
index 2995b22acb4354728c93fa2af5e07bfb1ab56846..e7ee619d62c5287171890da403c952b3c7615d65 100644 (file)
@@ -216,6 +216,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
                buffer[3] = 0xa4;
                i2c_master_send(c,buffer,4);
                default_tuner_init(c);
+               break;
        default:
                default_tuner_init(c);
                break;
@@ -365,6 +366,11 @@ static int tuner_fixup_std(struct tuner *t)
                        tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
                        t->std = V4L2_STD_NTSC_M_JP;
                        break;
+               case 'k':
+               case 'K':
+                       tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+                       t->std = V4L2_STD_NTSC_M_KR;
+                       break;
                case '-':
                        /* default parameter, do nothing */
                        break;
@@ -448,7 +454,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                        printk("%02x ",buffer[i]);
                printk("\n");
        }
-       /* TEA5767 autodetection code - only for addr = 0xc0 */
+       /* autodetection code based on the i2c addr */
        if (!no_autodetect) {
                switch (addr) {
                case 0x42:
index 6d03b9b05c6ec6b334b52c172eaec7b9ee5429f7..c8e5ad0e8185a0c2f3cea24be094148db2b928a4 100644 (file)
@@ -390,6 +390,14 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
                chip_write(chip, TDA9840_SW, t);
 }
 
+static int tda9840_checkit(struct CHIPSTATE *chip)
+{
+       int rc;
+       rc = chip_read(chip);
+       /* lower 5 bits should be 0 */
+       return ((rc & 0x1f) == 0) ? 1 : 0;
+}
+
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tda985x                */
 
@@ -1264,6 +1272,7 @@ static struct CHIPDESC chiplist[] = {
                .addr_hi    = I2C_TDA9840 >> 1,
                .registers  = 5,
 
+               .checkit    = tda9840_checkit,
                .getmode    = tda9840_getmode,
                .setmode    = tda9840_setmode,
                .checkmode  = generic_checkmode,
index fad9ea0ae4f22d73e9a8f70f82c152523b45f6d4..1864423b30465c032d347614b5b0271044e940e8 100644 (file)
@@ -746,24 +746,27 @@ static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
 
 static inline void tvp5150_reset(struct i2c_client *c)
 {
-       u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom;
+       u8 msb_id, lsb_id, msb_rom, lsb_rom;
        struct tvp5150 *decoder = i2c_get_clientdata(c);
 
-       type=tvp5150_read(c,TVP5150_AUTOSW_MSK);
        msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
        lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
        msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
        lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);
 
-       if (type==0xdc) {
-               ver_656=tvp5150_read(c,TVP5150_REV_SELECT);
-               tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656);
-       } else if (type==0xfc) {
-               tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+       if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */
+               tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id);
+
+               /* ITU-T BT.656.4 timing */
+               tvp5150_write(c,TVP5150_REV_SELECT,0);
        } else {
-               tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type);
+               if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */
+                       tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+               } else {
+                       tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id);
+                       tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom);
+               }
        }
-       tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom);
 
        /* Initializes TVP5150 to its default values */
        tvp5150_write_inittab(c, tvp5150_init_default);
@@ -893,6 +896,17 @@ static int tvp5150_command(struct i2c_client *c,
                }
        case DECODER_GET_STATUS:
                {
+                       int *iarg = arg;
+                       int status;
+                       int res=0;
+                       status = tvp5150_read(c, 0x88);
+                       if(status&0x08){
+                               res |= DECODER_STATUS_COLOR;
+                       }
+                       if(status&0x04 && status&0x02){
+                               res |= DECODER_STATUS_GOOD;
+                       }
+                       *iarg=res;
                        break;
                }
 
index 90628562851ed70dd5ee4dcf99aac4c6bdaa20fc..184974cc734de25f852d971d0983fcbc20219c10 100644 (file)
@@ -60,4 +60,7 @@ extern void i2o_iop_remove(struct i2o_controller *);
 #define I2O_IN_PORT    0x40
 #define I2O_OUT_PORT   0x44
 
+/* Motorola/Freescale specific register offset */
+#define I2O_MOTOROLA_PORT_OFFSET       0x10400
+
 #define I2O_IRQ_OUTBOUND_POST  0x00000008
index f9e5a23697a1f8ae54ae28b0d1388c492800ef25..c08ddac3717d8fb129da204b8f955fee38ea890d 100644 (file)
@@ -732,7 +732,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt)
            cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid);
        msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt));
 
-       if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
+       if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
                status = SUCCESS;
 
        return status;
index d698d7709c31c8d6073a58e3893de2c723f760f5..4f1515cae5dc94ceb589d74f3c58a3327823efe5 100644 (file)
@@ -88,6 +88,11 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
        struct device *dev = &pdev->dev;
        int i;
 
+       if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
+               printk(KERN_ERR "%s: device already claimed\n", c->name);
+               return -ENODEV;
+       }
+
        for (i = 0; i < 6; i++) {
                /* Skip I/O spaces */
                if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
@@ -163,6 +168,24 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
        c->in_port = c->base.virt + I2O_IN_PORT;
        c->out_port = c->base.virt + I2O_OUT_PORT;
 
+       /* Motorola/Freescale chip does not follow spec */
+       if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) {
+               /* Check if CPU is enabled */
+               if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) {
+                       printk(KERN_INFO "%s: MPC82XX needs CPU running to "
+                              "service I2O.\n", c->name);
+                       i2o_pci_free(c);
+                       return -ENODEV;
+               } else {
+                       c->irq_status += I2O_MOTOROLA_PORT_OFFSET;
+                       c->irq_mask += I2O_MOTOROLA_PORT_OFFSET;
+                       c->in_port += I2O_MOTOROLA_PORT_OFFSET;
+                       c->out_port += I2O_MOTOROLA_PORT_OFFSET;
+                       printk(KERN_INFO "%s: MPC82XX workarounds activated.\n",
+                              c->name);
+               }
+       }
+
        if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
                i2o_pci_free(c);
                return -ENOMEM;
@@ -298,7 +321,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
        struct i2o_controller *c;
        int rc;
        struct pci_dev *i960 = NULL;
-       int pci_dev_busy = 0;
+       int enabled = pdev->is_enabled;
 
        printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
 
@@ -308,16 +331,12 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
                return -ENODEV;
        }
 
-       if ((rc = pci_enable_device(pdev))) {
-               printk(KERN_WARNING "i2o: couldn't enable device %s\n",
-                      pci_name(pdev));
-               return rc;
-       }
-
-       if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
-               printk(KERN_ERR "i2o: device already claimed\n");
-               return -ENODEV;
-       }
+       if (!enabled)
+               if ((rc = pci_enable_device(pdev))) {
+                       printk(KERN_WARNING "i2o: couldn't enable device %s\n",
+                              pci_name(pdev));
+                       return rc;
+               }
 
        if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
                printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
@@ -395,9 +414,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
 
        if ((rc = i2o_pci_alloc(c))) {
                printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
-                      " failed\n", c->name);
-               if (rc == -ENODEV)
-                       pci_dev_busy = 1;
+                      "failed\n", c->name);
                goto free_controller;
        }
 
@@ -425,7 +442,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
        i2o_iop_free(c);
 
       disable:
-       if (!pci_dev_busy)
+       if (!enabled)
                pci_disable_device(pdev);
 
        return rc;
index c483a863b116fd6afecdfeb9372520d4987b744a..5d397b7a5497a428523b6a1c496fba62967ab703 100644 (file)
@@ -65,7 +65,7 @@ config MMC_AU1X
        depends on SOC_AU1X00 && MMC
        help
          This selects the AMD Alchemy(R) Multimedia card interface.
-         iIf you have a Alchemy platform with a MMC slot, say Y or M here.
+         If you have a Alchemy platform with a MMC slot, say Y or M here.
 
          If unsure, say N.
 
index aaf04638054e64148babae42a6e18e12079019cb..227c39a7c1b443a1ffa328391e36f991f0a102df 100644 (file)
@@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 
        u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
 
-       switch(cmd->flags) {
+       switch (mmc_rsp_type(cmd->flags)) {
        case MMC_RSP_R1:
                mmccmd |= SD_CMD_RT_1;
                break;
@@ -483,34 +483,35 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
        cmd = mrq->cmd;
        cmd->error = MMC_ERR_NONE;
 
-       if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) {
-
-               /* Techincally, we should be getting all 48 bits of the response
-                * (SD_RESP1 + SD_RESP2), but because our response omits the CRC,
-                * our data ends up being shifted 8 bits to the right.  In this case,
-                * that means that the OSR data starts at bit 31, so we can just
-                * read RESP0 and return that
-                */
-
-               cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
-       }
-       else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
-               u32 r[4];
-               int i;
-
-               r[0] = au_readl(host->iobase + SD_RESP3);
-               r[1] = au_readl(host->iobase + SD_RESP2);
-               r[2] = au_readl(host->iobase + SD_RESP1);
-               r[3] = au_readl(host->iobase + SD_RESP0);
-
-               /* The CRC is omitted from the response, so really we only got
-                * 120 bytes, but the engine expects 128 bits, so we have to shift
-                * things up
-                */
-
-               for(i = 0; i < 4; i++) {
-                       cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
-                       if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
+       if (cmd->flags & MMC_RSP_PRESENT) {
+               if (cmd->flags & MMC_RSP_136) {
+                       u32 r[4];
+                       int i;
+
+                       r[0] = au_readl(host->iobase + SD_RESP3);
+                       r[1] = au_readl(host->iobase + SD_RESP2);
+                       r[2] = au_readl(host->iobase + SD_RESP1);
+                       r[3] = au_readl(host->iobase + SD_RESP0);
+
+                       /* The CRC is omitted from the response, so really
+                        * we only got 120 bytes, but the engine expects
+                        * 128 bits, so we have to shift things up
+                        */
+
+                       for(i = 0; i < 4; i++) {
+                               cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
+                               if (i != 3)
+                                       cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
+                       }
+               } else {
+                       /* Techincally, we should be getting all 48 bits of
+                        * the response (SD_RESP1 + SD_RESP2), but because
+                        * our response omits the CRC, our data ends up
+                        * being shifted 8 bits to the right.  In this case,
+                        * that means that the OSR data starts at bit 31,
+                        * so we can just read RESP0 and return that
+                        */
+                       cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
                }
        }
 
index bfca5c176e8862c559e9f3abc1bf91c2ba9825c7..1888060c5e0c415cf5701250f845bf4d27a5e0a4 100644 (file)
@@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
 
                appcmd.opcode = MMC_APP_CMD;
                appcmd.arg = rca << 16;
-               appcmd.flags = MMC_RSP_R1;
+               appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
                appcmd.retries = 0;
                memset(appcmd.resp, 0, sizeof(appcmd.resp));
                appcmd.data = NULL;
@@ -331,7 +331,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 
        cmd.opcode = MMC_SELECT_CARD;
        cmd.arg = card->rca << 16;
-       cmd.flags = MMC_RSP_R1;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
        if (err != MMC_ERR_NONE)
@@ -358,7 +358,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
                        struct mmc_command cmd;
                        cmd.opcode = SD_APP_SET_BUS_WIDTH;
                        cmd.arg = SD_BUS_WIDTH_4;
-                       cmd.flags = MMC_RSP_R1;
+                       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
                        err = mmc_wait_for_app_cmd(host, card->rca, &cmd,
                                CMD_RETRIES);
@@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host)
 
                cmd.opcode = MMC_SELECT_CARD;
                cmd.arg = 0;
-               cmd.flags = MMC_RSP_NONE;
+               cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
 
                mmc_wait_for_cmd(host, &cmd, 0);
        }
@@ -677,7 +677,7 @@ static void mmc_idle_cards(struct mmc_host *host)
 
        cmd.opcode = MMC_GO_IDLE_STATE;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_NONE;
+       cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
 
        mmc_wait_for_cmd(host, &cmd, 0);
 
@@ -738,7 +738,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 
        cmd.opcode = MMC_SEND_OP_COND;
        cmd.arg = ocr;
-       cmd.flags = MMC_RSP_R3;
+       cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
 
        for (i = 100; i; i--) {
                err = mmc_wait_for_cmd(host, &cmd, 0);
@@ -766,7 +766,7 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 
        cmd.opcode = SD_APP_OP_COND;
        cmd.arg = ocr;
-       cmd.flags = MMC_RSP_R3;
+       cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
 
        for (i = 100; i; i--) {
                err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES);
@@ -805,7 +805,7 @@ static void mmc_discover_cards(struct mmc_host *host)
 
                cmd.opcode = MMC_ALL_SEND_CID;
                cmd.arg = 0;
-               cmd.flags = MMC_RSP_R2;
+               cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
 
                err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
                if (err == MMC_ERR_TIMEOUT) {
@@ -835,7 +835,7 @@ static void mmc_discover_cards(struct mmc_host *host)
 
                        cmd.opcode = SD_SEND_RELATIVE_ADDR;
                        cmd.arg = 0;
-                       cmd.flags = MMC_RSP_R6;
+                       cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
 
                        err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
                        if (err != MMC_ERR_NONE)
@@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host)
                } else {
                        cmd.opcode = MMC_SET_RELATIVE_ADDR;
                        cmd.arg = card->rca << 16;
-                       cmd.flags = MMC_RSP_R1;
+                       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
                        err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
                        if (err != MMC_ERR_NONE)
@@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host)
 
                cmd.opcode = MMC_SEND_CSD;
                cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R2;
+               cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
 
                err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
                if (err != MMC_ERR_NONE) {
@@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host)
 
                cmd.opcode = MMC_APP_CMD;
                cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R1;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
                err = mmc_wait_for_cmd(host, &cmd, 0);
                if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
@@ -932,7 +932,7 @@ static void mmc_read_scrs(struct mmc_host *host)
 
                cmd.opcode = SD_APP_SEND_SCR;
                cmd.arg = 0;
-               cmd.flags = MMC_RSP_R1;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
                memset(&data, 0, sizeof(struct mmc_data));
 
@@ -1003,7 +1003,7 @@ static void mmc_check_cards(struct mmc_host *host)
 
                cmd.opcode = MMC_SEND_STATUS;
                cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R1;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
                err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
                if (err == MMC_ERR_NONE)
index 5b014c370e809dc5ecfd6acd57384f6f6295877c..8eb2a2ede64b5c1272515c7f2d37150a5eb792df 100644 (file)
@@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                brq.mrq.data = &brq.data;
 
                brq.cmd.arg = req->sector << 9;
-               brq.cmd.flags = MMC_RSP_R1;
+               brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
                brq.data.timeout_ns = card->csd.tacc_ns * 10;
                brq.data.timeout_clks = card->csd.tacc_clks * 10;
                brq.data.blksz_bits = md->block_bits;
                brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
                brq.stop.opcode = MMC_STOP_TRANSMISSION;
                brq.stop.arg = 0;
-               brq.stop.flags = MMC_RSP_R1B;
+               brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
 
                if (rq_data_dir(req) == READ) {
                        brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
@@ -223,7 +223,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
                        cmd.opcode = MMC_SEND_STATUS;
                        cmd.arg = card->rca << 16;
-                       cmd.flags = MMC_RSP_R1;
+                       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",
@@ -430,7 +430,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
        mmc_card_claim_host(card);
        cmd.opcode = MMC_SET_BLOCKLEN;
        cmd.arg = 1 << md->block_bits;
-       cmd.flags = MMC_RSP_R1;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
        err = mmc_wait_for_cmd(card->host, &cmd, 5);
        mmc_card_release_host(card);
 
index 634ef53e85a50e63bbb52a5ae3008c7297a73f5d..37ee7f8dc82fe305195472e0ad5dd281e5c5f219 100644 (file)
@@ -124,15 +124,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
        }
 
        c |= cmd->opcode | MCI_CPSM_ENABLE;
-       switch (cmd->flags & MMC_RSP_MASK) {
-       case MMC_RSP_NONE:
-       default:
-               break;
-       case MMC_RSP_LONG:
-               c |= MCI_CPSM_LONGRSP;
-       case MMC_RSP_SHORT:
+       if (cmd->flags & MMC_RSP_PRESENT) {
+               if (cmd->flags & MMC_RSP_136)
+                       c |= MCI_CPSM_LONGRSP;
                c |= MCI_CPSM_RESPONSE;
-               break;
        }
        if (/*interrupt*/0)
                c |= MCI_CPSM_INTERRUPT;
index ee8f8a0420d1c7d16c164d65746f9c9411141892..285d7d0680977a6fbba99139a71a77fe7645d168 100644 (file)
@@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd,
        if (cmd->flags & MMC_RSP_BUSY)
                cmdat |= CMDAT_BUSY;
 
-       switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
-       case MMC_RSP_SHORT | MMC_RSP_CRC:
+#define RSP_TYPE(x)    ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
+       switch (RSP_TYPE(mmc_resp_type(cmd))) {
+       case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */
                cmdat |= CMDAT_RESP_SHORT;
                break;
-       case MMC_RSP_SHORT:
+       case RSP_TYPE(MMC_RSP_R3):
                cmdat |= CMDAT_RESP_R3;
                break;
-       case MMC_RSP_LONG | MMC_RSP_CRC:
+       case RSP_TYPE(MMC_RSP_R2):
                cmdat |= CMDAT_RESP_R2;
                break;
        default:
index f257576253613f6ca7d90f1fb2f9d545f2bfbfee..3be397d436fab83c9d76f5576eb5bcfda953aeeb 100644 (file)
@@ -459,7 +459,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
        /*
         * Do we expect a reply?
         */
-       if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) {
+       if (cmd->flags & MMC_RSP_PRESENT) {
                /*
                 * Read back status.
                 */
@@ -476,10 +476,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
                        cmd->error = MMC_ERR_BADCRC;
                /* All ok */
                else {
-                       if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT)
-                               wbsd_get_short_reply(host, cmd);
-                       else
+                       if (cmd->flags & MMC_RSP_136)
                                wbsd_get_long_reply(host, cmd);
+                       else
+                               wbsd_get_short_reply(host, cmd);
                }
        }
 
index effa0d7a73ac3b26e698f290a774c5c52cd69242..205bb708333502153faacef488cb0fd9da96017c 100644 (file)
@@ -301,7 +301,7 @@ config MTD_JEDEC
 
 config MTD_XIP
        bool "XIP aware MTD support"
-       depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM
+       depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP
        default y if XIP_KERNEL
        help
          This allows MTD support to work with flash memory which is also
index 701620b6baede850569e5516a1d2683a86323d6f..8b3784e2de891d0f0f8b3b2d6c84b6d3ed3019cf 100644 (file)
@@ -110,8 +110,9 @@ static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const voi
 {
        while (len > 0) {
                map_word d;
-               d.x[0] = *((uint32_t*)from)++;
+               d.x[0] = *((uint32_t*)from);
                dc21285_write32(map, d, to);
+               from += 4;
                to += 4;
                len -= 4;
        }
@@ -121,8 +122,9 @@ static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const voi
 {
        while (len > 0) {
                map_word d;
-               d.x[0] = *((uint16_t*)from)++;
+               d.x[0] = *((uint16_t*)from);
                dc21285_write16(map, d, to);
+               from += 2;
                to += 2;
                len -= 2;
        }
@@ -131,8 +133,9 @@ static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const voi
 static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 {
        map_word d;
-       d.x[0] = *((uint8_t*)from)++;
+       d.x[0] = *((uint8_t*)from);
        dc21285_write8(map, d, to);
+       from++;
        to++;
        len--;
 }
index 7488ee7f7cafa1075c6079b0f20081a614eeccb0..7f47124f118d37021cb84b467ac26d873b0d2cb4 100644 (file)
@@ -753,9 +753,11 @@ enum tx_desc_status {
 enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };
 
 struct vortex_extra_stats {
-        unsigned long tx_deferred;
-        unsigned long tx_multiple_collisions;
-        unsigned long rx_bad_ssd;
+       unsigned long tx_deferred;
+       unsigned long tx_max_collisions;
+       unsigned long tx_multiple_collisions;
+       unsigned long tx_single_collisions;
+       unsigned long rx_bad_ssd;
 };
 
 struct vortex_private {
@@ -863,12 +865,14 @@ static struct {
        const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
        { "tx_deferred" },
+       { "tx_max_collisions" },
        { "tx_multiple_collisions" },
+       { "tx_single_collisions" },
        { "rx_bad_ssd" },
 };
 
 /* number of ETHTOOL_GSTATS u64's */
-#define VORTEX_NUM_STATS     3
+#define VORTEX_NUM_STATS    5
 
 static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
                                   int chip_idx, int card_idx);
@@ -2108,9 +2112,12 @@ vortex_error(struct net_device *dev, int status)
                iowrite8(0, ioaddr + TxStatus);
                if (tx_status & 0x30) {                 /* txJabber or txUnderrun */
                        do_tx_reset = 1;
-               } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) {       /* maxCollisions */
-                       do_tx_reset = 1;
-                       reset_mask = 0x0108;            /* Reset interface logic, but not download logic */
+               } else if (tx_status & 0x08) {  /* maxCollisions */
+                       vp->xstats.tx_max_collisions++;
+                       if (vp->drv_flags & MAX_COLLISION_RESET) {
+                               do_tx_reset = 1;
+                               reset_mask = 0x0108;            /* Reset interface logic, but not download logic */
+                       }
                } else {                                                /* Merely re-enable the transmitter. */
                        iowrite16(TxEnable, ioaddr + EL3_CMD);
                }
@@ -2926,7 +2933,6 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
        EL3WINDOW(6);
        vp->stats.tx_carrier_errors             += ioread8(ioaddr + 0);
        vp->stats.tx_heartbeat_errors           += ioread8(ioaddr + 1);
-       vp->stats.collisions                    += ioread8(ioaddr + 3);
        vp->stats.tx_window_errors              += ioread8(ioaddr + 4);
        vp->stats.rx_fifo_errors                += ioread8(ioaddr + 5);
        vp->stats.tx_packets                    += ioread8(ioaddr + 6);
@@ -2939,10 +2945,15 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
        vp->stats.tx_bytes                      += ioread16(ioaddr + 12);
        /* Extra stats for get_ethtool_stats() */
        vp->xstats.tx_multiple_collisions       += ioread8(ioaddr + 2);
+       vp->xstats.tx_single_collisions         += ioread8(ioaddr + 3);
        vp->xstats.tx_deferred                  += ioread8(ioaddr + 8);
        EL3WINDOW(4);
        vp->xstats.rx_bad_ssd                   += ioread8(ioaddr + 12);
 
+       vp->stats.collisions = vp->xstats.tx_multiple_collisions
+               + vp->xstats.tx_single_collisions
+               + vp->xstats.tx_max_collisions;
+
        {
                u8 up = ioread8(ioaddr + 13);
                vp->stats.rx_bytes += (up & 0x0f) << 16;
@@ -3036,8 +3047,10 @@ static void vortex_get_ethtool_stats(struct net_device *dev,
        spin_unlock_irqrestore(&vp->lock, flags);
 
        data[0] = vp->xstats.tx_deferred;
-       data[1] = vp->xstats.tx_multiple_collisions;
-       data[2] = vp->xstats.rx_bad_ssd;
+       data[1] = vp->xstats.tx_max_collisions;
+       data[2] = vp->xstats.tx_multiple_collisions;
+       data[3] = vp->xstats.tx_single_collisions;
+       data[4] = vp->xstats.rx_bad_ssd;
 }
 
 
index adfba44dac5a009a484894fc3d36c71ae9dd6502..2beac55b57d605ec57213c52f418ae3a0ca2cc55 100644 (file)
@@ -586,6 +586,7 @@ struct rtl8139_private {
        dma_addr_t tx_bufs_dma;
        signed char phys[4];            /* MII device addresses. */
        char twistie, twist_row, twist_col;     /* Twister tune state. */
+       unsigned int watchdog_fired : 1;
        unsigned int default_port : 4;  /* Last dev->if_port value. */
        unsigned int have_thread : 1;
        spinlock_t lock;
@@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
 static void rtl8139_thread (void *_data);
+static void rtl8139_tx_timeout_task(void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data)
 {
        struct net_device *dev = _data;
        struct rtl8139_private *tp = netdev_priv(dev);
-       unsigned long thr_delay;
+       unsigned long thr_delay = next_tick;
 
-       if (rtnl_shlock_nowait() == 0) {
+       if (tp->watchdog_fired) {
+               tp->watchdog_fired = 0;
+               rtl8139_tx_timeout_task(_data);
+       } else if (rtnl_shlock_nowait() == 0) {
                rtl8139_thread_iter (dev, tp, tp->mmio_addr);
                rtnl_unlock ();
-
-               thr_delay = next_tick;
        } else {
                /* unlikely race.  mitigate with fast poll. */
                thr_delay = HZ / 2;
@@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct rtl8139_private *tp)
        if (tp->have_thread) {
                cancel_rearming_delayed_work(&tp->thread);
                tp->have_thread = 0;
-       }
+       } else
+               flush_scheduled_work();
 }
 
 static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
@@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
        /* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
-
-static void rtl8139_tx_timeout (struct net_device *dev)
+static void rtl8139_tx_timeout_task (void *_data)
 {
+       struct net_device *dev = _data;
        struct rtl8139_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        int i;
        u8 tmp8;
-       unsigned long flags;
 
        printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
                "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
@@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        if (tmp8 & CmdTxEnb)
                RTL_W8 (ChipCmd, CmdRxEnb);
 
-       spin_lock(&tp->rx_lock);
+       spin_lock_bh(&tp->rx_lock);
        /* Disable interrupts by clearing the interrupt mask. */
        RTL_W16 (IntrMask, 0x0000);
 
        /* Stop a shared interrupt from scavenging while we are. */
-       spin_lock_irqsave (&tp->lock, flags);
+       spin_lock_irq(&tp->lock);
        rtl8139_tx_clear (tp);
-       spin_unlock_irqrestore (&tp->lock, flags);
+       spin_unlock_irq(&tp->lock);
 
        /* ...and finally, reset everything */
        if (netif_running(dev)) {
                rtl8139_hw_start (dev);
                netif_wake_queue (dev);
        }
-       spin_unlock(&tp->rx_lock);
+       spin_unlock_bh(&tp->rx_lock);
 }
 
+static void rtl8139_tx_timeout (struct net_device *dev)
+{
+       struct rtl8139_private *tp = netdev_priv(dev);
+
+       if (!tp->have_thread) {
+               INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
+               schedule_delayed_work(&tp->thread, next_tick);
+       } else
+               tp->watchdog_fired = 1;
+
+}
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
index 6a6a08441804b0bd1d902f6e2d691976d5471e9b..47c72a63dfe11d67ab11dc3970096da8ce576218 100644 (file)
@@ -4,9 +4,9 @@
 #
 
 menu "Network device support"
+       depends on NET
 
 config NETDEVICES
-       depends on NET
        default y if UML
        bool "Network device support"
        ---help---
@@ -24,9 +24,6 @@ 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"
@@ -2718,8 +2715,6 @@ 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 4ff006c37626b92c8e80085480fc01f090da1cdb..e0f51afec778ef00bc2d7ecf2c3e28bf454bd549 100644 (file)
@@ -1145,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 }
 
 #define BOND_INTERSECT_FEATURES \
-       (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
+       (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
+       NETIF_F_TSO|NETIF_F_UFO)
 
 /* 
  * Compute the common dev->feature set available to all slaves.  Some
@@ -1168,6 +1169,16 @@ static int bond_compute_features(struct bonding *bond)
                          NETIF_F_HW_CSUM)))
                features &= ~NETIF_F_SG;
 
+       /* 
+        * features will include NETIF_F_TSO (NETIF_F_UFO) iff all 
+        * slave devices support NETIF_F_TSO (NETIF_F_UFO), which 
+        * implies that all slaves also support scatter-gather 
+        * (NETIF_F_SG), which implies that features also includes 
+        * NETIF_F_SG. So no need to check whether we have an  
+        * illegal combination of NETIF_F_{TSO,UFO} and 
+        * !NETIF_F_SG 
+        */
+
        features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
        bond_dev->features = features;
 
@@ -4080,6 +4091,8 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
 
 static struct ethtool_ops bond_ethtool_ops = {
        .get_tx_csum            = ethtool_op_get_tx_csum,
+       .get_tso                = ethtool_op_get_tso,
+       .get_ufo                = ethtool_op_get_ufo,
        .get_sg                 = ethtool_op_get_sg,
        .get_drvinfo            = bond_ethtool_get_drvinfo,
 };
index 32d13da43a0b6b1587186c460a6849e82ae97d81..041bcc5835575f8265adde88d1ab1fb3c3f51238 100644 (file)
@@ -260,7 +260,7 @@ static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer,
        char *ifname;
        int i, res, found, ret = count;
        struct slave *slave;
-       struct net_device *dev = 0;
+       struct net_device *dev = NULL;
        struct bonding *bond = to_bond(cd);
 
        /* Quick sanity check -- is the bond interface up? */
@@ -995,7 +995,7 @@ static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, s
                        printk(KERN_INFO DRV_NAME
                               ": %s: Setting primary slave to None.\n",
                               bond->dev->name);
-                       bond->primary_slave = 0;
+                       bond->primary_slave = NULL;
                                bond_select_active_slave(bond);
                } else {
                        printk(KERN_INFO DRV_NAME
@@ -1123,7 +1123,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b
                        printk(KERN_INFO DRV_NAME
                               ": %s: Setting active slave to None.\n",
                               bond->dev->name);
-                       bond->primary_slave = 0;
+                       bond->primary_slave = NULL;
                                bond_select_active_slave(bond);
                } else {
                        printk(KERN_INFO DRV_NAME
index bf1fd2b98bf897f5ea252caaa5856c25908ccc42..24253c807e555ec89d735d9dab12ccfb5344a9d1 100644 (file)
@@ -2752,8 +2752,6 @@ static int e100_resume(struct pci_dev *pdev)
        retval = pci_enable_wake(pdev, 0, 0);
        if (retval)
                DPRINTK(PROBE,ERR, "Error clearing wake events\n");
-       if(e100_hw_init(nic))
-               DPRINTK(HW, ERR, "e100_hw_init failed\n");
 
        netif_device_attach(netdev);
        if(netif_running(netdev))
index 0c18dbd67d3b0b95074c6e2b192d65339eaa478f..0e8e3fcde9ff9dc865a9c2170a5a4154aea52264 100644 (file)
@@ -199,8 +199,7 @@ static int gfar_probe(struct platform_device *pdev)
 
        /* get a pointer to the register memory */
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->regs = (struct gfar *)
-               ioremap(r->start, sizeof (struct gfar));
+       priv->regs = ioremap(r->start, sizeof (struct gfar));
 
        if (NULL == priv->regs) {
                err = -ENOMEM;
@@ -369,7 +368,7 @@ static int gfar_probe(struct platform_device *pdev)
        return 0;
 
 register_fail:
-       iounmap((void *) priv->regs);
+       iounmap(priv->regs);
 regs_fail:
        free_netdev(dev);
        return err;
@@ -382,7 +381,7 @@ static int gfar_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, NULL);
 
-       iounmap((void *) priv->regs);
+       iounmap(priv->regs);
        free_netdev(dev);
 
        return 0;
@@ -454,8 +453,7 @@ static void init_registers(struct net_device *dev)
 
        /* Zero out the rmon mib registers if it has them */
        if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-               memset((void *) &(priv->regs->rmon), 0,
-                      sizeof (struct rmon_mib));
+               memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib));
 
                /* Mask off the CAM interrupts */
                gfar_write(&priv->regs->rmon.cam1, 0xffffffff);
@@ -477,7 +475,7 @@ static void init_registers(struct net_device *dev)
 void gfar_halt(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        u32 tempval;
 
        /* Mask all interrupts */
@@ -507,7 +505,7 @@ void gfar_halt(struct net_device *dev)
 void stop_gfar(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        unsigned long flags;
 
        phy_stop(priv->phydev);
@@ -590,7 +588,7 @@ static void free_skb_resources(struct gfar_private *priv)
 void gfar_start(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        u32 tempval;
 
        /* Enable Rx and Tx in MACCFG1 */
@@ -624,7 +622,7 @@ int startup_gfar(struct net_device *dev)
        unsigned long vaddr;
        int i;
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        int err = 0;
        u32 rctrl = 0;
        u32 attrs = 0;
@@ -1622,7 +1620,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void adjust_link(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        unsigned long flags;
        struct phy_device *phydev = priv->phydev;
        int new_state = 0;
@@ -1703,7 +1701,7 @@ static void gfar_set_multi(struct net_device *dev)
 {
        struct dev_mc_list *mc_ptr;
        struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regs = priv->regs;
+       struct gfar __iomem *regs = priv->regs;
        u32 tempval;
 
        if(dev->flags & IFF_PROMISC) {
@@ -1842,7 +1840,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
        int idx;
        char tmpbuf[MAC_ADDR_LEN];
        u32 tempval;
-       u32 *macptr = &priv->regs->macstnaddr1;
+       u32 __iomem *macptr = &priv->regs->macstnaddr1;
 
        macptr += num*2;
 
index cb9d66ac3ab999db27455027f553c321047a4cfc..d37d5401be6ece4fb506527cb7104956b0723f50 100644 (file)
@@ -682,8 +682,8 @@ struct gfar_private {
        struct rxbd8 *cur_rx;           /* Next free rx ring entry */
        struct txbd8 *cur_tx;           /* Next free ring entry */
        struct txbd8 *dirty_tx;         /* The Ring entry to be freed. */
-       struct gfar *regs;      /* Pointer to the GFAR memory mapped Registers */
-       u32 *hash_regs[16];
+       struct gfar __iomem *regs;      /* Pointer to the GFAR memory mapped Registers */
+       u32 __iomem *hash_regs[16];
        int hash_width;
        struct net_device_stats stats; /* linux network statistics */
        struct gfar_extra_stats extra_stats;
@@ -718,14 +718,14 @@ struct gfar_private {
        uint32_t msg_enable;
 };
 
-static inline u32 gfar_read(volatile unsigned *addr)
+static inline u32 gfar_read(volatile unsigned __iomem *addr)
 {
        u32 val;
        val = in_be32(addr);
        return val;
 }
 
-static inline void gfar_write(volatile unsigned *addr, u32 val)
+static inline void gfar_write(volatile unsigned __iomem *addr, u32 val)
 {
        out_be32(addr, val);
 }
index 765e810620fe95f68834e7fede0019190609a494..5de7b2e259dcbddbbd770b340c6337282947a400 100644 (file)
@@ -144,11 +144,11 @@ static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
        u64 *extra = (u64 *) & priv->extra_stats;
 
        if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-               u32 *rmon = (u32 *) & priv->regs->rmon;
+               u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon;
                struct gfar_stats *stats = (struct gfar_stats *) buf;
 
                for (i = 0; i < GFAR_RMON_LEN; i++)
-                       stats->rmon[i] = (u64) (rmon[i]);
+                       stats->rmon[i] = (u64) gfar_read(&rmon[i]);
 
                for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
                        stats->extra[i] = extra[i];
@@ -221,11 +221,11 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi
 {
        int i;
        struct gfar_private *priv = netdev_priv(dev);
-       u32 *theregs = (u32 *) priv->regs;
+       u32 __iomem *theregs = (u32 __iomem *) priv->regs;
        u32 *buf = (u32 *) regbuf;
 
        for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
-               buf[i] = theregs[i];
+               buf[i] = gfar_read(&theregs[i]);
 }
 
 /* Convert microseconds to ethernet clock ticks, which changes
index 74e52fcbf8064d38186bab71450c57823345cc1c..c6b725529af508352698a32bca989999bc977457 100644 (file)
@@ -50,7 +50,7 @@
  * All PHY configuration is done through the TSEC1 MIIM regs */
 int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
 {
-       struct gfar_mii *regs = bus->priv;
+       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
 
        /* Set the PHY address and the register address we want to write */
        gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
@@ -70,7 +70,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
  * configuration has to be done through the TSEC1 MIIM regs */
 int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
-       struct gfar_mii *regs = bus->priv;
+       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
        u16 value;
 
        /* Set the PHY address and the register address we want to read */
@@ -94,7 +94,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 /* Reset the MIIM registers, and wait for the bus to free */
 int gfar_mdio_reset(struct mii_bus *bus)
 {
-       struct gfar_mii *regs = bus->priv;
+       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
        unsigned int timeout = PHY_INIT_TIMEOUT;
 
        spin_lock_bh(&bus->mdio_lock);
@@ -126,7 +126,7 @@ int gfar_mdio_probe(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct gianfar_mdio_data *pdata;
-       struct gfar_mii *regs;
+       struct gfar_mii __iomem *regs;
        struct mii_bus *new_bus;
        struct resource *r;
        int err = 0;
@@ -155,15 +155,14 @@ int gfar_mdio_probe(struct device *dev)
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        /* Set the PHY base address */
-       regs = (struct gfar_mii *) ioremap(r->start,
-                       sizeof (struct gfar_mii));
+       regs = ioremap(r->start, sizeof (struct gfar_mii));
 
        if (NULL == regs) {
                err = -ENOMEM;
                goto reg_map_fail;
        }
 
-       new_bus->priv = regs;
+       new_bus->priv = (void __force *)regs;
 
        new_bus->irq = pdata->irq;
 
@@ -181,7 +180,7 @@ int gfar_mdio_probe(struct device *dev)
        return 0;
 
 bus_register_fail:
-       iounmap((void *) regs);
+       iounmap(regs);
 reg_map_fail:
        kfree(new_bus);
 
@@ -197,7 +196,7 @@ int gfar_mdio_remove(struct device *dev)
 
        dev_set_drvdata(dev, NULL);
 
-       iounmap((void *) (&bus->priv));
+       iounmap((void __iomem *)bus->priv);
        bus->priv = NULL;
        kfree(bus);
 
index 3b1bef1ee21507ec9a453382ed94810d0d5053ce..77411a00d1ee6137d04b56c7c243d5e15260cbfe 100644 (file)
@@ -86,7 +86,6 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
-#include <asm/bug.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
index 7ef4b0434a3fa74cd438ce5d8abb45cc8ed5df22..c0998ef938e0042b3eb45aa4b9e460ec1531b919 100644 (file)
@@ -32,6 +32,8 @@
  */
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
index 1c6d328165bb066bd132b44c1fe4d4cbbbc0a096..0245e40b51a1f685e317f2ee4858475ea6d7ec14 100644 (file)
@@ -1610,6 +1610,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                }
                else if (!pskb_may_pull(skb, skb->len))
                        goto err;
+               else
+                       skb->ip_summed = CHECKSUM_NONE;
 
                len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2);
                if (len <= 0) {
@@ -1690,6 +1692,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                        kfree_skb(skb);
                } else {
                        skb_pull(skb, 2);       /* chop off protocol */
+                       skb_postpull_rcsum(skb, skb->data - 2, 2);
                        skb->dev = ppp->dev;
                        skb->protocol = htons(npindex_to_ethertype[npi]);
                        skb->mac.raw = skb->data;
index 2e1bed153c39c00827e2ef986bca3db3129c807d..6e1018448eea9b00a21215d3b284933ffab836a1 100644 (file)
@@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
        int i;
 
        RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed writing to the specified MII register */
                if (!(RTL_R32(PHYAR) & 0x80000000)) 
                        break;
-               udelay(100);
+               udelay(25);
        }
 }
 
@@ -499,15 +498,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr)
        int i, value = -1;
 
        RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed retrieving data from the specified MII register */
                if (RTL_R32(PHYAR) & 0x80000000) {
                        value = (int) (RTL_R32(PHYAR) & 0xFFFF);
                        break;
                }
-               udelay(100);
+               udelay(25);
        }
        return value;
 }
@@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 
                if (duplex == DUPLEX_HALF)
                        auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
+
+               if (duplex == DUPLEX_FULL)
+                       auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
        }
 
        tp->phy_auto_nego_reg = auto_nego;
index 4233ea55670f53e05f9bcc7fd4f2f1e6fba88e6f..50323941e3c0dea55d8c7357a63bc35631cae6db 100644 (file)
@@ -33,7 +33,6 @@ enum sis900_registers {
         rxcfg=0x34,             //Receive Configuration Register
         flctrl=0x38,            //Flow Control Register
         rxlen=0x3c,             //Receive Packet Length Register
-        cfgpmcsr=0x44,          //Configuration Power Management Control/Status Register
         rfcr=0x48,              //Receive Filter Control Register
         rfdr=0x4C,              //Receive Filter Data Register
         pmctrl=0xB0,            //Power Management Control Register
index f8b973a04b657adcaaaaaf4c8103c9ecea2ce4d2..cae2edf23004e9b54c571f0b23f34dbacf8a2662 100644 (file)
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/*
- * TOTEST
- *     - speed setting
- *     - suspend/resume
- */
-
 #include <linux/config.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
@@ -57,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "0.13"
+#define DRV_VERSION            "0.15"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -102,6 +96,10 @@ static int copybreak __read_mostly = 256;
 module_param(copybreak, int, 0);
 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
 
+static int disable_msi = 0;
+module_param(disable_msi, int, 0);
+MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+
 static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
@@ -198,7 +196,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 
        pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
-       vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+       vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
                (power_control & PCI_PM_CAP_PME_D3cold);
 
        pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
@@ -1834,6 +1832,8 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        u16 hwidx;
        u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
 
+       sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
        hwidx = sky2_read16(hw, STAT_PUT_IDX);
        BUG_ON(hwidx >= STATUS_RING_SIZE);
        rmb();
@@ -1913,12 +1913,10 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        }
 
 exit_loop:
-       sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
        sky2_tx_check(hw, 0, tx_done[0]);
        sky2_tx_check(hw, 1, tx_done[1]);
 
-       if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+       if (likely(work_done < to_do)) {
                /* need to restart TX timer */
                if (is_ec_a1(hw)) {
                        sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
@@ -2141,14 +2139,12 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
 
 static int sky2_reset(struct sky2_hw *hw)
 {
-       u32 ctst;
        u16 status;
        u8 t8, pmd_type;
-       int i;
-
-       ctst = sky2_read32(hw, B0_CTST);
+       int i, err;
 
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
+
        hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
        if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
                printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
@@ -2156,12 +2152,6 @@ static int sky2_reset(struct sky2_hw *hw)
                return -EOPNOTSUPP;
        }
 
-       /* ring for status responses */
-       hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
-                                        &hw->st_dma);
-       if (!hw->st_le)
-               return -ENOMEM;
-
        /* disable ASF */
        if (hw->chip_id <= CHIP_ID_YUKON_EC) {
                sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -2173,19 +2163,24 @@ static int sky2_reset(struct sky2_hw *hw)
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
        /* clear PCI errors, if any */
-       pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+       err = pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+       if (err)
+               goto pci_err;
+
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-       pci_write_config_word(hw->pdev, PCI_STATUS,
-                             status | PCI_STATUS_ERROR_BITS);
+       err = pci_write_config_word(hw->pdev, PCI_STATUS,
+                                   status | PCI_STATUS_ERROR_BITS);
+       if (err)
+               goto pci_err;
 
        sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
        /* clear any PEX errors */
-       if (is_pciex(hw)) {
-               u16 lstat;
-               pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
-                                      0xffffffffUL);
-               pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+               err = pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+                                                0xffffffffUL);
+               if (err)
+                       goto pci_err;
        }
 
        pmd_type = sky2_read8(hw, B2_PMD_TYP);
@@ -2297,6 +2292,14 @@ static int sky2_reset(struct sky2_hw *hw)
        sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
 
        return 0;
+
+pci_err:
+       /* This is to catch a BIOS bug workaround where
+        * mmconfig table doesn't have other buses.
+        */
+       printk(KERN_ERR PFX "%s: can't access PCI config space\n",
+              pci_name(hw->pdev));
+       return err;
 }
 
 static u32 sky2_supported_modes(const struct sky2_hw *hw)
@@ -2551,19 +2554,24 @@ static struct net_device_stats *sky2_get_stats(struct net_device *dev)
 static int sky2_set_mac_address(struct net_device *dev, void *p)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
-       struct sockaddr *addr = p;
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       const struct sockaddr *addr = p;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-       memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
+       memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
                    dev->dev_addr, ETH_ALEN);
-       memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
+       memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
                    dev->dev_addr, ETH_ALEN);
 
-       if (netif_running(dev))
-               sky2_phy_reinit(sky2);
+       /* virtual address for data */
+       gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+
+       /* physical address: used for pause frames */
+       gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
 
        return 0;
 }
@@ -2843,7 +2851,7 @@ static int sky2_set_coalesce(struct net_device *dev,
        if (ecmd->rx_coalesce_usecs_irq == 0)
                sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
        else {
-               sky2_write32(hw, STAT_TX_TIMER_INI,
+               sky2_write32(hw, STAT_ISR_TIMER_INI,
                             sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
                sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
        }
@@ -3055,6 +3063,61 @@ static void __devinit sky2_show_addr(struct net_device *dev)
                       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 }
 
+/* Handle software interrupt used during MSI test */
+static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id,
+                                           struct pt_regs *regs)
+{
+       struct sky2_hw *hw = dev_id;
+       u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+
+       if (status == 0)
+               return IRQ_NONE;
+
+       if (status & Y2_IS_IRQ_SW) {
+               sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+               hw->msi = 1;
+       }
+       sky2_write32(hw, B0_Y2_SP_ICR, 2);
+
+       sky2_read32(hw, B0_IMSK);
+       return IRQ_HANDLED;
+}
+
+/* Test interrupt path by forcing a a software IRQ */
+static int __devinit sky2_test_msi(struct sky2_hw *hw)
+{
+       struct pci_dev *pdev = hw->pdev;
+       int i, err;
+
+       sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+
+       err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw);
+       if (err) {
+               printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+                      pci_name(pdev), pdev->irq);
+               return err;
+       }
+
+       sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
+       wmb();
+
+       for (i = 0; i < 10; i++) {
+               barrier();
+               if (hw->msi)
+                       goto found;
+               mdelay(1);
+       }
+
+       err = -EOPNOTSUPP;
+       sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+ found:
+       sky2_write32(hw, B0_IMSK, 0);
+
+       free_irq(pdev->irq, hw);
+
+       return err;
+}
+
 static int __devinit sky2_probe(struct pci_dev *pdev,
                                const struct pci_device_id *ent)
 {
@@ -3135,6 +3198,12 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        }
        hw->pm_cap = pm_cap;
 
+       /* ring for status responses */
+       hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+                                        &hw->st_dma);
+       if (!hw->st_le)
+               goto err_out_iounmap;
+
        err = sky2_reset(hw);
        if (err)
                goto err_out_iounmap;
@@ -3169,7 +3238,22 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                }
        }
 
-       err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
+       if (!disable_msi && pci_enable_msi(pdev) == 0) {
+               err = sky2_test_msi(hw);
+               if (err == -EOPNOTSUPP) {
+                       /* MSI test failed, go back to INTx mode */
+                       printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
+                              "switching to INTx mode. Please report this failure to "
+                              "the PCI maintainer and include system chipset information.\n",
+                              pci_name(pdev));
+                       pci_disable_msi(pdev);
+               }
+               else if (err)
+                       goto err_out_unregister;
+       }
+
+       err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
+                         DRV_NAME, hw);
        if (err) {
                printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
                       pci_name(pdev), pdev->irq);
@@ -3184,6 +3268,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        return 0;
 
 err_out_unregister:
+       if (hw->msi)
+               pci_disable_msi(pdev);
        if (dev1) {
                unregister_netdev(dev1);
                free_netdev(dev1);
@@ -3226,6 +3312,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
        sky2_read8(hw, B0_CTST);
 
        free_irq(pdev->irq, hw);
+       if (hw->msi)
+               pci_disable_msi(pdev);
        pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -3263,25 +3351,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 static int sky2_resume(struct pci_dev *pdev)
 {
        struct sky2_hw *hw = pci_get_drvdata(pdev);
-       int i;
+       int i, err;
 
        pci_restore_state(pdev);
        pci_enable_wake(pdev, PCI_D0, 0);
-       sky2_set_power_state(hw, PCI_D0);
+       err = sky2_set_power_state(hw, PCI_D0);
+       if (err)
+               goto out;
 
-       sky2_reset(hw);
+       err = sky2_reset(hw);
+       if (err)
+               goto out;
 
        for (i = 0; i < 2; i++) {
                struct net_device *dev = hw->dev[i];
-               if (dev) {
-                       if (netif_running(dev)) {
-                               netif_device_attach(dev);
-                               if (sky2_up(dev))
-                                       dev_close(dev);
+               if (dev && netif_running(dev)) {
+                       netif_device_attach(dev);
+                       err = sky2_up(dev);
+                       if (err) {
+                               printk(KERN_ERR PFX "%s: could not up: %d\n",
+                                      dev->name, err);
+                               dev_close(dev);
+                               break;
                        }
                }
        }
-       return 0;
+out:
+       return err;
 }
 #endif
 
index 95518921001c47d03789ae15729234c72ecbf733..fd12c289a2387d835b9a310caaa3f30bcf1c7cd4 100644 (file)
@@ -1841,6 +1841,7 @@ struct sky2_hw {
        struct net_device    *dev[2];
 
        int                  pm_cap;
+       int                  msi;
        u8                   chip_id;
        u8                   chip_rev;
        u8                   copper;
@@ -1867,14 +1868,6 @@ static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg)
        return readb(hw->regs + reg);
 }
 
-/* This should probably go away, bus based tweeks suck */
-static inline int is_pciex(const struct sky2_hw *hw)
-{
-       u32 status;
-       pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
-       return (status & PCI_OS_PCI_X) == 0;
-}
-
 static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
 {
        writel(val, hw->regs + reg);
index f2d1dafde08773ad74107309b5e74ed9a0b60f16..e7dc653d5bd673ff10fb56970c25bc29a50a9815 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.48"
-#define DRV_MODULE_RELDATE     "Jan 16, 2006"
+#define DRV_MODULE_VERSION     "3.49"
+#define DRV_MODULE_RELDATE     "Feb 2, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -3482,6 +3482,17 @@ static void tg3_reset_task(void *_data)
        struct tg3 *tp = _data;
        unsigned int restart_timer;
 
+       tg3_full_lock(tp, 0);
+       tp->tg3_flags |= TG3_FLAG_IN_RESET_TASK;
+
+       if (!netif_running(tp->dev)) {
+               tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
+               tg3_full_unlock(tp);
+               return;
+       }
+
+       tg3_full_unlock(tp);
+
        tg3_netif_stop(tp);
 
        tg3_full_lock(tp, 1);
@@ -3494,10 +3505,12 @@ static void tg3_reset_task(void *_data)
 
        tg3_netif_start(tp);
 
-       tg3_full_unlock(tp);
-
        if (restart_timer)
                mod_timer(&tp->timer, jiffies + 1);
+
+       tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
+
+       tg3_full_unlock(tp);
 }
 
 static void tg3_tx_timeout(struct net_device *dev)
@@ -6786,6 +6799,13 @@ static int tg3_close(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
+       /* Calling flush_scheduled_work() may deadlock because
+        * linkwatch_event() may be on the workqueue and it will try to get
+        * the rtnl_lock which we are holding.
+        */
+       while (tp->tg3_flags & TG3_FLAG_IN_RESET_TASK)
+               msleep(1);
+
        netif_stop_queue(dev);
 
        del_timer_sync(&tp->timer);
@@ -10880,6 +10900,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
        if (dev) {
                struct tg3 *tp = netdev_priv(dev);
 
+               flush_scheduled_work();
                unregister_netdev(dev);
                if (tp->regs) {
                        iounmap(tp->regs);
@@ -10901,6 +10922,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
        if (!netif_running(dev))
                return 0;
 
+       flush_scheduled_work();
        tg3_netif_stop(tp);
 
        del_timer_sync(&tp->timer);
index e8243305f0e807a9433ac9e0762dc5266ff116aa..7f4b7f6ac40dec8085ac567457ce50ddb83038d3 100644 (file)
@@ -2162,6 +2162,7 @@ struct tg3 {
 #define TG3_FLAG_JUMBO_RING_ENABLE     0x00800000
 #define TG3_FLAG_10_100_ONLY           0x01000000
 #define TG3_FLAG_PAUSE_AUTONEG         0x02000000
+#define TG3_FLAG_IN_RESET_TASK         0x04000000
 #define TG3_FLAG_BROKEN_CHECKSUMS      0x10000000
 #define TG3_FLAG_GOT_SERDES_FLOWCTL    0x20000000
 #define TG3_FLAG_SPLIT_MODE            0x40000000
index 9839816668007223ebcb98dd21f7e50747542272..238e9c72cb3ab8c4f1556febafc82fb17deb2875 100644 (file)
@@ -214,7 +214,7 @@ static u32 uli526x_cr6_user_set;
 /* For module input parameter */
 static int debug;
 static u32 cr6set;
-static unsigned char mode = 8;
+static int mode = 8;
 
 /* function declaration ------------------------------------- */
 static int uli526x_open(struct net_device *);
index 2f61a47b4716947d331dca4a5e2ee2d311c05d15..1ff5de076d216ced4663d489d0be537d94ffd745 100644 (file)
@@ -1943,7 +1943,7 @@ static int dscc4_init_ring(struct net_device *dev)
                                        (++i%TX_RING_SIZE)*sizeof(*tx_fd));
        } while (i < TX_RING_SIZE);
 
-       if (dscc4_init_dummy_skb(dpriv) < 0)
+       if (!dscc4_init_dummy_skb(dpriv))
                goto err_free_dma_tx;
 
        memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE);
index 8dea07b47999c49483f556f2f32111645a68e6d7..eba8e5cfacc285c1d487d36e088556507fcbe26c 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/hdlc.h>
 #include <linux/pci.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include "hd64572.h"
index 9c1e10602f2b3ddbf1ae364021d27edab6323bad..9d3b51c3ef548f334e30f6fe9ef450deecc788ee 100644 (file)
@@ -27,8 +27,8 @@
 #include <linux/hdlc.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <asm/io.h>
-#include <asm/delay.h>
 
 #include "wanxl.h"
 
index c5cd61c7f92774043c3184b2b5b23983748adda0..e5bb9f5ae4291bf6b5e126219123e8454924bef9 100644 (file)
@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
        if (essid->length) {
                dwrq->flags = 1;        /* set ESSID to ON for Wireless Extensions */
                /* if it is to big, trunk it */
-               dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length);
+               dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length);
        } else {
                dwrq->flags = 0;
                dwrq->length = 0;
index 9e0229f7e25fbe3288e1bc12b51781868f2afa78..f46e8438e0d2439e8203be6c68471e5b8da6dc63 100644 (file)
@@ -1423,7 +1423,7 @@ static void __init ccio_init_resources(struct ioc *ioc)
        struct resource *res = ioc->mmio_region;
        char *name = kmalloc(14, GFP_KERNEL);
 
-       sprintf(name, "GSC Bus [%d/]", ioc->hw_path);
+       snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path);
 
        ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low);
        ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv);
@@ -1557,12 +1557,11 @@ static int ccio_probe(struct parisc_device *dev)
        int i;
        struct ioc *ioc, **ioc_p = &ioc_list;
        
-       ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL);
+       ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL);
        if (ioc == NULL) {
                printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
                return 1;
        }
-       memset(ioc, 0, sizeof(struct ioc));
 
        ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
@@ -1578,7 +1577,7 @@ static int ccio_probe(struct parisc_device *dev)
        ccio_ioc_init(ioc);
        ccio_init_resources(ioc);
        hppa_dma_ops = &ccio_ops;
-       dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+       dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
 
        /* if this fails, no I/O cards will work, so may as well bug */
        BUG_ON(dev->dev.platform_data == NULL);
index 216d1d859326b5119c71d4fafebf649834e93613..3d1a7f98c6763736f885ac276835b48b4d766146 100644 (file)
@@ -989,14 +989,12 @@ static int __init dino_probe(struct parisc_device *dev)
 */
        }
 
-       dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL);
+       dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL);
        if (!dino_dev) {
                printk("dino_init_chip - couldn't alloc dino_device\n");
                return 1;
        }
 
-       memset(dino_dev, 0, sizeof(struct dino_device));
-
        dino_dev->hba.dev = dev;
        dino_dev->hba.base_addr = ioremap(hpa, 4096);
        dino_dev->hba.lmmio_space_offset = 0;   /* CPU addrs == bus addrs */
index 5edf93f8075762b4c4accdd2e969879a9acfd570..07dc2b6d4e933e3ade9c442e308bd022fa3ac5dd 100644 (file)
@@ -60,12 +60,11 @@ static int hppb_probe(struct parisc_device *dev)
        }
 
        if(card->hpa) {
-               card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL);
+               card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL);
                if(!card->next) {
                        printk(KERN_ERR "HP-PB: Unable to allocate memory.\n");
                        return 1;
                }
-               memset(card->next, '\0', sizeof(struct hppb_card));
                card = card->next;
        }
         printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start);
index 19657efa8dc3989741d1df2ddd38ea8ff2b5db86..8d7a36392eb8cad7d3828c52a65ddad6a3007055 100644 (file)
@@ -873,28 +873,24 @@ void *iosapic_register(unsigned long hpa)
                return NULL;
        }
 
-       isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL);
+       isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
        if (!isi) {
                BUG();
                return NULL;
        }
 
-       memset(isi, 0, sizeof(struct iosapic_info));
-
        isi->addr = ioremap(hpa, 4096);
        isi->isi_hpa = hpa;
        isi->isi_version = iosapic_rd_version(isi);
        isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
 
        vip = isi->isi_vector = (struct vector_info *)
-               kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL);
+               kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL);
        if (vip == NULL) {
                kfree(isi);
                return NULL;
        }
 
-       memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
-
        for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
                vip->irqline = (unsigned char) cnt;
                vip->iosapic = isi;
index 2b3ba1dcf332382425bb3c387681ac9f95e701de..cb3d281761293f82eb5e7fbeec1e26d28d7bc473 100644 (file)
@@ -166,11 +166,12 @@ static void lasi_power_off(void)
 int __init
 lasi_init_chip(struct parisc_device *dev)
 {
+       extern void (*chassis_power_off)(void);
        struct gsc_asic *lasi;
        struct gsc_irq gsc_irq;
        int ret;
 
-       lasi = kmalloc(sizeof(*lasi), GFP_KERNEL);
+       lasi = kzalloc(sizeof(*lasi), GFP_KERNEL);
        if (!lasi)
                return -ENOMEM;
 
@@ -222,7 +223,7 @@ lasi_init_chip(struct parisc_device *dev)
         * ensure that only the first LASI (the one controlling the power off)
         * should set the HPA here */
        lasi_power_off_hpa = lasi->hpa;
-       pm_power_off = lasi_power_off;
+       chassis_power_off = lasi_power_off;
        
        return ret;
 }
index cbae8c8963fa3bdd163e729198b3764baafe7e28..e8a2a4a852f58a470bdce7f70d3a1c519429a4fa 100644 (file)
@@ -1565,7 +1565,7 @@ lba_driver_probe(struct parisc_device *dev)
        } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
                func_class &= 0xff;
                version = kmalloc(6, GFP_KERNEL);
-               sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf));
+               snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf));
                /* We could use one printk for both Elroy and Mercury,
                  * but for the mask for func_class.
                  */ 
@@ -1586,14 +1586,12 @@ lba_driver_probe(struct parisc_device *dev)
        **      have an IRT entry will get NULL back from iosapic code.
        */
        
-       lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL);
+       lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL);
        if (!lba_dev) {
                printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n");
                return(1);
        }
 
-       memset(lba_dev, 0, sizeof(struct lba_device));
-
 
        /* ---------- First : initialize data we already have --------- */
 
index 42a3c54e8e6ccb6d4a29983c313ecc6d078af2e8..a28e17898fbd2d2ee78480e67270312316b7e81c 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  *    Interfaces to retrieve and set PDC Stable options (firmware)
  *
- *    Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *    Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.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
  *
  *    Since locations between 96 and 192 are the various paths, most (if not
  *    all) PA-RISC machines should have them. Anyway, for safety reasons, the
- *    following code can deal with only 96 bytes of Stable Storage, and all
+ *    following code can deal with just 96 bytes of Stable Storage, and all
  *    sizes between 96 and 192 bytes (provided they are multiple of struct
  *    device_path size, eg: 128, 160 and 192) to provide full information.
  *    The code makes no use of data above 192 bytes. One last word: there's one
  *    path we can always count on: the primary path.
+ *
+ *    The current policy wrt file permissions is:
+ *     - write: root only
+ *     - read: (reading triggers PDC calls) ? root only : everyone
+ *    The rationale is that PDC calls could hog (DoS) the machine.
+ *
+ *     TODO:
+ *     - timer/fastsize write calls
  */
 
 #undef PDCS_DEBUG
 #include <linux/kobject.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/spinlock.h>
 
 #include <asm/pdc.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <asm/hardware.h>
 
-#define PDCS_VERSION   "0.10"
+#define PDCS_VERSION   "0.22"
+#define PDCS_PREFIX    "PDC Stable Storage"
 
 #define PDCS_ADDR_PPRI 0x00
 #define PDCS_ADDR_OSID 0x40
@@ -70,10 +80,12 @@ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(PDCS_VERSION);
 
+/* holds Stable Storage size. Initialized once and for all, no lock needed */
 static unsigned long pdcs_size __read_mostly;
 
 /* This struct defines what we need to deal with a parisc pdc path entry */
 struct pdcspath_entry {
+       rwlock_t rw_lock;               /* to protect path entry access */
        short ready;                    /* entry record is valid if != 0 */
        unsigned long addr;             /* entry address in stable storage */
        char *name;                     /* entry name */
@@ -121,6 +133,8 @@ struct pdcspath_attribute paths_attr_##_name = { \
  * content of the stable storage WRT various paths in these structs. We read
  * these structs when reading the files, and we will write to these structs when
  * writing to the files, and only then write them back to the Stable Storage.
+ *
+ * This function expects to be called with @entry->rw_lock write-hold.
  */
 static int
 pdcspath_fetch(struct pdcspath_entry *entry)
@@ -160,14 +174,15 @@ pdcspath_fetch(struct pdcspath_entry *entry)
  * pointer, from which it'll find out the corresponding hardware path.
  * For now we do not handle the case where there's an error in writing to the
  * Stable Storage area, so you'd better not mess up the data :P
+ *
+ * This function expects to be called with @entry->rw_lock write-hold.
  */
-static int
+static void
 pdcspath_store(struct pdcspath_entry *entry)
 {
        struct device_path *devpath;
 
-       if (!entry)
-               return -EINVAL;
+       BUG_ON(!entry);
 
        devpath = &entry->devpath;
        
@@ -176,10 +191,8 @@ pdcspath_store(struct pdcspath_entry *entry)
           First case, we don't have a preset hwpath... */
        if (!entry->ready) {
                /* ...but we have a device, map it */
-               if (entry->dev)
-                       device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
-               else
-                       return -EINVAL;
+               BUG_ON(!entry->dev);
+               device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
        }
        /* else, we expect the provided hwpath to be valid. */
        
@@ -191,15 +204,13 @@ pdcspath_store(struct pdcspath_entry *entry)
                printk(KERN_ERR "%s: an error occured when writing to PDC.\n"
                                "It is likely that the Stable Storage data has been corrupted.\n"
                                "Please check it carefully upon next reboot.\n", __func__);
-               return -EIO;
+               WARN_ON(1);
        }
                
        /* kobject is already registered */
        entry->ready = 2;
        
        DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
-       
-       return 0;
 }
 
 /**
@@ -214,14 +225,17 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf)
 {
        char *out = buf;
        struct device_path *devpath;
-       unsigned short i;
+       short i;
 
        if (!entry || !buf)
                return -EINVAL;
 
+       read_lock(&entry->rw_lock);
        devpath = &entry->devpath;
+       i = entry->ready;
+       read_unlock(&entry->rw_lock);
 
-       if (!entry->ready)
+       if (!i) /* entry is not ready */
                return -ENODATA;
        
        for (i = 0; i < 6; i++) {
@@ -242,7 +256,7 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf)
  * 
  * We will call this function to change the current hardware path.
  * Hardware paths are to be given '/'-delimited, without brackets.
- * We take care to make sure that the provided path actually maps to an existing
+ * We make sure that the provided path actually maps to an existing
  * device, BUT nothing would prevent some foolish user to set the path to some
  * PCI bridge or even a CPU...
  * A better work around would be to make sure we are at the end of a device tree
@@ -298,17 +312,19 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
        }
        
        /* So far so good, let's get in deep */
+       write_lock(&entry->rw_lock);
        entry->ready = 0;
        entry->dev = dev;
        
        /* Now, dive in. Write back to the hardware */
-       WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */
+       pdcspath_store(entry);
        
        /* Update the symlink to the real device */
        sysfs_remove_link(&entry->kobj, "device");
        sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+       write_unlock(&entry->rw_lock);
        
-       printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n",
+       printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
                entry->name, buf);
        
        return count;
@@ -326,14 +342,17 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf)
 {
        char *out = buf;
        struct device_path *devpath;
-       unsigned short i;
+       short i;
 
        if (!entry || !buf)
                return -EINVAL;
        
+       read_lock(&entry->rw_lock);
        devpath = &entry->devpath;
+       i = entry->ready;
+       read_unlock(&entry->rw_lock);
 
-       if (!entry->ready)
+       if (!i) /* entry is not ready */
                return -ENODATA;
        
        for (i = 0; devpath->layers[i] && (likely(i < 6)); i++)
@@ -388,15 +407,17 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count
        }
                
        /* So far so good, let's get in deep */
+       write_lock(&entry->rw_lock);
        
        /* First, overwrite the current layers with the new ones, not touching
           the hardware path. */
        memcpy(&entry->devpath.layers, &layers, sizeof(layers));
        
        /* Now, dive in. Write back to the hardware */
-       WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */
+       pdcspath_store(entry);
+       write_unlock(&entry->rw_lock);
        
-       printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n",
+       printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n",
                entry->name, buf);
        
        return count;
@@ -415,9 +436,6 @@ pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
        struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
        ssize_t ret = 0;
 
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-
        if (pdcs_attr->show)
                ret = pdcs_attr->show(entry, buf);
 
@@ -454,8 +472,8 @@ static struct sysfs_ops pdcspath_attr_ops = {
 };
 
 /* These are the two attributes of any PDC path. */
-static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write);
-static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write);
+static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write);
+static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write);
 
 static struct attribute *paths_subsys_attrs[] = {
        &paths_attr_hwpath.attr,
@@ -484,36 +502,119 @@ static struct pdcspath_entry *pdcspath_entries[] = {
        NULL,
 };
 
+
+/* For more insight of what's going on here, refer to PDC Procedures doc,
+ * Section PDC_STABLE */
+
 /**
- * pdcs_info_read - Pretty printing of the remaining useful data.
+ * pdcs_size_read - Stable Storage size output.
  * @entry: An allocated and populated subsytem struct. We don't use it tho.
  * @buf: The output buffer to write to.
- * 
- * We will call this function to format the output of the 'info' attribute file.
- * Please refer to PDC Procedures documentation, section PDC_STABLE to get a
- * better insight of what we're doing here.
  */
 static ssize_t
-pdcs_info_read(struct subsystem *entry, char *buf)
+pdcs_size_read(struct subsystem *entry, char *buf)
 {
        char *out = buf;
-       __u32 result;
-       struct device_path devpath;
-       char *tmpstr = NULL;
        
        if (!entry || !buf)
                return -EINVAL;
                
        /* show the size of the stable storage */
-       out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size);
+       out += sprintf(out, "%ld\n", pdcs_size);
 
-       /* deal with flags */
-       if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK)
-               return -EIO;
+       return out - buf;
+}
+
+/**
+ * pdcs_auto_read - Stable Storage autoboot/search flag output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
+ */
+static ssize_t
+pdcs_auto_read(struct subsystem *entry, char *buf, int knob)
+{
+       char *out = buf;
+       struct pdcspath_entry *pathentry;
        
-       out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off");
-       out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off");
-       out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0);
+       if (!entry || !buf)
+               return -EINVAL;
+
+       /* Current flags are stored in primary boot path entry */
+       pathentry = &pdcspath_entry_primary;
+
+       read_lock(&pathentry->rw_lock);
+       out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ?
+                                       "On" : "Off");
+       read_unlock(&pathentry->rw_lock);
+
+       return out - buf;
+}
+
+/**
+ * pdcs_autoboot_read - Stable Storage autoboot flag output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ */
+static inline ssize_t
+pdcs_autoboot_read(struct subsystem *entry, char *buf)
+{
+       return pdcs_auto_read(entry, buf, PF_AUTOBOOT);
+}
+
+/**
+ * pdcs_autosearch_read - Stable Storage autoboot flag output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ */
+static inline ssize_t
+pdcs_autosearch_read(struct subsystem *entry, char *buf)
+{
+       return pdcs_auto_read(entry, buf, PF_AUTOSEARCH);
+}
+
+/**
+ * pdcs_timer_read - Stable Storage timer count output (in seconds).
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ *
+ * The value of the timer field correponds to a number of seconds in powers of 2.
+ */
+static ssize_t
+pdcs_timer_read(struct subsystem *entry, char *buf)
+{
+       char *out = buf;
+       struct pdcspath_entry *pathentry;
+
+       if (!entry || !buf)
+               return -EINVAL;
+
+       /* Current flags are stored in primary boot path entry */
+       pathentry = &pdcspath_entry_primary;
+
+       /* print the timer value in seconds */
+       read_lock(&pathentry->rw_lock);
+       out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ?
+                               (1 << (pathentry->devpath.flags & PF_TIMER)) : 0);
+       read_unlock(&pathentry->rw_lock);
+
+       return out - buf;
+}
+
+/**
+ * pdcs_osid_read - Stable Storage OS ID register output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ */
+static ssize_t
+pdcs_osid_read(struct subsystem *entry, char *buf)
+{
+       char *out = buf;
+       __u32 result;
+       char *tmpstr = NULL;
+
+       if (!entry || !buf)
+               return -EINVAL;
 
        /* get OSID */
        if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
@@ -529,13 +630,31 @@ pdcs_info_read(struct subsystem *entry, char *buf)
                case 0x0005:    tmpstr = "Novell Netware dependent data"; break;
                default:        tmpstr = "Unknown"; break;
        }
-       out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16));
+       out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16));
+
+       return out - buf;
+}
+
+/**
+ * pdcs_fastsize_read - Stable Storage FastSize register output.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The output buffer to write to.
+ *
+ * This register holds the amount of system RAM to be tested during boot sequence.
+ */
+static ssize_t
+pdcs_fastsize_read(struct subsystem *entry, char *buf)
+{
+       char *out = buf;
+       __u32 result;
+
+       if (!entry || !buf)
+               return -EINVAL;
 
        /* get fast-size */
        if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK)
                return -EIO;
 
-       out += sprintf(out, "Memory tested: ");
        if ((result & 0x0F) < 0x0E)
                out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);
        else
@@ -546,22 +665,18 @@ pdcs_info_read(struct subsystem *entry, char *buf)
 }
 
 /**
- * pdcs_info_write - This function handles boot flag modifying.
+ * pdcs_auto_write - This function handles autoboot/search flag modifying.
  * @entry: An allocated and populated subsytem struct. We don't use it tho.
  * @buf: The input buffer to read from.
  * @count: The number of bytes to be read.
+ * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
  * 
- * We will call this function to change the current boot flags.
+ * We will call this function to change the current autoboot flag.
  * We expect a precise syntax:
- *     \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch
- *
- * As of now there is no incentive on my side to provide more "knobs" to that
- * interface, since modifying the rest of the data is pretty meaningless when
- * the machine is running and for the expected use of that facility, such as
- * PALO setting up the boot disk when installing a Linux distribution...
+ *     \"n\" (n == 0 or 1) to toggle AutoBoot Off or On
  */
 static ssize_t
-pdcs_info_write(struct subsystem *entry, const char *buf, size_t count)
+pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob)
 {
        struct pdcspath_entry *pathentry;
        unsigned char flags;
@@ -582,7 +697,9 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count)
        pathentry = &pdcspath_entry_primary;
        
        /* Be nice to the existing flag record */
+       read_lock(&pathentry->rw_lock);
        flags = pathentry->devpath.flags;
+       read_unlock(&pathentry->rw_lock);
        
        DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
                        
@@ -595,50 +712,85 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count)
        if ((c != 0) && (c != 1))
                goto parse_error;
        if (c == 0)
-               flags &= ~PF_AUTOBOOT;
+               flags &= ~knob;
        else
-               flags |= PF_AUTOBOOT;
-       
-       if (*temp++ != ' ')
-               goto parse_error;
-       
-       c = *temp++ - '0';
-       if ((c != 0) && (c != 1))
-               goto parse_error;
-       if (c == 0)
-               flags &= ~PF_AUTOSEARCH;
-       else
-               flags |= PF_AUTOSEARCH;
+               flags |= knob;
        
        DPRINTK("%s: flags after: 0x%X\n", __func__, flags);
                
        /* So far so good, let's get in deep */
+       write_lock(&pathentry->rw_lock);
        
        /* Change the path entry flags first */
        pathentry->devpath.flags = flags;
                
        /* Now, dive in. Write back to the hardware */
-       WARN_ON(pdcspath_store(pathentry));     /* this warn should *NEVER* happen */
+       pdcspath_store(pathentry);
+       write_unlock(&pathentry->rw_lock);
        
-       printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf);
+       printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n",
+               (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch",
+               (flags & knob) ? "On" : "Off");
        
        return count;
 
 parse_error:
-       printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__);
+       printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__);
        return -EINVAL;
 }
 
-/* The last attribute (the 'root' one actually) with all remaining data. */
-static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write);
+/**
+ * pdcs_autoboot_write - This function handles autoboot flag modifying.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The input buffer to read from.
+ * @count: The number of bytes to be read.
+ *
+ * We will call this function to change the current boot flags.
+ * We expect a precise syntax:
+ *     \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
+ */
+static inline ssize_t
+pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count)
+{
+       return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT);
+}
+
+/**
+ * pdcs_autosearch_write - This function handles autosearch flag modifying.
+ * @entry: An allocated and populated subsytem struct. We don't use it tho.
+ * @buf: The input buffer to read from.
+ * @count: The number of bytes to be read.
+ *
+ * We will call this function to change the current boot flags.
+ * We expect a precise syntax:
+ *     \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
+ */
+static inline ssize_t
+pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count)
+{
+       return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH);
+}
+
+/* The remaining attributes. */
+static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
+static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
+static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
+static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
+static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL);
+static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
 
 static struct subsys_attribute *pdcs_subsys_attrs[] = {
-       &pdcs_attr_info,
-       NULL,   /* maybe more in the future? */
+       &pdcs_attr_size,
+       &pdcs_attr_autoboot,
+       &pdcs_attr_autosearch,
+       &pdcs_attr_timer,
+       &pdcs_attr_osid,
+       &pdcs_attr_fastsize,
+       NULL,
 };
 
 static decl_subsys(paths, &ktype_pdcspath, NULL);
-static decl_subsys(pdc, NULL, NULL);
+static decl_subsys(stable, NULL, NULL);
 
 /**
  * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage.
@@ -656,8 +808,16 @@ pdcs_register_pathentries(void)
        struct pdcspath_entry *entry;
        int err;
        
+       /* Initialize the entries rw_lock before anything else */
+       for (i = 0; (entry = pdcspath_entries[i]); i++)
+               rwlock_init(&entry->rw_lock);
+
        for (i = 0; (entry = pdcspath_entries[i]); i++) {
-               if (pdcspath_fetch(entry) < 0)
+               write_lock(&entry->rw_lock);
+               err = pdcspath_fetch(entry);
+               write_unlock(&entry->rw_lock);
+
+               if (err < 0)
                        continue;
 
                if ((err = kobject_set_name(&entry->kobj, "%s", entry->name)))
@@ -667,13 +827,14 @@ pdcs_register_pathentries(void)
                        return err;
                
                /* kobject is now registered */
+               write_lock(&entry->rw_lock);
                entry->ready = 2;
                
-               if (!entry->dev)
-                       continue;
-
                /* Add a nice symlink to the real device */
-               sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+               if (entry->dev)
+                       sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+
+               write_unlock(&entry->rw_lock);
        }
        
        return 0;
@@ -688,14 +849,17 @@ pdcs_unregister_pathentries(void)
        unsigned short i;
        struct pdcspath_entry *entry;
        
-       for (i = 0; (entry = pdcspath_entries[i]); i++)
+       for (i = 0; (entry = pdcspath_entries[i]); i++) {
+               read_lock(&entry->rw_lock);
                if (entry->ready >= 2)
-                       kobject_unregister(&entry->kobj);       
+                       kobject_unregister(&entry->kobj);
+               read_unlock(&entry->rw_lock);
+       }
 }
 
 /*
- * For now we register the pdc subsystem with the firmware subsystem
- * and the paths subsystem with the pdc subsystem
+ * For now we register the stable subsystem with the firmware subsystem
+ * and the paths subsystem with the stable subsystem
  */
 static int __init
 pdc_stable_init(void)
@@ -707,19 +871,23 @@ pdc_stable_init(void)
        if (pdc_stable_get_size(&pdcs_size) != PDC_OK) 
                return -ENODEV;
 
-       printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION);
+       /* make sure we have enough data */
+       if (pdcs_size < 96)
+               return -ENODATA;
+
+       printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
 
-       /* For now we'll register the pdc subsys within this driver */
-       if ((rc = firmware_register(&pdc_subsys)))
+       /* For now we'll register the stable subsys within this driver */
+       if ((rc = firmware_register(&stable_subsys)))
                goto fail_firmreg;
 
-       /* Don't forget the info entry */
+       /* Don't forget the root entries */
        for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++)
                if (attr->show)
-                       error = subsys_create_file(&pdc_subsys, attr);
+                       error = subsys_create_file(&stable_subsys, attr);
        
-       /* register the paths subsys as a subsystem of pdc subsys */
-       kset_set_kset_s(&paths_subsys, pdc_subsys);
+       /* register the paths subsys as a subsystem of stable subsys */
+       kset_set_kset_s(&paths_subsys, stable_subsys);
        if ((rc= subsystem_register(&paths_subsys)))
                goto fail_subsysreg;
 
@@ -734,10 +902,10 @@ fail_pdcsreg:
        subsystem_unregister(&paths_subsys);
        
 fail_subsysreg:
-       firmware_unregister(&pdc_subsys);
+       firmware_unregister(&stable_subsys);
        
 fail_firmreg:
-       printk(KERN_INFO "PDC Stable Storage bailing out\n");
+       printk(KERN_INFO PDCS_PREFIX " bailing out\n");
        return rc;
 }
 
@@ -747,7 +915,7 @@ pdc_stable_exit(void)
        pdcs_unregister_pathentries();
        subsystem_unregister(&paths_subsys);
 
-       firmware_unregister(&pdc_subsys);
+       firmware_unregister(&stable_subsys);
 }
 
 
index c85653f315aad47be0b758863356e95b53c27b60..52f265e97729d14a32e50dd2e71f462245bf0e57 100644 (file)
@@ -2064,14 +2064,13 @@ sba_driver_callback(struct parisc_device *dev)
        printk(KERN_INFO "%s found %s at 0x%lx\n",
                MODULE_NAME, version, dev->hpa.start);
 
-       sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
+       sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
        if (!sba_dev) {
                printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
                return -ENOMEM;
        }
 
        parisc_set_drvdata(dev, sba_dev);
-       memset(sba_dev, 0, sizeof(struct sba_device));
 
        for(i=0; i<MAX_IOC; i++)
                spin_lock_init(&(sba_dev->ioc[i].res_lock));
index d14888e149bbeeb6f3c7bf517739e0be6e37b096..ba971fecd0d8c32bbf6bd4ff39a9ada45a100732 100644 (file)
@@ -89,6 +89,9 @@ static struct superio_device sio_dev;
 #define DBG_INIT(x...)
 #endif
 
+#define SUPERIO        "SuperIO"
+#define PFX    SUPERIO ": "
+
 static irqreturn_t
 superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
 {
@@ -117,7 +120,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
        local_irq = results & 0x0f;
 
        if (local_irq == 2 || local_irq > 7) {
-               printk(KERN_ERR "SuperIO: slave interrupted!\n");
+               printk(KERN_ERR PFX "slave interrupted!\n");
                return IRQ_HANDLED;
        }
 
@@ -128,7 +131,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
                outb(OCW3_ISR,IC_PIC1+0);
                results = inb(IC_PIC1+0);
                if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
-                       printk(KERN_WARNING "SuperIO: spurious interrupt!\n");
+                       printk(KERN_WARNING PFX "spurious interrupt!\n");
                        return IRQ_HANDLED;
                }
        }
@@ -163,27 +166,27 @@ superio_init(struct pci_dev *pcidev)
        /* ...then properly fixup the USB to point at suckyio PIC */
        sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
 
-       printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+       printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
               pci_name(pdev), pdev->irq);
 
        pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
        sio->sp1_base &= ~1;
-       printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base);
+       printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base);
 
        pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base);
        sio->sp2_base &= ~1;
-       printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base);
+       printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base);
 
        pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base);
        sio->pp_base &= ~1;
-       printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base);
+       printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base);
 
        pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base);
        sio->fdc_base &= ~1;
-       printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base);
+       printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base);
        pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base);
        sio->acpi_base &= ~1;
-       printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base);
+       printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base);
 
        request_region (IC_PIC1, 0x1f, "pic1");
        request_region (IC_PIC2, 0x1f, "pic2");
@@ -263,14 +266,14 @@ superio_init(struct pci_dev *pcidev)
        /* Setup USB power regulation */
        outb(1, sio->acpi_base + USB_REG_CR);
        if (inb(sio->acpi_base + USB_REG_CR) & 1)
-               printk(KERN_INFO "SuperIO: USB regulator enabled\n");
+               printk(KERN_INFO PFX "USB regulator enabled\n");
        else
-               printk(KERN_ERR "USB regulator not initialized!\n");
+               printk(KERN_ERR PFX "USB regulator not initialized!\n");
 
        if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT,
-                       "SuperIO", (void *)sio)) {
+                       SUPERIO, (void *)sio)) {
 
-               printk(KERN_ERR "SuperIO: could not get irq\n");
+               printk(KERN_ERR PFX "could not get irq\n");
                BUG();
                return;
        }
@@ -284,7 +287,7 @@ static void superio_disable_irq(unsigned int irq)
        u8 r8;
 
        if ((irq < 1) || (irq == 2) || (irq > 7)) {
-               printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+               printk(KERN_ERR PFX "Illegal irq number.\n");
                BUG();
                return;
        }
@@ -301,7 +304,7 @@ static void superio_enable_irq(unsigned int irq)
        u8 r8;
 
        if ((irq < 1) || (irq == 2) || (irq > 7)) {
-               printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq);
+               printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq);
                BUG();
                return;
        }
@@ -319,7 +322,7 @@ static unsigned int superio_startup_irq(unsigned int irq)
 }
 
 static struct hw_interrupt_type superio_interrupt_type = {
-       .typename =     "SuperIO",
+       .typename =     SUPERIO,
        .startup =      superio_startup_irq,
        .shutdown =     superio_disable_irq,
        .enable =       superio_enable_irq,
@@ -413,7 +416,7 @@ static void __devinit superio_serial_init(void)
 
        retval = early_serial_setup(&serial[0]);
        if (retval < 0) {
-               printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n");
+               printk(KERN_WARNING PFX "Register Serial #0 failed.\n");
                return;
        }
 
@@ -423,7 +426,7 @@ static void __devinit superio_serial_init(void)
        retval = early_serial_setup(&serial[1]);
 
        if (retval < 0)
-               printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n");
+               printk(KERN_WARNING PFX "Register Serial #1 failed.\n");
 #endif /* CONFIG_SERIAL_8250 */
 }
 
@@ -437,7 +440,7 @@ static void __devinit superio_parport_init(void)
                        PARPORT_DMA_NONE /* dma */,
                        NULL /*struct pci_dev* */) )
 
-               printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n");
+               printk(KERN_WARNING PFX "Probing parallel port failed.\n");
 #endif /* CONFIG_PARPORT_PC */
 }
 
@@ -499,7 +502,7 @@ static struct pci_device_id superio_tbl[] = {
 };
 
 static struct pci_driver superio_driver = {
-       .name =         "SuperIO",
+       .name =         SUPERIO,
        .id_table =     superio_tbl,
        .probe =        superio_probe,
 };
index 17dce2adf7fe9656ea328e6b0dd79df5e749e466..813c2c24ab1ef8a1273becb3dbfd2ecabcadaebf 100644 (file)
@@ -76,7 +76,7 @@ wax_init_chip(struct parisc_device *dev)
        struct gsc_irq gsc_irq;
        int ret;
 
-       wax = kmalloc(sizeof(*wax), GFP_KERNEL);
+       wax = kzalloc(sizeof(*wax), GFP_KERNEL);
        if (!wax)
                return -ENOMEM;
 
index f605dea57224ca23e5f1159c670f554104de1c21..f63c387976cf378a6f8ce78491a3d8de0f9a1c7c 100644 (file)
@@ -90,6 +90,15 @@ config PARPORT_ARC
        depends on ARM && PARPORT
        select PARPORT_NOT_PC
 
+config PARPORT_IP32
+       tristate "SGI IP32 builtin port (EXPERIMENTAL)"
+       depends on SGI_IP32 && PARPORT && EXPERIMENTAL
+       select PARPORT_NOT_PC
+       help
+         Say Y here if you need support for the parallel port on
+         SGI O2 machines. This code is also available as a module (say M),
+         called parport_ip32.  If in doubt, saying N is the safe plan.
+
 config PARPORT_AMIGA
        tristate "Amiga builtin port"
        depends on AMIGA && PARPORT
index 5372212bb9d901a77f9bd6bbba6543d28f607760..a19de35f8de262b6ca04ef9ba19c4480c9e364dd 100644 (file)
@@ -17,3 +17,4 @@ obj-$(CONFIG_PARPORT_MFC3)    += parport_mfc3.o
 obj-$(CONFIG_PARPORT_ATARI)    += parport_atari.o
 obj-$(CONFIG_PARPORT_SUNBPP)   += parport_sunbpp.o
 obj-$(CONFIG_PARPORT_GSC)      += parport_gsc.o
+obj-$(CONFIG_PARPORT_IP32)     += parport_ip32.o
index 5b887ba5aaf9e613c39939afd62c6f82febef660..690b239ad3a7c3fe5b0b7763fb3856b0d64a052e 100644 (file)
@@ -61,10 +61,10 @@ static void timeout_waiting_on_port (unsigned long cookie)
  *     set to zero, it returns immediately.
  *
  *     If an interrupt occurs before the timeout period elapses, this
- *     function returns one immediately.  If it times out, it returns
- *     a value greater than zero.  An error code less than zero
- *     indicates an error (most likely a pending signal), and the
- *     calling code should finish what it's doing as soon as it can.
+ *     function returns zero immediately.  If it times out, it returns
+ *     one.  An error code less than zero indicates an error (most
+ *     likely a pending signal), and the calling code should finish
+ *     what it's doing as soon as it can.
  */
 
 int parport_wait_event (struct parport *port, signed long timeout)
@@ -110,7 +110,7 @@ int parport_wait_event (struct parport *port, signed long timeout)
  *
  *     If the status lines take on the desired values before the
  *     timeout period elapses, parport_poll_peripheral() returns zero
- *     immediately.  A zero return value greater than zero indicates
+ *     immediately.  A return value greater than zero indicates
  *     a timeout.  An error code (less than zero) indicates an error,
  *     most likely a signal that arrived, and the caller should
  *     finish what it is doing as soon as possible.
index fde29a75f8884ddc223de82ba58c21f6a95bb2dd..1de52d9febf97a07d924bddc8bf20c7da5d84a74 100644 (file)
@@ -249,7 +249,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base,
        struct parport tmp;
        struct parport *p = &tmp;
 
-       priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL);
+       priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL);
        if (!priv) {
                printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
                return NULL;
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c
new file mode 100644 (file)
index 0000000..46e06e5
--- /dev/null
@@ -0,0 +1,2253 @@
+/* Low-level parallel port routines for built-in port on SGI IP32
+ *
+ * Author: Arnaud Giersch <arnaud.giersch@free.fr>
+ *
+ * Based on parport_pc.c by
+ *     Phil Blundell, Tim Waugh, Jose Renau, David Campbell,
+ *     Andrea Arcangeli, et al.
+ *
+ * Thanks to Ilya A. Volynets-Evenbakh for his help.
+ *
+ * Copyright (C) 2005, 2006 Arnaud Giersch.
+ *
+ * This program is free software; 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.
+ */
+
+/* Current status:
+ *
+ *     Basic SPP and PS2 modes are supported.
+ *     Support for parallel port IRQ is present.
+ *     Hardware SPP (a.k.a. compatibility), EPP, and ECP modes are
+ *     supported.
+ *     SPP/ECP FIFO can be driven in PIO or DMA mode.  PIO mode can work with
+ *     or without interrupt support.
+ *
+ *     Hardware ECP mode is not fully implemented (ecp_read_data and
+ *     ecp_write_addr are actually missing).
+ *
+ * To do:
+ *
+ *     Fully implement ECP mode.
+ *     EPP and ECP mode need to be tested.  I currently do not own any
+ *     peripheral supporting these extended mode, and cannot test them.
+ *     If DMA mode works well, decide if support for PIO FIFO modes should be
+ *     dropped.
+ *     Use the io{read,write} family functions when they become available in
+ *     the linux-mips.org tree.  Note: the MIPS specific functions readsb()
+ *     and writesb() are to be translated by ioread8_rep() and iowrite8_rep()
+ *     respectively.
+ */
+
+/* The built-in parallel port on the SGI 02 workstation (a.k.a. IP32) is an
+ * IEEE 1284 parallel port driven by a Texas Instrument TL16PIR552PH chip[1].
+ * This chip supports SPP, bidirectional, EPP and ECP modes.  It has a 16 byte
+ * FIFO buffer and supports DMA transfers.
+ *
+ * [1] http://focus.ti.com/docs/prod/folders/print/tl16pir552.html
+ *
+ * Theoretically, we could simply use the parport_pc module.  It is however
+ * not so simple.  The parport_pc code assumes that the parallel port
+ * registers are port-mapped.  On the O2, they are memory-mapped.
+ * Furthermore, each register is replicated on 256 consecutive addresses (as
+ * it is for the built-in serial ports on the same chip).
+ */
+
+/*--- Some configuration defines ---------------------------------------*/
+
+/* DEBUG_PARPORT_IP32
+ *     0       disable debug
+ *     1       standard level: pr_debug1 is enabled
+ *     2       parport_ip32_dump_state is enabled
+ *     >=3     verbose level: pr_debug is enabled
+ */
+#if !defined(DEBUG_PARPORT_IP32)
+#      define DEBUG_PARPORT_IP32  0    /* 0 (disabled) for production */
+#endif
+
+/*----------------------------------------------------------------------*/
+
+/* Setup DEBUG macros.  This is done before any includes, just in case we
+ * activate pr_debug() with DEBUG_PARPORT_IP32 >= 3.
+ */
+#if DEBUG_PARPORT_IP32 == 1
+#      warning DEBUG_PARPORT_IP32 == 1
+#elif DEBUG_PARPORT_IP32 == 2
+#      warning DEBUG_PARPORT_IP32 == 2
+#elif DEBUG_PARPORT_IP32 >= 3
+#      warning DEBUG_PARPORT_IP32 >= 3
+#      if !defined(DEBUG)
+#              define DEBUG /* enable pr_debug() in kernel.h */
+#      endif
+#endif
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parport.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/ip32/mace.h>
+
+/*--- Global variables -------------------------------------------------*/
+
+/* Verbose probing on by default for debugging. */
+#if DEBUG_PARPORT_IP32 >= 1
+#      define DEFAULT_VERBOSE_PROBING  1
+#else
+#      define DEFAULT_VERBOSE_PROBING  0
+#endif
+
+/* Default prefix for printk */
+#define PPIP32 "parport_ip32: "
+
+/*
+ * These are the module parameters:
+ * @features:          bit mask of features to enable/disable
+ *                     (all enabled by default)
+ * @verbose_probing:   log chit-chat during initialization
+ */
+#define PARPORT_IP32_ENABLE_IRQ        (1U << 0)
+#define PARPORT_IP32_ENABLE_DMA        (1U << 1)
+#define PARPORT_IP32_ENABLE_SPP        (1U << 2)
+#define PARPORT_IP32_ENABLE_EPP        (1U << 3)
+#define PARPORT_IP32_ENABLE_ECP        (1U << 4)
+static unsigned int features = ~0U;
+static int verbose_probing =   DEFAULT_VERBOSE_PROBING;
+
+/* We do not support more than one port. */
+static struct parport *this_port = NULL;
+
+/* Timing constants for FIFO modes.  */
+#define FIFO_NFAULT_TIMEOUT    100     /* milliseconds */
+#define FIFO_POLLING_INTERVAL  50      /* microseconds */
+
+/*--- I/O register definitions -----------------------------------------*/
+
+/**
+ * struct parport_ip32_regs - virtual addresses of parallel port registers
+ * @data:      Data Register
+ * @dsr:       Device Status Register
+ * @dcr:       Device Control Register
+ * @eppAddr:   EPP Address Register
+ * @eppData0:  EPP Data Register 0
+ * @eppData1:  EPP Data Register 1
+ * @eppData2:  EPP Data Register 2
+ * @eppData3:  EPP Data Register 3
+ * @ecpAFifo:  ECP Address FIFO
+ * @fifo:      General FIFO register.  The same address is used for:
+ *             - cFifo, the Parallel Port DATA FIFO
+ *             - ecpDFifo, the ECP Data FIFO
+ *             - tFifo, the ECP Test FIFO
+ * @cnfgA:     Configuration Register A
+ * @cnfgB:     Configuration Register B
+ * @ecr:       Extended Control Register
+ */
+struct parport_ip32_regs {
+       void __iomem *data;
+       void __iomem *dsr;
+       void __iomem *dcr;
+       void __iomem *eppAddr;
+       void __iomem *eppData0;
+       void __iomem *eppData1;
+       void __iomem *eppData2;
+       void __iomem *eppData3;
+       void __iomem *ecpAFifo;
+       void __iomem *fifo;
+       void __iomem *cnfgA;
+       void __iomem *cnfgB;
+       void __iomem *ecr;
+};
+
+/* Device Status Register */
+#define DSR_nBUSY              (1U << 7)       /* PARPORT_STATUS_BUSY */
+#define DSR_nACK               (1U << 6)       /* PARPORT_STATUS_ACK */
+#define DSR_PERROR             (1U << 5)       /* PARPORT_STATUS_PAPEROUT */
+#define DSR_SELECT             (1U << 4)       /* PARPORT_STATUS_SELECT */
+#define DSR_nFAULT             (1U << 3)       /* PARPORT_STATUS_ERROR */
+#define DSR_nPRINT             (1U << 2)       /* specific to TL16PIR552 */
+/* #define DSR_reserved                (1U << 1) */
+#define DSR_TIMEOUT            (1U << 0)       /* EPP timeout */
+
+/* Device Control Register */
+/* #define DCR_reserved                (1U << 7) | (1U <<  6) */
+#define DCR_DIR                        (1U << 5)       /* direction */
+#define DCR_IRQ                        (1U << 4)       /* interrupt on nAck */
+#define DCR_SELECT             (1U << 3)       /* PARPORT_CONTROL_SELECT */
+#define DCR_nINIT              (1U << 2)       /* PARPORT_CONTROL_INIT */
+#define DCR_AUTOFD             (1U << 1)       /* PARPORT_CONTROL_AUTOFD */
+#define DCR_STROBE             (1U << 0)       /* PARPORT_CONTROL_STROBE */
+
+/* ECP Configuration Register A */
+#define CNFGA_IRQ              (1U << 7)
+#define CNFGA_ID_MASK          ((1U << 6) | (1U << 5) | (1U << 4))
+#define CNFGA_ID_SHIFT         4
+#define CNFGA_ID_16            (00U << CNFGA_ID_SHIFT)
+#define CNFGA_ID_8             (01U << CNFGA_ID_SHIFT)
+#define CNFGA_ID_32            (02U << CNFGA_ID_SHIFT)
+/* #define CNFGA_reserved      (1U << 3) */
+#define CNFGA_nBYTEINTRANS     (1U << 2)
+#define CNFGA_PWORDLEFT                ((1U << 1) | (1U << 0))
+
+/* ECP Configuration Register B */
+#define CNFGB_COMPRESS         (1U << 7)
+#define CNFGB_INTRVAL          (1U << 6)
+#define CNFGB_IRQ_MASK         ((1U << 5) | (1U << 4) | (1U << 3))
+#define CNFGB_IRQ_SHIFT                3
+#define CNFGB_DMA_MASK         ((1U << 2) | (1U << 1) | (1U << 0))
+#define CNFGB_DMA_SHIFT                0
+
+/* Extended Control Register */
+#define ECR_MODE_MASK          ((1U << 7) | (1U << 6) | (1U << 5))
+#define ECR_MODE_SHIFT         5
+#define ECR_MODE_SPP           (00U << ECR_MODE_SHIFT)
+#define ECR_MODE_PS2           (01U << ECR_MODE_SHIFT)
+#define ECR_MODE_PPF           (02U << ECR_MODE_SHIFT)
+#define ECR_MODE_ECP           (03U << ECR_MODE_SHIFT)
+#define ECR_MODE_EPP           (04U << ECR_MODE_SHIFT)
+/* #define ECR_MODE_reserved   (05U << ECR_MODE_SHIFT) */
+#define ECR_MODE_TST           (06U << ECR_MODE_SHIFT)
+#define ECR_MODE_CFG           (07U << ECR_MODE_SHIFT)
+#define ECR_nERRINTR           (1U << 4)
+#define ECR_DMAEN              (1U << 3)
+#define ECR_SERVINTR           (1U << 2)
+#define ECR_F_FULL             (1U << 1)
+#define ECR_F_EMPTY            (1U << 0)
+
+/*--- Private data -----------------------------------------------------*/
+
+/**
+ * enum parport_ip32_irq_mode - operation mode of interrupt handler
+ * @PARPORT_IP32_IRQ_FWD:      forward interrupt to the upper parport layer
+ * @PARPORT_IP32_IRQ_HERE:     interrupt is handled locally
+ */
+enum parport_ip32_irq_mode { PARPORT_IP32_IRQ_FWD, PARPORT_IP32_IRQ_HERE };
+
+/**
+ * struct parport_ip32_private - private stuff for &struct parport
+ * @regs:              register addresses
+ * @dcr_cache:         cached contents of DCR
+ * @dcr_writable:      bit mask of writable DCR bits
+ * @pword:             number of bytes per PWord
+ * @fifo_depth:                number of PWords that FIFO will hold
+ * @readIntrThreshold: minimum number of PWords we can read
+ *                     if we get an interrupt
+ * @writeIntrThreshold:        minimum number of PWords we can write
+ *                     if we get an interrupt
+ * @irq_mode:          operation mode of interrupt handler for this port
+ * @irq_complete:      mutex used to wait for an interrupt to occur
+ */
+struct parport_ip32_private {
+       struct parport_ip32_regs        regs;
+       unsigned int                    dcr_cache;
+       unsigned int                    dcr_writable;
+       unsigned int                    pword;
+       unsigned int                    fifo_depth;
+       unsigned int                    readIntrThreshold;
+       unsigned int                    writeIntrThreshold;
+       enum parport_ip32_irq_mode      irq_mode;
+       struct completion               irq_complete;
+};
+
+/*--- Debug code -------------------------------------------------------*/
+
+/*
+ * pr_debug1 - print debug messages
+ *
+ * This is like pr_debug(), but is defined for %DEBUG_PARPORT_IP32 >= 1
+ */
+#if DEBUG_PARPORT_IP32 >= 1
+#      define pr_debug1(...)   printk(KERN_DEBUG __VA_ARGS__)
+#else /* DEBUG_PARPORT_IP32 < 1 */
+#      define pr_debug1(...)   do { } while (0)
+#endif
+
+/*
+ * pr_trace, pr_trace1 - trace function calls
+ * @p:         pointer to &struct parport
+ * @fmt:       printk format string
+ * @...:       parameters for format string
+ *
+ * Macros used to trace function calls.  The given string is formatted after
+ * function name.  pr_trace() uses pr_debug(), and pr_trace1() uses
+ * pr_debug1().  __pr_trace() is the low-level macro and is not to be used
+ * directly.
+ */
+#define __pr_trace(pr, p, fmt, ...)                                    \
+       pr("%s: %s" fmt "\n",                                           \
+          ({ const struct parport *__p = (p);                          \
+                  __p ? __p->name : "parport_ip32"; }),                \
+          __func__ , ##__VA_ARGS__)
+#define pr_trace(p, fmt, ...)  __pr_trace(pr_debug, p, fmt , ##__VA_ARGS__)
+#define pr_trace1(p, fmt, ...) __pr_trace(pr_debug1, p, fmt , ##__VA_ARGS__)
+
+/*
+ * __pr_probe, pr_probe - print message if @verbose_probing is true
+ * @p:         pointer to &struct parport
+ * @fmt:       printk format string
+ * @...:       parameters for format string
+ *
+ * For new lines, use pr_probe().  Use __pr_probe() for continued lines.
+ */
+#define __pr_probe(...)                                                        \
+       do { if (verbose_probing) printk(__VA_ARGS__); } while (0)
+#define pr_probe(p, fmt, ...)                                          \
+       __pr_probe(KERN_INFO PPIP32 "0x%lx: " fmt, (p)->base , ##__VA_ARGS__)
+
+/*
+ * parport_ip32_dump_state - print register status of parport
+ * @p:         pointer to &struct parport
+ * @str:       string to add in message
+ * @show_ecp_config:   shall we dump ECP configuration registers too?
+ *
+ * This function is only here for debugging purpose, and should be used with
+ * care.  Reading the parallel port registers may have undesired side effects.
+ * Especially if @show_ecp_config is true, the parallel port is resetted.
+ * This function is only defined if %DEBUG_PARPORT_IP32 >= 2.
+ */
+#if DEBUG_PARPORT_IP32 >= 2
+static void parport_ip32_dump_state(struct parport *p, char *str,
+                                   unsigned int show_ecp_config)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       unsigned int i;
+
+       printk(KERN_DEBUG PPIP32 "%s: state (%s):\n", p->name, str);
+       {
+               static const char ecr_modes[8][4] = {"SPP", "PS2", "PPF",
+                                                    "ECP", "EPP", "???",
+                                                    "TST", "CFG"};
+               unsigned int ecr = readb(priv->regs.ecr);
+               printk(KERN_DEBUG PPIP32 "    ecr=0x%02x", ecr);
+               printk(" %s",
+                      ecr_modes[(ecr & ECR_MODE_MASK) >> ECR_MODE_SHIFT]);
+               if (ecr & ECR_nERRINTR)
+                       printk(",nErrIntrEn");
+               if (ecr & ECR_DMAEN)
+                       printk(",dmaEn");
+               if (ecr & ECR_SERVINTR)
+                       printk(",serviceIntr");
+               if (ecr & ECR_F_FULL)
+                       printk(",f_full");
+               if (ecr & ECR_F_EMPTY)
+                       printk(",f_empty");
+               printk("\n");
+       }
+       if (show_ecp_config) {
+               unsigned int oecr, cnfgA, cnfgB;
+               oecr = readb(priv->regs.ecr);
+               writeb(ECR_MODE_PS2, priv->regs.ecr);
+               writeb(ECR_MODE_CFG, priv->regs.ecr);
+               cnfgA = readb(priv->regs.cnfgA);
+               cnfgB = readb(priv->regs.cnfgB);
+               writeb(ECR_MODE_PS2, priv->regs.ecr);
+               writeb(oecr, priv->regs.ecr);
+               printk(KERN_DEBUG PPIP32 "    cnfgA=0x%02x", cnfgA);
+               printk(" ISA-%s", (cnfgA & CNFGA_IRQ) ? "Level" : "Pulses");
+               switch (cnfgA & CNFGA_ID_MASK) {
+               case CNFGA_ID_8:
+                       printk(",8 bits");
+                       break;
+               case CNFGA_ID_16:
+                       printk(",16 bits");
+                       break;
+               case CNFGA_ID_32:
+                       printk(",32 bits");
+                       break;
+               default:
+                       printk(",unknown ID");
+                       break;
+               }
+               if (!(cnfgA & CNFGA_nBYTEINTRANS))
+                       printk(",ByteInTrans");
+               if ((cnfgA & CNFGA_ID_MASK) != CNFGA_ID_8)
+                       printk(",%d byte%s left", cnfgA & CNFGA_PWORDLEFT,
+                              ((cnfgA & CNFGA_PWORDLEFT) > 1) ? "s" : "");
+               printk("\n");
+               printk(KERN_DEBUG PPIP32 "    cnfgB=0x%02x", cnfgB);
+               printk(" irq=%u,dma=%u",
+                      (cnfgB & CNFGB_IRQ_MASK) >> CNFGB_IRQ_SHIFT,
+                      (cnfgB & CNFGB_DMA_MASK) >> CNFGB_DMA_SHIFT);
+               printk(",intrValue=%d", !!(cnfgB & CNFGB_INTRVAL));
+               if (cnfgB & CNFGB_COMPRESS)
+                       printk(",compress");
+               printk("\n");
+       }
+       for (i = 0; i < 2; i++) {
+               unsigned int dcr = i ? priv->dcr_cache : readb(priv->regs.dcr);
+               printk(KERN_DEBUG PPIP32 "    dcr(%s)=0x%02x",
+                      i ? "soft" : "hard", dcr);
+               printk(" %s", (dcr & DCR_DIR) ? "rev" : "fwd");
+               if (dcr & DCR_IRQ)
+                       printk(",ackIntEn");
+               if (!(dcr & DCR_SELECT))
+                       printk(",nSelectIn");
+               if (dcr & DCR_nINIT)
+                       printk(",nInit");
+               if (!(dcr & DCR_AUTOFD))
+                       printk(",nAutoFD");
+               if (!(dcr & DCR_STROBE))
+                       printk(",nStrobe");
+               printk("\n");
+       }
+#define sep (f++ ? ',' : ' ')
+       {
+               unsigned int f = 0;
+               unsigned int dsr = readb(priv->regs.dsr);
+               printk(KERN_DEBUG PPIP32 "    dsr=0x%02x", dsr);
+               if (!(dsr & DSR_nBUSY))
+                       printk("%cBusy", sep);
+               if (dsr & DSR_nACK)
+                       printk("%cnAck", sep);
+               if (dsr & DSR_PERROR)
+                       printk("%cPError", sep);
+               if (dsr & DSR_SELECT)
+                       printk("%cSelect", sep);
+               if (dsr & DSR_nFAULT)
+                       printk("%cnFault", sep);
+               if (!(dsr & DSR_nPRINT))
+                       printk("%c(Print)", sep);
+               if (dsr & DSR_TIMEOUT)
+                       printk("%cTimeout", sep);
+               printk("\n");
+       }
+#undef sep
+}
+#else /* DEBUG_PARPORT_IP32 < 2 */
+#define parport_ip32_dump_state(...)   do { } while (0)
+#endif
+
+/*
+ * CHECK_EXTRA_BITS - track and log extra bits
+ * @p:         pointer to &struct parport
+ * @b:         byte to inspect
+ * @m:         bit mask of authorized bits
+ *
+ * This is used to track and log extra bits that should not be there in
+ * parport_ip32_write_control() and parport_ip32_frob_control().  It is only
+ * defined if %DEBUG_PARPORT_IP32 >= 1.
+ */
+#if DEBUG_PARPORT_IP32 >= 1
+#define CHECK_EXTRA_BITS(p, b, m)                                      \
+       do {                                                            \
+               unsigned int __b = (b), __m = (m);                      \
+               if (__b & ~__m)                                         \
+                       pr_debug1(PPIP32 "%s: extra bits in %s(%s): "   \
+                                 "0x%02x/0x%02x\n",                    \
+                                 (p)->name, __func__, #b, __b, __m);   \
+       } while (0)
+#else /* DEBUG_PARPORT_IP32 < 1 */
+#define CHECK_EXTRA_BITS(...)  do { } while (0)
+#endif
+
+/*--- IP32 parallel port DMA operations --------------------------------*/
+
+/**
+ * struct parport_ip32_dma_data - private data needed for DMA operation
+ * @dir:       DMA direction (from or to device)
+ * @buf:       buffer physical address
+ * @len:       buffer length
+ * @next:      address of next bytes to DMA transfer
+ * @left:      number of bytes remaining
+ * @ctx:       next context to write (0: context_a; 1: context_b)
+ * @irq_on:    are the DMA IRQs currently enabled?
+ * @lock:      spinlock to protect access to the structure
+ */
+struct parport_ip32_dma_data {
+       enum dma_data_direction         dir;
+       dma_addr_t                      buf;
+       dma_addr_t                      next;
+       size_t                          len;
+       size_t                          left;
+       unsigned int                    ctx;
+       unsigned int                    irq_on;
+       spinlock_t                      lock;
+};
+static struct parport_ip32_dma_data parport_ip32_dma;
+
+/**
+ * parport_ip32_dma_setup_context - setup next DMA context
+ * @limit:     maximum data size for the context
+ *
+ * The alignment constraints must be verified in caller function, and the
+ * parameter @limit must be set accordingly.
+ */
+static void parport_ip32_dma_setup_context(unsigned int limit)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&parport_ip32_dma.lock, flags);
+       if (parport_ip32_dma.left > 0) {
+               /* Note: ctxreg is "volatile" here only because
+                * mace->perif.ctrl.parport.context_a and context_b are
+                * "volatile".  */
+               volatile u64 __iomem *ctxreg = (parport_ip32_dma.ctx == 0) ?
+                       &mace->perif.ctrl.parport.context_a :
+                       &mace->perif.ctrl.parport.context_b;
+               u64 count;
+               u64 ctxval;
+               if (parport_ip32_dma.left <= limit) {
+                       count = parport_ip32_dma.left;
+                       ctxval = MACEPAR_CONTEXT_LASTFLAG;
+               } else {
+                       count = limit;
+                       ctxval = 0;
+               }
+
+               pr_trace(NULL,
+                        "(%u): 0x%04x:0x%04x, %u -> %u%s",
+                        limit,
+                        (unsigned int)parport_ip32_dma.buf,
+                        (unsigned int)parport_ip32_dma.next,
+                        (unsigned int)count,
+                        parport_ip32_dma.ctx, ctxval ? "*" : "");
+
+               ctxval |= parport_ip32_dma.next &
+                       MACEPAR_CONTEXT_BASEADDR_MASK;
+               ctxval |= ((count - 1) << MACEPAR_CONTEXT_DATALEN_SHIFT) &
+                       MACEPAR_CONTEXT_DATALEN_MASK;
+               writeq(ctxval, ctxreg);
+               parport_ip32_dma.next += count;
+               parport_ip32_dma.left -= count;
+               parport_ip32_dma.ctx ^= 1U;
+       }
+       /* If there is nothing more to send, disable IRQs to avoid to
+        * face an IRQ storm which can lock the machine.  Disable them
+        * only once. */
+       if (parport_ip32_dma.left == 0 && parport_ip32_dma.irq_on) {
+               pr_debug(PPIP32 "IRQ off (ctx)\n");
+               disable_irq_nosync(MACEISA_PAR_CTXA_IRQ);
+               disable_irq_nosync(MACEISA_PAR_CTXB_IRQ);
+               parport_ip32_dma.irq_on = 0;
+       }
+       spin_unlock_irqrestore(&parport_ip32_dma.lock, flags);
+}
+
+/**
+ * parport_ip32_dma_interrupt - DMA interrupt handler
+ * @irq:       interrupt number
+ * @dev_id:    unused
+ * @regs:      pointer to &struct pt_regs
+ */
+static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id,
+                                             struct pt_regs *regs)
+{
+       if (parport_ip32_dma.left)
+               pr_trace(NULL, "(%d): ctx=%d", irq, parport_ip32_dma.ctx);
+       parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND);
+       return IRQ_HANDLED;
+}
+
+#if DEBUG_PARPORT_IP32
+static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id,
+                                              struct pt_regs *regs)
+{
+       pr_trace1(NULL, "(%d)", irq);
+       return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * parport_ip32_dma_start - begins a DMA transfer
+ * @dir:       DMA direction: DMA_TO_DEVICE or DMA_FROM_DEVICE
+ * @addr:      pointer to data buffer
+ * @count:     buffer size
+ *
+ * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be
+ * correctly balanced.
+ */
+static int parport_ip32_dma_start(enum dma_data_direction dir,
+                                 void *addr, size_t count)
+{
+       unsigned int limit;
+       u64 ctrl;
+
+       pr_trace(NULL, "(%d, %lu)", dir, (unsigned long)count);
+
+       /* FIXME - add support for DMA_FROM_DEVICE.  In this case, buffer must
+        * be 64 bytes aligned. */
+       BUG_ON(dir != DMA_TO_DEVICE);
+
+       /* Reset DMA controller */
+       ctrl = MACEPAR_CTLSTAT_RESET;
+       writeq(ctrl, &mace->perif.ctrl.parport.cntlstat);
+
+       /* DMA IRQs should normally be enabled */
+       if (!parport_ip32_dma.irq_on) {
+               WARN_ON(1);
+               enable_irq(MACEISA_PAR_CTXA_IRQ);
+               enable_irq(MACEISA_PAR_CTXB_IRQ);
+               parport_ip32_dma.irq_on = 1;
+       }
+
+       /* Prepare DMA pointers */
+       parport_ip32_dma.dir = dir;
+       parport_ip32_dma.buf = dma_map_single(NULL, addr, count, dir);
+       parport_ip32_dma.len = count;
+       parport_ip32_dma.next = parport_ip32_dma.buf;
+       parport_ip32_dma.left = parport_ip32_dma.len;
+       parport_ip32_dma.ctx = 0;
+
+       /* Setup DMA direction and first two contexts */
+       ctrl = (dir == DMA_TO_DEVICE) ? 0 : MACEPAR_CTLSTAT_DIRECTION;
+       writeq(ctrl, &mace->perif.ctrl.parport.cntlstat);
+       /* Single transfer should not cross a 4K page boundary */
+       limit = MACEPAR_CONTEXT_DATA_BOUND -
+               (parport_ip32_dma.next & (MACEPAR_CONTEXT_DATA_BOUND - 1));
+       parport_ip32_dma_setup_context(limit);
+       parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND);
+
+       /* Real start of DMA transfer */
+       ctrl |= MACEPAR_CTLSTAT_ENABLE;
+       writeq(ctrl, &mace->perif.ctrl.parport.cntlstat);
+
+       return 0;
+}
+
+/**
+ * parport_ip32_dma_stop - ends a running DMA transfer
+ *
+ * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be
+ * correctly balanced.
+ */
+static void parport_ip32_dma_stop(void)
+{
+       u64 ctx_a;
+       u64 ctx_b;
+       u64 ctrl;
+       u64 diag;
+       size_t res[2];  /* {[0] = res_a, [1] = res_b} */
+
+       pr_trace(NULL, "()");
+
+       /* Disable IRQs */
+       spin_lock_irq(&parport_ip32_dma.lock);
+       if (parport_ip32_dma.irq_on) {
+               pr_debug(PPIP32 "IRQ off (stop)\n");
+               disable_irq_nosync(MACEISA_PAR_CTXA_IRQ);
+               disable_irq_nosync(MACEISA_PAR_CTXB_IRQ);
+               parport_ip32_dma.irq_on = 0;
+       }
+       spin_unlock_irq(&parport_ip32_dma.lock);
+       /* Force IRQ synchronization, even if the IRQs were disabled
+        * elsewhere. */
+       synchronize_irq(MACEISA_PAR_CTXA_IRQ);
+       synchronize_irq(MACEISA_PAR_CTXB_IRQ);
+
+       /* Stop DMA transfer */
+       ctrl = readq(&mace->perif.ctrl.parport.cntlstat);
+       ctrl &= ~MACEPAR_CTLSTAT_ENABLE;
+       writeq(ctrl, &mace->perif.ctrl.parport.cntlstat);
+
+       /* Adjust residue (parport_ip32_dma.left) */
+       ctx_a = readq(&mace->perif.ctrl.parport.context_a);
+       ctx_b = readq(&mace->perif.ctrl.parport.context_b);
+       ctrl = readq(&mace->perif.ctrl.parport.cntlstat);
+       diag = readq(&mace->perif.ctrl.parport.diagnostic);
+       res[0] = (ctrl & MACEPAR_CTLSTAT_CTXA_VALID) ?
+               1 + ((ctx_a & MACEPAR_CONTEXT_DATALEN_MASK) >>
+                    MACEPAR_CONTEXT_DATALEN_SHIFT) :
+               0;
+       res[1] = (ctrl & MACEPAR_CTLSTAT_CTXB_VALID) ?
+               1 + ((ctx_b & MACEPAR_CONTEXT_DATALEN_MASK) >>
+                    MACEPAR_CONTEXT_DATALEN_SHIFT) :
+               0;
+       if (diag & MACEPAR_DIAG_DMACTIVE)
+               res[(diag & MACEPAR_DIAG_CTXINUSE) != 0] =
+                       1 + ((diag & MACEPAR_DIAG_CTRMASK) >>
+                            MACEPAR_DIAG_CTRSHIFT);
+       parport_ip32_dma.left += res[0] + res[1];
+
+       /* Reset DMA controller, and re-enable IRQs */
+       ctrl = MACEPAR_CTLSTAT_RESET;
+       writeq(ctrl, &mace->perif.ctrl.parport.cntlstat);
+       pr_debug(PPIP32 "IRQ on (stop)\n");
+       enable_irq(MACEISA_PAR_CTXA_IRQ);
+       enable_irq(MACEISA_PAR_CTXB_IRQ);
+       parport_ip32_dma.irq_on = 1;
+
+       dma_unmap_single(NULL, parport_ip32_dma.buf, parport_ip32_dma.len,
+                        parport_ip32_dma.dir);
+}
+
+/**
+ * parport_ip32_dma_get_residue - get residue from last DMA transfer
+ *
+ * Returns the number of bytes remaining from last DMA transfer.
+ */
+static inline size_t parport_ip32_dma_get_residue(void)
+{
+       return parport_ip32_dma.left;
+}
+
+/**
+ * parport_ip32_dma_register - initialize DMA engine
+ *
+ * Returns zero for success.
+ */
+static int parport_ip32_dma_register(void)
+{
+       int err;
+
+       spin_lock_init(&parport_ip32_dma.lock);
+       parport_ip32_dma.irq_on = 1;
+
+       /* Reset DMA controller */
+       writeq(MACEPAR_CTLSTAT_RESET, &mace->perif.ctrl.parport.cntlstat);
+
+       /* Request IRQs */
+       err = request_irq(MACEISA_PAR_CTXA_IRQ, parport_ip32_dma_interrupt,
+                         0, "parport_ip32", NULL);
+       if (err)
+               goto fail_a;
+       err = request_irq(MACEISA_PAR_CTXB_IRQ, parport_ip32_dma_interrupt,
+                         0, "parport_ip32", NULL);
+       if (err)
+               goto fail_b;
+#if DEBUG_PARPORT_IP32
+       /* FIXME - what is this IRQ for? */
+       err = request_irq(MACEISA_PAR_MERR_IRQ, parport_ip32_merr_interrupt,
+                         0, "parport_ip32", NULL);
+       if (err)
+               goto fail_merr;
+#endif
+       return 0;
+
+#if DEBUG_PARPORT_IP32
+fail_merr:
+       free_irq(MACEISA_PAR_CTXB_IRQ, NULL);
+#endif
+fail_b:
+       free_irq(MACEISA_PAR_CTXA_IRQ, NULL);
+fail_a:
+       return err;
+}
+
+/**
+ * parport_ip32_dma_unregister - release and free resources for DMA engine
+ */
+static void parport_ip32_dma_unregister(void)
+{
+#if DEBUG_PARPORT_IP32
+       free_irq(MACEISA_PAR_MERR_IRQ, NULL);
+#endif
+       free_irq(MACEISA_PAR_CTXB_IRQ, NULL);
+       free_irq(MACEISA_PAR_CTXA_IRQ, NULL);
+}
+
+/*--- Interrupt handlers and associates --------------------------------*/
+
+/**
+ * parport_ip32_wakeup - wakes up code waiting for an interrupt
+ * @p:         pointer to &struct parport
+ */
+static inline void parport_ip32_wakeup(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       complete(&priv->irq_complete);
+}
+
+/**
+ * parport_ip32_interrupt - interrupt handler
+ * @irq:       interrupt number
+ * @dev_id:    pointer to &struct parport
+ * @regs:      pointer to &struct pt_regs
+ *
+ * Caught interrupts are forwarded to the upper parport layer if IRQ_mode is
+ * %PARPORT_IP32_IRQ_FWD.
+ */
+static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id,
+                                         struct pt_regs *regs)
+{
+       struct parport * const p = dev_id;
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       enum parport_ip32_irq_mode irq_mode = priv->irq_mode;
+       switch (irq_mode) {
+       case PARPORT_IP32_IRQ_FWD:
+               parport_generic_irq(irq, p, regs);
+               break;
+       case PARPORT_IP32_IRQ_HERE:
+               parport_ip32_wakeup(p);
+               break;
+       }
+       return IRQ_HANDLED;
+}
+
+/*--- Some utility function to manipulate ECR register -----------------*/
+
+/**
+ * parport_ip32_read_econtrol - read contents of the ECR register
+ * @p:         pointer to &struct parport
+ */
+static inline unsigned int parport_ip32_read_econtrol(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return readb(priv->regs.ecr);
+}
+
+/**
+ * parport_ip32_write_econtrol - write new contents to the ECR register
+ * @p:         pointer to &struct parport
+ * @c:         new value to write
+ */
+static inline void parport_ip32_write_econtrol(struct parport *p,
+                                              unsigned int c)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       writeb(c, priv->regs.ecr);
+}
+
+/**
+ * parport_ip32_frob_econtrol - change bits from the ECR register
+ * @p:         pointer to &struct parport
+ * @mask:      bit mask of bits to change
+ * @val:       new value for changed bits
+ *
+ * Read from the ECR, mask out the bits in @mask, exclusive-or with the bits
+ * in @val, and write the result to the ECR.
+ */
+static inline void parport_ip32_frob_econtrol(struct parport *p,
+                                             unsigned int mask,
+                                             unsigned int val)
+{
+       unsigned int c;
+       c = (parport_ip32_read_econtrol(p) & ~mask) ^ val;
+       parport_ip32_write_econtrol(p, c);
+}
+
+/**
+ * parport_ip32_set_mode - change mode of ECP port
+ * @p:         pointer to &struct parport
+ * @mode:      new mode to write in ECR
+ *
+ * ECR is reset in a sane state (interrupts and DMA disabled), and placed in
+ * mode @mode.  Go through PS2 mode if needed.
+ */
+static void parport_ip32_set_mode(struct parport *p, unsigned int mode)
+{
+       unsigned int omode;
+
+       mode &= ECR_MODE_MASK;
+       omode = parport_ip32_read_econtrol(p) & ECR_MODE_MASK;
+
+       if (!(mode == ECR_MODE_SPP || mode == ECR_MODE_PS2
+             || omode == ECR_MODE_SPP || omode == ECR_MODE_PS2)) {
+               /* We have to go through PS2 mode */
+               unsigned int ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR;
+               parport_ip32_write_econtrol(p, ecr);
+       }
+       parport_ip32_write_econtrol(p, mode | ECR_nERRINTR | ECR_SERVINTR);
+}
+
+/*--- Basic functions needed for parport -------------------------------*/
+
+/**
+ * parport_ip32_read_data - return current contents of the DATA register
+ * @p:         pointer to &struct parport
+ */
+static inline unsigned char parport_ip32_read_data(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return readb(priv->regs.data);
+}
+
+/**
+ * parport_ip32_write_data - set new contents for the DATA register
+ * @p:         pointer to &struct parport
+ * @d:         new value to write
+ */
+static inline void parport_ip32_write_data(struct parport *p, unsigned char d)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       writeb(d, priv->regs.data);
+}
+
+/**
+ * parport_ip32_read_status - return current contents of the DSR register
+ * @p:         pointer to &struct parport
+ */
+static inline unsigned char parport_ip32_read_status(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return readb(priv->regs.dsr);
+}
+
+/**
+ * __parport_ip32_read_control - return cached contents of the DCR register
+ * @p:         pointer to &struct parport
+ */
+static inline unsigned int __parport_ip32_read_control(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return priv->dcr_cache; /* use soft copy */
+}
+
+/**
+ * __parport_ip32_write_control - set new contents for the DCR register
+ * @p:         pointer to &struct parport
+ * @c:         new value to write
+ */
+static inline void __parport_ip32_write_control(struct parport *p,
+                                               unsigned int c)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       CHECK_EXTRA_BITS(p, c, priv->dcr_writable);
+       c &= priv->dcr_writable; /* only writable bits */
+       writeb(c, priv->regs.dcr);
+       priv->dcr_cache = c;            /* update soft copy */
+}
+
+/**
+ * __parport_ip32_frob_control - change bits from the DCR register
+ * @p:         pointer to &struct parport
+ * @mask:      bit mask of bits to change
+ * @val:       new value for changed bits
+ *
+ * This is equivalent to read from the DCR, mask out the bits in @mask,
+ * exclusive-or with the bits in @val, and write the result to the DCR.
+ * Actually, the cached contents of the DCR is used.
+ */
+static inline void __parport_ip32_frob_control(struct parport *p,
+                                              unsigned int mask,
+                                              unsigned int val)
+{
+       unsigned int c;
+       c = (__parport_ip32_read_control(p) & ~mask) ^ val;
+       __parport_ip32_write_control(p, c);
+}
+
+/**
+ * parport_ip32_read_control - return cached contents of the DCR register
+ * @p:         pointer to &struct parport
+ *
+ * The return value is masked so as to only return the value of %DCR_STROBE,
+ * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT.
+ */
+static inline unsigned char parport_ip32_read_control(struct parport *p)
+{
+       const unsigned int rm =
+               DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT;
+       return __parport_ip32_read_control(p) & rm;
+}
+
+/**
+ * parport_ip32_write_control - set new contents for the DCR register
+ * @p:         pointer to &struct parport
+ * @c:         new value to write
+ *
+ * The value is masked so as to only change the value of %DCR_STROBE,
+ * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT.
+ */
+static inline void parport_ip32_write_control(struct parport *p,
+                                             unsigned char c)
+{
+       const unsigned int wm =
+               DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT;
+       CHECK_EXTRA_BITS(p, c, wm);
+       __parport_ip32_frob_control(p, wm, c & wm);
+}
+
+/**
+ * parport_ip32_frob_control - change bits from the DCR register
+ * @p:         pointer to &struct parport
+ * @mask:      bit mask of bits to change
+ * @val:       new value for changed bits
+ *
+ * This differs from __parport_ip32_frob_control() in that it only allows to
+ * change the value of %DCR_STROBE, %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT.
+ */
+static inline unsigned char parport_ip32_frob_control(struct parport *p,
+                                                     unsigned char mask,
+                                                     unsigned char val)
+{
+       const unsigned int wm =
+               DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT;
+       CHECK_EXTRA_BITS(p, mask, wm);
+       CHECK_EXTRA_BITS(p, val, wm);
+       __parport_ip32_frob_control(p, mask & wm, val & wm);
+       return parport_ip32_read_control(p);
+}
+
+/**
+ * parport_ip32_disable_irq - disable interrupts on the rising edge of nACK
+ * @p:         pointer to &struct parport
+ */
+static inline void parport_ip32_disable_irq(struct parport *p)
+{
+       __parport_ip32_frob_control(p, DCR_IRQ, 0);
+}
+
+/**
+ * parport_ip32_enable_irq - enable interrupts on the rising edge of nACK
+ * @p:         pointer to &struct parport
+ */
+static inline void parport_ip32_enable_irq(struct parport *p)
+{
+       __parport_ip32_frob_control(p, DCR_IRQ, DCR_IRQ);
+}
+
+/**
+ * parport_ip32_data_forward - enable host-to-peripheral communications
+ * @p:         pointer to &struct parport
+ *
+ * Enable the data line drivers, for 8-bit host-to-peripheral communications.
+ */
+static inline void parport_ip32_data_forward(struct parport *p)
+{
+       __parport_ip32_frob_control(p, DCR_DIR, 0);
+}
+
+/**
+ * parport_ip32_data_reverse - enable peripheral-to-host communications
+ * @p:         pointer to &struct parport
+ *
+ * Place the data bus in a high impedance state, if @p->modes has the
+ * PARPORT_MODE_TRISTATE bit set.
+ */
+static inline void parport_ip32_data_reverse(struct parport *p)
+{
+       __parport_ip32_frob_control(p, DCR_DIR, DCR_DIR);
+}
+
+/**
+ * parport_ip32_init_state - for core parport code
+ * @dev:       pointer to &struct pardevice
+ * @s:         pointer to &struct parport_state to initialize
+ */
+static void parport_ip32_init_state(struct pardevice *dev,
+                                   struct parport_state *s)
+{
+       s->u.ip32.dcr = DCR_SELECT | DCR_nINIT;
+       s->u.ip32.ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR;
+}
+
+/**
+ * parport_ip32_save_state - for core parport code
+ * @p:         pointer to &struct parport
+ * @s:         pointer to &struct parport_state to save state to
+ */
+static void parport_ip32_save_state(struct parport *p,
+                                   struct parport_state *s)
+{
+       s->u.ip32.dcr = __parport_ip32_read_control(p);
+       s->u.ip32.ecr = parport_ip32_read_econtrol(p);
+}
+
+/**
+ * parport_ip32_restore_state - for core parport code
+ * @p:         pointer to &struct parport
+ * @s:         pointer to &struct parport_state to restore state from
+ */
+static void parport_ip32_restore_state(struct parport *p,
+                                      struct parport_state *s)
+{
+       parport_ip32_set_mode(p, s->u.ip32.ecr & ECR_MODE_MASK);
+       parport_ip32_write_econtrol(p, s->u.ip32.ecr);
+       __parport_ip32_write_control(p, s->u.ip32.dcr);
+}
+
+/*--- EPP mode functions -----------------------------------------------*/
+
+/**
+ * parport_ip32_clear_epp_timeout - clear Timeout bit in EPP mode
+ * @p:         pointer to &struct parport
+ *
+ * Returns 1 if the Timeout bit is clear, and 0 otherwise.
+ */
+static unsigned int parport_ip32_clear_epp_timeout(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       unsigned int cleared;
+
+       if (!(parport_ip32_read_status(p) & DSR_TIMEOUT))
+               cleared = 1;
+       else {
+               unsigned int r;
+               /* To clear timeout some chips require double read */
+               parport_ip32_read_status(p);
+               r = parport_ip32_read_status(p);
+               /* Some reset by writing 1 */
+               writeb(r | DSR_TIMEOUT, priv->regs.dsr);
+               /* Others by writing 0 */
+               writeb(r & ~DSR_TIMEOUT, priv->regs.dsr);
+
+               r = parport_ip32_read_status(p);
+               cleared = !(r & DSR_TIMEOUT);
+       }
+
+       pr_trace(p, "(): %s", cleared ? "cleared" : "failed");
+       return cleared;
+}
+
+/**
+ * parport_ip32_epp_read - generic EPP read function
+ * @eppreg:    I/O register to read from
+ * @p:         pointer to &struct parport
+ * @buf:       buffer to store read data
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_read(void __iomem *eppreg,
+                                   struct parport *p, void *buf,
+                                   size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       size_t got;
+       parport_ip32_set_mode(p, ECR_MODE_EPP);
+       parport_ip32_data_reverse(p);
+       parport_ip32_write_control(p, DCR_nINIT);
+       if ((flags & PARPORT_EPP_FAST) && (len > 1)) {
+               readsb(eppreg, buf, len);
+               if (readb(priv->regs.dsr) & DSR_TIMEOUT) {
+                       parport_ip32_clear_epp_timeout(p);
+                       return -EIO;
+               }
+               got = len;
+       } else {
+               u8 *bufp = buf;
+               for (got = 0; got < len; got++) {
+                       *bufp++ = readb(eppreg);
+                       if (readb(priv->regs.dsr) & DSR_TIMEOUT) {
+                               parport_ip32_clear_epp_timeout(p);
+                               break;
+                       }
+               }
+       }
+       parport_ip32_data_forward(p);
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       return got;
+}
+
+/**
+ * parport_ip32_epp_write - generic EPP write function
+ * @eppreg:    I/O register to write to
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_write(void __iomem *eppreg,
+                                    struct parport *p, const void *buf,
+                                    size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       size_t written;
+       parport_ip32_set_mode(p, ECR_MODE_EPP);
+       parport_ip32_data_forward(p);
+       parport_ip32_write_control(p, DCR_nINIT);
+       if ((flags & PARPORT_EPP_FAST) && (len > 1)) {
+               writesb(eppreg, buf, len);
+               if (readb(priv->regs.dsr) & DSR_TIMEOUT) {
+                       parport_ip32_clear_epp_timeout(p);
+                       return -EIO;
+               }
+               written = len;
+       } else {
+               const u8 *bufp = buf;
+               for (written = 0; written < len; written++) {
+                       writeb(*bufp++, eppreg);
+                       if (readb(priv->regs.dsr) & DSR_TIMEOUT) {
+                               parport_ip32_clear_epp_timeout(p);
+                               break;
+                       }
+               }
+       }
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       return written;
+}
+
+/**
+ * parport_ip32_epp_read_data - read a block of data in EPP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer to store read data
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_read_data(struct parport *p, void *buf,
+                                        size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return parport_ip32_epp_read(priv->regs.eppData0, p, buf, len, flags);
+}
+
+/**
+ * parport_ip32_epp_write_data - write a block of data in EPP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_write_data(struct parport *p, const void *buf,
+                                         size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return parport_ip32_epp_write(priv->regs.eppData0, p, buf, len, flags);
+}
+
+/**
+ * parport_ip32_epp_read_addr - read a block of addresses in EPP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer to store read data
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_read_addr(struct parport *p, void *buf,
+                                        size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return parport_ip32_epp_read(priv->regs.eppAddr, p, buf, len, flags);
+}
+
+/**
+ * parport_ip32_epp_write_addr - write a block of addresses in EPP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ * @flags:     may be PARPORT_EPP_FAST
+ */
+static size_t parport_ip32_epp_write_addr(struct parport *p, const void *buf,
+                                         size_t len, int flags)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       return parport_ip32_epp_write(priv->regs.eppAddr, p, buf, len, flags);
+}
+
+/*--- ECP mode functions (FIFO) ----------------------------------------*/
+
+/**
+ * parport_ip32_fifo_wait_break - check if the waiting function should return
+ * @p:         pointer to &struct parport
+ * @expire:    timeout expiring date, in jiffies
+ *
+ * parport_ip32_fifo_wait_break() checks if the waiting function should return
+ * immediately or not.  The break conditions are:
+ *     - expired timeout;
+ *     - a pending signal;
+ *     - nFault asserted low.
+ * This function also calls cond_resched().
+ */
+static unsigned int parport_ip32_fifo_wait_break(struct parport *p,
+                                                unsigned long expire)
+{
+       cond_resched();
+       if (time_after(jiffies, expire)) {
+               pr_debug1(PPIP32 "%s: FIFO write timed out\n", p->name);
+               return 1;
+       }
+       if (signal_pending(current)) {
+               pr_debug1(PPIP32 "%s: Signal pending\n", p->name);
+               return 1;
+       }
+       if (!(parport_ip32_read_status(p) & DSR_nFAULT)) {
+               pr_debug1(PPIP32 "%s: nFault asserted low\n", p->name);
+               return 1;
+       }
+       return 0;
+}
+
+/**
+ * parport_ip32_fwp_wait_polling - wait for FIFO to empty (polling)
+ * @p:         pointer to &struct parport
+ *
+ * Returns the number of bytes that can safely be written in the FIFO.  A
+ * return value of zero means that the calling function should terminate as
+ * fast as possible.
+ */
+static unsigned int parport_ip32_fwp_wait_polling(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport * const physport = p->physport;
+       unsigned long expire;
+       unsigned int count;
+       unsigned int ecr;
+
+       expire = jiffies + physport->cad->timeout;
+       count = 0;
+       while (1) {
+               if (parport_ip32_fifo_wait_break(p, expire))
+                       break;
+
+               /* Check FIFO state.  We do nothing when the FIFO is nor full,
+                * nor empty.  It appears that the FIFO full bit is not always
+                * reliable, the FIFO state is sometimes wrongly reported, and
+                * the chip gets confused if we give it another byte. */
+               ecr = parport_ip32_read_econtrol(p);
+               if (ecr & ECR_F_EMPTY) {
+                       /* FIFO is empty, fill it up */
+                       count = priv->fifo_depth;
+                       break;
+               }
+
+               /* Wait a moment... */
+               udelay(FIFO_POLLING_INTERVAL);
+       } /* while (1) */
+
+       return count;
+}
+
+/**
+ * parport_ip32_fwp_wait_interrupt - wait for FIFO to empty (interrupt-driven)
+ * @p:         pointer to &struct parport
+ *
+ * Returns the number of bytes that can safely be written in the FIFO.  A
+ * return value of zero means that the calling function should terminate as
+ * fast as possible.
+ */
+static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p)
+{
+       static unsigned int lost_interrupt = 0;
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport * const physport = p->physport;
+       unsigned long nfault_timeout;
+       unsigned long expire;
+       unsigned int count;
+       unsigned int ecr;
+
+       nfault_timeout = min((unsigned long)physport->cad->timeout,
+                            msecs_to_jiffies(FIFO_NFAULT_TIMEOUT));
+       expire = jiffies + physport->cad->timeout;
+       count = 0;
+       while (1) {
+               if (parport_ip32_fifo_wait_break(p, expire))
+                       break;
+
+               /* Initialize mutex used to take interrupts into account */
+               INIT_COMPLETION(priv->irq_complete);
+
+               /* Enable serviceIntr */
+               parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0);
+
+               /* Enabling serviceIntr while the FIFO is empty does not
+                * always generate an interrupt, so check for emptiness
+                * now. */
+               ecr = parport_ip32_read_econtrol(p);
+               if (!(ecr & ECR_F_EMPTY)) {
+                       /* FIFO is not empty: wait for an interrupt or a
+                        * timeout to occur */
+                       wait_for_completion_interruptible_timeout(
+                               &priv->irq_complete, nfault_timeout);
+                       ecr = parport_ip32_read_econtrol(p);
+                       if ((ecr & ECR_F_EMPTY) && !(ecr & ECR_SERVINTR)
+                           && !lost_interrupt) {
+                               printk(KERN_WARNING PPIP32
+                                      "%s: lost interrupt in %s\n",
+                                      p->name, __func__);
+                               lost_interrupt = 1;
+                       }
+               }
+
+               /* Disable serviceIntr */
+               parport_ip32_frob_econtrol(p, ECR_SERVINTR, ECR_SERVINTR);
+
+               /* Check FIFO state */
+               if (ecr & ECR_F_EMPTY) {
+                       /* FIFO is empty, fill it up */
+                       count = priv->fifo_depth;
+                       break;
+               } else if (ecr & ECR_SERVINTR) {
+                       /* FIFO is not empty, but we know that can safely push
+                        * writeIntrThreshold bytes into it */
+                       count = priv->writeIntrThreshold;
+                       break;
+               }
+               /* FIFO is not empty, and we did not get any interrupt.
+                * Either it's time to check for nFault, or a signal is
+                * pending.  This is verified in
+                * parport_ip32_fifo_wait_break(), so we continue the loop. */
+       } /* while (1) */
+
+       return count;
+}
+
+/**
+ * parport_ip32_fifo_write_block_pio - write a block of data (PIO mode)
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ *
+ * Uses PIO to write the contents of the buffer @buf into the parallel port
+ * FIFO.  Returns the number of bytes that were actually written.  It can work
+ * with or without the help of interrupts.  The parallel port must be
+ * correctly initialized before calling parport_ip32_fifo_write_block_pio().
+ */
+static size_t parport_ip32_fifo_write_block_pio(struct parport *p,
+                                               const void *buf, size_t len)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       const u8 *bufp = buf;
+       size_t left = len;
+
+       priv->irq_mode = PARPORT_IP32_IRQ_HERE;
+
+       while (left > 0) {
+               unsigned int count;
+
+               count = (p->irq == PARPORT_IRQ_NONE) ?
+                       parport_ip32_fwp_wait_polling(p) :
+                       parport_ip32_fwp_wait_interrupt(p);
+               if (count == 0)
+                       break;  /* Transmission should be stopped */
+               if (count > left)
+                       count = left;
+               if (count == 1) {
+                       writeb(*bufp, priv->regs.fifo);
+                       bufp++, left--;
+               } else {
+                       writesb(priv->regs.fifo, bufp, count);
+                       bufp += count, left -= count;
+               }
+       }
+
+       priv->irq_mode = PARPORT_IP32_IRQ_FWD;
+
+       return len - left;
+}
+
+/**
+ * parport_ip32_fifo_write_block_dma - write a block of data (DMA mode)
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ *
+ * Uses DMA to write the contents of the buffer @buf into the parallel port
+ * FIFO.  Returns the number of bytes that were actually written.  The
+ * parallel port must be correctly initialized before calling
+ * parport_ip32_fifo_write_block_dma().
+ */
+static size_t parport_ip32_fifo_write_block_dma(struct parport *p,
+                                               const void *buf, size_t len)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport * const physport = p->physport;
+       unsigned long nfault_timeout;
+       unsigned long expire;
+       size_t written;
+       unsigned int ecr;
+
+       priv->irq_mode = PARPORT_IP32_IRQ_HERE;
+
+       parport_ip32_dma_start(DMA_TO_DEVICE, (void *)buf, len);
+       INIT_COMPLETION(priv->irq_complete);
+       parport_ip32_frob_econtrol(p, ECR_DMAEN | ECR_SERVINTR, ECR_DMAEN);
+
+       nfault_timeout = min((unsigned long)physport->cad->timeout,
+                            msecs_to_jiffies(FIFO_NFAULT_TIMEOUT));
+       expire = jiffies + physport->cad->timeout;
+       while (1) {
+               if (parport_ip32_fifo_wait_break(p, expire))
+                       break;
+               wait_for_completion_interruptible_timeout(&priv->irq_complete,
+                                                         nfault_timeout);
+               ecr = parport_ip32_read_econtrol(p);
+               if (ecr & ECR_SERVINTR)
+                       break;  /* DMA transfer just finished */
+       }
+       parport_ip32_dma_stop();
+       written = len - parport_ip32_dma_get_residue();
+
+       priv->irq_mode = PARPORT_IP32_IRQ_FWD;
+
+       return written;
+}
+
+/**
+ * parport_ip32_fifo_write_block - write a block of data
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ *
+ * Uses PIO or DMA to write the contents of the buffer @buf into the parallel
+ * p FIFO.  Returns the number of bytes that were actually written.
+ */
+static size_t parport_ip32_fifo_write_block(struct parport *p,
+                                           const void *buf, size_t len)
+{
+       size_t written = 0;
+       if (len)
+               /* FIXME - Maybe some threshold value should be set for @len
+                * under which we revert to PIO mode? */
+               written = (p->modes & PARPORT_MODE_DMA) ?
+                       parport_ip32_fifo_write_block_dma(p, buf, len) :
+                       parport_ip32_fifo_write_block_pio(p, buf, len);
+       return written;
+}
+
+/**
+ * parport_ip32_drain_fifo - wait for FIFO to empty
+ * @p:         pointer to &struct parport
+ * @timeout:   timeout, in jiffies
+ *
+ * This function waits for FIFO to empty.  It returns 1 when FIFO is empty, or
+ * 0 if the timeout @timeout is reached before, or if a signal is pending.
+ */
+static unsigned int parport_ip32_drain_fifo(struct parport *p,
+                                           unsigned long timeout)
+{
+       unsigned long expire = jiffies + timeout;
+       unsigned int polling_interval;
+       unsigned int counter;
+
+       /* Busy wait for approx. 200us */
+       for (counter = 0; counter < 40; counter++) {
+               if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY)
+                       break;
+               if (time_after(jiffies, expire))
+                       break;
+               if (signal_pending(current))
+                       break;
+               udelay(5);
+       }
+       /* Poll slowly.  Polling interval starts with 1 millisecond, and is
+        * increased exponentially until 128.  */
+       polling_interval = 1; /* msecs */
+       while (!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY)) {
+               if (time_after_eq(jiffies, expire))
+                       break;
+               msleep_interruptible(polling_interval);
+               if (signal_pending(current))
+                       break;
+               if (polling_interval < 128)
+                       polling_interval *= 2;
+       }
+
+       return !!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY);
+}
+
+/**
+ * parport_ip32_get_fifo_residue - reset FIFO
+ * @p:         pointer to &struct parport
+ * @mode:      current operation mode (ECR_MODE_PPF or ECR_MODE_ECP)
+ *
+ * This function resets FIFO, and returns the number of bytes remaining in it.
+ */
+static unsigned int parport_ip32_get_fifo_residue(struct parport *p,
+                                                 unsigned int mode)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       unsigned int residue;
+       unsigned int cnfga;
+
+       /* FIXME - We are missing one byte if the printer is off-line.  I
+        * don't know how to detect this.  It looks that the full bit is not
+        * always reliable.  For the moment, the problem is avoided in most
+        * cases by testing for BUSY in parport_ip32_compat_write_data().
+        */
+       if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY)
+               residue = 0;
+       else {
+               pr_debug1(PPIP32 "%s: FIFO is stuck\n", p->name);
+
+               /* Stop all transfers.
+                *
+                * Microsoft's document instructs to drive DCR_STROBE to 0,
+                * but it doesn't work (at least in Compatibility mode, not
+                * tested in ECP mode).  Switching directly to Test mode (as
+                * in parport_pc) is not an option: it does confuse the port,
+                * ECP service interrupts are no more working after that.  A
+                * hard reset is then needed to revert to a sane state.
+                *
+                * Let's hope that the FIFO is really stuck and that the
+                * peripheral doesn't wake up now.
+                */
+               parport_ip32_frob_control(p, DCR_STROBE, 0);
+
+               /* Fill up FIFO */
+               for (residue = priv->fifo_depth; residue > 0; residue--) {
+                       if (parport_ip32_read_econtrol(p) & ECR_F_FULL)
+                               break;
+                       writeb(0x00, priv->regs.fifo);
+               }
+       }
+       if (residue)
+               pr_debug1(PPIP32 "%s: %d PWord%s left in FIFO\n",
+                         p->name, residue,
+                         (residue == 1) ? " was" : "s were");
+
+       /* Now reset the FIFO */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+
+       /* Host recovery for ECP mode */
+       if (mode == ECR_MODE_ECP) {
+               parport_ip32_data_reverse(p);
+               parport_ip32_frob_control(p, DCR_nINIT, 0);
+               if (parport_wait_peripheral(p, DSR_PERROR, 0))
+                       pr_debug1(PPIP32 "%s: PEerror timeout 1 in %s\n",
+                                 p->name, __func__);
+               parport_ip32_frob_control(p, DCR_STROBE, DCR_STROBE);
+               parport_ip32_frob_control(p, DCR_nINIT, DCR_nINIT);
+               if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR))
+                       pr_debug1(PPIP32 "%s: PEerror timeout 2 in %s\n",
+                                 p->name, __func__);
+       }
+
+       /* Adjust residue if needed */
+       parport_ip32_set_mode(p, ECR_MODE_CFG);
+       cnfga = readb(priv->regs.cnfgA);
+       if (!(cnfga & CNFGA_nBYTEINTRANS)) {
+               pr_debug1(PPIP32 "%s: cnfgA contains 0x%02x\n",
+                         p->name, cnfga);
+               pr_debug1(PPIP32 "%s: Accounting for extra byte\n",
+                         p->name);
+               residue++;
+       }
+
+       /* Don't care about partial PWords since we do not support
+        * PWord != 1 byte. */
+
+       /* Back to forward PS2 mode. */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       parport_ip32_data_forward(p);
+
+       return residue;
+}
+
+/**
+ * parport_ip32_compat_write_data - write a block of data in SPP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ * @flags:     ignored
+ */
+static size_t parport_ip32_compat_write_data(struct parport *p,
+                                            const void *buf, size_t len,
+                                            int flags)
+{
+       static unsigned int ready_before = 1;
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport * const physport = p->physport;
+       size_t written = 0;
+
+       /* Special case: a timeout of zero means we cannot call schedule().
+        * Also if O_NONBLOCK is set then use the default implementation. */
+       if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
+               return parport_ieee1284_write_compat(p, buf, len, flags);
+
+       /* Reset FIFO, go in forward mode, and disable ackIntEn */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT);
+       parport_ip32_data_forward(p);
+       parport_ip32_disable_irq(p);
+       parport_ip32_set_mode(p, ECR_MODE_PPF);
+       physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
+
+       /* Wait for peripheral to become ready */
+       if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT,
+                                      DSR_nBUSY | DSR_nFAULT)) {
+               /* Avoid to flood the logs */
+               if (ready_before)
+                       printk(KERN_INFO PPIP32 "%s: not ready in %s\n",
+                              p->name, __func__);
+               ready_before = 0;
+               goto stop;
+       }
+       ready_before = 1;
+
+       written = parport_ip32_fifo_write_block(p, buf, len);
+
+       /* Wait FIFO to empty.  Timeout is proportional to FIFO_depth.  */
+       parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth);
+
+       /* Check for a potential residue */
+       written -= parport_ip32_get_fifo_residue(p, ECR_MODE_PPF);
+
+       /* Then, wait for BUSY to get low. */
+       if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY))
+               printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n",
+                      p->name, __func__);
+
+stop:
+       /* Reset FIFO */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
+
+       return written;
+}
+
+/*
+ * FIXME - Insert here parport_ip32_ecp_read_data().
+ */
+
+/**
+ * parport_ip32_ecp_write_data - write a block of data in ECP mode
+ * @p:         pointer to &struct parport
+ * @buf:       buffer of data to write
+ * @len:       length of buffer @buf
+ * @flags:     ignored
+ */
+static size_t parport_ip32_ecp_write_data(struct parport *p,
+                                         const void *buf, size_t len,
+                                         int flags)
+{
+       static unsigned int ready_before = 1;
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport * const physport = p->physport;
+       size_t written = 0;
+
+       /* Special case: a timeout of zero means we cannot call schedule().
+        * Also if O_NONBLOCK is set then use the default implementation. */
+       if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
+               return parport_ieee1284_ecp_write_data(p, buf, len, flags);
+
+       /* Negotiate to forward mode if necessary. */
+       if (physport->ieee1284.phase != IEEE1284_PH_FWD_IDLE) {
+               /* Event 47: Set nInit high. */
+               parport_ip32_frob_control(p, DCR_nINIT | DCR_AUTOFD,
+                                            DCR_nINIT | DCR_AUTOFD);
+
+               /* Event 49: PError goes high. */
+               if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) {
+                       printk(KERN_DEBUG PPIP32 "%s: PError timeout in %s",
+                              p->name, __func__);
+                       physport->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
+                       return 0;
+               }
+       }
+
+       /* Reset FIFO, go in forward mode, and disable ackIntEn */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT);
+       parport_ip32_data_forward(p);
+       parport_ip32_disable_irq(p);
+       parport_ip32_set_mode(p, ECR_MODE_ECP);
+       physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
+
+       /* Wait for peripheral to become ready */
+       if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT,
+                                      DSR_nBUSY | DSR_nFAULT)) {
+               /* Avoid to flood the logs */
+               if (ready_before)
+                       printk(KERN_INFO PPIP32 "%s: not ready in %s\n",
+                              p->name, __func__);
+               ready_before = 0;
+               goto stop;
+       }
+       ready_before = 1;
+
+       written = parport_ip32_fifo_write_block(p, buf, len);
+
+       /* Wait FIFO to empty.  Timeout is proportional to FIFO_depth.  */
+       parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth);
+
+       /* Check for a potential residue */
+       written -= parport_ip32_get_fifo_residue(p, ECR_MODE_ECP);
+
+       /* Then, wait for BUSY to get low. */
+       if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY))
+               printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n",
+                      p->name, __func__);
+
+stop:
+       /* Reset FIFO */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
+
+       return written;
+}
+
+/*
+ * FIXME - Insert here parport_ip32_ecp_write_addr().
+ */
+
+/*--- Default parport operations ---------------------------------------*/
+
+static __initdata struct parport_operations parport_ip32_ops = {
+       .write_data             = parport_ip32_write_data,
+       .read_data              = parport_ip32_read_data,
+
+       .write_control          = parport_ip32_write_control,
+       .read_control           = parport_ip32_read_control,
+       .frob_control           = parport_ip32_frob_control,
+
+       .read_status            = parport_ip32_read_status,
+
+       .enable_irq             = parport_ip32_enable_irq,
+       .disable_irq            = parport_ip32_disable_irq,
+
+       .data_forward           = parport_ip32_data_forward,
+       .data_reverse           = parport_ip32_data_reverse,
+
+       .init_state             = parport_ip32_init_state,
+       .save_state             = parport_ip32_save_state,
+       .restore_state          = parport_ip32_restore_state,
+
+       .epp_write_data         = parport_ieee1284_epp_write_data,
+       .epp_read_data          = parport_ieee1284_epp_read_data,
+       .epp_write_addr         = parport_ieee1284_epp_write_addr,
+       .epp_read_addr          = parport_ieee1284_epp_read_addr,
+
+       .ecp_write_data         = parport_ieee1284_ecp_write_data,
+       .ecp_read_data          = parport_ieee1284_ecp_read_data,
+       .ecp_write_addr         = parport_ieee1284_ecp_write_addr,
+
+       .compat_write_data      = parport_ieee1284_write_compat,
+       .nibble_read_data       = parport_ieee1284_read_nibble,
+       .byte_read_data         = parport_ieee1284_read_byte,
+
+       .owner                  = THIS_MODULE,
+};
+
+/*--- Device detection -------------------------------------------------*/
+
+/**
+ * parport_ip32_ecp_supported - check for an ECP port
+ * @p:         pointer to the &parport structure
+ *
+ * Returns 1 if an ECP port is found, and 0 otherwise.  This function actually
+ * checks if an Extended Control Register seems to be present.  On successful
+ * return, the port is placed in SPP mode.
+ */
+static __init unsigned int parport_ip32_ecp_supported(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       unsigned int ecr;
+
+       ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR;
+       writeb(ecr, priv->regs.ecr);
+       if (readb(priv->regs.ecr) != (ecr | ECR_F_EMPTY))
+               goto fail;
+
+       pr_probe(p, "Found working ECR register\n");
+       parport_ip32_set_mode(p, ECR_MODE_SPP);
+       parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT);
+       return 1;
+
+fail:
+       pr_probe(p, "ECR register not found\n");
+       return 0;
+}
+
+/**
+ * parport_ip32_fifo_supported - check for FIFO parameters
+ * @p:         pointer to the &parport structure
+ *
+ * Check for FIFO parameters of an Extended Capabilities Port.  Returns 1 on
+ * success, and 0 otherwise.  Adjust FIFO parameters in the parport structure.
+ * On return, the port is placed in SPP mode.
+ */
+static __init unsigned int parport_ip32_fifo_supported(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       unsigned int configa, configb;
+       unsigned int pword;
+       unsigned int i;
+
+       /* Configuration mode */
+       parport_ip32_set_mode(p, ECR_MODE_CFG);
+       configa = readb(priv->regs.cnfgA);
+       configb = readb(priv->regs.cnfgB);
+
+       /* Find out PWord size */
+       switch (configa & CNFGA_ID_MASK) {
+       case CNFGA_ID_8:
+               pword = 1;
+               break;
+       case CNFGA_ID_16:
+               pword = 2;
+               break;
+       case CNFGA_ID_32:
+               pword = 4;
+               break;
+       default:
+               pr_probe(p, "Unknown implementation ID: 0x%0x\n",
+                        (configa & CNFGA_ID_MASK) >> CNFGA_ID_SHIFT);
+               goto fail;
+               break;
+       }
+       if (pword != 1) {
+               pr_probe(p, "Unsupported PWord size: %u\n", pword);
+               goto fail;
+       }
+       priv->pword = pword;
+       pr_probe(p, "PWord is %u bits\n", 8 * priv->pword);
+
+       /* Check for compression support */
+       writeb(configb | CNFGB_COMPRESS, priv->regs.cnfgB);
+       if (readb(priv->regs.cnfgB) & CNFGB_COMPRESS)
+               pr_probe(p, "Hardware compression detected (unsupported)\n");
+       writeb(configb & ~CNFGB_COMPRESS, priv->regs.cnfgB);
+
+       /* Reset FIFO and go in test mode (no interrupt, no DMA) */
+       parport_ip32_set_mode(p, ECR_MODE_TST);
+
+       /* FIFO must be empty now */
+       if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) {
+               pr_probe(p, "FIFO not reset\n");
+               goto fail;
+       }
+
+       /* Find out FIFO depth. */
+       priv->fifo_depth = 0;
+       for (i = 0; i < 1024; i++) {
+               if (readb(priv->regs.ecr) & ECR_F_FULL) {
+                       /* FIFO full */
+                       priv->fifo_depth = i;
+                       break;
+               }
+               writeb((u8)i, priv->regs.fifo);
+       }
+       if (i >= 1024) {
+               pr_probe(p, "Can't fill FIFO\n");
+               goto fail;
+       }
+       if (!priv->fifo_depth) {
+               pr_probe(p, "Can't get FIFO depth\n");
+               goto fail;
+       }
+       pr_probe(p, "FIFO is %u PWords deep\n", priv->fifo_depth);
+
+       /* Enable interrupts */
+       parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0);
+
+       /* Find out writeIntrThreshold: number of PWords we know we can write
+        * if we get an interrupt. */
+       priv->writeIntrThreshold = 0;
+       for (i = 0; i < priv->fifo_depth; i++) {
+               if (readb(priv->regs.fifo) != (u8)i) {
+                       pr_probe(p, "Invalid data in FIFO\n");
+                       goto fail;
+               }
+               if (!priv->writeIntrThreshold
+                   && readb(priv->regs.ecr) & ECR_SERVINTR)
+                       /* writeIntrThreshold reached */
+                       priv->writeIntrThreshold = i + 1;
+               if (i + 1 < priv->fifo_depth
+                   && readb(priv->regs.ecr) & ECR_F_EMPTY) {
+                       /* FIFO empty before the last byte? */
+                       pr_probe(p, "Data lost in FIFO\n");
+                       goto fail;
+               }
+       }
+       if (!priv->writeIntrThreshold) {
+               pr_probe(p, "Can't get writeIntrThreshold\n");
+               goto fail;
+       }
+       pr_probe(p, "writeIntrThreshold is %u\n", priv->writeIntrThreshold);
+
+       /* FIFO must be empty now */
+       if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) {
+               pr_probe(p, "Can't empty FIFO\n");
+               goto fail;
+       }
+
+       /* Reset FIFO */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       /* Set reverse direction (must be in PS2 mode) */
+       parport_ip32_data_reverse(p);
+       /* Test FIFO, no interrupt, no DMA */
+       parport_ip32_set_mode(p, ECR_MODE_TST);
+       /* Enable interrupts */
+       parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0);
+
+       /* Find out readIntrThreshold: number of PWords we can read if we get
+        * an interrupt. */
+       priv->readIntrThreshold = 0;
+       for (i = 0; i < priv->fifo_depth; i++) {
+               writeb(0xaa, priv->regs.fifo);
+               if (readb(priv->regs.ecr) & ECR_SERVINTR) {
+                       /* readIntrThreshold reached */
+                       priv->readIntrThreshold = i + 1;
+                       break;
+               }
+       }
+       if (!priv->readIntrThreshold) {
+               pr_probe(p, "Can't get readIntrThreshold\n");
+               goto fail;
+       }
+       pr_probe(p, "readIntrThreshold is %u\n", priv->readIntrThreshold);
+
+       /* Reset ECR */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       parport_ip32_data_forward(p);
+       parport_ip32_set_mode(p, ECR_MODE_SPP);
+       return 1;
+
+fail:
+       priv->fifo_depth = 0;
+       parport_ip32_set_mode(p, ECR_MODE_SPP);
+       return 0;
+}
+
+/*--- Initialization code ----------------------------------------------*/
+
+/**
+ * parport_ip32_make_isa_registers - compute (ISA) register addresses
+ * @regs:      pointer to &struct parport_ip32_regs to fill
+ * @base:      base address of standard and EPP registers
+ * @base_hi:   base address of ECP registers
+ * @regshift:  how much to shift register offset by
+ *
+ * Compute register addresses, according to the ISA standard.  The addresses
+ * of the standard and EPP registers are computed from address @base.  The
+ * addresses of the ECP registers are computed from address @base_hi.
+ */
+static void __init
+parport_ip32_make_isa_registers(struct parport_ip32_regs *regs,
+                               void __iomem *base, void __iomem *base_hi,
+                               unsigned int regshift)
+{
+#define r_base(offset)    ((u8 __iomem *)base    + ((offset) << regshift))
+#define r_base_hi(offset) ((u8 __iomem *)base_hi + ((offset) << regshift))
+       *regs = (struct parport_ip32_regs){
+               .data           = r_base(0),
+               .dsr            = r_base(1),
+               .dcr            = r_base(2),
+               .eppAddr        = r_base(3),
+               .eppData0       = r_base(4),
+               .eppData1       = r_base(5),
+               .eppData2       = r_base(6),
+               .eppData3       = r_base(7),
+               .ecpAFifo       = r_base(0),
+               .fifo           = r_base_hi(0),
+               .cnfgA          = r_base_hi(0),
+               .cnfgB          = r_base_hi(1),
+               .ecr            = r_base_hi(2)
+       };
+#undef r_base_hi
+#undef r_base
+}
+
+/**
+ * parport_ip32_probe_port - probe and register IP32 built-in parallel port
+ *
+ * Returns the new allocated &parport structure.  On error, an error code is
+ * encoded in return value with the ERR_PTR function.
+ */
+static __init struct parport *parport_ip32_probe_port(void)
+{
+       struct parport_ip32_regs regs;
+       struct parport_ip32_private *priv = NULL;
+       struct parport_operations *ops = NULL;
+       struct parport *p = NULL;
+       int err;
+
+       parport_ip32_make_isa_registers(&regs, &mace->isa.parallel,
+                                       &mace->isa.ecp1284, 8 /* regshift */);
+
+       ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
+       priv = kmalloc(sizeof(struct parport_ip32_private), GFP_KERNEL);
+       p = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, ops);
+       if (ops == NULL || priv == NULL || p == NULL) {
+               err = -ENOMEM;
+               goto fail;
+       }
+       p->base = MACE_BASE + offsetof(struct sgi_mace, isa.parallel);
+       p->base_hi = MACE_BASE + offsetof(struct sgi_mace, isa.ecp1284);
+       p->private_data = priv;
+
+       *ops = parport_ip32_ops;
+       *priv = (struct parport_ip32_private){
+               .regs                   = regs,
+               .dcr_writable           = DCR_DIR | DCR_SELECT | DCR_nINIT |
+                                         DCR_AUTOFD | DCR_STROBE,
+               .irq_mode               = PARPORT_IP32_IRQ_FWD,
+       };
+       init_completion(&priv->irq_complete);
+
+       /* Probe port. */
+       if (!parport_ip32_ecp_supported(p)) {
+               err = -ENODEV;
+               goto fail;
+       }
+       parport_ip32_dump_state(p, "begin init", 0);
+
+       /* We found what looks like a working ECR register.  Simply assume
+        * that all modes are correctly supported.  Enable basic modes. */
+       p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
+       p->modes |= PARPORT_MODE_TRISTATE;
+
+       if (!parport_ip32_fifo_supported(p)) {
+               printk(KERN_WARNING PPIP32
+                      "%s: error: FIFO disabled\n", p->name);
+               /* Disable hardware modes depending on a working FIFO. */
+               features &= ~PARPORT_IP32_ENABLE_SPP;
+               features &= ~PARPORT_IP32_ENABLE_ECP;
+               /* DMA is not needed if FIFO is not supported.  */
+               features &= ~PARPORT_IP32_ENABLE_DMA;
+       }
+
+       /* Request IRQ */
+       if (features & PARPORT_IP32_ENABLE_IRQ) {
+               int irq = MACEISA_PARALLEL_IRQ;
+               if (request_irq(irq, parport_ip32_interrupt, 0, p->name, p)) {
+                       printk(KERN_WARNING PPIP32
+                              "%s: error: IRQ disabled\n", p->name);
+                       /* DMA cannot work without interrupts. */
+                       features &= ~PARPORT_IP32_ENABLE_DMA;
+               } else {
+                       pr_probe(p, "Interrupt support enabled\n");
+                       p->irq = irq;
+                       priv->dcr_writable |= DCR_IRQ;
+               }
+       }
+
+       /* Allocate DMA resources */
+       if (features & PARPORT_IP32_ENABLE_DMA) {
+               if (parport_ip32_dma_register())
+                       printk(KERN_WARNING PPIP32
+                              "%s: error: DMA disabled\n", p->name);
+               else {
+                       pr_probe(p, "DMA support enabled\n");
+                       p->dma = 0; /* arbitrary value != PARPORT_DMA_NONE */
+                       p->modes |= PARPORT_MODE_DMA;
+               }
+       }
+
+       if (features & PARPORT_IP32_ENABLE_SPP) {
+               /* Enable compatibility FIFO mode */
+               p->ops->compat_write_data = parport_ip32_compat_write_data;
+               p->modes |= PARPORT_MODE_COMPAT;
+               pr_probe(p, "Hardware support for SPP mode enabled\n");
+       }
+       if (features & PARPORT_IP32_ENABLE_EPP) {
+               /* Set up access functions to use EPP hardware. */
+               p->ops->epp_read_data = parport_ip32_epp_read_data;
+               p->ops->epp_write_data = parport_ip32_epp_write_data;
+               p->ops->epp_read_addr = parport_ip32_epp_read_addr;
+               p->ops->epp_write_addr = parport_ip32_epp_write_addr;
+               p->modes |= PARPORT_MODE_EPP;
+               pr_probe(p, "Hardware support for EPP mode enabled\n");
+       }
+       if (features & PARPORT_IP32_ENABLE_ECP) {
+               /* Enable ECP FIFO mode */
+               p->ops->ecp_write_data = parport_ip32_ecp_write_data;
+               /* FIXME - not implemented */
+/*             p->ops->ecp_read_data  = parport_ip32_ecp_read_data; */
+/*             p->ops->ecp_write_addr = parport_ip32_ecp_write_addr; */
+               p->modes |= PARPORT_MODE_ECP;
+               pr_probe(p, "Hardware support for ECP mode enabled\n");
+       }
+
+       /* Initialize the port with sensible values */
+       parport_ip32_set_mode(p, ECR_MODE_PS2);
+       parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT);
+       parport_ip32_data_forward(p);
+       parport_ip32_disable_irq(p);
+       parport_ip32_write_data(p, 0x00);
+       parport_ip32_dump_state(p, "end init", 0);
+
+       /* Print out what we found */
+       printk(KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)",
+              p->name, p->base, p->base_hi);
+       if (p->irq != PARPORT_IRQ_NONE)
+               printk(", irq %d", p->irq);
+       printk(" [");
+#define printmode(x)   if (p->modes & PARPORT_MODE_##x)                \
+                               printk("%s%s", f++ ? "," : "", #x)
+       {
+               unsigned int f = 0;
+               printmode(PCSPP);
+               printmode(TRISTATE);
+               printmode(COMPAT);
+               printmode(EPP);
+               printmode(ECP);
+               printmode(DMA);
+       }
+#undef printmode
+       printk("]\n");
+
+       parport_announce_port(p);
+       return p;
+
+fail:
+       if (p)
+               parport_put_port(p);
+       kfree(priv);
+       kfree(ops);
+       return ERR_PTR(err);
+}
+
+/**
+ * parport_ip32_unregister_port - unregister a parallel port
+ * @p:         pointer to the &struct parport
+ *
+ * Unregisters a parallel port and free previously allocated resources
+ * (memory, IRQ, ...).
+ */
+static __exit void parport_ip32_unregister_port(struct parport *p)
+{
+       struct parport_ip32_private * const priv = p->physport->private_data;
+       struct parport_operations *ops = p->ops;
+
+       parport_remove_port(p);
+       if (p->modes & PARPORT_MODE_DMA)
+               parport_ip32_dma_unregister();
+       if (p->irq != PARPORT_IRQ_NONE)
+               free_irq(p->irq, p);
+       parport_put_port(p);
+       kfree(priv);
+       kfree(ops);
+}
+
+/**
+ * parport_ip32_init - module initialization function
+ */
+static int __init parport_ip32_init(void)
+{
+       pr_info(PPIP32 "SGI IP32 built-in parallel port driver v0.6\n");
+       pr_debug1(PPIP32 "Compiled on %s, %s\n", __DATE__, __TIME__);
+       this_port = parport_ip32_probe_port();
+       return IS_ERR(this_port) ? PTR_ERR(this_port) : 0;
+}
+
+/**
+ * parport_ip32_exit - module termination function
+ */
+static void __exit parport_ip32_exit(void)
+{
+       parport_ip32_unregister_port(this_port);
+}
+
+/*--- Module stuff -----------------------------------------------------*/
+
+MODULE_AUTHOR("Arnaud Giersch <arnaud.giersch@free.fr>");
+MODULE_DESCRIPTION("SGI IP32 built-in parallel port driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.6");         /* update in parport_ip32_init() too */
+
+module_init(parport_ip32_init);
+module_exit(parport_ip32_exit);
+
+module_param(verbose_probing, bool, S_IRUGO);
+MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialization");
+
+module_param(features, uint, S_IRUGO);
+MODULE_PARM_DESC(features,
+                "Bit mask of features to enable"
+                ", bit 0: IRQ support"
+                ", bit 1: DMA support"
+                ", bit 2: hardware SPP mode"
+                ", bit 3: hardware EPP mode"
+                ", bit 4: hardware ECP mode");
+
+/*--- Inform (X)Emacs about preferred coding style ---------------------*/
+/*
+ * Local Variables:
+ * mode: c
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * tab-width: 8
+ * fill-column: 78
+ * ispell-local-dictionary: "american"
+ * End:
+ */
index 76dd077e3184f7ed85f3a78de3c8c66a29753199..166de3507780f65c7354ebf4c9548c558baf3d00 100644 (file)
@@ -329,9 +329,9 @@ static int __devinit parport_register (struct pci_dev *dev,
 
                if (priv->num_par == ARRAY_SIZE (priv->port)) {
                        printk (KERN_WARNING
-                               "parport_serial: %s: only %u parallel ports "
+                               "parport_serial: %s: only %zu parallel ports "
                                "supported (%d reported)\n", pci_name (dev),
-                               ARRAY_SIZE (priv->port), card->numports);
+                               ARRAY_SIZE(priv->port), card->numports);
                        break;
                }
 
index b62aee8de3cba0aeddae8f659b1dcadc99e1fdde..ea83b70e0de2ccf5bf03b49ea27875a5b46e1a85 100644 (file)
@@ -199,7 +199,7 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer,
 
                if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) {
                        if (belen != len) {
-                               printk (KERN_DEBUG "%s: Device ID was %d bytes"
+                               printk (KERN_DEBUG "%s: Device ID was %zd bytes"
                                        " while device told it would be %d"
                                        " bytes\n",
                                        port->name, len, belen);
@@ -214,7 +214,7 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer,
                if (buffer[len-1] == ';') {
                        printk (KERN_DEBUG "%s: Device ID reading stopped"
                                " before device told data not available. "
-                               "Current idlen %d of %d, len bytes %02X %02X\n",
+                               "Current idlen %u of %u, len bytes %02X %02X\n",
                                port->name, current_idlen, numidlens,
                                length[0], length[1]);
                        goto done;
index 6f50cc9323d9590093ae70fb986f519aceafb642..6912399d0937099c89d08d9caea2850b0b0d1337 100644 (file)
@@ -55,13 +55,21 @@ config DASD_DIAG
          Disks under VM.  If you are not running under VM or unsure what it is,
          say "N".
 
+config DASD_EER
+       tristate "Extended error reporting (EER)"
+       depends on DASD
+       help
+         This driver provides a character device interface to the
+          DASD extended error reporting. This is only needed if you want to
+          use applications written for the EER facility.
+
 config DASD_CMB
        tristate "Compatibility interface for DASD channel measurement blocks"
        depends on DASD
        help
-         This driver provides an additional interface to the channel measurement
-         facility, which is normally accessed though sysfs, with a set of
-         ioctl functions specific to the dasd driver.
+         This driver provides an additional interface to the channel
+          measurement facility, which is normally accessed though sysfs, with
+          a set of ioctl functions specific to the dasd driver.
          This is only needed if you want to use applications written for
          linux-2.4 dasd channel measurement facility interface.
 
index 58c6780134f7487dc8ba65819d0dbd476f580494..0c0d871e8f512f9a4e38acd1a813d25b321df48a 100644 (file)
@@ -5,6 +5,7 @@
 dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o
 dasd_fba_mod-objs  := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
 dasd_diag_mod-objs := dasd_diag.o
+dasd_eer_mod-objs := dasd_eer.o
 dasd_mod-objs      := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \
                        dasd_genhd.o dasd_erp.o
 
@@ -13,5 +14,6 @@ obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o
 obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o
 obj-$(CONFIG_DASD_FBA)  += dasd_fba_mod.o
 obj-$(CONFIG_DASD_CMB)  += dasd_cmb.o
+obj-$(CONFIG_DASD_EER)  += dasd_eer.o
 obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o
 obj-$(CONFIG_DCSSBLK) += dcssblk.o
index abdf1ee633e7ecf3dced11ca4850237e3b2fc807..08c88fcd896339eeb8c9700535c5aa0f620d313b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/hdreg.h>
+#include <linux/notifier.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
@@ -57,6 +58,7 @@ static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
 static void dasd_flush_ccw_queue(struct dasd_device *, int);
 static void dasd_tasklet(struct dasd_device *);
 static void do_kick_device(void *data);
+static void dasd_disable_eer(struct dasd_device *device);
 
 /*
  * SECTION: Operations on the device structure.
@@ -151,6 +153,8 @@ dasd_state_new_to_known(struct dasd_device *device)
 static inline void
 dasd_state_known_to_new(struct dasd_device * device)
 {
+       /* disable extended error reporting for this device */
+       dasd_disable_eer(device);
        /* Forget the discipline information. */
        device->discipline = NULL;
        device->state = DASD_STATE_NEW;
@@ -867,6 +871,9 @@ dasd_handle_state_change_pending(struct dasd_device *device)
        struct dasd_ccw_req *cqr;
        struct list_head *l, *n;
 
+       /* first of all call extended error reporting */
+       dasd_write_eer_trigger(DASD_EER_STATECHANGE, device, NULL);
+
        device->stopped &= ~DASD_STOPPED_PENDING;
 
         /* restart all 'running' IO on queue */
@@ -1086,6 +1093,19 @@ restart:
                        }
                        goto restart;
                }
+
+               /* first of all call extended error reporting */
+               if (device->eer && cqr->status == DASD_CQR_FAILED) {
+                       dasd_write_eer_trigger(DASD_EER_FATALERROR,
+                                              device, cqr);
+
+                       /* restart request  */
+                       cqr->status = DASD_CQR_QUEUED;
+                       cqr->retries = 255;
+                       device->stopped |= DASD_STOPPED_QUIESCE;
+                       goto restart;
+               }
+
                /* Process finished ERP request. */
                if (cqr->refers) {
                        __dasd_process_erp(device, cqr);
@@ -1223,7 +1243,8 @@ __dasd_start_head(struct dasd_device * device)
        cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
         /* check FAILFAST */
        if (device->stopped & ~DASD_STOPPED_PENDING &&
-           test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) {
+           test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+           (!device->eer)) {
                cqr->status = DASD_CQR_FAILED;
                dasd_schedule_bh(device);
        }
@@ -1965,6 +1986,9 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
        switch (event) {
        case CIO_GONE:
        case CIO_NO_PATH:
+               /* first of all call extended error reporting */
+               dasd_write_eer_trigger(DASD_EER_NOPATH, device, NULL);
+
                if (device->state < DASD_STATE_BASIC)
                        break;
                /* Device is active. We want to keep it. */
@@ -2022,6 +2046,51 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
        put_driver(drv);
 }
 
+/*
+ * notifications for extended error reports
+ */
+static struct notifier_block *dasd_eer_chain;
+
+int
+dasd_register_eer_notifier(struct notifier_block *nb)
+{
+       return notifier_chain_register(&dasd_eer_chain, nb);
+}
+
+int
+dasd_unregister_eer_notifier(struct notifier_block *nb)
+{
+       return notifier_chain_unregister(&dasd_eer_chain, nb);
+}
+
+/*
+ * Notify the registered error reporting module of a problem
+ */
+void
+dasd_write_eer_trigger(unsigned int id, struct dasd_device *device,
+                      struct dasd_ccw_req *cqr)
+{
+       if (device->eer) {
+               struct dasd_eer_trigger temp;
+               temp.id = id;
+               temp.device = device;
+               temp.cqr = cqr;
+               notifier_call_chain(&dasd_eer_chain, DASD_EER_TRIGGER,
+                                   (void *)&temp);
+       }
+}
+
+/*
+ * Tell the registered error reporting module to disable error reporting for
+ * a given device and to cleanup any private data structures on that device.
+ */
+static void
+dasd_disable_eer(struct dasd_device *device)
+{
+       notifier_call_chain(&dasd_eer_chain, DASD_EER_DISABLE, (void *)device);
+}
+
+
 static int __init
 dasd_init(void)
 {
@@ -2103,6 +2172,11 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online);
 EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
 EXPORT_SYMBOL_GPL(dasd_generic_auto_online);
 
+EXPORT_SYMBOL(dasd_register_eer_notifier);
+EXPORT_SYMBOL(dasd_unregister_eer_notifier);
+EXPORT_SYMBOL(dasd_write_eer_trigger);
+
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
index 4ee0f934e325388c779e20c05e32098b55ebe1ce..c811380b90796752e5d2fea8d98f04c6953e6a24 100644 (file)
@@ -1108,6 +1108,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
                case 0x0B:
                        DEV_MESSAGE(KERN_WARNING, device, "%s",
                                    "FORMAT F - Volume is suspended duplex");
+                       /* call extended error reporting (EER) */
+                       dasd_write_eer_trigger(DASD_EER_PPRCSUSPEND, device,
+                                              erp->refers);
                        break;
                case 0x0C:
                        DEV_MESSAGE(KERN_WARNING, device, "%s",
index bc3823d35223362d97a0b939f59ca687b1345759..e15dd79780509dc87eaa789beb05863efaf5cc64 100644 (file)
@@ -29,6 +29,7 @@
 #define DASD_ECKD_CCW_PSF               0x27
 #define DASD_ECKD_CCW_RSSD              0x3e
 #define DASD_ECKD_CCW_LOCATE_RECORD     0x47
+#define DASD_ECKD_CCW_SNSS               0x54
 #define DASD_ECKD_CCW_DEFINE_EXTENT     0x63
 #define DASD_ECKD_CCW_WRITE_MT          0x85
 #define DASD_ECKD_CCW_READ_MT           0x86
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
new file mode 100644 (file)
index 0000000..f70cd77
--- /dev/null
@@ -0,0 +1,1090 @@
+/*
+ *     character device driver for extended error reporting
+ *
+ *
+ *     Copyright (C) 2005 IBM Corporation
+ *     extended error reporting for DASD ECKD devices
+ *     Author(s): Stefan Weinhuber <wein@de.ibm.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/poll.h>
+#include <linux/notifier.h>
+
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <asm/atomic.h>
+#include <asm/ebcdic.h>
+
+#include "dasd_int.h"
+#include "dasd_eckd.h"
+
+
+MODULE_LICENSE("GPL");
+
+MODULE_AUTHOR("Stefan Weinhuber <wein@de.ibm.com>");
+MODULE_DESCRIPTION("DASD extended error reporting module");
+
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#endif                         /* PRINTK_HEADER */
+#define PRINTK_HEADER "dasd(eer):"
+
+
+
+
+
+/*****************************************************************************/
+/*      the internal buffer                                                  */
+/*****************************************************************************/
+
+/*
+ * The internal buffer is meant to store obaque blobs of data, so it doesn't
+ * know of higher level concepts like triggers.
+ * It consists of a number of pages that are used as a ringbuffer. Each data
+ * blob is stored in a simple record that consists of an integer, which
+ * contains the size of the following data, and the data bytes themselfes.
+ *
+ * To allow for multiple independent readers we create one internal buffer
+ * each time the device is opened and destroy the buffer when the file is
+ * closed again.
+ *
+ * One record can be written to a buffer by using the functions
+ * - dasd_eer_start_record (one time per record to write the size to the buffer
+ *                          and reserve the space for the data)
+ * - dasd_eer_write_buffer (one or more times per record to write the data)
+ * The data can be written in several steps but you will have to compute
+ * the total size up front for the invocation of dasd_eer_start_record.
+ * If the ringbuffer is full, dasd_eer_start_record will remove the required
+ * number of old records.
+ *
+ * A record is typically read in two steps, first read the integer that
+ * specifies the size of the following data, then read the data.
+ * Both can be done by
+ * - dasd_eer_read_buffer
+ *
+ * For all mentioned functions you need to get the bufferlock first and keep it
+ * until a complete record is written or read.
+ */
+
+
+/*
+ * Alle information necessary to keep track of an internal buffer is kept in
+ * a struct eerbuffer. The buffer specific to a file pointer is strored in
+ * the private_data field of that file. To be able to write data to all
+ * existing buffers, each buffer is also added to the bufferlist.
+ * If the user doesn't want to read a complete record in one go, we have to
+ * keep track of the rest of the record. residual stores the number of bytes
+ * that are still to deliver. If the rest of the record is invalidated between
+ * two reads then residual will be set to -1 so that the next read will fail.
+ * All entries in the eerbuffer structure are protected with the bufferlock.
+ * To avoid races between writing to a buffer on the one side and creating
+ * and destroying buffers on the other side, the bufferlock must also be used
+ * to protect the bufferlist.
+ */
+
+struct eerbuffer {
+       struct list_head list;
+       char **buffer;
+       int buffersize;
+       int buffer_page_count;
+       int head;
+        int tail;
+       int residual;
+};
+
+LIST_HEAD(bufferlist);
+
+static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED;
+
+DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue);
+
+/*
+ * How many free bytes are available on the buffer.
+ * needs to be called with bufferlock held
+ */
+static int
+dasd_eer_get_free_bytes(struct eerbuffer *eerb)
+{
+       if (eerb->head < eerb->tail) {
+               return eerb->tail - eerb->head - 1;
+       } else
+               return eerb->buffersize - eerb->head + eerb->tail -1;
+}
+
+/*
+ * How many bytes of buffer space are used.
+ * needs to be called with bufferlock held
+ */
+static int
+dasd_eer_get_filled_bytes(struct eerbuffer *eerb)
+{
+
+       if (eerb->head >= eerb->tail) {
+               return eerb->head - eerb->tail;
+       } else
+               return eerb->buffersize - eerb->tail + eerb->head;
+}
+
+/*
+ * The dasd_eer_write_buffer function just copies count bytes of data
+ * to the buffer. Make sure to call dasd_eer_start_record first, to
+ * make sure that enough free space is available.
+ * needs to be called with bufferlock held
+ */
+static void
+dasd_eer_write_buffer(struct eerbuffer *eerb, int count, char *data)
+{
+
+       unsigned long headindex,localhead;
+       unsigned long rest, len;
+       char *nextdata;
+
+       nextdata = data;
+       rest = count;
+       while (rest > 0) {
+               headindex = eerb->head / PAGE_SIZE;
+               localhead = eerb->head % PAGE_SIZE;
+               len = min(rest, (PAGE_SIZE - localhead));
+               memcpy(eerb->buffer[headindex]+localhead, nextdata, len);
+               nextdata += len;
+               rest -= len;
+               eerb->head += len;
+               if ( eerb->head == eerb->buffersize )
+                       eerb->head = 0; /* wrap around */
+               if (eerb->head > eerb->buffersize) {
+                       MESSAGE(KERN_ERR, "%s", "runaway buffer head.");
+                       BUG();
+               }
+       }
+}
+
+/*
+ * needs to be called with bufferlock held
+ */
+static int
+dasd_eer_read_buffer(struct eerbuffer *eerb, int count, char *data)
+{
+
+       unsigned long tailindex,localtail;
+       unsigned long rest, len, finalcount;
+       char *nextdata;
+
+       finalcount = min(count, dasd_eer_get_filled_bytes(eerb));
+       nextdata = data;
+       rest = finalcount;
+       while (rest > 0) {
+               tailindex = eerb->tail / PAGE_SIZE;
+               localtail = eerb->tail % PAGE_SIZE;
+               len = min(rest, (PAGE_SIZE - localtail));
+               memcpy(nextdata, eerb->buffer[tailindex]+localtail, len);
+               nextdata += len;
+               rest -= len;
+               eerb->tail += len;
+               if ( eerb->tail == eerb->buffersize )
+                       eerb->tail = 0; /* wrap around */
+               if (eerb->tail > eerb->buffersize) {
+                       MESSAGE(KERN_ERR, "%s", "runaway buffer tail.");
+                       BUG();
+               }
+       }
+       return finalcount;
+}
+
+/*
+ * Whenever you want to write a blob of data to the internal buffer you
+ * have to start by using this function first. It will write the number
+ * of bytes that will be written to the buffer. If necessary it will remove
+ * old records to make room for the new one.
+ * needs to be called with bufferlock held
+ */
+static int
+dasd_eer_start_record(struct eerbuffer *eerb, int count)
+{
+       int tailcount;
+       if (count + sizeof(count) > eerb->buffersize)
+               return -ENOMEM;
+       while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) {
+               if (eerb->residual > 0) {
+                       eerb->tail += eerb->residual;
+                       if (eerb->tail >= eerb->buffersize)
+                               eerb->tail -= eerb->buffersize;
+                       eerb->residual = -1;
+               }
+               dasd_eer_read_buffer(eerb, sizeof(tailcount),
+                                    (char*)(&tailcount));
+               eerb->tail += tailcount;
+               if (eerb->tail >= eerb->buffersize)
+                       eerb->tail -= eerb->buffersize;
+       }
+       dasd_eer_write_buffer(eerb, sizeof(count), (char*)(&count));
+
+       return 0;
+};
+
+/*
+ * release pages that are not used anymore
+ */
+static void
+dasd_eer_free_buffer_pages(char **buf, int no_pages)
+{
+       int i;
+
+       for (i = 0; i < no_pages; ++i) {
+               free_page((unsigned long)buf[i]);
+       }
+}
+
+/*
+ * allocate a new set of memory pages
+ */
+static int
+dasd_eer_allocate_buffer_pages(char **buf, int no_pages)
+{
+       int i;
+
+       for (i = 0; i < no_pages; ++i) {
+               buf[i] = (char *) get_zeroed_page(GFP_KERNEL);
+               if (!buf[i]) {
+                       dasd_eer_free_buffer_pages(buf, i);
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
+/*
+ * empty the buffer by resetting head and tail
+ * In case there is a half read data blob in the buffer, we set residual
+ * to -1 to indicate that the remainder of the blob is lost.
+ */
+static void
+dasd_eer_purge_buffer(struct eerbuffer *eerb)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&bufferlock, flags);
+       if (eerb->residual > 0)
+               eerb->residual = -1;
+       eerb->tail=0;
+       eerb->head=0;
+       spin_unlock_irqrestore(&bufferlock, flags);
+}
+
+/*
+ * set the size of the buffer, newsize is the new number of pages to be used
+ * we don't try to copy any data back an forth, so any resize will also purge
+ * the buffer
+ */
+static int
+dasd_eer_resize_buffer(struct eerbuffer *eerb, int newsize)
+{
+       int i, oldcount, reuse;
+       char **new;
+       char **old;
+       unsigned long flags;
+
+       if (newsize < 1)
+               return -EINVAL;
+       if (eerb->buffer_page_count == newsize) {
+               /* documented behaviour is that any successfull invocation
+                 * will purge all records */
+               dasd_eer_purge_buffer(eerb);
+               return 0;
+       }
+       new = kmalloc(newsize*sizeof(char*), GFP_KERNEL);
+       if (!new)
+               return -ENOMEM;
+
+       reuse=min(eerb->buffer_page_count, newsize);
+       for (i = 0; i < reuse; ++i) {
+               new[i] = eerb->buffer[i];
+       }
+       if (eerb->buffer_page_count < newsize) {
+               if (dasd_eer_allocate_buffer_pages(
+                           &new[eerb->buffer_page_count],
+                           newsize - eerb->buffer_page_count)) {
+                       kfree(new);
+                       return -ENOMEM;
+               }
+       }
+
+       spin_lock_irqsave(&bufferlock, flags);
+       old = eerb->buffer;
+       eerb->buffer = new;
+       if (eerb->residual > 0)
+               eerb->residual = -1;
+       eerb->tail = 0;
+       eerb->head = 0;
+       oldcount = eerb->buffer_page_count;
+       eerb->buffer_page_count = newsize;
+       spin_unlock_irqrestore(&bufferlock, flags);
+
+       if (oldcount > newsize) {
+               for (i = newsize; i < oldcount; ++i) {
+                       free_page((unsigned long)old[i]);
+               }
+       }
+       kfree(old);
+
+       return 0;
+}
+
+
+/*****************************************************************************/
+/*      The extended error reporting functionality                           */
+/*****************************************************************************/
+
+/*
+ * When a DASD device driver wants to report an error, it calls the
+ * function dasd_eer_write_trigger (via a notifier mechanism) and gives the
+ * respective trigger ID as parameter.
+ * Currently there are four kinds of triggers:
+ *
+ * DASD_EER_FATALERROR:  all kinds of unrecoverable I/O problems
+ * DASD_EER_PPRCSUSPEND: PPRC was suspended
+ * DASD_EER_NOPATH:      There is no path to the device left.
+ * DASD_EER_STATECHANGE: The state of the device has changed.
+ *
+ * For the first three triggers all required information can be supplied by
+ * the caller. For these triggers a record is written by the function
+ * dasd_eer_write_standard_trigger.
+ *
+ * When dasd_eer_write_trigger is called to write a DASD_EER_STATECHANGE
+ * trigger, we have to gather the necessary sense data first. We cannot queue
+ * the necessary SNSS (sense subsystem status) request immediatly, since we
+ * are likely to run in a deadlock situation. Instead, we schedule a
+ * work_struct that calls the function dasd_eer_sense_subsystem_status to
+ * create and start an SNSS  request asynchronously.
+ *
+ * To avoid memory allocations at runtime, the necessary memory is allocated
+ * when the extended error reporting is enabled for a device (by
+ * dasd_eer_probe). There is one private eer data structure for each eer
+ * enabled DASD device. It contains memory for the work_struct, one SNSS cqr
+ * and a flags field that is used to coordinate the use of the cqr. The call
+ * to write a state change trigger can come in at any time, so we have one flag
+ * CQR_IN_USE that protects the cqr itself. When this flag indicates that the
+ * cqr is currently in use, dasd_eer_sense_subsystem_status cannot start a
+ * second request but sets the SNSS_REQUESTED flag instead.
+ *
+ * When the request is finished, the callback function dasd_eer_SNSS_cb
+ * is called. This function will invoke the function
+ * dasd_eer_write_SNSS_trigger to finally write the trigger. It will also
+ * check the SNSS_REQUESTED flag and if it is set it will call
+ * dasd_eer_sense_subsystem_status again.
+ *
+ * To avoid race conditions during the handling of the lock, the flags must
+ * be protected by the snsslock.
+ */
+
+struct dasd_eer_private {
+       struct dasd_ccw_req *cqr;
+       unsigned long flags;
+       struct work_struct worker;
+};
+
+static void dasd_eer_destroy(struct dasd_device *device,
+                            struct dasd_eer_private *eer);
+static int
+dasd_eer_write_trigger(struct dasd_eer_trigger *trigger);
+static void dasd_eer_sense_subsystem_status(void *data);
+static int dasd_eer_notify(struct notifier_block *self,
+                          unsigned long action, void *data);
+
+struct workqueue_struct *dasd_eer_workqueue;
+
+#define SNSS_DATA_SIZE 44
+static spinlock_t snsslock = SPIN_LOCK_UNLOCKED;
+
+#define DASD_EER_BUSID_SIZE 10
+struct dasd_eer_header {
+       __u32 total_size;
+       __u32 trigger;
+       __u64 tv_sec;
+       __u64 tv_usec;
+       char busid[DASD_EER_BUSID_SIZE];
+} __attribute__ ((packed));
+
+static struct notifier_block dasd_eer_nb = {
+       .notifier_call = dasd_eer_notify,
+};
+
+/*
+ * flags for use with dasd_eer_private
+ */
+#define CQR_IN_USE     0
+#define SNSS_REQUESTED 1
+
+/*
+ * This function checks if extended error reporting is available for a given
+ * dasd_device. If yes, then it creates and returns a struct dasd_eer,
+ * otherwise it returns an -EPERM error pointer.
+ */
+struct dasd_eer_private *
+dasd_eer_probe(struct dasd_device *device)
+{
+       struct dasd_eer_private *private;
+
+       if (!(device && device->discipline
+             && !strcmp(device->discipline->name, "ECKD"))) {
+               return ERR_PTR(-EPERM);
+       }
+       /* allocate the private data structure */
+       private = (struct dasd_eer_private *)kmalloc(
+               sizeof(struct dasd_eer_private), GFP_KERNEL);
+       if (!private) {
+               return ERR_PTR(-ENOMEM);
+       }
+       INIT_WORK(&private->worker, dasd_eer_sense_subsystem_status,
+                 (void *)device);
+       private->cqr = dasd_kmalloc_request("ECKD",
+                                           1 /* SNSS */ ,
+                                           SNSS_DATA_SIZE ,
+                                           device);
+       if (!private->cqr) {
+               kfree(private);
+               return ERR_PTR(-ENOMEM);
+       }
+       private->flags = 0;
+       return private;
+};
+
+/*
+ * If our private SNSS request is queued, remove it from the
+ * dasd ccw queue so we can free the requests memory.
+ */
+static void
+dasd_eer_dequeue_SNSS_request(struct dasd_device *device,
+                             struct dasd_eer_private *eer)
+{
+       struct list_head *lst, *nxt;
+       struct dasd_ccw_req *cqr, *erpcqr;
+       dasd_erp_fn_t erp_fn;
+
+       spin_lock_irq(get_ccwdev_lock(device->cdev));
+       list_for_each_safe(lst, nxt, &device->ccw_queue) {
+               cqr = list_entry(lst, struct dasd_ccw_req, list);
+               /* we are looking for two kinds or requests */
+               /* first kind: our SNSS request: */
+               if (cqr == eer->cqr) {
+                       if (cqr->status == DASD_CQR_IN_IO)
+                               device->discipline->term_IO(cqr);
+                       list_del(&cqr->list);
+                       break;
+               }
+               /* second kind: ERP requests for our SNSS request */
+               if (cqr->refers) {
+                       /* If this erp request chain ends in our cqr, then */
+                        /* cal the erp_postaction to clean it up  */
+                       erpcqr = cqr;
+                       while (erpcqr->refers) {
+                               erpcqr = erpcqr->refers;
+                       }
+                       if (erpcqr == eer->cqr) {
+                               erp_fn = device->discipline->erp_postaction(
+                                        cqr);
+                               erp_fn(cqr);
+                       }
+                       continue;
+               }
+       }
+       spin_unlock_irq(get_ccwdev_lock(device->cdev));
+}
+
+/*
+ * This function dismantles a struct dasd_eer that was created by
+ * dasd_eer_probe. Since we want to free our private data structure,
+ * we must make sure that the memory is not in use anymore.
+ * We have to flush the work queue and remove a possible SNSS request
+ * from the dasd queue.
+ */
+static void
+dasd_eer_destroy(struct dasd_device *device, struct dasd_eer_private *eer)
+{
+       flush_workqueue(dasd_eer_workqueue);
+       dasd_eer_dequeue_SNSS_request(device, eer);
+       dasd_kfree_request(eer->cqr, device);
+       kfree(eer);
+};
+
+/*
+ * enable the extended error reporting for a particular device
+ */
+static int
+dasd_eer_enable_on_device(struct dasd_device *device)
+{
+       void *eer;
+       if (!device)
+               return -ENODEV;
+       if (device->eer)
+               return 0;
+       if (!try_module_get(THIS_MODULE)) {
+               return -EINVAL;
+       }
+       eer = (void *)dasd_eer_probe(device);
+       if (IS_ERR(eer)) {
+               module_put(THIS_MODULE);
+               return PTR_ERR(eer);
+       }
+       device->eer = eer;
+       return 0;
+}
+
+/*
+ * enable the extended error reporting for a particular device
+ */
+static int
+dasd_eer_disable_on_device(struct dasd_device *device)
+{
+       struct dasd_eer_private *eer = device->eer;
+
+       if (!device)
+               return -ENODEV;
+       if (!device->eer)
+               return 0;
+       device->eer = NULL;
+       dasd_eer_destroy(device,eer);
+       module_put(THIS_MODULE);
+
+       return 0;
+}
+
+/*
+ * Set extended error reporting (eer)
+ * Note: This will be registered as a DASD ioctl, to be called on DASD devices.
+ */
+static int
+dasd_ioctl_set_eer(struct block_device *bdev, int no, long args)
+{
+       struct dasd_device *device;
+       int intval;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (bdev != bdev->bd_contains)
+               /* Error-reporting is not allowed for partitions */
+               return -EINVAL;
+       if (get_user(intval, (int __user *) args))
+               return -EFAULT;
+       device =  bdev->bd_disk->private_data;
+       if (device == NULL)
+               return -ENODEV;
+
+       intval = (intval != 0);
+       DEV_MESSAGE (KERN_DEBUG, device,
+                    "set eer on device to %d", intval);
+       if (intval)
+               return dasd_eer_enable_on_device(device);
+       else
+               return dasd_eer_disable_on_device(device);
+}
+
+/*
+ * Get value of extended error reporting.
+ * Note: This will be registered as a DASD ioctl, to be called on DASD devices.
+ */
+static int
+dasd_ioctl_get_eer(struct block_device *bdev, int no, long args)
+{
+       struct dasd_device *device;
+
+       device =  bdev->bd_disk->private_data;
+       if (device == NULL)
+               return -ENODEV;
+       return put_user((device->eer != NULL), (int __user *) args);
+}
+
+/*
+ * The following function can be used for those triggers that have
+ * all necessary data available when the function is called.
+ * If the parameter cqr is not NULL, the chain of requests will be searched
+ * for valid sense data, and all valid sense data sets will be added to
+ * the triggers data.
+ */
+static int
+dasd_eer_write_standard_trigger(int trigger, struct dasd_device *device,
+                               struct dasd_ccw_req *cqr)
+{
+       struct dasd_ccw_req *temp_cqr;
+       int data_size;
+       struct timeval tv;
+       struct dasd_eer_header header;
+       unsigned long flags;
+       struct eerbuffer *eerb;
+
+       /* go through cqr chain and count the valid sense data sets */
+       temp_cqr = cqr;
+       data_size = 0;
+       while (temp_cqr) {
+               if (temp_cqr->irb.esw.esw0.erw.cons)
+                       data_size += 32;
+               temp_cqr = temp_cqr->refers;
+       }
+
+       header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
+       header.trigger = trigger;
+       do_gettimeofday(&tv);
+       header.tv_sec = tv.tv_sec;
+       header.tv_usec = tv.tv_usec;
+       strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
+
+       spin_lock_irqsave(&bufferlock, flags);
+       list_for_each_entry(eerb, &bufferlist, list) {
+               dasd_eer_start_record(eerb, header.total_size);
+               dasd_eer_write_buffer(eerb, sizeof(header), (char*)(&header));
+               temp_cqr = cqr;
+               while (temp_cqr) {
+                       if (temp_cqr->irb.esw.esw0.erw.cons)
+                               dasd_eer_write_buffer(eerb, 32, cqr->irb.ecw);
+                       temp_cqr = temp_cqr->refers;
+               }
+               dasd_eer_write_buffer(eerb, 4,"EOR");
+       }
+       spin_unlock_irqrestore(&bufferlock, flags);
+
+       wake_up_interruptible(&dasd_eer_read_wait_queue);
+
+       return 0;
+}
+
+/*
+ * This function writes a DASD_EER_STATECHANGE trigger.
+ */
+static void
+dasd_eer_write_SNSS_trigger(struct dasd_device *device,
+                           struct dasd_ccw_req *cqr)
+{
+       int data_size;
+       int snss_rc;
+       struct timeval tv;
+       struct dasd_eer_header header;
+       unsigned long flags;
+       struct eerbuffer *eerb;
+
+       snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
+       if (snss_rc)
+               data_size = 0;
+       else
+               data_size = SNSS_DATA_SIZE;
+
+       header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
+       header.trigger = DASD_EER_STATECHANGE;
+       do_gettimeofday(&tv);
+       header.tv_sec = tv.tv_sec;
+       header.tv_usec = tv.tv_usec;
+       strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
+
+       spin_lock_irqsave(&bufferlock, flags);
+       list_for_each_entry(eerb, &bufferlist, list) {
+               dasd_eer_start_record(eerb, header.total_size);
+               dasd_eer_write_buffer(eerb, sizeof(header),(char*)(&header));
+               if (!snss_rc)
+                       dasd_eer_write_buffer(eerb, SNSS_DATA_SIZE, cqr->data);
+               dasd_eer_write_buffer(eerb, 4,"EOR");
+       }
+       spin_unlock_irqrestore(&bufferlock, flags);
+
+       wake_up_interruptible(&dasd_eer_read_wait_queue);
+}
+
+/*
+ * callback function for use with SNSS request
+ */
+static void
+dasd_eer_SNSS_cb(struct dasd_ccw_req *cqr, void *data)
+{
+        struct dasd_device *device;
+       struct dasd_eer_private *private;
+       unsigned long irqflags;
+
+        device = (struct dasd_device *)data;
+       private = (struct dasd_eer_private *)device->eer;
+       dasd_eer_write_SNSS_trigger(device, cqr);
+       spin_lock_irqsave(&snsslock, irqflags);
+       if(!test_and_clear_bit(SNSS_REQUESTED, &private->flags)) {
+               clear_bit(CQR_IN_USE, &private->flags);
+               spin_unlock_irqrestore(&snsslock, irqflags);
+               return;
+       };
+       clear_bit(CQR_IN_USE, &private->flags);
+       spin_unlock_irqrestore(&snsslock, irqflags);
+       dasd_eer_sense_subsystem_status(device);
+       return;
+}
+
+/*
+ * clean a used cqr before using it again
+ */
+static void
+dasd_eer_clean_SNSS_request(struct dasd_ccw_req *cqr)
+{
+       struct ccw1 *cpaddr = cqr->cpaddr;
+       void *data = cqr->data;
+
+       memset(cqr, 0, sizeof(struct dasd_ccw_req));
+       memset(cpaddr, 0, sizeof(struct ccw1));
+       memset(data, 0, SNSS_DATA_SIZE);
+       cqr->cpaddr = cpaddr;
+       cqr->data = data;
+       strncpy((char *) &cqr->magic, "ECKD", 4);
+       ASCEBC((char *) &cqr->magic, 4);
+       set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+}
+
+/*
+ * build and start an SNSS request
+ * This function is called from a work queue so we have to
+ * pass the dasd_device pointer as a void pointer.
+ */
+static void
+dasd_eer_sense_subsystem_status(void *data)
+{
+       struct dasd_device *device;
+       struct dasd_eer_private *private;
+       struct dasd_ccw_req *cqr;
+       struct ccw1 *ccw;
+       unsigned long irqflags;
+
+       device = (struct dasd_device *)data;
+       private = (struct dasd_eer_private *)device->eer;
+       if (!private) /* device not eer enabled any more */
+               return;
+       cqr = private->cqr;
+       spin_lock_irqsave(&snsslock, irqflags);
+       if(test_and_set_bit(CQR_IN_USE, &private->flags)) {
+               set_bit(SNSS_REQUESTED, &private->flags);
+               spin_unlock_irqrestore(&snsslock, irqflags);
+               return;
+       };
+       spin_unlock_irqrestore(&snsslock, irqflags);
+       dasd_eer_clean_SNSS_request(cqr);
+       cqr->device = device;
+       cqr->retries = 255;
+       cqr->expires = 10 * HZ;
+
+       ccw = cqr->cpaddr;
+       ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+       ccw->count = SNSS_DATA_SIZE;
+       ccw->flags = 0;
+       ccw->cda = (__u32)(addr_t)cqr->data;
+
+       cqr->buildclk = get_clock();
+       cqr->status = DASD_CQR_FILLED;
+       cqr->callback = dasd_eer_SNSS_cb;
+       cqr->callback_data = (void *)device;
+        dasd_add_request_head(cqr);
+
+       return;
+}
+
+/*
+ * This function is called for all triggers. It calls the appropriate
+ * function that writes the actual trigger records.
+ */
+static int
+dasd_eer_write_trigger(struct dasd_eer_trigger *trigger)
+{
+       int rc;
+       struct dasd_eer_private *private = trigger->device->eer;
+
+       switch (trigger->id) {
+       case DASD_EER_FATALERROR:
+       case DASD_EER_PPRCSUSPEND:
+               rc = dasd_eer_write_standard_trigger(
+                       trigger->id, trigger->device, trigger->cqr);
+               break;
+       case DASD_EER_NOPATH:
+               rc = dasd_eer_write_standard_trigger(
+                       trigger->id, trigger->device, NULL);
+               break;
+       case DASD_EER_STATECHANGE:
+                if (queue_work(dasd_eer_workqueue, &private->worker)) {
+                        rc=0;
+                } else {
+                        /* If the work_struct was already queued, it can't
+                         * be queued again. But this is OK since we don't
+                         * need to have it queued twice.
+                         */
+                        rc = -EBUSY;
+                }
+               break;
+       default: /* unknown trigger, so we write it without any sense data */
+               rc = dasd_eer_write_standard_trigger(
+                       trigger->id, trigger->device, NULL);
+               break;
+       }
+       return rc;
+}
+
+/*
+ * This function is registered with the dasd device driver and gets called
+ * for all dasd eer notifications.
+ */
+static int dasd_eer_notify(struct notifier_block *self,
+                           unsigned long action, void *data)
+{
+       switch (action) {
+       case DASD_EER_DISABLE:
+               dasd_eer_disable_on_device((struct dasd_device *)data);
+               break;
+       case DASD_EER_TRIGGER:
+               dasd_eer_write_trigger((struct dasd_eer_trigger *)data);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+
+/*****************************************************************************/
+/*      the device operations                                                */
+/*****************************************************************************/
+
+/*
+ * On the one side we need a lock to access our internal buffer, on the
+ * other side a copy_to_user can sleep. So we need to copy the data we have
+ * to transfer in a readbuffer, which is protected by the readbuffer_mutex.
+ */
+static char readbuffer[PAGE_SIZE];
+DECLARE_MUTEX(readbuffer_mutex);
+
+
+static int
+dasd_eer_open(struct inode *inp, struct file *filp)
+{
+       struct eerbuffer *eerb;
+       unsigned long flags;
+
+       eerb = kmalloc(sizeof(struct eerbuffer), GFP_KERNEL);
+       eerb->head = 0;
+       eerb->tail = 0;
+       eerb->residual = 0;
+       eerb->buffer_page_count = 1;
+       eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
+        eerb->buffer = kmalloc(eerb->buffer_page_count*sizeof(char*),
+                              GFP_KERNEL);
+        if (!eerb->buffer)
+                return -ENOMEM;
+       if (dasd_eer_allocate_buffer_pages(eerb->buffer,
+                                          eerb->buffer_page_count)) {
+               kfree(eerb->buffer);
+               return -ENOMEM;
+       }
+       filp->private_data = eerb;
+       spin_lock_irqsave(&bufferlock, flags);
+       list_add(&eerb->list, &bufferlist);
+       spin_unlock_irqrestore(&bufferlock, flags);
+
+       return nonseekable_open(inp,filp);
+}
+
+static int
+dasd_eer_close(struct inode *inp, struct file *filp)
+{
+       struct eerbuffer *eerb;
+       unsigned long flags;
+
+       eerb = (struct eerbuffer *)filp->private_data;
+       spin_lock_irqsave(&bufferlock, flags);
+       list_del(&eerb->list);
+       spin_unlock_irqrestore(&bufferlock, flags);
+       dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count);
+       kfree(eerb->buffer);
+       kfree(eerb);
+
+       return 0;
+}
+
+static long
+dasd_eer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int intval;
+       struct eerbuffer *eerb;
+
+       eerb = (struct eerbuffer *)filp->private_data;
+       switch (cmd) {
+       case DASD_EER_PURGE:
+               dasd_eer_purge_buffer(eerb);
+               return 0;
+       case DASD_EER_SETBUFSIZE:
+               if (get_user(intval, (int __user *)arg))
+                       return -EFAULT;
+               return dasd_eer_resize_buffer(eerb, intval);
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static ssize_t
+dasd_eer_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
+{
+       int tc,rc;
+       int tailcount,effective_count;
+        unsigned long flags;
+       struct eerbuffer *eerb;
+
+       eerb = (struct eerbuffer *)filp->private_data;
+       if(down_interruptible(&readbuffer_mutex))
+               return -ERESTARTSYS;
+
+       spin_lock_irqsave(&bufferlock, flags);
+
+       if (eerb->residual < 0) { /* the remainder of this record */
+                                 /* has been deleted             */
+               eerb->residual = 0;
+               spin_unlock_irqrestore(&bufferlock, flags);
+               up(&readbuffer_mutex);
+               return -EIO;
+       } else if (eerb->residual > 0) {
+               /* OK we still have a second half of a record to deliver */
+               effective_count = min(eerb->residual, (int)count);
+               eerb->residual -= effective_count;
+       } else {
+               tc = 0;
+               while (!tc) {
+                       tc = dasd_eer_read_buffer(eerb,
+                               sizeof(tailcount), (char*)(&tailcount));
+                       if (!tc) {
+                               /* no data available */
+                               spin_unlock_irqrestore(&bufferlock, flags);
+                               up(&readbuffer_mutex);
+                               if (filp->f_flags & O_NONBLOCK)
+                                       return -EAGAIN;
+                               rc = wait_event_interruptible(
+                                       dasd_eer_read_wait_queue,
+                                       eerb->head != eerb->tail);
+                               if (rc) {
+                                       return rc;
+                               }
+                               if(down_interruptible(&readbuffer_mutex))
+                                       return -ERESTARTSYS;
+                               spin_lock_irqsave(&bufferlock, flags);
+                       }
+               }
+               WARN_ON(tc != sizeof(tailcount));
+               effective_count = min(tailcount,(int)count);
+               eerb->residual = tailcount - effective_count;
+       }
+
+       tc = dasd_eer_read_buffer(eerb, effective_count, readbuffer);
+       WARN_ON(tc != effective_count);
+
+       spin_unlock_irqrestore(&bufferlock, flags);
+
+       if (copy_to_user(buf, readbuffer, effective_count)) {
+               up(&readbuffer_mutex);
+               return -EFAULT;
+       }
+
+       up(&readbuffer_mutex);
+       return effective_count;
+}
+
+static unsigned int
+dasd_eer_poll (struct file *filp, poll_table *ptable)
+{
+       unsigned int mask;
+       unsigned long flags;
+       struct eerbuffer *eerb;
+
+       eerb = (struct eerbuffer *)filp->private_data;
+       poll_wait(filp, &dasd_eer_read_wait_queue, ptable);
+       spin_lock_irqsave(&bufferlock, flags);
+       if (eerb->head != eerb->tail)
+               mask = POLLIN | POLLRDNORM ;
+       else
+               mask = 0;
+       spin_unlock_irqrestore(&bufferlock, flags);
+       return mask;
+}
+
+static struct file_operations dasd_eer_fops = {
+       .open           = &dasd_eer_open,
+       .release        = &dasd_eer_close,
+       .unlocked_ioctl = &dasd_eer_ioctl,
+       .compat_ioctl   = &dasd_eer_ioctl,
+       .read           = &dasd_eer_read,
+       .poll           = &dasd_eer_poll,
+       .owner          = THIS_MODULE,
+};
+
+static struct miscdevice dasd_eer_dev = {
+       .minor      = MISC_DYNAMIC_MINOR,
+       .name       = "dasd_eer",
+       .fops       = &dasd_eer_fops,
+};
+
+
+/*****************************************************************************/
+/*     Init and exit                                                        */
+/*****************************************************************************/
+
+static int
+__init dasd_eer_init(void)
+{
+       int rc;
+
+       dasd_eer_workqueue = create_singlethread_workqueue("dasd_eer");
+       if (!dasd_eer_workqueue) {
+               MESSAGE(KERN_ERR , "%s", "dasd_eer_init could not "
+                      "create workqueue \n");
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       rc = dasd_register_eer_notifier(&dasd_eer_nb);
+       if (rc) {
+               MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+                      "register error reporting");
+               goto queue;
+       }
+
+       dasd_ioctl_no_register(THIS_MODULE, BIODASDEERSET, dasd_ioctl_set_eer);
+       dasd_ioctl_no_register(THIS_MODULE, BIODASDEERGET, dasd_ioctl_get_eer);
+
+       /* we don't need our own character device,
+        * so we just register as misc device */
+       rc = misc_register(&dasd_eer_dev);
+       if (rc) {
+               MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+                      "register misc device");
+               goto unregister;
+       }
+
+       return 0;
+
+unregister:
+       dasd_unregister_eer_notifier(&dasd_eer_nb);
+       dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET,
+                                dasd_ioctl_set_eer);
+       dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET,
+                                dasd_ioctl_get_eer);
+queue:
+       destroy_workqueue(dasd_eer_workqueue);
+out:
+       return rc;
+
+}
+module_init(dasd_eer_init);
+
+static void
+__exit dasd_eer_exit(void)
+{
+       dasd_unregister_eer_notifier(&dasd_eer_nb);
+       dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET,
+                                dasd_ioctl_set_eer);
+       dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET,
+                                dasd_ioctl_get_eer);
+       destroy_workqueue(dasd_eer_workqueue);
+
+       WARN_ON(misc_deregister(&dasd_eer_dev) != 0);
+}
+module_exit(dasd_eer_exit);
index c20af9874500019fff41d20b7d200cfd84f187c1..d1b08fa13fd224184a9387625c218302b1724eed 100644 (file)
@@ -275,6 +275,34 @@ struct dasd_discipline {
 
 extern struct dasd_discipline *dasd_diag_discipline_pointer;
 
+
+/*
+ * Notification numbers for extended error reporting notifications:
+ * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's
+ * eer pointer) is freed. The error reporting module needs to do all necessary
+ * cleanup steps.
+ * The DASD_EER_TRIGGER notification sends the actual error reports (triggers).
+ */
+#define DASD_EER_DISABLE 0
+#define DASD_EER_TRIGGER 1
+
+/* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */
+#define DASD_EER_FATALERROR  1
+#define DASD_EER_NOPATH      2
+#define DASD_EER_STATECHANGE 3
+#define DASD_EER_PPRCSUSPEND 4
+
+/*
+ * The dasd_eer_trigger structure contains all data that we need to send
+ * along with an DASD_EER_TRIGGER notification.
+ */
+struct dasd_eer_trigger {
+       unsigned int id;
+       struct dasd_device *device;
+       struct dasd_ccw_req *cqr;
+};
+
+
 struct dasd_device {
        /* Block device stuff. */
        struct gendisk *gdp;
@@ -288,6 +316,9 @@ struct dasd_device {
        unsigned long flags;            /* per device flags */
        unsigned short features;        /* copy of devmap-features (read-only!) */
 
+       /* extended error reporting stuff (eer) */
+       void *eer;
+
        /* Device discipline stuff. */
        struct dasd_discipline *discipline;
        char *private;
@@ -488,6 +519,12 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
 int dasd_generic_set_offline (struct ccw_device *cdev);
 int dasd_generic_notify(struct ccw_device *, int);
 void dasd_generic_auto_online (struct ccw_driver *);
+int dasd_register_eer_notifier(struct notifier_block *);
+int dasd_unregister_eer_notifier(struct notifier_block *);
+void dasd_write_eer_trigger(unsigned int , struct dasd_device *,
+                       struct dasd_ccw_req *);
+
+
 
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
index 44e4b4bb1c5abf86c7f069fc2759209f4c556ea8..3e75095f35d03e70f21bb43304d9fa537258c8fa 100644 (file)
@@ -68,6 +68,6 @@ extern void *chsc_get_chp_desc(struct subchannel*, int);
 
 extern int chsc_enable_facility(int);
 
-#define to_channelpath(dev) container_of(dev, struct channel_path, dev)
+#define to_channelpath(device) container_of(device, struct channel_path, dev)
 
 #endif
index 38d6d00fb0fcc593ab3931c7e6026e7ddffa8e39..014cc8d54a9fc26861598a3f9182f763476dd5c5 100644 (file)
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <asm/semaphore.h>
-#include <asm/delay.h>
 
 #include "aacraid.h"
 
index 311a4122bd7094b6ddd49af223abe08d3a40dc01..93edaa8696cf35e0b54a72dc3cfd266931e2c18b 100644 (file)
@@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev)
        free_irq(fp->intr, fp);
 
        if (fp->regs)
-               iounmap((void *) fp->regs);
+               iounmap(fp->regs);
        if (fp->dma)
-               iounmap((void *) fp->dma);
+               iounmap(fp->dma);
        kfree(fp->dma_cmd_space);
 
        scsi_host_put(host);
index 245ca99a641eb6432ee14434500531d36675fb22..c551bb84dbfb6c46351624dcf640d3ac9be44ca4 100644 (file)
@@ -1245,7 +1245,7 @@ static int __init init_scsi(void)
        if (error)
                goto cleanup_sysctl;
 
-       for (i = 0; i < NR_CPUS; i++)
+       for_each_cpu(i)
                INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
 
        devfs_mk_dir("scsi");
index 59a1c9d9d3bdc174eabed3553db658367288da44..723f7acbeb12b48c830f1e59ce3679478c633f2a 100644 (file)
@@ -463,7 +463,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb)
 }
 
 static void*
-mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
 {
        struct mempool_zone *zone = pool_data;
 
index 7d0700091f3d6417e8c37ab6919b6a0de32042a9..2a547538d444fc94c836933e5fefd9d301d2493e 100644 (file)
@@ -1679,7 +1679,7 @@ static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
        int sg_bufflen = tablesize * sizeof(struct scatterlist);
-       unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
+       gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
        /*
         * TODO: test without low_dma, we should not need it since
index 7aef7518b0d1cb4291d38ad3f4e860d67dbbd9a0..8c5c276c55771eb297fa756ed2cf23e0159d8fc2 100644 (file)
@@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = {
 
 static struct uart_port serial21285_port = {
        .mapbase        = 0x42000160,
-       .iotype         = SERIAL_IO_MEM,
+       .iotype         = UPIO_MEM,
        .irq            = NO_IRQ,
        .fifosize       = 16,
        .ops            = &serial21285_ops,
index 8cbf0fc5a225ce0ba54a8a9eeb85ce65e15bfd12..7f0f35a05dcac35e30a05cce2f962ccf7e0510e6 100644 (file)
@@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
                 * Make sure that we do not overflow the buffer
                 */
                if (tty_request_buffer_room(tty, 1) == 0) {
-                       schedule_work(&tty->flip.work);
+                       tty_schedule_flip(tty);
                        return;
                }
 
@@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
        } while((rx = uart->urx.w) & URX_DATA_READY);
 #endif
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 
 clear_and_exit:
        return;
index 60f5a5dc17f1cf1cf4e10c38127690872d1df1bc..9843ae3d420e24f1441efc6513f0ed1ddbb945b2 100644 (file)
@@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
 
        info->rx_cur = (QUICC_BD *)bdp;
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void receive_break(ser_info_t *info)
@@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info)
         * the break.  If not, we exit now, losing the break.  FIXME
         */
        tty_insert_flip_char(tty, 0, TTY_BREAK);
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
index 179c1f065e60a5662498c006f28c48b83828baa1..b1fc97d5f643ea4772b44e22b148b642b279670d 100644 (file)
@@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
         *      and restore the IER
         */
        wait_for_xmitr(up, BOTH_EMPTY);
+       up->ier |= UART_IER_THRI;
        serial_out(up, UART_IER, ier | UART_IER_THRI);
 }
 
index 06ae8fbcc9471e3efa1e7407666f68497f4d9e60..8d8d7a70d03e894629b888c7404fe24afeb9abf7 100644 (file)
@@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = {
 #elif defined(CONFIG_SOC_AU1550)
        PORT(UART0_ADDR, AU1550_UART0_INT),
        PORT(UART1_ADDR, AU1550_UART1_INT),
-       PORT(UART2_ADDR, AU1550_UART2_INT),
        PORT(UART3_ADDR, AU1550_UART3_INT),
 #elif defined(CONFIG_SOC_AU1200)
        PORT(UART0_ADDR, AU1200_UART0_INT),
index 2a912153321e47345d9e11ea1698467993d41817..94886c000d2a2e8ff9581d83423bee68cfeaa409 100644 (file)
@@ -439,6 +439,20 @@ static int pci_siig_init(struct pci_dev *dev)
        return -ENODEV;
 }
 
+static int pci_siig_setup(struct serial_private *priv,
+                         struct pciserial_board *board,
+                         struct uart_port *port, int idx)
+{
+       unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
+
+       if (idx > 3) {
+               bar = 4;
+               offset = (idx - 4) * 8;
+       }
+
+       return setup_port(priv, port, bar, offset, 0);
+}
+
 /*
  * Timedia has an explosion of boards, and to avoid the PCI table from
  * growing *huge*, we use this function to collapse some 70 entries
@@ -748,7 +762,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
                .init           = pci_siig_init,
-               .setup          = pci_default_setup,
+               .setup          = pci_siig_setup,
        },
        /*
         * Titan cards
@@ -1868,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_SUBVENDOR_ID_CONNECT_TECH,
                PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
                pbn_b0_4_1843200 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_VENDOR_ID_AFAVLAB,
+               PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
+               pbn_b0_4_1152000 },
        {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
                PCI_SUBVENDOR_ID_CONNECT_TECH,
                PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
@@ -2141,6 +2159,15 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b0_bt_4_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
+       {       PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_8_921600 },
 
        /*
         * Computone devices submitted by Doug McNash dmcnash@computone.com
index 0d38f0f2ae2975d41f08fa059ab796385be2e71e..0f4361c8466b3d495442e9ca69fd17250606b0ef 100644 (file)
@@ -98,6 +98,7 @@ config SERIAL_8250_NR_UARTS
 config SERIAL_8250_RUNTIME_UARTS
        int "Number of 8250/16550 serial ports to register at runtime"
        depends on SERIAL_8250
+       range 0 SERIAL_8250_NR_UARTS
        default "4"
        help
          Set this to the maximum number of serial ports you want
@@ -892,20 +893,20 @@ config SERIAL_VR41XX_CONSOLE
          a console on a serial port, say Y.  Otherwise, say N.
 
 config SERIAL_JSM
-        tristate "Digi International NEO PCI Support"
-       depends on PCI && BROKEN
-        select SERIAL_CORE
-        help
-          This is a driver for Digi International's Neo series
-          of cards which provide multiple serial ports. You would need
-          something like this to connect more than two modems to your Linux
-          box, for instance in order to become a dial-in server. This driver
-          supports PCI boards only.
-          If you have a card like this, say Y here and read the file
-          <file:Documentation/jsm.txt>.
-
-          To compile this driver as a module, choose M here: the
-          module will be called jsm.
+       tristate "Digi International NEO PCI Support"
+       depends on PCI
+       select SERIAL_CORE
+       help
+         This is a driver for Digi International's Neo series
+         of cards which provide multiple serial ports. You would need
+         something like this to connect more than two modems to your Linux
+         box, for instance in order to become a dial-in server. This driver
+         supports PCI boards only.
+         If you have a card like this, say Y here and read the file
+         <file:Documentation/jsm.txt>.
+
+         To compile this driver as a module, choose M here: the
+         module will be called jsm.
 
 config SERIAL_SGI_IOC4
        tristate "SGI IOC4 controller serial support"
index 429de2723a1c4d95597038625db48e52a966cae3..321a3b3a5728b3334afb75771722690a7d1d04cf 100644 (file)
@@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = {
                .port   = {
                        .membase        = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
                        .mapbase        = INTEGRATOR_UART0_BASE,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UARTINT0,
                        .uartclk        = 14745600,
                        .fifosize       = 16,
@@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = {
                .port   = {
                        .membase        = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
                        .mapbase        = INTEGRATOR_UART1_BASE,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UARTINT1,
                        .uartclk        = 14745600,
                        .fifosize       = 16,
index ceb5d7f37bbd26920b27813b29daf812ec33926e..344022fe53ef870522700ef2e92e57e6b25c1945 100644 (file)
@@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res
        int ret = 0;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                if (up->port.mapbase) {
                        *res = request_mem_region(up->port.mapbase, size, "serial");
                        if (!*res)
@@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res
                }
                break;
 
-       case SERIAL_IO_HUB6:
-       case SERIAL_IO_PORT:
+       case UPIO_HUB6:
+       case UPIO_PORT:
                *res = request_region(up->port.iobase, size, "serial");
                if (!*res)
                        ret = -EBUSY;
@@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port)
        size <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                if (up->port.mapbase) {
                        /*
                         * Unmap the area.
@@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port)
                }
                break;
 
-       case SERIAL_IO_HUB6:
-       case SERIAL_IO_PORT:
+       case UPIO_HUB6:
+       case UPIO_PORT:
                start = up->port.iobase;
 
                if (size)
index 16af5626c243bedba451412e5c77abbdbba7f107..b7bf4c698a4795e3d3453ff696a90ad7fbdfc7b4 100644 (file)
@@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
                /* If we have not enough room in tty flip buffer, then we try
                 * later, which will be the next rx-interrupt or a timeout
                 */
-               if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) {
-                       tty->flip.work.func((void *)tty);
-                       if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) {
-                               printk(KERN_WARNING "TTY_DONT_FLIP set\n");
-                               return;
-                       }
+               if(tty_buffer_request_room(tty, i) < i) {
+                       printk(KERN_WARNING "No room in flip buffer\n");
+                       return;
                }
 
                /* get pointer */
@@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
                                continue;
 
                      error_return:
-                       *tty->flip.char_buf_ptr++ = ch;
-                       *tty->flip.flag_buf_ptr++ = flg;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flg);
 
                }               /* End while (i--) */
 
@@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SMC1_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .flags = FLAG_SMC,
@@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SMC2_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .flags = FLAG_SMC,
@@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC1_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC2_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC3_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC4_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
index a64ba26a94e8b317a0e6ef1b31e778a892986231..ba5541de673b1706079fc28e5423612e556f8006 100644 (file)
@@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport)
                }
                tty_insert_flip_char(tty, ch, flag);
              ignore_char:
+                       ;
        } while (status & DZ_DVAL);
 
        if (tty)
@@ -650,7 +651,7 @@ static void __init dz_init_ports(void)
        for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
                spin_lock_init(&dport->port.lock);
                dport->port.membase     = (char *) base;
-               dport->port.iotype      = SERIAL_IO_PORT;
+               dport->port.iotype      = UPIO_PORT;
                dport->port.irq         = dec_interrupt[DEC_IRQ_DZ11];
                dport->port.line        = i;
                dport->port.fifosize    = 1;
index 858048efe1edbd4da7a5d2d49b5fb587a333ba28..4d53fb5ca87b7b1ded6fffb1e2ce427be1d71b23 100644 (file)
@@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = {
        .rtsirq = UART1_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
-               .iotype         = SERIAL_IO_MEM,
+               .iotype         = UPIO_MEM,
                .membase        = (void *)IMX_UART1_BASE,
                .mapbase        = IMX_UART1_BASE, /* FIXME */
                .irq            = UART1_MINT_RX,
@@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = {
        .rtsirq = UART2_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
-               .iotype         = SERIAL_IO_MEM,
+               .iotype         = UPIO_MEM,
                .membase        = (void *)IMX_UART2_BASE,
                .mapbase        = IMX_UART2_BASE, /* FIXME */
                .irq            = UART2_MINT_RX,
index 66f117d150650294db0c88fa04308e67e83e37e1..419dd3cd786240f5db8c721877674b83c3c04f4a 100644 (file)
@@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
        /* Lower and upper byte of baud rate generator divisor.  */
        write_zsreg(channel, R12, regs[R12]);
        write_zsreg(channel, R13, regs[R13]);
-       
+
        /* Now rewrite R14, with BRENAB (if set).  */
        write_zsreg(channel, R14, regs[R14]);
 
@@ -571,7 +571,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
        else
                clear_bits |= DTR;
 
-       /* NOTE: Not subject to 'transmitter active' rule.  */ 
+       /* NOTE: Not subject to 'transmitter active' rule.  */
        up->curregs[R5] |= set_bits;
        up->curregs[R5] &= ~clear_bits;
        write_zsreg(channel, R5, up->curregs[R5]);
@@ -654,7 +654,7 @@ static void ip22zilog_enable_ms(struct uart_port *port)
        if (new_reg != up->curregs[R15]) {
                up->curregs[R15] = new_reg;
 
-               /* NOTE: Not subject to 'transmitter active' rule.  */ 
+               /* NOTE: Not subject to 'transmitter active' rule.  */
                write_zsreg(channel, R15, up->curregs[R15]);
        }
 }
@@ -680,7 +680,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
        if (new_reg != up->curregs[R5]) {
                up->curregs[R5] = new_reg;
 
-               /* NOTE: Not subject to 'transmitter active' rule.  */ 
+               /* NOTE: Not subject to 'transmitter active' rule.  */
                write_zsreg(channel, R5, up->curregs[R5]);
        }
 
index 18753193f59b7be467af3bb3a3eca1cd67889341..dfc1e86d3aa119b5977a3d6efc9abbcdeafe67e4 100644 (file)
@@ -380,7 +380,6 @@ struct neo_uart_struct {
 extern struct  uart_driver jsm_uart_driver;
 extern struct  board_ops jsm_neo_ops;
 extern int     jsm_debug;
-extern int     jsm_rawreadok;
 
 /*************************************************************************
  *
index 7e56c78241945975081657176342f0416c935cd7..b1b66e71d281125f990a9dc742ef56dc48786c3e 100644 (file)
@@ -49,11 +49,8 @@ struct uart_driver jsm_uart_driver = {
 };
 
 int jsm_debug;
-int jsm_rawreadok;
 module_param(jsm_debug, int, 0);
-module_param(jsm_rawreadok, int, 0);
 MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
-MODULE_PARM_DESC(jsm_rawreadok, "Bypass flip buffers on input");
 
 static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
index 6fa0d62d6f686269eadf52abacf56e516f7be3f8..4d48b625cd3d9f7fdc67e76b6a742372b3f28953 100644 (file)
  *
  * Contact Information:
  * Scott H Kilau <Scott_Kilau@digi.com>
- * Wendy Xiong   <wendyx@us.ltcfwd.linux.ibm.com>
- *
+ * Ananda Venkatarman <mansarov@us.ibm.com>
+ * Modifications:
+ * 01/19/06:   changed jsm_input routine to use the dynamically allocated
+ *             tty_buffer changes. Contributors: Scott Kilau and Ananda V.
  ***********************************************************************/
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -497,16 +499,15 @@ void jsm_input(struct jsm_channel *ch)
 {
        struct jsm_board *bd;
        struct tty_struct *tp;
+       struct tty_ldisc *ld;
        u32 rmask;
        u16 head;
        u16 tail;
        int data_len;
        unsigned long lock_flags;
-       int flip_len;
+       int flip_len = 0;
        int len = 0;
        int n = 0;
-       char *buf = NULL;
-       char *buf2 = NULL;
        int s = 0;
        int i = 0;
 
@@ -574,56 +575,50 @@ void jsm_input(struct jsm_channel *ch)
 
        /*
         * If the rxbuf is empty and we are not throttled, put as much
-        * as we can directly into the linux TTY flip buffer.
-        * The jsm_rawreadok case takes advantage of carnal knowledge that
-        * the char_buf and the flag_buf are next to each other and
-        * are each of (2 * TTY_FLIPBUF_SIZE) size.
+        * as we can directly into the linux TTY buffer.
         *
-        * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf
-        *actually still uses the flag buffer, so you can't
-        *use it for input data
         */
-       if (jsm_rawreadok) {
-               if (tp->real_raw)
-                       flip_len = MYFLIPLEN;
-               else
-                       flip_len = 2 * TTY_FLIPBUF_SIZE;
-       } else
-               flip_len = TTY_FLIPBUF_SIZE - tp->flip.count;
+       flip_len = TTY_FLIPBUF_SIZE;
 
        len = min(data_len, flip_len);
        len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
+       ld = tty_ldisc_ref(tp);
 
-       if (len <= 0) {
-               spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
-               jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
-               return;
-       }
+       /*
+        * If the DONT_FLIP flag is on, don't flush our buffer, and act
+        * like the ld doesn't have any space to put the data right now.
+        */
+       if (test_bit(TTY_DONT_FLIP, &tp->flags))
+               len = 0;
 
        /*
-        * If we're bypassing flip buffers on rx, we can blast it
-        * right into the beginning of the buffer.
+        * If we were unable to get a reference to the ld,
+        * don't flush our buffer, and act like the ld doesn't
+        * have any space to put the data right now.
         */
-       if (jsm_rawreadok) {
-               if (tp->real_raw) {
-                       if (ch->ch_flags & CH_FLIPBUF_IN_USE) {
-                               jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
-                                       "JSM - FLIPBUF in use. delaying input\n");
-                               spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
-                               return;
-                       }
-                       ch->ch_flags |= CH_FLIPBUF_IN_USE;
-                       buf = ch->ch_bd->flipbuf;
-                       buf2 = NULL;
-               } else {
-                       buf = tp->flip.char_buf;
-                       buf2 = tp->flip.flag_buf;
-               }
+       if (!ld) {
+               len = 0;
        } else {
-               buf = tp->flip.char_buf_ptr;
-               buf2 = tp->flip.flag_buf_ptr;
+               /*
+                * If ld doesn't have a pointer to a receive_buf function,
+                * flush the data, then act like the ld doesn't have any
+                * space to put the data right now.
+                */
+               if (!ld->receive_buf) {
+                               ch->ch_r_head = ch->ch_r_tail;
+                               len = 0;
+               }
        }
 
+       if (len <= 0) {
+               spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+               jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
+               if (ld)
+                       tty_ldisc_deref(ld);
+               return;
+       }
+
+       len = tty_buffer_request_room(tp, len);
        n = len;
 
        /*
@@ -638,121 +633,47 @@ void jsm_input(struct jsm_channel *ch)
                if (s <= 0)
                        break;
 
-               memcpy(buf, ch->ch_rqueue + tail, s);
-
-               /* buf2 is only set when port isn't raw */
-               if (buf2)
-                       memcpy(buf2, ch->ch_equeue + tail, s);
-
-               tail += s;
-               buf += s;
-               if (buf2)
-                       buf2 += s;
-               n -= s;
-               /* Flip queue if needed */
-               tail &= rmask;
-       }
+                       /*
+                        * If conditions are such that ld needs to see all
+                        * UART errors, we will have to walk each character
+                        * and error byte and send them to the buffer one at
+                        * a time.
+                        */
 
-       /*
-        * In high performance mode, we don't have to update
-        * flag_buf or any of the counts or pointers into flip buf.
-        */
-       if (!jsm_rawreadok) {
                if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
-                       for (i = 0; i < len; i++) {
+                       for (i = 0; i < s; i++) {
                                /*
                                 * Give the Linux ld the flags in the
                                 * format it likes.
                                 */
-                               if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI)
-                                       tp->flip.flag_buf_ptr[i] = TTY_BREAK;
-                               else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE)
-                                       tp->flip.flag_buf_ptr[i] = TTY_PARITY;
-                               else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE)
-                                       tp->flip.flag_buf_ptr[i] = TTY_FRAME;
+                               if (*(ch->ch_equeue +tail +i) & UART_LSR_BI)
+                                       tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i),  TTY_BREAK);
+                               else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE)
+                                       tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY);
+                               else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE)
+                                       tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME);
                                else
-                                       tp->flip.flag_buf_ptr[i] = TTY_NORMAL;
+                               tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
                        }
                } else {
-                       memset(tp->flip.flag_buf_ptr, 0, len);
+                       tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ;
                }
-
-               tp->flip.char_buf_ptr += len;
-               tp->flip.flag_buf_ptr += len;
-               tp->flip.count += len;
-       }
-       else if (!tp->real_raw) {
-               if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
-                       for (i = 0; i < len; i++) {
-                               /*
-                                * Give the Linux ld the flags in the
-                                * format it likes.
-                                */
-                               if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI)
-                                       tp->flip.flag_buf_ptr[i] = TTY_BREAK;
-                               else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE)
-                                       tp->flip.flag_buf_ptr[i] = TTY_PARITY;
-                               else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE)
-                                       tp->flip.flag_buf_ptr[i] = TTY_FRAME;
-                               else
-                                       tp->flip.flag_buf_ptr[i] = TTY_NORMAL;
-                       }
-               } else
-                       memset(tp->flip.flag_buf, 0, len);
+               tail += s;
+               n -= s;
+               /* Flip queue if needed */
+               tail &= rmask;
        }
 
-       /*
-        * If we're doing raw reads, jam it right into the
-        * line disc bypassing the flip buffers.
-        */
-       if (jsm_rawreadok) {
-               if (tp->real_raw) {
-                       ch->ch_r_tail = tail & rmask;
-                       ch->ch_e_tail = tail & rmask;
-
-                       jsm_check_queue_flow_control(ch);
-
-                       /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
+       ch->ch_r_tail = tail & rmask;
+       ch->ch_e_tail = tail & rmask;
+       jsm_check_queue_flow_control(ch);
+       spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
 
-                       spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
+       /* Tell the tty layer its okay to "eat" the data now */
+       tty_flip_buffer_push(tp);
 
-                       jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
-                               "jsm_input. %d real_raw len:%d calling receive_buf for board %d\n",
-                               __LINE__, len, ch->ch_bd->boardnum);
-                       tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
-
-                       /* Allow use of channel flip buffer again */
-                       spin_lock_irqsave(&ch->ch_lock, lock_flags);
-                       ch->ch_flags &= ~CH_FLIPBUF_IN_USE;
-                       spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
-
-               } else {
-                       ch->ch_r_tail = tail & rmask;
-                       ch->ch_e_tail = tail & rmask;
-
-                       jsm_check_queue_flow_control(ch);
-
-                       /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
-                       spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
-
-                       jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
-                               "jsm_input. %d not real_raw len:%d calling receive_buf for board %d\n",
-                               __LINE__, len, ch->ch_bd->boardnum);
-
-                       tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len);
-               }
-       } else {
-               ch->ch_r_tail = tail & rmask;
-               ch->ch_e_tail = tail & rmask;
-
-               jsm_check_queue_flow_control(ch);
-
-               spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
-
-               jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
-                       "jsm_input. %d not jsm_read raw okay scheduling flip\n", __LINE__);
-               tty_schedule_flip(tp);
-       }
+       if (ld)
+               tty_ldisc_deref(ld);
 
        jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
 }
index b48066a64a7df59b88f29e83aa28a6570e78300b..242a04104393e1e25e5462f23110830ba587c798 100644 (file)
@@ -80,7 +80,7 @@
 #include <asm/serial.h>
 
 /* Standard COM flags */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
 
 /*
  * SERIAL_PORT_DFNS tells us about built-in ports that have no
index 07d0dd80aa3dd2197861abddd1f27633aa7b7c2a..7c3ec24f7e50413466b0350835f12c84ef4a136c 100644 (file)
@@ -37,7 +37,7 @@ struct old_serial_port {
        unsigned int irq;
        unsigned int flags;
        unsigned char io_type;
-       unsigned char *iomem_base;
+       unsigned char __iomem *iomem_base;
        unsigned short iomem_reg_shift;
 };
 
index d957a3a9edf1f52bc0ebdeeb6f662ed9cfef7a47..8cbbb954df2cbdf4b4d360f469f7a5408ffbfa15 100644 (file)
@@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct;
  *     keep going.  Perhaps one day the cflag settings for the
  *     console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
-    defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
-#define        CONSOLE_BAUD_RATE       19200
-#define        DEFAULT_CBAUD           B19200
-#endif
-
 #if defined(CONFIG_HW_FEITH)
 #define        CONSOLE_BAUD_RATE       38400
 #define        DEFAULT_CBAUD           B38400
-#endif
-
-#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
 #define CONSOLE_BAUD_RATE      115200
 #define DEFAULT_CBAUD          B115200
+#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+      defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#define        CONSOLE_BAUD_RATE       19200
+#define        DEFAULT_CBAUD           B19200
 #endif
 
 #ifndef CONSOLE_BAUD_RATE
@@ -350,8 +346,7 @@ static inline void receive_chars(struct mcf_serial *info)
                }
                tty_insert_flip_char(tty, ch, flag);
        }
-
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
        return;
 }
 
index 4e49168c31761a976588c35fee2a0d446644cd4a..868eaf4a1a68c08a533c8676243d27b06f0b0534 100644 (file)
@@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev)
                port->mapbase   = dev->hpa.start + MUX_OFFSET +
                                                (i * MUX_LINE_OFFSET);
                port->membase   = ioremap(port->mapbase, MUX_LINE_OFFSET);
-               port->iotype    = SERIAL_IO_MEM;
+               port->iotype    = UPIO_MEM;
                port->type      = PORT_MUX;
                port->irq       = NO_IRQ;
                port->uartclk   = 0;
index 4e03a87f3fb48df3f70b505a2b89bb86f91b4584..9b7ed58cb53b53a6800851d40d22ba41743668bb 100644 (file)
@@ -1492,7 +1492,7 @@ no_dma:
        /*
         * Init remaining bits of "port" structure
         */
-       uap->port.iotype = SERIAL_IO_MEM;
+       uap->port.iotype = UPIO_MEM;
        uap->port.irq = np->intrs[0].line;
        uap->port.uartclk = ZS_CLOCK;
        uap->port.fifosize = 1;
index 0a2dd6c5b95fdecc116e78a4090552e31be90eaa..7410e093a6b9ffa733a4629c947c4d7324ecdcc7 100644 (file)
@@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...)
 
 /* we can support 3 uarts, but not always use them */
 
+#ifdef CONFIG_CPU_S3C2400
+#define NR_PORTS (2)
+#else
 #define NR_PORTS (3)
+#endif
 
 /* port irq numbers */
 
index ff7b60b4de37171d116bf34d2b9a5abf36cf5926..2c00b862585295474c56a32872a009d7a35c363a 100644 (file)
@@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void)
                sa1100_ports[i].port.ops       = &sa1100_pops;
                sa1100_ports[i].port.fifosize  = 8;
                sa1100_ports[i].port.line      = i;
-               sa1100_ports[i].port.iotype    = SERIAL_IO_MEM;
+               sa1100_ports[i].port.iotype    = UPIO_MEM;
                init_timer(&sa1100_ports[i].timer);
                sa1100_ports[i].timer.function = sa1100_timeout;
                sa1100_ports[i].timer.data     = (unsigned long)&sa1100_ports[i];
index 0717abfdae06f1eed3d132cdbd7e7a3cced60858..95fb4939c675f8119a2b630c6e23a380fc7a9d44 100644 (file)
@@ -2237,7 +2237,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
         * If this port is a console, then the spinlock is already
         * initialised.
         */
-       if (!uart_console(port))
+       if (!(uart_console(port) && (port->cons->flags & CON_ENABLED)))
                spin_lock_init(&port->lock);
 
        uart_configure_port(drv, state, port);
index d0490f67f597fa1be96f0271be6b99339216339b..04186eaae227053401af018fb65c4504853c863c 100644 (file)
@@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART1_PHYS),
                        .mapbase        = UART1_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART1INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
@@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART2_PHYS),
                        .mapbase        = UART2_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART2INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
@@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART3_PHYS),
                        .mapbase        = UART3_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART3INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
index 80737c131ce70fe0b60f2053771980631c5fcdb3..44f6bf79bbe12725fc0ba499501ba49625bcda60 100644 (file)
@@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff923000,
                        .mapbase        = 0xff923000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 61,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
                .type           = PORT_SCIF,
@@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff924000,
                        .mapbase        = 0xff924000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 62,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
                .type           = PORT_SCIF,
@@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff925000,
                        .mapbase        = 0xff925000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 63,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 2,
                },
                .type           = PORT_SCIF,
@@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xffe00000,
                        .mapbase        = 0xffe00000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 43,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
                .type           = PORT_SCIF,
@@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xffe10000,
                        .mapbase        = 0xffe10000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 79,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
                .type           = PORT_SCIF,
index 8bcaebcc0ad7b20e1986df7e74c4968071b14fe9..85664228a0b6a56123c04c00b5cf57a49f122a03 100644 (file)
@@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg
                up->port.irq = edev->irqs[0];
                up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
                up->port.mapbase = (unsigned long)up->regs;
-               up->port.iotype = SERIAL_IO_MEM;
+               up->port.iotype = UPIO_MEM;
 
                writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
 
index bc67442c6b4ce92f227cf62c81b7f507c11cb6e5..308704566948ea1a89a43fdad26810c6f7d09432 100644 (file)
@@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset)
        offset <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_HUB6:
+       case UPIO_HUB6:
                outb(up->port.hub6 - 1 + offset, up->port.iobase);
                return inb(up->port.iobase + 1);
 
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                return readb(up->port.membase + offset);
 
        default:
@@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value)
        offset <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_HUB6:
+       case UPIO_HUB6:
                outb(up->port.hub6 - 1 + offset, up->port.iobase);
                outb(value, up->port.iobase + 1);
                break;
 
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                writeb(value, up->port.membase + offset);
                break;
 
@@ -1052,7 +1052,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
                return;
 
        up->type_probed = PORT_UNKNOWN;
-       up->port.iotype = SERIAL_IO_MEM;
+       up->port.iotype = UPIO_MEM;
 
        /*
         * First we look for Ebus-bases su's
index 3c72484adea7593c85169e894fe5bf14cfe2674c..5cc4d4c2935ce7e3f2b685d4ed44e69025b12b1e 100644 (file)
@@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void)
                up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB;
 
                /* Channel A */
-               up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM;
+               up[(chip * 2) + 0].port.iotype = UPIO_MEM;
                up[(chip * 2) + 0].port.irq = zilog_irq;
                up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
                up[(chip * 2) + 0].port.fifosize = 1;
@@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void)
                up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
 
                /* Channel B */
-               up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM;
+               up[(chip * 2) + 1].port.iotype = UPIO_MEM;
                up[(chip * 2) + 1].port.irq = zilog_irq;
                up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
                up[(chip * 2) + 1].port.fifosize = 1;
index 9378895a8d56e9506a8e3569173087138089b832..df705fda42436f392308138a2634ddb4628998f6 100644 (file)
@@ -496,7 +496,7 @@ static int __init v850e_uart_init (void)
 
                        port->ops = &v850e_uart_ops;
                        port->line = chan;
-                       port->iotype = SERIAL_IO_MEM;
+                       port->iotype = UPIO_MEM;
                        port->flags = UPF_BOOT_AUTOCONF;
 
                        /* We actually use multiple IRQs, but the serial
index c70ae81b5d984d14350d047a6265bb1d079f17ec..12357e1fa5589e6661472d2752d701566ca41c05 100644 (file)
@@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
 
 static int nic_wait(struct ioc3_driver_data *idd)
 {
-       volatile unsigned mcr;
+       unsigned mcr;
 
         do {
-                mcr = (volatile unsigned)idd->vma->mcr;
+                mcr = readl(&idd->vma->mcr);
         } while (!(mcr & 2));
 
         return mcr & 1;
@@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd)
        unsigned long flags;
 
        local_irq_save(flags);
-       idd->vma->mcr = mcr_pack(500, 65);
+       writel(mcr_pack(500, 65), &idd->vma->mcr);
        presence = nic_wait(idd);
        local_irq_restore(flags);
 
@@ -68,7 +68,7 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd)
        unsigned long flags;
 
        local_irq_save(flags);
-       idd->vma->mcr = mcr_pack(6, 13);
+       writel(mcr_pack(6, 13), &idd->vma->mcr);
        result = nic_wait(idd);
        local_irq_restore(flags);
 
@@ -80,9 +80,9 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd)
 static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit)
 {
        if (bit)
-               idd->vma->mcr = mcr_pack(6, 110);
+               writel(mcr_pack(6, 110), &idd->vma->mcr);
        else
-               idd->vma->mcr = mcr_pack(80, 30);
+               writel(mcr_pack(80, 30), &idd->vma->mcr);
 
        nic_wait(idd);
 }
@@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd)
         int save = 0, loops = 3;
         unsigned long first, addr;
 
-        idd->vma->gpcr_s = GPCR_MLAN_EN;
+        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);
 
         while(loops>0) {
                 idd->nic_part[0] = 0;
@@ -408,7 +408,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
 
        read_lock_irqsave(&ioc3_submodules_lock, flags);
 
-       if(idd->dual_irq && idd->vma->eisr) {
+       if(idd->dual_irq && readb(&idd->vma->eisr)) {
                /* send Ethernet IRQ to the driver */
                if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
                                                ioc3_ethernet->intr) {
@@ -682,7 +682,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
        idd->id = ioc3_counter++;
        up_write(&ioc3_devices_rwsem);
 
-       idd->gpdr_shadow = idd->vma->gpdr;
+       idd->gpdr_shadow = readl(&idd->vma->gpdr);
 
        /* Read IOC3 NIC contents */
        probe_nic(idd);
index b77dbd63e596fea9770cde47928dad197ab51e1d..7a75faeb0526d6f89c37dbe854c52b5cddd5ebeb 100644 (file)
@@ -75,16 +75,6 @@ config SPI_BUTTERFLY
          inexpensive battery powered microcontroller evaluation board.
          This same cable can be used to flash new firmware.
 
-config SPI_BUTTERFLY
-       tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
-       depends on SPI_MASTER && PARPORT && EXPERIMENTAL
-       select SPI_BITBANG
-       help
-         This uses a custom parallel port cable to connect to an AVR
-         Butterfly <http://www.atmel.com/products/avr/butterfly>, an
-         inexpensive battery powered microcontroller evaluation board.
-         This same cable can be used to flash new firmware.
-
 #
 # Add new SPI master controllers in alphabetical order above this line
 #
index 79a3c59615ab90a35039787296f1dbe99a10fe92..ff9e5faa4dc9f369ec30e829279646547f1fba73 100644 (file)
@@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
        struct butterfly        *pp = spidev_to_pp(spi);
 
        /* set default clock polarity */
-       if (value)
+       if (value != BITBANG_CS_INACTIVE)
                setsck(spi, spi->mode & SPI_CPOL);
 
        /* no chipselect on this USI link config */
        if (is_usidev(spi))
                return;
 
-       /* here, value == "activate or not" */
-
-       /* most PARPORT_CONTROL_* bits are negated */
+       /* here, value == "activate or not";
+        * most PARPORT_CONTROL_* bits are negated, so we must
+        * morph it to value == "bit value to write in control register"
+        */
        if (spi_cs_bit == PARPORT_CONTROL_INIT)
                value = !value;
 
-       /* here, value == "bit value to write in control register"  */
-
        parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
 }
 
@@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi,
 
 /* override default partitioning with cmdlinepart */
 static struct mtd_partition partitions[] = { {
-       /* JFFS2 wants partitions of 4*N blocks for this device ... */
+       /* JFFS2 wants partitions of 4*N blocks for this device,
+        * so sectors 0 and 1 can't be partitions by themselves.
+        */
 
        /* sector 0 = 8 pages * 264 bytes/page (1 block)
         * sector 1 = 248 pages * 264 bytes/page
@@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p)
        if (status < 0)
                goto clean2;
 
-       /* Bus 1 lets us talk to at45db041b (firmware disables AVR)
-        * or AVR (firmware resets at45, acts as spi slave)
+       /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR
+        * (firmware resets at45, acts as spi slave) or neither (we ignore
+        * both, AVR uses AT45).  Here we expect firmware for the first option.
         */
        pp->info[0].max_speed_hz = 15 * 1000 * 1000;
        strcpy(pp->info[0].modalias, "mtd_dataflash");
@@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p)
                                pp->dataflash->dev.bus_id);
 
 #ifdef HAVE_USI
-       /* even more custom AVR firmware */
+       /* Bus 2 is only for talking to the AVR, and it can work no
+        * matter who masters bus 1; needs appropriate AVR firmware.
+        */
        pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
        strcpy(pp->info[1].modalias, "butterfly");
        // pp->info[1].platform_data = ... TBD ... ;
@@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p)
        pp = butterfly;
        butterfly = NULL;
 
-#ifdef HAVE_USI
-       spi_unregister_device(pp->butterfly);
-       pp->butterfly = NULL;
-#endif
-       spi_unregister_device(pp->dataflash);
-       pp->dataflash = NULL;
-
+       /* stop() unregisters child devices too */
+       pdev = to_platform_device(pp->bitbang.master->cdev.dev);
        status = spi_bitbang_stop(&pp->bitbang);
 
        /* turn off VCC */
@@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p)
        parport_release(pp->pd);
        parport_unregister_device(pp->pd);
 
-       pdev = to_platform_device(pp->bitbang.master->cdev.dev);
-
        (void) spi_master_put(pp->bitbang.master);
 
        platform_device_unregister(pdev);
@@ -420,4 +417,5 @@ static void __exit butterfly_exit(void)
 }
 module_exit(butterfly_exit);
 
+MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly");
 MODULE_LICENSE("GPL");
index a0e5af638e0e3792209c475b5c9c2de173082c86..4a51e56f85b6b0a3d362bdd44317c2c484c84319 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/paccess.h>
index f6704688ee8c2e15efb500ce0ed807030e078280..5578a9dd04e80bcffb92e1119c82bb4aa5ce174b 100644 (file)
@@ -3558,10 +3558,16 @@ static void ixj_write_frame(IXJ *j)
                                }
                        /* Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG  */
                                if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
-                                       if(j->write_buffer_rp + cnt == 0 && j->write_buffer_rp + cnt + 1 == 0 && j->write_buffer_rp + cnt + 2 == 0 &&
-                                          j->write_buffer_rp + cnt + 3 == 0 && j->write_buffer_rp + cnt + 4 == 0 && j->write_buffer_rp + cnt + 5 == 0 &&
-                                          j->write_buffer_rp + cnt + 6 == 0 && j->write_buffer_rp + cnt + 7 == 0 && j->write_buffer_rp + cnt + 8 == 0 &&
-                                          j->write_buffer_rp + cnt + 9 == 0) {
+                                       if (j->write_buffer_rp[cnt] == 0 &&
+                                           j->write_buffer_rp[cnt + 1] == 0 &&
+                                           j->write_buffer_rp[cnt + 2] == 0 &&
+                                           j->write_buffer_rp[cnt + 3] == 0 &&
+                                           j->write_buffer_rp[cnt + 4] == 0 &&
+                                           j->write_buffer_rp[cnt + 5] == 0 &&
+                                           j->write_buffer_rp[cnt + 6] == 0 &&
+                                           j->write_buffer_rp[cnt + 7] == 0 &&
+                                           j->write_buffer_rp[cnt + 8] == 0 &&
+                                           j->write_buffer_rp[cnt + 9] == 0) {
                                        /* someone is trying to write silence lets make this a type 0 frame. */
                                                outb_p(0x00, j->DSPbase + 0x0C);
                                                outb_p(0x00, j->DSPbase + 0x0D);
index 076462c8ba2a35a79c03282aa33467f542b804d9..dce9d987f0fc474a3c0d59a1ccc4daf4def4c933 100644 (file)
@@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
 
        return NULL;
 }
-EXPORT_SYMBOL_GPL(usb_match_id);
+EXPORT_SYMBOL(usb_match_id);
 
 int usb_device_match(struct device *dev, struct device_driver *drv)
 {
@@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
 
        return retval;
 }
-EXPORT_SYMBOL_GPL(usb_register_driver);
+EXPORT_SYMBOL(usb_register_driver);
 
 /**
  * usb_deregister - unregister a USB driver
@@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver)
 
        usbfs_update_special();
 }
-EXPORT_SYMBOL_GPL(usb_deregister);
+EXPORT_SYMBOL(usb_deregister);
index 9d5015e99372c4d0f9f6c67fa95f39f9d460eb85..bd39bbd88d41e7042e7fa76bf2a35e1c3145ebbc 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 {
index 68c690605aa7cfc9469c1189bee9200c0ba7639b..9e32485ee7bbc448da71b86c7e89fd4b76ffb2ea 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
 {
index a7bcd17112c08850777653db36417d266dd9dd30..0339f5640a78f0d56a4b1db24de78b5f0f73ecba 100644 (file)
 
 #define STI_DRIVERVERSION "Version 0.9a"
 
-struct sti_struct *default_sti;
+struct sti_struct *default_sti __read_mostly;
 
-static int num_sti_roms;                         /* # of STI ROMS found */
-static struct sti_struct *sti_roms[MAX_STI_ROMS]; /* ptr to each sti_struct */
+/* number of STI ROMS found and their ptrs to each struct */
+static int num_sti_roms __read_mostly;
+static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly;
 
 
 /* The colour indices used by STI are
@@ -266,7 +267,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest)
 
 
 
-static char default_sti_path[21];
+static char default_sti_path[21] __read_mostly;
 
 #ifndef MODULE
 static int __init sti_setup(char *str)
@@ -414,10 +415,10 @@ sti_init_glob_cfg(struct sti_struct *sti,
        if (!sti->sti_mem_request)
                sti->sti_mem_request = 256; /* STI default */
 
-       glob_cfg = kmalloc(sizeof(*sti->glob_cfg), GFP_KERNEL);
-       glob_cfg_ext = kmalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
-       save_addr = kmalloc(save_addr_size, GFP_KERNEL);
-       sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL);
+       glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL);
+       glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
+       save_addr = kzalloc(save_addr_size, GFP_KERNEL);
+       sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);
 
        if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
                kfree(glob_cfg);
@@ -427,11 +428,6 @@ sti_init_glob_cfg(struct sti_struct *sti,
                return -ENOMEM;
        }
 
-       memset(glob_cfg, 0, sizeof(*glob_cfg));
-       memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext));
-       memset(save_addr, 0, save_addr_size);
-       memset(sti_mem_addr, 0, sti->sti_mem_request);
-
        glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
        glob_cfg->save_addr = STI_PTR(save_addr);
        for (i=0; i<8; i++) {
@@ -502,9 +498,9 @@ sti_init_glob_cfg(struct sti_struct *sti,
 
 #ifdef CONFIG_FB
 struct sti_cooked_font * __init
-sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
+sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
 {
-       struct font_desc *fbfont;
+       const struct font_desc *fbfont;
        unsigned int size, bpc;
        void *dest;
        struct sti_rom_font *nf;
@@ -525,10 +521,9 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
        size = bpc * 256;
        size += sizeof(struct sti_rom_font);
 
-       nf = kmalloc(size, GFP_KERNEL);
+       nf = kzalloc(size, GFP_KERNEL);
        if (!nf)
                return NULL;
-       memset(nf, 0, size);
 
        nf->first_char = 0;
        nf->last_char = 255;
@@ -544,7 +539,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
        dest += sizeof(struct sti_rom_font);
        memcpy(dest, fbfont->data, bpc*256);
 
-       cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL);
+       cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
        if (!cooked_font) {
                kfree(nf);
                return NULL;
@@ -559,7 +554,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
 }
 #else
 struct sti_cooked_font * __init
-sti_select_fbfont(struct sti_cooked_rom *cooked_rom, char *fbfont_name)
+sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
 {
        return NULL;
 }
@@ -617,7 +612,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
        struct sti_rom_font *raw_font, *font_start;
        struct sti_cooked_font *cooked_font;
        
-       cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL);
+       cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
        if (!cooked_font)
                return 0;
 
@@ -631,7 +626,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
        while (raw_font->next_font) {
                raw_font = ((void *)font_start) + (raw_font->next_font);
 
-               cooked_font->next_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL);
+               cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
                if (!cooked_font->next_font)
                        return 1;
 
@@ -668,10 +663,9 @@ sti_bmode_font_raw(struct sti_cooked_font *f)
        unsigned char *n, *p, *q;
        int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
        
-       n = kmalloc (4*size, GFP_KERNEL);
+       n = kzalloc (4*size, GFP_KERNEL);
        if (!n)
                return NULL;
-       memset (n, 0, 4*size);
        p = n + 3;
        q = (unsigned char *)f->raw;
        while (size--) {
@@ -816,13 +810,12 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd
                return NULL;
        }
        
-       sti = kmalloc(sizeof(*sti), GFP_KERNEL);
+       sti = kzalloc(sizeof(*sti), GFP_KERNEL);
        if (!sti) {
                printk(KERN_ERR "Not enough memory !\n");
                return NULL;
        }
 
-       memset(sti, 0, sizeof(*sti));
        spin_lock_init(&sti->lock);
 
 test_rom:
@@ -1035,7 +1028,7 @@ static struct parisc_driver pa_sti_driver = {
  * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[]
  */
 
-static int sticore_initialized;
+static int sticore_initialized __read_mostly;
 
 static void __init sti_init_roms(void)
 {
index f3927b6cda9d4d7f6edc8c29a65be8249577e5fc..f5361cd8ccce1359cd706d0e081a873b77235955 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 25148de5fe6795799999269bd3a92cb0991a0311..eeeac924b500730e1ee9538c7ddc7436ddb9ccd4 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 32a9f99154e23b30bb804ba6601b6f804c9baff5..bf1f10067960be8feb075d8740229d1419993b53 100644 (file)
@@ -116,13 +116,19 @@ static void buf_put_int64(struct cbuf *buf, u64 val)
        }
 }
 
-static void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
+static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
 {
+       char *ret;
+
+       ret = NULL;
        if (buf_check_size(buf, slen + 2)) {
                buf_put_int16(buf, slen);
+               ret = buf->p;
                memcpy(buf->p, s, slen);
                buf->p += slen;
        }
+
+       return ret;
 }
 
 static inline void buf_put_string(struct cbuf *buf, const char *s)
@@ -430,15 +436,19 @@ static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p)
 static void
 v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
 {
-       if (data) {
-               str->len = strlen(data);
-               str->str = bufp->p;
-       } else {
-               str->len = 0;
-               str->str = NULL;
-       }
+       int len;
+       char *s;
+
+       if (data)
+               len = strlen(data);
+       else
+               len = 0;
 
-       buf_put_stringn(bufp, data, str->len);
+       s = buf_put_stringn(bufp, data, len);
+       if (str) {
+               str->len = len;
+               str->str = s;
+       }
 }
 
 static int
index 945cb368d451948156bf518ee7e40616ac09e675..ea1134eb47c8e591f6917262f3a340605d310dd5 100644 (file)
@@ -471,10 +471,13 @@ static void v9fs_write_work(void *a)
                }
 
                spin_lock(&m->lock);
-               req =
-                   list_entry(m->unsent_req_list.next, struct v9fs_req,
+again:
+               req = list_entry(m->unsent_req_list.next, struct v9fs_req,
                               req_list);
                list_move_tail(&req->req_list, &m->req_list);
+               if (req->err == ERREQFLUSH)
+                       goto again;
+
                m->wbuf = req->tcall->sdata;
                m->wsize = req->tcall->size;
                m->wpos = 0;
@@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
        struct v9fs_str *ename;
 
        tag = req->tag;
-       if (req->rcall->id == RERROR && !req->err) {
+       if (!req->err && req->rcall->id == RERROR) {
                ecode = req->rcall->params.rerror.errno;
                ename = &req->rcall->params.rerror.error;
 
@@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
                        req->err = -EIO;
        }
 
-       if (req->cb && req->err != ERREQFLUSH) {
+       if (req->err == ERREQFLUSH)
+               return;
+
+       if (req->cb) {
                dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
                        req->tcall, req->rcall);
 
@@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
        struct v9fs_mux_rpc *r;
 
        if (err == ERREQFLUSH) {
+               kfree(rc);
                dprintk(DEBUG_MUX, "err req flush\n");
                return;
        }
index 91f552454c7656470eecd32a6d00513e5b54d81f..63e5b0398e8b9e5f447fc1d2234a0ec11d50680c 100644 (file)
@@ -886,8 +886,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
        }
 
        /* copy extension buffer into buffer */
-       if (fcall->params.rstat.stat.extension.len < buflen)
-               buflen = fcall->params.rstat.stat.extension.len;
+       if (fcall->params.rstat.stat.extension.len+1 < buflen)
+               buflen = fcall->params.rstat.stat.extension.len + 1;
 
        memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
        buffer[buflen-1] = 0;
@@ -951,7 +951,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        if (!link)
                link = ERR_PTR(-ENOMEM);
        else {
-               len = v9fs_readlink(dentry, link, strlen(link));
+               len = v9fs_readlink(dentry, link, PATH_MAX);
 
                if (len < 0) {
                        __putname(link);
index 93b5dc4082ff24e3e015244c31ff3e7a35d757d1..e9749b0eecd8a27e5a1d09ece2eee57e63c14529 100644 (file)
@@ -883,8 +883,6 @@ config CONFIGFS_FS
          Both sysfs and configfs can and should exist together on the
          same system. One is not a replacement for the other.
 
-         If unsure, say N.
-
 endmenu
 
 menu "Miscellaneous filesystems"
index 5e4a90ee103f5eacedc1f8acaafacb847f56b5ec..62cfd17dc5fee6c87a1dbaabe5e01299e89dc5ad 100644 (file)
@@ -2867,22 +2867,22 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
                else if (test_set_buffer_locked(bh))
                        continue;
 
-               get_bh(bh);
                if (rw == WRITE || rw == SWRITE) {
                        if (test_clear_buffer_dirty(bh)) {
                                bh->b_end_io = end_buffer_write_sync;
+                               get_bh(bh);
                                submit_bh(WRITE, bh);
                                continue;
                        }
                } else {
                        if (!buffer_uptodate(bh)) {
                                bh->b_end_io = end_buffer_read_sync;
+                               get_bh(bh);
                                submit_bh(rw, bh);
                                continue;
                        }
                }
                unlock_buffer(bh);
-               put_bh(bh);
        }
 }
 
index 5dd0207ffd46607f947aadb9b1c7c1d8e5e39890..057e60217fc5644a31e00578c75ec1619e3bb99c 100644 (file)
@@ -931,8 +931,8 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
 static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        int err, i;
-       sg_req_info_t *r;
-       struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg;
+       sg_req_info_t __user *r;
+       struct compat_sg_req_info __user *o = (void __user *)arg;
        r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
        err = sys_ioctl(fd,cmd,(unsigned long)r);
        if (err < 0)
@@ -2739,8 +2739,8 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
 static int
 lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct compat_timeval *tc = (struct compat_timeval *)arg;
-       struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval));
+       struct compat_timeval __user *tc = (struct compat_timeval __user *)arg;
+       struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
        struct timeval ts;
        if (get_user(ts.tv_sec, &tc->tv_sec) ||
            get_user(ts.tv_usec, &tc->tv_usec) ||
index 8899d9c5f6bf76ec7f8d4a3b825ca95a182b85d1..f70e46951b3781ec1baa4677e715919ac78724c2 100644 (file)
@@ -36,6 +36,7 @@ struct configfs_dirent {
        int                     s_type;
        umode_t                 s_mode;
        struct dentry           * s_dentry;
+       struct iattr            * s_iattr;
 };
 
 #define CONFIGFS_ROOT          0x0001
@@ -48,10 +49,11 @@ struct configfs_dirent {
 #define CONFIGFS_NOT_PINNED    (CONFIGFS_ITEM_ATTR)
 
 extern struct vfsmount * configfs_mount;
+extern kmem_cache_t *configfs_dir_cachep;
 
 extern int configfs_is_root(struct config_item *item);
 
-extern struct inode * configfs_new_inode(mode_t mode);
+extern struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent *);
 extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *));
 
 extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
@@ -63,6 +65,7 @@ extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
 
 extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
 extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
+extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr);
 
 extern int configfs_pin_fs(void);
 extern void configfs_release_fs(void);
@@ -120,8 +123,10 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
 
 static inline void release_configfs_dirent(struct configfs_dirent * sd)
 {
-       if (!(sd->s_type & CONFIGFS_ROOT))
-               kfree(sd);
+       if (!(sd->s_type & CONFIGFS_ROOT)) {
+               kfree(sd->s_iattr);
+               kmem_cache_free(configfs_dir_cachep, sd);
+       }
 }
 
 static inline struct configfs_dirent * configfs_get(struct configfs_dirent * sd)
index b668ec61527e19b6c2160c7fd65595b536372964..ca60e3abef451d64ce9df9374b2b49dfe8a5d97c 100644 (file)
@@ -72,7 +72,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
 {
        struct configfs_dirent * sd;
 
-       sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+       sd = kmem_cache_alloc(configfs_dir_cachep, GFP_KERNEL);
        if (!sd)
                return NULL;
 
@@ -136,13 +136,19 @@ static int create_dir(struct config_item * k, struct dentry * p,
        int error;
        umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
 
-       error = configfs_create(d, mode, init_dir);
+       error = configfs_make_dirent(p->d_fsdata, d, k, mode,
+                                    CONFIGFS_DIR);
        if (!error) {
-               error = configfs_make_dirent(p->d_fsdata, d, k, mode,
-                                          CONFIGFS_DIR);
+               error = configfs_create(d, mode, init_dir);
                if (!error) {
                        p->d_inode->i_nlink++;
                        (d)->d_op = &configfs_dentry_ops;
+               } else {
+                       struct configfs_dirent *sd = d->d_fsdata;
+                       if (sd) {
+                               list_del_init(&sd->s_sibling);
+                               configfs_put(sd);
+                       }
                }
        }
        return error;
@@ -182,12 +188,19 @@ int configfs_create_link(struct configfs_symlink *sl,
        int err = 0;
        umode_t mode = S_IFLNK | S_IRWXUGO;
 
-       err = configfs_create(dentry, mode, init_symlink);
+       err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode,
+                                  CONFIGFS_ITEM_LINK);
        if (!err) {
-               err = configfs_make_dirent(parent->d_fsdata, dentry, sl,
-                                        mode, CONFIGFS_ITEM_LINK);
+               err = configfs_create(dentry, mode, init_symlink);
                if (!err)
                        dentry->d_op = &configfs_dentry_ops;
+               else {
+                       struct configfs_dirent *sd = dentry->d_fsdata;
+                       if (sd) {
+                               list_del_init(&sd->s_sibling);
+                               configfs_put(sd);
+                       }
+               }
        }
        return err;
 }
@@ -241,13 +254,15 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
        struct configfs_attribute * attr = sd->s_element;
        int error;
 
+       dentry->d_fsdata = configfs_get(sd);
+       sd->s_dentry = dentry;
        error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file);
-       if (error)
+       if (error) {
+               configfs_put(sd);
                return error;
+       }
 
        dentry->d_op = &configfs_dentry_ops;
-       dentry->d_fsdata = configfs_get(sd);
-       sd->s_dentry = dentry;
        d_rehash(dentry);
 
        return 0;
@@ -839,6 +854,7 @@ struct inode_operations configfs_dir_inode_operations = {
        .symlink        = configfs_symlink,
        .unlink         = configfs_unlink,
        .lookup         = configfs_lookup,
+       .setattr        = configfs_setattr,
 };
 
 #if 0
index c26cd61f13afd3c9cc02ff7799ff95c58f622df5..3921920d8716a32f3495e8200abad6c0b2d08f2c 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/fs.h>
 #include <linux/module.h>
-#include <linux/dnotify.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
@@ -150,7 +149,7 @@ out:
 /**
  *     fill_write_buffer - copy buffer from userspace.
  *     @buffer:        data buffer for file.
- *     @userbuf:       data from user.
+ *     @buf:           data from user.
  *     @count:         number of bytes in @userbuf.
  *
  *     Allocate @buffer->page if it hasn't been already, then
@@ -177,8 +176,9 @@ fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size
 
 /**
  *     flush_write_buffer - push buffer to config_item.
- *     @file:          file pointer.
+ *     @dentry:        dentry to the attribute
  *     @buffer:        data buffer for file.
+ *     @count:         number of bytes
  *
  *     Get the correct pointers for the config_item and the attribute we're
  *     dealing with, then call the store() method for the attribute,
@@ -217,15 +217,16 @@ static ssize_t
 configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct configfs_buffer * buffer = file->private_data;
+       ssize_t len;
 
        down(&buffer->sem);
-       count = fill_write_buffer(buffer,buf,count);
-       if (count > 0)
-               count = flush_write_buffer(file->f_dentry,buffer,count);
-       if (count > 0)
-               *ppos += count;
+       len = fill_write_buffer(buffer, buf, count);
+       if (len > 0)
+               len = flush_write_buffer(file->f_dentry, buffer, count);
+       if (len > 0)
+               *ppos += len;
        up(&buffer->sem);
-       return count;
+       return len;
 }
 
 static int check_perm(struct inode * inode, struct file * file)
index 6577c588de9d31d1795f7cd683fd81a149a716d1..c153bd9534cb6d72066094c8110ce0f35fec3ff3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/pagemap.h>
 #include <linux/namei.h>
 #include <linux/backing-dev.h>
+#include <linux/capability.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
@@ -48,18 +49,107 @@ static struct backing_dev_info configfs_backing_dev_info = {
        .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
-struct inode * configfs_new_inode(mode_t mode)
+static struct inode_operations configfs_inode_operations ={
+       .setattr        = configfs_setattr,
+};
+
+int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
+{
+       struct inode * inode = dentry->d_inode;
+       struct configfs_dirent * sd = dentry->d_fsdata;
+       struct iattr * sd_iattr;
+       unsigned int ia_valid = iattr->ia_valid;
+       int error;
+
+       if (!sd)
+               return -EINVAL;
+
+       sd_iattr = sd->s_iattr;
+
+       error = inode_change_ok(inode, iattr);
+       if (error)
+               return error;
+
+       error = inode_setattr(inode, iattr);
+       if (error)
+               return error;
+
+       if (!sd_iattr) {
+               /* setting attributes for the first time, allocate now */
+               sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+               if (!sd_iattr)
+                       return -ENOMEM;
+               /* assign default attributes */
+               memset(sd_iattr, 0, sizeof(struct iattr));
+               sd_iattr->ia_mode = sd->s_mode;
+               sd_iattr->ia_uid = 0;
+               sd_iattr->ia_gid = 0;
+               sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
+               sd->s_iattr = sd_iattr;
+       }
+
+       /* attributes were changed atleast once in past */
+
+       if (ia_valid & ATTR_UID)
+               sd_iattr->ia_uid = iattr->ia_uid;
+       if (ia_valid & ATTR_GID)
+               sd_iattr->ia_gid = iattr->ia_gid;
+       if (ia_valid & ATTR_ATIME)
+               sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
+                                               inode->i_sb->s_time_gran);
+       if (ia_valid & ATTR_MTIME)
+               sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
+                                               inode->i_sb->s_time_gran);
+       if (ia_valid & ATTR_CTIME)
+               sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
+                                               inode->i_sb->s_time_gran);
+       if (ia_valid & ATTR_MODE) {
+               umode_t mode = iattr->ia_mode;
+
+               if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+                       mode &= ~S_ISGID;
+               sd_iattr->ia_mode = sd->s_mode = mode;
+       }
+
+       return error;
+}
+
+static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
+{
+       inode->i_mode = mode;
+       inode->i_uid = 0;
+       inode->i_gid = 0;
+       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+}
+
+static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
+{
+       inode->i_mode = iattr->ia_mode;
+       inode->i_uid = iattr->ia_uid;
+       inode->i_gid = iattr->ia_gid;
+       inode->i_atime = iattr->ia_atime;
+       inode->i_mtime = iattr->ia_mtime;
+       inode->i_ctime = iattr->ia_ctime;
+}
+
+struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd)
 {
        struct inode * inode = new_inode(configfs_sb);
        if (inode) {
-               inode->i_mode = mode;
-               inode->i_uid = 0;
-               inode->i_gid = 0;
                inode->i_blksize = PAGE_CACHE_SIZE;
                inode->i_blocks = 0;
-               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                inode->i_mapping->a_ops = &configfs_aops;
                inode->i_mapping->backing_dev_info = &configfs_backing_dev_info;
+               inode->i_op = &configfs_inode_operations;
+
+               if (sd->s_iattr) {
+                       /* sysfs_dirent has non-default attributes
+                        * get them for the new inode from persistent copy
+                        * in sysfs_dirent
+                        */
+                       set_inode_attr(inode, sd->s_iattr);
+               } else
+                       set_default_inode_attr(inode, mode);
        }
        return inode;
 }
@@ -70,7 +160,8 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *
        struct inode * inode = NULL;
        if (dentry) {
                if (!dentry->d_inode) {
-                       if ((inode = configfs_new_inode(mode))) {
+                       struct configfs_dirent *sd = dentry->d_fsdata;
+                       if ((inode = configfs_new_inode(mode, sd))) {
                                if (dentry->d_parent && dentry->d_parent->d_inode) {
                                        struct inode *p_inode = dentry->d_parent->d_inode;
                                        p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
@@ -103,10 +194,9 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *
  */
 const unsigned char * configfs_get_name(struct configfs_dirent *sd)
 {
-       struct attribute * attr;
+       struct configfs_attribute *attr;
 
-       if (!sd || !sd->s_element)
-               BUG();
+       BUG_ON(!sd || !sd->s_element);
 
        /* These always have a dentry, so use that */
        if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
@@ -114,7 +204,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd)
 
        if (sd->s_type & CONFIGFS_ITEM_ATTR) {
                attr = sd->s_element;
-               return attr->name;
+               return attr->ca_name;
        }
        return NULL;
 }
@@ -130,13 +220,17 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
 
        if (dentry) {
                spin_lock(&dcache_lock);
+               spin_lock(&dentry->d_lock);
                if (!(d_unhashed(dentry) && dentry->d_inode)) {
                        dget_locked(dentry);
                        __d_drop(dentry);
+                       spin_unlock(&dentry->d_lock);
                        spin_unlock(&dcache_lock);
                        simple_unlink(parent->d_inode, dentry);
-               } else
+               } else {
+                       spin_unlock(&dentry->d_lock);
                        spin_unlock(&dcache_lock);
+               }
        }
 }
 
@@ -145,6 +239,10 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
        struct configfs_dirent * sd;
        struct configfs_dirent * parent_sd = dir->d_fsdata;
 
+       if (dir->d_inode == NULL)
+               /* no inode means this hasn't been made visible yet */
+               return;
+
        mutex_lock(&dir->d_inode->i_mutex);
        list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
                if (!sd->s_element)
index 1a2f6f6a4d917da58791d8f1287f29a90e14bed1..f920d30478e531a7a656548d9d9c7169a0cc99bf 100644 (file)
@@ -38,6 +38,7 @@
 
 struct vfsmount * configfs_mount = NULL;
 struct super_block * configfs_sb = NULL;
+kmem_cache_t *configfs_dir_cachep;
 static int configfs_mnt_count = 0;
 
 static struct super_operations configfs_ops = {
@@ -62,6 +63,7 @@ static struct configfs_dirent configfs_root = {
        .s_children     = LIST_HEAD_INIT(configfs_root.s_children),
        .s_element      = &configfs_root_group.cg_item,
        .s_type         = CONFIGFS_ROOT,
+       .s_iattr        = NULL,
 };
 
 static int configfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -73,9 +75,11 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
        sb->s_magic = CONFIGFS_MAGIC;
        sb->s_op = &configfs_ops;
+       sb->s_time_gran = 1;
        configfs_sb = sb;
 
-       inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+       inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+                                  &configfs_root);
        if (inode) {
                inode->i_op = &configfs_dir_inode_operations;
                inode->i_fop = &configfs_dir_operations;
@@ -128,19 +132,31 @@ static decl_subsys(config, NULL, NULL);
 
 static int __init configfs_init(void)
 {
-       int err;
+       int err = -ENOMEM;
+
+       configfs_dir_cachep = kmem_cache_create("configfs_dir_cache",
+                                               sizeof(struct configfs_dirent),
+                                               0, 0, NULL, NULL);
+       if (!configfs_dir_cachep)
+               goto out;
 
        kset_set_kset_s(&config_subsys, kernel_subsys);
        err = subsystem_register(&config_subsys);
-       if (err)
-               return err;
+       if (err) {
+               kmem_cache_destroy(configfs_dir_cachep);
+               configfs_dir_cachep = NULL;
+               goto out;
+       }
 
        err = register_filesystem(&configfs_fs_type);
        if (err) {
                printk(KERN_ERR "configfs: Unable to register filesystem!\n");
                subsystem_unregister(&config_subsys);
+               kmem_cache_destroy(configfs_dir_cachep);
+               configfs_dir_cachep = NULL;
        }
 
+out:
        return err;
 }
 
@@ -148,11 +164,13 @@ static void __exit configfs_exit(void)
 {
        unregister_filesystem(&configfs_fs_type);
        subsystem_unregister(&config_subsys);
+       kmem_cache_destroy(configfs_dir_cachep);
+       configfs_dir_cachep = NULL;
 }
 
 MODULE_AUTHOR("Oracle");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.1");
+MODULE_VERSION("0.0.2");
 MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration.");
 
 module_init(configfs_init);
index 50f5840521a93c0b91fda648a9f3fc9debc659d8..e5512e295cf2970b865d7ee398ed41d87634e067 100644 (file)
@@ -162,8 +162,7 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
        if (!(sd->s_type & CONFIGFS_ITEM_LINK))
                goto out;
 
-       if (dentry->d_parent == configfs_sb->s_root)
-               BUG();
+       BUG_ON(dentry->d_parent == configfs_sb->s_root);
 
        sl = sd->s_element;
 
@@ -277,5 +276,6 @@ struct inode_operations configfs_symlink_inode_operations = {
        .follow_link = configfs_follow_link,
        .readlink = generic_readlink,
        .put_link = configfs_put_link,
+       .setattr = configfs_setattr,
 };
 
index 86bdb93789c6629c60027fdba100e99aa2709610..a173bba326666e322ca92813c1667671f783f65e 100644 (file)
@@ -743,7 +743,9 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
        dentry->d_op = NULL;
        dentry->d_fsdata = NULL;
        dentry->d_mounted = 0;
+#ifdef CONFIG_PROFILING
        dentry->d_cookie = NULL;
+#endif
        INIT_HLIST_NODE(&dentry->d_hash);
        INIT_LIST_HEAD(&dentry->d_lru);
        INIT_LIST_HEAD(&dentry->d_subdirs);
index efc97d9b78604d040ba12ae9b1e418a6f9818534..d575452cd9f758d510891b2b9e109c89c6332764 100644 (file)
@@ -56,7 +56,7 @@ static u64 debugfs_u8_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
- * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -98,7 +98,7 @@ static u64 debugfs_u16_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
 
 /**
- * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -140,7 +140,7 @@ static u64 debugfs_u32_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
 
 /**
- * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
index 30dbbd1df51191a68d536ca430fad8001a80c39f..848044af7e1677e6fba1c2d3f76897a916b1bb93 100644 (file)
@@ -857,6 +857,7 @@ do_holes:
                        /* Handle holes */
                        if (!buffer_mapped(map_bh)) {
                                char *kaddr;
+                               loff_t i_size_aligned;
 
                                /* AKPM: eargh, -ENOTBLK is a hack */
                                if (dio->rw == WRITE) {
@@ -864,8 +865,14 @@ do_holes:
                                        return -ENOTBLK;
                                }
 
+                               /*
+                                * Be sure to account for a partial block as the
+                                * last block in the file
+                                */
+                               i_size_aligned = ALIGN(i_size_read(dio->inode),
+                                                       1 << blkbits);
                                if (dio->block_in_file >=
-                                       i_size_read(dio->inode)>>blkbits) {
+                                               i_size_aligned >> blkbits) {
                                        /* We hit eof */
                                        page_cache_release(page);
                                        goto out;
index 35acc43b897f7e46b1563b2fa696973dec67ebe7..da52b4a5db64005173124575e63161ed1d6c3d35 100644 (file)
@@ -220,7 +220,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
        struct ext2_inode_info *ei = EXT2_I(inode);
        int name_index;
        void *value = NULL;
-       size_t size;
+       size_t size = 0;
        int error;
 
        if (S_ISLNK(inode->i_mode))
index 74714af4ae6979acf4516ff614e77b79155d3a80..e52765219e165eb866c4a0dafd120ce1d966806c 100644 (file)
@@ -605,7 +605,7 @@ got:
        insert_inode_hash(inode);
 
        if (DQUOT_ALLOC_INODE(inode)) {
-               err = -ENOSPC;
+               err = -EDQUOT;
                goto fail_drop;
        }
 
index 8d6819846fc97241375542c7316d2d9cd6a0b26e..cb6f9bd658de9646da588af8feacb64bbe1d3742 100644 (file)
@@ -221,6 +221,11 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
                seq_puts(seq, ",grpquota");
 #endif
 
+#if defined(CONFIG_EXT2_FS_XIP)
+       if (sbi->s_mount_opt & EXT2_MOUNT_XIP)
+               seq_puts(seq, ",xip");
+#endif
+
        return 0;
 }
 
index 47a9da2dfb4fbd9739ab46531fca3ec2d5040c9d..0d21d558b87a19d2105d32ff8df19698ffe439a5 100644 (file)
@@ -226,7 +226,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
        struct ext3_inode_info *ei = EXT3_I(inode);
        int name_index;
        void *value = NULL;
-       size_t size;
+       size_t size = 0;
        int error;
 
        if (S_ISLNK(inode->i_mode))
index e99c5a73b39e6f172e52ee394cba5b9289a78e87..88aa1ae13f9f3022c7978d9bbd7e5cb20c2d71aa 100644 (file)
@@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip)
        if (MSDOS_I(inode)->i_start == 0)
                return 0;
 
-       /*
-        * Write a new EOF, and get the remaining cluster chain for freeing.
-        */
+       fat_cache_inval_inode(inode);
+
        wait = IS_DIRSYNC(inode);
+       i_start = free_start = MSDOS_I(inode)->i_start;
+       i_logstart = MSDOS_I(inode)->i_logstart;
+
+       /* First, we write the new file size. */
+       if (!skip) {
+               MSDOS_I(inode)->i_start = 0;
+               MSDOS_I(inode)->i_logstart = 0;
+       }
+       MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+       inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
+       if (wait) {
+               err = fat_sync_inode(inode);
+               if (err) {
+                       MSDOS_I(inode)->i_start = i_start;
+                       MSDOS_I(inode)->i_logstart = i_logstart;
+                       return err;
+               }
+       } else
+               mark_inode_dirty(inode);
+
+       /* Write a new EOF, and get the remaining cluster chain for freeing. */
        if (skip) {
                struct fat_entry fatent;
                int ret, fclus, dclus;
@@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip)
                        return ret;
 
                free_start = ret;
-               i_start = i_logstart = 0;
-               fat_cache_inval_inode(inode);
-       } else {
-               fat_cache_inval_inode(inode);
-
-               i_start = free_start = MSDOS_I(inode)->i_start;
-               i_logstart = MSDOS_I(inode)->i_logstart;
-               MSDOS_I(inode)->i_start = 0;
-               MSDOS_I(inode)->i_logstart = 0;
        }
-       MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
-       inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
-       if (wait) {
-               err = fat_sync_inode(inode);
-               if (err)
-                       goto error;
-       } else
-               mark_inode_dirty(inode);
        inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
 
        /* Freeing the remained cluster chain */
        return fat_free_clusters(inode, free_start);
-
-error:
-       if (i_start) {
-               MSDOS_I(inode)->i_start = i_start;
-               MSDOS_I(inode)->i_logstart = i_logstart;
-       }
-       return err;
 }
 
 void fat_truncate(struct inode *inode)
index 32fb0a3f1da46b712ab514037ed0d8fbe0233808..944652e9dde13c4e7438b3a3074a5b6f95066a34 100644 (file)
@@ -196,19 +196,9 @@ EXPORT_SYMBOL_GPL(fat_date_unix2dos);
 
 int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
 {
-       int i, e, err = 0;
+       int i, err = 0;
 
-       for (i = 0; i < nr_bhs; i++) {
-               lock_buffer(bhs[i]);
-               if (test_clear_buffer_dirty(bhs[i])) {
-                       get_bh(bhs[i]);
-                       bhs[i]->b_end_io = end_buffer_write_sync;
-                       e = submit_bh(WRITE, bhs[i]);
-                       if (!err && e)
-                               err = e;
-               } else
-                       unlock_buffer(bhs[i]);
-       }
+       ll_rw_block(SWRITE, nr_bhs, bhs);
        for (i = 0; i < nr_bhs; i++) {
                wait_on_buffer(bhs[i]);
                if (buffer_eopnotsupp(bhs[i])) {
index 5f96786d1c73dc6c9ac27565b521835f6fe5ff12..dc4a7007f4e742c4e30563db78b34bd21d39ab58 100644 (file)
@@ -208,8 +208,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
        struct inode * inode = filp->f_dentry->d_inode;
        int error = 0;
 
-       /* O_APPEND cannot be cleared if the file is marked as append-only */
-       if (!(arg & O_APPEND) && IS_APPEND(inode))
+       /*
+        * O_APPEND cannot be cleared if the file is marked as append-only
+        * and the file is open for write.
+        */
+       if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
                return -EPERM;
 
        /* O_NOATIME can only be set by the owner or superuser */
index fd066b261c751875de1c4871974b54d335eafcd7..cea7cbea11d0d5fca944ab11a331568fe0949fb7 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -379,7 +379,6 @@ static void __devinit fdtable_defer_list_init(int cpu)
 void __init files_defer_init(void)
 {
        int i;
-       /* Really early - can't use for_each_cpu */
-       for (i = 0; i < NR_CPUS; i++)
+       for_each_cpu(i)
                fdtable_defer_list_init(i);
 }
index 4526da8907c6d384fefee03b18bd6894558bf459..f556a0d5c0d31010b86552ff958dcb55b20947f5 100644 (file)
@@ -120,9 +120,9 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc)
        return do_get_request(fc);
 }
 
+/* Must be called with fuse_lock held */
 static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
 {
-       spin_lock(&fuse_lock);
        if (req->preallocated) {
                atomic_dec(&fc->num_waiting);
                list_add(&req->list, &fc->unused_list);
@@ -134,10 +134,18 @@ static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
                fc->outstanding_debt--;
        else
                up(&fc->outstanding_sem);
-       spin_unlock(&fuse_lock);
 }
 
 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
+{
+       if (atomic_dec_and_test(&req->count)) {
+               spin_lock(&fuse_lock);
+               fuse_putback_request(fc, req);
+               spin_unlock(&fuse_lock);
+       }
+}
+
+static void fuse_put_request_locked(struct fuse_conn *fc, struct fuse_req *req)
 {
        if (atomic_dec_and_test(&req->count))
                fuse_putback_request(fc, req);
@@ -163,26 +171,36 @@ void fuse_release_background(struct fuse_req *req)
  * still waiting), the 'end' callback is called if given, else the
  * reference to the request is released
  *
+ * Releasing extra reference for foreground requests must be done
+ * within the same locked region as setting state to finished.  This
+ * is because fuse_reset_request() may be called after request is
+ * finished and it must be the sole possessor.  If request is
+ * interrupted and put in the background, it will return with an error
+ * and hence never be reset and reused.
+ *
  * Called with fuse_lock, unlocks it
  */
 static void request_end(struct fuse_conn *fc, struct fuse_req *req)
 {
-       void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
-       req->end = NULL;
        list_del(&req->list);
        req->state = FUSE_REQ_FINISHED;
-       spin_unlock(&fuse_lock);
-       if (req->background) {
+       if (!req->background) {
+               wake_up(&req->waitq);
+               fuse_put_request_locked(fc, req);
+               spin_unlock(&fuse_lock);
+       } else {
+               void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
+               req->end = NULL;
+               spin_unlock(&fuse_lock);
                down_read(&fc->sbput_sem);
                if (fc->mounted)
                        fuse_release_background(req);
                up_read(&fc->sbput_sem);
+               if (end)
+                       end(fc, req);
+               else
+                       fuse_put_request(fc, req);
        }
-       wake_up(&req->waitq);
-       if (end)
-               end(fc, req);
-       else
-               fuse_put_request(fc, req);
 }
 
 /*
index 878ccca61213c7cefcff20ce7e1e5b8e10039aab..3041503bde02f918382cacc49ec97275d1994b1f 100644 (file)
@@ -967,7 +967,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
                mask_add = 1;
 
        /* don't let user-space set invalid bits: we don't want flags set */
-       mask &= IN_ALL_EVENTS;
+       mask &= IN_ALL_EVENTS | IN_ONESHOT;
        if (unlikely(!mask)) {
                ret = -EINVAL;
                goto out;
index 429f4b263cf1198bf179af4377ff8b1c21af3d5e..ca917973c2c06d1fe1035a4d61ef21f505e5b435 100644 (file)
@@ -1308,6 +1308,7 @@ int journal_stop(handle_t *handle)
        transaction_t *transaction = handle->h_transaction;
        journal_t *journal = transaction->t_journal;
        int old_handle_count, err;
+       pid_t pid;
 
        J_ASSERT(transaction->t_updates > 0);
        J_ASSERT(journal_current_handle() == handle);
@@ -1333,8 +1334,15 @@ int journal_stop(handle_t *handle)
         * It doesn't cost much - we're about to run a commit and sleep
         * on IO anyway.  Speeds up many-threaded, many-dir operations
         * by 30x or more...
+        *
+        * But don't do this if this process was the most recent one to
+        * perform a synchronous write.  We do this to detect the case where a
+        * single process is doing a stream of sync writes.  No point in waiting
+        * for joiners in that case.
         */
-       if (handle->h_sync) {
+       pid = current->pid;
+       if (handle->h_sync && journal->j_last_sync_writer != pid) {
+               journal->j_last_sync_writer = pid;
                do {
                        old_handle_count = transaction->t_handle_count;
                        schedule_timeout_uninterruptible(1);
index b2e95421d932025407f758bb590d49b165a0a05a..ce7b54b0b2b7596333276bdcf42d40cf3011df0a 100644 (file)
@@ -1965,7 +1965,7 @@ retry:
                iovec_cnt++;
 
                if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {
-                       static char allff[3]={255,255,255};
+                       static unsigned char allff[3]={255,255,255};
                        /* Add some extra padding if necessary */
                        node_iovec[iovec_cnt].iov_base = allff;
                        node_iovec[iovec_cnt].iov_len =
index 63c020e6589e5c81e296f2eae3b9a2e5917aeee0..71fd08fa410301deef23dcc563f9232c92081fa9 100644 (file)
@@ -388,6 +388,7 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
+       inode->i_nlink = 2;
        root = d_alloc_root(inode);
        if (!root) {
                iput(inode);
index 145524039577c2719bd6c95cced7fb3469cf4453..220058d8616d143d7afb386a395b818b60a855aa 100644 (file)
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
 #define NLMCLNT_GRACE_WAIT     (5*HZ)
 #define NLMCLNT_POLL_TIMEOUT   (30*HZ)
+#define NLMCLNT_MAX_RETRIES    3
 
 static int     nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int     nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
 static int     nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
 static int     nlm_stat_to_errno(u32 stat);
 static void    nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
+static int     nlmclnt_cancel(struct nlm_host *, int , struct file_lock *);
 
 static const struct rpc_call_ops nlmclnt_unlock_ops;
 static const struct rpc_call_ops nlmclnt_cancel_ops;
@@ -598,7 +600,7 @@ out_unblock:
        nlmclnt_finish_block(req);
        /* Cancel the blocked request if it is still pending */
        if (resp->status == NLM_LCK_BLOCKED)
-               nlmclnt_cancel(host, fl);
+               nlmclnt_cancel(host, req->a_args.block, fl);
 out:
        nlmclnt_release_lockargs(req);
        return status;
@@ -728,8 +730,7 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = {
  * We always use an async RPC call for this in order not to hang a
  * process that has been Ctrl-C'ed.
  */
-int
-nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
+static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl)
 {
        struct nlm_rqst *req;
        unsigned long   flags;
@@ -750,6 +751,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
        req->a_flags = RPC_TASK_ASYNC;
 
        nlmclnt_setlockargs(req, fl);
+       req->a_args.block = block;
 
        status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops);
        if (status < 0) {
@@ -801,6 +803,9 @@ die:
        return;
 
 retry_cancel:
+       /* Don't ever retry more than 3 times */
+       if (req->a_retries++ >= NLMCLNT_MAX_RETRIES)
+               goto die;
        nlm_rebind_host(req->a_host);
        rpc_restart_call(task);
        rpc_delay(task, 30 * HZ);
index 7ac9fb4acb2c7d265fc48dff00810861f65cc4ce..e28de846c5919f84ba0f45ea464a4ee91913f7a9 100644 (file)
@@ -790,7 +790,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 
        inode = nd->dentry->d_inode;
        if (nd->depth)
-               lookup_flags = LOOKUP_FOLLOW;
+               lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
 
        /* At this point we know we have a real path component. */
        for(;;) {
@@ -885,7 +885,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 last_with_slashes:
                lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
 last_component:
-               nd->flags &= ~LOOKUP_CONTINUE;
+               /* Clear LOOKUP_CONTINUE iff it was previously unset */
+               nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
                if (lookup_flags & LOOKUP_PARENT)
                        goto lookup_parent;
                if (this.name[0] == '.') switch (this.len) {
@@ -1069,6 +1070,8 @@ static int fastcall do_path_lookup(int dfd, const char *name,
                                unsigned int flags, struct nameidata *nd)
 {
        int retval = 0;
+       int fput_needed;
+       struct file *file;
 
        nd->last_type = LAST_ROOT; /* if there are only slashes... */
        nd->flags = flags;
@@ -1090,29 +1093,22 @@ static int fastcall do_path_lookup(int dfd, const char *name,
                nd->mnt = mntget(current->fs->pwdmnt);
                nd->dentry = dget(current->fs->pwd);
        } else {
-               struct file *file;
-               int fput_needed;
                struct dentry *dentry;
 
                file = fget_light(dfd, &fput_needed);
-               if (!file) {
-                       retval = -EBADF;
-                       goto out_fail;
-               }
+               retval = -EBADF;
+               if (!file)
+                       goto unlock_fail;
 
                dentry = file->f_dentry;
 
-               if (!S_ISDIR(dentry->d_inode->i_mode)) {
-                       retval = -ENOTDIR;
-                       fput_light(file, fput_needed);
-                       goto out_fail;
-               }
+               retval = -ENOTDIR;
+               if (!S_ISDIR(dentry->d_inode->i_mode))
+                       goto fput_unlock_fail;
 
                retval = file_permission(file, MAY_EXEC);
-               if (retval) {
-                       fput_light(file, fput_needed);
-                       goto out_fail;
-               }
+               if (retval)
+                       goto fput_unlock_fail;
 
                nd->mnt = mntget(file->f_vfsmnt);
                nd->dentry = dget(dentry);
@@ -1123,10 +1119,17 @@ static int fastcall do_path_lookup(int dfd, const char *name,
        current->total_link_count = 0;
        retval = link_path_walk(name, nd);
 out:
-       if (unlikely(current->audit_context
-                    && nd && nd->dentry && nd->dentry->d_inode))
+       if (likely(retval == 0)) {
+               if (unlikely(current->audit_context && nd && nd->dentry &&
+                               nd->dentry->d_inode))
                audit_inode(name, nd->dentry->d_inode, flags);
-out_fail:
+       }
+       return retval;
+
+fput_unlock_fail:
+       fput_light(file, fput_needed);
+unlock_fail:
+       read_unlock(&current->fs->lock);
        return retval;
 }
 
index ce97becff4611c0fae4e90ce655bd8cffe850c77..058a44865bebdad95cb9416eefcedd1dd1473c25 100644 (file)
@@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
                p->mnt_namespace = NULL;
                list_del_init(&p->mnt_child);
                if (p->mnt_parent != p)
-                       mnt->mnt_mountpoint->d_mounted--;
+                       p->mnt_mountpoint->d_mounted--;
                change_mnt_propagation(p, MS_PRIVATE);
        }
 }
@@ -1325,27 +1325,17 @@ dput_out:
        return retval;
 }
 
-int copy_namespace(int flags, struct task_struct *tsk)
+/*
+ * Allocate a new namespace structure and populate it with contents
+ * copied from the namespace of the passed in task structure.
+ */
+struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 {
        struct namespace *namespace = tsk->namespace;
        struct namespace *new_ns;
        struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
-       struct fs_struct *fs = tsk->fs;
        struct vfsmount *p, *q;
 
-       if (!namespace)
-               return 0;
-
-       get_namespace(namespace);
-
-       if (!(flags & CLONE_NEWNS))
-               return 0;
-
-       if (!capable(CAP_SYS_ADMIN)) {
-               put_namespace(namespace);
-               return -EPERM;
-       }
-
        new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
        if (!new_ns)
                goto out;
@@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk)
        }
        up_write(&namespace_sem);
 
-       tsk->namespace = new_ns;
-
        if (rootmnt)
                mntput(rootmnt);
        if (pwdmnt)
@@ -1405,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk)
        if (altrootmnt)
                mntput(altrootmnt);
 
-       put_namespace(namespace);
-       return 0;
+out:
+       return new_ns;
+}
+
+int copy_namespace(int flags, struct task_struct *tsk)
+{
+       struct namespace *namespace = tsk->namespace;
+       struct namespace *new_ns;
+       int err = 0;
+
+       if (!namespace)
+               return 0;
+
+       get_namespace(namespace);
+
+       if (!(flags & CLONE_NEWNS))
+               return 0;
+
+       if (!capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
+       new_ns = dup_namespace(tsk, tsk->fs);
+       if (!new_ns) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       tsk->namespace = new_ns;
 
 out:
        put_namespace(namespace);
-       return -ENOMEM;
+       return err;
 }
 
 asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
index 10ae377e68ff2e0e3253a51ef411c040a3a89f7d..04ab2fc360e792404815e67ee44c3adb03510a25 100644 (file)
@@ -481,7 +481,7 @@ retry:
                if (wdata->verf.committed != NFS_FILE_SYNC) {
                        need_commit = 1;
                        if (memcmp(&first_verf.verifier, &wdata->verf.verifier,
-                                       sizeof(first_verf.verifier)));
+                                       sizeof(first_verf.verifier)))
                                goto sync_retry;
                }
 
index e897e00c2c9d3c49eb6c1c954df11cceefce392c..c0a754ecdee66447464a9bb67c900071896909a3 100644 (file)
@@ -465,10 +465,11 @@ static int __init root_nfs_ports(void)
                                        "number from server, using default\n");
                        port = nfsd_port;
                }
-               nfs_port = htons(port);
+               nfs_port = port;
                dprintk("Root-NFS: Portmapper on server returned %d "
                        "as nfsd port\n", port);
        }
+       nfs_port = htons(nfs_port);
 
        if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
                printk(KERN_ERR "Root-NFS: Unable to get mountd port "
index a00fe86862935a5c053505baca0fd6d1cdbdad09..6d63f1d9e5f598bdf15f9f44173083622a53eea5 100644 (file)
@@ -195,10 +195,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
 
        /* Openowner is now set, so sequence id will get bumped.  Now we need
         * these checks before we do any creates: */
+       status = nfserr_grace;
        if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
-               return nfserr_grace;
+               goto out;
+       status = nfserr_no_grace;
        if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-               return nfserr_no_grace;
+               goto out;
 
        switch (open->op_claim_type) {
                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
index d424041b38e9b568ffba1a287639f68f4c9d07f3..bae3d7548beae59961a436033fd69a99da391a57 100644 (file)
@@ -58,7 +58,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
                goto out;
        }
 
-       down(&OCFS2_I(inode)->ip_io_sem);
+       mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
 
        lock_buffer(bh);
        set_buffer_uptodate(bh);
@@ -82,7 +82,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
                brelse(bh);
        }
 
-       up(&OCFS2_I(inode)->ip_io_sem);
+       mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
 out:
        mlog_exit(ret);
        return ret;
@@ -125,13 +125,13 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
                flags &= ~OCFS2_BH_CACHED;
 
        if (inode)
-               down(&OCFS2_I(inode)->ip_io_sem);
+               mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
        for (i = 0 ; i < nr ; i++) {
                if (bhs[i] == NULL) {
                        bhs[i] = sb_getblk(sb, block++);
                        if (bhs[i] == NULL) {
                                if (inode)
-                                       up(&OCFS2_I(inode)->ip_io_sem);
+                                       mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
                                status = -EIO;
                                mlog_errno(status);
                                goto bail;
@@ -220,7 +220,7 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
                        ocfs2_set_buffer_uptodate(inode, bh);
        }
        if (inode)
-               up(&OCFS2_I(inode)->ip_io_sem);
+               mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
 
        mlog(ML_BH_IO, "block=(%"MLFu64"), nr=(%d), cached=%s\n", block, nr,
             (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes");
index 7307ba528913e660a0ebb235944c7736d5323fac..d08971d29b63b39c9478945bc64e900abc742a07 100644 (file)
@@ -917,8 +917,9 @@ static int o2hb_thread(void *data)
                elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
 
                mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n",
-                    before_hb.tv_sec, before_hb.tv_usec,
-                    after_hb.tv_sec, after_hb.tv_usec, elapsed_msec);
+                    before_hb.tv_sec, (unsigned long) before_hb.tv_usec,
+                    after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
+                    elapsed_msec);
 
                if (elapsed_msec < reg->hr_timeout_ms) {
                        /* the kthread api has blocked signals for us so no
index 35d92c01a9724110f6de8a35c87359afd9b9485b..d22d4cf08db165a80f8cd14ffe6304ebfba45e6a 100644 (file)
@@ -1285,14 +1285,16 @@ static void o2net_idle_timer(unsigned long data)
        mlog(ML_NOTICE, "here are some times that might help debug the "
             "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
             "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n",
-            sc->sc_tv_timer.tv_sec, sc->sc_tv_timer.tv_usec, 
-            now.tv_sec, now.tv_usec,
-            sc->sc_tv_data_ready.tv_sec, sc->sc_tv_data_ready.tv_usec, 
-            sc->sc_tv_advance_start.tv_sec, sc->sc_tv_advance_start.tv_usec, 
-            sc->sc_tv_advance_stop.tv_sec, sc->sc_tv_advance_stop.tv_usec, 
+            sc->sc_tv_timer.tv_sec, (long) sc->sc_tv_timer.tv_usec, 
+            now.tv_sec, (long) now.tv_usec,
+            sc->sc_tv_data_ready.tv_sec, (long) sc->sc_tv_data_ready.tv_usec,
+            sc->sc_tv_advance_start.tv_sec,
+            (long) sc->sc_tv_advance_start.tv_usec,
+            sc->sc_tv_advance_stop.tv_sec,
+            (long) sc->sc_tv_advance_stop.tv_usec,
             sc->sc_msg_key, sc->sc_msg_type,
-            sc->sc_tv_func_start.tv_sec, sc->sc_tv_func_start.tv_usec,
-            sc->sc_tv_func_stop.tv_sec, sc->sc_tv_func_stop.tv_usec);
+            sc->sc_tv_func_start.tv_sec, (long) sc->sc_tv_func_start.tv_usec,
+            sc->sc_tv_func_stop.tv_sec, (long) sc->sc_tv_func_stop.tv_usec);
 
        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
 }
index 3fecba0a60233ebc8458deb970f13d76c74deaab..42eb53b5293be362df0b5d3a608c5f360a004122 100644 (file)
@@ -657,6 +657,7 @@ void dlm_complete_thread(struct dlm_ctxt *dlm);
 int dlm_launch_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
+int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
 
 void dlm_put(struct dlm_ctxt *dlm);
 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
index da3c22045f898152b7b2ccbd5ac2f1761b5bd9c0..6ee30837389c9feed2ba7af4475cbaf51b1932e7 100644 (file)
@@ -573,8 +573,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data)
        spin_lock(&dlm_domain_lock);
        dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
        /* Once the dlm ctxt is marked as leaving then we don't want
-        * to be put in someone's domain map. */
+        * to be put in someone's domain map. 
+        * Also, explicitly disallow joining at certain troublesome
+        * times (ie. during recovery). */
        if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) {
+               int bit = query->node_idx;
                spin_lock(&dlm->spinlock);
 
                if (dlm->dlm_state == DLM_CTXT_NEW &&
@@ -586,6 +589,19 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data)
                } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) {
                        /* Disallow parallel joins. */
                        response = JOIN_DISALLOW;
+               } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) {
+                       mlog(ML_NOTICE, "node %u trying to join, but recovery "
+                            "is ongoing.\n", bit);
+                       response = JOIN_DISALLOW;
+               } else if (test_bit(bit, dlm->recovery_map)) {
+                       mlog(ML_NOTICE, "node %u trying to join, but it "
+                            "still needs recovery.\n", bit);
+                       response = JOIN_DISALLOW;
+               } else if (test_bit(bit, dlm->domain_map)) {
+                       mlog(ML_NOTICE, "node %u trying to join, but it "
+                            "is still in the domain! needs recovery?\n",
+                            bit);
+                       response = JOIN_DISALLOW;
                } else {
                        /* Alright we're fully a part of this domain
                         * so we keep some state as to who's joining
index 27e984f7e4cdbd40585a2927e3f9080282ed7af3..a3194fe173d97b498b5753777e85306569ed094b 100644 (file)
@@ -1050,17 +1050,10 @@ static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm,
        node = dlm_bitmap_diff_iter_next(&bdi, &sc);
        while (node >= 0) {
                if (sc == NODE_UP) {
-                       /* a node came up.  easy.  might not even need
-                        * to talk to it if its node number is higher
-                        * or if we are already blocked. */
-                       mlog(0, "node up! %d\n", node);
-                       if (blocked)
-                               goto next;
-
-                       if (node > dlm->node_num) {
-                               mlog(0, "node > this node. skipping.\n");
-                               goto next;
-                       }
+                       /* a node came up.  clear any old vote from
+                        * the response map and set it in the vote map
+                        * then restart the mastery. */
+                       mlog(ML_NOTICE, "node %d up while restarting\n", node);
 
                        /* redo the master request, but only for the new node */
                        mlog(0, "sending request to new node\n");
@@ -2005,6 +1998,15 @@ fail:
                                break;
 
                        mlog(0, "timed out during migration\n");
+                       /* avoid hang during shutdown when migrating lockres 
+                        * to a node which also goes down */
+                       if (dlm_is_node_dead(dlm, target)) {
+                               mlog(0, "%s:%.*s: expected migration target %u "
+                                    "is no longer up.  restarting.\n",
+                                    dlm->name, res->lockname.len,
+                                    res->lockname.name, target);
+                               ret = -ERESTARTSYS;
+                       }
                }
                if (ret == -ERESTARTSYS) {
                        /* migration failed, detach and clean up mle */
index 0c8eb1093f0056bb4d8673e42c633c5a6ce3e8fe..186e9a76aa5807565ad09e31e0bd0fa7584dcab5 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/inet.h>
 #include <linux/timer.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
 
 
 #include "cluster/heartbeat.h"
@@ -256,6 +257,27 @@ static int dlm_recovery_thread(void *data)
        return 0;
 }
 
+/* returns true when the recovery master has contacted us */
+static int dlm_reco_master_ready(struct dlm_ctxt *dlm)
+{
+       int ready;
+       spin_lock(&dlm->spinlock);
+       ready = (dlm->reco.new_master != O2NM_INVALID_NODE_NUM);
+       spin_unlock(&dlm->spinlock);
+       return ready;
+}
+
+/* returns true if node is no longer in the domain
+ * could be dead or just not joined */
+int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node)
+{
+       int dead;
+       spin_lock(&dlm->spinlock);
+       dead = test_bit(node, dlm->domain_map);
+       spin_unlock(&dlm->spinlock);
+       return dead;
+}
+
 /* callers of the top-level api calls (dlmlock/dlmunlock) should
  * block on the dlm->reco.event when recovery is in progress.
  * the dlm recovery thread will set this state when it begins
@@ -297,6 +319,7 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm)
 static int dlm_do_recovery(struct dlm_ctxt *dlm)
 {
        int status = 0;
+       int ret;
 
        spin_lock(&dlm->spinlock);
 
@@ -343,10 +366,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                goto master_here;
 
        if (dlm->reco.new_master == O2NM_INVALID_NODE_NUM) {
-               /* choose a new master */
-               if (!dlm_pick_recovery_master(dlm)) {
+               /* choose a new master, returns 0 if this node
+                * is the master, -EEXIST if it's another node.
+                * this does not return until a new master is chosen
+                * or recovery completes entirely. */
+               ret = dlm_pick_recovery_master(dlm);
+               if (!ret) {
                        /* already notified everyone.  go. */
-                       dlm->reco.new_master = dlm->node_num;
                        goto master_here;
                }
                mlog(0, "another node will master this recovery session.\n");
@@ -371,8 +397,13 @@ master_here:
        if (status < 0) {
                mlog(ML_ERROR, "error %d remastering locks for node %u, "
                     "retrying.\n", status, dlm->reco.dead_node);
+               /* yield a bit to allow any final network messages
+                * to get handled on remaining nodes */
+               msleep(100);
        } else {
                /* success!  see if any other nodes need recovery */
+               mlog(0, "DONE mastering recovery of %s:%u here(this=%u)!\n",
+                    dlm->name, dlm->reco.dead_node, dlm->node_num);
                dlm_reset_recovery(dlm);
        }
        dlm_end_recovery(dlm);
@@ -477,7 +508,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                                        BUG();
                                        break;
                                case DLM_RECO_NODE_DATA_DEAD:
-                                       mlog(0, "node %u died after "
+                                       mlog(ML_NOTICE, "node %u died after "
                                             "requesting recovery info for "
                                             "node %u\n", ndata->node_num,
                                             dead_node);
@@ -485,6 +516,19 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                                        // start all over
                                        destroy = 1;
                                        status = -EAGAIN;
+                                       /* instead of spinning like crazy here,
+                                        * wait for the domain map to catch up
+                                        * with the network state.  otherwise this
+                                        * can be hit hundreds of times before
+                                        * the node is really seen as dead. */
+                                       wait_event_timeout(dlm->dlm_reco_thread_wq,
+                                                          dlm_is_node_dead(dlm,
+                                                               ndata->node_num),
+                                                          msecs_to_jiffies(1000));
+                                       mlog(0, "waited 1 sec for %u, "
+                                            "dead? %s\n", ndata->node_num,
+                                            dlm_is_node_dead(dlm, ndata->node_num) ?
+                                            "yes" : "no");
                                        goto leave;
                                case DLM_RECO_NODE_DATA_RECEIVING:
                                case DLM_RECO_NODE_DATA_REQUESTED:
@@ -678,11 +722,27 @@ static void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data)
        dlm = item->dlm;
        dead_node = item->u.ral.dead_node;
        reco_master = item->u.ral.reco_master;
+       mres = (struct dlm_migratable_lockres *)data;
+
+       if (dead_node != dlm->reco.dead_node ||
+           reco_master != dlm->reco.new_master) {
+               /* show extra debug info if the recovery state is messed */
+               mlog(ML_ERROR, "%s: bad reco state: reco(dead=%u, master=%u), "
+                    "request(dead=%u, master=%u)\n",
+                    dlm->name, dlm->reco.dead_node, dlm->reco.new_master,
+                    dead_node, reco_master);
+               mlog(ML_ERROR, "%s: name=%.*s master=%u locks=%u/%u flags=%u "
+                    "entry[0]={c=%"MLFu64",l=%u,f=%u,t=%d,ct=%d,hb=%d,n=%u}\n",
+                    dlm->name, mres->lockname_len, mres->lockname, mres->master,
+                    mres->num_locks, mres->total_locks, mres->flags,
+                    mres->ml[0].cookie, mres->ml[0].list, mres->ml[0].flags,
+                    mres->ml[0].type, mres->ml[0].convert_type,
+                    mres->ml[0].highest_blocked, mres->ml[0].node);
+               BUG();
+       }
        BUG_ON(dead_node != dlm->reco.dead_node);
        BUG_ON(reco_master != dlm->reco.new_master);
 
-       mres = (struct dlm_migratable_lockres *)data;
-
        /* lock resources should have already been moved to the
         * dlm->reco.resources list.  now move items from that list
         * to a temp list if the dead owner matches.  note that the
@@ -757,15 +817,18 @@ int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data)
                        continue;
 
                switch (ndata->state) {
+                       /* should have moved beyond INIT but not to FINALIZE yet */
                        case DLM_RECO_NODE_DATA_INIT:
                        case DLM_RECO_NODE_DATA_DEAD:
-                       case DLM_RECO_NODE_DATA_DONE:
                        case DLM_RECO_NODE_DATA_FINALIZE_SENT:
                                mlog(ML_ERROR, "bad ndata state for node %u:"
                                     " state=%d\n", ndata->node_num,
                                     ndata->state);
                                BUG();
                                break;
+                       /* these states are possible at this point, anywhere along
+                        * the line of recovery */
+                       case DLM_RECO_NODE_DATA_DONE:
                        case DLM_RECO_NODE_DATA_RECEIVING:
                        case DLM_RECO_NODE_DATA_REQUESTED:
                        case DLM_RECO_NODE_DATA_REQUESTING:
@@ -799,13 +862,31 @@ static void dlm_move_reco_locks_to_list(struct dlm_ctxt *dlm,
 {
        struct dlm_lock_resource *res;
        struct list_head *iter, *iter2;
+       struct dlm_lock *lock;
 
        spin_lock(&dlm->spinlock);
        list_for_each_safe(iter, iter2, &dlm->reco.resources) {
                res = list_entry (iter, struct dlm_lock_resource, recovering);
+               /* always prune any $RECOVERY entries for dead nodes,
+                * otherwise hangs can occur during later recovery */
                if (dlm_is_recovery_lock(res->lockname.name,
-                                        res->lockname.len))
+                                        res->lockname.len)) {
+                       spin_lock(&res->spinlock);
+                       list_for_each_entry(lock, &res->granted, list) {
+                               if (lock->ml.node == dead_node) {
+                                       mlog(0, "AHA! there was "
+                                            "a $RECOVERY lock for dead "
+                                            "node %u (%s)!\n", 
+                                            dead_node, dlm->name);
+                                       list_del_init(&lock->list);
+                                       dlm_lock_put(lock);
+                                       break;
+                               }
+                       }
+                       spin_unlock(&res->spinlock);
                        continue;
+               }
+
                if (res->owner == dead_node) {
                        mlog(0, "found lockres owned by dead node while "
                                  "doing recovery for node %u. sending it.\n",
@@ -1179,7 +1260,7 @@ static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data)
 again:
                ret = dlm_lockres_master_requery(dlm, res, &real_master);
                if (ret < 0) {
-                       mlog(0, "dlm_lockres_master_requery failure: %d\n",
+                       mlog(0, "dlm_lockres_master_requery ret=%d\n",
                                  ret);
                        goto again;
                }
@@ -1757,6 +1838,7 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
        struct dlm_lock_resource *res;
        int i;
        struct list_head *bucket;
+       struct dlm_lock *lock;
 
 
        /* purge any stale mles */
@@ -1780,10 +1862,25 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
                bucket = &(dlm->resources[i]);
                list_for_each(iter, bucket) {
                        res = list_entry (iter, struct dlm_lock_resource, list);
+                       /* always prune any $RECOVERY entries for dead nodes,
+                        * otherwise hangs can occur during later recovery */
                        if (dlm_is_recovery_lock(res->lockname.name,
-                                                res->lockname.len))
+                                                res->lockname.len)) {
+                               spin_lock(&res->spinlock);
+                               list_for_each_entry(lock, &res->granted, list) {
+                                       if (lock->ml.node == dead_node) {
+                                               mlog(0, "AHA! there was "
+                                                    "a $RECOVERY lock for dead "
+                                                    "node %u (%s)!\n",
+                                                    dead_node, dlm->name);
+                                               list_del_init(&lock->list);
+                                               dlm_lock_put(lock);
+                                               break;
+                                       }
+                               }
+                               spin_unlock(&res->spinlock);
                                continue;
-                       
+                       }                       
                        spin_lock(&res->spinlock);
                        /* zero the lvb if necessary */
                        dlm_revalidate_lvb(dlm, res, dead_node);
@@ -1869,12 +1966,9 @@ void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data)
                return;
 
        spin_lock(&dlm->spinlock);
-
        set_bit(idx, dlm->live_nodes_map);
-
-       /* notify any mles attached to the heartbeat events */
-       dlm_hb_event_notify_attached(dlm, idx, 1);
-
+       /* do NOT notify mle attached to the heartbeat events.
+        * new nodes are not interesting in mastery until joined. */
        spin_unlock(&dlm->spinlock);
 
        dlm_put(dlm);
@@ -1897,7 +1991,18 @@ static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st)
        mlog(0, "unlockast for recovery lock fired!\n");
 }
 
-
+/*
+ * dlm_pick_recovery_master will continually attempt to use
+ * dlmlock() on the special "$RECOVERY" lockres with the
+ * LKM_NOQUEUE flag to get an EX.  every thread that enters
+ * this function on each node racing to become the recovery
+ * master will not stop attempting this until either:
+ * a) this node gets the EX (and becomes the recovery master),
+ * or b) dlm->reco.new_master gets set to some nodenum 
+ * != O2NM_INVALID_NODE_NUM (another node will do the reco).
+ * so each time a recovery master is needed, the entire cluster
+ * will sync at this point.  if the new master dies, that will
+ * be detected in dlm_do_recovery */
 static int dlm_pick_recovery_master(struct dlm_ctxt *dlm)
 {
        enum dlm_status ret;
@@ -1906,23 +2011,45 @@ static int dlm_pick_recovery_master(struct dlm_ctxt *dlm)
 
        mlog(0, "starting recovery of %s at %lu, dead=%u, this=%u\n",
             dlm->name, jiffies, dlm->reco.dead_node, dlm->node_num);
-retry:
+again: 
        memset(&lksb, 0, sizeof(lksb));
 
        ret = dlmlock(dlm, LKM_EXMODE, &lksb, LKM_NOQUEUE|LKM_RECOVERY,
                      DLM_RECOVERY_LOCK_NAME, dlm_reco_ast, dlm, dlm_reco_bast);
 
+       mlog(0, "%s: dlmlock($RECOVERY) returned %d, lksb=%d\n",
+            dlm->name, ret, lksb.status);
+
        if (ret == DLM_NORMAL) {
                mlog(0, "dlm=%s dlmlock says I got it (this=%u)\n",
                     dlm->name, dlm->node_num);
-               /* I am master, send message to all nodes saying
-                * that I am beginning a recovery session */
-               status = dlm_send_begin_reco_message(dlm,
-                                             dlm->reco.dead_node);
+               
+               /* got the EX lock.  check to see if another node 
+                * just became the reco master */
+               if (dlm_reco_master_ready(dlm)) {
+                       mlog(0, "%s: got reco EX lock, but %u will "
+                            "do the recovery\n", dlm->name,
+                            dlm->reco.new_master);
+                       status = -EEXIST;
+               } else {
+                       status = dlm_send_begin_reco_message(dlm,
+                                     dlm->reco.dead_node);
+                       /* this always succeeds */
+                       BUG_ON(status);
+
+                       /* set the new_master to this node */
+                       spin_lock(&dlm->spinlock);
+                       dlm->reco.new_master = dlm->node_num;
+                       spin_unlock(&dlm->spinlock);
+               }
 
                /* recovery lock is a special case.  ast will not get fired,
                 * so just go ahead and unlock it. */
                ret = dlmunlock(dlm, &lksb, 0, dlm_reco_unlock_ast, dlm);
+               if (ret == DLM_DENIED) {
+                       mlog(0, "got DLM_DENIED, trying LKM_CANCEL\n");
+                       ret = dlmunlock(dlm, &lksb, LKM_CANCEL, dlm_reco_unlock_ast, dlm);
+               }
                if (ret != DLM_NORMAL) {
                        /* this would really suck. this could only happen
                         * if there was a network error during the unlock
@@ -1930,20 +2057,42 @@ retry:
                         * is actually "done" and the lock structure is
                         * even freed.  we can continue, but only
                         * because this specific lock name is special. */
-                       mlog(0, "dlmunlock returned %d\n", ret);
-               }
-
-               if (status < 0) {
-                       mlog(0, "failed to send recovery message. "
-                                  "must retry with new node map.\n");
-                       goto retry;
+                       mlog(ML_ERROR, "dlmunlock returned %d\n", ret);
                }
        } else if (ret == DLM_NOTQUEUED) {
                mlog(0, "dlm=%s dlmlock says another node got it (this=%u)\n",
                     dlm->name, dlm->node_num);
                /* another node is master. wait on
-                * reco.new_master != O2NM_INVALID_NODE_NUM */
+                * reco.new_master != O2NM_INVALID_NODE_NUM 
+                * for at most one second */
+               wait_event_timeout(dlm->dlm_reco_thread_wq,
+                                        dlm_reco_master_ready(dlm),
+                                        msecs_to_jiffies(1000));
+               if (!dlm_reco_master_ready(dlm)) {
+                       mlog(0, "%s: reco master taking awhile\n",
+                            dlm->name);
+                       goto again;
+               }
+               /* another node has informed this one that it is reco master */
+               mlog(0, "%s: reco master %u is ready to recover %u\n",
+                    dlm->name, dlm->reco.new_master, dlm->reco.dead_node);
                status = -EEXIST;
+       } else {
+               struct dlm_lock_resource *res;
+
+               /* dlmlock returned something other than NOTQUEUED or NORMAL */
+               mlog(ML_ERROR, "%s: got %s from dlmlock($RECOVERY), "
+                    "lksb.status=%s\n", dlm->name, dlm_errname(ret),
+                    dlm_errname(lksb.status));
+               res = dlm_lookup_lockres(dlm, DLM_RECOVERY_LOCK_NAME,
+                                        DLM_RECOVERY_LOCK_NAME_LEN);
+               if (res) {
+                       dlm_print_one_lock_resource(res);
+                       dlm_lockres_put(res);
+               } else {
+                       mlog(ML_ERROR, "recovery lock not found\n");
+               }
+               BUG();
        }
 
        return status;
@@ -1982,7 +2131,7 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node)
                        mlog(0, "not sending begin reco to self\n");
                        continue;
                }
-
+retry:
                ret = -EINVAL;
                mlog(0, "attempting to send begin reco msg to %d\n",
                          nodenum);
@@ -1991,8 +2140,17 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node)
                /* negative status is handled ok by caller here */
                if (ret >= 0)
                        ret = status;
+               if (dlm_is_host_down(ret)) {
+                       /* node is down.  not involved in recovery
+                        * so just keep going */
+                       mlog(0, "%s: node %u was down when sending "
+                            "begin reco msg (%d)\n", dlm->name, nodenum, ret);
+                       ret = 0;
+               }
                if (ret < 0) {
                        struct dlm_lock_resource *res;
+                       /* this is now a serious problem, possibly ENOMEM 
+                        * in the network stack.  must retry */
                        mlog_errno(ret);
                        mlog(ML_ERROR, "begin reco of dlm %s to node %u "
                            " returned %d\n", dlm->name, nodenum, ret);
@@ -2004,7 +2162,10 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node)
                        } else {
                                mlog(ML_ERROR, "recovery lock not found\n");
                        }
-                       break;
+                       /* sleep for a bit in hopes that we can avoid 
+                        * another ENOMEM */
+                       msleep(100);
+                       goto retry;
                }
        }
 
@@ -2027,19 +2188,34 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data)
 
        spin_lock(&dlm->spinlock);
        if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) {
-               mlog(0, "new_master already set to %u!\n",
-                         dlm->reco.new_master);
+               if (test_bit(dlm->reco.new_master, dlm->recovery_map)) {
+                       mlog(0, "%s: new_master %u died, changing "
+                            "to %u\n", dlm->name, dlm->reco.new_master,
+                            br->node_idx);
+               } else {
+                       mlog(0, "%s: new_master %u NOT DEAD, changing "
+                            "to %u\n", dlm->name, dlm->reco.new_master,
+                            br->node_idx);
+                       /* may not have seen the new master as dead yet */
+               }
        }
        if (dlm->reco.dead_node != O2NM_INVALID_NODE_NUM) {
-               mlog(0, "dead_node already set to %u!\n",
-                         dlm->reco.dead_node);
+               mlog(ML_NOTICE, "%s: dead_node previously set to %u, "
+                    "node %u changing it to %u\n", dlm->name, 
+                    dlm->reco.dead_node, br->node_idx, br->dead_node);
        }
        dlm->reco.new_master = br->node_idx;
        dlm->reco.dead_node = br->dead_node;
        if (!test_bit(br->dead_node, dlm->recovery_map)) {
-               mlog(ML_ERROR, "recovery master %u sees %u as dead, but this "
+               mlog(0, "recovery master %u sees %u as dead, but this "
                     "node has not yet.  marking %u as dead\n",
                     br->node_idx, br->dead_node, br->dead_node);
+               if (!test_bit(br->dead_node, dlm->domain_map) ||
+                   !test_bit(br->dead_node, dlm->live_nodes_map))
+                       mlog(0, "%u not in domain/live_nodes map "
+                            "so setting it in reco map manually\n",
+                            br->dead_node);
+               set_bit(br->dead_node, dlm->recovery_map);
                __dlm_hb_node_down(dlm, br->dead_node);
        }
        spin_unlock(&dlm->spinlock);
index cec2ce1cd318962ecf4dcfc553dda8a111a16fba..c95f08d2e925493fba9ab0a690769cfdda8243e3 100644 (file)
@@ -188,6 +188,19 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
                        actions &= ~(DLM_UNLOCK_REMOVE_LOCK|
                                     DLM_UNLOCK_REGRANT_LOCK|
                                     DLM_UNLOCK_CLEAR_CONVERT_TYPE);
+               } else if (status == DLM_RECOVERING || 
+                          status == DLM_MIGRATING || 
+                          status == DLM_FORWARD) {
+                       /* must clear the actions because this unlock
+                        * is about to be retried.  cannot free or do
+                        * any list manipulation. */
+                       mlog(0, "%s:%.*s: clearing actions, %s\n",
+                            dlm->name, res->lockname.len,
+                            res->lockname.name,
+                            status==DLM_RECOVERING?"recovering":
+                            (status==DLM_MIGRATING?"migrating":
+                             "forward"));
+                       actions = 0;
                }
                if (flags & LKM_CANCEL)
                        lock->cancel_pending = 0;
index e1fdd288796ecaf4d3879ac841e6d7b3d3a295d3..c3764f4744ee60c9a7f6e6e2b11ff7c1fd9f48c4 100644 (file)
@@ -27,7 +27,7 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <asm/signal.h>
+#include <linux/signal.h>
 
 #include <linux/module.h>
 #include <linux/fs.h>
index f2fb40cd296a2890b1af082794c1324ba6969c0d..b6ba292e9544000444718395aee0be5f39bf6de0 100644 (file)
@@ -262,8 +262,7 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
                el = &eb->h_list;
        }
 
-       if (el->l_tree_depth)
-               BUG();
+       BUG_ON(el->l_tree_depth);
 
        for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
                rec = &el->l_recs[i];
@@ -364,8 +363,8 @@ static int ocfs2_extent_map_lookup_read(struct inode *inode,
                return ret;
        }
 
-       if (ent->e_tree_depth)
-               BUG();  /* FIXME: Make sure this isn't a corruption */
+       /* FIXME: Make sure this isn't a corruption */
+       BUG_ON(ent->e_tree_depth);
 
        *ret_ent = ent;
 
@@ -423,8 +422,7 @@ static int ocfs2_extent_map_try_insert(struct inode *inode,
                                          le32_to_cpu(rec->e_clusters), NULL,
                                          NULL);
 
-       if (!old_ent)
-               BUG();
+       BUG_ON(!old_ent);
 
        ret = -EEXIST;
        if (old_ent->e_tree_depth < tree_depth)
@@ -988,7 +986,7 @@ int __init init_ocfs2_extent_maps(void)
        return 0;
 }
 
-void __exit exit_ocfs2_extent_maps(void)
+void exit_ocfs2_extent_maps(void)
 {
        kmem_cache_destroy(ocfs2_em_ent_cachep);
 }
index eaf33caa0a1f8b73dad142387216bd837dda5add..1715bc90e705eb36e3e0e56577265bb3053b38c6 100644 (file)
@@ -1022,8 +1022,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
                }
                newsize = count + saved_pos;
 
-               mlog(0, "pos=%lld newsize=%"MLFu64" cursize=%lld\n",
-                    saved_pos, newsize, i_size_read(inode));
+               mlog(0, "pos=%lld newsize=%lld cursize=%lld\n",
+                    (long long) saved_pos, (long long) newsize,
+                    (long long) i_size_read(inode));
 
                /* No need for a higher level metadata lock if we're
                 * never going past i_size. */
@@ -1042,8 +1043,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
                spin_unlock(&OCFS2_I(inode)->ip_lock);
 
                mlog(0, "Writing at EOF, may need more allocation: "
-                    "i_size = %lld, newsize = %"MLFu64", need %u clusters\n",
-                    i_size_read(inode), newsize, clusters);
+                    "i_size = %lld, newsize = %lld, need %u clusters\n",
+                    (long long) i_size_read(inode), (long long) newsize,
+                    clusters);
 
                /* We only want to continue the rest of this loop if
                 * our extend will actually require more
index d4ecc0627716fbc6a7d44a178384dffce5f3fed6..8122489c5762bb9c7f042ba5ebb3cf79a852b60c 100644 (file)
@@ -903,10 +903,10 @@ void ocfs2_clear_inode(struct inode *inode)
                        "Clear inode of %"MLFu64", inode is locked\n",
                        oi->ip_blkno);
 
-       mlog_bug_on_msg(down_trylock(&oi->ip_io_sem),
-                       "Clear inode of %"MLFu64", io_sem is locked\n",
+       mlog_bug_on_msg(!mutex_trylock(&oi->ip_io_mutex),
+                       "Clear inode of %"MLFu64", io_mutex is locked\n",
                        oi->ip_blkno);
-       up(&oi->ip_io_sem);
+       mutex_unlock(&oi->ip_io_mutex);
 
        /*
         * down_trylock() returns 0, down_write_trylock() returns 1
index 9b017743365380bf92f5c7c31912d24f031b9c0f..84c5079612870bae7ba80aa5e8831a63564687d9 100644 (file)
@@ -46,10 +46,10 @@ struct ocfs2_inode_info
        struct list_head                ip_io_markers;
        int                             ip_orphaned_slot;
 
-       struct semaphore                ip_io_sem;
+       struct mutex                    ip_io_mutex;
 
        /* Used by the journalling code to attach an inode to a
-        * handle.  These are protected by ip_io_sem in order to lock
+        * handle.  These are protected by ip_io_mutex in order to lock
         * out other I/O to the inode until we either commit or
         * abort. */
        struct list_head                ip_handle_list;
index 303c8d96457f818d7623b0025e7fbcfd74a2dfb5..fa0bcac5ceaef0aeef8539f45a4b7ace3c6be648 100644 (file)
@@ -147,8 +147,7 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
 
        mlog_entry("(max_buffs = %d)\n", max_buffs);
 
-       if (!osb || !osb->journal->j_journal)
-               BUG();
+       BUG_ON(!osb || !osb->journal->j_journal);
 
        if (ocfs2_is_hard_readonly(osb)) {
                ret = -EROFS;
@@ -401,7 +400,7 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
         * j_trans_barrier for us. */
        ocfs2_set_inode_lock_trans(OCFS2_SB(inode->i_sb)->journal, inode);
 
-       down(&OCFS2_I(inode)->ip_io_sem);
+       mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
        switch (type) {
        case OCFS2_JOURNAL_ACCESS_CREATE:
        case OCFS2_JOURNAL_ACCESS_WRITE:
@@ -416,7 +415,7 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
                status = -EINVAL;
                mlog(ML_ERROR, "Uknown access type!\n");
        }
-       up(&OCFS2_I(inode)->ip_io_sem);
+       mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
 
        if (status < 0)
                mlog(ML_ERROR, "Error %d getting %d access to buffer!\n",
@@ -561,7 +560,11 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
        SET_INODE_JOURNAL(inode);
        OCFS2_I(inode)->ip_open_count++;
 
-       status = ocfs2_meta_lock(inode, NULL, &bh, 1);
+       /* Skip recovery waits here - journal inode metadata never
+        * changes in a live cluster so it can be considered an
+        * exception to the rule. */
+       status = ocfs2_meta_lock_full(inode, NULL, &bh, 1,
+                                     OCFS2_META_LOCK_RECOVERY);
        if (status < 0) {
                if (status != -ERESTARTSYS)
                        mlog(ML_ERROR, "Could not get lock on journal!\n");
@@ -672,8 +675,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
 
        mlog_entry_void();
 
-       if (!osb)
-               BUG();
+       BUG_ON(!osb);
 
        journal = osb->journal;
        if (!journal)
@@ -805,8 +807,7 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full)
 
        mlog_entry_void();
 
-       if (!journal)
-               BUG();
+       BUG_ON(!journal);
 
        status = journal_wipe(journal->j_journal, full);
        if (status < 0) {
@@ -1072,10 +1073,10 @@ restart:
                                        NULL);
 
 bail:
-       down(&osb->recovery_lock);
+       mutex_lock(&osb->recovery_lock);
        if (!status &&
            !ocfs2_node_map_is_empty(osb, &osb->recovery_map)) {
-               up(&osb->recovery_lock);
+               mutex_unlock(&osb->recovery_lock);
                goto restart;
        }
 
@@ -1083,7 +1084,7 @@ bail:
        mb(); /* sync with ocfs2_recovery_thread_running */
        wake_up(&osb->recovery_event);
 
-       up(&osb->recovery_lock);
+       mutex_unlock(&osb->recovery_lock);
 
        mlog_exit(status);
        /* no one is callint kthread_stop() for us so the kthread() api
@@ -1098,7 +1099,7 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
        mlog_entry("(node_num=%d, osb->node_num = %d)\n",
                   node_num, osb->node_num);
 
-       down(&osb->recovery_lock);
+       mutex_lock(&osb->recovery_lock);
        if (osb->disable_recovery)
                goto out;
 
@@ -1120,7 +1121,7 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
        }
 
 out:
-       up(&osb->recovery_lock);
+       mutex_unlock(&osb->recovery_lock);
        wake_up(&osb->recovery_event);
 
        mlog_exit_void();
@@ -1271,8 +1272,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
 
        /* Should not ever be called to recover ourselves -- in that
         * case we should've called ocfs2_journal_load instead. */
-       if (osb->node_num == node_num)
-               BUG();
+       BUG_ON(osb->node_num == node_num);
 
        slot_num = ocfs2_node_num_to_slot(si, node_num);
        if (slot_num == OCFS2_INVALID_SLOT) {
index f468c600cf92297de8cc4999123783518b102c52..8d8e4779df92ba7ffe84f293d17cddb9b7afb6f3 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/rbtree.h>
 #include <linux/workqueue.h>
 #include <linux/kref.h>
+#include <linux/mutex.h>
 
 #include "cluster/nodemanager.h"
 #include "cluster/heartbeat.h"
@@ -233,7 +234,7 @@ struct ocfs2_super
        struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */
 
        atomic_t vol_state;
-       struct semaphore recovery_lock;
+       struct mutex recovery_lock;
        struct task_struct *recovery_thread_task;
        int disable_recovery;
        wait_queue_head_t checkpoint_event;
index 364d64bd5f1067177779bf0a5d3754a67cebde0d..046824b6b6256267d8a9d15275b034e7abeae025 100644 (file)
@@ -932,7 +932,7 @@ static void ocfs2_inode_init_once(void *data,
                oi->ip_dir_start_lookup = 0;
 
                init_rwsem(&oi->ip_alloc_sem);
-               init_MUTEX(&(oi->ip_io_sem));
+               mutex_init(&oi->ip_io_mutex);
 
                oi->ip_blkno = 0ULL;
                oi->ip_clusters = 0;
@@ -1137,9 +1137,9 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        /* disable any new recovery threads and wait for any currently
         * running ones to exit. Do this before setting the vol_state. */
-       down(&osb->recovery_lock);
+       mutex_lock(&osb->recovery_lock);
        osb->disable_recovery = 1;
-       up(&osb->recovery_lock);
+       mutex_unlock(&osb->recovery_lock);
        wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
 
        /* At this point, we know that no more recovery threads can be
@@ -1254,8 +1254,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
        osb->sb = sb;
        /* Save off for ocfs2_rw_direct */
        osb->s_sectsize_bits = blksize_bits(sector_size);
-       if (!osb->s_sectsize_bits)
-               BUG();
+       BUG_ON(!osb->s_sectsize_bits);
 
        osb->net_response_ids = 0;
        spin_lock_init(&osb->net_response_lock);
@@ -1283,7 +1282,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
        snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
                 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 
-       init_MUTEX(&osb->recovery_lock);
+       mutex_init(&osb->recovery_lock);
 
        osb->disable_recovery = 0;
        osb->recovery_thread_task = NULL;
index 600a8bc5b54113454868fec31113a097394dd08a..fc29cb7a437d22e861da2e75cf8046fe1f5b9777 100644 (file)
@@ -77,8 +77,7 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb,
        if (arr && ((inode = *arr) != NULL)) {
                /* get a ref in addition to the array ref */
                inode = igrab(inode);
-               if (!inode)
-                       BUG();
+               BUG_ON(!inode);
 
                return inode;
        }
@@ -89,8 +88,7 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb,
        /* add one more if putting into array for first time */
        if (arr && inode) {
                *arr = igrab(inode);
-               if (!*arr)
-                       BUG();
+               BUG_ON(!*arr);
        }
        return inode;
 }
index 3a0458fd3e1b72f6b8d44608639fc3c8984d62d0..300b5bedfb21d8b168a6b94d5304618479ff7236 100644 (file)
@@ -388,7 +388,7 @@ out_free:
        }
 }
 
-/* Item insertion is guarded by ip_io_sem, so the insertion path takes
+/* Item insertion is guarded by ip_io_mutex, so the insertion path takes
  * advantage of this by not rechecking for a duplicate insert during
  * the slow case. Additionally, if the cache needs to be bumped up to
  * a tree, the code will not recheck after acquiring the lock --
@@ -418,7 +418,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
             (unsigned long long) bh->b_blocknr);
 
        /* No need to recheck under spinlock - insertion is guarded by
-        * ip_io_sem */
+        * ip_io_mutex */
        spin_lock(&oi->ip_lock);
        if (ocfs2_insert_can_use_array(oi, ci)) {
                /* Fast case - it's an array and there's a free
@@ -440,7 +440,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
 
 /* Called against a newly allocated buffer. Most likely nobody should
  * be able to read this sort of metadata while it's still being
- * allocated, but this is careful to take ip_io_sem anyway. */
+ * allocated, but this is careful to take ip_io_mutex anyway. */
 void ocfs2_set_new_buffer_uptodate(struct inode *inode,
                                   struct buffer_head *bh)
 {
@@ -451,9 +451,9 @@ void ocfs2_set_new_buffer_uptodate(struct inode *inode,
 
        set_buffer_uptodate(bh);
 
-       down(&oi->ip_io_sem);
+       mutex_lock(&oi->ip_io_mutex);
        ocfs2_set_buffer_uptodate(inode, bh);
-       up(&oi->ip_io_sem);
+       mutex_unlock(&oi->ip_io_mutex);
 }
 
 /* Requires ip_lock. */
@@ -537,7 +537,7 @@ int __init init_ocfs2_uptodate_cache(void)
        return 0;
 }
 
-void __exit exit_ocfs2_uptodate_cache(void)
+void exit_ocfs2_uptodate_cache(void)
 {
        if (ocfs2_uptodate_cachep)
                kmem_cache_destroy(ocfs2_uptodate_cachep);
index e5aacdf4eabf2021d5ded5e3bd0b63dd8cfefa15..01cd32d26b06867c28f67326941ee4c52ab1f087 100644 (file)
@@ -27,7 +27,7 @@
 #define OCFS2_UPTODATE_H
 
 int __init init_ocfs2_uptodate_cache(void);
-void __exit exit_ocfs2_uptodate_cache(void);
+void exit_ocfs2_uptodate_cache(void);
 
 void ocfs2_metadata_cache_init(struct inode *inode);
 void ocfs2_metadata_cache_purge(struct inode *inode);
index 8f8014285a349c14f547c8e3d92d47cc9a6ff4b7..1d24fead51a6385d9e2ce69c9e7353ade88c039a 100644 (file)
@@ -548,7 +548,7 @@ static int show_stat(struct seq_file *p, void *v)
        }
        seq_printf(p, "intr %llu", (unsigned long long)sum);
 
-#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA)
+#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
        for (i = 0; i < NR_IRQS; i++)
                seq_printf(p, " %u", kstat_irqs(i));
 #endif
index a4ef91bb4f3b9afe61628d52a7bb3e08356b42da..b4199ec3ece460bd9818c419b7b9ed1a10fab06f 100644 (file)
@@ -35,7 +35,7 @@ static int v2_check_quota_file(struct super_block *sb, int type)
  
        size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
        if (size != sizeof(struct v2_disk_dqheader)) {
-               printk("quota_v2: failed read expected=%d got=%d\n",
+               printk("quota_v2: failed read expected=%zd got=%zd\n",
                        sizeof(struct v2_disk_dqheader), size);
                return 0;
        }
index a3ec238fd9e0347bef211170353137fa5250f949..e664ac16fad92e9320b94f98fa3e52c9df191fcf 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/reiserfs_fs.h>
 #include <asm/types.h>
-#include <asm/bug.h>
 
 #define DELTA 0x9E3779B9
 #define FULLROUNDS 10          /* 32 is overkill, 16 is strong crypto */
index 77891de0e02e7b0f470545b98fc1bb00e075e508..ef5e5414e7a83eb9b4295bbaba5464410b11e030 100644 (file)
@@ -1125,7 +1125,7 @@ static void handle_attrs(struct super_block *s)
                        REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
                }
        } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) {
-               REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS;
+               REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ATTRS);
        }
 }
 
index c0f02d36c60e539c108d4b51fb2ce94762d5ce82..bc60a3e14ef37c05d07f579e123154d9ad9358fc 100644 (file)
@@ -510,9 +510,9 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp,
 
        if (sig) {
                if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
-                   || __get_user(up, (sigset_t * __user *)sig)
+                   || __get_user(up, (sigset_t __user * __user *)sig)
                    || __get_user(sigsetsize,
-                               (size_t * __user)(sig+sizeof(void *))))
+                               (size_t __user *)(sig+sizeof(void *))))
                        return -EFAULT;
        }
 
index c177b92419c56680c50cc1e6eceed41366ff84de..30294218fa63abbac1c193a5245eb69ece61693a 100644 (file)
@@ -247,8 +247,9 @@ void generic_shutdown_super(struct super_block *sb)
 
                /* Forget any remaining inodes */
                if (invalidate_inodes(sb)) {
-                       printk("VFS: Busy inodes after unmount. "
-                          "Self-destruct in 5 seconds.  Have a nice day...\n");
+                       printk("VFS: Busy inodes after unmount of %s. "
+                          "Self-destruct in 5 seconds.  Have a nice day...\n",
+                          sb->s_id);
                }
 
                unlock_kernel();
index 4fae57d9d1151008fa690a889c98ee4e0c737ecd..201049ac8a96f94851213604d2017043b1dee155 100644 (file)
@@ -579,10 +579,9 @@ static void udf_table_free_blocks(struct super_block * sb,
                        {
                                loffset = nextoffset;
                                aed->lengthAllocDescs = cpu_to_le32(adsize);
-                               if (obh)
-                                       sptr = UDF_I_DATA(inode) + nextoffset -  udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize;
-                               else
-                                       sptr = obh->b_data + nextoffset - adsize;
+                               sptr = UDF_I_DATA(inode) + nextoffset -
+                                       udf_file_entry_alloc_offset(inode) +
+                                       UDF_I_LENEATTR(inode) - adsize;
                                dptr = nbh->b_data + sizeof(struct allocExtDesc);
                                memcpy(dptr, sptr, adsize);
                                nextoffset = sizeof(struct allocExtDesc) + adsize;
index ca732e79c48bb60af77c28dfe8f0a4f75b9f64b1..ab9a7629d23e82c094e8b7db9606a57af007e294 100644 (file)
@@ -296,7 +296,7 @@ static struct dentry *
 udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = NULL;
-       struct fileIdentDesc cfi, *fi;
+       struct fileIdentDesc cfi;
        struct udf_fileident_bh fibh;
 
        if (dentry->d_name.len > UDF_NAME_LEN-2)
@@ -318,7 +318,7 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        else
 #endif /* UDF_RECOVERY */
 
-       if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi)))
+       if (udf_find_entry(dir, dentry, &fibh, &cfi))
        {
                if (fibh.sbh != fibh.ebh)
                        udf_release_data(fibh.ebh);
index e0c04e36a0518a42548d4b4aad82743f7572bb82..3c3f62ce2ad9a926e71b5e52bb76f6b763009425 100644 (file)
@@ -376,7 +376,7 @@ out:
  * This function gets the block which contains the fragment.
  */
 
-static int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
+int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
 {
        struct super_block * sb = inode->i_sb;
        struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi;
index d4aacee593ffbb9a2daec491518ff9c4bf3dfec0..e9055ef7f5ac97dbe33791e0d5f9c227a06985f9 100644 (file)
@@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
 /*
  * Read on-disk structures associated with cylinder groups
  */
-static int ufs_read_cylinder_structures (struct super_block *sb) {
+static int ufs_read_cylinder_structures (struct super_block *sb)
+{
        struct ufs_sb_info * sbi = UFS_SB(sb);
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block *usb;
@@ -415,6 +416,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
        base = space = kmalloc(size, GFP_KERNEL);
        if (!base)
                goto failed; 
+       sbi->s_csp = (struct ufs_csum *)space;
        for (i = 0; i < blks; i += uspi->s_fpb) {
                size = uspi->s_bsize;
                if (i + uspi->s_fpb > blks)
@@ -430,7 +432,6 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
                        goto failed;
 
                ubh_ubhcpymem (space, ubh, size);
-               sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space;
 
                space += size;
                ubh_brelse (ubh);
@@ -486,7 +487,8 @@ failed:
  * Put on-disk structures associated with cylinder groups and 
  * write them back to disk
  */
-static void ufs_put_cylinder_structures (struct super_block *sb) {
+static void ufs_put_cylinder_structures (struct super_block *sb)
+{
        struct ufs_sb_info * sbi = UFS_SB(sb);
        struct ufs_sb_private_info * uspi;
        struct ufs_buffer_head * ubh;
@@ -499,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) {
 
        size = uspi->s_cssize;
        blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
-       base = space = (char*) sbi->s_csp[0];
+       base = space = (char*) sbi->s_csp;
        for (i = 0; i < blks; i += uspi->s_fpb) {
                size = uspi->s_bsize;
                if (i + uspi->s_fpb > blks)
index 61d2e35012a462e2cb6be0f9fc27bd10e20db0b1..02e86291ef8adfde874aac0e72b37fd2f51bad85 100644 (file)
  * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr>
  */
 
+/*
+ * Modified to avoid infinite loop on 2006 by
+ * Evgeniy Dushistov <dushistov@mail.ru>
+ */
+
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift)
 #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
 
-#define DATA_BUFFER_USED(bh) \
-       (atomic_read(&bh->b_count)>1 || buffer_locked(bh))
 
 static int ufs_trunc_direct (struct inode * inode)
 {
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
-       struct buffer_head * bh;
        __fs32 * p;
        unsigned frag1, frag2, frag3, frag4, block1, block2;
        unsigned frag_to_free, free_count;
-       unsigned i, j, tmp;
+       unsigned i, tmp;
        int retry;
        
        UFSD(("ENTER\n"))
@@ -117,15 +119,7 @@ static int ufs_trunc_direct (struct inode * inode)
                ufs_panic (sb, "ufs_trunc_direct", "internal error");
        frag1 = ufs_fragnum (frag1);
        frag2 = ufs_fragnum (frag2);
-       for (j = frag1; j < frag2; j++) {
-               bh = sb_find_get_block (sb, tmp + j);
-               if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
-                       retry = 1;
-                       brelse (bh);
-                       goto next1;
-               }
-               bforget (bh);
-       }
+
        inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift;
        mark_inode_dirty(inode);
        ufs_free_fragments (inode, tmp + frag1, frag2 - frag1);
@@ -140,15 +134,7 @@ next1:
                tmp = fs32_to_cpu(sb, *p);
                if (!tmp)
                        continue;
-               for (j = 0; j < uspi->s_fpb; j++) {
-                       bh = sb_find_get_block(sb, tmp + j);
-                       if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
-                               retry = 1;
-                               brelse (bh);
-                               goto next2;
-                       }
-                       bforget (bh);
-               }
+
                *p = 0;
                inode->i_blocks -= uspi->s_nspb;
                mark_inode_dirty(inode);
@@ -162,7 +148,6 @@ next1:
                        frag_to_free = tmp;
                        free_count = uspi->s_fpb;
                }
-next2:;
        }
        
        if (free_count > 0)
@@ -179,15 +164,7 @@ next2:;
        if (!tmp )
                ufs_panic(sb, "ufs_truncate_direct", "internal error");
        frag4 = ufs_fragnum (frag4);
-       for (j = 0; j < frag4; j++) {
-               bh = sb_find_get_block (sb, tmp + j);
-               if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
-                       retry = 1;
-                       brelse (bh);
-                       goto next1;
-               }
-               bforget (bh);
-       }
+
        *p = 0;
        inode->i_blocks -= frag4 << uspi->s_nspfshift;
        mark_inode_dirty(inode);
@@ -204,9 +181,8 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_buffer_head * ind_ubh;
-       struct buffer_head * bh;
        __fs32 * ind;
-       unsigned indirect_block, i, j, tmp;
+       unsigned indirect_block, i, tmp;
        unsigned frag_to_free, free_count;
        int retry;
 
@@ -238,15 +214,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
                tmp = fs32_to_cpu(sb, *ind);
                if (!tmp)
                        continue;
-               for (j = 0; j < uspi->s_fpb; j++) {
-                       bh = sb_find_get_block(sb, tmp + j);
-                       if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) {
-                               retry = 1;
-                               brelse (bh);
-                               goto next;
-                       }
-                       bforget (bh);
-               }       
+
                *ind = 0;
                ubh_mark_buffer_dirty(ind_ubh);
                if (free_count == 0) {
@@ -261,7 +229,6 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
                }
                inode->i_blocks -= uspi->s_nspb;
                mark_inode_dirty(inode);
-next:;
        }
 
        if (free_count > 0) {
@@ -430,9 +397,7 @@ void ufs_truncate (struct inode * inode)
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
-       struct buffer_head * bh;
-       unsigned offset;
-       int err, retry;
+       int retry;
        
        UFSD(("ENTER\n"))
        sb = inode->i_sb;
@@ -442,6 +407,9 @@ void ufs_truncate (struct inode * inode)
                return;
        if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
                return;
+
+       block_truncate_page(inode->i_mapping,   inode->i_size, ufs_getfrag_block);
+
        lock_kernel();
        while (1) {
                retry = ufs_trunc_direct(inode);
@@ -457,15 +425,7 @@ void ufs_truncate (struct inode * inode)
                blk_run_address_space(inode->i_mapping);
                yield();
        }
-       offset = inode->i_size & uspi->s_fshift;
-       if (offset) {
-               bh = ufs_bread (inode, inode->i_size >> uspi->s_fshift, 0, &err);
-               if (bh) {
-                       memset (bh->b_data + offset, 0, uspi->s_fsize - offset);
-                       mark_buffer_dirty (bh);
-                       brelse (bh);
-               }
-       }
+
        inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
        ufsi->i_lastfrag = DIRECT_FRAGMENT;
        unlock_kernel();
index 9892268e30050fdd4a21846160c74a708fe56545..8f2beec526cfb58257dbf77b258384ce2310970b 100644 (file)
@@ -747,10 +747,11 @@ xfs_convert_page(
                        struct backing_dev_info *bdi;
 
                        bdi = inode->i_mapping->backing_dev_info;
+                       wbc->nr_to_write--;
                        if (bdi_write_congested(bdi)) {
                                wbc->encountered_congestion = 1;
                                done = 1;
-                       } else if (--wbc->nr_to_write <= 0) {
+                       } else if (wbc->nr_to_write <= 0) {
                                done = 1;
                        }
                }
index eda7919b70a18814e82477828eeaa91794ccb8d6..d7f6f2d8ac8ec1c3b8f3185d3e18e958f8dc65a6 100644 (file)
@@ -673,6 +673,8 @@ linvfs_setattr(
        if (ia_valid & ATTR_ATIME) {
                vattr.va_mask |= XFS_AT_ATIME;
                vattr.va_atime = attr->ia_atime;
+               if (ia_valid & ATTR_ATIME_SET)
+                       inode->i_atime = attr->ia_atime;
        }
        if (ia_valid & ATTR_MTIME) {
                vattr.va_mask |= XFS_AT_MTIME;
index cc9c7e8cced5c2de6f88f3557de2bd6c4c3de385..f3b7b1a59c568d6950f7432ac467b361b2a02eaf 100644 (file)
@@ -572,7 +572,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-static inline unsigned long
+static __always_inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
        switch (size) {
index f5bcc9a1aed645b9a1703cafc5308bc2d8e668ec..b726acfcab14b5a522941097a975108d1903232d 100644 (file)
@@ -116,7 +116,11 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
                                        ->offset[((vaddr)&4095)>>2]
 #define __REG32(paddr)         __REGV32(io_p2v(paddr))
 
-extern void omap_map_common_io(void);
+extern void omap1_map_common_io(void);
+extern void omap1_init_common_hw(void);
+
+extern void omap2_map_common_io(void);
+extern void omap2_init_common_hw(void);
 
 #else
 
index 1c9de29cafef1b7684a1e5ea4b7a0236f7166fb1..a2330bf83695a8da6fac9febfbf6458bb45acb0e 100644 (file)
@@ -17,6 +17,7 @@
  *  14-Sep-2004 BJD  Added misccr and getpin to gpio
  *  01-Oct-2004 BJD  Added the new gpio functions
  *  16-Oct-2004 BJD  Removed the clock variables
+ *  15-Jan-2006 LCVR Added s3c2400_gpio_getirq()
 */
 
 #ifndef __ASM_ARCH_HARDWARE_H
@@ -55,6 +56,12 @@ extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
 
 extern int s3c2410_gpio_getirq(unsigned int pin);
 
+#ifdef CONFIG_CPU_S3C2400
+
+extern int s3c2400_gpio_getirq(unsigned int pin);
+
+#endif /* CONFIG_CPU_S3C2400 */
+
 /* s3c2410_gpio_irqfilter
  *
  * set the irq filtering on the given pin
index 7f1be48ad67e033d5de562d4ed8670fa0d3cfdf8..9697f93afe742a560eabf1bf6678fc332b8d6bee 100644 (file)
@@ -22,6 +22,7 @@
  *    28-Mar-2005    LCVR    Fixed definition of GPB10
  *    26-Oct-2005    BJD     Added generic configuration types
  *    27-Nov-2005    LCVR    Added definitions to S3C2400 registers
+ *    15-Jan-2006    LCVR    Written S3C24XX_GPIO_BASE() macro
 */
 
 
 #define S3C2410_GPIO_BANKG   (32*6)
 #define S3C2410_GPIO_BANKH   (32*7)
 
+#ifdef CONFIG_CPU_S3C2400
+#define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
+#define S3C24XX_MISCCR        S3C2400_MISCCR
+#else
+#define S3C24XX_GPIO_BASE(x)  S3C2410_GPIO_BASE(x)
+#define S3C24XX_MISCCR        S3C2410_MISCCR
+#endif /* CONFIG_CPU_S3C2400 */
+
+
+/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
+
+#define S3C2400_BANKNUM(pin)     (((pin) & ~31) / 32)
+#define S3C2400_BASEA2B(pin)     ((((pin) & ~31) >> 2))
+#define S3C2400_BASEC2H(pin)     ((S3C2400_BANKNUM(pin) * 10) + \
+                                 (2 * (S3C2400_BANKNUM(pin)-2)))
+
+#define S3C2400_GPIO_BASE(pin)   (pin < S3C2410_GPIO_BANKC ? \
+                                 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
+                                 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
+
+
 #define S3C2410_GPIO_BASE(pin)   ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
 #define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
 
index d4256d5f3a7c1f84553fec367ccdf47eff71fb6f..747bdd31a74b9bf1af4c5df957ce70812bc1802b 100644 (file)
@@ -77,7 +77,7 @@ ip_fast_csum(unsigned char * iph, unsigned int ihl)
        mov     %0, %0, lsr #16"
        : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
        : "1" (iph), "2" (ihl)
-       : "cc");
+       : "cc", "memory");
        return sum;
 }
 
index 6caa59f1f5954853ff597cbc2c79412e0158823f..cb29d84e690ddd9a25109731389c34954f49a39c 100644 (file)
  * simply bail out immediately through the slow path where the lock will be
  * reattempted until it succeeds.
  */
-#define __mutex_fastpath_lock(count, fail_fn)                          \
-do {                                                                   \
-       int __ex_flag, __res;                                           \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);           \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%2]        \n"                             \
-               "sub    %0, %0, #1      \n"                             \
-               "strex  %1, %0, [%2]    \n"                             \
-                                                                       \
-               : "=&r" (__res), "=&r" (__ex_flag)                      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       if (unlikely(__res || __ex_flag))                               \
-               fail_fn(count);                                         \
-} while (0)
-
-#define __mutex_fastpath_lock_retval(count, fail_fn)                   \
-({                                                                     \
-       int __ex_flag, __res;                                           \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall int (*)(atomic_t *), fail_fn);            \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%2]        \n"                             \
-               "sub    %0, %0, #1      \n"                             \
-               "strex  %1, %0, [%2]    \n"                             \
-                                                                       \
-               : "=&r" (__res), "=&r" (__ex_flag)                      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       __res |= __ex_flag;                                             \
-       if (unlikely(__res != 0))                                       \
-               __res = fail_fn(count);                                 \
-       __res;                                                          \
-})
+static inline void
+__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res;
+
+       __asm__ (
+
+               "ldrex  %0, [%2]        \n\t"
+               "sub    %0, %0, #1      \n\t"
+               "strex  %1, %0, [%2]    "
+
+               : "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __res |= __ex_flag;
+       if (unlikely(__res != 0))
+               fail_fn(count);
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res;
+
+       __asm__ (
+
+               "ldrex  %0, [%2]        \n\t"
+               "sub    %0, %0, #1      \n\t"
+               "strex  %1, %0, [%2]    "
+
+               : "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __res |= __ex_flag;
+       if (unlikely(__res != 0))
+               __res = fail_fn(count);
+       return __res;
+}
 
 /*
  * Same trick is used for the unlock fast path. However the original value,
  * rather than the result, is used to test for success in order to have
  * better generated assembly.
  */
-#define __mutex_fastpath_unlock(count, fail_fn)                                \
-do {                                                                   \
-       int __ex_flag, __res, __orig;                                   \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);           \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%3]        \n"                             \
-               "add    %1, %0, #1      \n"                             \
-               "strex  %2, %1, [%3]    \n"                             \
-                                                                       \
-               : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       if (unlikely(__orig || __ex_flag))                              \
-               fail_fn(count);                                         \
-} while (0)
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res, __orig;
+
+       __asm__ (
+
+               "ldrex  %0, [%3]        \n\t"
+               "add    %1, %0, #1      \n\t"
+               "strex  %2, %1, [%3]    "
+
+               : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __orig |= __ex_flag;
+       if (unlikely(__orig != 0))
+               fail_fn(count);
+}
 
 /*
  * If the unlock was done on a contended lock, or if the unlock simply fails
@@ -110,12 +109,12 @@ __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
 
        __asm__ (
 
-               "1: ldrex       %0, [%3]        \n"
-               "subs           %1, %0, #1      \n"
-               "strexeq        %2, %1, [%3]    \n"
-               "movlt          %0, #0          \n"
-               "cmpeq          %2, #0          \n"
-               "bgt            1b              \n"
+               "1: ldrex       %0, [%3]        \n\t"
+               "subs           %1, %0, #1      \n\t"
+               "strexeq        %2, %1, [%3]    \n\t"
+               "movlt          %0, #0          \n\t"
+               "cmpeq          %2, #0          \n\t"
+               "bgt            1b              "
 
                : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
                : "r" (&count->counter)
index d3eb0f1e42085c7911aaa6f5d4303d38a78cd022..b7fef1572dc0f52d34ad9efa7eae87faf3ac684a 100644 (file)
@@ -290,7 +290,7 @@ static inline int find_next_zero_bit (const unsigned long * addr, int size, int
        tmp = *p;
        
  found_first:
-       tmp |= ~0UL >> size;
+       tmp |= ~0UL << size;
  found_middle:
        return result + ffz(tmp);
 }
index 02be7b3a8a83fd3fcd652472a4b3848c45cbd255..f686b519878ed34ed5f557d1e40014f869116e53 100644 (file)
@@ -209,7 +209,7 @@ static inline int find_next_zero_bit(const void *addr, int size, int offset)
        tmp = *p;
 
 found_first:
-       tmp |= ~0UL >> size;
+       tmp |= ~0UL << size;
 found_middle:
        return result + ffz(tmp);
 }
index c0411ec9d651785200e64d45734983db17d2fcbc..ff7c2b7215946a37fc8fc11eb9c2f29750d1f963 100644 (file)
@@ -227,7 +227,7 @@ static __inline__ int find_next_zero_bit (const unsigned long * addr, int size,
        tmp = *p;
 
 found_first:
-       tmp |= ~0UL >> size;
+       tmp |= ~0UL << size;
 found_middle:
        return result + ffz(tmp);
 }
index 36a92ed6a9d0d7a916c60f33313bec9d4fb0c494..399145a247f290580c53576a81c0f7ba94ee61e8 100644 (file)
@@ -507,7 +507,7 @@ struct alt_instr {
 #define smp_rmb()      rmb()
 #define smp_wmb()      wmb()
 #define smp_read_barrier_depends()     read_barrier_depends()
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 #else
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
index d7e19eb344b7ab4f83c6611ec3afb675edf86d13..af503a122b23592eb6e82836fffd30ead57de91a 100644 (file)
 #ifndef _ASM_I386_TOPOLOGY_H
 #define _ASM_I386_TOPOLOGY_H
 
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu)                              \
+       (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu])
+#define topology_core_id(cpu)                                          \
+       (cpu_core_id[cpu] == BAD_APICID ? 0 : cpu_core_id[cpu])
+#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu)          (cpu_sibling_map[cpu])
+#endif
+
 #ifdef CONFIG_NUMA
 
 #include <asm/mpspec.h>
index 597496ed2aeea58efd01ee6f62b98cac6183747d..cf6f2cd9c514e223aed23254828f256ec6f2203e 100644 (file)
 #define __NR_faccessat         307
 #define __NR_pselect6          308
 #define __NR_ppoll             309
+#define __NR_unshare           310
 
-#define NR_syscalls 310
+#define NR_syscalls 311
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
index e62b95301d513321befd401291a90d6c867f4325..93f45c5f189f0649bc0df0b62fcc6f10bc270a50 100644 (file)
 
 #include <linux/irq.h>
 
-#ifndef MAX_HWIFS
-# ifdef CONFIG_PCI
-#define MAX_HWIFS      10
-# else
-#define MAX_HWIFS      6
-# endif
-#endif
-
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
 static inline int ide_default_irq(unsigned long base)
index 09b99029ac1ac82ad3afe3a5063fd935ee4e6356..23c8e1be1911873ec0efd3441f6216eff536e401 100644 (file)
@@ -559,6 +559,23 @@ ia64_eoi (void)
 
 #define cpu_relax()    ia64_hint(ia64_hint_pause)
 
+static inline int
+ia64_get_irr(unsigned int vector)
+{
+       unsigned int reg = vector / 64;
+       unsigned int bit = vector % 64;
+       u64 irr;
+
+       switch (reg) {
+       case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break;
+       case 1: irr = ia64_getreg(_IA64_REG_CR_IRR1); break;
+       case 2: irr = ia64_getreg(_IA64_REG_CR_IRR2); break;
+       case 3: irr = ia64_getreg(_IA64_REG_CR_IRR3); break;
+       }
+
+       return test_bit(bit, &irr);
+}
+
 static inline void
 ia64_set_lrr0 (unsigned long val)
 {
index 313cad0628d07a5555d430d17ab6236f52fa59cb..0b210abbe0033ce06a1f7c1db28e8bcf0395ef6e 100644 (file)
@@ -658,15 +658,7 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
        return isrv.status;
 }
 
-/* Flush all the processor and platform level instruction and/or data caches */
-static inline s64
-ia64_sal_cache_flush (u64 cache_type)
-{
-       struct ia64_sal_retval isrv;
-       SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
-       return isrv.status;
-}
-
+extern s64 ia64_sal_cache_flush (u64 cache_type);
 
 /* Initialize all the processor and platform level instruction and data caches */
 static inline s64
index f50da3d91d07f6844b05bbe42b37c20e940bb1e4..01e5b41032357a1c615c8326d7c7a7ea12df5882 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
 #define BTE_LNSTAT_STORE(_bte, _x)                                     \
                        HUB_S(_bte->bte_base_addr, (_x))
 #define BTE_SRC_STORE(_bte, _x)                                                \
-                       HUB_S(_bte->bte_source_addr, (_x))
+({                                                                     \
+               u64 __addr = ((_x) & ~AS_MASK);                         \
+               if (is_shub2())                                         \
+                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
+               HUB_S(_bte->bte_source_addr, __addr);                   \
+})
 #define BTE_DEST_STORE(_bte, _x)                                       \
-                       HUB_S(_bte->bte_destination_addr, (_x))
+({                                                                     \
+               u64 __addr = ((_x) & ~AS_MASK);                         \
+               if (is_shub2())                                         \
+                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
+               HUB_S(_bte->bte_destination_addr, __addr);              \
+})
 #define BTE_CTRL_STORE(_bte, _x)                                       \
                        HUB_S(_bte->bte_control_addr, (_x))
 #define BTE_NOTIF_STORE(_bte, _x)                                      \
-                       HUB_S(_bte->bte_notify_addr, (_x))
+({                                                                     \
+               u64 __addr = ia64_tpa((_x) & ~AS_MASK);                 \
+               if (is_shub2())                                         \
+                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
+               HUB_S(_bte->bte_notify_addr, __addr);                   \
+})
 
 #define BTE_START_TRANSFER(_bte, _len, _mode)                          \
        is_shub2() ? BTE_CTRL_STORE(_bte, IBLS_BUSY | (_mode << 24) | _len) \
index a3431372c6e7b9843271ae53f4a7e7233b1cfa9b..60a51a406eec5f19019d99ec01ff87f9461ef83d 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_INTR_H
 
 #include <linux/rcupdate.h>
 
-#define SGI_UART_VECTOR                (0xe9)
+#define SGI_UART_VECTOR                0xe9
 
 /* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */
-#define SGI_XPC_ACTIVATE                (0x30)
-#define SGI_II_ERROR                    (0x31)
-#define SGI_XBOW_ERROR                  (0x32)
-#define SGI_PCIASIC_ERROR               (0x33)
-#define SGI_ACPI_SCI_INT                (0x34)
-#define SGI_TIOCA_ERROR                 (0x35)
-#define SGI_TIO_ERROR                   (0x36)
-#define SGI_TIOCX_ERROR                 (0x37)
-#define SGI_MMTIMER_VECTOR              (0x38)
-#define SGI_XPC_NOTIFY                  (0xe7)
-
-#define IA64_SN2_FIRST_DEVICE_VECTOR    (0x3c)
-#define IA64_SN2_LAST_DEVICE_VECTOR     (0xe6)
-
-#define SN2_IRQ_RESERVED        (0x1)
-#define SN2_IRQ_CONNECTED       (0x2)
-#define SN2_IRQ_SHARED          (0x4)
+#define SGI_XPC_ACTIVATE       0x30
+#define SGI_II_ERROR           0x31
+#define SGI_XBOW_ERROR         0x32
+#define SGI_PCIASIC_ERROR      0x33
+#define SGI_ACPI_SCI_INT       0x34
+#define SGI_TIOCA_ERROR                0x35
+#define SGI_TIO_ERROR          0x36
+#define SGI_TIOCX_ERROR                0x37
+#define SGI_MMTIMER_VECTOR     0x38
+#define SGI_XPC_NOTIFY         0xe7
+
+#define IA64_SN2_FIRST_DEVICE_VECTOR   0x3c
+#define IA64_SN2_LAST_DEVICE_VECTOR    0xe6
+
+#define SN2_IRQ_RESERVED       0x1
+#define SN2_IRQ_CONNECTED      0x2
+#define SN2_IRQ_SHARED         0x4
 
 // The SN PROM irq struct
 struct sn_irq_info {
index 80c5a234e2599c90006de76e27b47f49b6197ade..06253871562303b223a9cbfef4ba017ed2f44f32 100644 (file)
@@ -249,32 +249,7 @@ extern void ia64_load_extra (struct task_struct *task);
 # define switch_to(prev,next,last)     __switch_to(prev, next, last)
 #endif
 
-/*
- * On IA-64, we don't want to hold the runqueue's lock during the low-level context-switch,
- * because that could cause a deadlock.  Here is an example by Erich Focht:
- *
- * Example:
- * CPU#0:
- * schedule()
- *    -> spin_lock_irq(&rq->lock)
- *    -> context_switch()
- *       -> wrap_mmu_context()
- *          -> read_lock(&tasklist_lock)
- *
- * CPU#1:
- * sys_wait4() or release_task() or forget_original_parent()
- *    -> write_lock(&tasklist_lock)
- *    -> do_notify_parent()
- *       -> wake_up_parent()
- *          -> try_to_wake_up()
- *             -> spin_lock_irq(&parent_rq->lock)
- *
- * If the parent's rq happens to be on CPU#0, we'll wait for the rq->lock
- * of that CPU which will not be released, because there we wait for the
- * tasklist_lock to become available.
- */
 #define __ARCH_WANT_UNLOCKED_CTXSW
-
 #define ARCH_HAS_PREFETCH_SWITCH_STACK
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
index 412ef8e493a8cc2644ad79294f9907ddd8e4566c..3ee19dfa46dfde66f5723030f5a0e3a9e114bca6 100644 (file)
@@ -102,6 +102,13 @@ void build_cpu_to_node_map(void);
 
 #endif /* CONFIG_NUMA */
 
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu)      (cpu_data(cpu)->socket_id)
+#define topology_core_id(cpu)                  (cpu_data(cpu)->core_id)
+#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu)          (cpu_sibling_map[cpu])
+#endif
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_IA64_TOPOLOGY_H */
index e8659e739a648e57f52d28d4eb15fa4087b84047..476180f4cba2b6518479b74ebbbbb1647a7f7376 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <asm/irq.h>
 
 typedef struct {
        unsigned int __softirq_pending;
index 2e7e651c3e3fa754d52bfa88198dd3e5fcca981f..1ce0518ace2e65fc50c065918ff7351871bed031 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005 by Ralf Baechle
+ * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2005 MIPS Technologies, Inc.
  */
 #ifndef _ASM_ABI_H
@@ -13,7 +13,7 @@
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
+       void (* const do_signal)(struct pt_regs *regs);
        int (* const setup_frame)(struct k_sigaction * ka,
                                  struct pt_regs *regs, int signr,
                                  sigset_t *set);
index 3b0c8aaf6e8bfaf62ec78fd854fe790a7af3f907..8e802059fe67d5a5016795d3d7ea1d00e127bf1f 100644 (file)
@@ -644,20 +644,26 @@ static inline unsigned long ffz(unsigned long word)
 }
 
 /*
- * flz - find last zero in word.
+ * fls - find last bit set.
  * @word: The word to search
  *
- * Returns 0..SZLONG-1
- * Undefined if no zero exists, so code should check against ~0UL first.
+ * Returns 1..SZLONG
+ * Returns 0 if no bit exists
  */
-static inline unsigned long flz(unsigned long word)
+static inline unsigned long fls(unsigned long word)
 {
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       return __ilog2(~word);
-#else
 #ifdef CONFIG_32BIT
-       int r = 31, s;
-       word = ~word;
+#ifdef CONFIG_CPU_MIPS32
+       __asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
+
+       return 32 - word;
+#else
+       {
+       int r = 32, s;
+
+       if (word == 0)
+               return 0;
+
        s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
        s = 8;  if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
        s = 4;  if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
@@ -665,10 +671,23 @@ static inline unsigned long flz(unsigned long word)
        s = 1;  if ((word & 0x80000000)) s = 0; r -= s;
 
        return r;
+       }
 #endif
+#endif /* CONFIG_32BIT */
+
 #ifdef CONFIG_64BIT
-       int r = 63, s;
-       word = ~word;
+#ifdef CONFIG_CPU_MIPS64
+
+       __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
+
+       return 64 - word;
+#else
+       {
+       int r = 64, s;
+
+       if (word == 0)
+               return 0;
+
        s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
        s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
        s = 8;  if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
@@ -677,24 +696,11 @@ static inline unsigned long flz(unsigned long word)
        s = 1;  if ((word & 0x8000000000000000UL)) s = 0; r -= s;
 
        return r;
+       }
 #endif
-#endif
+#endif /* CONFIG_64BIT */
 }
 
-/*
- * fls - find last bit set.
- * @word: The word to search
- *
- * Returns 1..SZLONG
- * Returns 0 if no bit exists
- */
-static inline unsigned long fls(unsigned long word)
-{
-       if (word == 0)
-               return 0;
-
-       return flz(~word) + 1;
-}
 #define fls64(x)   generic_fls64(x)
 
 /*
index d1fe9e5c62e42918410ed37cbd107f56d99bc9bd..584f8128fffdb580f9973a72590c09c48c59c0cc 100644 (file)
@@ -8,10 +8,39 @@
 #ifndef _ASM_BYTEORDER_H
 #define _ASM_BYTEORDER_H
 
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include <asm/types.h>
 
 #ifdef __GNUC__
 
+#ifdef CONFIG_CPU_MIPSR2
+
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+{
+       __asm__(
+       "       wsbh    %0, %1                  \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+#define __arch__swab16(x)      ___arch__swab16(x)
+
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+       __asm__(
+       "       wsbh    %0, %1                  \n"
+       "       rotr    %0, %0, 16              \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+#define __arch__swab32(x)      ___arch__swab32(x)
+
+#endif /* CONFIG_CPU_MIPSR2 */
+
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __BYTEORDER_HAS_U64__
 #  define __SWAB_64_THRU_32__
index a18ba2edc0b68c9bda4da3a6531387dfcfb7d789..aeae9fabf4a9be581937ce767a2eb4af1c6c3979 100644 (file)
@@ -49,8 +49,7 @@ static inline void flush_dcache_page(struct page *page)
 
 extern void (*flush_icache_page)(struct vm_area_struct *vma,
        struct page *page);
-extern void (*flush_icache_range)(unsigned long __user start,
-       unsigned long __user end);
+extern void (*flush_icache_range)(unsigned long start, unsigned long end);
 #define flush_cache_vmap(start, end)           flush_cache_all()
 #define flush_cache_vunmap(start, end)         flush_cache_all()
 
diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/cobalt/cobalt.h
deleted file mode 100644 (file)
index 78e1df2..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Lowlevel hardware stuff for the MIPS based Cobalt microservers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1997 Cobalt Microserver
- * Copyright (C) 1997, 2003 Ralf Baechle
- * Copyright (C) 2001, 2002, 2003 Liam Davies (ldavies@agile.tv)
- */
-#ifndef __ASM_COBALT_H
-#define __ASM_COBALT_H
-
-/*
- * i8259 legacy interrupts used on Cobalt:
- *
- *     8  - RTC
- *     9  - PCI
- *    14  - IDE0
- *    15  - IDE1
- */
-#define COBALT_QUBE_SLOT_IRQ   9
-
-/*
- * CPU IRQs  are 16 ... 23
- */
-#define COBALT_CPU_IRQ         16
-
-#define COBALT_GALILEO_IRQ     (COBALT_CPU_IRQ + 2)
-#define COBALT_SCC_IRQ          (COBALT_CPU_IRQ + 3)   /* pre-production has 85C30 */
-#define COBALT_RAQ_SCSI_IRQ    (COBALT_CPU_IRQ + 3)
-#define COBALT_ETH0_IRQ                (COBALT_CPU_IRQ + 3)
-#define COBALT_QUBE1_ETH0_IRQ  (COBALT_CPU_IRQ + 4)
-#define COBALT_ETH1_IRQ                (COBALT_CPU_IRQ + 4)
-#define COBALT_SERIAL_IRQ      (COBALT_CPU_IRQ + 5)
-#define COBALT_SCSI_IRQ         (COBALT_CPU_IRQ + 5)
-#define COBALT_VIA_IRQ         (COBALT_CPU_IRQ + 6)    /* Chained to VIA ISA bridge */
-
-/*
- * PCI configuration space manifest constants.  These are wired into
- * the board layout according to the PCI spec to enable the software
- * to probe the hardware configuration space in a well defined manner.
- *
- * The PCI_DEVSHFT() macro transforms these values into numbers
- * suitable for passing as the dev parameter to the various
- * pcibios_read/write_config routines.
- */
-#define COBALT_PCICONF_CPU      0x06
-#define COBALT_PCICONF_ETH0     0x07
-#define COBALT_PCICONF_RAQSCSI  0x08
-#define COBALT_PCICONF_VIA      0x09
-#define COBALT_PCICONF_PCISLOT  0x0A
-#define COBALT_PCICONF_ETH1     0x0C
-
-
-/*
- * The Cobalt board id information.  The boards have an ID number wired
- * into the VIA that is available in the high nibble of register 94.
- * This register is available in the VIA configuration space through the
- * interface routines qube_pcibios_read/write_config. See cobalt/pci.c
- */
-#define VIA_COBALT_BRD_ID_REG  0x94
-#define VIA_COBALT_BRD_REG_to_ID(reg)  ((unsigned char) (reg) >> 4)
-#define COBALT_BRD_ID_QUBE1    0x3
-#define COBALT_BRD_ID_RAQ1     0x4
-#define COBALT_BRD_ID_QUBE2    0x5
-#define COBALT_BRD_ID_RAQ2     0x6
-
-/*
- * Galileo chipset access macros for the Cobalt. The base address for
- * the GT64111 chip is 0x14000000
- *
- * Most of this really should go into a separate GT64111 header file.
- */
-#define GT64111_IO_BASE                0x10000000UL
-#define GT64111_IO_END         0x11ffffffUL
-#define GT64111_MEM_BASE       0x12000000UL
-#define GT64111_MEM_END                0x13ffffffUL
-#define GT64111_BASE           0x14000000UL
-#define GALILEO_REG(ofs)       CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs))
-
-#define GALILEO_INL(port)      (*(volatile unsigned int *) GALILEO_REG(port))
-#define GALILEO_OUTL(val, port)                                                \
-do {                                                                   \
-       *(volatile unsigned int *) GALILEO_REG(port) = (val);           \
-} while (0)
-
-#define GALILEO_INTR_T0EXP     (1 << 8)
-#define GALILEO_INTR_RETRY_CTR (1 << 20)
-
-#define GALILEO_ENTC0          0x01
-#define GALILEO_SELTC0         0x02
-
-#define PCI_CFG_SET(devfn,where)                                       \
-       GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) |           \
-               (PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS)
-
-#define COBALT_LED_PORT                (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
-# define COBALT_LED_BAR_LEFT   (1 << 0)        /* Qube */
-# define COBALT_LED_BAR_RIGHT  (1 << 1)        /* Qube */
-# define COBALT_LED_WEB                (1 << 2)        /* RaQ */
-# define COBALT_LED_POWER_OFF  (1 << 3)        /* RaQ */
-# define COBALT_LED_RESET      0x0f
-
-#define COBALT_KEY_PORT                ((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
-# define COBALT_KEY_CLEAR      (1 << 1)
-# define COBALT_KEY_LEFT       (1 << 2)
-# define COBALT_KEY_UP         (1 << 3)
-# define COBALT_KEY_DOWN       (1 << 4)
-# define COBALT_KEY_RIGHT      (1 << 5)
-# define COBALT_KEY_ENTER      (1 << 6)
-# define COBALT_KEY_SELECT     (1 << 7)
-# define COBALT_KEY_MASK       0xfe
-
-#endif /* __ASM_COBALT_H */
diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/cobalt/mach-gt64120.h
deleted file mode 100644 (file)
index 587fc43..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* there's something here ... in the dark */
index 2fc90632f88cfeaab2e8fbaea794a961019a3a6f..6111a0ce58c4cf4bb4b1db0b5aa6fb064fc3d413 100644 (file)
 
 __asm__(
        "       .macro  _ssnop                                  \n\t"
-       "       sll     $0, $2, 1                               \n\t"
+       "       sll     $0, $0, 1                               \n\t"
        "       .endm                                           \n\t"
        "                                                       \n\t"
        "       .macro  _ehb                                    \n\t"
index abdf54ee64cf306d35b0dd32702c5fed061d4f58..774348734fa0b38a8fbe916972a966a59302be17 100644 (file)
@@ -47,6 +47,17 @@ static inline void local_irq_enable(void)
  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  * no nops at all.
  */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
 __asm__ (
        "       .macro  local_irq_disable\n"
        "       .set    push                                            \n"
@@ -55,8 +66,8 @@ __asm__ (
        "       di                                                      \n"
 #else
        "       mfc0    $1,$12                                          \n"
-       "       ori     $1,1                                            \n"
-       "       xori    $1,1                                            \n"
+       "       ori     $1,0x1f                                         \n"
+       "       xori    $1,0x1f                                         \n"
        "       .set    noreorder                                       \n"
        "       mtc0    $1,$12                                          \n"
 #endif
@@ -96,8 +107,8 @@ __asm__ (
        "       andi    \\result, 1                                     \n"
 #else
        "       mfc0    \\result, $12                                   \n"
-       "       ori     $1, \\result, 1                                 \n"
-       "       xori    $1, 1                                           \n"
+       "       ori     $1, \\result, 0x1f                              \n"
+       "       xori    $1, 0x1f                                        \n"
        "       .set    noreorder                                       \n"
        "       mtc0    $1, $12                                         \n"
 #endif
@@ -114,6 +125,7 @@ __asm__ __volatile__(                                                       \
 
 __asm__ (
        "       .macro  local_irq_restore flags                         \n"
+       "       .set    push                                            \n"
        "       .set    noreorder                                       \n"
        "       .set    noat                                            \n"
 #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
@@ -135,14 +147,13 @@ __asm__ (
 #else
        "       mfc0    $1, $12                                         \n"
        "       andi    \\flags, 1                                      \n"
-       "       ori     $1, 1                                           \n"
-       "       xori    $1, 1                                           \n"
+       "       ori     $1, 0x1f                                        \n"
+       "       xori    $1, 0x1f                                        \n"
        "       or      \\flags, $1                                     \n"
        "       mtc0    \\flags, $12                                    \n"
 #endif
        "       irq_disable_hazard                                      \n"
-       "       .set    at                                              \n"
-       "       .set    reorder                                         \n"
+       "       .set    pop                                             \n"
        "       .endm                                                   \n");
 
 #define local_irq_restore(flags)                                       \
index d42685747e7d3f66d42bbd45d2d95ed718bfb1f9..5a4c8a54b8f43801755e43b9b8a7b92cb35fb79a 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
  * variations of functions: non-prefixed ones that preserve the value
  * and prefixed ones that preserve byte addresses.  The latters are
  * typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "mem_" prefix.
+ * string I/O functions), hence the "__mem_" prefix.
  */
 #if defined(CONFIG_SWAP_IO_SPACE)
 
 # define ioswabb(x)            (x)
-# define mem_ioswabb(x)                (x)
+# define __mem_ioswabb(x)      (x)
 # ifdef CONFIG_SGI_IP22
 /*
  * IP22 seems braindead enough to swap 16bits values in hardware, but
  * not 32bits.  Go figure... Can't tell without documentation.
  */
 #  define ioswabw(x)           (x)
-#  define mem_ioswabw(x)       le16_to_cpu(x)
+#  define __mem_ioswabw(x)     le16_to_cpu(x)
 # else
 #  define ioswabw(x)           le16_to_cpu(x)
-#  define mem_ioswabw(x)       (x)
+#  define __mem_ioswabw(x)     (x)
 # endif
 # define ioswabl(x)            le32_to_cpu(x)
-# define mem_ioswabl(x)                (x)
+# define __mem_ioswabl(x)      (x)
 # define ioswabq(x)            le64_to_cpu(x)
-# define mem_ioswabq(x)                (x)
+# define __mem_ioswabq(x)      (x)
 
 #else
 
 # define ioswabb(x)            (x)
-# define mem_ioswabb(x)                (x)
+# define __mem_ioswabb(x)      (x)
 # define ioswabw(x)            (x)
-# define mem_ioswabw(x)                cpu_to_le16(x)
+# define __mem_ioswabw(x)      cpu_to_le16(x)
 # define ioswabl(x)            (x)
-# define mem_ioswabl(x)                cpu_to_le32(x)
+# define __mem_ioswabl(x)      cpu_to_le32(x)
 # define ioswabq(x)            (x)
-# define mem_ioswabq(x)                cpu_to_le32(x)
+# define __mem_ioswabq(x)      cpu_to_le32(x)
 
 #endif
 
@@ -343,7 +342,7 @@ static inline void pfx##write##bwlq(type val,                               \
                BUG();                                                  \
 }                                                                      \
                                                                        \
-static inline type pfx##read##bwlq(volatile void __iomem *mem)         \
+static inline type pfx##read##bwlq(const volatile void __iomem *mem)   \
 {                                                                      \
        volatile type *__mem;                                           \
        type __val;                                                     \
@@ -418,7 +417,7 @@ __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
                                                                        \
 __BUILD_MEMORY_PFX(__raw_, bwlq, type)                                 \
 __BUILD_MEMORY_PFX(, bwlq, type)                                       \
-__BUILD_MEMORY_PFX(mem_, bwlq, type)                                   \
+__BUILD_MEMORY_PFX(__mem_, bwlq, type)                                 \
 
 BUILDIO_MEM(b, u8)
 BUILDIO_MEM(w, u16)
@@ -431,7 +430,7 @@ BUILDIO_MEM(q, u64)
 
 #define BUILDIO_IOPORT(bwlq, type)                                     \
        __BUILD_IOPORT_PFX(, bwlq, type)                                \
-       __BUILD_IOPORT_PFX(mem_, bwlq, type)
+       __BUILD_IOPORT_PFX(__mem_, bwlq, type)
 
 BUILDIO_IOPORT(b, u8)
 BUILDIO_IOPORT(w, u16)
@@ -465,7 +464,7 @@ static inline void writes##bwlq(volatile void __iomem *mem,         \
        const volatile type *__addr = addr;                             \
                                                                        \
        while (count--) {                                               \
-               mem_write##bwlq(*__addr, mem);                          \
+               __mem_write##bwlq(*__addr, mem);                        \
                __addr++;                                               \
        }                                                               \
 }                                                                      \
@@ -476,7 +475,7 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr,      \
        volatile type *__addr = addr;                                   \
                                                                        \
        while (count--) {                                               \
-               *__addr = mem_read##bwlq(mem);                          \
+               *__addr = __mem_read##bwlq(mem);                        \
                __addr++;                                               \
        }                                                               \
 }
@@ -489,7 +488,7 @@ static inline void outs##bwlq(unsigned long port, const void *addr, \
        const volatile type *__addr = addr;                             \
                                                                        \
        while (count--) {                                               \
-               mem_out##bwlq(*__addr, port);                           \
+               __mem_out##bwlq(*__addr, port);                         \
                __addr++;                                               \
        }                                                               \
 }                                                                      \
@@ -500,7 +499,7 @@ static inline void ins##bwlq(unsigned long port, void *addr,                \
        volatile type *__addr = addr;                                   \
                                                                        \
        while (count--) {                                               \
-               *__addr = mem_in##bwlq(port);                           \
+               *__addr = __mem_in##bwlq(port);                         \
                __addr++;                                               \
        }                                                               \
 }
index 8e1d7ed7d8e3c3d786e8d9d427b9a8848da4d2c9..4686e17c206cc166603c73b3f8d655ab5d7fcf78 100644 (file)
@@ -1198,7 +1198,11 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
 
 /* UARTS 0-3 */
 #define UART_BASE                 UART0_ADDR
+#ifdef CONFIG_SOC_AU1200
+#define UART_DEBUG_BASE           UART1_ADDR
+#else
 #define UART_DEBUG_BASE           UART3_ADDR
+#endif
 
 #define UART_RX                0       /* Receive buffer */
 #define UART_TX                4       /* Transmit buffer */
diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h
new file mode 100644 (file)
index 0000000..78e1df2
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Lowlevel hardware stuff for the MIPS based Cobalt microservers.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Cobalt Microserver
+ * Copyright (C) 1997, 2003 Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 Liam Davies (ldavies@agile.tv)
+ */
+#ifndef __ASM_COBALT_H
+#define __ASM_COBALT_H
+
+/*
+ * i8259 legacy interrupts used on Cobalt:
+ *
+ *     8  - RTC
+ *     9  - PCI
+ *    14  - IDE0
+ *    15  - IDE1
+ */
+#define COBALT_QUBE_SLOT_IRQ   9
+
+/*
+ * CPU IRQs  are 16 ... 23
+ */
+#define COBALT_CPU_IRQ         16
+
+#define COBALT_GALILEO_IRQ     (COBALT_CPU_IRQ + 2)
+#define COBALT_SCC_IRQ          (COBALT_CPU_IRQ + 3)   /* pre-production has 85C30 */
+#define COBALT_RAQ_SCSI_IRQ    (COBALT_CPU_IRQ + 3)
+#define COBALT_ETH0_IRQ                (COBALT_CPU_IRQ + 3)
+#define COBALT_QUBE1_ETH0_IRQ  (COBALT_CPU_IRQ + 4)
+#define COBALT_ETH1_IRQ                (COBALT_CPU_IRQ + 4)
+#define COBALT_SERIAL_IRQ      (COBALT_CPU_IRQ + 5)
+#define COBALT_SCSI_IRQ         (COBALT_CPU_IRQ + 5)
+#define COBALT_VIA_IRQ         (COBALT_CPU_IRQ + 6)    /* Chained to VIA ISA bridge */
+
+/*
+ * PCI configuration space manifest constants.  These are wired into
+ * the board layout according to the PCI spec to enable the software
+ * to probe the hardware configuration space in a well defined manner.
+ *
+ * The PCI_DEVSHFT() macro transforms these values into numbers
+ * suitable for passing as the dev parameter to the various
+ * pcibios_read/write_config routines.
+ */
+#define COBALT_PCICONF_CPU      0x06
+#define COBALT_PCICONF_ETH0     0x07
+#define COBALT_PCICONF_RAQSCSI  0x08
+#define COBALT_PCICONF_VIA      0x09
+#define COBALT_PCICONF_PCISLOT  0x0A
+#define COBALT_PCICONF_ETH1     0x0C
+
+
+/*
+ * The Cobalt board id information.  The boards have an ID number wired
+ * into the VIA that is available in the high nibble of register 94.
+ * This register is available in the VIA configuration space through the
+ * interface routines qube_pcibios_read/write_config. See cobalt/pci.c
+ */
+#define VIA_COBALT_BRD_ID_REG  0x94
+#define VIA_COBALT_BRD_REG_to_ID(reg)  ((unsigned char) (reg) >> 4)
+#define COBALT_BRD_ID_QUBE1    0x3
+#define COBALT_BRD_ID_RAQ1     0x4
+#define COBALT_BRD_ID_QUBE2    0x5
+#define COBALT_BRD_ID_RAQ2     0x6
+
+/*
+ * Galileo chipset access macros for the Cobalt. The base address for
+ * the GT64111 chip is 0x14000000
+ *
+ * Most of this really should go into a separate GT64111 header file.
+ */
+#define GT64111_IO_BASE                0x10000000UL
+#define GT64111_IO_END         0x11ffffffUL
+#define GT64111_MEM_BASE       0x12000000UL
+#define GT64111_MEM_END                0x13ffffffUL
+#define GT64111_BASE           0x14000000UL
+#define GALILEO_REG(ofs)       CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs))
+
+#define GALILEO_INL(port)      (*(volatile unsigned int *) GALILEO_REG(port))
+#define GALILEO_OUTL(val, port)                                                \
+do {                                                                   \
+       *(volatile unsigned int *) GALILEO_REG(port) = (val);           \
+} while (0)
+
+#define GALILEO_INTR_T0EXP     (1 << 8)
+#define GALILEO_INTR_RETRY_CTR (1 << 20)
+
+#define GALILEO_ENTC0          0x01
+#define GALILEO_SELTC0         0x02
+
+#define PCI_CFG_SET(devfn,where)                                       \
+       GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) |           \
+               (PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS)
+
+#define COBALT_LED_PORT                (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
+# define COBALT_LED_BAR_LEFT   (1 << 0)        /* Qube */
+# define COBALT_LED_BAR_RIGHT  (1 << 1)        /* Qube */
+# define COBALT_LED_WEB                (1 << 2)        /* RaQ */
+# define COBALT_LED_POWER_OFF  (1 << 3)        /* RaQ */
+# define COBALT_LED_RESET      0x0f
+
+#define COBALT_KEY_PORT                ((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
+# define COBALT_KEY_CLEAR      (1 << 1)
+# define COBALT_KEY_LEFT       (1 << 2)
+# define COBALT_KEY_UP         (1 << 3)
+# define COBALT_KEY_DOWN       (1 << 4)
+# define COBALT_KEY_RIGHT      (1 << 5)
+# define COBALT_KEY_ENTER      (1 << 6)
+# define COBALT_KEY_SELECT     (1 << 7)
+# define COBALT_KEY_MASK       0xfe
+
+#endif /* __ASM_COBALT_H */
diff --git a/include/asm-mips/mach-cobalt/cpu-feature-overrides.h b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..ace8c5e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+#define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
+
+#define cpu_has_tlb            1
+#define cpu_has_4kex           1
+#define cpu_has_3k_cache       0
+#define cpu_has_4k_cache       1
+#define cpu_has_tx39_cache     0
+#define cpu_has_sb1_cache      0
+#define cpu_has_fpu            1
+#define cpu_has_32fpr          1
+#define cpu_has_counter                1
+#define cpu_has_watch          0
+#define cpu_has_divec          1
+#define cpu_has_vce            0
+#define cpu_has_cache_cdex_p   0
+#define cpu_has_cache_cdex_s   0
+#define cpu_has_prefetch       0
+#define cpu_has_mcheck         0
+#define cpu_has_ejtag          0
+
+#define cpu_has_subset_pcaches 0
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 0
+
+#ifdef CONFIG_64BIT
+#define cpu_has_llsc            0
+#else
+#define cpu_has_llsc            1
+#endif
+
+#define cpu_has_mips16         0
+#define cpu_has_mdmx           0
+#define cpu_has_mips3d         0
+#define cpu_has_smartmips      0
+#define cpu_has_vtag_icache    0
+#define cpu_has_ic_fills_f_dc  0
+#define cpu_icache_snoops_remote_store 0
+#define cpu_has_dsp            0
+
+#define cpu_has_mips32r1       0
+#define cpu_has_mips32r2       0
+#define cpu_has_mips64r1       0
+#define cpu_has_mips64r2       0
+
+#endif /* __ASM_COBALT_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-cobalt/mach-gt64120.h b/include/asm-mips/mach-cobalt/mach-gt64120.h
new file mode 100644 (file)
index 0000000..587fc43
--- /dev/null
@@ -0,0 +1 @@
+/* there's something here ... in the dark */
index b80c30725cf66578d0e30b22b407242cac41e908..36070b5654abadb0593337139a8d5761d879ce2d 100644 (file)
@@ -18,7 +18,7 @@
  * so, for 64bit IP32 kernel we just don't use ll/sc.
  * This does not affect luserland.
  */
-#if defined(CONFIG_CPU_R5000) && defined(CONFIG_64BIT)
+#if (defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)) && defined(CONFIG_64BIT)
 #define cpu_has_llsc           0
 #else
 #define cpu_has_llsc           1
index a5ea9d828aee4083ba0bef097cd0ea409af6bf66..cc53196efa40a0623383c6df50b0adaed3553a0f 100644 (file)
@@ -166,123 +166,6 @@ static inline void invalidate_tcache_page(unsigned long addr)
                : "r" (base),                                           \
                  "i" (op));
 
-static inline void blast_dcache16(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.dcache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-       unsigned long ws_end = current_cpu_data.dcache.ways <<
-                              current_cpu_data.dcache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_dcache16_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-
-       do {
-               cache16_unroll32(start,Hit_Writeback_Inv_D);
-               start += 0x200;
-       } while (start < end);
-}
-
-static inline void blast_dcache16_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-       unsigned long ws_end = current_cpu_data.dcache.ways <<
-                              current_cpu_data.dcache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_icache16(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.icache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache16_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-
-       do {
-               cache16_unroll32(start,Hit_Invalidate_I);
-               start += 0x200;
-       } while (start < end);
-}
-
-static inline void blast_icache16_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache16(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.scache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache16_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = page + PAGE_SIZE;
-
-       do {
-               cache16_unroll32(start,Hit_Writeback_Inv_SD);
-               start += 0x200;
-       } while (start < end);
-}
-
-static inline void blast_scache16_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x200)
-                       cache16_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache32_unroll32(base,op)                                      \
        __asm__ __volatile__(                                           \
        "       .set push                                       \n"     \
@@ -309,123 +192,6 @@ static inline void blast_scache16_page_indexed(unsigned long page)
                : "r" (base),                                           \
                  "i" (op));
 
-static inline void blast_dcache32(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.dcache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-       unsigned long ws_end = current_cpu_data.dcache.ways <<
-                              current_cpu_data.dcache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_dcache32_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-
-       do {
-               cache32_unroll32(start,Hit_Writeback_Inv_D);
-               start += 0x400;
-       } while (start < end);
-}
-
-static inline void blast_dcache32_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-       unsigned long ws_end = current_cpu_data.dcache.ways <<
-                              current_cpu_data.dcache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_icache32(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.icache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache32_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-
-       do {
-               cache32_unroll32(start,Hit_Invalidate_I);
-               start += 0x400;
-       } while (start < end);
-}
-
-static inline void blast_icache32_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache32(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.scache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache32_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = page + PAGE_SIZE;
-
-       do {
-               cache32_unroll32(start,Hit_Writeback_Inv_SD);
-               start += 0x400;
-       } while (start < end);
-}
-
-static inline void blast_scache32_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x400)
-                       cache32_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache64_unroll32(base,op)                                      \
        __asm__ __volatile__(                                           \
        "       .set push                                       \n"     \
@@ -452,84 +218,6 @@ static inline void blast_scache32_page_indexed(unsigned long page)
                : "r" (base),                                           \
                  "i" (op));
 
-static inline void blast_icache64(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.icache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x800)
-                       cache64_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache64_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-
-       do {
-               cache64_unroll32(start,Hit_Invalidate_I);
-               start += 0x800;
-       } while (start < end);
-}
-
-static inline void blast_icache64_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-       unsigned long ws_end = current_cpu_data.icache.ways <<
-                              current_cpu_data.icache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x800)
-                       cache64_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache64(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.scache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x800)
-                       cache64_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache64_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = page + PAGE_SIZE;
-
-       do {
-               cache64_unroll32(start,Hit_Writeback_Inv_SD);
-               start += 0x800;
-       } while (start < end);
-}
-
-static inline void blast_scache64_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x800)
-                       cache64_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache128_unroll32(base,op)                                     \
        __asm__ __volatile__(                                           \
        "       .set push                                       \n"     \
@@ -556,43 +244,55 @@ static inline void blast_scache64_page_indexed(unsigned long page)
                : "r" (base),                                           \
                  "i" (op));
 
-static inline void blast_scache128(void)
-{
-       unsigned long start = INDEX_BASE;
-       unsigned long end = start + current_cpu_data.scache.waysize;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x1000)
-                       cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache128_page(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = page + PAGE_SIZE;
-
-       do {
-               cache128_unroll32(start,Hit_Writeback_Inv_SD);
-               start += 0x1000;
-       } while (start < end);
-}
-
-static inline void blast_scache128_page_indexed(unsigned long page)
-{
-       unsigned long start = page;
-       unsigned long end = start + PAGE_SIZE;
-       unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-       unsigned long ws_end = current_cpu_data.scache.ways <<
-                              current_cpu_data.scache.waybit;
-       unsigned long ws, addr;
-
-       for (ws = 0; ws < ws_end; ws += ws_inc)
-               for (addr = start; addr < end; addr += 0x1000)
-                       cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
+/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \
+static inline void blast_##pfx##cache##lsize(void)                     \
+{                                                                      \
+       unsigned long start = INDEX_BASE;                               \
+       unsigned long end = start + current_cpu_data.desc.waysize;      \
+       unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;     \
+       unsigned long ws_end = current_cpu_data.desc.ways <<            \
+                              current_cpu_data.desc.waybit;            \
+       unsigned long ws, addr;                                         \
+                                                                       \
+       for (ws = 0; ws < ws_end; ws += ws_inc)                         \
+               for (addr = start; addr < end; addr += lsize * 32)      \
+                       cache##lsize##_unroll32(addr|ws,indexop);       \
+}                                                                      \
+                                                                       \
+static inline void blast_##pfx##cache##lsize##_page(unsigned long page)        \
+{                                                                      \
+       unsigned long start = page;                                     \
+       unsigned long end = page + PAGE_SIZE;                           \
+                                                                       \
+       do {                                                            \
+               cache##lsize##_unroll32(start,hitop);                   \
+               start += lsize * 32;                                    \
+       } while (start < end);                                          \
+}                                                                      \
+                                                                       \
+static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
+{                                                                      \
+       unsigned long start = page;                                     \
+       unsigned long end = start + PAGE_SIZE;                          \
+       unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;     \
+       unsigned long ws_end = current_cpu_data.desc.ways <<            \
+                              current_cpu_data.desc.waybit;            \
+       unsigned long ws, addr;                                         \
+                                                                       \
+       for (ws = 0; ws < ws_end; ws += ws_inc)                         \
+               for (addr = start; addr < end; addr += lsize * 32)      \
+                       cache##lsize##_unroll32(addr|ws,indexop);       \
+}
+
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
 
 #endif /* _ASM_R4KCACHE_H */
index 2f10ebcbe141e0c898cef92ff8491da67da56fa7..e48c0bfab2573de3481075845f017a6c76a2813f 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1999, 2001 by Ralf Baechle
+ * Copyright (C) 1997, 1999, 2001, 06 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #ifndef _ASM_REBOOT_H
@@ -11,6 +11,5 @@
 
 extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
-extern void (*_machine_power_off)(void);
 
 #endif /* _ASM_REBOOT_H */
index 5a06f6d1389981d3bb8a9c66bf384d15846e98ec..907da600fddd16497773728c8f59a1154f2f01dd 100644 (file)
@@ -141,26 +141,4 @@ extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 
-#ifdef CONFIG_32BIT
-#define __HAVE_ARCH_MEMSCAN
-static __inline__ void *memscan(void *__addr, int __c, size_t __size)
-{
-       char *__end = (char *)__addr + __size;
-       unsigned char __uc = (unsigned char) __c;
-
-       __asm__(".set\tpush\n\t"
-               ".set\tnoat\n\t"
-               ".set\treorder\n\t"
-               "1:\tbeq\t%0,%1,2f\n\t"
-               "addiu\t%0,1\n\t"
-               "lbu\t$1,-1(%0)\n\t"
-               "bne\t$1,%z4,1b\n"
-               "2:\t.set\tpop"
-               : "=r" (__addr), "=r" (__end)
-               : "0" (__addr), "1" (__end), "Jr" (__uc));
-
-       return __addr;
-}
-#endif /* CONFIG_32BIT */
-
 #endif /* _ASM_STRING_H */
index 1612b3fe10801471ee0f4f1c6d19fed91c1c3934..fa193f861e71629d3a15d2c3ed481ea99f7b9de5 100644 (file)
@@ -114,6 +114,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SYSCALL_AUDIT      4       /* syscall auditing active */
 #define TIF_SECCOMP            5       /* secure computing */
+#define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18
@@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
index 3bb7f0087d68111af56b6086e279c3b586df9227..de85bd2245f7dd2d57e2ea6d35621c441d8f678e 100644 (file)
@@ -2,7 +2,7 @@
  * Author: MontaVista Software, Inc.
  *         source@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
+ * Copyright 2001-2006 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
 #include <asm/tx4927/tx4927_mips.h>
 
 /*
- This register naming came from the intergrate cpu/controoler name TX4927
+ This register naming came from the integrated CPU/controller name TX4927
  followed by the device name from table 4.2.2 on page 4-3 and then followed
  by the register name from table 4.2.3 on pages 4-4 to 4-8.  The manaul
- used is "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001".
+ used was "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001".
  */
 
 #define TX4927_SIO_0_BASE
 
 /* TX4927 Timer 0 (32-bit registers) */
 #define TX4927_TMR0_BASE                0xf000
-#define TX4927_TMR0_TMTCR0              0xf004
-#define TX4927_TMR0_TMTISR0             0xf008
+#define TX4927_TMR0_TMTCR0              0xf000
+#define TX4927_TMR0_TMTISR0             0xf004
 #define TX4927_TMR0_TMCPRA0             0xf008
 #define TX4927_TMR0_TMCPRB0             0xf00c
 #define TX4927_TMR0_TMITMR0             0xf010
 
 /* TX4927 Timer 1 (32-bit registers) */
 #define TX4927_TMR1_BASE                0xf100
-#define TX4927_TMR1_TMTCR1              0xf104
-#define TX4927_TMR1_TMTISR1             0xf108
+#define TX4927_TMR1_TMTCR1              0xf100
+#define TX4927_TMR1_TMTISR1             0xf104
 #define TX4927_TMR1_TMCPRA1             0xf108
 #define TX4927_TMR1_TMCPRB1             0xf10c
 #define TX4927_TMR1_TMITMR1             0xf110
 
 /* TX4927 Timer 2 (32-bit registers) */
 #define TX4927_TMR2_BASE                0xf200
-#define TX4927_TMR2_TMTCR2              0xf104
-#define TX4927_TMR2_TMTISR2             0xf208
+#define TX4927_TMR2_TMTCR2              0xf200
+#define TX4927_TMR2_TMTISR2             0xf204
 #define TX4927_TMR2_TMCPRA2             0xf208
-#define TX4927_TMR2_TMCPRB2             0xf20c
 #define TX4927_TMR2_TMITMR2             0xf210
 #define TX4927_TMR2_TMCCDR2             0xf220
-#define TX4927_TMR2_TMPGMR2             0xf230
+#define TX4927_TMR2_TMWTMR2             0xf240
 #define TX4927_TMR2_TMTRR2              0xf2f0
 #define TX4927_TMR2_LIMIT               0xf2ff
 
index 165f6b8b217fe6254e40c76515fb6469af5f3aca..66c064690f41ea3b4da0c84f8005466e1f3e9a94 100644 (file)
@@ -253,6 +253,16 @@ struct tx4927_pcic_reg {
 #define TX4927_CCFG_PCIDIVMODE_5        0x00001000
 #define TX4927_CCFG_PCIDIVMODE_6        0x00001800
 
+#define TX4937_CCFG_PCIDIVMODE_MASK    0x00001c00
+#define TX4937_CCFG_PCIDIVMODE_8       0x00000000
+#define TX4937_CCFG_PCIDIVMODE_4       0x00000400
+#define TX4937_CCFG_PCIDIVMODE_9       0x00000800
+#define TX4937_CCFG_PCIDIVMODE_4_5     0x00000c00
+#define TX4937_CCFG_PCIDIVMODE_10      0x00001000
+#define TX4937_CCFG_PCIDIVMODE_5       0x00001400
+#define TX4937_CCFG_PCIDIVMODE_11      0x00001800
+#define TX4937_CCFG_PCIDIVMODE_5_5     0x00001c00
+
 /* PCFG : Pin Configuration */
 #define TX4927_PCFG_PCICLKEN_ALL        0x003f0000
 #define TX4927_PCFG_PCICLKEN(ch)        (0x00010000<<(ch))
index 41bb96bb2120da534d5c0d38992c026777c213f7..91d813a37823e03a68690233818a754eac0b8f05 100644 (file)
@@ -202,49 +202,49 @@ struct __large_struct { unsigned long buf[100]; };
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
-#else
-#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
+#ifdef CONFIG_32BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr)
 #endif
 
-#define __get_user_nocheck(x,ptr,size)                                 \
-({                                                                     \
-       __typeof(*(ptr)) __gu_val =  (__typeof(*(ptr))) 0;              \
-       long __gu_err = 0;                                              \
-                                                                       \
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr)                              \
+do {                                                                   \
        switch (size) {                                                 \
-       case 1: __get_user_asm("lb", ptr); break;                       \
-       case 2: __get_user_asm("lh", ptr); break;                       \
-       case 4: __get_user_asm("lw", ptr); break;                       \
-       case 8: __GET_USER_DW(ptr); break;                              \
+       case 1: __get_user_asm(val, "lb", ptr); break;                  \
+       case 2: __get_user_asm(val, "lh", ptr); break;                  \
+       case 4: __get_user_asm(val, "lw", ptr); break;                  \
+       case 8: __GET_USER_DW(val, ptr); break;                         \
        default: __get_user_unknown(); break;                           \
        }                                                               \
-       (x) = (__typeof__(*(ptr))) __gu_val;                            \
+} while (0)
+
+#define __get_user_nocheck(x,ptr,size)                                 \
+({                                                                     \
+       long __gu_err;                                                  \
+                                                                       \
+       __get_user_common((x), size, ptr);                              \
        __gu_err;                                                       \
 })
 
 #define __get_user_check(x,ptr,size)                                   \
 ({                                                                     \
-       const __typeof__(*(ptr)) __user * __gu_addr = (ptr);            \
-       __typeof__(*(ptr)) __gu_val = 0;                                \
        long __gu_err = -EFAULT;                                        \
+       const void __user * __gu_ptr = (ptr);                           \
+                                                                       \
+       if (likely(access_ok(VERIFY_READ,  __gu_ptr, size)))            \
+               __get_user_common((x), size, __gu_ptr);                 \
                                                                        \
-       if (likely(access_ok(VERIFY_READ,  __gu_addr, size))) {         \
-               switch (size) {                                         \
-               case 1: __get_user_asm("lb", __gu_addr); break;         \
-               case 2: __get_user_asm("lh", __gu_addr); break;         \
-               case 4: __get_user_asm("lw", __gu_addr); break;         \
-               case 8: __GET_USER_DW(__gu_addr); break;                \
-               default: __get_user_unknown(); break;                   \
-               }                                                       \
-       }                                                               \
-       (x) = (__typeof__(*(ptr))) __gu_val;                            \
        __gu_err;                                                       \
 })
 
-#define __get_user_asm(insn, addr)                                     \
+#define __get_user_asm(val, insn, addr)                                        \
 {                                                                      \
+       long __gu_tmp;                                                  \
+                                                                       \
        __asm__ __volatile__(                                           \
        "1:     " insn "        %1, %3                          \n"     \
        "2:                                                     \n"     \
@@ -255,14 +255,16 @@ struct __large_struct { unsigned long buf[100]; };
        "       .section __ex_table,\"a\"                       \n"     \
        "       "__UA_ADDR "\t1b, 3b                            \n"     \
        "       .previous                                       \n"     \
-       : "=r" (__gu_err), "=r" (__gu_val)                              \
+       : "=r" (__gu_err), "=r" (__gu_tmp)                              \
        : "0" (0), "o" (__m(addr)), "i" (-EFAULT));                     \
+                                                                       \
+       (val) = (__typeof__(val)) __gu_tmp;                             \
 }
 
 /*
  * Get a long long 64 using 32 bit registers.
  */
-#define __get_user_asm_ll32(addr)                                      \
+#define __get_user_asm_ll32(val, addr)                                 \
 {                                                                      \
        __asm__ __volatile__(                                           \
        "1:     lw      %1, (%3)                                \n"     \
@@ -278,21 +280,20 @@ struct __large_struct { unsigned long buf[100]; };
        "       " __UA_ADDR "   1b, 4b                          \n"     \
        "       " __UA_ADDR "   2b, 4b                          \n"     \
        "       .previous                                       \n"     \
-       : "=r" (__gu_err), "=&r" (__gu_val)                             \
+       : "=r" (__gu_err), "=&r" (val)                                  \
        : "0" (0), "r" (addr), "i" (-EFAULT));                          \
 }
 
-extern void __get_user_unknown(void);
-
 /*
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
-#else
+#ifdef CONFIG_32BIT
 #define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
 #endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+#endif
 
 #define __put_user_nocheck(x,ptr,size)                                 \
 ({                                                                     \
index 89ea8b60e945cbb6d6660d85d9b02229ce36950f..e7ff9b1877835c4911d02afe6c747ecae6b02ca2 100644 (file)
 #define __NR_inotify_init              (__NR_Linux + 284)
 #define __NR_inotify_add_watch         (__NR_Linux + 285)
 #define __NR_inotify_rm_watch          (__NR_Linux + 286)
-
+#define __NR_migrate_pages             (__NR_Linux + 287)
+#define __NR_openat                    (__NR_Linux + 288)
+#define __NR_mkdirat                   (__NR_Linux + 289)
+#define __NR_mknodat                   (__NR_Linux + 290)
+#define __NR_fchownat                  (__NR_Linux + 291)
+#define __NR_futimesat                 (__NR_Linux + 292)
+#define __NR_newfstatat                        (__NR_Linux + 293)
+#define __NR_unlinkat                  (__NR_Linux + 294)
+#define __NR_renameat                  (__NR_Linux + 295)
+#define __NR_linkat                    (__NR_Linux + 296)
+#define __NR_symlinkat                 (__NR_Linux + 297)
+#define __NR_readlinkat                        (__NR_Linux + 298)
+#define __NR_fchmodat                  (__NR_Linux + 299)
+#define __NR_faccessat                 (__NR_Linux + 300)
+#define __NR_pselect6                  (__NR_Linux + 301)
+#define __NR_ppoll                     (__NR_Linux + 302)
+#define __NR_unshare                   (__NR_Linux + 303)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            286
+#define __NR_Linux_syscalls            303
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                283
+#define __NR_O32_Linux_syscalls                303
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_inotify_init              (__NR_Linux + 243)
 #define __NR_inotify_add_watch         (__NR_Linux + 244)
 #define __NR_inotify_rm_watch          (__NR_Linux + 245)
+#define __NR_migrate_pages             (__NR_Linux + 246)
+#define __NR_openat                    (__NR_Linux + 247)
+#define __NR_mkdirat                   (__NR_Linux + 248)
+#define __NR_mknodat                   (__NR_Linux + 249)
+#define __NR_fchownat                  (__NR_Linux + 250)
+#define __NR_futimesat                 (__NR_Linux + 251)
+#define __NR_newfstatat                        (__NR_Linux + 252)
+#define __NR_unlinkat                  (__NR_Linux + 253)
+#define __NR_renameat                  (__NR_Linux + 254)
+#define __NR_linkat                    (__NR_Linux + 255)
+#define __NR_symlinkat                 (__NR_Linux + 256)
+#define __NR_readlinkat                        (__NR_Linux + 257)
+#define __NR_fchmodat                  (__NR_Linux + 258)
+#define __NR_faccessat                 (__NR_Linux + 259)
+#define __NR_pselect6                  (__NR_Linux + 260)
+#define __NR_ppoll                     (__NR_Linux + 261)
+#define __NR_unshare                   (__NR_Linux + 262)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            245
+#define __NR_Linux_syscalls            262
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         242
+#define __NR_64_Linux_syscalls         262
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_inotify_init              (__NR_Linux + 247)
 #define __NR_inotify_add_watch         (__NR_Linux + 248)
 #define __NR_inotify_rm_watch          (__NR_Linux + 249)
+#define __NR_migrate_pages             (__NR_Linux + 250)
+#define __NR_openat                    (__NR_Linux + 251)
+#define __NR_mkdirat                   (__NR_Linux + 252)
+#define __NR_mknodat                   (__NR_Linux + 253)
+#define __NR_fchownat                  (__NR_Linux + 254)
+#define __NR_futimesat                 (__NR_Linux + 255)
+#define __NR_newfstatat                        (__NR_Linux + 256)
+#define __NR_unlinkat                  (__NR_Linux + 257)
+#define __NR_renameat                  (__NR_Linux + 258)
+#define __NR_linkat                    (__NR_Linux + 259)
+#define __NR_symlinkat                 (__NR_Linux + 260)
+#define __NR_readlinkat                        (__NR_Linux + 261)
+#define __NR_fchmodat                  (__NR_Linux + 262)
+#define __NR_faccessat                 (__NR_Linux + 263)
+#define __NR_pselect6                  (__NR_Linux + 264)
+#define __NR_ppoll                     (__NR_Linux + 265)
+#define __NR_unshare                   (__NR_Linux + 266)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            249
+#define __NR_Linux_syscalls            266
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                246
+#define __NR_N32_Linux_syscalls                266
 
 #ifndef __ASSEMBLY__
 
index 2ca56d34aaad32e582a68a5fd0d75ce410ac03cf..4dc7253ff5d06a2e80a44388996b31bd8ce9019c 100644 (file)
@@ -1,9 +1,13 @@
+/* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 2006 Kyle McMartin <kyle@parisc-linux.org>
+ */
+
 #ifndef _ASM_PARISC_ATOMIC_H_
 #define _ASM_PARISC_ATOMIC_H_
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <asm/system.h>
-/* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.  */
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
@@ -46,15 +50,6 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
 #  define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)
 #endif
 
-/* Note that we need not lock read accesses - aligned word writes/reads
- * are atomic, so a reader never sees unconsistent values.
- *
- * Cache-line alignment would conflict with, for example, linux/module.h
- */
-
-typedef struct { volatile int counter; } atomic_t;
-
-
 /* This should get optimized out since it's never called.
 ** Or get a link error if xchg is used "wrong".
 */
@@ -69,10 +64,9 @@ extern unsigned long __xchg64(unsigned long, unsigned long *);
 #endif
 
 /* optimizer better get rid of switch since size is a constant */
-static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
-                                       int size)
+static __inline__ unsigned long
+__xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
-
        switch(size) {
 #ifdef __LP64__
        case 8: return __xchg64(x,(unsigned long *) ptr);
@@ -129,7 +123,13 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
                                    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+/* Note that we need not lock read accesses - aligned word writes/reads
+ * are atomic, so a reader never sees unconsistent values.
+ *
+ * Cache-line alignment would conflict with, for example, linux/module.h
+ */
 
+typedef struct { volatile int counter; } atomic_t;
 
 /* It's possible to reduce all atomic operations to either
  * __atomic_add_return, atomic_set and atomic_read (the latter
@@ -210,12 +210,66 @@ static __inline__ int atomic_read(const atomic_t *v)
 
 #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
 
-#define ATOMIC_INIT(i) { (i) }
+#define ATOMIC_INIT(i) ((atomic_t) { (i) })
 
 #define smp_mb__before_atomic_dec()    smp_mb()
 #define smp_mb__after_atomic_dec()     smp_mb()
 #define smp_mb__before_atomic_inc()    smp_mb()
 #define smp_mb__after_atomic_inc()     smp_mb()
 
+#ifdef __LP64__
+
+typedef struct { volatile s64 counter; } atomic64_t;
+
+#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
+
+static __inline__ int
+__atomic64_add_return(s64 i, atomic64_t *v)
+{
+       int ret;
+       unsigned long flags;
+       _atomic_spin_lock_irqsave(v, flags);
+
+       ret = (v->counter += i);
+
+       _atomic_spin_unlock_irqrestore(v, flags);
+       return ret;
+}
+
+static __inline__ void
+atomic64_set(atomic64_t *v, s64 i)
+{
+       unsigned long flags;
+       _atomic_spin_lock_irqsave(v, flags);
+
+       v->counter = i;
+
+       _atomic_spin_unlock_irqrestore(v, flags);
+}
+
+static __inline__ s64
+atomic64_read(const atomic64_t *v)
+{
+       return v->counter;
+}
+
+#define atomic64_add(i,v)      ((void)(__atomic64_add_return( ((s64)i),(v))))
+#define atomic64_sub(i,v)      ((void)(__atomic64_add_return(-((s64)i),(v))))
+#define atomic64_inc(v)                ((void)(__atomic64_add_return(   1,(v))))
+#define atomic64_dec(v)                ((void)(__atomic64_add_return(  -1,(v))))
+
+#define atomic64_add_return(i,v)       (__atomic64_add_return( ((s64)i),(v)))
+#define atomic64_sub_return(i,v)       (__atomic64_add_return(-((s64)i),(v)))
+#define atomic64_inc_return(v)         (__atomic64_add_return(   1,(v)))
+#define atomic64_dec_return(v)         (__atomic64_add_return(  -1,(v)))
+
+#define atomic64_add_negative(a, v)    (atomic64_add_return((a), (v)) < 0)
+
+#define atomic64_inc_and_test(v)       (atomic64_inc_return(v) == 0)
+#define atomic64_dec_and_test(v)       (atomic64_dec_return(v) == 0)
+
+#endif /* __LP64__ */
+
 #include <asm-generic/atomic.h>
-#endif
+
+#endif /* _ASM_PARISC_ATOMIC_H_ */
index 1bc3c83ee74bc0acc635041179760ef83d644f68..c53af9ff41b5f825cfc75bf3fea1bbc786b58c55 100644 (file)
@@ -183,4 +183,10 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
                __flush_cache_page(vma, vmaddr);
 
 }
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void);
 #endif
+
+#endif /* _PARISC_CACHEFLUSH_H */
+
index a1228a3d20715fc9518efc7fb48c70013053c16e..2f7292afde3c93a16e208c85397f1203cd080776 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _ASM_PARISC_COMPAT_UCONTEXT_H
 #define _ASM_PARISC_COMPAT_UCONTEXT_H
 
-#include<linux/compat.h>
-#include<asm/compat_signal.h>
+#include <linux/compat.h>
 
 /* 32-bit ucontext as seen from an 64-bit kernel */
 struct compat_ucontext {
index 6a910311b56b43d4bc65f94e9fc4393a1fdc1033..671e06042b406f9b53f7254aa5f49e7daaa9250a 100644 (file)
@@ -58,7 +58,7 @@
 #define CRT_ID_ELK_1024DB      0x27849CA5      /* Elk 1024x768 double buffer */
 #define CRT_ID_ELK_GS          S9000_ID_A1924A /* Elk 1280x1024 GreyScale    */
 #define CRT_ID_CRX24           S9000_ID_A1439A /* Piranha */
-#define CRT_ID_VISUALIZE_EG    0x2D08C0A7      /* Graffiti (built-in B132+/B160L) */
+#define CRT_ID_VISUALIZE_EG    0x2D08C0A7      /* Graffiti, A4450A (built-in B132+/B160L) */
 #define CRT_ID_THUNDER         0x2F23E5FC      /* Thunder 1 VISUALIZE 48*/
 #define CRT_ID_THUNDER2                0x2F8D570E      /* Thunder 2 VISUALIZE 48 XP*/
 #define CRT_ID_HCRX            S9000_ID_HCRX   /* Hyperdrive HCRX */
index f277254159b7585f2681583932ad13e93e2f8cf5..fe7f6a2f5aa765b50c04323f14605c7bc36f25da 100644 (file)
 */
 #define PCI_MAX_BUSSES 256
 
+
+/* To be used as: mdelay(pci_post_reset_delay);
+ *
+ * post_reset is the time the kernel should stall to prevent anyone from
+ * accessing the PCI bus once #RESET is de-asserted. 
+ * PCI spec somewhere says 1 second but with multi-PCI bus systems,
+ * this makes the boot time much longer than necessary.
+ * 20ms seems to work for all the HP PCI implementations to date.
+ */
+#define pci_post_reset_delay 50
+
+
 /*
 ** pci_hba_data (aka H2P_OBJECT in HP/UX)
 **
@@ -83,7 +95,7 @@ static __inline__  int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a)
 
 /*
 ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses.
-** See pcibios.c for more conversions used by Generic PCI code.
+** See pci.c for more conversions used by Generic PCI code.
 **
 ** Platform characteristics/firmware guarantee that
 **     (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO
@@ -191,9 +203,6 @@ struct pci_bios_ops {
 */
 extern struct pci_port_ops *pci_port;
 extern struct pci_bios_ops *pci_bios;
-extern int pci_post_reset_delay;       /* delay after de-asserting #RESET */
-extern int pci_hba_count;
-extern struct pci_hba_data *parisc_pci_hba[];
 
 #ifdef CONFIG_PCI
 extern void pcibios_register_hba(struct pci_hba_data *);
index 6291d6692e5db772ab0f37809dca082e38cac6a7..3122fad38a1b766417ac8dd38f510ff181424f71 100644 (file)
@@ -137,7 +137,6 @@ static inline void pte_free_kernel(pte_t *pte)
 
 #define pte_free(page) pte_free_kernel(page_address(page))
 
-extern int do_check_pgt_cache(int, int);
 #define check_pgt_cache()      do { } while (0)
 
 #endif
index b4554711c3e739d126be89721006cf6f3375540a..4e34c6b44059b569b61318e6df3474115084a29c 100644 (file)
@@ -213,7 +213,7 @@ extern  void *vmalloc_start;
 #define PAGE_COPY       PAGE_EXECREAD
 #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
 #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
-#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
 #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
 #define PAGE_GATEWAY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ)
 #define PAGE_FLUSH      __pgprot(_PAGE_FLUSH)
index 5623c032b64c9207e53bd3f4e984fc233564ccb2..f0dd3b30f6c4633eba7e667b1b54401bc4c5ccde 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef _ASM_PARISC_RT_SIGFRAME_H
 #define _ASM_PARISC_RT_SIGFRAME_H
 
-#ifdef CONFIG_COMPAT
-#include <asm/compat_rt_sigframe.h>
-#endif
-
 #define SIGRETURN_TRAMP 4
 #define SIGRESTARTBLOCK_TRAMP 5 
 #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
index 80b7b98c70a150484875767753d35eddbfde4adc..c56fccbf34ad17c69052e5c8e56616071a92e837 100644 (file)
 #define __NR_keyctl            (__NR_Linux + 266)
 #define __NR_ioprio_set                (__NR_Linux + 267)
 #define __NR_ioprio_get                (__NR_Linux + 268)
+#define __NR_inotify_init      (__NR_Linux + 269)
+#define __NR_inotify_add_watch (__NR_Linux + 270)
+#define __NR_inotify_rm_watch  (__NR_Linux + 271)
+#define __NR_migrate_pages     (__NR_Linux + 272)
+#define __NR_pselect6          (__NR_Linux + 273)
+#define __NR_ppoll             (__NR_Linux + 274)
+#define __NR_openat            (__NR_Linux + 275)
+#define __NR_mkdirat           (__NR_Linux + 276)
+#define __NR_mknodat           (__NR_Linux + 277)
+#define __NR_fchownat          (__NR_Linux + 278)
+#define __NR_futimesat         (__NR_Linux + 279)
+#define __NR_newfstatat                (__NR_Linux + 280)
+#define __NR_unlinkat          (__NR_Linux + 281)
+#define __NR_renameat          (__NR_Linux + 282)
+#define __NR_linkat            (__NR_Linux + 283)
+#define __NR_symlinkat         (__NR_Linux + 284)
+#define __NR_readlinkat                (__NR_Linux + 285)
+#define __NR_fchmodat          (__NR_Linux + 286)
+#define __NR_faccessat         (__NR_Linux + 287)
 
-#define __NR_Linux_syscalls     269
+#define __NR_Linux_syscalls     288
 
 #define HPUX_GATEWAY_ADDR       0xC0000004
 #define LINUX_GATEWAY_ADDR      0x100
index accb80c9a339c2b2b2ee38de36c3fec1a76ab551..aacaabd28ac10ddcc7175a5cf7fbe293be7205f9 100644 (file)
@@ -126,6 +126,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr)
        return (void __user *)(unsigned long)uptr;
 }
 
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+       return (u32)(unsigned long)uptr;
+}
+
 static inline void __user *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = current->thread.regs;
index 837756ab7dc7fe868c2caa19d526406849617d13..2ac63f56959270e49cd3169b8a9c0067854cb603 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
 
index 5b2bd4eefb01870e4a31647232331a1d10bbd962..cbd297f44cce6490ac1220898a945d58c95158aa 100644 (file)
@@ -222,5 +222,7 @@ extern int of_address_to_resource(struct device_node *dev, int index,
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
                                      struct resource *r);
 
+extern void kdump_move_device_tree(void);
+
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
index 82ce47607774b5a21d79c733559b0ffe94a91b05..2dc93632f210c94d2fdd18b47dc44ea6d0014bd1 100644 (file)
@@ -521,6 +521,11 @@ struct smu_sdbp_cpupiddata {
 extern struct smu_sdbp_header *smu_get_sdb_partition(int id,
                                        unsigned int *size);
 
+/* Get "sdb" partition data from an SMU satellite */
+extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id,
+                                       int id, unsigned int *size);
+
+
 #endif /* __KERNEL__ */
 
 
index 67cdaf3ae9fc6270a5b558ee23e9be13762506d5..c044ec16a8791e89114e890625accd803d7bf1d5 100644 (file)
@@ -37,7 +37,7 @@ struct thread_info {
        int             preempt_count;          /* 0 => preemptable,
                                                   <0 => BUG */
        struct restart_block restart_block;
-       void *nvgprs_frame;
+       void __user *nvgprs_frame;
        /* low level flags - has atomic operations done on it */
        unsigned long   flags ____cacheline_aligned_in_smp;
 };
index 1630c26e8f45a5c27eef949454fb4702747fc7f0..c744ff33b1df62b0ead905356025a1e650c6b1e8 100644 (file)
@@ -204,7 +204,8 @@ typedef struct attrib_data_t {
  *
  * Here ist how the ioctl-nr should be used:
  *    0 -   31   DASD driver itself
- *   32 -  239   still open
+ *   32 -  229   still open
+ *  230 -  239   DASD extended error reporting
  *  240 -  255   reserved for EMC 
  *******************************************************************************/
 
@@ -236,12 +237,22 @@ typedef struct attrib_data_t {
 #define BIODASDPSRD    _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t)
 /* Get Attributes (cache operations) */
 #define BIODASDGATTR   _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) 
+/* retrieve extended error-reporting value */
+#define BIODASDEERGET  _IOR(DASD_IOCTL_LETTER,6,int)
 
 
 /* #define BIODASDFORMAT  _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
 #define BIODASDFMT     _IOW(DASD_IOCTL_LETTER,1,format_data_t) 
 /* Set Attributes (cache operations) */
 #define BIODASDSATTR   _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) 
+/* retrieve extended error-reporting value */
+#define BIODASDEERSET  _IOW(DASD_IOCTL_LETTER,3,int)
+
+
+/* remove all records from the eer buffer */
+#define DASD_EER_PURGE       _IO(DASD_IOCTL_LETTER,230)
+/* set the number of pages that are used for the internal eer buffer */
+#define DASD_EER_SETBUFSIZE  _IOW(DASD_IOCTL_LETTER,230,int)
 
 
 #endif                         /* DASD_H */
index 71f55eb2350a3e77838d73684b08fff5d34b7fde..b05825dd16d7043d3e578d515433e1ceda0b124f 100644 (file)
@@ -90,10 +90,16 @@ extern void iounmap(void *addr);
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
 
 #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
 #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
 #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
 
 #define memset_io(a,b,c)        memset(__io_virt(a),(b),(c))
 #define memcpy_fromio(a,b,c)    memcpy((a),__io_virt(b),(c))
index ea0788967c5127a931a2f8974cc5429e23ade6ea..fcd6c256a2d194aa4b1269f89cfc25fabb8c96a6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  include/asm-s390/timer.h
  *
- *  (C) Copyright IBM Corp. 2003
+ *  (C) Copyright IBM Corp. 2003,2006
  *  Virtual CPU timer
  *
  *  Author: Jan Glauber (jang@de.ibm.com)
@@ -10,6 +10,8 @@
 #ifndef _ASM_S390_TIMER_H
 #define _ASM_S390_TIMER_H
 
+#ifdef __KERNEL__
+
 #include <linux/timer.h>
 
 #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL)
@@ -43,4 +45,6 @@ extern void add_virt_timer_periodic(void *new);
 extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires);
 extern int del_virt_timer(struct vtimer_list *timer);
 
-#endif
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_S390_TIMER_H */
index be104f21c70a004dd8ac0c992267a031c126d3d7..0b7c0ca4c3d7730b8e342bf368e2a5179c8a0cda 100644 (file)
@@ -61,7 +61,7 @@
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
 
-static inline int __access_ok(const void *addr, unsigned long size)
+static inline int __access_ok(const void __user *addr, unsigned long size)
 {
        return 1;
 }
@@ -208,25 +208,25 @@ extern int __put_user_bad(void) __attribute__((noreturn));
        case 1: {                                               \
                unsigned char __x;                              \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 2: {                                               \
                unsigned short __x;                             \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 4: {                                               \
                unsigned int __x;                               \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 8: {                                               \
                unsigned long long __x;                         \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        default:                                                \
index 2ac64e65e336531c8fcd918e52e0edde710f495d..0615d601a7c67560b23634a8f51ddd6dd4f96aa9 100644 (file)
 #define __NR_faccessat         296
 #define __NR_pselect6          297
 #define __NR_ppoll             298
+#define __NR_unshare           299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
index 84ac2bdb09025abbfd0747aec763bf453541c6ea..c58ba8a096cf4579aa65f136c17ff0396dbdbdc6 100644 (file)
 #define __NR_faccessat         296
 #define __NR_pselect6          297
 #define __NR_ppoll             298
+#define __NR_unshare           299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
index 8955d2376ac824e5e3a7bd3e97459b442f206cf7..609b9e87222a41c3594014e4f585d6a88333af79 100644 (file)
@@ -188,7 +188,7 @@ static inline int find_next_zero_bit(const void *addr, int size, int offset)
        tmp = *p;
 
  found_first:
-       tmp |= ~0UL >> size;
+       tmp |= ~0UL << size;
  found_middle:
        return result + ffz (tmp);
 }
index 4f6a4dc455bb9e83fcc1e139561e8abf80a4c62b..bdbd8935612a7d6eaa9f96e63e796abc72cfb66b 100644 (file)
@@ -17,6 +17,7 @@
 #define APIC_DEBUG   2
 
 extern int apic_verbosity;
+extern int apic_runs_main_timer;
 
 /*
  * Define the default level of output to be very little
index 41c0ac8559be1733e9f3d27badd4e545f93f8ddc..76bb6193ae9107a380ac6b754d5dd498869eef5f 100644 (file)
@@ -61,7 +61,7 @@
 #define X86_FEATURE_K6_MTRR    (3*32+ 1) /* AMD K6 nonstandard MTRRs */
 #define X86_FEATURE_CYRIX_ARR  (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR        (3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* 4 free */
+#define X86_FEATURE_REP_GOOD   (3*32+ 4) /* rep microcode works well on this CPU */
 #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
 #define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
 
index 8661b476fb404f74e14d4ed7342e92575c37c50d..8689951e350348be7123affa57241d77997eb41b 100644 (file)
 #define set_softirq_pending(x) write_pda(__softirq_pending, (x))
 #define or_softirq_pending(x)  or_pda(__softirq_pending, (x))
 
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-static inline void ack_bad_irq(unsigned int irq)
-{
-       printk("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
-       /*
-        * Currently unexpected vectors happen only on SMP and APIC.
-        * We _must_ ack these because every local APIC has only N
-        * irq slots per priority level, and a 'hanging, unacked' IRQ
-        * holds up an irq slot - in excessive cases (when multiple
-        * unexpected vectors occur) that might lock up the APIC
-        * completely.
-        */
-       ack_APIC_irq();
-#endif
-}
+extern void ack_bad_irq(unsigned int irq);
+
 #endif /* __ASM_HARDIRQ_H */
index 9afc0c7d3661931fbb52efa6c4a4be09c1ddc6d2..20468983d4532f54fbf994b4d323ccd924db132d 100644 (file)
 #define __NR_ia32_readlinkat           305
 #define __NR_ia32_fchmodat             306
 #define __NR_ia32_faccessat            307
+#define __NR_ia32_pselect6             308
+#define __NR_ia32_ppoll                        309
+#define __NR_ia32_unshare              310
 
-#define IA32_NR_syscalls 308   /* must be > than biggest syscall! */
+#define IA32_NR_syscalls 315   /* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
index ae28cd44bcd3158433641c67e3afdf26a1a25cd8..c564bae034338272e952c05fb84646b9b60a669f 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef _X86_64_KEXEC_H
 #define _X86_64_KEXEC_H
 
+#include <linux/string.h>
+
 #include <asm/page.h>
-#include <asm/proto.h>
 #include <asm/ptrace.h>
 
 /*
index 34e434ce3268409b7cc90f5fb1c6c925d051086c..dffe276ca2df49d55044dad35b124373f64e6bf8 100644 (file)
@@ -22,8 +22,15 @@ extern void numa_set_node(int cpu, int node);
 extern unsigned char apicid_to_node[256];
 #ifdef CONFIG_NUMA
 extern void __init init_cpu_to_node(void);
+
+static inline void clear_node_cpumask(int cpu)
+{
+       clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+}
+
 #else
 #define init_cpu_to_node() do {} while (0)
+#define clear_node_cpumask(cpu) do {} while (0)
 #endif
 
 #define NUMA_NO_NODE 0xff
index 115e496c613951bd0ebd5667e18c075e76d5bf60..c99832e7bf3f76a0b531e8d9ae913fc17fcb3f40 100644 (file)
@@ -41,10 +41,18 @@ extern void iommu_hole_init(void);
 
 extern void time_init_gtod(void);
 extern int pmtimer_mark_offset(void);
+extern void pmtimer_resume(void);
+extern void pmtimer_wait(unsigned);
 extern unsigned int do_gettimeoffset_pm(void);
+#ifdef CONFIG_X86_PM_TIMER
 extern u32 pmtmr_ioport;
+#else
+#define pmtmr_ioport 0
+#endif
 extern unsigned long long monotonic_base;
 extern int sysctl_vsyscall;
+extern int nohpet;
+extern unsigned long vxtime_hz;
 
 extern void do_softirq_thunk(void);
 
@@ -65,6 +73,9 @@ extern void free_bootmem_generic(unsigned long phys, unsigned len);
 
 extern void load_gs_index(unsigned gs);
 
+extern void stop_timer_interrupt(void);
+extern void main_timer_handler(struct pt_regs *regs);
+
 extern unsigned long end_pfn_map; 
 
 extern void show_trace(unsigned long * rsp);
index a73f0c789d8b994b3459771ec90a51e93af0eb08..b7f66034ae7ac5e4d9ba115cf6db9d651bb2c41b 100644 (file)
@@ -327,7 +327,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 #define wmb()  asm volatile("" ::: "memory")
 #endif
 #define read_barrier_depends() do {} while(0)
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
index 2fa7f27381b40b69d39562a5e6394b1a975ec803..c642f5d9882df400e91b3f1fdf7ba3ff966c54bf 100644 (file)
@@ -57,6 +57,15 @@ extern int __node_distance(int, int);
 
 #endif
 
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu)                              \
+       (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu])
+#define topology_core_id(cpu)                                          \
+       (cpu_core_id[cpu] == BAD_APICID ? 0 : cpu_core_id[cpu])
+#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu)          (cpu_sibling_map[cpu])
+#endif
+
 #include <asm-generic/topology.h>
 
 #endif
index 436d099b5b6b162e21aee103525e03222176bab3..da0341c57949717e17b59a9c16499b4b31e5d8c1 100644 (file)
@@ -599,8 +599,14 @@ __SYSCALL(__NR_readlinkat, sys_readlinkat)
 __SYSCALL(__NR_fchmodat, sys_fchmodat)
 #define __NR_faccessat         269
 __SYSCALL(__NR_faccessat, sys_faccessat)
-
-#define __NR_syscall_max __NR_faccessat
+#define __NR_pselect6          270
+__SYSCALL(__NR_pselect6, sys_ni_syscall)       /* for now */
+#define __NR_ppoll             271
+__SYSCALL(__NR_ppoll,  sys_ni_syscall)         /* for now */
+#define __NR_unshare           272
+__SYSCALL(__NR_unshare,        sys_unshare)
+
+#define __NR_syscall_max __NR_unshare
 
 #ifndef __NO_STUBS
 
index 6a2a19f14bb26bb3f4f49815b566c2a4e8353cab..208650b1ad3ac08a340d93e87729890d807a3bdb 100644 (file)
@@ -81,7 +81,7 @@ static inline int generic_fls64(__u64 x)
 {
        __u32 h = x >> 32;
        if (h)
-               return fls(x) + 32;
+               return fls(h) + 32;
        return fls(x);
 }
 
index acffb8c9073acdf858410baa5bac35032860453a..a7f01502753581f3a27b935645a4f362b4277772 100644 (file)
@@ -126,7 +126,7 @@ extern struct config_item *config_group_find_obj(struct config_group *, const ch
 
 
 struct configfs_attribute {
-       char                    *ca_name;
+       const char              *ca_name;
        struct module           *ca_owner;
        mode_t                  ca_mode;
 };
index 13e9f4a3ab26c9e05d05bf0b5a181bab6cb735d4..20b446f26ecd445e75016b8cfdceed711d25dad0 100644 (file)
@@ -84,7 +84,6 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/bitmap.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 extern cpumask_t _unused_cpumask_arg_;
index a3ed5e059d479eb2ff7ee712f6adff5170c2a4be..4361f3789975d366a39a762d688d02df9408eb82 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <linux/rcupdate.h>
-#include <asm/bug.h>
 
 struct nameidata;
 struct vfsmount;
@@ -108,7 +107,9 @@ struct dentry {
        struct dentry_operations *d_op;
        struct super_block *d_sb;       /* The root of the dentry tree */
        void *d_fsdata;                 /* fs-specific data */
+#ifdef CONFIG_PROFILING
        struct dcookie_struct *d_cookie; /* cookie, if any */
+#endif
        int d_mounted;
        unsigned char d_iname[DNAME_INLINE_LEN_MIN];    /* small names */
 };
index b1999bfeaa5621556e0f98cd86e1a4fa9b59d745..b81e58b2ebf8d0ba3b39ba31399cb8756b4c63ad 100644 (file)
@@ -135,7 +135,7 @@ typedef struct video_spu {
 
 typedef struct video_spu_palette {      /* SPU Palette information */
        int length;
-       uint8_t *palette;
+       uint8_t __user *palette;
 } video_spu_palette_t;
 
 
index 23fe746a1d514b8f912c7c6cfab8e53d5ba8e92d..18cf1f3e11845dd6ba28f81b3defd2e4ed52adff 100644 (file)
@@ -82,6 +82,7 @@ struct elevator_queue
 extern void elv_dispatch_sort(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 *);
index dbd7bb4a33b7e8aa2eabed69674930400798e775..0cf0bea010fe2110417f98e83c3cbf60f94f2da5 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/signal.h>
 #include <linux/time.h>
 #include <linux/user.h>
+#include <linux/ptrace.h>
 
 struct elf_siginfo
 {
index 7863a59bd5986983fdeb4c92dca2782427bf184e..63f1d63cc1d8cd93154d0874421e2b509c08ddfa 100644 (file)
@@ -100,6 +100,9 @@ extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
                                         u8 command, u8 *values);
+extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
+                                         u8 command, u8 length,
+                                         u8 *values);
 
 /*
  * A driver is capable of handling one or more physical devices present on
index 9ba8067966677bca95064140fdc124610b7437d8..5a9d8c5991719d121b25471f79b66fd9b25012b0 100644 (file)
@@ -1115,9 +1115,11 @@ static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c)
                return ERR_PTR(-ENOMEM);
 
        mmsg->mfa = readl(c->in_port);
-       if (mmsg->mfa == I2O_QUEUE_EMPTY) {
+       if (unlikely(mmsg->mfa >= c->in_queue.len)) {
                mempool_free(mmsg, c->in_msg.mempool);
-               return ERR_PTR(-EBUSY);
+               if(mmsg->mfa == I2O_QUEUE_EMPTY)
+                       return ERR_PTR(-EBUSY);
+               return ERR_PTR(-EFAULT);
        }
 
        return &mmsg->msg;
index 110b3cfac021af3be75a1feb2c65fbec359fb72c..a7fc4cc79b235f5ffefae57b99c2668d1ed3397a 100644 (file)
@@ -582,7 +582,6 @@ typedef struct ide_drive_s {
        unsigned noprobe        : 1;    /* from:  hdx=noprobe */
        unsigned removable      : 1;    /* 1 if need to do check_media_change */
        unsigned attach         : 1;    /* needed for removable devices */
-       unsigned is_flash       : 1;    /* 1 if probed as flash */
        unsigned forced_geom    : 1;    /* 1 if hdx=c,h,s was given at boot */
        unsigned no_unmask      : 1;    /* disallow setting unmask bit */
        unsigned no_io_32bit    : 1;    /* disallow enabling 32bit I/O */
@@ -1006,7 +1005,6 @@ extern    ide_hwif_t      ide_hwifs[];            /* master data repository */
 extern int noautodma;
 
 extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
-extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs);
 
 /*
  * This is used on exit from the driver to designate the next irq handler
index e7906a72a4f156a5d38288d45677fdcbe8a09597..da7c09e4ede6e83198bf1ab5f16c571b0cc214ee 100644 (file)
@@ -27,7 +27,7 @@ struct ioc3_driver_data {
        int id;                         /* IOC3 sequence number */
        /* PCI mapping */
        unsigned long pma;              /* physical address */
-       struct __iomem ioc3 *vma;       /* pointer to registers */
+       struct ioc3 __iomem *vma;       /* pointer to registers */
        struct pci_dev *pdev;           /* PCI device */
        /* IRQ stuff */
        int dual_irq;                   /* set if separate IRQs are used */
index 558cb4c26ec9ee6c1d6f8daab784f8bc497fba84..0fe4aa891ddc1f1086493b65218b656ef8d9b7e1 100644 (file)
@@ -23,6 +23,7 @@
 #define jfs_debug jbd_debug
 #else
 
+#include <linux/types.h>
 #include <linux/buffer_head.h>
 #include <linux/journal-head.h>
 #include <linux/stddef.h>
@@ -238,7 +239,6 @@ typedef struct journal_superblock_s
 
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <asm/bug.h>
 
 #define JBD_ASSERTIONS
 #ifdef JBD_ASSERTIONS
@@ -618,6 +618,7 @@ struct transaction_s
  * @j_wbuf: array of buffer_heads for journal_commit_transaction
  * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
  *     number that will fit in j_blocksize
+ * @j_last_sync_writer: most recent pid which did a synchronous write
  * @j_private: An opaque pointer to fs-private information.
  */
 
@@ -807,6 +808,8 @@ struct journal_s
        struct buffer_head      **j_wbuf;
        int                     j_wbufsize;
 
+       pid_t                   j_last_sync_writer;
+
        /*
         * An opaque pointer to fs-private information.  ext3 puts its
         * superblock pointer here
index 45f625d7d0b2aab6ca2ee0e99dda5f0cd03109e3..3aed37314ab805de8fe3dcfec0a5282d7035cc54 100644 (file)
@@ -151,6 +151,11 @@ extern unsigned int keymap_count;
 
 static inline void con_schedule_flip(struct tty_struct *t)
 {
+       unsigned long flags;
+       spin_lock_irqsave(&t->buf.lock, flags);
+       if (t->buf.tail != NULL)
+               t->buf.tail->active = 0;
+       spin_unlock_irqrestore(&t->buf.lock, flags);
        schedule_work(&t->buf.work);
 }
 
index 945daa1f13dd05d6a7ad95e6022108a824d6a3dd..47208bd99f9e1c2ef6753e4b7d56739691531576 100644 (file)
@@ -34,9 +34,11 @@ struct list_head {
 #define LIST_HEAD(name) \
        struct list_head name = LIST_HEAD_INIT(name)
 
-#define INIT_LIST_HEAD(ptr) do { \
-       (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+       list->next = list;
+       list->prev = list;
+}
 
 /*
  * Insert a new entry between two known consecutive entries.
@@ -534,7 +536,11 @@ struct hlist_node {
 #define HLIST_HEAD_INIT { .first = NULL }
 #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
+static inline void INIT_HLIST_NODE(struct hlist_node *h)
+{
+       h->next = NULL;
+       h->pprev = NULL;
+}
 
 static inline int hlist_unhashed(const struct hlist_node *h)
 {
index 95c8fea293baa8e9e413420adca449e02fd6507f..920766cea79cbc15634411e4c9633c27f6c8fd61 100644 (file)
@@ -84,6 +84,7 @@ struct nlm_rqst {
        struct nlm_args         a_args;         /* arguments */
        struct nlm_res          a_res;          /* result */
        struct nlm_wait *       a_block;
+       unsigned int            a_retries;      /* Retry count */
        char                    a_owner[NLMCLNT_OHSIZE];
 };
 
@@ -148,7 +149,6 @@ struct nlm_rqst * nlmclnt_alloc_call(void);
 int              nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl);
 void             nlmclnt_finish_block(struct nlm_rqst *req);
 long             nlmclnt_block(struct nlm_rqst *req, long timeout);
-int              nlmclnt_cancel(struct nlm_host *, struct file_lock *);
 u32              nlmclnt_grant(struct nlm_lock *);
 void             nlmclnt_recovery(struct nlm_host *, u32);
 int              nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
index 85854b867463484cf1cc1c7fe76ae5c4f5ca4201..75e9f0724997e631806ceb7dd3733dfd7b2d8cc1 100644 (file)
@@ -303,7 +303,7 @@ struct page {
  */
 #define put_page_testzero(p)                           \
        ({                                              \
-               BUG_ON(page_count(p) == 0);             \
+               BUG_ON(atomic_read(&(p)->_count) == -1);\
                atomic_add_negative(-1, &(p)->_count);  \
        })
 
index ccd3e13de1e82eff1730a7cb17f57a4e9e8b4b56..f38872abc12669e0d08e53ac7da62ceedad01306 100644 (file)
@@ -21,24 +21,35 @@ struct mmc_command {
        u32                     arg;
        u32                     resp[4];
        unsigned int            flags;          /* expected response type */
-#define MMC_RSP_NONE   (0 << 0)
-#define MMC_RSP_SHORT  (1 << 0)
-#define MMC_RSP_LONG   (2 << 0)
-#define MMC_RSP_MASK   (3 << 0)
-#define MMC_RSP_CRC    (1 << 3)                /* expect valid crc */
-#define MMC_RSP_BUSY   (1 << 4)                /* card may send busy */
-#define MMC_RSP_OPCODE (1 << 5)                /* response contains opcode */
+#define MMC_RSP_PRESENT        (1 << 0)
+#define MMC_RSP_136    (1 << 1)                /* 136 bit response */
+#define MMC_RSP_CRC    (1 << 2)                /* expect valid crc */
+#define MMC_RSP_BUSY   (1 << 3)                /* card may send busy */
+#define MMC_RSP_OPCODE (1 << 4)                /* response contains opcode */
+#define MMC_CMD_MASK   (3 << 5)                /* command type */
+#define MMC_CMD_AC     (0 << 5)
+#define MMC_CMD_ADTC   (1 << 5)
+#define MMC_CMD_BC     (2 << 5)
+#define MMC_CMD_BCR    (3 << 5)
 
 /*
  * These are the response types, and correspond to valid bit
  * patterns of the above flags.  One additional valid pattern
  * is all zeros, which means we don't expect a response.
  */
-#define MMC_RSP_R1     (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE)
-#define MMC_RSP_R1B    (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
-#define MMC_RSP_R2     (MMC_RSP_LONG|MMC_RSP_CRC)
-#define MMC_RSP_R3     (MMC_RSP_SHORT)
-#define MMC_RSP_R6     (MMC_RSP_SHORT|MMC_RSP_CRC)
+#define MMC_RSP_NONE   (0)
+#define MMC_RSP_R1     (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1B    (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
+#define MMC_RSP_R2     (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3     (MMC_RSP_PRESENT)
+#define MMC_RSP_R6     (MMC_RSP_PRESENT|MMC_RSP_CRC)
+
+#define mmc_resp_type(cmd)     ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
+
+/*
+ * These are the command types.
+ */
+#define mmc_cmd_type(cmd)      ((cmd)->flags & MMC_CMD_TYPE)
 
        unsigned int            retries;        /* max number of retries */
        unsigned int            error;          /* command error */
index a14dc306545b86f2f353d4ab2022523264109a51..81c3f77f652c95f6ec9ba8efee8450dc4e501a8f 100644 (file)
@@ -79,7 +79,7 @@
 /* SD commands                           type  argument     response */
   /* class 8 */
 /* This is basically the same command as for MMC with some quirks. */
-#define SD_SEND_RELATIVE_ADDR     3   /* ac                      R6  */
+#define SD_SEND_RELATIVE_ADDR     3   /* bcr                     R6  */
 
   /* Application commands */
 #define SD_APP_SET_BUS_WIDTH      6   /* ac   [1:0] bus width    R1  */
index fedfbc8a287ff64228dee5a0f9fe551026988ea0..7dfd6e1fcde787f785442b71ca974d4fbbf5a782 100644 (file)
@@ -15,7 +15,6 @@
 #include <asm/unaligned.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
 #define map_bankwidth(map) 1
index 6731977c4c13a00e39a251a12d7be31311960062..3abc8e3b4879a5eac2dd54374f0fb9b37ca9f3a7 100644 (file)
@@ -15,6 +15,7 @@ struct namespace {
 
 extern int copy_namespace(int, struct task_struct *);
 extern void __put_namespace(struct namespace *namespace);
+extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *);
 
 static inline void put_namespace(struct namespace *namespace)
 {
index b04dfa3083c9527d59ceec1e6fe095ed63ebecde..f63e6ee911130b9b30204980459ccddd2d005279 100644 (file)
@@ -1,10 +1,10 @@
 #ifndef _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
 
-#include <net/netfilter/xt_connbytes.h>
+#include <linux/netfilter/xt_connbytes.h>
 #define ipt_connbytes_what xt_connbytes_what
 
-#define IPT_CONNBYTES_PKTS     XT_CONNBYTES_PACKETS
+#define IPT_CONNBYTES_PKTS     XT_CONNBYTES_PKTS
 #define IPT_CONNBYTES_BYTES    XT_CONNBYTES_BYTES
 #define IPT_CONNBYTES_AVGPKT   XT_CONNBYTES_AVGPKT
 
index 7fd1bec453f181130f0a92caf8ac6b3d3d5e43ce..a3f6eff39d335c71abc26cbb227528c7d9bd119a 100644 (file)
@@ -27,16 +27,22 @@ struct ipt_policy_spec
                        reqid:1;
 };
 
+union ipt_policy_addr
+{
+       struct in_addr  a4;
+       struct in6_addr a6;
+};
+
 struct ipt_policy_elem
 {
-       u_int32_t       saddr;
-       u_int32_t       smask;
-       u_int32_t       daddr;
-       u_int32_t       dmask;
-       u_int32_t       spi;
-       u_int32_t       reqid;
-       u_int8_t        proto;
-       u_int8_t        mode;
+       union ipt_policy_addr   saddr;
+       union ipt_policy_addr   smask;
+       union ipt_policy_addr   daddr;
+       union ipt_policy_addr   dmask;
+       u_int32_t               spi;
+       u_int32_t               reqid;
+       u_int8_t                proto;
+       u_int8_t                mode;
 
        struct ipt_policy_spec  match;
        struct ipt_policy_spec  invert;
index 5a93afcd2ff1ea7f3d15424cef7eec67795572a7..671bd818300fa167e8f12b6d584fba7fc292cab6 100644 (file)
@@ -27,16 +27,22 @@ struct ip6t_policy_spec
                        reqid:1;
 };
 
+union ip6t_policy_addr
+{
+       struct in_addr  a4;
+       struct in6_addr a6;
+};
+
 struct ip6t_policy_elem
 {
-       struct in6_addr saddr;
-       struct in6_addr smask;
-       struct in6_addr daddr;
-       struct in6_addr dmask;
-       u_int32_t       spi;
-       u_int32_t       reqid;
-       u_int8_t        proto;
-       u_int8_t        mode;
+       union ip6t_policy_addr  saddr;
+       union ip6t_policy_addr  smask;
+       union ip6t_policy_addr  daddr;
+       union ip6t_policy_addr  dmask;
+       u_int32_t               spi;
+       u_int32_t               reqid;
+       u_int8_t                proto;
+       u_int8_t                mode;
 
        struct ip6t_policy_spec match;
        struct ip6t_policy_spec invert;
index 4726ef7ba8e8e2fe35d03ef68184173320374ef4..b959a4525cbd31df6999237544583e3fd403441a 100644 (file)
@@ -84,7 +84,6 @@
 #include <linux/threads.h>
 #include <linux/bitmap.h>
 #include <linux/numa.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
 extern nodemask_t _unused_nodemask_arg_;
index f67f838a3a1f27390711aa90259723ea951f771a..008d736a6c9a59766a7a4114223fd8bddc456ecc 100644 (file)
@@ -128,6 +128,11 @@ struct amiga_parport_state {
        unsigned char statusdir;/* ciab.ddrb & 7 */
 };
 
+struct ip32_parport_state {
+       unsigned int dcr;
+       unsigned int ecr;
+};
+
 struct parport_state {
        union {
                struct pc_parport_state pc;
@@ -135,6 +140,7 @@ struct parport_state {
                struct ax_parport_state ax;
                struct amiga_parport_state amiga;
                /* Atari has not state. */
+               struct ip32_parport_state ip32;
                void *misc; 
        } u;
 };
index b0b908f583c58a38a614e6e51f30d71ae43d9508..7a61ccdcbc4bcb98aae1ca93f00227541dabdf4e 100644 (file)
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_550        0x2060
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_650        0x2061
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_850        0x2062
+#define PCI_DEVICE_ID_SIIG_8S_20x_550  0x2080
+#define PCI_DEVICE_ID_SIIG_8S_20x_650  0x2081
+#define PCI_DEVICE_ID_SIIG_8S_20x_850  0x2082
 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL   0x2050
 
 #define PCI_VENDOR_ID_RADISYS          0x1331
 #define PCI_VENDOR_ID_AFAVLAB          0x14db
 #define PCI_DEVICE_ID_AFAVLAB_P028     0x2180
 #define PCI_DEVICE_ID_AFAVLAB_P030     0x2182
+#define PCI_SUBDEVICE_ID_AFAVLAB_P061          0x2150
 
 #define PCI_VENDOR_ID_BROADCOM         0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752      0x1600
index 2c177e4c8f226d50803162dcb421beb629d4cbd3..8a94c717c26636fb6e21f54db6c1c63e1a066f2d 100644 (file)
@@ -114,7 +114,7 @@ struct pkt_ctrl_command {
 
 struct packet_settings
 {
-       __u                   size;           /* packet size in (512 byte) sectors */
+       __u32                   size;           /* packet size in (512 byte) sectors */
        __u8                    fp;             /* fixed packets */
        __u8                    link_loss;      /* the rest is specified
                                                 * as per Mt Fuji */
@@ -169,8 +169,8 @@ struct packet_iosched
 #if (PAGE_SIZE % CD_FRAMESIZE) != 0
 #error "PAGE_SIZE must be a multiple of CD_FRAMESIZE"
 #endif
-#define PACKET_MAX_SIZE                32
-#define PAGES_PER_PACKET       (PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE)
+#define PACKET_MAX_SIZE                128
+#define FRAMES_PER_PAGE                (PAGE_SIZE / CD_FRAMESIZE)
 #define PACKET_MAX_SECTORS     (PACKET_MAX_SIZE * CD_FRAMESIZE >> 9)
 
 enum packet_data_state {
@@ -219,7 +219,7 @@ struct packet_data
        atomic_t                io_errors;      /* Number of read/write errors during IO */
 
        struct bio              *r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */
-       struct page             *pages[PAGES_PER_PACKET];
+       struct page             *pages[PACKET_MAX_SIZE / FRAMES_PER_PAGE];
 
        int                     cache_valid;    /* If non-zero, the data for the zone defined */
                                                /* by the sector variable is completely cached */
index 4f34d3d60f2ed6485d450bd4ca06cbea450e6997..21e5a9124856bbcc6a2c2c3cdf02fff4a56d62d3 100644 (file)
@@ -190,7 +190,6 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
  */
 #define sb_dquot_ops                           (NULL)
 #define sb_quotactl_ops                                (NULL)
-#define sync_dquots_dev(dev,type)              (NULL)
 #define DQUOT_INIT(inode)                      do { } while(0)
 #define DQUOT_DROP(inode)                      do { } while(0)
 #define DQUOT_ALLOC_INODE(inode)               (0)
index 981f9aa433538a8ec2e8b0142da769b2e5a4dd87..b87aefa082e2b69c868f673946dd1cbc16610a51 100644 (file)
@@ -240,11 +240,14 @@ extern int rcu_pending(int cpu);
  * This means that all preempt_disable code sequences, including NMI and
  * hardware-interrupt handlers, in progress on entry will have completed
  * before this primitive returns.  However, this does not guarantee that
- * softirq handlers will have completed, since in some kernels
+ * softirq handlers will have completed, since in some kernels, these
+ * handlers can run in process context, and can block.
  *
  * This primitive provides the guarantees made by the (deprecated)
  * synchronize_kernel() API.  In contrast, synchronize_rcu() only
  * guarantees that rcu_read_lock() sections will have completed.
+ * In "classic RCU", these two guarantees happen to be one and
+ * the same, but can differ in realtime RCU implementations.
  */
 #define synchronize_sched() synchronize_rcu()
 
index 0a3605099c444c2617a5ef43232c0382e4bfb75d..806ec5b067075554792d5631996b24595157d697 100644 (file)
@@ -58,9 +58,13 @@ extern struct reiserfs_xattr_handler posix_acl_default_handler;
 extern struct reiserfs_xattr_handler posix_acl_access_handler;
 #else
 
-#define reiserfs_get_acl NULL
 #define reiserfs_cache_default_acl(inode) 0
 
+static inline struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
+{
+       return NULL;
+}
+
 static inline int reiserfs_xattr_posix_acl_init(void)
 {
        return 0;
index bb1da86747c701f410d7222e4c09f8a7e7bc9670..7cbef482e13aac4b74d66e86afa65ba1ece22d8d 100644 (file)
@@ -1499,15 +1499,11 @@ static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
 
 static inline int security_inode_alloc (struct inode *inode)
 {
-       if (unlikely (IS_PRIVATE (inode)))
-               return 0;
        return security_ops->inode_alloc_security (inode);
 }
 
 static inline void security_inode_free (struct inode *inode)
 {
-       if (unlikely (IS_PRIVATE (inode)))
-               return;
        security_ops->inode_free_security (inode);
 }
 
index 9dfa3ee769ae2c02846a19a8f4a7b727a78baf33..44153fdf73fc0787072b21c043713f0fb62815a5 100644 (file)
@@ -17,7 +17,6 @@ extern void cpu_idle(void);
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
 #include <asm/smp.h>
-#include <asm/bug.h>
 
 /*
  * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
index b68c11a2d6dd912274b146df30d17bc4045800a9..be4772ed43c005add341102aaae7dcd15d1ed818 100644 (file)
@@ -48,7 +48,7 @@ struct rpc_cred {
 
        /* per-flavor data */
 };
-#define RPCAUTH_CRED_LOCKED    0x0001
+#define RPCAUTH_CRED_NEW       0x0001
 #define RPCAUTH_CRED_UPTODATE  0x0002
 
 #define RPCAUTH_CRED_MAGIC     0x0f4aa4f0
@@ -83,9 +83,10 @@ struct rpc_auth {
        struct rpc_cred_cache * au_credcache;
        /* per-flavor data */
 };
-#define RPC_AUTH_PROC_CREDS    0x0010          /* process creds (including
-                                                * uid/gid, fs[ug]id, gids)
-                                                */
+
+/* Flags for rpcauth_lookupcred() */
+#define RPCAUTH_LOOKUP_NEW             0x01    /* Accept an uninitialised cred */
+#define RPCAUTH_LOOKUP_ROOTCREDS       0x02    /* This really ought to go! */
 
 /*
  * Client authentication ops
@@ -105,6 +106,7 @@ struct rpc_authops {
 
 struct rpc_credops {
        const char *            cr_name;        /* Name of the auth flavour */
+       int                     (*cr_init)(struct rpc_auth *, struct rpc_cred *);
        void                    (*crdestroy)(struct rpc_cred *);
 
        int                     (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
index 5dc94e777fab926d408477dbea464a3c78bcd3fd..37c1c76fd5472f7aafdbee3a7f36e6806a7e3468 100644 (file)
@@ -43,16 +43,20 @@ extern void mark_free_pages(struct zone *zone);
 /* kernel/power/swsusp.c */
 extern int software_suspend(void);
 
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
 extern int pm_prepare_console(void);
 extern void pm_restore_console(void);
-
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */
 #else
 static inline int software_suspend(void)
 {
        printk("Warning: fake suspend called\n");
        return -EPERM;
 }
-#endif
+#endif /* CONFIG_PM */
 
 #ifdef CONFIG_SUSPEND_SMP
 extern void disable_nonboot_cpus(void);
index 3787102e4b129abe52f3b53461ff1e7fffb33b40..a7bd3b4558d26efaa3ed8dae0b5bb53f0d184cab 100644 (file)
@@ -57,6 +57,7 @@ struct tty_buffer {
        unsigned char *flag_buf_ptr;
        int used;
        int size;
+       int active;
        /* Data points here */
        unsigned long data[0];
 };
@@ -64,6 +65,7 @@ struct tty_buffer {
 struct tty_bufhead {
        struct work_struct              work;
        struct semaphore pty_sem;
+       spinlock_t lock;
        struct tty_buffer *head;        /* Queue head */
        struct tty_buffer *tail;        /* Active buffer */
        struct tty_buffer *free;        /* Free queue head */
index be1400e82482f8aebd4d14e17e9d5ea99958cd85..82961eb1988861a08c6c459d3d095a1535bf52fb 100644 (file)
@@ -17,7 +17,7 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
                                   unsigned char ch, char flag)
 {
        struct tty_buffer *tb = tty->buf.tail;
-       if (tb && tb->used < tb->size) {
+       if (tb && tb->active && tb->used < tb->size) {
                tb->flag_buf_ptr[tb->used] = flag;
                tb->char_buf_ptr[tb->used++] = ch;
                return 1;
@@ -27,6 +27,11 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
 
 _INLINE_ void tty_schedule_flip(struct tty_struct *tty)
 {
+       unsigned long flags;
+       spin_lock_irqsave(&tty->buf.lock, flags);
+       if (tty->buf.tail != NULL)
+               tty->buf.tail->active = 0;
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
        schedule_delayed_work(&tty->buf.work, 1);
 }
 
index 7a6babeca25619fdadfe639f5c9696822c7341e0..b0ffe4356e5a60c8a7e74101ae45053fcc44b8d6 100644 (file)
@@ -148,11 +148,11 @@ typedef __u16 __bitwise __fs16;
 #define UFS_USEEFT  ((__u16)65535)
 
 #define UFS_FSOK      0x7c269d38
-#define UFS_FSACTIVE  ((char)0x00)
-#define UFS_FSCLEAN   ((char)0x01)
-#define UFS_FSSTABLE  ((char)0x02)
-#define UFS_FSOSF1    ((char)0x03)     /* is this correct for DEC OSF/1? */
-#define UFS_FSBAD     ((char)0xff)
+#define UFS_FSACTIVE  ((__s8)0x00)
+#define UFS_FSCLEAN   ((__s8)0x01)
+#define UFS_FSSTABLE  ((__s8)0x02)
+#define UFS_FSOSF1    ((__s8)0x03)     /* is this correct for DEC OSF/1? */
+#define UFS_FSBAD     ((__s8)0xff)
 
 /* From here to next blank line, s_flags for ufs_sb_info */
 /* directory entry encoding */
@@ -502,8 +502,7 @@ struct ufs_super_block {
 /*
  * Convert cylinder group to base address of its global summary info.
  */
-#define fs_cs(indx) \
-       s_csp[(indx) >> uspi->s_csshift][(indx) & ~uspi->s_csmask]
+#define fs_cs(indx) s_csp[(indx)]
 
 /*
  * Cylinder group block for a file system.
@@ -913,6 +912,7 @@ extern int ufs_sync_inode (struct inode *);
 extern void ufs_delete_inode (struct inode *);
 extern struct buffer_head * ufs_getfrag (struct inode *, unsigned, int, int *);
 extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
+extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create);
 
 /* namei.c */
 extern struct file_operations ufs_dir_operations;
index c1be4c2264862e0f768b6d1cc129eab37bea3400..8ff13c160f3d6a6bcba70055ccbec0d26d882317 100644 (file)
@@ -25,7 +25,7 @@ struct ufs_csum;
 
 struct ufs_sb_info {
        struct ufs_sb_private_info * s_uspi;    
-       struct ufs_csum * s_csp[UFS_MAXCSBUFS];
+       struct ufs_csum * s_csp;
        unsigned s_bytesex;
        unsigned s_flags;
        struct buffer_head ** s_ucg;
index 6f6c69777648f0f72f41a55fc1f79092a15092e1..5208b12d555095cb2d246728aca9b649093b724d 100644 (file)
@@ -549,7 +549,7 @@ struct v4l2_framebuffer
 struct v4l2_clip
 {
        struct v4l2_rect        c;
-       struct v4l2_clip        *next;
+       struct v4l2_clip        __user *next;
 };
 
 struct v4l2_window
@@ -629,6 +629,7 @@ typedef __u64 v4l2_std_id;
 #define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
 #define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
 #define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
 
 #define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
 #define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
@@ -661,7 +662,8 @@ typedef __u64 v4l2_std_id;
                                 V4L2_STD_PAL_H         |\
                                 V4L2_STD_PAL_I)
 #define V4L2_STD_NTSC           (V4L2_STD_NTSC_M       |\
-                                V4L2_STD_NTSC_M_JP)
+                                V4L2_STD_NTSC_M_JP     |\
+                                V4L2_STD_NTSC_M_KR)
 #define V4L2_STD_SECAM_DK              (V4L2_STD_SECAM_D       |\
                                 V4L2_STD_SECAM_K       |\
                                 V4L2_STD_SECAM_K1)
index 67856eb93b435093807db606e220ce575988571f..dac43b15a5b04bf6b5c90fc07aabf033a717d1cb 100644 (file)
@@ -88,12 +88,6 @@ extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
 extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
 extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 
-static inline struct nf_conntrack_l3proto *
-__nf_ct_l3proto_find(u_int16_t l3proto)
-{
-       return nf_ct_l3protos[l3proto];
-}
-
 extern struct nf_conntrack_l3proto *
 nf_ct_l3proto_find_get(u_int16_t l3proto);
 
@@ -103,4 +97,13 @@ extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
 extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
+
+static inline struct nf_conntrack_l3proto *
+__nf_ct_l3proto_find(u_int16_t l3proto)
+{
+       if (unlikely(l3proto >= AF_MAX))
+               return &nf_conntrack_generic_l3proto;
+       return nf_ct_l3protos[l3proto];
+}
+
 #endif /*_NF_CONNTRACK_L3PROTO_H*/
index 8c522ae031bbf5a3011212e00f16289b06e6648c..072f407848a6fe1464a77a4d2bd1f47a052e6e40 100644 (file)
@@ -700,7 +700,7 @@ struct sctp_chunk {
        __u8 ecn_ce_done;       /* Have we processed the ECN CE bit? */
        __u8 pdiscard;          /* Discard the whole packet now? */
        __u8 tsn_gap_acked;     /* Is this chunk acked by a GAP ACK? */
-       __u8 fast_retransmit;    /* Is this chunk fast retransmitted? */
+       __s8 fast_retransmit;    /* Is this chunk fast retransmitted? */
        __u8 tsn_missing_report; /* Data chunk missing counter. */
 };
 
index 1806e5b6141936376352373343c3a37510af6bbf..30758035d6161b13eb7b6715978340d28058bb3f 100644 (file)
@@ -1354,12 +1354,12 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *);
  *     Enable debug/info messages 
  */
 
-#if 0
-#define NETDEBUG(fmt, args...) do { } while (0)
-#define LIMIT_NETDEBUG(fmt, args...) do { } while(0)
-#else
+#ifdef CONFIG_NETDEBUG
 #define NETDEBUG(fmt, args...) printk(fmt,##args)
 #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0)
+#else
+#define NETDEBUG(fmt, args...) do { } while (0)
+#define LIMIT_NETDEBUG(fmt, args...) do { } while(0)
 #endif
 
 /*
index b9923b1434a2f82a698c5011fbe55191bddf8965..38416a199def24332f22692e9da1203a962a8d58 100644 (file)
@@ -31,19 +31,8 @@ config EXPERIMENTAL
          you say Y here, you will be offered the choice of using features or
          drivers that are currently considered to be in the alpha-test phase.
 
-config CLEAN_COMPILE
-       bool "Select only drivers expected to compile cleanly" if EXPERIMENTAL
-       default y
-       help
-         Select this option if you don't even want to see the option
-         to configure known-broken drivers.
-
-         If unsure, say Y
-
 config BROKEN
        bool
-       depends on !CLEAN_COMPILE
-       default y
 
 config BROKEN_ON_SMP
        bool
@@ -180,7 +169,6 @@ config SYSCTL
 config AUDIT
        bool "Auditing support"
        depends on NET
-       default y if SECURITY_SELINUX
        help
          Enable auditing infrastructure that can be used with another
          kernel subsystem, such as SELinux (which requires this for
index 1867290c37e3c164c916e0471c64c0c6e5528a97..8c9cd88b6785fb72abcde1d848822c6bdb4541e7 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/security.h>
 
 #include <asm/uaccess.h>
-#include <asm/bug.h>
 
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
index fe2f71f92ae0b01fbbfe08053bb34e36058e85de..ba42b0a76961f8eb3b667bf4a059405e3b9f52cf 100644 (file)
@@ -641,7 +641,7 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
  * task has been modifying its cpuset.
  */
 
-void cpuset_update_task_memory_state()
+void cpuset_update_task_memory_state(void)
 {
        int my_cpusets_mem_gen;
        struct task_struct *tsk = current;
index 7f0ab5ee948c633a8065e685a5147e0df3d439ad..8e88b374cee90b646234d7cfa64b108c8ab9bbe2 100644 (file)
@@ -446,6 +446,55 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
        }
 }
 
+/*
+ * Allocate a new mm structure and copy contents from the
+ * mm structure of the passed in task structure.
+ */
+static struct mm_struct *dup_mm(struct task_struct *tsk)
+{
+       struct mm_struct *mm, *oldmm = current->mm;
+       int err;
+
+       if (!oldmm)
+               return NULL;
+
+       mm = allocate_mm();
+       if (!mm)
+               goto fail_nomem;
+
+       memcpy(mm, oldmm, sizeof(*mm));
+
+       if (!mm_init(mm))
+               goto fail_nomem;
+
+       if (init_new_context(tsk, mm))
+               goto fail_nocontext;
+
+       err = dup_mmap(mm, oldmm);
+       if (err)
+               goto free_pt;
+
+       mm->hiwater_rss = get_mm_rss(mm);
+       mm->hiwater_vm = mm->total_vm;
+
+       return mm;
+
+free_pt:
+       mmput(mm);
+
+fail_nomem:
+       return NULL;
+
+fail_nocontext:
+       /*
+        * If init_new_context() failed, we cannot use mmput() to free the mm
+        * because it calls destroy_context()
+        */
+       mm_free_pgd(mm);
+       free_mm(mm);
+       return NULL;
+}
+
 static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
 {
        struct mm_struct * mm, *oldmm;
@@ -473,43 +522,17 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
        }
 
        retval = -ENOMEM;
-       mm = allocate_mm();
+       mm = dup_mm(tsk);
        if (!mm)
                goto fail_nomem;
 
-       /* Copy the current MM stuff.. */
-       memcpy(mm, oldmm, sizeof(*mm));
-       if (!mm_init(mm))
-               goto fail_nomem;
-
-       if (init_new_context(tsk,mm))
-               goto fail_nocontext;
-
-       retval = dup_mmap(mm, oldmm);
-       if (retval)
-               goto free_pt;
-
-       mm->hiwater_rss = get_mm_rss(mm);
-       mm->hiwater_vm = mm->total_vm;
-
 good_mm:
        tsk->mm = mm;
        tsk->active_mm = mm;
        return 0;
 
-free_pt:
-       mmput(mm);
 fail_nomem:
        return retval;
-
-fail_nocontext:
-       /*
-        * If init_new_context() failed, we cannot use mmput() to free the mm
-        * because it calls destroy_context()
-        */
-       mm_free_pgd(mm);
-       free_mm(mm);
-       return retval;
 }
 
 static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
@@ -597,32 +620,17 @@ out:
        return newf;
 }
 
-static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+/*
+ * Allocate a new files structure and copy contents from the
+ * passed in files structure.
+ */
+static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 {
-       struct files_struct *oldf, *newf;
+       struct files_struct *newf;
        struct file **old_fds, **new_fds;
-       int open_files, size, i, error = 0, expand;
+       int open_files, size, i, expand;
        struct fdtable *old_fdt, *new_fdt;
 
-       /*
-        * A background process may not have any files ...
-        */
-       oldf = current->files;
-       if (!oldf)
-               goto out;
-
-       if (clone_flags & CLONE_FILES) {
-               atomic_inc(&oldf->count);
-               goto out;
-       }
-
-       /*
-        * Note: we may be using current for both targets (See exec.c)
-        * This works because we cache current->files (old) as oldf. Don't
-        * break this.
-        */
-       tsk->files = NULL;
-       error = -ENOMEM;
        newf = alloc_files();
        if (!newf)
                goto out;
@@ -651,9 +659,9 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
        if (expand) {
                spin_unlock(&oldf->file_lock);
                spin_lock(&newf->file_lock);
-               error = expand_files(newf, open_files-1);
+               *errorp = expand_files(newf, open_files-1);
                spin_unlock(&newf->file_lock);
-               if (error < 0)
+               if (*errorp < 0)
                        goto out_release;
                new_fdt = files_fdtable(newf);
                /*
@@ -702,10 +710,8 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
                memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
        }
 
-       tsk->files = newf;
-       error = 0;
 out:
-       return error;
+       return newf;
 
 out_release:
        free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
@@ -715,6 +721,40 @@ out_release:
        goto out;
 }
 
+static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+{
+       struct files_struct *oldf, *newf;
+       int error = 0;
+
+       /*
+        * A background process may not have any files ...
+        */
+       oldf = current->files;
+       if (!oldf)
+               goto out;
+
+       if (clone_flags & CLONE_FILES) {
+               atomic_inc(&oldf->count);
+               goto out;
+       }
+
+       /*
+        * Note: we may be using current for both targets (See exec.c)
+        * This works because we cache current->files (old) as oldf. Don't
+        * break this.
+        */
+       tsk->files = NULL;
+       error = -ENOMEM;
+       newf = dup_fd(oldf, &error);
+       if (!newf)
+               goto out;
+
+       tsk->files = newf;
+       error = 0;
+out:
+       return error;
+}
+
 /*
  *     Helper to unshare the files of the current task.
  *     We don't want to expose copy_files internals to
@@ -1323,3 +1363,249 @@ void __init proc_caches_init(void)
                        sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
                        SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
 }
+
+
+/*
+ * Check constraints on flags passed to the unshare system call and
+ * force unsharing of additional process context as appropriate.
+ */
+static inline void check_unshare_flags(unsigned long *flags_ptr)
+{
+       /*
+        * If unsharing a thread from a thread group, must also
+        * unshare vm.
+        */
+       if (*flags_ptr & CLONE_THREAD)
+               *flags_ptr |= CLONE_VM;
+
+       /*
+        * If unsharing vm, must also unshare signal handlers.
+        */
+       if (*flags_ptr & CLONE_VM)
+               *flags_ptr |= CLONE_SIGHAND;
+
+       /*
+        * If unsharing signal handlers and the task was created
+        * using CLONE_THREAD, then must unshare the thread
+        */
+       if ((*flags_ptr & CLONE_SIGHAND) &&
+           (atomic_read(&current->signal->count) > 1))
+               *flags_ptr |= CLONE_THREAD;
+
+       /*
+        * If unsharing namespace, must also unshare filesystem information.
+        */
+       if (*flags_ptr & CLONE_NEWNS)
+               *flags_ptr |= CLONE_FS;
+}
+
+/*
+ * Unsharing of tasks created with CLONE_THREAD is not supported yet
+ */
+static int unshare_thread(unsigned long unshare_flags)
+{
+       if (unshare_flags & CLONE_THREAD)
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Unshare the filesystem structure if it is being shared
+ */
+static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+{
+       struct fs_struct *fs = current->fs;
+
+       if ((unshare_flags & CLONE_FS) &&
+           (fs && atomic_read(&fs->count) > 1)) {
+               *new_fsp = __copy_fs_struct(current->fs);
+               if (!*new_fsp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unshare the namespace structure if it is being shared
+ */
+static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
+{
+       struct namespace *ns = current->namespace;
+
+       if ((unshare_flags & CLONE_NEWNS) &&
+           (ns && atomic_read(&ns->count) > 1)) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               *new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs);
+               if (!*new_nsp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unsharing of sighand for tasks created with CLONE_SIGHAND is not
+ * supported yet
+ */
+static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
+{
+       struct sighand_struct *sigh = current->sighand;
+
+       if ((unshare_flags & CLONE_SIGHAND) &&
+           (sigh && atomic_read(&sigh->count) > 1))
+               return -EINVAL;
+       else
+               return 0;
+}
+
+/*
+ * Unshare vm if it is being shared
+ */
+static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp)
+{
+       struct mm_struct *mm = current->mm;
+
+       if ((unshare_flags & CLONE_VM) &&
+           (mm && atomic_read(&mm->mm_users) > 1)) {
+               *new_mmp = dup_mm(current);
+               if (!*new_mmp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unshare file descriptor table if it is being shared
+ */
+static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
+{
+       struct files_struct *fd = current->files;
+       int error = 0;
+
+       if ((unshare_flags & CLONE_FILES) &&
+           (fd && atomic_read(&fd->count) > 1)) {
+               *new_fdp = dup_fd(fd, &error);
+               if (!*new_fdp)
+                       return error;
+       }
+
+       return 0;
+}
+
+/*
+ * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not
+ * supported yet
+ */
+static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp)
+{
+       if (unshare_flags & CLONE_SYSVSEM)
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * unshare allows a process to 'unshare' part of the process
+ * context which was originally shared using clone.  copy_*
+ * functions used by do_fork() cannot be used here directly
+ * because they modify an inactive task_struct that is being
+ * constructed. Here we are modifying the current, active,
+ * task_struct.
+ */
+asmlinkage long sys_unshare(unsigned long unshare_flags)
+{
+       int err = 0;
+       struct fs_struct *fs, *new_fs = NULL;
+       struct namespace *ns, *new_ns = NULL;
+       struct sighand_struct *sigh, *new_sigh = NULL;
+       struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
+       struct files_struct *fd, *new_fd = NULL;
+       struct sem_undo_list *new_ulist = NULL;
+
+       check_unshare_flags(&unshare_flags);
+
+       if ((err = unshare_thread(unshare_flags)))
+               goto bad_unshare_out;
+       if ((err = unshare_fs(unshare_flags, &new_fs)))
+               goto bad_unshare_cleanup_thread;
+       if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs)))
+               goto bad_unshare_cleanup_fs;
+       if ((err = unshare_sighand(unshare_flags, &new_sigh)))
+               goto bad_unshare_cleanup_ns;
+       if ((err = unshare_vm(unshare_flags, &new_mm)))
+               goto bad_unshare_cleanup_sigh;
+       if ((err = unshare_fd(unshare_flags, &new_fd)))
+               goto bad_unshare_cleanup_vm;
+       if ((err = unshare_semundo(unshare_flags, &new_ulist)))
+               goto bad_unshare_cleanup_fd;
+
+       if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+
+               task_lock(current);
+
+               if (new_fs) {
+                       fs = current->fs;
+                       current->fs = new_fs;
+                       new_fs = fs;
+               }
+
+               if (new_ns) {
+                       ns = current->namespace;
+                       current->namespace = new_ns;
+                       new_ns = ns;
+               }
+
+               if (new_sigh) {
+                       sigh = current->sighand;
+                       current->sighand = new_sigh;
+                       new_sigh = sigh;
+               }
+
+               if (new_mm) {
+                       mm = current->mm;
+                       active_mm = current->active_mm;
+                       current->mm = new_mm;
+                       current->active_mm = new_mm;
+                       activate_mm(active_mm, new_mm);
+                       new_mm = mm;
+               }
+
+               if (new_fd) {
+                       fd = current->files;
+                       current->files = new_fd;
+                       new_fd = fd;
+               }
+
+               task_unlock(current);
+       }
+
+bad_unshare_cleanup_fd:
+       if (new_fd)
+               put_files_struct(new_fd);
+
+bad_unshare_cleanup_vm:
+       if (new_mm)
+               mmput(new_mm);
+
+bad_unshare_cleanup_sigh:
+       if (new_sigh)
+               if (atomic_dec_and_test(&new_sigh->count))
+                       kmem_cache_free(sighand_cachep, new_sigh);
+
+bad_unshare_cleanup_ns:
+       if (new_ns)
+               put_namespace(new_ns);
+
+bad_unshare_cleanup_fs:
+       if (new_fs)
+               put_fs_struct(new_fs);
+
+bad_unshare_cleanup_thread:
+bad_unshare_out:
+       return err;
+}
index 0cbe633420fb9b6d46376debb0c68d201a5966d5..55b1e5b85db97fef9b361ba86daee3dab0211f7f 100644 (file)
@@ -179,3 +179,6 @@ EXPORT_SYMBOL(inter_module_register);
 EXPORT_SYMBOL(inter_module_unregister);
 EXPORT_SYMBOL(inter_module_get_request);
 EXPORT_SYMBOL(inter_module_put);
+
+MODULE_LICENSE("GPL");
+
index 3ea6325228dafd293b8421ac4d47ea49457b17a0..fef1af8a73ce07818862eb434c29b62468e99323 100644 (file)
@@ -344,23 +344,6 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
        spin_unlock_irqrestore(&kretprobe_lock, flags);
 }
 
-/*
- * This kprobe pre_handler is registered with every kretprobe. When probe
- * hits it will set up the return probe.
- */
-static int __kprobes pre_handler_kretprobe(struct kprobe *p,
-                                          struct pt_regs *regs)
-{
-       struct kretprobe *rp = container_of(p, struct kretprobe, kp);
-       unsigned long flags = 0;
-
-       /*TODO: consider to only swap the RA after the last pre_handler fired */
-       spin_lock_irqsave(&kretprobe_lock, flags);
-       arch_prepare_kretprobe(rp, regs);
-       spin_unlock_irqrestore(&kretprobe_lock, flags);
-       return 0;
-}
-
 static inline void free_rp_inst(struct kretprobe *rp)
 {
        struct kretprobe_instance *ri;
@@ -578,6 +561,23 @@ void __kprobes unregister_jprobe(struct jprobe *jp)
 
 #ifdef ARCH_SUPPORTS_KRETPROBES
 
+/*
+ * This kprobe pre_handler is registered with every kretprobe. When probe
+ * hits it will set up the return probe.
+ */
+static int __kprobes pre_handler_kretprobe(struct kprobe *p,
+                                          struct pt_regs *regs)
+{
+       struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+       unsigned long flags = 0;
+
+       /*TODO: consider to only swap the RA after the last pre_handler fired */
+       spin_lock_irqsave(&kretprobe_lock, flags);
+       arch_prepare_kretprobe(rp, regs);
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
+       return 0;
+}
+
 int __kprobes register_kretprobe(struct kretprobe *rp)
 {
        int ret = 0;
@@ -631,12 +631,12 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp)
        unregister_kprobe(&rp->kp);
        /* No race here */
        spin_lock_irqsave(&kretprobe_lock, flags);
-       free_rp_inst(rp);
        while ((ri = get_used_rp_inst(rp)) != NULL) {
                ri->rp = NULL;
                hlist_del(&ri->uflist);
        }
        spin_unlock_irqrestore(&kretprobe_lock, flags);
+       free_rp_inst(rp);
 }
 
 static int __init init_kprobes(void)
index 618ed6e23ecccf12b16d9bac17a62510758989be..5aad477ddc79c94567c02e9ee704f1eb71fa1b66 100644 (file)
@@ -1670,6 +1670,9 @@ static struct module *load_module(void __user *umod,
                goto free_mod;
        }
 
+       /* Userspace could have altered the string after the strlen_user() */
+       args[arglen - 1] = '\0';
+
        if (find_module(mod->name)) {
                err = -EEXIST;
                goto free_mod;
@@ -2092,7 +2095,8 @@ static unsigned long mod_find_symname(struct module *mod, const char *name)
        unsigned int i;
 
        for (i = 0; i < mod->num_symtab; i++)
-               if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0)
+               if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 &&
+                   mod->symtab[i].st_info != 'U')
                        return mod->symtab[i].st_value;
        return 0;
 }
index 579d239d129fd5dd03458f8889577400b3b56aa1..623786d4415950b08c8fb6f3461bfb8c86c152b2 100644 (file)
@@ -9,7 +9,9 @@
 #include <linux/console.h>
 #include "power.h"
 
-#ifdef SUSPEND_CONSOLE
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+#define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
+
 static int orig_fgconsole, orig_kmsg;
 
 int pm_prepare_console(void)
index d8f0d1a76bae9fbf18a8c1d20326d9dc20dd232d..388dba68084109af8f51d2da84e355bb40c99b2e 100644 (file)
@@ -1,14 +1,6 @@
 #include <linux/suspend.h>
 #include <linux/utsname.h>
 
-/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but
-   we probably do not take enough locks for switching consoles, etc,
-   so bad things might happen.
-*/
-#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-#define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
-#endif
-
 struct swsusp_info {
        struct new_utsname      uts;
        u32                     version_code;
@@ -42,14 +34,6 @@ static struct subsys_attribute _name##_attr = {      \
 
 extern struct subsystem power_subsys;
 
-#ifdef SUSPEND_CONSOLE
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static int pm_prepare_console(void) { return 0; }
-static void pm_restore_console(void) {}
-#endif
-
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
 
index 59c91c148e82d0f3ddbbea3a0cdf8260702cd9eb..4e90905f0e87ec1e394acc9c61251b0a2505b3ac 100644 (file)
@@ -743,7 +743,6 @@ static int submit(int rw, pgoff_t page_off, void *page)
        if (!bio)
                return -ENOMEM;
        bio->bi_sector = page_off * (PAGE_SIZE >> 9);
-       bio_get(bio);
        bio->bi_bdev = resume_bdev;
        bio->bi_end_io = end_io;
 
@@ -753,14 +752,13 @@ static int submit(int rw, pgoff_t page_off, void *page)
                goto Done;
        }
 
-       if (rw == WRITE)
-               bio_set_pages_dirty(bio);
 
        atomic_set(&io_done, 1);
        submit_bio(rw | (1 << BIO_RW_SYNC), bio);
        while (atomic_read(&io_done))
                yield();
-
+       if (rw == READ)
+               bio_set_pages_dirty(bio);
  Done:
        bio_put(bio);
        return error;
index f77f23f8f479c898666082f3c9da0d52bb5a5bab..bc38804e40ddf72954695470ae50fb3a5c0b82a9 100644 (file)
@@ -5551,13 +5551,15 @@ static void calibrate_migration_costs(const cpumask_t *cpu_map)
                        -1
 #endif
                );
-       printk("migration_cost=");
-       for (distance = 0; distance <= max_distance; distance++) {
-               if (distance)
-                       printk(",");
-               printk("%ld", (long)migration_cost[distance] / 1000);
+       if (system_state == SYSTEM_BOOTING) {
+               printk("migration_cost=");
+               for (distance = 0; distance <= max_distance; distance++) {
+                       if (distance)
+                               printk(",");
+                       printk("%ld", (long)migration_cost[distance] / 1000);
+               }
+               printk("\n");
        }
-       printk("\n");
        j1 = jiffies;
        if (migration_debug)
                printk("migration: %ld seconds\n", (j1-j0)/HZ);
@@ -6109,7 +6111,7 @@ void __init sched_init(void)
        runqueue_t *rq;
        int i, j, k;
 
-       for (i = 0; i < NR_CPUS; i++) {
+       for_each_cpu(i) {
                prio_array_t *array;
 
                rq = cpu_rq(i);
index d3efafd8109a3e4597bf89213d8eaa8fa1852f33..b373fc2420da06d73840fd3694301e504688468f 100644 (file)
@@ -283,7 +283,7 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
        return(q);
 }
 
-static inline void __sigqueue_free(struct sigqueue *q)
+static void __sigqueue_free(struct sigqueue *q)
 {
        if (q->flags & SIGQUEUE_PREALLOC)
                return;
index 0929c698affce76e1d48e52ca456b6c82298f928..f91218a5463e48e9716b3d14a4d54500477c6a6d 100644 (file)
@@ -428,7 +428,7 @@ void kernel_kexec(void)
 {
 #ifdef CONFIG_KEXEC
        struct kimage *image;
-       image = xchg(&kexec_image, 0);
+       image = xchg(&kexec_image, NULL);
        if (!image) {
                return;
        }
index 1f23e683d6aa01da497a86a8cd5ac6804ef5d6fe..804539165d8b1aea0ea0dac3631377d7ae107f89 100644 (file)
@@ -637,15 +637,16 @@ void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
  *
  * Returns the timespec representation of the nsec parameter.
  */
-inline struct timespec ns_to_timespec(const nsec_t nsec)
+struct timespec ns_to_timespec(const nsec_t nsec)
 {
        struct timespec ts;
 
-       if (nsec)
-               ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC,
-                                                    &ts.tv_nsec);
-       else
-               ts.tv_sec = ts.tv_nsec = 0;
+       if (!nsec)
+               return (struct timespec) {0, 0};
+
+       ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec);
+       if (unlikely(nsec < 0))
+               set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec);
 
        return ts;
 }
index 4f1cb0ab5251aed2b690003527a26258e15c49a0..b9dad3994676948f114e757a59f18c29f950e5f7 100644 (file)
@@ -495,7 +495,7 @@ unsigned long next_timer_interrupt(void)
        base = &__get_cpu_var(tvec_bases);
        spin_lock(&base->t_base.lock);
        expires = base->timer_jiffies + (LONG_MAX >> 1);
-       list = 0;
+       list = NULL;
 
        /* Look for timer events in tv1. */
        j = base->timer_jiffies & TVR_MASK;
index a5d2cdc5684cfdf0d2834692c3abc6024da515de..fd355a99327cdeab8333781991ea3ecd59997ca4 100644 (file)
@@ -15,7 +15,7 @@ unsigned long int_sqrt(unsigned long x)
        op = x;
        res = 0;
 
-       one = 1 << 30;
+       one = 1UL << (BITS_PER_LONG - 2);
        while (one > op)
                one >>= 2;
 
index 7a0e6809490d4e17e3d461426371871acefdf4e2..efe67fa96a71647b3af9f6c010fd2abc4a661619 100644 (file)
@@ -72,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj)
         * Add 1 to strlen for leading '/' of each level.
         */
        do {
+               if (kobject_name(parent) == NULL)
+                       return 0;
                length += strlen(kobject_name(parent)) + 1;
                parent = parent->parent;
        } while (parent);
@@ -107,6 +109,8 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
        int len;
 
        len = get_kobj_path_length(kobj);
+       if (len == 0)
+               return NULL;
        path = kmalloc(len, gfp_mask);
        if (!path)
                return NULL;
@@ -162,6 +166,11 @@ int kobject_add(struct kobject * kobj)
                return -ENOENT;
        if (!kobj->k_name)
                kobj->k_name = kobj->name;
+       if (!kobj->k_name) {
+               pr_debug("kobject attempted to be registered with no name!\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
        parent = kobject_get(kobj->parent);
 
        pr_debug("kobject %s: registering. parent: %s, set: %s\n",
index f56e27ae9d528c5a33bf745532ab366e0c7aa005..1b1985c136ec9a00862845f0f516656b2e84b8b0 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/kobject.h>
 #include <net/sock.h>
 
-#define BUFFER_SIZE    1024    /* buffer for the variables */
+#define BUFFER_SIZE    2048    /* buffer for the variables */
 #define NUM_ENVP       32      /* number of env pointers */
 
 #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
index c8bb8cc899d70017111e9388990cc2d76f8b5844..d8b6bb419d49cd9fed7c6e33b7bc8c1850477f35 100644 (file)
@@ -72,9 +72,9 @@ static void __spin_lock_debug(spinlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_spin_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
@@ -144,9 +144,9 @@ static void __read_lock_debug(rwlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_read_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
@@ -217,9 +217,9 @@ static void __write_lock_debug(rwlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_write_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
index 8a8b3a16133ed643ccf572a0f33ceb80d1a9adc7..c4c1ac5fbd1aea372553ce094171ff8c152b2433 100644 (file)
@@ -94,10 +94,28 @@ next:                       bs = bm->bad_shift[text[shift-i]];
        return UINT_MAX;
 }
 
+static int subpattern(u8 *pattern, int i, int j, int g)
+{
+       int x = i+g-1, y = j+g-1, ret = 0;
+
+       while(pattern[x--] == pattern[y--]) {
+               if (y < 0) {
+                       ret = 1;
+                       break;
+               }
+               if (--g == 0) {
+                       ret = pattern[i-1] != pattern[j-1];
+                       break;
+               }
+       }
+
+       return ret;
+}
+
 static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
                               unsigned int len)
 {
-       int i, j, ended, l[ASIZE];
+       int i, j, g;
 
        for (i = 0; i < ASIZE; i++)
                bm->bad_shift[i] = len;
@@ -106,23 +124,15 @@ static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
 
        /* Compute the good shift array, used to match reocurrences 
         * of a subpattern */
-       for (i = 1; i < bm->patlen; i++) {
-               for (j = 0; j < bm->patlen && bm->pattern[bm->patlen - 1 - j]
-                               == bm->pattern[bm->patlen - 1 - i - j]; j++);
-               l[i] = j;
-       }  
-
        bm->good_shift[0] = 1;
        for (i = 1; i < bm->patlen; i++)
                bm->good_shift[i] = bm->patlen;
-       for (i = bm->patlen - 1; i > 0; i--)
-               bm->good_shift[l[i]] = i;
-       ended = 0;
-       for (i = 0; i < bm->patlen; i++) {
-               if (l[i] == bm->patlen - 1 - i)
-                       ended = i;
-               if (ended)
-                       bm->good_shift[i] = ended;
+        for (i = bm->patlen-1, g = 1; i > 0; g++, i--) {
+               for (j = i-1; j >= 1-g ; j--)
+                       if (subpattern(bm->pattern, i, j, g)) {
+                               bm->good_shift[g] = bm->patlen-j-g;
+                               break;
+                       }
        }
 }
 
index b21d78c941b527b9c8021d23a6d63bf3dd892523..67f29516662a4b9d3c2291731a2259808646f54c 100644 (file)
@@ -107,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr)
        set_page_count(page, 1);
        page[1].mapping = (void *)free_huge_page;
        for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
-               clear_highpage(&page[i]);
+               clear_user_highpage(&page[i], addr);
        return page;
 }
 
@@ -391,12 +391,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
 
        if (!new_page) {
                page_cache_release(old_page);
-
-               /* Logically this is OOM, not a SIGBUS, but an OOM
-                * could cause the kernel to go killing other
-                * processes which won't help the hugepage situation
-                * at all (?) */
-               return VM_FAULT_SIGBUS;
+               return VM_FAULT_OOM;
        }
 
        spin_unlock(&mm->page_table_lock);
@@ -444,6 +439,7 @@ retry:
                page = alloc_huge_page(vma, address);
                if (!page) {
                        hugetlb_put_quota(mapping);
+                       ret = VM_FAULT_OOM;
                        goto out;
                }
 
index 27da6d5c77bade350dd88f15eed6424923d91de7..3bd7fb7e4b759923524073d662085605b04d6087 100644 (file)
@@ -1159,6 +1159,7 @@ static inline unsigned interleave_nid(struct mempolicy *pol,
                return interleave_nodes(pol);
 }
 
+#ifdef CONFIG_HUGETLBFS
 /* Return a zonelist suitable for a huge page allocation. */
 struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
 {
@@ -1172,6 +1173,7 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
        }
        return zonelist_policy(GFP_HIGHUSER, pol);
 }
+#endif
 
 /* Allocate a page in interleaved policy.
    Own path because it needs to do special accounting. */
index 44b4eb4202d91e33acc45384f1468a4823ff5442..dde04ff4be31873b88c38efbf94d30fd06ca5329 100644 (file)
@@ -1213,18 +1213,21 @@ static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
 {
        int cpu = 0;
 
-       memset(ret, 0, sizeof(*ret));
+       memset(ret, 0, nr * sizeof(unsigned long));
        cpus_and(*cpumask, *cpumask, cpu_online_map);
 
        cpu = first_cpu(*cpumask);
        while (cpu < NR_CPUS) {
                unsigned long *in, *out, off;
 
+               if (!cpu_isset(cpu, *cpumask))
+                       continue;
+
                in = (unsigned long *)&per_cpu(page_states, cpu);
 
                cpu = next_cpu(cpu, *cpumask);
 
-               if (cpu < NR_CPUS)
+               if (likely(cpu < NR_CPUS))
                        prefetch(&per_cpu(page_states, cpu));
 
                out = (unsigned long *)ret;
@@ -1886,8 +1889,7 @@ static void setup_pagelist_highmark(struct per_cpu_pageset *p,
  * not check if the processor is online before following the pageset pointer.
  * Other parts of the kernel may not check if the zone is available.
  */
-static struct per_cpu_pageset
-       boot_pageset[NR_CPUS];
+static struct per_cpu_pageset boot_pageset[NR_CPUS];
 
 /*
  * Dynamically allocate memory for the
index 71370256a7eb11e8b6eeb0c88cbd0e23955ab163..d66c2b0d9715abea6d68336bb7291bd81e23753a 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -294,6 +294,7 @@ struct kmem_list3 {
        unsigned long next_reap;
        int free_touched;
        unsigned int free_limit;
+       unsigned int colour_next;       /* Per-node cache coloring */
        spinlock_t list_lock;
        struct array_cache *shared;     /* shared per node */
        struct array_cache **alien;     /* on other nodes */
@@ -344,6 +345,7 @@ static void kmem_list3_init(struct kmem_list3 *parent)
        INIT_LIST_HEAD(&parent->slabs_free);
        parent->shared = NULL;
        parent->alien = NULL;
+       parent->colour_next = 0;
        spin_lock_init(&parent->list_lock);
        parent->free_objects = 0;
        parent->free_touched = 0;
@@ -390,7 +392,6 @@ struct kmem_cache {
 
        size_t colour;          /* cache colouring range */
        unsigned int colour_off;        /* colour offset */
-       unsigned int colour_next;       /* cache colouring */
        struct kmem_cache *slabp_cache;
        unsigned int slab_size;
        unsigned int dflags;    /* dynamic flags */
@@ -883,14 +884,14 @@ static void __drain_alien_cache(struct kmem_cache *cachep,
        }
 }
 
-static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3)
+static void drain_alien_cache(struct kmem_cache *cachep, struct array_cache **alien)
 {
        int i = 0;
        struct array_cache *ac;
        unsigned long flags;
 
        for_each_online_node(i) {
-               ac = l3->alien[i];
+               ac = alien[i];
                if (ac) {
                        spin_lock_irqsave(&ac->lock, flags);
                        __drain_alien_cache(cachep, ac, i);
@@ -899,9 +900,18 @@ static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3)
        }
 }
 #else
-#define alloc_alien_cache(node, limit) do { } while (0)
-#define free_alien_cache(ac_ptr) do { } while (0)
-#define drain_alien_cache(cachep, l3) do { } while (0)
+
+#define drain_alien_cache(cachep, alien) do { } while (0)
+
+static inline struct array_cache **alloc_alien_cache(int node, int limit)
+{
+       return (struct array_cache **) 0x01020304ul;
+}
+
+static inline void free_alien_cache(struct array_cache **ac_ptr)
+{
+}
+
 #endif
 
 static int __devinit cpuup_callback(struct notifier_block *nfb,
@@ -935,6 +945,11 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                                l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
                                    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
+                               /*
+                                * The l3s don't come and go as CPUs come and
+                                * go.  cache_chain_mutex is sufficient
+                                * protection here.
+                                */
                                cachep->nodelists[node] = l3;
                        }
 
@@ -949,26 +964,46 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                   & array cache's */
                list_for_each_entry(cachep, &cache_chain, next) {
                        struct array_cache *nc;
+                       struct array_cache *shared;
+                       struct array_cache **alien;
 
                        nc = alloc_arraycache(node, cachep->limit,
-                                             cachep->batchcount);
+                                               cachep->batchcount);
                        if (!nc)
                                goto bad;
+                       shared = alloc_arraycache(node,
+                                       cachep->shared * cachep->batchcount,
+                                       0xbaadf00d);
+                       if (!shared)
+                               goto bad;
+
+                       alien = alloc_alien_cache(node, cachep->limit);
+                       if (!alien)
+                               goto bad;
                        cachep->array[cpu] = nc;
 
                        l3 = cachep->nodelists[node];
                        BUG_ON(!l3);
-                       if (!l3->shared) {
-                               if (!(nc = alloc_arraycache(node,
-                                                           cachep->shared *
-                                                           cachep->batchcount,
-                                                           0xbaadf00d)))
-                                       goto bad;
 
-                               /* we are serialised from CPU_DEAD or
-                                  CPU_UP_CANCELLED by the cpucontrol lock */
-                               l3->shared = nc;
+                       spin_lock_irq(&l3->list_lock);
+                       if (!l3->shared) {
+                               /*
+                                * We are serialised from CPU_DEAD or
+                                * CPU_UP_CANCELLED by the cpucontrol lock
+                                */
+                               l3->shared = shared;
+                               shared = NULL;
+                       }
+#ifdef CONFIG_NUMA
+                       if (!l3->alien) {
+                               l3->alien = alien;
+                               alien = NULL;
                        }
+#endif
+                       spin_unlock_irq(&l3->list_lock);
+
+                       kfree(shared);
+                       free_alien_cache(alien);
                }
                mutex_unlock(&cache_chain_mutex);
                break;
@@ -977,25 +1012,34 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                break;
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_DEAD:
+               /*
+                * Even if all the cpus of a node are down, we don't free the
+                * kmem_list3 of any cache. This to avoid a race between
+                * cpu_down, and a kmalloc allocation from another cpu for
+                * memory from the node of the cpu going down.  The list3
+                * structure is usually allocated from kmem_cache_create() and
+                * gets destroyed at kmem_cache_destroy().
+                */
                /* fall thru */
        case CPU_UP_CANCELED:
                mutex_lock(&cache_chain_mutex);
 
                list_for_each_entry(cachep, &cache_chain, next) {
                        struct array_cache *nc;
+                       struct array_cache *shared;
+                       struct array_cache **alien;
                        cpumask_t mask;
 
                        mask = node_to_cpumask(node);
-                       spin_lock_irq(&cachep->spinlock);
                        /* cpu is dead; no one can alloc from it. */
                        nc = cachep->array[cpu];
                        cachep->array[cpu] = NULL;
                        l3 = cachep->nodelists[node];
 
                        if (!l3)
-                               goto unlock_cache;
+                               goto free_array_cache;
 
-                       spin_lock(&l3->list_lock);
+                       spin_lock_irq(&l3->list_lock);
 
                        /* Free limit for this kmem_list3 */
                        l3->free_limit -= cachep->batchcount;
@@ -1003,34 +1047,44 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                                free_block(cachep, nc->entry, nc->avail, node);
 
                        if (!cpus_empty(mask)) {
-                               spin_unlock(&l3->list_lock);
-                               goto unlock_cache;
+                               spin_unlock_irq(&l3->list_lock);
+                               goto free_array_cache;
                        }
 
-                       if (l3->shared) {
+                       shared = l3->shared;
+                       if (shared) {
                                free_block(cachep, l3->shared->entry,
                                           l3->shared->avail, node);
-                               kfree(l3->shared);
                                l3->shared = NULL;
                        }
-                       if (l3->alien) {
-                               drain_alien_cache(cachep, l3);
-                               free_alien_cache(l3->alien);
-                               l3->alien = NULL;
-                       }
 
-                       /* free slabs belonging to this node */
-                       if (__node_shrink(cachep, node)) {
-                               cachep->nodelists[node] = NULL;
-                               spin_unlock(&l3->list_lock);
-                               kfree(l3);
-                       } else {
-                               spin_unlock(&l3->list_lock);
+                       alien = l3->alien;
+                       l3->alien = NULL;
+
+                       spin_unlock_irq(&l3->list_lock);
+
+                       kfree(shared);
+                       if (alien) {
+                               drain_alien_cache(cachep, alien);
+                               free_alien_cache(alien);
                        }
-                     unlock_cache:
-                       spin_unlock_irq(&cachep->spinlock);
+free_array_cache:
                        kfree(nc);
                }
+               /*
+                * In the previous loop, all the objects were freed to
+                * the respective cache's slabs,  now we can go ahead and
+                * shrink each nodelist to its limit.
+                */
+               list_for_each_entry(cachep, &cache_chain, next) {
+                       l3 = cachep->nodelists[node];
+                       if (!l3)
+                               continue;
+                       spin_lock_irq(&l3->list_lock);
+                       /* free slabs belonging to this node */
+                       __node_shrink(cachep, node);
+                       spin_unlock_irq(&l3->list_lock);
+               }
                mutex_unlock(&cache_chain_mutex);
                break;
 #endif
@@ -1119,7 +1173,6 @@ void __init kmem_cache_init(void)
                BUG();
 
        cache_cache.colour = left_over / cache_cache.colour_off;
-       cache_cache.colour_next = 0;
        cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
                                      sizeof(struct slab), cache_line_size());
 
@@ -2011,18 +2064,16 @@ static void drain_cpu_caches(struct kmem_cache *cachep)
 
        smp_call_function_all_cpus(do_drain, cachep);
        check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
        for_each_online_node(node) {
                l3 = cachep->nodelists[node];
                if (l3) {
-                       spin_lock(&l3->list_lock);
+                       spin_lock_irq(&l3->list_lock);
                        drain_array_locked(cachep, l3->shared, 1, node);
-                       spin_unlock(&l3->list_lock);
+                       spin_unlock_irq(&l3->list_lock);
                        if (l3->alien)
-                               drain_alien_cache(cachep, l3);
+                               drain_alien_cache(cachep, l3->alien);
                }
        }
-       spin_unlock_irq(&cachep->spinlock);
 }
 
 static int __node_shrink(struct kmem_cache *cachep, int node)
@@ -2324,20 +2375,20 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
                 */
                ctor_flags |= SLAB_CTOR_ATOMIC;
 
-       /* About to mess with non-constant members - lock. */
+       /* Take the l3 list lock to change the colour_next on this node */
        check_irq_off();
-       spin_lock(&cachep->spinlock);
+       l3 = cachep->nodelists[nodeid];
+       spin_lock(&l3->list_lock);
 
        /* Get colour for the slab, and cal the next value. */
-       offset = cachep->colour_next;
-       cachep->colour_next++;
-       if (cachep->colour_next >= cachep->colour)
-               cachep->colour_next = 0;
-       offset *= cachep->colour_off;
+       offset = l3->colour_next;
+       l3->colour_next++;
+       if (l3->colour_next >= cachep->colour)
+               l3->colour_next = 0;
+       spin_unlock(&l3->list_lock);
 
-       spin_unlock(&cachep->spinlock);
+       offset *= cachep->colour_off;
 
-       check_irq_off();
        if (local_flags & __GFP_WAIT)
                local_irq_enable();
 
@@ -2367,7 +2418,6 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
        if (local_flags & __GFP_WAIT)
                local_irq_disable();
        check_irq_off();
-       l3 = cachep->nodelists[nodeid];
        spin_lock(&l3->list_lock);
 
        /* Make slab active. */
@@ -2725,6 +2775,7 @@ static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int node
        BUG_ON(!l3);
 
       retry:
+       check_irq_off();
        spin_lock(&l3->list_lock);
        entry = l3->slabs_partial.next;
        if (entry == &l3->slabs_partial) {
@@ -3304,11 +3355,11 @@ static int do_tune_cpucache(struct kmem_cache *cachep, int limit, int batchcount
        smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
 
        check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
+       spin_lock(&cachep->spinlock);
        cachep->batchcount = batchcount;
        cachep->limit = limit;
        cachep->shared = shared;
-       spin_unlock_irq(&cachep->spinlock);
+       spin_unlock(&cachep->spinlock);
 
        for_each_online_cpu(i) {
                struct array_cache *ccold = new.new[i];
@@ -3440,7 +3491,7 @@ static void cache_reap(void *unused)
 
                l3 = searchp->nodelists[numa_node_id()];
                if (l3->alien)
-                       drain_alien_cache(searchp, l3);
+                       drain_alien_cache(searchp, l3->alien);
                spin_lock_irq(&l3->list_lock);
 
                drain_array_locked(searchp, cpu_cache_get(searchp), 0,
@@ -3564,8 +3615,7 @@ static int s_show(struct seq_file *m, void *p)
        int node;
        struct kmem_list3 *l3;
 
-       check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
+       spin_lock(&cachep->spinlock);
        active_objs = 0;
        num_slabs = 0;
        for_each_online_node(node) {
@@ -3573,7 +3623,8 @@ static int s_show(struct seq_file *m, void *p)
                if (!l3)
                        continue;
 
-               spin_lock(&l3->list_lock);
+               check_irq_on();
+               spin_lock_irq(&l3->list_lock);
 
                list_for_each(q, &l3->slabs_full) {
                        slabp = list_entry(q, struct slab, list);
@@ -3598,9 +3649,10 @@ static int s_show(struct seq_file *m, void *p)
                        num_slabs++;
                }
                free_objects += l3->free_objects;
-               shared_avail += l3->shared->avail;
+               if (l3->shared)
+                       shared_avail += l3->shared->avail;
 
-               spin_unlock(&l3->list_lock);
+               spin_unlock_irq(&l3->list_lock);
        }
        num_slabs += active_slabs;
        num_objs = num_slabs * cachep->num;
@@ -3644,7 +3696,7 @@ static int s_show(struct seq_file *m, void *p)
        }
 #endif
        seq_putc(m, '\n');
-       spin_unlock_irq(&cachep->spinlock);
+       spin_unlock(&cachep->spinlock);
        return 0;
 }
 
index 1c240c4b71d9bba885ee2a507dd2d83de3f004e9..a1f42bdc0245c84889080f20be6abb42ac808add 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -336,7 +336,7 @@ EXPORT_SYMBOL(slab_reclaim_pages);
 
 #ifdef CONFIG_SMP
 
-void *__alloc_percpu(size_t size, size_t align)
+void *__alloc_percpu(size_t size)
 {
        int i;
        struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
index bc2442a7b0eef63dedb08958b83c25a4d1afb518..76247424dea185d92997032d7c848dc5a550482a 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
 
-void put_page(struct page *page)
+static void put_compound_page(struct page *page)
 {
-       if (unlikely(PageCompound(page))) {
-               page = (struct page *)page_private(page);
-               if (put_page_testzero(page)) {
-                       void (*dtor)(struct page *page);
+       page = (struct page *)page_private(page);
+       if (put_page_testzero(page)) {
+               void (*dtor)(struct page *page);
 
-                       dtor = (void (*)(struct page *))page[1].mapping;
-                       (*dtor)(page);
-               }
-               return;
+               dtor = (void (*)(struct page *))page[1].mapping;
+               (*dtor)(page);
        }
-       if (put_page_testzero(page))
+}
+
+void put_page(struct page *page)
+{
+       if (unlikely(PageCompound(page)))
+               put_compound_page(page);
+       else if (put_page_testzero(page))
                __page_cache_release(page);
 }
 EXPORT_SYMBOL(put_page);
@@ -244,6 +247,15 @@ void release_pages(struct page **pages, int nr, int cold)
                struct page *page = pages[i];
                struct zone *pagezone;
 
+               if (unlikely(PageCompound(page))) {
+                       if (zone) {
+                               spin_unlock_irq(&zone->lru_lock);
+                               zone = NULL;
+                       }
+                       put_compound_page(page);
+                       continue;
+               }
+
                if (!put_page_testzero(page))
                        continue;
 
index 4d638944d933bf971c7750425474dfd3079360eb..34e42968b477d9291a1671dfa32a43af77b7a74c 100644 (file)
@@ -59,8 +59,10 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
        proto = find_snap_client(skb->h.raw);
        if (proto) {
                /* Pass the frame on. */
+               u8 *hdr = skb->data;
                skb->h.raw  += 5;
                skb_pull(skb, 5);
+               skb_postpull_rcsum(skb, hdr, 5);
                rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
        } else {
                skb->sk = NULL;
index bc603d9aea56c1a798ae6c763e813365e4f689ea..5126f58d9c44fb2b6dea23f3063904c8fa003243 100644 (file)
@@ -27,6 +27,13 @@ if NET
 
 menu "Networking options"
 
+config NETDEBUG
+       bool "Network packet debugging"
+       help
+         You can say Y here if you want to get additional messages useful in
+         debugging bad packets, but can overwhelm logs under denial of service
+         attacks.
+
 source "net/packet/Kconfig"
 source "net/unix/Kconfig"
 source "net/xfrm/Kconfig"
index ce617b3dbbb8dbb4c9a77cfcfe70c25c5748f304..802baf755ef465c392b757642999c3e40b20e2d4 100644 (file)
@@ -46,7 +46,7 @@
 #define PRINTR(format, args...) do { if (net_ratelimit()) \
                                 printk(format , ## args); } while (0)
 
-static unsigned int nlbufsiz = 4096;
+static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0600);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
                            "(defaults to 4096)");
@@ -98,12 +98,14 @@ static void ulog_timer(unsigned long data)
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
        struct sk_buff *skb;
+       unsigned int n;
 
-       skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+       n = max(size, nlbufsiz);
+       skb = alloc_skb(n, GFP_ATOMIC);
        if (!skb) {
                PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
-                      "of size %ub!\n", nlbufsiz);
-               if (size < nlbufsiz) {
+                      "of size %ub!\n", n);
+               if (n > size) {
                        /* try to allocate only as much as we need for
                         * current packet */
                        skb = alloc_skb(size, GFP_ATOMIC);
index 00729b3604f8b540e507f74e0aabf4cf6e06fa96..cbd4020cc84d6a142c0128496a80de3909b1f58e 100644 (file)
@@ -934,6 +934,13 @@ static int do_replace(void __user *user, unsigned int len)
                BUGPRINT("Entries_size never zero\n");
                return -EINVAL;
        }
+       /* overflow check */
+       if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
+                       SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+               return -ENOMEM;
+
        countersize = COUNTER_OFFSET(tmp.nentries) * 
                                        (highest_possible_processor_id()+1);
        newinfo = (struct ebt_table_info *)
index ffb82073056e761267dcbd480603d01645cfd7cf..2afb0de953291c3dfb2e16b25ba764a43e3cd860 100644 (file)
@@ -3237,7 +3237,7 @@ static int __init net_dev_init(void)
         *      Initialise the packet receive queues.
         */
 
-       for (i = 0; i < NR_CPUS; i++) {
+       for_each_cpu(i) {
                struct softnet_data *queue;
 
                queue = &per_cpu(softnet_data, i);
index ac1d1fcf8673f63158691ee0004952b803206f84..fdc4f38bc46ccfbcc86c4a36698489cfcd0ba08b 100644 (file)
@@ -121,7 +121,7 @@ void __init net_random_init(void)
 {
        int i;
 
-       for (i = 0; i < NR_CPUS; i++) {
+       for_each_cpu(i) {
                struct nrnd_state *state = &per_cpu(net_rand_state,i);
                __net_srandom(state, i+jiffies);
        }
@@ -133,7 +133,7 @@ static int net_random_reseed(void)
        unsigned long seed[NR_CPUS];
 
        get_random_bytes(seed, sizeof(seed));
-       for (i = 0; i < NR_CPUS; i++) {
+       for_each_cpu(i) {
                struct nrnd_state *state = &per_cpu(net_rand_state,i);
                __net_srandom(state, seed[i]);
        }
index d2b5933b45102ffc613fb0fc732e799982395d8e..add3cae65e2db7d9c5112ff3ad611c2b5f92770e 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <asm/bug.h>
 #include <asm/div64.h>
 
 #include "tfrc.h"
index 105039eb7629359c92884305de6506235da2dc1b..4d1c40972a4bcb7b2d32e08b0c21fa79eb69c02c 100644 (file)
@@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
        u32 daddr;
 
        if (ip_options_echo(&icmp_param->replyopts, skb))
-               goto out;
+               return;
 
        if (icmp_xmit_lock())
                return;
@@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
        ip_rt_put(rt);
 out_unlock:
        icmp_xmit_unlock();
-out:;
 }
 
 
@@ -525,7 +524,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
                                          iph->tos;
 
        if (ip_options_echo(&icmp_param.replyopts, skb_in))
-               goto ende;
+               goto out_unlock;
 
 
        /*
index 0b4e95f93dad62cbfed26297ada2fbe86cf07163..64ce52bf0485a368f016e1de23103e19db004d64 100644 (file)
@@ -1578,7 +1578,7 @@ static int sf_setstate(struct ip_mc_list *pmc)
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
                if (new_in) {
                        if (!psf->sf_oldin) {
-                               struct ip_sf_list *prev = 0;
+                               struct ip_sf_list *prev = NULL;
 
                                for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
                                        if (dpsf->sf_inaddr == psf->sf_inaddr)
index d34a9fa608e0b88dec20adaa567100a5b63c4ee0..342d0b9098f5f8ca9bdd5a019b6a7a0660ace097 100644 (file)
@@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network,
        struct multipath_dest *d, *target_dest = NULL;
 
        /* store the weight information for a certain route */
-       spin_lock(&state[state_idx].lock);
+       spin_lock_bh(&state[state_idx].lock);
 
        /* find state entry for gateway or add one if necessary */
        list_for_each_entry_rcu(r, &state[state_idx].head, list) {
@@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network,
         * we are finished
         */
 
-       spin_unlock(&state[state_idx].lock);
+       spin_unlock_bh(&state[state_idx].lock);
 }
 
 static void __multipath_free(struct rcu_head *head)
@@ -302,7 +302,7 @@ static void wrandom_flush(void)
        for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
                struct multipath_route *r;
 
-               spin_lock(&state[i].lock);
+               spin_lock_bh(&state[i].lock);
                list_for_each_entry_rcu(r, &state[i].head, list) {
                        struct multipath_dest *d;
                        list_for_each_entry_rcu(d, &r->dests, list) {
@@ -315,7 +315,7 @@ static void wrandom_flush(void)
                                 __multipath_free);
                }
 
-               spin_unlock(&state[i].lock);
+               spin_unlock_bh(&state[i].lock);
        }
 }
 
index afe3d8f8177d7df83df0264e20f3072077ff1317..dd1048be8a0115b4cd08591fbd3b29b19e9bda36 100644 (file)
@@ -807,6 +807,13 @@ static int do_replace(void __user *user, unsigned int len)
        if (len != sizeof(tmp) + tmp.size)
                return -ENOPROTOOPT;
 
+       /* overflow check */
+       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+                       SMP_CACHE_BYTES)
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
        newinfo = xt_alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
index c9ebbe0d2d9cc6ad8bca99b0b3f94ab699695d52..e0b5926c76f94d0adfee4fa2a26f10bdbce33bf6 100644 (file)
@@ -1216,7 +1216,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
 
        b = skb->tail;
 
-       type |= NFNL_SUBSYS_CTNETLINK << 8;
+       type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
        nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
        nfmsg = NLMSG_DATA(nlh);
 
@@ -1567,6 +1567,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
 };
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 static int __init ctnetlink_init(void)
 {
index d3c5a371f993e390a5f6c521b649050be8d950b9..4ba4463cec280ee816d814afc25cae8ec197cf55 100644 (file)
@@ -71,6 +71,7 @@ static int tftp_help(struct sk_buff **pskb,
 
                exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
                exp->mask.src.ip = 0xffffffff;
+               exp->mask.src.u.udp.port = 0;
                exp->mask.dst.ip = 0xffffffff;
                exp->mask.dst.u.udp.port = 0xffff;
                exp->mask.dst.protonum = 0xff;
index ad438fb185b8943dfafde63c13fcbb405a5caf46..92c54999a19d023d049af354123b096839757aad 100644 (file)
@@ -209,8 +209,8 @@ ip_nat_in(unsigned int hooknum,
            && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
                enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
-               if (ct->tuplehash[dir].tuple.src.ip !=
-                   ct->tuplehash[!dir].tuple.dst.ip) {
+               if (ct->tuplehash[dir].tuple.dst.ip !=
+                   ct->tuplehash[!dir].tuple.src.ip) {
                        dst_release((*pskb)->dst);
                        (*pskb)->dst = NULL;
                }
index 2371b2062c2d812468ad62f4fe19d4360e748f41..16f47c675fefd8304d86174f6d4beeebdec6539b 100644 (file)
@@ -921,6 +921,13 @@ do_replace(void __user *user, unsigned int len)
        if (len != sizeof(tmp) + tmp.size)
                return -ENOPROTOOPT;
 
+       /* overflow check */
+       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+                       SMP_CACHE_BYTES)
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
        newinfo = xt_alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
index 641dbc477650f6059e9577386a1664d6c9ea0206..180a9ea57b69fb4e05a7c8b171f1bc1628ae6f8c 100644 (file)
  * each nlgroup you are using, so the total kernel memory usage increases
  * by that factor.
  *
+ * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since
+ * nlbufsiz is used with alloc_skb, which adds another
+ * sizeof(struct skb_shared_info).  Use NLMSG_GOODSIZE instead.
+ *
  * flushtimeout:
  *   Specify, after how many hundredths of a second the queue should be
  *   flushed even if it is not full yet.
@@ -76,7 +80,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
 
 #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
 
-static unsigned int nlbufsiz = 4096;
+static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0400);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
 
@@ -143,22 +147,26 @@ static void ulog_timer(unsigned long data)
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
        struct sk_buff *skb;
+       unsigned int n;
 
        /* alloc skb which should be big enough for a whole
         * multipart message. WARNING: has to be <= 131000
         * due to slab allocator restrictions */
 
-       skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+       n = max(size, nlbufsiz);
+       skb = alloc_skb(n, GFP_ATOMIC);
        if (!skb) {
-               PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n",
-                       nlbufsiz);
+               PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n);
 
-               /* try to allocate only as much as we need for 
-                * current packet */
+               if (n > size) {
+                       /* try to allocate only as much as we need for 
+                        * current packet */
 
-               skb = alloc_skb(size, GFP_ATOMIC);
-               if (!skb)
-                       PRINTR("ipt_ULOG: can't even allocate %ub\n", size);
+                       skb = alloc_skb(size, GFP_ATOMIC);
+                       if (!skb)
+                               PRINTR("ipt_ULOG: can't even allocate %ub\n",
+                                      size);
+               }
        }
 
        return skb;
index 18ca8258a1c597c170fd718f5c8556a1eaefb382..5a7a265280f927a4ccac41140e7b682c8d3f3fe9 100644 (file)
@@ -26,10 +26,13 @@ MODULE_LICENSE("GPL");
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
 {
-#define MATCH(x,y)     (!e->match.x || ((e->x == (y)) ^ e->invert.x))
+#define MATCH_ADDR(x,y,z)      (!e->match.x ||                              \
+                                ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
+                                 ^ e->invert.x))
+#define MATCH(x,y)             (!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
-       return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
-              MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+       return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
+              MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
               MATCH(proto, x->id.proto) &&
               MATCH(mode, x->props.mode) &&
               MATCH(spi, x->id.spi) &&
@@ -89,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
                        return 0;
        }
 
-       return strict ? 1 : 0;
+       return strict ? i == info->len : 0;
 }
 
 static int match(const struct sk_buff *skb,
index 39d49dc333a7f0dc47e1bbd1f8d7a7c02c3f2cfb..1b167c4bb3beb0254f446a6ab21ca41fd87a0455 100644 (file)
@@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto)
        int res = 0;
        int cpu;
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for_each_cpu(cpu)
                res += proto->stats[cpu].inuse;
 
        return res;
index 42196ba3b0b912701d727b8a4ede46108292b49e..45f7ae58f2c0e13979415c34d76dce492cd32f84 100644 (file)
@@ -8,7 +8,6 @@
  *     
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/inetdevice.h>
index d328d59861438ae0b8bad815a3ef34cacf7de328..b7d8822c1be49cbcd73ca303d7d253e93cdec406 100644 (file)
@@ -2165,6 +2165,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                                        dev->name);
                                break;
                        }
+
+                       if (idev)
+                               idev->if_flags |= IF_READY;
                } else {
                        if (!netif_carrier_ok(dev)) {
                                /* device is still not ready. */
@@ -3321,9 +3324,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
 
        switch (event) {
        case RTM_NEWADDR:
-               dst_hold(&ifp->rt->u.dst);
-               if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
-                       dst_release(&ifp->rt->u.dst);
+               ip6_ins_rt(ifp->rt, NULL, NULL, NULL);
                if (ifp->idev->cnf.forwarding)
                        addrconf_join_anycast(ifp);
                break;
@@ -3334,8 +3335,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
                dst_hold(&ifp->rt->u.dst);
                if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
                        dst_free(&ifp->rt->u.dst);
-               else
-                       dst_release(&ifp->rt->u.dst);
                break;
        }
 }
index 064ffab82a9fe5f7d674bc344e0798b6f97e62ec..6c9711ac1c0324adb5496541efebc55e89a50bf7 100644 (file)
@@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk)
        struct sk_buff *skb;
        struct ipv6_txoptions *opt;
 
-       /*
-        *      Release destination entry
-        */
-
-       sk_dst_reset(sk);
-
        /* Release rx options */
 
        if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
index 4420948a1bfe9f23ec29de602551dd6bca9cbcf3..807c021d64a282f5490364f0785cf407b17a7802 100644 (file)
@@ -1978,7 +1978,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
                if (new_in) {
                        if (!psf->sf_oldin) {
-                               struct ip6_sf_list *prev = 0;
+                               struct ip6_sf_list *prev = NULL;
 
                                for (dpsf=pmc->mca_tomb; dpsf;
                                     dpsf=dpsf->sf_next) {
index 847068fd33676cfd3b6bc510be992baf4ab8d06d..74ff56c322f47ee45b3b873e4672d0bc9c13511a 100644 (file)
@@ -978,6 +978,13 @@ do_replace(void __user *user, unsigned int len)
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
 
+       /* overflow check */
+       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+                       SMP_CACHE_BYTES)
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
        newinfo = xt_alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
index afe1cc4c18a5bffc734d6011b1dfddd395007158..3d39ec924041a4883fb86f7e90a3db9c912f8976 100644 (file)
@@ -26,8 +26,9 @@ MODULE_LICENSE("GPL");
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
 {
-#define MATCH_ADDR(x,y,z)      (!e->match.x || \
-                                ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
+#define MATCH_ADDR(x,y,z)      (!e->match.x ||                                \
+                                ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
+                                 ^ e->invert.x))
 #define MATCH(x,y)             (!e->match.x || ((e->x == (y)) ^ e->invert.x))
        
        return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
@@ -91,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
                        return 0;
        }
 
-       return strict ? 1 : 0;
+       return strict ? i == info->len : 0;
 }
 
 static int match(const struct sk_buff *skb,
index 50a13e75d70ec5fecd20269c8c4e90bc523164cc..4238b1ed886012a331b1c5dd16ddffa1ea2eaaae 100644 (file)
@@ -38,7 +38,7 @@ static int fold_prot_inuse(struct proto *proto)
        int res = 0;
        int cpu;
 
-       for (cpu=0; cpu<NR_CPUS; cpu++)
+       for_each_cpu(cpu)
                res += proto->stats[cpu].inuse;
 
        return res;
index 66f1d12ea578319f144044313a6776cefa7090d2..738376cf0c519cdcd3d5fbb832b525fe9a2d122d 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
-#include <asm/bug.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
index 69bd957380e7025fe393c720bde30974c4691284..91cce8b2d7a5643b523c55b12758756a0d374aee 100644 (file)
@@ -11,7 +11,6 @@
  * 
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/netdevice.h>
index 62bb509f05d4fc4bf32a7b0eb9db0ff0c8e972c5..0ce337a1d974da68634b351c84b09e815a968244 100644 (file)
@@ -188,7 +188,7 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
 struct nf_conntrack_protocol *
 __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
 {
-       if (unlikely(nf_ct_protos[l3proto] == NULL))
+       if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
                return &nf_conntrack_generic_protocol;
 
        return nf_ct_protos[l3proto][protocol];
index ab0c920f0d30bbf840d731f8c6baddaab7c3f089..6f210f399762d8196630e2c8a087dc0f548a759d 100644 (file)
@@ -657,8 +657,6 @@ static int __init init(void)
        /* FIXME should be configurable whether IPv4 and IPv6 FTP connections
                 are tracked or not - YK */
        for (i = 0; i < ports_c; i++) {
-               memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
-
                ftp[i][0].tuple.src.l3num = PF_INET;
                ftp[i][1].tuple.src.l3num = PF_INET6;
                for (j = 0; j < 2; j++) {
index 73ab16bc7d4052d155257686b09cd103da3a960d..9ff3463037e1d0b080820c4457d488a1dd7e6bdc 100644 (file)
@@ -1232,7 +1232,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
 
        b = skb->tail;
 
-       type |= NFNL_SUBSYS_CTNETLINK << 8;
+       type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
        nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
        nfmsg = NLMSG_DATA(nlh);
 
@@ -1589,6 +1589,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
 };
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 static int __init ctnetlink_init(void)
 {
index e10512e229b60e2c3cc216f01a5550a9ca7ba006..3b3c781b40c067f62b19f47744297c4a6cd747f9 100644 (file)
@@ -37,7 +37,7 @@
 #include "../bridge/br_private.h"
 #endif
 
-#define NFULNL_NLBUFSIZ_DEFAULT        4096
+#define NFULNL_NLBUFSIZ_DEFAULT        NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT         100     /* every second */
 #define NFULNL_QTHRESH_DEFAULT         100     /* 100 packets */
 
@@ -314,24 +314,28 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
                                        unsigned int pkt_size)
 {
        struct sk_buff *skb;
+       unsigned int n;
 
        UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
 
        /* alloc skb which should be big enough for a whole multipart
         * message.  WARNING: has to be <= 128k due to slab restrictions */
 
-       skb = alloc_skb(inst_size, GFP_ATOMIC);
+       n = max(inst_size, pkt_size);
+       skb = alloc_skb(n, GFP_ATOMIC);
        if (!skb) {
                PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n",
                        inst_size);
 
-               /* try to allocate only as much as we need for current
-                * packet */
+               if (n > pkt_size) {
+                       /* try to allocate only as much as we need for current
+                        * packet */
 
-               skb = alloc_skb(pkt_size, GFP_ATOMIC);
-               if (!skb)
-                       PRINTR("nfnetlink_log: can't even alloc %u bytes\n",
-                               pkt_size);
+                       skb = alloc_skb(pkt_size, GFP_ATOMIC);
+                       if (!skb)
+                               PRINTR("nfnetlink_log: can't even alloc %u "
+                                      "bytes\n", pkt_size);
+               }
        }
 
        return skb;
index 18ed9c5d209ca8e13b1cfc7330862fc3534cd275..cac38b2e147aec5cf1aa10707753150585dc9d9f 100644 (file)
@@ -825,7 +825,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        }
 
        if (nfqa[NFQA_MARK-1])
-               skb->nfmark = ntohl(*(u_int32_t *)NFA_DATA(nfqa[NFQA_MARK-1]));
+               entry->skb->nfmark = ntohl(*(u_int32_t *)
+                                          NFA_DATA(nfqa[NFQA_MARK-1]));
                
        issue_verdict(entry, verdict);
        instance_put(queue);
index a40991ef72c92b4d6a59368b67c15ed7ea2c70e7..437cba7260a4a1a6970546cbf36f650114a785ab 100644 (file)
@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
         *    When a Fast Retransmit is being performed the sender SHOULD
         *    ignore the value of cwnd and SHOULD NOT delay retransmission.
         */
-       if (!chunk->fast_retransmit)
+       if (chunk->fast_retransmit <= 0)
                if (transport->flight_size >= transport->cwnd) {
                        retval = SCTP_XMIT_RWND_FULL;
                        goto finish;
index efb72faba20cd50aec065d4fe498c85ecae8d4ae..f148f9576dd226035b3b6c34d439d7558818ce4a 100644 (file)
@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                 * chunks that are not yet acked should be added to the
                 * retransmit queue.
                 */
-               if ((fast_retransmit && chunk->fast_retransmit) ||
+               if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
                   (!fast_retransmit && !chunk->tsn_gap_acked)) {
                        /* RFC 2960 6.2.1 Processing a Received SACK
                         *
@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
                        /* Mark the chunk as ineligible for fast retransmit 
                         * after it is retransmitted.
                         */
-                       chunk->fast_retransmit = 0;
+                       if (chunk->fast_retransmit > 0)
+                               chunk->fast_retransmit = -1;
 
                        *start_timer = 1;
                        q->empty = 0;
@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
                        list_for_each(lchunk1, lqueue) {
                                chunk1 = list_entry(lchunk1, struct sctp_chunk,
                                                    transmitted_list);
-                               chunk1->fast_retransmit = 0;
+                               if (chunk1->fast_retransmit > 0)
+                                       chunk1->fast_retransmit = -1;
                        }
                }
        }
@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q,
                /*
                 * M4) If any DATA chunk is found to have a
                 * 'TSN.Missing.Report'
-                * value larger than or equal to 4, mark that chunk for
+                * value larger than or equal to 3, mark that chunk for
                 * retransmission and start the fast retransmit procedure.
                 */
 
-               if (chunk->tsn_missing_report >= 4) {
+               if (chunk->tsn_missing_report >= 3) {
                        chunk->fast_retransmit = 1;
                        do_fast_retransmit = 1;
                }
index b38a263853c32038b07fe7dcb9dae457d4456722..a00851f981dbfcb17b26f64d7bfc2a5e64e31a5d 100644 (file)
@@ -2078,7 +2078,7 @@ void socket_seq_show(struct seq_file *seq)
        int cpu;
        int counter = 0;
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for_each_cpu(cpu)
                counter += per_cpu(sockets_in_use, cpu);
 
        /* It can be negative, by the way. 8) */
index 9ac1b8c26c01184595f34de62db8ef23b15c6890..8d6f1a176b159f9ee1a989dd0803fc0d5eb5d2d0 100644 (file)
@@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
  */
 struct rpc_cred *
 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
-               int taskflags)
+               int flags)
 {
        struct rpc_cred_cache *cache = auth->au_credcache;
        HLIST_HEAD(free);
@@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
                        *cred = NULL;
        int             nr = 0;
 
-       if (!(taskflags & RPC_TASK_ROOTCREDS))
+       if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
                nr = acred->uid & RPC_CREDCACHE_MASK;
 retry:
        spin_lock(&rpc_credcache_lock);
@@ -202,7 +202,7 @@ retry:
        hlist_for_each_safe(pos, next, &cache->hashtable[nr]) {
                struct rpc_cred *entry;
                entry = hlist_entry(pos, struct rpc_cred, cr_hash);
-               if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
+               if (entry->cr_ops->crmatch(acred, entry, flags)) {
                        hlist_del(&entry->cr_hash);
                        cred = entry;
                        break;
@@ -224,7 +224,7 @@ retry:
        rpcauth_destroy_credlist(&free);
 
        if (!cred) {
-               new = auth->au_ops->crcreate(auth, acred, taskflags);
+               new = auth->au_ops->crcreate(auth, acred, flags);
                if (!IS_ERR(new)) {
 #ifdef RPC_DEBUG
                        new->cr_magic = RPCAUTH_CRED_MAGIC;
@@ -232,13 +232,21 @@ retry:
                        goto retry;
                } else
                        cred = new;
+       } else if ((cred->cr_flags & RPCAUTH_CRED_NEW)
+                       && cred->cr_ops->cr_init != NULL
+                       && !(flags & RPCAUTH_LOOKUP_NEW)) {
+               int res = cred->cr_ops->cr_init(auth, cred);
+               if (res < 0) {
+                       put_rpccred(cred);
+                       cred = ERR_PTR(res);
+               }
        }
 
        return (struct rpc_cred *) cred;
 }
 
 struct rpc_cred *
-rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
+rpcauth_lookupcred(struct rpc_auth *auth, int flags)
 {
        struct auth_cred acred = {
                .uid = current->fsuid,
@@ -250,7 +258,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
        dprintk("RPC:     looking up %s cred\n",
                auth->au_ops->au_name);
        get_group_info(acred.group_info);
-       ret = auth->au_ops->lookup_cred(auth, &acred, taskflags);
+       ret = auth->au_ops->lookup_cred(auth, &acred, flags);
        put_group_info(acred.group_info);
        return ret;
 }
@@ -265,11 +273,14 @@ rpcauth_bindcred(struct rpc_task *task)
                .group_info = current->group_info,
        };
        struct rpc_cred *ret;
+       int flags = 0;
 
        dprintk("RPC: %4d looking up %s cred\n",
                task->tk_pid, task->tk_auth->au_ops->au_name);
        get_group_info(acred.group_info);
-       ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags);
+       if (task->tk_flags & RPC_TASK_ROOTCREDS)
+               flags |= RPCAUTH_LOOKUP_ROOTCREDS;
+       ret = auth->au_ops->lookup_cred(auth, &acred, flags);
        if (!IS_ERR(ret))
                task->tk_msg.rpc_cred = ret;
        else
index 8d782282ec194c6f682fd71b2a100c25141c45c0..bb46efd92e5723475b3dd1c1cbf38f78c2af7c82 100644 (file)
@@ -158,6 +158,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
        old = gss_cred->gc_ctx;
        gss_cred->gc_ctx = ctx;
        cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+       cred->cr_flags &= ~RPCAUTH_CRED_NEW;
        write_unlock(&gss_ctx_lock);
        if (old)
                gss_put_ctx(old);
@@ -580,7 +581,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
        } else {
                struct auth_cred acred = { .uid = uid };
                spin_unlock(&gss_auth->lock);
-               cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0);
+               cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
                if (IS_ERR(cred)) {
                        err = PTR_ERR(cred);
                        goto err_put_ctx;
@@ -758,13 +759,13 @@ gss_destroy_cred(struct rpc_cred *rc)
  * Lookup RPCSEC_GSS cred for the current process
  */
 static struct rpc_cred *
-gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
+gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
-       return rpcauth_lookup_credcache(auth, acred, taskflags);
+       return rpcauth_lookup_credcache(auth, acred, flags);
 }
 
 static struct rpc_cred *
-gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
+gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
        struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
        struct gss_cred *cred = NULL;
@@ -785,13 +786,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
         */
        cred->gc_flags = 0;
        cred->gc_base.cr_ops = &gss_credops;
+       cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
        cred->gc_service = gss_auth->service;
-       do {
-               err = gss_create_upcall(gss_auth, cred);
-       } while (err == -EAGAIN);
-       if (err < 0)
-               goto out_err;
-
        return &cred->gc_base;
 
 out_err:
@@ -801,13 +797,34 @@ out_err:
 }
 
 static int
-gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags)
+gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
+{
+       struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
+       struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
+       int err;
+
+       do {
+               err = gss_create_upcall(gss_auth, gss_cred);
+       } while (err == -EAGAIN);
+       return err;
+}
+
+static int
+gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
 {
        struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
 
+       /*
+        * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
+        * we don't really care if the credential has expired or not,
+        * since the caller should be prepared to reinitialise it.
+        */
+       if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
+               goto out;
        /* Don't match with creds that have expired. */
        if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
                return 0;
+out:
        return (rc->cr_uid == acred->uid);
 }
 
@@ -1241,6 +1258,7 @@ static struct rpc_authops authgss_ops = {
 static struct rpc_credops gss_credops = {
        .cr_name        = "AUTH_GSS",
        .crdestroy      = gss_destroy_cred,
+       .cr_init        = gss_cred_init,
        .crmatch        = gss_match,
        .crmarshal      = gss_marshal,
        .crrefresh      = gss_refresh,
index 1b3ed4fd198735e332b3f8f46492956f91457860..df14b6bfbf10f9a0bc8874b0a332b3b170a06199 100644 (file)
@@ -75,7 +75,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 
        atomic_set(&cred->uc_count, 1);
        cred->uc_flags = RPCAUTH_CRED_UPTODATE;
-       if (flags & RPC_TASK_ROOTCREDS) {
+       if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
                cred->uc_uid = 0;
                cred->uc_gid = 0;
                cred->uc_gids[0] = NOGROUP;
@@ -108,12 +108,12 @@ unx_destroy_cred(struct rpc_cred *cred)
  * request root creds (e.g. for NFS swapping).
  */
 static int
-unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
+unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 {
        struct unx_cred *cred = (struct unx_cred *) rcred;
        int             i;
 
-       if (!(taskflags & RPC_TASK_ROOTCREDS)) {
+       if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
                int groups;
 
                if (cred->uc_uid != acred->uid
index 9764c80ab0b26927eaa23dd90be7e35bc158ef93..a5c0c7b6e151b4a8712ec67d3c3cdbf32308497c 100644 (file)
@@ -38,44 +38,42 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly;
 
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
-static void
-__rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err)
+static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
+               void (*destroy_msg)(struct rpc_pipe_msg *), int err)
 {
        struct rpc_pipe_msg *msg;
-       void (*destroy_msg)(struct rpc_pipe_msg *);
 
-       destroy_msg = rpci->ops->destroy_msg;
-       while (!list_empty(head)) {
+       if (list_empty(head))
+               return;
+       do {
                msg = list_entry(head->next, struct rpc_pipe_msg, list);
-               list_del_init(&msg->list);
+               list_del(&msg->list);
                msg->errno = err;
                destroy_msg(msg);
-       }
-}
-
-static void
-__rpc_purge_upcall(struct inode *inode, int err)
-{
-       struct rpc_inode *rpci = RPC_I(inode);
-
-       __rpc_purge_list(rpci, &rpci->pipe, err);
-       rpci->pipelen = 0;
+       } while (!list_empty(head));
        wake_up(&rpci->waitq);
 }
 
 static void
 rpc_timeout_upcall_queue(void *data)
 {
+       LIST_HEAD(free_list);
        struct rpc_inode *rpci = (struct rpc_inode *)data;
        struct inode *inode = &rpci->vfs_inode;
+       void (*destroy_msg)(struct rpc_pipe_msg *);
 
-       mutex_lock(&inode->i_mutex);
-       if (rpci->ops == NULL)
-               goto out;
-       if (rpci->nreaders == 0 && !list_empty(&rpci->pipe))
-               __rpc_purge_upcall(inode, -ETIMEDOUT);
-out:
-       mutex_unlock(&inode->i_mutex);
+       spin_lock(&inode->i_lock);
+       if (rpci->ops == NULL) {
+               spin_unlock(&inode->i_lock);
+               return;
+       }
+       destroy_msg = rpci->ops->destroy_msg;
+       if (rpci->nreaders == 0) {
+               list_splice_init(&rpci->pipe, &free_list);
+               rpci->pipelen = 0;
+       }
+       spin_unlock(&inode->i_lock);
+       rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT);
 }
 
 int
@@ -84,7 +82,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
        struct rpc_inode *rpci = RPC_I(inode);
        int res = -EPIPE;
 
-       mutex_lock(&inode->i_mutex);
+       spin_lock(&inode->i_lock);
        if (rpci->ops == NULL)
                goto out;
        if (rpci->nreaders) {
@@ -100,7 +98,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
                res = 0;
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       spin_unlock(&inode->i_lock);
        wake_up(&rpci->waitq);
        return res;
 }
@@ -115,21 +113,29 @@ static void
 rpc_close_pipes(struct inode *inode)
 {
        struct rpc_inode *rpci = RPC_I(inode);
+       struct rpc_pipe_ops *ops;
 
        mutex_lock(&inode->i_mutex);
-       if (rpci->ops != NULL) {
+       ops = rpci->ops;
+       if (ops != NULL) {
+               LIST_HEAD(free_list);
+
+               spin_lock(&inode->i_lock);
                rpci->nreaders = 0;
-               __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);
-               __rpc_purge_upcall(inode, -EPIPE);
-               rpci->nwriters = 0;
-               if (rpci->ops->release_pipe)
-                       rpci->ops->release_pipe(inode);
+               list_splice_init(&rpci->in_upcall, &free_list);
+               list_splice_init(&rpci->pipe, &free_list);
+               rpci->pipelen = 0;
                rpci->ops = NULL;
+               spin_unlock(&inode->i_lock);
+               rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
+               rpci->nwriters = 0;
+               if (ops->release_pipe)
+                       ops->release_pipe(inode);
+               cancel_delayed_work(&rpci->queue_timeout);
+               flush_scheduled_work();
        }
        rpc_inode_setowner(inode, NULL);
        mutex_unlock(&inode->i_mutex);
-       cancel_delayed_work(&rpci->queue_timeout);
-       flush_scheduled_work();
 }
 
 static struct inode *
@@ -177,16 +183,26 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
                goto out;
        msg = (struct rpc_pipe_msg *)filp->private_data;
        if (msg != NULL) {
+               spin_lock(&inode->i_lock);
                msg->errno = -EAGAIN;
-               list_del_init(&msg->list);
+               list_del(&msg->list);
+               spin_unlock(&inode->i_lock);
                rpci->ops->destroy_msg(msg);
        }
        if (filp->f_mode & FMODE_WRITE)
                rpci->nwriters --;
-       if (filp->f_mode & FMODE_READ)
+       if (filp->f_mode & FMODE_READ) {
                rpci->nreaders --;
-       if (!rpci->nreaders)
-               __rpc_purge_upcall(inode, -EAGAIN);
+               if (rpci->nreaders == 0) {
+                       LIST_HEAD(free_list);
+                       spin_lock(&inode->i_lock);
+                       list_splice_init(&rpci->pipe, &free_list);
+                       rpci->pipelen = 0;
+                       spin_unlock(&inode->i_lock);
+                       rpc_purge_list(rpci, &free_list,
+                                       rpci->ops->destroy_msg, -EAGAIN);
+               }
+       }
        if (rpci->ops->release_pipe)
                rpci->ops->release_pipe(inode);
 out:
@@ -209,6 +225,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
        }
        msg = filp->private_data;
        if (msg == NULL) {
+               spin_lock(&inode->i_lock);
                if (!list_empty(&rpci->pipe)) {
                        msg = list_entry(rpci->pipe.next,
                                        struct rpc_pipe_msg,
@@ -218,6 +235,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
                        filp->private_data = msg;
                        msg->copied = 0;
                }
+               spin_unlock(&inode->i_lock);
                if (msg == NULL)
                        goto out_unlock;
        }
@@ -225,7 +243,9 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
        res = rpci->ops->upcall(filp, msg, buf, len);
        if (res < 0 || msg->len == msg->copied) {
                filp->private_data = NULL;
-               list_del_init(&msg->list);
+               spin_lock(&inode->i_lock);
+               list_del(&msg->list);
+               spin_unlock(&inode->i_lock);
                rpci->ops->destroy_msg(msg);
        }
 out_unlock:
@@ -610,7 +630,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
                return ERR_PTR(error);
        dir = nd->dentry->d_inode;
        mutex_lock(&dir->i_mutex);
-       dentry = lookup_hash(nd);
+       dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len);
        if (IS_ERR(dentry))
                goto out_err;
        if (dentry->d_inode) {
@@ -672,7 +692,7 @@ rpc_rmdir(char *path)
                return error;
        dir = nd.dentry->d_inode;
        mutex_lock(&dir->i_mutex);
-       dentry = lookup_hash(&nd);
+       dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
        if (IS_ERR(dentry)) {
                error = PTR_ERR(dentry);
                goto out_release;
@@ -733,7 +753,7 @@ rpc_unlink(char *path)
                return error;
        dir = nd.dentry->d_inode;
        mutex_lock(&dir->i_mutex);
-       dentry = lookup_hash(&nd);
+       dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
        if (IS_ERR(dentry)) {
                error = PTR_ERR(dentry);
                goto out_release;
index 077bbf9fb9b7605f08af1de583141bbea0429be0..dbf4620768d61ee267f07fc0f0df7e47d2746c81 100644 (file)
@@ -13,7 +13,6 @@
  *
  */
 
-#include <asm/bug.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
index 5760e057ecbac174679bedfe60de520645ec659a..d64aae85c3788e10036b772baed84217d08d1bd2 100644 (file)
@@ -123,7 +123,17 @@ KBUILD_HAVE_NLS := $(shell \
      then echo yes ; \
      else echo no ; fi)
 ifeq ($(KBUILD_HAVE_NLS),no)
-HOSTCFLAGS     += -DKBUILD_NO_NLS
+  HOSTCFLAGS   += -DKBUILD_NO_NLS
+else
+  KBUILD_NEED_LINTL := $(shell \
+    if echo -e "\#include <libintl.h>\nint main(int a, char** b) { gettext(\"\"); return 0; }\n" | \
+      $(HOSTCC) $(HOSTCFLAGS) -x c - -o /dev/null> /dev/null 2>&1 ; \
+    then echo no ; \
+    else echo yes ; fi)
+  ifeq ($(KBUILD_NEED_LINTL),yes)
+    HOSTLOADLIBES_conf += -lintl
+    HOSTLOADLIBES_mconf        += -lintl
+  endif
 endif
 
 # generated files seem to need this to find local include files
index fae3e29fc924a8c8eaa419187d2880241a4e0a3b..bbf4887cff74f095d1dc25518dc90c1b3e7f2cf1 100644 (file)
@@ -2,8 +2,11 @@
 #
 
 check-lxdialog  := $(srctree)/$(src)/check-lxdialog.sh
-HOST_EXTRACFLAGS:= $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES  := $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+# Use reursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
  
 HOST_EXTRACFLAGS += -DLOCALE 
 
index 448e353923f3b52545a7473d4ff5a4e342a7f959..120d624e672c5740faf2aa744aa7785c5edbecab 100644 (file)
@@ -4,17 +4,17 @@
 # What library to link
 ldflags()
 {
-       echo "main() {}" | $cc -lncursesw -xc - -o /dev/null 2> /dev/null
+       $cc -print-file-name=libncursesw.so | grep -q /
        if [ $? -eq 0 ]; then
                echo '-lncursesw'
                exit
        fi
-       echo "main() {}" | $cc -lncurses -xc - -o /dev/null 2> /dev/null
+       $cc -print-file-name=libncurses.so | grep -q /
        if [ $? -eq 0 ]; then
                echo '-lncurses'
                exit
        fi
-       echo "main() {}" | $cc -lcurses -xc - -o /dev/null 2> /dev/null
+       $cc -print-file-name=libcurses.so | grep -q /
        if [ $? -eq 0 ]; then
                echo '-lcurses'
                exit
@@ -36,10 +36,13 @@ ccflags()
        fi
 }
 
-compiler=""
+# Temp file, try to clean up after us
+tmp=.lxdialog.tmp
+trap "rm -f $tmp" 0 1 2 3 15
+
 # Check if we can link to ncurses
 check() {
-       echo "main() {}" | $cc -xc - -o /dev/null 2> /dev/null
+       echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
        if [ $? != 0 ]; then
                echo " *** Unable to find the ncurses libraries."          1>&2
                echo " *** make menuconfig require the ncurses libraries"  1>&2
@@ -59,6 +62,7 @@ if [ $# == 0 ]; then
        exit 1
 fi
 
+cc=""
 case "$1" in
        "-check")
                shift
index 90db5c76cf6e5bdad2778f6a18e6a772dd281c51..0c62798ac7d80149a91cdfc2e0cc447951efe9c2 100644 (file)
@@ -67,9 +67,10 @@ asmlinkage long sys_add_key(const char __user *_type,
        description = kmalloc(dlen + 1, GFP_KERNEL);
        if (!description)
                goto error;
+       description[dlen] = '\0';
 
        ret = -EFAULT;
-       if (copy_from_user(description, _description, dlen + 1) != 0)
+       if (copy_from_user(description, _description, dlen) != 0)
                goto error2;
 
        /* pull the payload in if one was supplied */
@@ -161,9 +162,10 @@ asmlinkage long sys_request_key(const char __user *_type,
        description = kmalloc(dlen + 1, GFP_KERNEL);
        if (!description)
                goto error;
+       description[dlen] = '\0';
 
        ret = -EFAULT;
-       if (copy_from_user(description, _description, dlen + 1) != 0)
+       if (copy_from_user(description, _description, dlen) != 0)
                goto error2;
 
        /* pull the callout info into kernel space */
@@ -182,9 +184,10 @@ asmlinkage long sys_request_key(const char __user *_type,
                callout_info = kmalloc(dlen + 1, GFP_KERNEL);
                if (!callout_info)
                        goto error2;
+               callout_info[dlen] = '\0';
 
                ret = -EFAULT;
-               if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0)
+               if (copy_from_user(callout_info, _callout_info, dlen) != 0)
                        goto error3;
        }
 
@@ -279,9 +282,10 @@ long keyctl_join_session_keyring(const char __user *_name)
                name = kmalloc(nlen + 1, GFP_KERNEL);
                if (!name)
                        goto error;
+               name[nlen] = '\0';
 
                ret = -EFAULT;
-               if (copy_from_user(name, _name, nlen + 1) != 0)
+               if (copy_from_user(name, _name, nlen) != 0)
                        goto error2;
        }
 
@@ -583,9 +587,10 @@ long keyctl_keyring_search(key_serial_t ringid,
        description = kmalloc(dlen + 1, GFP_KERNEL);
        if (!description)
                goto error;
+       description[dlen] = '\0';
 
        ret = -EFAULT;
-       if (copy_from_user(description, _description, dlen + 1) != 0)
+       if (copy_from_user(description, _description, dlen) != 0)
                goto error2;
 
        /* get the keyring at which to begin the search */
index b59582b92283eb667fe7cab218da01af215a3628..f636f53ca5444ccabdd231e5be72d8bbe976838e 100644 (file)
@@ -1,6 +1,6 @@
 config SECURITY_SELINUX
        bool "NSA SELinux Support"
-       depends on SECURITY && NET && INET
+       depends on SECURITY_NETWORK && AUDIT && NET && INET
        default n
        help
          This selects NSA Security-Enhanced Linux (SELinux).
index 06d54d9d20a5049e25911e33668dc3ed1a2dd9c4..688c0a267b62060de2f0b4172b8fe09fe5ff7361 100644 (file)
@@ -4,9 +4,7 @@
 
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
 
-selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
-
-selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
+selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o
 
 selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
 
index 53d6c7bbf56459f6aa7145a7c3649a754588abc1..ac5d69bb3377edb3c8bec35f7a1c1570425980d8 100644 (file)
@@ -43,13 +43,11 @@ static const struct av_perm_to_string
 #undef S_
 };
 
-#ifdef CONFIG_AUDIT
 static const char *class_to_string[] = {
 #define S_(s) s,
 #include "class_to_string.h"
 #undef S_
 };
-#endif
 
 #define TB_(s) static const char * s [] = {
 #define TE_(s) };
index 4ae834d89bce9e81a98c8be4a0056341603ffded..b7773bf68efa8fb104c45312b8a385cbb701d499 100644 (file)
@@ -232,7 +232,6 @@ static void superblock_free_security(struct super_block *sb)
        kfree(sbsec);
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
 static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
        struct sk_security_struct *ssec;
@@ -261,7 +260,6 @@ static void sk_free_security(struct sock *sk)
        sk->sk_security = NULL;
        kfree(ssec);
 }
-#endif /* CONFIG_SECURITY_NETWORK */
 
 /* The security server must be initialized before
    any labeling or access decisions can be provided. */
@@ -2736,8 +2734,6 @@ static void selinux_task_to_inode(struct task_struct *p,
        return;
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
-
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad)
 {
@@ -3556,15 +3552,6 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
 
 #endif /* CONFIG_NETFILTER */
 
-#else
-
-static inline int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
-{
-       return 0;
-}
-
-#endif /* CONFIG_SECURITY_NETWORK */
-
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
        struct task_security_struct *tsec;
@@ -4340,7 +4327,6 @@ static struct security_operations selinux_ops = {
        .getprocattr =                  selinux_getprocattr,
        .setprocattr =                  selinux_setprocattr,
 
-#ifdef CONFIG_SECURITY_NETWORK
         .unix_stream_connect =         selinux_socket_unix_stream_connect,
        .unix_may_send =                selinux_socket_unix_may_send,
 
@@ -4362,7 +4348,6 @@ static struct security_operations selinux_ops = {
        .sk_alloc_security =            selinux_sk_alloc_security,
        .sk_free_security =             selinux_sk_free_security,
        .sk_getsid =                    selinux_sk_getsid_security,
-#endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
        .xfrm_policy_alloc_security =   selinux_xfrm_policy_alloc,
@@ -4440,7 +4425,7 @@ next_sb:
    all processes and objects when they are created. */
 security_initcall(selinux_init);
 
-#if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_NETFILTER)
+#if defined(CONFIG_NETFILTER)
 
 static struct nf_hook_ops selinux_ipv4_op = {
        .hook =         selinux_ipv4_postroute_last,
@@ -4501,13 +4486,13 @@ static void selinux_nf_ip_exit(void)
 }
 #endif
 
-#else /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#else /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 #define selinux_nf_ip_exit()
 #endif
 
-#endif /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#endif /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 int selinux_disable(void)
index 54147c1f6361d67d85db502737830e8da461e86a..149feb410654812ae4612438923ae990761302d3 100644 (file)
@@ -882,14 +882,20 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
        writel(0x1fff, aaci->base + AACI_INTCLR);
        writel(aaci->maincr, aaci->base + AACI_MAINCR);
 
+       ret = aaci_probe_ac97(aaci);
+       if (ret)
+               goto out;
+
        /*
-        * Size the FIFOs.
+        * Size the FIFOs (must be multiple of 16).
         */
        aaci->fifosize = aaci_size_fifo(aaci);
-
-       ret = aaci_probe_ac97(aaci);
-       if (ret)
+       if (aaci->fifosize & 15) {
+               printk(KERN_WARNING "AACI: fifosize = %d not supported\n",
+                      aaci->fifosize);
+               ret = -ENODEV;
                goto out;
+       }
 
        ret = aaci_init_pcm(aaci);
        if (ret)
index 3a6d48666db0c4fe718fd1084820f6073cff91bc..0741c28e56ce6639f79b23966095be2b9f3e8afe 100644 (file)
@@ -178,10 +178,10 @@ tas_write_register(       struct tas_data_t *self,
        if (write_mode & WRITE_SHADOW)
                memcpy(self->shadow[reg_num],data,reg_width);
        if (write_mode & WRITE_HW) {
-               rc=i2c_smbus_write_block_data(self->client,
-                                             reg_num,
-                                             reg_width,
-                                             data);
+               rc=i2c_smbus_write_i2c_block_data(self->client,
+                                                 reg_num,
+                                                 reg_width,
+                                                 data);
                if (rc < 0) {
                        printk("tas: I2C block write failed \n");  
                        return rc; 
@@ -199,10 +199,10 @@ tas_sync_register(        struct tas_data_t *self,
 
        if (reg_width==0 || self==NULL)
                return -EINVAL;
-       rc=i2c_smbus_write_block_data(self->client,
-                                     reg_num,
-                                     reg_width,
-                                     self->shadow[reg_num]);
+       rc=i2c_smbus_write_i2c_block_data(self->client,
+                                         reg_num,
+                                         reg_width,
+                                         self->shadow[reg_num]);
        if (rc < 0) {
                printk("tas: I2C block write failed \n");
                return rc;
index 67c3fd04cfdd177546be1218742758e7b44df236..2ce56180e7d4d1709742d95d896af906780d82b5 100644 (file)
@@ -29,7 +29,7 @@
  **********************************************************************
  */
 
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include "8010.h"
 #include "recmgr.h"
 
index 4988f873a7bacc6bd1749bea5f1d137823401da1..aa57170101fd44dd2a090b0acd2c302bbe00e3e8 100644 (file)
@@ -66,7 +66,7 @@ static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, i
 
 static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
 {
-       if (rec) {
+       if (rec->space) {
                unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
 
                dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
@@ -881,6 +881,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
        chip->can_capture = 1;
        chip->num_freqs = ARRAY_SIZE(awacs_freqs);
        chip->freq_table = awacs_freqs;
+       chip->pdev = NULL;
 
        chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
 
index 15c63cb2ccba6d432d05cb44fdae84d189aa09e9..838fc113c441113ed36302f252561500f380892e 100644 (file)
@@ -239,8 +239,8 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
        block[4] = (right_vol >> 8)  & 0xff;
        block[5] = (right_vol >> 0)  & 0xff;
   
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
-                                      6, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,
+                                          block) < 0) {
                snd_printk("failed to set volume \n");
                return -EINVAL;
        }
@@ -345,8 +345,8 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
                val[1] = 0;
        }
 
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-                                      2, val) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+                                          2, val) < 0) {
                snd_printk("failed to set DRC\n");
                return -EINVAL;
        }
@@ -381,8 +381,8 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
        val[4] = 0x60;
        val[5] = 0xa0;
 
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-                                      6, val) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+                                          6, val) < 0) {
                snd_printk("failed to set DRC\n");
                return -EINVAL;
        }
@@ -492,8 +492,8 @@ static int tumbler_set_mono_volume(struct pmac_tumbler *mix,
        vol = info->table[vol];
        for (i = 0; i < info->bytes; i++)
                block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
-       if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
-                                      info->bytes, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,
+                                          info->bytes, block) < 0) {
                snd_printk("failed to set mono volume %d\n", info->index);
                return -EINVAL;
        }
@@ -625,7 +625,8 @@ static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int r
                for (j = 0; j < 3; j++)
                        block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
        }
-       if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,
+                                          9, block) < 0) {
                snd_printk("failed to set mono volume %d\n", reg);
                return -EINVAL;
        }