]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Pull thinkpad-2.6.24 into release branch
authorLen Brown <len.brown@intel.com>
Tue, 20 Nov 2007 06:20:42 +0000 (01:20 -0500)
committerLen Brown <len.brown@intel.com>
Tue, 20 Nov 2007 06:20:42 +0000 (01:20 -0500)
852 files changed:
Documentation/accounting/getdelays.c
Documentation/feature-removal-schedule.txt
Documentation/hwmon/sysfs-interface
Documentation/lguest/lguest.c
Documentation/local_ops.txt
Documentation/markers.txt
Documentation/networking/00-INDEX
Documentation/networking/3c505.txt
Documentation/networking/Configurable [deleted file]
Documentation/networking/comx.txt [deleted file]
Documentation/networking/ncsa-telnet [deleted file]
Documentation/networking/pt.txt [deleted file]
Documentation/networking/routing.txt [deleted file]
Documentation/networking/slicecom.hun [deleted file]
Documentation/networking/slicecom.txt [deleted file]
Documentation/powerpc/booting-without-of.txt
Documentation/rtc.txt
Documentation/video4linux/CARDLIST.em28xx
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/mach-iop32x/n2100.c
arch/arm/mach-netx/xc.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/time.c
arch/arm/mm/consistent.c
arch/arm/plat-omap/fb.c
arch/avr32/Kconfig
arch/avr32/mach-at32ap/at32ap7000.c
arch/avr32/mach-at32ap/hsmc.c
arch/avr32/mach-at32ap/intc.c
arch/cris/Kconfig
arch/cris/arch-v10/defconfig
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v10/drivers/axisflashmap.c
arch/cris/arch-v10/drivers/gpio.c
arch/cris/arch-v10/kernel/entry.S
arch/cris/arch-v10/kernel/fasttimer.c
arch/cris/arch-v10/kernel/io_interface_mux.c
arch/cris/arch-v10/kernel/irq.c
arch/cris/arch-v10/kernel/setup.c
arch/cris/arch-v10/kernel/time.c
arch/cris/arch-v10/lib/memset.c
arch/cris/arch-v10/lib/string.c
arch/cris/arch-v10/lib/usercopy.c
arch/cris/arch-v32/drivers/Kconfig
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/sync_serial.c
arch/cris/arch-v32/kernel/cache.c [new file with mode: 0644]
arch/cris/arch-v32/kernel/cacheflush.S [new file with mode: 0644]
arch/cris/arch-v32/kernel/io.c
arch/cris/arch-v32/kernel/setup.c
arch/cris/defconfig
arch/cris/kernel/crisksyms.c
arch/cris/kernel/irq.c
arch/cris/kernel/process.c
arch/cris/kernel/ptrace.c
arch/cris/kernel/sys_cris.c
arch/cris/kernel/time.c
arch/frv/mm/init.c
arch/ia64/hp/sim/boot/fw-emu.c
arch/ia64/ia32/ia32priv.h
arch/ia64/kernel/.gitignore [new file with mode: 0644]
arch/ia64/kernel/acpi.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/palinfo.c
arch/ia64/kernel/patch.c
arch/ia64/kernel/perfmon.c
arch/ia64/mm/contig.c
arch/ia64/sn/kernel/irq.c
arch/ia64/sn/kernel/xpc_main.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/kernel/cevt-bcm1480.c
arch/mips/kernel/cevt-sb1250.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/csrc-sb1250.c
arch/mips/kernel/genex.S
arch/mips/kernel/irixsig.c
arch/mips/kernel/irq-rm7000.c
arch/mips/kernel/irq-rm9000.c
arch/mips/kernel/irq_cpu.c
arch/mips/kernel/proc.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/traps.c
arch/mips/kernel/vpe.c
arch/mips/lasat/interrupt.c
arch/mips/mm/c-r4k.c
arch/mips/mm/cerr-sb1.c
arch/mips/mm/init.c
arch/mips/pci/fixup-sni.c
arch/mips/pci/pci-lasat.c
arch/mips/pci/pci-vr41xx.c
arch/mips/qemu/Makefile
arch/mips/qemu/q-console.c [new file with mode: 0644]
arch/mips/qemu/q-firmware.c
arch/mips/qemu/q-setup.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sni/pcimt.c
arch/mips/vr41xx/common/icu.c
arch/powerpc/Makefile
arch/powerpc/boot/dts/walnut.dts
arch/powerpc/boot/wrapper
arch/powerpc/configs/pasemi_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/idle.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/swsusp_32.S
arch/powerpc/kernel/time.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/mm/40x_mmu.c
arch/powerpc/mm/44x_mmu.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/hash_low_64.S
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/slb.c
arch/powerpc/mm/tlb_64.c
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/smp.c
arch/powerpc/platforms/celleb/setup.c
arch/powerpc/platforms/iseries/irq.h
arch/powerpc/platforms/iseries/setup.c
arch/powerpc/platforms/iseries/vio.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/eeh_driver.c
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/i8259.c
arch/powerpc/sysdev/mv64x60_pci.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/misc.S
arch/ppc/mm/44x_mmu.c
arch/ppc/mm/4xx_mmu.c
arch/ppc/mm/fault.c
arch/ppc/mm/mmu_decl.h
arch/ppc/platforms/4xx/ebony.c
arch/ppc/platforms/4xx/luan.c
arch/ppc/platforms/4xx/ocotea.c
arch/ppc/platforms/4xx/taishan.c
arch/ppc/syslib/i8259.c
arch/ppc/syslib/m8260_setup.c
arch/s390/kernel/early.c
arch/s390/kernel/process.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/vtime.c
arch/sh/Kconfig
arch/sh/Kconfig.debug
arch/sh/boards/renesas/hs7751rvoip/irq.c
arch/sh/boards/renesas/hs7751rvoip/setup.c
arch/sh/boards/renesas/sh7710voipgw/setup.c
arch/sh/boards/se/7206/irq.c
arch/sh/boards/se/770x/setup.c
arch/sh/boards/se/7722/setup.c
arch/sh/boards/se/7780/setup.c
arch/sh/boards/snapgear/Makefile
arch/sh/boards/snapgear/rtc.c [deleted file]
arch/sh/boards/snapgear/setup.c
arch/sh/boot/Makefile
arch/sh/cchips/hd6446x/Makefile
arch/sh/cchips/voyagergx/Makefile
arch/sh/drivers/pci/Makefile
arch/sh/drivers/pci/pci-st40.c [deleted file]
arch/sh/drivers/pci/pci-st40.h [deleted file]
arch/sh/kernel/Makefile
arch/sh/kernel/cpu/sh3/ex.S
arch/sh/kernel/cpu/sh4/probe.c
arch/sh/kernel/irq.c
arch/sh/kernel/kgdb_stub.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms.c
arch/sh/lib/Makefile
arch/sh/mm/Kconfig
arch/sh/mm/Makefile
arch/sh/mm/clear_page.S
arch/sh/mm/copy_page.S
arch/sh/mm/pg-sh4.c
arch/sh/oprofile/Makefile
arch/sh64/kernel/process.c
arch/sh64/kernel/traps.c
arch/sparc/kernel/irq.c
arch/sparc64/kernel/ds.c
arch/sparc64/kernel/module.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/time.c
arch/um/Makefile
arch/um/Makefile-i386
arch/um/drivers/net_kern.c
arch/um/drivers/ubd_kern.c
arch/um/include/user.h
arch/um/kernel/irq.c
arch/um/kernel/skas/clone.c
arch/um/os-Linux/file.c
arch/x86/Kconfig [moved from arch/x86/Kconfig.i386 with 74% similarity]
arch/x86/Kconfig.cpu
arch/x86/Kconfig.x86_64 [deleted file]
arch/x86/Makefile
arch/x86/Makefile_32
arch/x86/Makefile_64
arch/x86/boot/Makefile
arch/x86/boot/cpucheck.c
arch/x86/boot/pmjump.S
arch/x86/ia32/ia32entry.S
arch/x86/ia32/ptrace32.c
arch/x86/kernel/Makefile_32
arch/x86/kernel/Makefile_64
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/processor.c
arch/x86/kernel/cpu/cpufreq/Kconfig [moved from arch/x86/kernel/cpu/cpufreq/Kconfig_32 with 77% similarity]
arch/x86/kernel/cpu/cpufreq/Kconfig_64 [deleted file]
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/i387_64.c
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/nmi_32.c
arch/x86/kernel/reboot_fixups_32.c
arch/x86/kernel/setup_64.c
arch/x86/kernel/time_64.c
arch/x86/lguest/boot.c
arch/x86/lib/delay_32.c
arch/x86/lib/delay_64.c
arch/x86/mach-voyager/voyager_cat.c
arch/x86/mach-voyager/voyager_smp.c
arch/x86/pci/acpi.c
arch/x86/vdso/Makefile
arch/x86/vdso/vgetcpu.c
block/cfq-iosched.c
block/ll_rw_blk.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/ac.c
drivers/acpi/battery.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbs.c
drivers/acpi/toshiba_acpi.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_platform.c
drivers/ata/pata_serverworks.c
drivers/ata/sata_nv.c
drivers/ata/sata_qstor.c
drivers/block/nbd.c
drivers/block/paride/pf.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/block/rd.c
drivers/char/drm/drmP.h
drivers/char/drm/drm_ioctl.c
drivers/char/drm/drm_os_linux.h
drivers/char/drm/savage_bci.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/random.c
drivers/char/rtc.c
drivers/char/tty_ioctl.c
drivers/char/virtio_console.c
drivers/cpufreq/cpufreq_conservative.c
drivers/crypto/geode-aes.c
drivers/dma/dmaengine.c
drivers/dma/ioat.c
drivers/dma/ioat_dca.c
drivers/dma/ioat_dma.c
drivers/dma/ioatdma.h
drivers/dma/ioatdma_hw.h
drivers/dma/ioatdma_registers.h
drivers/edac/i5000_edac.c
drivers/firewire/fw-sbp2.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/abituguru3.c
drivers/hwmon/applesmc.c
drivers/hwmon/f75375s.c
drivers/hwmon/i5k_amb.c [new file with mode: 0644]
drivers/hwmon/ibmpex.c
drivers/hwmon/lm70.c
drivers/hwmon/sis5595.c
drivers/hwmon/w83627hf.c
drivers/hwmon/w83781d.c
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/chips/eeprom.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/Kconfig
drivers/ide/cris/ide-cris.c
drivers/ide/ide-dma.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-lib.c
drivers/ide/ide-probe.c
drivers/ide/ide-taskfile.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/it821x.c
drivers/ide/pci/jmicron.c
drivers/ide/pci/piix.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/sis5513.c
drivers/ide/ppc/pmac.c
drivers/ide/setup-pci.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/ehca/ehca_av.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_iverbs.h
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/hipz_hw.h
drivers/infiniband/hw/ipath/ipath_cq.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/isdn/hisax/Kconfig
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/sc/card.h
drivers/isdn/sc/packet.c
drivers/isdn/sc/shmem.c
drivers/kvm/svm.c
drivers/kvm/x86_emulate.c
drivers/leds/leds-gpio.c
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/macintosh/windfarm_core.c
drivers/md/bitmap.c
drivers/md/dm-table.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/Kconfig
drivers/media/common/saa7146_core.c
drivers/media/dvb/frontends/mt2131.c
drivers/media/dvb/frontends/s5h1409.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/ves1820.c
drivers/media/dvb/ttpci/Kconfig
drivers/media/video/Kconfig
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx23885/Kconfig
drivers/media/video/cx88/Kconfig
drivers/media/video/em28xx/Kconfig
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/planb.c
drivers/media/video/pvrusb2/pvrusb2-ctrl.c
drivers/media/video/pvrusb2/pvrusb2-main.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/saa7134/Kconfig
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/tuner-core.c
drivers/media/video/tvp5150.c
drivers/message/i2o/i2o_block.c
drivers/misc/ioc4.c
drivers/mmc/card/queue.c
drivers/mmc/host/sdhci.c
drivers/net/82596.c
drivers/net/Kconfig
drivers/net/arcnet/Kconfig
drivers/net/arm/ep93xx_eth.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/chelsio/sge.c
drivers/net/cris/eth_v10.c
drivers/net/e1000/e1000_main.c
drivers/net/fs_enet/Kconfig
drivers/net/fs_enet/Makefile
drivers/net/hamradio/6pack.c
drivers/net/irda/irtty-sir.c
drivers/net/loopback.c
drivers/net/mlx4/alloc.c
drivers/net/mlx4/qp.c
drivers/net/myri_sbus.c
drivers/net/netx-eth.c
drivers/net/pasemi_mac.c
drivers/net/phy/marvell.c
drivers/net/phy/phy_device.c
drivers/net/ppp_async.c
drivers/net/ppp_generic.c
drivers/net/ppp_synctty.c
drivers/net/pppol2tp.c
drivers/net/qla3xxx.c
drivers/net/qla3xxx.h
drivers/net/r8169.c
drivers/net/rrunner.c
drivers/net/s2io.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/slip.c
drivers/net/smc91x.h
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/tehuti.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tulip/Kconfig
drivers/net/usb/Kconfig
drivers/net/usb/usbnet.c
drivers/net/via-velocity.c
drivers/net/virtio_net.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/Kconfig
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/debugfs.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pcmcia.c
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43/rfkill.h
drivers/net/wireless/b43legacy/debugfs.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/strip.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.h
drivers/oprofile/oprofile_stats.c
drivers/pci/Kconfig
drivers/pci/hotplug/Kconfig
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pnp/pnpacpi/rsparser.c
drivers/rtc/Kconfig
drivers/rtc/hctosys.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-stk17ta8.c
drivers/s390/block/dcssblk.c
drivers/s390/cio/cmf.c
drivers/s390/cio/device.c
drivers/s390/net/smsgiucv.c
drivers/scsi/Kconfig
drivers/scsi/aic94xx/aic94xx_sds.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/osst.c
drivers/serial/8250_early.c
drivers/serial/8250_pci.c
drivers/serial/8250_pnp.c
drivers/serial/atmel_serial.c
drivers/serial/crisv10.c
drivers/serial/crisv10.h [new file with mode: 0644]
drivers/serial/sh-sci.h
drivers/serial/uartlite.c
drivers/sh/superhyway/superhyway.c
drivers/spi/spi.c
drivers/spi/spi_txx9.c
drivers/spi/tle62x0.c
drivers/ssb/main.c
drivers/ssb/pcmcia.c
drivers/telephony/phonedev.c
drivers/usb/serial/keyspan.c
drivers/video/Kconfig
drivers/video/cyber2000fb.c
drivers/video/gbefb.c
drivers/video/geode/lxfb.h
drivers/video/ps3fb.c
drivers/video/s1d13xxxfb.c
drivers/video/sis/sis_main.c
drivers/video/uvesafb.c
drivers/virtio/virtio_ring.c
drivers/w1/masters/ds2490.c
fs/9p/v9fs.c
fs/9p/vfs_super.c
fs/Kconfig
fs/afs/vlocation.c
fs/bfs/bfs.h
fs/bfs/dir.c
fs/bfs/file.c
fs/bfs/inode.c
fs/cifs/CHANGES
fs/cifs/Makefile
fs/cifs/asn1.c
fs/cifs/cifs_spnego.c [new file with mode: 0644]
fs/cifs/cifs_spnego.h [new file with mode: 0644]
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/md5.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/smbencrypt.c
fs/cifs/xattr.c
fs/dlm/lowcomms.c
fs/ecryptfs/crypto.c
fs/ecryptfs/read_write.c
fs/exec.c
fs/ext2/balloc.c
fs/ext2/ioctl.c
fs/ext3/balloc.c
fs/ext3/dir.c
fs/ext3/ioctl.c
fs/ext3/namei.c
fs/ext4/balloc.c
fs/ext4/ioctl.c
fs/fuse/file.c
fs/hugetlbfs/inode.c
fs/ioprio.c
fs/jfs/ioctl.c
fs/nfsd/nfs2acl.c
fs/nfsd/nfs3acl.c
fs/nfsd/nfsfh.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dcache.c
fs/ocfs2/dir.c
fs/ocfs2/dlmglue.c
fs/ocfs2/file.c
fs/ocfs2/namei.c
fs/open.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/internal.h
fs/proc/proc_net.c
fs/proc/root.c
fs/read_write.c
fs/reiserfs/ioctl.c
fs/reiserfs/stree.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/smbfs/proc.c
fs/smbfs/smbiod.c
include/acpi/processor.h
include/asm-arm/hardware/iop3xx.h
include/asm-arm/pgtable.h
include/asm-arm26/irq_regs.h [deleted file]
include/asm-avr32/sysreg.h
include/asm-cris/atomic.h
include/asm-cris/checksum.h
include/asm-cris/ethernet.h
include/asm-cris/fasttimer.h
include/asm-cris/hardirq.h
include/asm-cris/posix_types.h
include/asm-cris/termbits.h
include/asm-cris/thread_info.h
include/asm-cris/tlb.h
include/asm-cris/unistd.h
include/asm-frv/irq.h
include/asm-ia64/pal.h
include/asm-m68knommu/unistd.h
include/asm-mips/cpu-info.h
include/asm-mips/lasat/lasatint.h
include/asm-mips/mach-lasat/irq.h [new file with mode: 0644]
include/asm-mips/timex.h
include/asm-powerpc/commproc.h
include/asm-powerpc/cputable.h
include/asm-powerpc/pgtable-ppc32.h
include/asm-powerpc/systbl.h
include/asm-powerpc/time.h
include/asm-powerpc/tlbflush.h
include/asm-sh/cacheflush.h
include/asm-sh/cpu-sh3/timer.h
include/asm-sh/page.h
include/asm-sh/pgtable.h
include/asm-sh/processor.h
include/asm-sh/ptrace.h
include/asm-sh/vga.h [new file with mode: 0644]
include/asm-sh64/ptrace.h
include/asm-sparc64/vio.h
include/asm-um/pgtable-3level.h
include/asm-x86/i387_64.h
include/asm-x86/lguest_hcall.h
include/asm-x86/mach-default/mach_reboot.h
include/asm-x86/mach-es7000/mach_mpparse.h
include/asm-x86/mach-voyager/setup_arch.h
include/asm-x86/ptrace.h
include/linux/acpi.h
include/linux/ata.h
include/linux/blkdev.h
include/linux/cgroup_subsys.h
include/linux/cpu_acct.h [deleted file]
include/linux/cpuidle.h
include/linux/ext3_fs.h
include/linux/f75375s.h [new file with mode: 0644]
include/linux/futex.h
include/linux/hugetlb.h
include/linux/i2c.h
include/linux/ide.h
include/linux/kallsyms.h
include/linux/libata.h
include/linux/mc146818rtc.h
include/linux/mroute.h
include/linux/net.h
include/linux/netfilter/Kbuild
include/linux/netfilter_ipv4/Kbuild
include/linux/netfilter_ipv6/Kbuild
include/linux/netlink.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pid_namespace.h
include/linux/proc_fs.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/selinux.h
include/linux/skbuff.h
include/linux/smp.h
include/linux/tty.h
include/linux/virtio_ring.h
include/net/af_unix.h
include/net/dst.h
include/net/fib_rules.h
include/net/inet_common.h
include/net/inet_hashtables.h
include/net/inetpeer.h
include/net/ip_fib.h
include/net/ip_vs.h
include/net/mac80211.h
include/net/net_namespace.h
include/net/request_sock.h
include/net/sctp/command.h
include/net/sctp/constants.h
include/net/sctp/sctp.h
include/net/sctp/structs.h
include/net/sock.h
include/pcmcia/cs_types.h
init/Kconfig
init/main.c
ipc/mqueue.c
kernel/Makefile
kernel/cgroup.c
kernel/cpu_acct.c [deleted file]
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/futex_compat.c
kernel/irq/handle.c
kernel/marker.c
kernel/params.c
kernel/pid.c
kernel/power/disk.c
kernel/resource.c
kernel/sched.c
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_stats.h
kernel/signal.c
kernel/sys.c
kernel/sysctl.c
kernel/sysctl_check.c
kernel/taskstats.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
kernel/timer.c
lib/Makefile
lib/bitmap.c
lib/libcrc32c.c
mm/hugetlb.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/page-writeback.c
mm/page_alloc.c
mm/page_isolation.c
mm/rmap.c
mm/slab.c
mm/slob.c
mm/slub.c
mm/util.c
mm/vmstat.c
net/8021q/vlan.c
net/8021q/vlan.h
net/8021q/vlan_dev.c
net/9p/mod.c
net/9p/trans_fd.c
net/bridge/br_netfilter.c
net/bridge/netfilter/ebt_arp.c
net/core/dev.c
net/core/dev_mcast.c
net/core/dst.c
net/core/fib_rules.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/request_sock.c
net/core/sock.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/proto.c
net/decnet/dn_dev.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_crypt_wep.c
net/ieee80211/softmac/ieee80211softmac_wx.c
net/ipv4/fib_frontend.c
net/ipv4/fib_rules.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipcomp.c
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/nf_nat_amanda.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_ftp.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_irc.c
net/ipv4/netfilter/nf_nat_pptp.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_tftp.c
net/ipv4/proc.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tunnel4.c
net/ipv4/udp.c
net/ipv4/udplite.c
net/ipv6/fib6_rules.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/ndisc.c
net/ipv6/netfilter/Makefile
net/ipv6/netfilter/ip6_queue.c
net/ipv6/proc.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udplite.c
net/ipx/af_ipx.c
net/mac80211/Kconfig
net/mac80211/Makefile
net/mac80211/ieee80211.c
net/mac80211/ieee80211_common.h [deleted file]
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_ioctl.c
net/mac80211/ieee80211_rate.c
net/mac80211/ieee80211_rate.h
net/mac80211/ieee80211_sta.c
net/mac80211/rc80211_simple.c
net/mac80211/rx.c
net/mac80211/wep.c
net/mac80211/wpa.c
net/netfilter/Makefile
net/netfilter/nf_conntrack_extend.c
net/netfilter/nf_sockopt.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_time.c
net/netfilter/xt_u32.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rfkill/rfkill.c
net/rxrpc/ar-local.c
net/sched/cls_u32.c
net/sched/sch_generic.c
net/sched/sch_teql.c
net/sctp/associola.c
net/sctp/bind_addr.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/inqueue.c
net/sctp/outqueue.c
net/sctp/proc.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/sysctl.c
net/sctp/transport.c
net/sctp/ulpqueue.c
net/socket.c
net/sunrpc/xprtrdma/transport.c
net/unix/af_unix.c
net/unix/garbage.c
samples/markers/marker-example.c
samples/markers/probe-example.c
scripts/kconfig/Makefile
scripts/kconfig/confdata.c
security/commoncap.c
security/selinux/ss/avtab.c
security/selinux/ss/avtab.h
security/selinux/ss/conditional.c
security/selinux/ss/ebitmap.c
security/selinux/ss/mls.c
security/selinux/ss/mls.h
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/xfrm.c

index ab82b7f53312a58719766e68dd5081d0724a4d75..d6cb1a86fd61ebcdf05b95d95e5517a891b2e63c 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/genetlink.h>
 #include <linux/taskstats.h>
+#include <linux/cgroupstats.h>
 
 /*
  * Generic macros for dealing with netlink sockets. Might be duplicated
@@ -78,6 +79,7 @@ static void usage(void)
        fprintf(stderr, "  -i: print IO accounting (works only with -p)\n");
        fprintf(stderr, "  -l: listen forever\n");
        fprintf(stderr, "  -v: debug on\n");
+       fprintf(stderr, "  -C: container path\n");
 }
 
 /*
@@ -212,6 +214,14 @@ void task_context_switch_counts(struct taskstats *t)
               t->nvcsw, t->nivcsw);
 }
 
+void print_cgroupstats(struct cgroupstats *c)
+{
+       printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, "
+               "uninterruptible %llu\n", c->nr_sleeping, c->nr_io_wait,
+               c->nr_running, c->nr_stopped, c->nr_uninterruptible);
+}
+
+
 void print_ioacct(struct taskstats *t)
 {
        printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
@@ -239,11 +249,14 @@ int main(int argc, char *argv[])
        int maskset = 0;
        char *logfile = NULL;
        int loop = 0;
+       int containerset = 0;
+       char containerpath[1024];
+       int cfd = 0;
 
        struct msgtemplate msg;
 
        while (1) {
-               c = getopt(argc, argv, "qdiw:r:m:t:p:vl");
+               c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:");
                if (c < 0)
                        break;
 
@@ -260,6 +273,10 @@ int main(int argc, char *argv[])
                        printf("printing task/process context switch rates\n");
                        print_task_context_switch_counts = 1;
                        break;
+               case 'C':
+                       containerset = 1;
+                       strncpy(containerpath, optarg, strlen(optarg) + 1);
+                       break;
                case 'w':
                        logfile = strdup(optarg);
                        printf("write to file %s\n", logfile);
@@ -334,6 +351,11 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (tid && containerset) {
+               fprintf(stderr, "Select either -t or -C, not both\n");
+               goto err;
+       }
+
        if (tid) {
                rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
                              cmd_type, &tid, sizeof(__u32));
@@ -344,6 +366,20 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (containerset) {
+               cfd = open(containerpath, O_RDONLY);
+               if (cfd < 0) {
+                       perror("error opening container file");
+                       goto err;
+               }
+               rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET,
+                             CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32));
+               if (rc < 0) {
+                       perror("error sending cgroupstats command");
+                       goto err;
+               }
+       }
+
        do {
                int i;
 
@@ -422,6 +458,9 @@ int main(int argc, char *argv[])
                                }
                                break;
 
+                       case CGROUPSTATS_TYPE_CGROUP_STATS:
+                               print_cgroupstats(NLA_DATA(na));
+                               break;
                        default:
                                fprintf(stderr, "Unknown nla_type %d\n",
                                        na->nla_type);
@@ -443,5 +482,7 @@ err:
        close(nl_sd);
        if (fd)
                close(fd);
+       if (cfd)
+               close(cfd);
        return 0;
 }
index 6bb9be54ab767817557b680407edca2f582e03e9..20c4c8bac9d7d599fa43e1162b7db62cb7ad9011 100644 (file)
@@ -181,15 +181,6 @@ Who:       Nick Piggin <npiggin@suse.de>
 
 ---------------------------
 
-What:  Interrupt only SA_* flags
-When:  September 2007
-Why:   The interrupt related SA_* flags are replaced by IRQF_* to move them
-       out of the signal namespace.
-
-Who:   Thomas Gleixner <tglx@linutronix.de>
-
----------------------------
-
 What:  PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
 When:  October 2008
 Why:   The stacking of class devices makes these values misleading and
index a17b692d2679ca520adfa986d9035a19ea88bd57..f4a8ebc1ef1acc11ae4bdd22c9299f4b84467c73 100644 (file)
@@ -328,6 +328,37 @@ curr[1-*]_input    Current input value
                Unit: milliampere
                RO
 
+*********
+* Power *
+*********
+
+power[1-*]_average             Average power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_average_highest     Historical average maximum power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_average_lowest      Historical average minimum power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_input               Instantaneous power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_input_highest       Historical maximum power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_input_lowest                Historical minimum power use
+                               Unit: microWatt
+                               RO
+
+power[1-*]_reset_history       Reset input_highest, input_lowest,
+                               average_highest and average_lowest.
+                               WO
 
 **********
 * Alarms *
index f2668390e8f773276357917e79625790d4e98b5a..42008395534d67c39dfc1da086ee9f35eaa95c3a 100644 (file)
@@ -62,8 +62,8 @@ typedef uint8_t u8;
 #endif
 /* We can have up to 256 pages for devices. */
 #define DEVICE_PAGES 256
-/* This fits nicely in a single 4096-byte page. */
-#define VIRTQUEUE_NUM 127
+/* This will occupy 2 pages: it must be a power of 2. */
+#define VIRTQUEUE_NUM 128
 
 /*L:120 verbose is both a global flag and a macro.  The C preprocessor allows
  * this, and although I wouldn't recommend it, it works quite nicely here. */
@@ -1036,7 +1036,8 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
        void *p;
 
        /* First we need some pages for this virtqueue. */
-       pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize();
+       pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1)
+               / getpagesize();
        p = get_pages(pages);
 
        /* Initialize the configuration. */
@@ -1045,7 +1046,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
        vq->config.pfn = to_guest_phys(p) / getpagesize();
 
        /* Initialize the vring. */
-       vring_init(&vq->vring, num_descs, p);
+       vring_init(&vq->vring, num_descs, p, getpagesize());
 
        /* Add the configuration information to this device's descriptor. */
        add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE,
@@ -1342,7 +1343,7 @@ static bool service_io(struct device *dev)
        if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
                fprintf(stderr, "Scsi commands unsupported\n");
                in->status = VIRTIO_BLK_S_UNSUPP;
-               wlen = sizeof(in);
+               wlen = sizeof(*in);
        } else if (out->type & VIRTIO_BLK_T_OUT) {
                /* Write */
 
@@ -1363,7 +1364,7 @@ static bool service_io(struct device *dev)
                        /* Die, bad Guest, die. */
                        errx(1, "Write past end %llu+%u", off, ret);
                }
-               wlen = sizeof(in);
+               wlen = sizeof(*in);
                in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
        } else {
                /* Read */
@@ -1376,10 +1377,10 @@ static bool service_io(struct device *dev)
                ret = readv(vblk->fd, iov+1, in_num-1);
                verbose("READ from sector %llu: %i\n", out->sector, ret);
                if (ret >= 0) {
-                       wlen = sizeof(in) + ret;
+                       wlen = sizeof(*in) + ret;
                        in->status = VIRTIO_BLK_S_OK;
                } else {
-                       wlen = sizeof(in);
+                       wlen = sizeof(*in);
                        in->status = VIRTIO_BLK_S_IOERR;
                }
        }
index 4269a1105b378fafcc689435a2531b9d9d4287db..1a45f11e645e978f445ba7396f0c5411a1695e06 100644 (file)
@@ -45,6 +45,29 @@ long fails. The definition looks like :
 typedef struct { atomic_long_t a; } local_t;
 
 
+* Rules to follow when using local atomic operations
+
+- Variables touched by local ops must be per cpu variables.
+- _Only_ the CPU owner of these variables must write to them.
+- This CPU can use local ops from any context (process, irq, softirq, nmi, ...)
+  to update its local_t variables.
+- Preemption (or interrupts) must be disabled when using local ops in
+  process context to   make sure the process won't be migrated to a
+  different CPU between getting the per-cpu variable and doing the
+  actual local op.
+- When using local ops in interrupt context, no special care must be
+  taken on a mainline kernel, since they will run on the local CPU with
+  preemption already disabled. I suggest, however, to explicitly
+  disable preemption anyway to make sure it will still work correctly on
+  -rt kernels.
+- Reading the local cpu variable will provide the current copy of the
+  variable.
+- Reads of these variables can be done from any CPU, because updates to
+  "long", aligned, variables are always atomic. Since no memory
+  synchronization is done by the writer CPU, an outdated copy of the
+  variable can be read when reading some _other_ cpu's variables.
+
+
 * Rules to follow when using local atomic operations
 
 - Variables touched by local ops must be per cpu variables.
index 295a71bc301ebb067fbf7d2ee6770e14426c063a..d9f50a19fa0c48185968e875aa2c9163bae3e6fa 100644 (file)
@@ -35,12 +35,14 @@ In order to use the macro trace_mark, you should include linux/marker.h.
 
 And,
 
-trace_mark(subsystem_event, "%d %s", someint, somestring);
+trace_mark(subsystem_event, "myint %d mystring %s", someint, somestring);
 Where :
 - subsystem_event is an identifier unique to your event
     - subsystem is the name of your subsystem.
     - event is the name of the event to mark.
-- "%d %s" is the formatted string for the serializer.
+- "myint %d mystring %s" is the formatted string for the serializer. "myint" and
+  "mystring" are repectively the field names associated with the first and
+  second parameter.
 - someint is an integer.
 - somestring is a char pointer.
 
index f5a5e6d3d5419598775d096aa351bd4f5f90741e..563e442f2d4246a37ffd46250fa64fa0e494c645 100644 (file)
@@ -4,8 +4,6 @@
        - information on the 3Com EtherLink Plus (3c505) driver.
 6pack.txt
        - info on the 6pack protocol, an alternative to KISS for AX.25
-Configurable
-       - info on some of the configurable network parameters
 DLINK.txt
        - info on the D-Link DE-600/DE-620 parallel port pocket adapters
 PLIP.txt
@@ -26,8 +24,6 @@ baycom.txt
        - info on the driver for Baycom style amateur radio modems
 bridge.txt
        - where to get user space programs for ethernet bridging with Linux.
-comx.txt
-       - info on drivers for COMX line of synchronous serial adapters.
 cops.txt
        - info on the COPS LocalTalk Linux driver
 cs89x0.txt
@@ -78,20 +74,14 @@ ltpc.txt
        - the Apple or Farallon LocalTalk PC card driver
 multicast.txt
        - Behaviour of cards under Multicast
-ncsa-telnet
-       - notes on how NCSA telnet (DOS) breaks with MTU discovery enabled.
 netdevices.txt
        - info on network device driver functions exported to the kernel.
 olympic.txt
        - IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info.
 policy-routing.txt
        - IP policy-based routing
-pt.txt
-       - the Gracilis Packetwin AX.25 device driver
 ray_cs.txt
        - Raylink Wireless LAN card driver info.
-routing.txt
-       - the new routing mechanism
 shaper.txt
        - info on the module that can shape/limit transmitted traffic.
 sk98lin.txt
index b9d5b723011882a4f3eff65fe80252a0bf7b36d4..72f38b13101d74c5eb8e6f32e2d5ae4c7559f005 100644 (file)
@@ -14,8 +14,7 @@ If no base address is given at boot time, the driver will autoprobe
 ports 0x300, 0x280 and 0x310 (in that order).  If no IRQ is given, the driver
 will try to probe for it.
 
-The driver can be used as a loadable module.  See net-modules.txt for details
-of the parameters it can take.  
+The driver can be used as a loadable module.
 
 Theoretically, one instance of the driver can now run multiple cards,
 in the standard way (when loading a module, say "modprobe 3c505
diff --git a/Documentation/networking/Configurable b/Documentation/networking/Configurable
deleted file mode 100644 (file)
index 69c0dd4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-
-There are a few network parameters that can be tuned to better match
-the kernel to your system hardware and intended usage. The defaults
-are usually a good choice for 99% of the people 99% of the time, but
-you should be aware they do exist and can be changed.
-
-The current list of parameters can be found in the files:
-
-       linux/net/TUNABLE
-       Documentation/networking/ip-sysctl.txt
-
-Some of these are accessible via the sysctl interface, and many more are
-scheduled to be added in this way. For example, some parameters related 
-to Address Resolution Protocol (ARP) are very easily viewed and altered.
-
-       # cat /proc/sys/net/ipv4/arp_timeout
-       6000
-       # echo 7000 > /proc/sys/net/ipv4/arp_timeout
-       # cat /proc/sys/net/ipv4/arp_timeout
-       7000
-
-Others are already accessible via the related user space programs.
-For example, MAX_WINDOW has a default of 32 k which is a good choice for
-modern hardware, but if you have a slow (8 bit) Ethernet card and/or a slow
-machine, then this will be far too big for the card to keep up with fast 
-machines transmitting on the same net, resulting in overruns and receive errors.
-A value of about 4 k would be more appropriate, which can be set via:
-
-       # route add -net 192.168.3.0 window 4096
-
-The remainder of these can only be presently changed by altering a #define
-in the related header file. This means an edit and recompile cycle.
-
-                                               Paul Gortmaker 06/96
diff --git a/Documentation/networking/comx.txt b/Documentation/networking/comx.txt
deleted file mode 100644 (file)
index d1526eb..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-
-               COMX drivers for the 2.2 kernel
-
-Originally written by: Tivadar Szemethy, <tiv@itc.hu>
-Currently maintained by: Gergely Madarasz <gorgo@itc.hu>
-
-Last change: 21/06/1999.
-
-INTRODUCTION
-
-This document describes the software drivers and their use for the 
-COMX line of synchronous serial adapters for Linux version 2.2.0 and
-above.
-The cards are produced and sold by ITC-Pro Ltd. Budapest, Hungary
-For further info contact <info@itc.hu> 
-or http://www.itc.hu (mostly in Hungarian).
-The firmware files and software are available from ftp://ftp.itc.hu
-
-Currently, the drivers support the following cards and protocols:
-
-COMX (2x64 kbps intelligent board)
-CMX (1x256 + 1x128 kbps intelligent board)
-HiCOMX (2x2Mbps intelligent board)
-LoCOMX (1x512 kbps passive board)
-MixCOM (1x512 or 2x512kbps passive board with a hardware watchdog an
-       optional BRI interface and optional flashROM (1-32M))
-SliceCOM       (1x2Mbps channelized E1 board)
-PciCOM (X21)
-
-At the moment of writing this document, the (Cisco)-HDLC, LAPB, SyncPPP and
-Frame Relay (DTE, rfc1294 IP encapsulation with partially implemented Q933a 
-LMI) protocols are available as link-level protocol. 
-X.25 support is being worked on.
-
-USAGE
-
-Load the comx.o module and the hardware-specific and protocol-specific 
-modules you'll need into the running kernel using the insmod utility.
-This creates the /proc/comx directory.
-See the example scripts in the 'etc' directory.
-
-/proc INTERFACE INTRO
-
-The COMX driver set has a new type of user interface based on the /proc 
-filesystem which eliminates the need for external user-land software doing 
-IOCTL calls. 
-Each network interface or device (i.e. those ones you configure with 'ifconfig'
-and 'route' etc.) has a corresponding directory under /proc/comx. You can
-dynamically create a new interface by saying 'mkdir /proc/comx/comx0' (or you
-can name it whatever you want up to 8 characters long, comx[n] is just a 
-convention).
-Generally the files contained in these directories are text files, which can
-be viewed by 'cat filename' and you can write a string to such a file by
-saying 'echo _string_ >filename'. This is very similar to the sysctl interface.
-Don't use a text editor to edit these files, always use 'echo' (or 'cat'
-where appropriate).
-When you've created the comx[n] directory, two files are created automagically
-in it: 'boardtype' and 'protocol'. You have to fill in these files correctly
-for your board and protocol you intend to use (see the board and protocol 
-descriptions in this file below or the example scripts in the 'etc' directory).
-After filling in these files, other files will appear in the directory for 
-setting the various hardware- and protocol-related informations (for example
-irq and io addresses, keepalive values etc.) These files are set to default 
-values upon creation, so you don't necessarily have to change all of them.
-
-When you're ready with filling in the files in the comx[n] directory, you can
-configure the corresponding network interface with the standard network 
-configuration utilities. If you're unable to bring the interfaces up, look up
-the various kernel log files on your system, and consult the messages for
-a probable reason.
-
-EXAMPLE
-
-To create the interface 'comx0' which is the first channel of a COMX card:
-
-insmod comx 
-# insmod comx-hw-comx ; insmod comx-proto-ppp  (these are usually
-autoloaded if you use the kernel module loader)
-
-mkdir /proc/comx/comx0
-echo comx >/proc/comx/comx0/boardtype
-echo 0x360 >/proc/comx/comx0/io                <- jumper-selectable I/O port 
-echo 0x0a >/proc/comx/comx0/irq                <- jumper-selectable IRQ line
-echo 0xd000 >/proc/comx/comx0/memaddr  <- software-configurable memory
-                                          address. COMX uses 64 KB, and this
-                                          can be: 0xa000, 0xb000, 0xc000, 
-                                          0xd000, 0xe000. Avoid conflicts
-                                          with other hardware.
-cat </etc/siol1.rom >/proc/comx/comx0/firmware <- the firmware for the card
-echo HDLC >/proc/comx/comx0/protocol   <- the data-link protocol
-echo 10 >/proc/comx/comx0/keepalive    <- the keepalive for the protocol
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255 <-
-                                          finally configure it with ifconfig
-Check its status:
-cat /proc/comx/comx0/status
-
-If you want to use the second channel of this board:
-
-mkdir /proc/comx/comx1
-echo comx >/proc/comx/comx1/boardtype
-echo 0x360 >/proc/comx/comx1/io        
-echo 10 >/proc/comx/comx1/irq          
-echo 0xd000 >/proc/comx/comx1/memaddr
-echo 1 >/proc/comx/comx1/channel       <- channels are numbered 
-                                          as 0 (default) and 1
-
-Now, check if the driver recognized that you're going to use the other
-channel of the same adapter:
-
-cat /proc/comx/comx0/twin
-comx1
-cat /proc/comx/comx1/twin
-comx0
-
-You don't have to load the firmware twice, if you use both channels of
-an adapter, just write it into the channel 0's /proc firmware file.
-
-Default values: io 0x360 for COMX, 0x320 (HICOMX), irq 10, memaddr 0xd0000
-
-THE LOCOMX HARDWARE DRIVER
-
-The LoCOMX driver doesn't require firmware, and it doesn't use memory either,
-but it uses DMA channels 1 and 3. You can set the clock rate (if enabled by
-jumpers on the board) by writing the kbps value into the file named 'clock'.
-Set it to 'external' (it is the default) if you have external clock source.
-
-(Note: currently the LoCOMX driver does not support the internal clock)
-
-THE COMX, CMX AND HICOMX DRIVERS
-
-On the HICOMX, COMX and CMX, you have to load the firmware (it is different for
-the three cards!). All these adapters can share the same memory
-address (we usually use 0xd0000). On the CMX you can set the internal
-clock rate (if enabled by jumpers on the small adapter boards) by writing
-the kbps value into the 'clock' file. You have to do this before initializing
-the card. If you use both HICOMX and CMX/COMX cards, initialize the HICOMX
-first. The I/O address of the HICOMX board is not configurable by any
-method available to the user: it is hardwired to 0x320, and if you have to 
-change it, consult ITC-Pro Ltd.
-
-THE MIXCOM DRIVER
-
-The MixCOM board doesn't require firmware, the driver communicates with
-it through I/O ports. You can have three of these cards in one machine.
-
-THE SLICECOM DRIVER
-
-The SliceCOM board doesn't require firmware. You can have 4 of these cards
-in one machine. The driver doesn't (yet) support shared interrupts, so
-you will need a separate IRQ line for every board.
-Read Documentation/networking/slicecom.txt for help on configuring
-this adapter.
-
-THE HDLC/PPP LINE PROTOCOL DRIVER
-
-The HDLC/SyncPPP line protocol driver uses the kernel's built-in syncppp
-driver (syncppp.o). You don't have to manually select syncppp.o when building
-the kernel, the dependencies compile it in automatically.
-
-
-
-
-EXAMPLE
-(setting up hw parameters, see above)
-
-# using HDLC:
-echo hdlc >/proc/comx/comx0/protocol
-echo 10 >/proc/comx/comx0/keepalive    <- not necessary, 10 is the default
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-(setting up hw parameters, see above)
-
-# using PPP:
-echo ppp >/proc/comx/comx0/protocol
-ifconfig comx0 up
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-
-THE LAPB LINE PROTOCOL DRIVER
-
-For this, you'll need to configure LAPB support (See 'LAPB Data Link Driver' in
-'Network options' section) into your kernel (thanks to Jonathan Naylor for his 
-excellent implementation). 
-comx-proto-lapb.o provides the following files in the appropriate directory
-(the default values in parens): t1 (5), t2 (1), n2 (20), mode (DTE, STD) and
-window (7). Agree with the administrator of your peer router on these
-settings (most people use defaults, but you have to know if you are DTE or
-DCE).
-
-EXAMPLE
-
-(setting up hw parameters, see above)
-echo lapb >/proc/comx/comx0/protocol
-echo dce >/proc/comx/comx0/mode                <- DCE interface in this example
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-
-THE FRAME RELAY PROTOCOL DRIVER
-
-You DON'T need any other frame relay related modules from the kernel to use
-COMX-Frame Relay. This protocol is a bit more complicated than the others, 
-because it allows to use 'subinterfaces' or DLCIs within one physical device.
-First you have to create the 'master' device (the actual physical interface)
-as you would do for other protocols. Specify 'frad' as protocol type.
-Now you can bring this interface up by saying 'ifconfig comx0 up' (or whatever
-you've named the interface). Do not assign any IP address to this interface
-and do not set any routes through it.
-Then, set up your DLCIs the following way: create a comx interface for each
-DLCI you intend to use (with mkdir), and write 'dlci' to the 'boardtype' file, 
-and 'ietf-ip' to the 'protocol' file. Currently, the only supported 
-encapsulation type is this (also called as RFC1294/1490 IP encapsulation).
-Write the DLCI number to the 'dlci' file, and write the name of the physical
-COMX device to the file called 'master'. 
-Now you can assign an IP address to this interface and set routes using it.
-See the example file for further info and example config script.
-Notes: this driver implements a DTE interface with partially implemented
-Q933a LMI.
-You can find an extensively commented example in the 'etc' directory.
-
-FURTHER /proc FILES
-
-boardtype:
-Type of the hardware. Valid values are:
- 'comx', 'hicomx', 'locomx', 'cmx', 'slicecom'.
-
-protocol:
-Data-link protocol on this channel. Can be: HDLC, LAPB, PPP, FRAD
-
-status:
-You can read the channel's actual status from the 'status' file, for example
-'cat /proc/comx/comx3/status'.
-
-lineup_delay:
-Interpreted in seconds (default is 1). Used to avoid line jitter: the system
-will consider the line status 'UP' only if it is up for at least this number
-of seconds.
-
-debug: 
-You can set various debug options through this file. Valid options are:
-'comx_events', 'comx_tx', 'comx_rx', 'hw_events', 'hw_tx', 'hw_rx'.
-You can enable a debug options by writing its name prepended by a '+' into
-the debug file, for example 'echo +comx_rx >comx0/debug'. 
-Disabling an option happens similarly, use the '-' prefix 
-(e.g. 'echo -hw_rx >debug').
-Debug results can be read from the debug file, for example: 
-tail -f /proc/comx/comx2/debug
-
-
diff --git a/Documentation/networking/ncsa-telnet b/Documentation/networking/ncsa-telnet
deleted file mode 100644 (file)
index d77d28b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-NCSA telnet doesn't work with path MTU discovery enabled. This is due to a
-bug in NCSA that also stops it working with other modern networking code
-such as Solaris.
-
-The following information is courtesy of 
-Marek <marekm@i17linuxb.ists.pwr.wroc.pl>
-
-There is a fixed version somewhere on ftp.upe.ac.za (sorry, I don't
-remember the exact pathname, and this site is very slow from here).
-It may or may not be faster for you to get it from
-ftp://ftp.ists.pwr.wroc.pl/pub/msdos/telnet/ncsa_upe/tel23074.zip
-(source is in v230704s.zip).  I have tested it with 1.3.79 (with
-path mtu discovery enabled - ncsa 2.3.08 didn't work) and it seems
-to work.  I don't know if anyone is working on this code - this
-version is over a year old.  Too bad - it's faster and often more
-stable than these windoze telnets, and runs on almost anything...
diff --git a/Documentation/networking/pt.txt b/Documentation/networking/pt.txt
deleted file mode 100644 (file)
index 72e888c..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-This is the README for the Gracilis Packetwin device driver, version 0.5
-ALPHA for Linux 1.3.43.
-
-These files will allow you to talk to the PackeTwin (now know as PT) and
-connect through it just like a pair of TNCs.  To do this you will also
-require the AX.25 code in the kernel enabled.
-
-There are four files in this archive; this readme, a patch file, a .c file
-and finally a .h file.  The two program files need to be put into the
-drivers/net directory in the Linux source tree, for me this is the
-directory /usr/src/linux/drivers/net.  The patch file needs to be patched in
-at the top of the Linux source tree (/usr/src/linux in my case).
-
-You will most probably have to edit the pt.c file to suit your own setup,
-this should just involve changing some of the defines at the top of the file. 
-Please note that if you run an external modem you must specify a speed of 0.
-
-The program is currently setup to run a 4800 baud external modem on port A
-and a Kantronics DE-9600 daughter board on port B so if you have this (or
-something similar) then you're right.
-
-To compile in the driver, put the files in the correct place and patch in
-the diff.  You will have to re-configure the kernel again before you
-recompile it. 
-
-The driver is not real good at the moment for finding the card.  You can
-'help' it by changing the order of the potential addresses in the structure
-found in the pt_init() function so the address of where the card is is put
-first.
-
-After compiling, you have to get them going, they are pretty well like any
-other net device and just need ifconfig to get them going.
-As an example, here is my /etc/rc.net
---------------------------
-
-#
-# Configure the PackeTwin, port A.
-/sbin/ifconfig pt0a 44.136.8.87 hw ax25 vk2xlz mtu 512 
-/sbin/ifconfig pt0a 44.136.8.87 broadcast 44.136.8.255 netmask 255.255.255.0
-/sbin/route add -net 44.136.8.0 netmask 255.255.255.0 dev pt0a
-/sbin/route add -net 44.0.0.0 netmask 255.0.0.0 gw 44.136.8.68 dev pt0a
-/sbin/route add -net 138.25.16.0 netmask 255.255.240.0 dev pt0a
-/sbin/route add -host 44.136.8.255 dev pt0a
-#
-# Configure the PackeTwin, port B.
-/sbin/ifconfig pt0b 44.136.8.87 hw ax25 vk2xlz-1 mtu 512
-/sbin/ifconfig pt0b 44.136.8.87 broadcast 44.255.255.255 netmask 255.0.0.0
-/sbin/route add -host 44.136.8.216 dev pt0b
-/sbin/route add -host 44.136.8.95  dev pt0b
-/sbin/route add -host 44.255.255.255 dev pt0b
-
-This version of the driver comes under the GNU GPL.  If you have one of my
-previous (non-GPL) versions of the driver, please update to this one.
-
-I hope that this all works well for you.  I would be pleased to hear how
-many people use the driver and if it does its job.
-
-  - Craig vk2xlz <csmall@small.dropbear.id.au>
diff --git a/Documentation/networking/routing.txt b/Documentation/networking/routing.txt
deleted file mode 100644 (file)
index a26838b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-The directory ftp.inr.ac.ru:/ip-routing contains:
-
-- iproute.c - "professional" routing table maintenance utility.
-
-- rdisc.tar.gz - rdisc daemon, ported from Sun.
-       STRONGLY RECOMMENDED FOR ALL HOSTS.
-
-- routing.tgz - original Mike McLagan's route by source patch.
-               Currently it is obsolete.
-
-- gated.dif-ss<NEWEST>.gz - gated-R3_6Alpha_2 fixes.
-               Look at README.gated
-
-- mrouted-3.8.dif.gz - mrouted-3.8 fixes.
-
-- rtmon.c - trivial debugging utility: reads and stores netlink.
-
-
-NEWS for user.
-
-- Policy based routing. Routing decisions are made on the basis
-  not only of destination address, but also source address,
-  TOS and incoming interface.
-- Complete set of IP level control messages.
-  Now Linux is the only OS in the world complying to RFC requirements.
-  Great win 8)
-- New interface addressing paradigm.
-  Assignment of address ranges to interface,
-  multiple prefixes etc. etc.
-  Do not bother, it is compatible with the old one. Moreover:
-- You don't need to do "route add aaa.bbb.ccc... eth0" anymore,
-  it is done automatically.
-- "Abstract" UNIX sockets and security enhancements.
-  This is necessary to use TIRPC and TLI emulation library.
-
-NEWS for hacker.
-
-- New destination cache. Flexible, robust and just beautiful.
-- Network stack is reordered, simplified, optimized, a lot of bugs fixed.
-  (well, and new bugs were introduced, but I haven't seen them yet 8))
-  It is difficult to describe all the changes, look into source.
-
-If you see this file, then this patch works 8)
-
-Alexey Kuznetsov.
-kuznet@ms2.inr.ac.ru
diff --git a/Documentation/networking/slicecom.hun b/Documentation/networking/slicecom.hun
deleted file mode 100644 (file)
index bed2f04..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-
-SliceCOM adapter felhasznaloi dokumentacioja - 0.51 verziohoz
-
-Bartók István <bartoki@itc.hu>
-Utolso modositas: Wed Aug 29 17:26:58 CEST 2001
-
------------------------------------------------------------------
-
-Hasznalata:
-
-Forditas:
-
-Code maturity level options
-       [*] Prompt for development and/or incomplete code/drivers
-
-Network device support
-       Wan interfaces
-               <M> MultiGate (COMX) synchronous
-                       <M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
-                       <M> Support for HDLC and syncPPP...
-
-
-A modulok betoltese:
-
-modprobe comx
-
-modprobe comx-proto-ppp                # a Cisco-HDLC es a SyncPPP protokollt is
-                               # ez a modul adja
-
-modprobe comx-hw-munich                # a modul betoltodeskor azonnal jelent a
-                               # syslogba a detektalt kartyakrol
-
-
-Konfiguralas:
-
-# Ezen az interfeszen Cisco-HDLC vonali protokoll fog futni
-# Az interfeszhez rendelt idoszeletek: 1,2 (128 kbit/sec-es vonal)
-# (a G.703 keretben az elso adatot vivo idoszelet az 1-es)
-#
-mkdir /proc/comx/comx0.1/
-echo slicecom  >/proc/comx/comx0.1/boardtype
-echo hdlc      >/proc/comx/comx0.1/protocol
-echo 1 2       >/proc/comx/comx0.1/timeslots
-
-
-# Ezen az interfeszen SyncPPP vonali protokoll fog futni
-# Az interfeszhez rendelt idoszelet: 3 (64 kbit/sec-es vonal)
-#
-mkdir /proc/comx/comx0.2/
-echo slicecom  >/proc/comx/comx0.2/boardtype
-echo ppp       >/proc/comx/comx0.2/protocol
-echo 3         >/proc/comx/comx0.2/timeslots
-
-...
-
-ifconfig comx0.1 up
-ifconfig comx0.2 up
-
------------------------------------------------------------------
-
-A COMX driverek default 20 csomagnyi transmit queue-t rendelnek a halozati
-interfeszekhez. WAN halozatokban ennel hosszabbat is szokas hasznalni
-(20 es 100 kozott), hogy a vonal kihasznaltsaga nagy terheles eseten jobb
-legyen (bar ezzel megno a varhato kesleltetes a csomagok sorban allasa miatt):
-
-# ifconfig comx0 txqueuelen 50
-
-Ezt a beallitasi lehetoseget csak az ujabb disztribuciok ifconfig parancsa
-tamogatja (amik mar a 2.2 kernelekhez keszultek, mint a RedHat 6.1 vagy a
-Debian 2.2).
-
-A 2.1-es Debian disztribuciohoz a http://www.debian.org/~rcw/2.2/netbase/
-cimrol toltheto le ujabb netbase csomag, ami mar ilyet tamogato ifconfig
-parancsot tartalmaz. Bovebben a 2.2 kernel hasznalatarol Debian 2.1 alatt:
-http://www.debian.org/releases/stable/running-kernel-2.2
-
------------------------------------------------------------------
-
-A kartya LED-jeinek jelentese:
-
-piros  - eg, ha Remote Alarm-ot kuld a tuloldal
-zold   - eg, ha a vett jelben megtalalja a keretszinkront
-
-Reszletesebben:
-
-piros: zold:   jelentes:
-
--      -       nincs keretszinkron (nincs jel, vagy rossz a jel)
--      eg      "minden rendben"
-eg     eg      a vetel OK, de a tuloldal Remote Alarm-ot kuld
-eg     -       ez nincs ertelmezve, egyelore funkcio nelkul
-
------------------------------------------------------------------
-
-Reszletesebb leiras a hardver beallitasi lehetosegeirol:
-
-Az altalanos,- es a protokoll-retegek beallitasi lehetosegeirol a 'comx.txt'
-fajlban leirtak SliceCOM kartyanal is ervenyesek, itt csak a hardver-specifikus
-beallitasi lehetosegek vannak osszefoglalva:
-
-Konfiguralasi interfesz a /proc/comx/ alatt:
-
-Minden timeslot-csoportnak kulon comx* interfeszt kell letrehozni mkdir-rel:
-comx0, comx1, .. stb. Itt beallithato, hogy az adott interfesz hanyadik kartya
-melyik timeslotja(i)bol alljon ossze. A Cisco-fele serial3:1 elnevezesek
-(serial3:1 = a 3. kartyaban az 1-es idoszelet-csoport) Linuxon aliasing-ot
-jelentenenek, ezert mi nem tudunk ilyen elnevezest hasznalni.
-
-Tobb kartya eseten a comx0.1, comx0.2, ... vagy slice0.1, slice0.2 nevek
-hasznalhatoak.
-
-Tobb SliceCOM kartya is lehet egy gepben, de sajat interrupt kell mindegyiknek,
-nem tud meg megosztott interruptot kezelni.
-
-Az egesz kartyat erinto beallitasok:
-
-Az ioport es irq beallitas nincs: amit a PCI BIOS kioszt a rendszernek,
-azt hasznalja a driver.
-
-
-comx0/boardnum - hanyadik SliceCOM kartya a gepben (a 'termeszetes' PCI
-               sorrendben ertve: ahogyan a /proc/pci-ban vagy az 'lspci'
-               kimeneteben megjelenik, altalaban az alaplapi PCI meghajto
-               aramkorokhoz kozelebb eso kartyak a kisebb sorszamuak)
-
-               Default: 0 (0-tol kezdodik a szamolas)
-
-
-Bar a kovetkezoket csak egy-egy interfeszen allitjuk at, megis az egesz kartya
-mukodeset egyszerre allitjak. A megkotes hogy csak UP-ban levo interfeszen
-hasznalhatoak, azert van, mert kulonben nem vart eredmenyekre vezetne egy ilyen
-paranccsorozat:
-
-       echo 0        >boardnum
-       echo internal >clock_source
-       echo 1        >boardnum
-
-- Ez a 0-s board clock_source-at allitana at.
-
-Ezek a beallitasok megmaradnak az osszes interfesz torlesekor, de torlodnek
-a driver modul ki/betoltesekor.
-
-
-comx0/clock_source - A Tx orajelforrasa, a Cisco-val hasonlatosra keszult.
-       Hasznalata:
-
-       papaya:# echo line     >/proc/comx/comx0/clock_source
-       papaya:# echo internal >/proc/comx/comx0/clock_source
-
-       line     - A Tx orajelet a vett adatfolyambol dekodolja, igyekszik
-               igazodni hozza. Ha nem lat orajelet az inputon, akkor
-               atall a sajat orajelgeneratorara.
-       internal - A Tx orajelet a sajat orajelgeneratora szolgaltatja.
-
-       Default: line
-
-       Normal osszeallitas eseten a tavkozlesi szolgaltato eszkoze
-       (pl. HDSL modem) adja az orajelet, ezert ez a default.
-
-
-comx0/framing  - A CRC4 ki/be kapcsolasa
-
-       A CRC4: 16 PCM keretet (A PCM keret az, amibe a 32 darab 64
-       kilobites csatorna van bemultiplexalva. Nem osszetevesztendo a HDLC
-       kerettel.) 2x8 -as csoportokra osztanak, es azokhoz 4-4 bites CRC-t
-       szamolnak. Elsosorban a vonal minosegenek a monitorozasara szolgal.
-
-       papaya:~# echo crc4     >/proc/comx/comx0/framing
-       papaya:~# echo no-crc4  >/proc/comx/comx0/framing
-
-       Default a 'crc4', a MATAV vonalak altalaban igy futnak. De ha nem
-       egyforma is a beallitas a vonal ket vegen, attol a forgalom altalaban
-       at tud menni.
-
-
-comx0/linecode - A vonali kodolas beallitasa
-
-       papaya:~# echo hdb3     >/proc/comx/comx0/linecode
-       papaya:~# echo ami      >/proc/comx/comx0/linecode
-
-       Default a 'hdb3', a MATAV vonalak igy futnak.
-       
-       (az AMI kodolas igen ritka E1-es vonalaknal). Ha ez a beallitas nem
-       egyezik a vonal ket vegen, akkor elofordulhat hogy a keretszinkron
-       osszejon, de CRC4-hibak es a vonalakon atvitt adatokban is hibak
-       keletkeznek (amit a HDLC/SyncPPP szinten CRC-hibaval jelez)
-
-
-comx0/reg      - a kartya aramkoreinek, a MUNICH (reg) es a FALC (lbireg)
-comx0/lbireg   regisztereinek kozvetlen elerese. Hasznalata:
-
-               echo >reg 0x04 0x0      - a 4-es regiszterbe 0-t ir
-               echo >reg 0x104         - printk()-val kiirja a 4-es regiszter
-                                       tartalmat a syslogba.
-
-               WARNING: ezek csak a fejleszteshez keszultek, sok galibat
-               lehet veluk okozni!
-
-
-comx0/loopback - A kartya G.703 jelenek a visszahurkolasara is van lehetoseg:
-
-       papaya:# echo none   >/proc/comx/comx0/loopback
-       papaya:# echo local  >/proc/comx/comx0/loopback
-       papaya:# echo remote >/proc/comx/comx0/loopback
-
-       none   - nincs visszahurkolas, normal mukodes
-       local  - a kartya a sajat maga altal adott jelet kapja vissza
-       remote - a kartya a kivulrol vett jelet adja kifele
-
-       Default: none
-
------------------------------------------------------------------
-
-Az interfeszhez (Cisco terminologiaban 'channel-group') kapcsolodo beallitasok:
-
-comx0/timeslots        - mely timeslotok (idoszeletek) tartoznak az adott interfeszhez.
-
-       papaya:~# cat /proc/comx/comx0/timeslots
-       1 3 4 5 6
-       papaya:~#
-
-       Egy timeslot megkeresese (hanyas interfeszbe tartozik nalunk):
-
-       papaya:~# grep ' 4' /proc/comx/comx*/timeslots
-       /proc/comx/comx0/timeslots:1 3 4 5 6
-       papaya:~#
-
-       Beallitasa:
-       papaya:~# echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
-       
-       A timeslotok sorrendje nem szamit, '1 3 2' ugyanaz mint az '1 2 3'.
-
-       Beallitashoz az adott interfesznek DOWN-ban kell lennie
-       (ifconfig comx0 down), de ugyanannak a kartyanak a tobbi interfesze
-       uzemelhet kozben.
-
-       Beallitaskor leellenorzi, hogy az uj timeslotok nem utkoznek-e egy
-       masik interfesz timeslotjaival. Ha utkoznek, akkor nem allitja at.
-
-       Mindig 10-es szamrendszerben tortenik a timeslotok ertelmezese, nehogy
-       a 08, 09 alaku felirast rosszul ertelmezze.
-
------------------------------------------------------------------
-
-Az interfeszek es a kartya allapotanak lekerdezese:
-
-- A ' '-szel kezdodo sorok az eredeti kimenetet, a //-rel kezdodo sorok a
-magyarazatot jelzik.
-
- papaya:~$ cat /proc/comx/comx1/status
- Interface administrative status is UP, modem status is UP, protocol is UP
- Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
- Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
-               (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
- Debug flags: none
- RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
-            buffer overrun: 0, pbuffer overrun: 0
- TX errors: underrun: 0
- Line keepalive (value: 10) status UP [0]
-
-// Itt kezdodik a hardver-specifikus resz:
- Controller status:
-         No alarms
-
-// Alarm: hibajelzes:
-//
-// No alarms - minden rendben
-//
-// LOS  - Loss Of Signal - nem erzekel jelet a bemeneten.
-// AIS  - Alarm Indication Signal - csak egymas utani 1-esek jonnek
-//     a bemeneten, a tuloldal igy is jelezheti hogy meghibasodott vagy
-//     nincs inicializalva.
-// AUXP - Auxiliary Pattern Indication - 01010101.. sorozat jon a bemeneten.
-// LFA  - Loss of Frame Alignment - nincs keretszinkron
-// RRA  - Receive Remote Alarm - a tuloldal el, de hibat jelez.
-// LMFA - Loss of CRC4 Multiframe Alignment - nincs CRC4-multikeret-szinkron
-// NMF  - No Multiframe alignment Found after 400 msec - ilyen alarm a no-crc4
-//     es crc4 keretezesek eseten nincs, lasd lentebb
-//
-// Egyeb lehetseges hibajelzesek:
-//
-// Transmit Line Short - a kartya ugy erzi hogy az adasi kimenete rovidre
-//     van zarva, ezert kikapcsolta az adast. (nem feltetlenul veszi eszre
-//     a kulso rovidzarat)
-
-// A veteli oldal csomagjainak lancolt listai, debug celokra:
-
- Rx ring:
-         rafutott: 0
-         lastcheck: 50845731, jiffies: 51314281
-         base: 017b1858
-         rx_desc_ptr: 0
-         rx_desc_ptr: 017b1858
-         hw_curr_ptr: 017b1858
-         06040000 017b1868 017b1898 c016ff00
-         06040000 017b1878 017b1e9c c016ff00
-         46040000 017b1888 017b24a0 c016ff00
-         06040000 017b1858 017b2aa4 c016ff00
-
-// A kartyat hasznalo tobbi interfesz: a 0-s channel-group a comx1 interfesz,
-// es az 1,2,...,16 timeslotok tartoznak hozza:
-
- Interfaces using this board: (channel-group, interface, timeslots)
-          0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-          1 comx2: 17
-          2 comx3: 18
-          3 comx4: 19
-          4 comx5: 20
-          5 comx6: 21
-          6 comx7: 22
-          7 comx8: 23
-          8 comx9: 24
-          9 comx10: 25
-         10 comx11: 26
-         11 comx12: 27
-         12 comx13: 28
-         13 comx14: 29
-         14 comx15: 30
-         15 comx16: 31
-
-// Hany esemenyt kezelt le a driver egy-egy hardver-interrupt kiszolgalasanal:
-
- Interrupt work histogram:
- hist[ 0]:        0 hist[ 1]:        2 hist[ 2]:    18574 hist[ 3]:       79
- hist[ 4]:       14 hist[ 5]:        1 hist[ 6]:        0 hist[ 7]:        1
- hist[ 8]:        0 hist[ 9]:        7
-
-// Hany kikuldendo csomag volt mar a Tx-ringben amikor ujabb lett irva bele:
-
- Tx ring histogram:
- hist[ 0]:     2329 hist[ 1]:        0 hist[ 2]:        0 hist[ 3]:        0
-
-// Az E1-interfesz hiba-szamlaloi, az rfc2495-nek megfeleloen:
-// (kb. a Cisco routerek "show controllers e1" formatumaban: http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
-
-Data in current interval (91 seconds elapsed):
-   9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
-   0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
-Data in Interval 1 (15 minutes):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 4 intervals (1 hour):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 96 intervals (24 hours):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-
------------------------------------------------------------------
-
-Nehany kulonlegesebb beallitasi lehetoseg (idovel beepulhetnek majd a driverbe):
-Ezekkel sok galibat lehet okozni, nagyon ovatosan kell oket hasznalni!
-
-       modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
-       devices: (lasd page 107 es g706 Annex B)
-               lbireg[ 0x1b ] |= 0x08
-               lbireg[ 0x1c ] |= 0xc0
-       - ilyenkor ertelmezett az NMF - 'No Multiframe alignment Found after
-       400 msec' alarm.
-
-       FALC - a vonali meghajto IC
-       local loop - a sajat adasomat halljam vissza
-       remote loop - a kivulrol jovo adast adom vissza
-
-       Egy hibakeresesre hasznalhato dolog:
-               - 1-es timeslot local loop a FALC-ban:  echo >lbireg 0x1d 0x21
-               - local loop kikapcsolasa:              echo >lbireg 0x1d 0x00
diff --git a/Documentation/networking/slicecom.txt b/Documentation/networking/slicecom.txt
deleted file mode 100644 (file)
index c82c0cf..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-
-SliceCOM adapter user's documentation - for the 0.51 driver version
-
-Written by Bartók István <bartoki@itc.hu>
-
-English translation: Lakatos György <gyuri@itc.hu>
-Mon Dec 11 15:28:42 CET 2000
-
-Last modified: Wed Aug 29 17:25:37 CEST 2001
-
------------------------------------------------------------------
-
-Usage:
-
-Compiling the kernel:
-
-Code maturity level options
-       [*] Prompt for development and/or incomplete code/drivers
-
-Network device support
-       Wan interfaces
-               <M> MultiGate (COMX) synchronous
-                       <M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
-                       <M> Support for HDLC and syncPPP...
-
-
-Loading the modules:
-
-modprobe comx
-
-modprobe comx-proto-ppp                # module for  Cisco-HDLC and SyncPPP protocols
-
-modprobe comx-hw-munich                # the module logs information by the kernel
-                               # about the detected boards
-
-
-Configuring the board:
-
-# This interface will use the Cisco-HDLC line protocol,
-# the timeslices assigned are 1,2 (128 KiBit line speed)
-# (the first data timeslice in the G.703 frame is no. 1)
-#
-mkdir /proc/comx/comx0.1/
-echo slicecom  >/proc/comx/comx0.1/boardtype
-echo hdlc      >/proc/comx/comx0.1/protocol
-echo 1 2       >/proc/comx/comx0.1/timeslots
-
-
-# This interface uses SyncPPP line protocol, the assigned 
-# is no. 3 (64 KiBit line speed)
-#
-mkdir /proc/comx/comx0.2/
-echo slicecom  >/proc/comx/comx0.2/boardtype
-echo ppp       >/proc/comx/comx0.2/protocol
-echo 3         >/proc/comx/comx0.2/timeslots
-
-...
-
-ifconfig comx0.1 up
-ifconfig comx0.2 up
-
------------------------------------------------------------------
-
-The COMX interfaces use a 10 packet transmit queue by default, however WAN
-networks sometimes use bigger values (20 to 100), to utilize the line better
-by large traffic (though the line delay increases because of more packets
-join the queue).
-
-# ifconfig comx0 txqueuelen 50
-
-This option is only supported by the ifconfig command of the later 
-distributions, which came with 2.2 kernels, such as RedHat 6.1 or Debian 2.2.
-
-You can download a newer netbase packet from 
-http://www.debian.org/~rcw/2.2/netbase/ for Debian 2.1, which has a new
-ifconfig. You can get further information about using 2.2 kernel with
-Debian 2.1 from http://www.debian.org/releases/stable/running-kernel-2.2
-
------------------------------------------------------------------
-
-The SliceCom LEDs:
-
-red    - on, if the interface is unconfigured, or it gets Remote Alarm-s
-green  - on, if the board finds frame-sync in the received signal      
-
-A bit more detailed:
-
-red:   green:  meaning:
-
--      -       no frame-sync, no signal received, or signal SNAFU.
--      on      "Everything is OK"
-on     on      Reception is ok, but the remote end sends Remote Alarm
-on     -       The interface is unconfigured
-
------------------------------------------------------------------
-
-A more detailed description of the hardware setting options:
-
-The general and the protocol layer options described in the 'comx.txt' file
-apply to the SliceCom as well, I only summarize the SliceCom hardware specific
-settings below.
-
-The '/proc/comx' configuring interface:
-
-An interface directory should be created for every timeslot group with
-'mkdir', e,g: 'comx0', 'comx1' etc. The timeslots can be assigned here to the
-specific interface. The Cisco-like naming convention (serial3:1 - first
-timeslot group of the 3rd. board) can't be used here, because these mean IP
-aliasing in Linux.
-
-You can give any meaningful name to keep the configuration clear; 
-e.g: 'comx0.1', 'comx0.2', 'comx1.1', comx1.2', if you have two boards
-with two interfaces each.
-
-Settings, which apply to the board:
-
-Neither 'io' nor 'irq' settings required, the driver uses the resources
-given by the PCI BIOS.
-
-comx0/boardnum - board number of the SliceCom in the PC (using the 'natural'
-               PCI order) as listed in '/proc/pci' or the output of the
-               'lspci' command, generally the slots nearer to the motherboard
-               PCI driver chips have the lower numbers.
-               
-               Default: 0 (the counting starts with 0)
-
-Though the options below are to be set on a single interface, they apply to the
-whole board. The restriction, to use them on 'UP' interfaces, is because the 
-command sequence below could lead to unpredictable results.
-
-       # echo 0        >boardnum
-       # echo internal >clock_source
-       # echo 1        >boardnum
-
-The sequence would set the clock source of board 0.
-
-These settings will persist after all the interfaces are cleared, but are
-cleared when the driver module is unloaded and loaded again.
-
-comx0/clock_source - source of the transmit clock
-       Usage:
-
-       # echo line     >/proc/comx/comx0/clock_source
-       # echo internal >/proc/comx/comx0/clock_source
-
-       line    - The Tx clock is being decoded if the input data stream,
-               if no clock seen on the input, then the board will use it's
-               own clock generator.
-
-       internal - The Tx clock is supplied by the builtin clock generator.     
-
-       Default: line
-
-       Normally, the telecommunication company's end device (the HDSL
-       modem) provides the Tx clock, that's why 'line' is the default.
-
-comx0/framing  - Switching CRC4 off/on
-
-       CRC4: 16 PCM frames (The 32 64Kibit channels are multiplexed into a
-       PCM frame, nothing to do with HDLC frames) are divided into 2x8
-       groups, each group has a 4 bit CRC.
-
-       # echo crc4     >/proc/comx/comx0/framing
-       # echo no-crc4  >/proc/comx/comx0/framing
-
-       Default is 'crc4', the Hungarian MATAV lines behave like this. 
-       The traffic generally passes if this setting on both ends don't match.
-
-comx0/linecode - Setting the line coding
-
-       # echo hdb3     >/proc/comx/comx0/linecode
-       # echo ami      >/proc/comx/comx0/linecode
-
-       Default a 'hdb3', MATAV lines use this.
-       
-       (AMI coding is rarely used with E1 lines). Frame sync may occur, if
-       this setting doesn't match the other end's, but CRC4 and data errors
-       will come, which will result in CRC errors on HDLC/SyncPPP level. 
-
-comx0/reg      - direct access to the board's MUNICH (reg) and FALC (lbireg)
-comx0/lbireg   circuit's registers  
-
-       # echo >reg 0x04 0x0    - write 0 to register 4
-       # echo >reg 0x104       - write the contents of register 4 with
-                               printk() to syslog
-
-WARNING! These are only for development purposes, messing with this will
-       result much trouble!
-
-comx0/loopback - Places a loop to the board's G.703 signals
-
-       # echo none   >/proc/comx/comx0/loopback
-       # echo local  >/proc/comx/comx0/loopback
-       # echo remote >/proc/comx/comx0/loopback
-
-       none   - normal operation, no loop
-       local  - the board receives it's own output
-       remote - the board sends the received data to the remote side
-
-       Default: none
-
------------------------------------------------------------------
-
-Interface (channel group in Cisco terms) settings: 
-
-comx0/timeslots        - which timeslots belong to the given interface
-
-       Setting:
-
-       # echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
-
-       # cat /proc/comx/comx0/timeslots
-       1 2 5 6 7 8 
-       #
-
-       Finding a timeslot: 
-
-       # grep ' 4' /proc/comx/comx*/timeslots
-       /proc/comx/comx0/timeslots:1 3 4 5 6
-       #
-
-       The timeslots can be in any order, '1 2 3' is the same as '1 3 2'.
-
-       The interface has to be DOWN during the setting ('ifconfig comx0
-       down'), but the other interfaces could operate normally.
-
-       The driver checks if the assigned timeslots are vacant, if not, then
-       the setting won't be applied.
-
-       The timeslot values are treated as decimal numbers, not to misunderstand
-       values of 08, 09 form.
-
------------------------------------------------------------------
-
-Checking the interface and board status:
-
-- Lines beginning with ' ' (space) belong to the original output, the lines
-which begin with '//' are the comments.
-
- papaya:~$ cat /proc/comx/comx1/status
- Interface administrative status is UP, modem status is UP, protocol is UP
- Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
- Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
-               (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
- Debug flags: none
- RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
-            buffer overrun: 0, pbuffer overrun: 0
- TX errors: underrun: 0
- Line keepalive (value: 10) status UP [0]
-
-// The hardware specific part starts here:
- Controller status:
-         No alarms
-
-// Alarm: 
-//
-// No alarms - Everything OK
-//
-// LOS  - Loss Of Signal - No signal sensed on the input
-// AIS  - Alarm Indication Signal - The remote side sends '11111111'-s, 
-//     it tells, that there's an error condition, or it's not
-//     initialised.
-// AUXP - Auxiliary Pattern Indication - 01010101.. received.
-// LFA  - Loss of Frame Alignment - no frame sync received.
-// RRA  - Receive Remote Alarm - the remote end's OK, but signals error cond.
-// LMFA - Loss of CRC4 Multiframe Alignment - no CRC4 multiframe sync.
-// NMF  - No Multiframe alignment Found after 400 msec - no such alarm using
-//     no-crc4 or crc4 framing, see below.
-//
-// Other possible error messages:
-//
-// Transmit Line Short - the board felt, that it's output is short-circuited,
-//     so it switched the transmission off. (The board can't definitely tell,
-//     that it's output is short-circuited.)
-
-// Chained list of the received packets, for debug purposes:
-
- Rx ring:
-         rafutott: 0
-         lastcheck: 50845731, jiffies: 51314281
-         base: 017b1858
-         rx_desc_ptr: 0
-         rx_desc_ptr: 017b1858
-         hw_curr_ptr: 017b1858
-         06040000 017b1868 017b1898 c016ff00
-         06040000 017b1878 017b1e9c c016ff00
-         46040000 017b1888 017b24a0 c016ff00
-         06040000 017b1858 017b2aa4 c016ff00
-
-// All the interfaces using the board: comx1, using the 1,2,...16 timeslots,
-// comx2, using timeslot 17, etc.
-
- Interfaces using this board: (channel-group, interface, timeslots)
-          0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-          1 comx2: 17
-          2 comx3: 18
-          3 comx4: 19
-          4 comx5: 20
-          5 comx6: 21
-          6 comx7: 22
-          7 comx8: 23
-          8 comx9: 24
-          9 comx10: 25
-         10 comx11: 26
-         11 comx12: 27
-         12 comx13: 28
-         13 comx14: 29
-         14 comx15: 30
-         15 comx16: 31
-
-// The number of events handled by the driver during an interrupt cycle:
-
- Interrupt work histogram:
- hist[ 0]:        0 hist[ 1]:        2 hist[ 2]:    18574 hist[ 3]:       79
- hist[ 4]:       14 hist[ 5]:        1 hist[ 6]:        0 hist[ 7]:        1
- hist[ 8]:        0 hist[ 9]:        7
-
-// The number of packets to send in the Tx ring, when a new one arrived:
-
- Tx ring histogram:
- hist[ 0]:     2329 hist[ 1]:        0 hist[ 2]:        0 hist[ 3]:        0
-
-// The error counters of the E1 interface, according to the RFC2495,
-// (similar to the Cisco "show controllers e1" command's output:
-// http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
-
-Data in current interval (91 seconds elapsed):
-   9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
-   0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
-Data in Interval 1 (15 minutes):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 4 intervals (1 hour):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 96 intervals (24 hours):
-   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
-   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
-   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-
------------------------------------------------------------------
-
-Some unique options, (may get into the driver later):
-Treat them very carefully, these can cause much trouble!
-
-       modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
-       devices: (see page 107 and g706 Annex B)
-               lbireg[ 0x1b ] |= 0x08
-               lbireg[ 0x1c ] |= 0xc0
-
-       - The NMF - 'No Multiframe alignment Found after 400 msec' alarm 
-       comes into account.
-
-       FALC - the line driver chip.
-       local loop - I hear my transmission back.
-       remote loop - I echo the remote transmission back.
-
-       Something useful for finding errors:
-       
-               - local loop for timeslot 1 in the FALC chip:
-
-       # echo >lbireg 0x1d 0x21
-
-               - Switching the loop off:
-
-       # echo >lbireg 0x1d 0x00
index a96e85397eb792cb10e5e5cc066664846a1b289e..ac1be25c1e253e7711ecfeb5d542f471fe7eba69 100644 (file)
@@ -52,6 +52,7 @@ Table of Contents
       i) Freescale QUICC Engine module (QE)
       j) CFI or JEDEC memory-mapped NOR flash
       k) Global Utilities Block
+      l) Xilinx IP cores
 
   VII - Specifying interrupt information for devices
     1) interrupts property
@@ -851,12 +852,18 @@ address which can extend beyond that limit.
         /cpus/PowerPC,970FX@0
         /cpus/PowerPC,970FX@1
       (unit addresses do not require leading zeroes)
-    - d-cache-line-size : one cell, L1 data cache line size in bytes
-    - i-cache-line-size : one cell, L1 instruction cache line size in
+    - d-cache-block-size : one cell, L1 data cache block size in bytes (*)
+    - i-cache-block-size : one cell, L1 instruction cache block size in
       bytes
     - d-cache-size : one cell, size of L1 data cache in bytes
     - i-cache-size : one cell, size of L1 instruction cache in bytes
 
+(*) The cache "block" size is the size on which the cache management
+instructions operate. Historically, this document used the cache
+"line" size here which is incorrect. The kernel will prefer the cache
+block size and will fallback to cache line size for backward
+compatibility.
+
   Recommended properties:
 
     - timebase-frequency : a cell indicating the frequency of the
@@ -870,6 +877,10 @@ address which can extend beyond that limit.
       for the above, the common code doesn't use that property, but
       you are welcome to re-use the pSeries or Maple one. A future
       kernel version might provide a common function for this.
+    - d-cache-line-size : one cell, L1 data cache line size in bytes
+      if different from the block size
+    - i-cache-line-size : one cell, L1 instruction cache line size in
+      bytes if different from the block size
 
   You are welcome to add any property you find relevant to your board,
   like some information about the mechanism used to soft-reset the
@@ -2242,6 +2253,266 @@ platforms are moved over to use the flattened-device-tree model.
                           available.
                           For Axon: 0x0000012a
 
+   l) Xilinx IP cores
+
+   The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
+   in Xilinx Spartan and Virtex FPGAs.  The devices cover the whole range
+   of standard device types (network, serial, etc.) and miscellanious
+   devices (gpio, LCD, spi, etc).  Also, since these devices are
+   implemented within the fpga fabric every instance of the device can be
+   synthesised with different options that change the behaviour.
+
+   Each IP-core has a set of parameters which the FPGA designer can use to
+   control how the core is synthesized.  Historically, the EDK tool would
+   extract the device parameters relevant to device drivers and copy them
+   into an 'xparameters.h' in the form of #define symbols.  This tells the
+   device drivers how the IP cores are configured, but it requres the kernel
+   to be recompiled every time the FPGA bitstream is resynthesized.
+
+   The new approach is to export the parameters into the device tree and
+   generate a new device tree each time the FPGA bitstream changes.  The
+   parameters which used to be exported as #defines will now become
+   properties of the device node.  In general, device nodes for IP-cores
+   will take the following form:
+
+       (name)@(base-address) {
+               compatible = "xlnx,(ip-core-name)-(HW_VER)"
+                            [, (list of compatible devices), ...];
+               reg = <(baseaddr) (size)>;
+               interrupt-parent = <&interrupt-controller-phandle>;
+               interrupts = < ... >;
+               xlnx,(parameter1) = "(string-value)";
+               xlnx,(parameter2) = <(int-value)>;
+       };
+
+       (ip-core-name): the name of the ip block (given after the BEGIN
+                       directive in system.mhs).  Should be in lowercase
+                       and all underscores '_' converted to dashes '-'.
+       (name):         is derived from the "PARAMETER INSTANCE" value.
+       (parameter#):   C_* parameters from system.mhs.  The C_ prefix is
+                       dropped from the parameter name, the name is converted
+                       to lowercase and all underscore '_' characters are
+                       converted to dashes '-'.
+       (baseaddr):     the C_BASEADDR parameter.
+       (HW_VER):       from the HW_VER parameter.
+       (size):         equals C_HIGHADDR - C_BASEADDR + 1
+
+   Typically, the compatible list will include the exact IP core version
+   followed by an older IP core version which implements the same
+   interface or any other device with the same interface.
+
+   'reg', 'interrupt-parent' and 'interrupts' are all optional properties.
+
+   For example, the following block from system.mhs:
+
+       BEGIN opb_uartlite
+               PARAMETER INSTANCE = opb_uartlite_0
+               PARAMETER HW_VER = 1.00.b
+               PARAMETER C_BAUDRATE = 115200
+               PARAMETER C_DATA_BITS = 8
+               PARAMETER C_ODD_PARITY = 0
+               PARAMETER C_USE_PARITY = 0
+               PARAMETER C_CLK_FREQ = 50000000
+               PARAMETER C_BASEADDR = 0xEC100000
+               PARAMETER C_HIGHADDR = 0xEC10FFFF
+               BUS_INTERFACE SOPB = opb_7
+               PORT OPB_Clk = CLK_50MHz
+               PORT Interrupt = opb_uartlite_0_Interrupt
+               PORT RX = opb_uartlite_0_RX
+               PORT TX = opb_uartlite_0_TX
+               PORT OPB_Rst = sys_bus_reset_0
+       END
+
+   becomes the following device tree node:
+
+       opb-uartlite-0@ec100000 {
+               device_type = "serial";
+               compatible = "xlnx,opb-uartlite-1.00.b";
+               reg = <ec100000 10000>;
+               interrupt-parent = <&opb-intc>;
+               interrupts = <1 0>; // got this from the opb_intc parameters
+               current-speed = <d#115200>;     // standard serial device prop
+               clock-frequency = <d#50000000>; // standard serial device prop
+               xlnx,data-bits = <8>;
+               xlnx,odd-parity = <0>;
+               xlnx,use-parity = <0>;
+       };
+
+   Some IP cores actually implement 2 or more logical devices.  In this case,
+   the device should still describe the whole IP core with a single node
+   and add a child node for each logical device.  The ranges property can
+   be used to translate from parent IP-core to the registers of each device.
+   (Note: this makes the assumption that both logical devices have the same
+   bus binding.  If this is not true, then separate nodes should be used for
+   each logical device).  The 'cell-index' property can be used to enumerate
+   logical devices within an IP core.  For example, the following is the
+   system.mhs entry for the dual ps2 controller found on the ml403 reference
+   design.
+
+       BEGIN opb_ps2_dual_ref
+               PARAMETER INSTANCE = opb_ps2_dual_ref_0
+               PARAMETER HW_VER = 1.00.a
+               PARAMETER C_BASEADDR = 0xA9000000
+               PARAMETER C_HIGHADDR = 0xA9001FFF
+               BUS_INTERFACE SOPB = opb_v20_0
+               PORT Sys_Intr1 = ps2_1_intr
+               PORT Sys_Intr2 = ps2_2_intr
+               PORT Clkin1 = ps2_clk_rx_1
+               PORT Clkin2 = ps2_clk_rx_2
+               PORT Clkpd1 = ps2_clk_tx_1
+               PORT Clkpd2 = ps2_clk_tx_2
+               PORT Rx1 = ps2_d_rx_1
+               PORT Rx2 = ps2_d_rx_2
+               PORT Txpd1 = ps2_d_tx_1
+               PORT Txpd2 = ps2_d_tx_2
+       END
+
+   It would result in the following device tree nodes:
+
+       opb_ps2_dual_ref_0@a9000000 {
+               ranges = <0 a9000000 2000>;
+               // If this device had extra parameters, then they would
+               // go here.
+               ps2@0 {
+                       compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+                       reg = <0 40>;
+                       interrupt-parent = <&opb-intc>;
+                       interrupts = <3 0>;
+                       cell-index = <0>;
+               };
+               ps2@1000 {
+                       compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+                       reg = <1000 40>;
+                       interrupt-parent = <&opb-intc>;
+                       interrupts = <3 0>;
+                       cell-index = <0>;
+               };
+       };
+
+   Also, the system.mhs file defines bus attachments from the processor
+   to the devices.  The device tree structure should reflect the bus
+   attachments.  Again an example; this system.mhs fragment:
+
+       BEGIN ppc405_virtex4
+               PARAMETER INSTANCE = ppc405_0
+               PARAMETER HW_VER = 1.01.a
+               BUS_INTERFACE DPLB = plb_v34_0
+               BUS_INTERFACE IPLB = plb_v34_0
+       END
+
+       BEGIN opb_intc
+               PARAMETER INSTANCE = opb_intc_0
+               PARAMETER HW_VER = 1.00.c
+               PARAMETER C_BASEADDR = 0xD1000FC0
+               PARAMETER C_HIGHADDR = 0xD1000FDF
+               BUS_INTERFACE SOPB = opb_v20_0
+       END
+
+       BEGIN opb_uart16550
+               PARAMETER INSTANCE = opb_uart16550_0
+               PARAMETER HW_VER = 1.00.d
+               PARAMETER C_BASEADDR = 0xa0000000
+               PARAMETER C_HIGHADDR = 0xa0001FFF
+               BUS_INTERFACE SOPB = opb_v20_0
+       END
+
+       BEGIN plb_v34
+               PARAMETER INSTANCE = plb_v34_0
+               PARAMETER HW_VER = 1.02.a
+       END
+
+       BEGIN plb_bram_if_cntlr
+               PARAMETER INSTANCE = plb_bram_if_cntlr_0
+               PARAMETER HW_VER = 1.00.b
+               PARAMETER C_BASEADDR = 0xFFFF0000
+               PARAMETER C_HIGHADDR = 0xFFFFFFFF
+               BUS_INTERFACE SPLB = plb_v34_0
+       END
+
+       BEGIN plb2opb_bridge
+               PARAMETER INSTANCE = plb2opb_bridge_0
+               PARAMETER HW_VER = 1.01.a
+               PARAMETER C_RNG0_BASEADDR = 0x20000000
+               PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
+               PARAMETER C_RNG1_BASEADDR = 0x60000000
+               PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
+               PARAMETER C_RNG2_BASEADDR = 0x80000000
+               PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
+               PARAMETER C_RNG3_BASEADDR = 0xC0000000
+               PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
+               BUS_INTERFACE SPLB = plb_v34_0
+               BUS_INTERFACE MOPB = opb_v20_0
+       END
+
+   Gives this device tree (some properties removed for clarity):
+
+       plb-v34-0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "ibm,plb";
+               ranges; // 1:1 translation
+
+               plb-bram-if-cntrl-0@ffff0000 {
+                       reg = <ffff0000 10000>;
+               }
+
+               opb-v20-0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <20000000 20000000 20000000
+                                 60000000 60000000 20000000
+                                 80000000 80000000 40000000
+                                 c0000000 c0000000 20000000>;
+
+                       opb-uart16550-0@a0000000 {
+                               reg = <a00000000 2000>;
+                       };
+
+                       opb-intc-0@d1000fc0 {
+                               reg = <d1000fc0 20>;
+                       };
+               };
+       };
+
+   That covers the general approach to binding xilinx IP cores into the
+   device tree.  The following are bindings for specific devices:
+
+      i) Xilinx ML300 Framebuffer
+
+      Simple framebuffer device from the ML300 reference design (also on the
+      ML403 reference design as well as others).
+
+      Optional properties:
+       - resolution = <xres yres> : pixel resolution of framebuffer.  Some
+                                    implementations use a different resolution.
+                                    Default is <d#640 d#480>
+       - virt-resolution = <xvirt yvirt> : Size of framebuffer in memory.
+                                           Default is <d#1024 d#480>.
+       - rotate-display (empty) : rotate display 180 degrees.
+
+      ii) Xilinx SystemACE
+
+      The Xilinx SystemACE device is used to program FPGAs from an FPGA
+      bitstream stored on a CF card.  It can also be used as a generic CF
+      interface device.
+
+      Optional properties:
+       - 8-bit (empty) : Set this property for SystemACE in 8 bit mode
+
+      iii) Xilinx EMAC and Xilinx TEMAC
+
+      Xilinx Ethernet devices.  In addition to general xilinx properties
+      listed above, nodes for these devices should include a phy-handle
+      property, and may include other common network device properties
+      like local-mac-address.
+      
+      iv) Xilinx Uartlite
+
+      Xilinx uartlite devices are simple fixed speed serial ports.
+
+      Requred properties:
+       - current-speed : Baud rate of uartlite
+
    More devices will be defined as this spec matures.
 
 VII - Specifying interrupt information for devices
index c931d613f6410cb7dce6732ac1f68ddaf6a3ee9d..e20b19c1b60da04b95cfc62a0cec57428a53bb12 100644 (file)
@@ -180,9 +180,10 @@ driver returns ENOIOCTLCMD.  Some common examples:
     *  RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called
        to set the frequency while the framework will handle the read for you
        since the frequency is stored in the irq_freq member of the rtc_device
-       structure.  Also make sure you set the max_user_freq member in your
-       initialization routines so the framework can sanity check the user
-       input for you.
+       structure.  Your driver needs to initialize the irq_freq member during
+       init.  Make sure you check the requested frequency is in range of your
+       hardware in the irq_set_freq function.  If you cannot actually change
+       the frequency, just return -ENOTTY.
 
 If all else fails, check out the rtc-test.c driver!
 
index a3026689bbe6b62b60878c89c16355dd5c8ace8a..37f0e3cedf43dba5dacbba345ea58ecc05364888 100644 (file)
@@ -8,4 +8,7 @@
   7 -> Leadtek Winfast USB II                   (em2800)
   8 -> Kworld USB2800                           (em2800)
   9 -> Pinnacle Dazzle DVC 90                   (em2820/em2840) [2304:0207]
+ 10 -> Hauppauge WinTV HVR 900                  (em2880)
+ 11 -> Terratec Hybrid XS                       (em2880)
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
+ 13 -> Terratec Prodigy XS                      (em2880)
index 6c0e44bbf601849ff78d18f2bb63ef423c2fe6b9..cad0882754a68ebee704d42e2ec34cb1155a6b14 100644 (file)
@@ -787,23 +787,25 @@ B43 WIRELESS DRIVER
 P:     Michael Buesch
 M:     mb@bu3sch.de
 P:     Stefano Brivio
-M:     st3@riseup.net
+M:     stefano.brivio@polimi.it
 L:     linux-wireless@vger.kernel.org
-W:     http://bcm43xx.berlios.de/
+W:     http://linuxwireless.org/en/users/Drivers/b43
 S:     Maintained
 
 B43LEGACY WIRELESS DRIVER
 P:     Larry Finger
 M:     Larry.Finger@lwfinger.net
+P:     Stefano Brivio
+M:     stefano.brivio@polimi.it
 L:     linux-wireless@vger.kernel.org
-W:     http://bcm43xx.berlios.de/
+W:     http://linuxwireless.org/en/users/Drivers/b43
 S:     Maintained
 
 BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
 P:     Larry Finger
 M:     Larry.Finger@lwfinger.net
 P:     Stefano Brivio
-M:     st3@riseup.net
+M:     stefano.brivio@polimi.it
 L:     linux-wireless@vger.kernel.org
 W:     http://bcm43xx.berlios.de/
 S:     Maintained
@@ -2549,7 +2551,7 @@ S:        Supported
 
 MISCELLANEOUS MCA-SUPPORT
 P:     James Bottomley
-M:     jejb@steeleye.com
+M:     James.Bottomley@HansenPartnership.com
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
@@ -3301,9 +3303,11 @@ S:       Maintained
 
 SCSI SUBSYSTEM
 P:     James E.J. Bottomley
-M:     James.Bottomley@SteelEye.com
+M:     James.Bottomley@HansenPartnership.com
 L:     linux-scsi@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-pending-2.6.git
 S:     Maintained
 
 SCSI TAPE DRIVER
@@ -3450,15 +3454,10 @@ L:      lm-sensors@lm-sensors.org
 S:     Maintained
 
 SOFTMAC LAYER (IEEE 802.11)
-P:     Johannes Berg
-M:     johannes@sipsolutions.net
-P:     Joe Jezak
-M:     josejx@gentoo.org
 P:     Daniel Drake
 M:     dsd@gentoo.org
-W:     http://softmac.sipsolutions.net/
 L:     linux-wireless@vger.kernel.org
-S:     Maintained
+S:     Obsolete
 
 SOFTWARE RAID (Multiple Disks) SUPPORT
 P:     Ingo Molnar
index 188c3b6b3fa9ac33fbe9fba2417365eae23585d6..a65ffd27de6b5f6786f2d17cc716f003efa628b9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 24
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = Arr Matey! A Hairy Bilge Rat!
 
 # *DOCUMENTATION*
@@ -197,8 +197,13 @@ CROSS_COMPILE      ?=
 UTS_MACHINE    := $(ARCH)
 SRCARCH        := $(ARCH)
 
-# for i386 and x86_64 we use SRCARCH equal to x86
-SRCARCH := $(if $(filter x86_64 i386,$(SRCARCH)),x86,$(SRCARCH))
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+        SRCARCH := x86
+endif
+ifeq ($(ARCH),x86_64)
+        SRCARCH := x86
+endif
 
 KCONFIG_CONFIG ?= .config
 
@@ -528,9 +533,22 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
 
 # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
-KBUILD_CPPFLAGS += $(CPPFLAGS)
-KBUILD_AFLAGS   += $(AFLAGS)
-KBUILD_CFLAGS   += $(CFLAGS)
+# But warn user when we do so
+warn-assign = \
+$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
+
+ifneq ($(KCPPFLAGS),)
+        $(call warn-assign,CPPFLAGS)
+        KBUILD_CPPFLAGS += $(KCPPFLAGS)
+endif
+ifneq ($(KAFLAGS),)
+        $(call warn-assign,AFLAGS)
+        KBUILD_AFLAGS += $(KAFLAGS)
+endif
+ifneq ($(KCFLAGS),)
+        $(call warn-assign,CFLAGS)
+        KBUILD_CFLAGS += $(KCFLAGS)
+endif
 
 # Use --build-id when available.
 LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
@@ -1314,12 +1332,7 @@ else
 ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
 endif
 
-# Take care of arch/x86
-ifeq ($(ARCH), $(SRCARCH))
-ALLSOURCE_ARCHS := $(ARCH)
-else
-ALLSOURCE_ARCHS := $(ARCH) $(SRCARCH)
-endif
+ALLSOURCE_ARCHS := $(SRCARCH)
 
 define find-sources
         ( for arch in $(ALLSOURCE_ARCHS) ; do \
index a0cdaafa115b65accca46e4fdf8a4307d4ee2408..a7e9fea978a65fbb89508f428d870471b0fb7a6b 100644 (file)
@@ -1040,6 +1040,8 @@ source "drivers/power/Kconfig"
 
 source "drivers/hwmon/Kconfig"
 
+source "drivers/watchdog/Kconfig"
+
 source "drivers/ssb/Kconfig"
 
 #source "drivers/l3/Kconfig"
index 1873bd8cd1b2cb167e6ba780916c0ef6933acede..bc91d6e66bc4ea05e067d3b322b3ed8f1f64ac07 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/f75375s.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -200,11 +201,21 @@ static struct platform_device n2100_serial_device = {
        .resource       = &n2100_uart_resource,
 };
 
+static struct f75375s_platform_data n2100_f75375s = {
+       .pwm            = { 255, 255 },
+       .pwm_enable = { 0, 0 },
+};
+
 static struct i2c_board_info __initdata n2100_i2c_devices[] = {
        {
                I2C_BOARD_INFO("rtc-rs5c372", 0x32),
                .type = "rs5c372b",
        },
+       {
+               I2C_BOARD_INFO("f75375", 0x2e),
+               .type = "f75375",
+               .platform_data = &n2100_f75375s,
+       },
 };
 
 /*
index bd5184fe177c876c921b0153b3108bd2c7141df3..ca9c5b61283acd5ebe1d7c3ecce9cbb53bfd6083 100644 (file)
@@ -190,15 +190,15 @@ struct xc *request_xc(int xcno, struct device *dev)
                goto exit;
 
        if (!request_mem_region
-           (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(dev->kobj)))
+           (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(&dev->kobj)))
                goto exit_free;
 
        if (!request_mem_region
-           (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(dev->kobj)))
+           (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(&dev->kobj)))
                goto exit_release_1;
 
        if (!request_mem_region
-           (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(dev->kobj)))
+           (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(&dev->kobj)))
                goto exit_release_2;
 
        x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
index 5da798282a5451295a77074295d579c48db318ad..61d9c9d69e6b54c17d49067a3f3822e161c33d09 100644 (file)
@@ -150,22 +150,45 @@ static void clk_pxa3xx_cken_disable(struct clk *clk)
        local_irq_enable();
 }
 
+static const struct clkops clk_pxa3xx_cken_ops = {
+       .enable         = clk_pxa3xx_cken_enable,
+       .disable        = clk_pxa3xx_cken_disable,
+};
+
 static const struct clkops clk_pxa3xx_hsio_ops = {
        .enable         = clk_pxa3xx_cken_enable,
        .disable        = clk_pxa3xx_cken_disable,
        .getrate        = clk_pxa3xx_hsio_getrate,
 };
 
+#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \
+       {                                               \
+               .name   = _name,                        \
+               .dev    = _dev,                         \
+               .ops    = &clk_pxa3xx_cken_ops,         \
+               .rate   = _rate,                        \
+               .cken   = CKEN_##_cken,                 \
+               .delay  = _delay,                       \
+       }
+
+#define PXA3xx_CK(_name, _cken, _ops, _dev)            \
+       {                                               \
+               .name   = _name,                        \
+               .dev    = _dev,                         \
+               .ops    = _ops,                         \
+               .cken   = CKEN_##_cken,                 \
+       }
+
 static struct clk pxa3xx_clks[] = {
-       INIT_CK("LCDCLK", LCD,    &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
-       INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
+       PXA3xx_CK("LCDCLK", LCD,    &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
+       PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
 
-       INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
-       INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
-       INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
+       PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+       PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+       PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
 
-       INIT_CKEN("I2CCLK",  I2C,  32842000, 0, &pxa_device_i2c.dev),
-       INIT_CKEN("UDCCLK",  UDC,  48000000, 5, &pxa_device_udc.dev),
+       PXA3xx_CKEN("I2CCLK", I2C,  32842000, 0, &pxa_device_i2c.dev),
+       PXA3xx_CKEN("UDCCLK", UDC,  48000000, 5, &pxa_device_udc.dev),
 };
 
 void __init pxa3xx_init_irq(void)
index a2d45d742ce444872a6761a90500b6651c9e448f..fbfa1920353d8c9c12ef5535342d8bb2b4b5f5fd 100644 (file)
@@ -68,6 +68,7 @@ pxa_ost0_interrupt(int irq, void *dev_id)
        if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
                /* Disarm the compare/match, signal the event. */
                OIER &= ~OIER_E0;
+               OSSR = OSSR_M0;
                c->event_handler(c);
        } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
                /* Call the event handler as many times as necessary
@@ -100,9 +101,9 @@ pxa_ost0_interrupt(int irq, void *dev_id)
                 * anything that might put us "very close".
         */
 #define MIN_OSCR_DELTA 16
-       do {
+               do {
                        OSSR = OSSR_M0;
-               next_match = (OSMR0 += LATCH);
+                       next_match = (OSMR0 += LATCH);
                        c->event_handler(c);
                } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
                         && (c->mode == CLOCK_EVT_MODE_PERIODIC));
@@ -114,14 +115,16 @@ pxa_ost0_interrupt(int irq, void *dev_id)
 static int
 pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
 {
-       unsigned long irqflags;
+       unsigned long flags, next, oscr;
 
-       raw_local_irq_save(irqflags);
-       OSMR0 = OSCR + delta;
-       OSSR = OSSR_M0;
+       raw_local_irq_save(flags);
        OIER |= OIER_E0;
-       raw_local_irq_restore(irqflags);
-       return 0;
+       next = OSCR + delta;
+       OSMR0 = next;
+       oscr = OSCR;
+       raw_local_irq_restore(flags);
+
+       return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
 }
 
 static void
@@ -132,15 +135,16 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                raw_local_irq_save(irqflags);
-               OSMR0 = OSCR + LATCH;
                OSSR = OSSR_M0;
                OIER |= OIER_E0;
+               OSMR0 = OSCR + LATCH;
                raw_local_irq_restore(irqflags);
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
                raw_local_irq_save(irqflags);
                OIER &= ~OIER_E0;
+               OSSR = OSSR_M0;
                raw_local_irq_restore(irqflags);
                break;
 
@@ -149,6 +153,7 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
                /* initializing, released, or preparing for suspend */
                raw_local_irq_save(irqflags);
                OIER &= ~OIER_E0;
+               OSSR = OSSR_M0;
                raw_local_irq_restore(irqflags);
                break;
 
index cefdf2f9f26e2b758fd7b96ecafded6fa8b73ff3..333a82a3717e07daa8979986480579b943507e53 100644 (file)
@@ -322,7 +322,6 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 
                if (off < kern_size &&
                    user_size <= (kern_size - off)) {
-                       vma->vm_flags |= VM_RESERVED;
                        ret = remap_pfn_range(vma, vma->vm_start,
                                              page_to_pfn(c->vm_pages) + off,
                                              user_size << PAGE_SHIFT,
index 4493bcff51729a2e4340d0d196ce67e10a1611ca..ee40c1a0b83d6788f24bd66b8530661b357c5b07 100644 (file)
@@ -171,7 +171,7 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
  * Called from map_io. We need to call to this early enough so that we
  * can reserve the fixed SDRAM regions before VM could get hold of them.
  */
-void omapfb_reserve_sdram(void)
+void __init omapfb_reserve_sdram(void)
 {
        struct bootmem_data     *bdata;
        unsigned long           sdram_start, sdram_size;
index bbecbd8469b59a449b6d525c1bc0725f81b7da29..4f402c92450496342bd0ea4a92bd2c09b4478b68 100644 (file)
@@ -19,9 +19,6 @@ config AVR32
          There is an AVR32 Linux project with a web page at
          http://avr32linux.org/.
 
-config UID16
-       bool
-
 config GENERIC_GPIO
        bool
        default y
index a9d9ec081e3d7b8c729dfff3100ca3f2bc5f2b45..7c4388f4f17ff697405455c39a0bd78641ae4ca9 100644 (file)
@@ -474,7 +474,7 @@ static struct resource at32ap700x_rtc0_resource[] = {
 static struct resource at32_wdt0_resource[] = {
        {
                .start  = 0xfff000b0,
-               .end    = 0xfff000bf,
+               .end    = 0xfff000cf,
                .flags  = IORESOURCE_MEM,
        },
 };
@@ -690,7 +690,7 @@ static struct resource atmel_usart0_resource[] = {
        IRQ(6),
 };
 DEFINE_DEV_DATA(atmel_usart, 0);
-DEV_CLK(usart, atmel_usart0, pba, 4);
+DEV_CLK(usart, atmel_usart0, pba, 3);
 
 static struct atmel_uart_data atmel_usart1_data = {
        .use_dma_tx     = 1,
index 704607fbcc696d2223241ff26103176daa254b46..fa427ed427874843ea523c30c2c69b46089914be 100644 (file)
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define DEBUG
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/init.h>
index dd5c009cf224838379af65d498c35ed7357afcf2..0b286cd53028a469441af1ad99b56f97a6c37287 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 
+#include <asm/intc.h>
 #include <asm/io.h>
 
 #include "intc.h"
@@ -136,7 +137,8 @@ fail:
        panic("Interrupt controller initialization failed!\n");
 }
 
-unsigned long intc_get_pending(int group)
+unsigned long intc_get_pending(unsigned int group)
 {
        return intc_readl(&intc0, INTREQ0 + 4 * group);
 }
+EXPORT_SYMBOL_GPL(intc_get_pending);
index 21900a9378bbc04b4bb5fccd6161fb86a4d86ecd..222da1501f47c0e81508996e8f74ec7c5ff21353 100644 (file)
@@ -13,6 +13,10 @@ config ZONE_DMA
        bool
        default y
 
+config NO_DMA
+       bool
+       default y
+
 config RWSEM_GENERIC_SPINLOCK
        bool
        default y
@@ -57,6 +61,10 @@ menu "General setup"
 
 source "fs/Kconfig.binfmt"
 
+config GENERIC_HARDIRQS
+       bool
+       default y
+
 config ETRAX_CMDLINE
        string "Kernel command line"
        default "root=/dev/mtdblock3"
@@ -149,7 +157,8 @@ source "net/Kconfig"
 
 # bring in ETRAX built-in drivers
 menu "Drivers for built-in interfaces"
-source arch/cris/arch-v10/drivers/Kconfig
+# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
+source arch/cris/arch/drivers/Kconfig
 
 endmenu
 
@@ -180,6 +189,10 @@ source "drivers/isdn/Kconfig"
 
 source "drivers/telephony/Kconfig"
 
+source "drivers/i2c/Kconfig"
+
+source "drivers/rtc/Kconfig"
+
 #
 # input before char - char/joystick depends on it. As does USB.
 #
@@ -194,6 +207,10 @@ source "fs/Kconfig"
 
 source "sound/Kconfig"
 
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/Kconfig"
+
 source "drivers/usb/Kconfig"
 
 source "kernel/Kconfig.instrumentation"
index 710c20ba2be7ae79fdf618317a2c4e845dc47a19..572f119263996bbd23050fd6dc32c353b2675664 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_MTD=y
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_AMDSTD=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_ETRAX_I2C=y
@@ -145,7 +144,6 @@ CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_GEOMETRY is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_AMDSTD=y
 # CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_NORA is not set
index 03e2e68f947dd7c3d49424e5781ec9e1f4e3cf57..faf8b4d3ca01c66f37e5d4d9e4fd43a2d0728c27 100644 (file)
@@ -2,6 +2,7 @@ config ETRAX_ETHERNET
        bool "Ethernet support"
        depends on ETRAX_ARCH_V10
        select NET_ETHERNET
+       select MII
        help
          This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
          controller.
@@ -605,8 +606,6 @@ config ETRAX_AXISFLASHMAP
        select MTD
        select MTD_CFI
        select MTD_CFI_AMDSTD
-       select MTD_OBSOLETE_CHIPS
-       select MTD_AMDSTD
        select MTD_CHAR
        select MTD_BLOCK
        select MTD_PARTITIONS
index efd7b0f3a91042aa85455309594979ec6de44a3a..ea3cf2e39a14d943ab5532f53aeaf1560cd7be32 100644 (file)
@@ -312,12 +312,12 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
                "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
               map_cs->name, map_cs->size, map_cs->map_priv_1);
 
-#ifdef CONFIG_MTD_AMDSTD
-       mtd_cs = do_map_probe("amd_flash", map_cs);
-#endif
 #ifdef CONFIG_MTD_CFI
+       mtd_cs = do_map_probe("cfi_probe", map_cs);
+#endif
+#ifdef CONFIG_MTD_JEDECPROBE
        if (!mtd_cs) {
-               mtd_cs = do_map_probe("cfi_probe", map_cs);
+               mtd_cs = do_map_probe("jedec_probe", map_cs);
        }
 #endif
 
index f389ed6998fe4f92ec9fc28b95ce2cc8cbd65e34..0d347a7058355c0d9ff7e90cbd0e73a0b535b6af 100644 (file)
@@ -297,8 +297,10 @@ gpio_poll(struct file *file,
                data = *R_PORT_PB_DATA;
        else if (priv->minor == GPIO_MINOR_G)
                data = *R_PORT_G_DATA;
-       else
+       else {
+               spin_unlock(&gpio_lock);
                return 0;
+       }
        
        if ((data & priv->highalarm) ||
            (~data & priv->lowalarm)) {
@@ -381,18 +383,21 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
 
        ssize_t retval = count;
        if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
-               return -EFAULT;
+               retval = -EFAULT;
+               goto out;
        }
     
        if (!access_ok(VERIFY_READ, buf, count)) {
-               return -EFAULT;
+               retval = -EFAULT;
+               goto out;
        }
        clk_mask = priv->clk_mask;
        data_mask = priv->data_mask;
        /* It must have been configured using the IO_CFG_WRITE_MODE */
        /* Perhaps a better error code? */
        if (clk_mask == 0 || data_mask == 0) {
-               return -EPERM;
+               retval = -EPERM;
+               goto out;
        }
        write_msb = priv->write_msb;
        D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
@@ -425,6 +430,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
                        }
                }
        }
+out:
        spin_unlock(&gpio_lock);
        return retval;
 }
@@ -506,6 +512,7 @@ gpio_release(struct inode *inode, struct file *filp)
        while (p) {
                if (p->highalarm | p->lowalarm) {
                        gpio_some_alarms = 1;
+                       spin_unlock(&gpio_lock);
                        return 0;
                }
                p = p->next;
index c5844cb70f095bc96333bc46f9b114db2f725439..ec62c951fa3cc37a1dd709609cd1a9bfa669ef1a 100644 (file)
@@ -500,9 +500,8 @@ _work_notifysig:
        ;; deal with pending signals and notify-resume requests
 
        move.d  $r9, $r10       ; do_notify_resume syscall/irq param
-       moveq   0, $r11         ; oldset param - 0 in this case
-       move.d  $sp, $r12       ; the regs param
-       move.d  $r1, $r13       ; the thread_info_flags parameter
+       move.d  $sp, $r11       ; the regs param
+       move.d  $r1, $r12       ; the thread_info_flags parameter
        jsr     do_notify_resume
        
        ba _Rexit
@@ -678,13 +677,19 @@ IRQ1_interrupt:
        push    $r10            ; push orig_r10
        clear.d [$sp=$sp-4]     ; frametype == 0, normal frame
 
+       ;; If there is a glitch on the NMI pin shorter than ~100ns
+       ;; (i.e. non-active by the time we get here) then the nmi_pin bit
+       ;; in R_IRQ_MASK0_RD will already be cleared.  The watchdog_nmi bit
+       ;; is cleared by us however (when feeding the watchdog), which is why
+       ;; we use that bit to determine what brought us here.
+
        move.d  [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog?
-       and.d   0x80000000, $r1
-       beq     wdog
+       and.d   (1<<30), $r1
+       bne     wdog
        move.d  $sp, $r10
        jsr     handle_nmi
        setf m                  ; Enable NMI again
-       retb                    ; Return from NMI
+       ba      _Rexit          ; Return the standard way
        nop
 wdog:
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
@@ -775,22 +780,9 @@ multiple_interrupt:
        push    $r10            ; push orig_r10
        clear.d [$sp=$sp-4]     ; frametype == 0, normal frame
        
-       moveq   2, $r2          ; first bit we care about is the timer0 irq
-       move.d  [R_VECT_MASK_RD], $r0; read the irq bits that triggered the multiple irq
-       move.d  $r0, [R_VECT_MASK_CLR] ; Block all active IRQs
-1:     
-       btst    $r2, $r0        ; check for the irq given by bit r2
-       bpl     2f
-       move.d  $r2, $r10       ; First argument to do_IRQ
-       move.d  $sp, $r11       ; second argument to do_IRQ
-       jsr     do_IRQ
-2:
-       addq    1, $r2          ; next vector bit
-       cmp.b   32, $r2
-       bne     1b      ; process all irq's up to and including number 31
-       moveq   0, $r9  ; make ret_from_intr realise we came from an ir
+       move.d  $sp, $r10
+       jsr     do_multiple_IRQ
        
-       move.d  $r0, [R_VECT_MASK_SET] ;  Unblock all the IRQs
        jump    ret_from_intr
 
 do_sigtrap:
@@ -837,6 +829,13 @@ _ugdb_handle_breakpoint:
        ba      do_sigtrap              ; SIGTRAP the offending process. 
        pop     $dccr                   ; Restore dccr in delay slot.
        
+       .global kernel_execve
+kernel_execve:
+       move.d __NR_execve, $r9
+       break 13
+       ret
+       nop
+
        .data
 
 hw_bp_trigs:
@@ -1135,6 +1134,42 @@ sys_call_table:
        .long sys_add_key
        .long sys_request_key
        .long sys_keyctl
+       .long sys_ioprio_set
+       .long sys_ioprio_get            /* 290 */
+       .long sys_inotify_init
+       .long sys_inotify_add_watch
+       .long sys_inotify_rm_watch
+       .long sys_migrate_pages
+       .long sys_openat                /* 295 */
+       .long sys_mkdirat
+       .long sys_mknodat
+       .long sys_fchownat
+       .long sys_futimesat
+       .long sys_fstatat64             /* 300 */
+       .long sys_unlinkat
+       .long sys_renameat
+       .long sys_linkat
+       .long sys_symlinkat
+       .long sys_readlinkat            /* 305 */
+       .long sys_fchmodat
+       .long sys_faccessat
+       .long sys_pselect6
+       .long sys_ppoll
+       .long sys_unshare               /* 310 */
+       .long sys_set_robust_list
+       .long sys_get_robust_list
+       .long sys_splice
+       .long sys_sync_file_range
+       .long sys_tee                   /* 315 */
+       .long sys_vmsplice
+       .long sys_move_pages
+       .long sys_getcpu
+       .long sys_epoll_pwait
+       .long sys_utimensat             /* 320 */
+       .long sys_signalfd
+       .long sys_timerfd
+       .long sys_eventfd
+       .long sys_fallocate
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
index d3ea052e5ee148581a64d451e45d3033ad23ea67..c1a3a2100ee71e1094a8df045bec8f5948ef5023 100644 (file)
@@ -1,97 +1,9 @@
-/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $
+/*
  * linux/arch/cris/kernel/fasttimer.c
  *
  * Fast timers for ETRAX100/ETRAX100LX
- * This may be useful in other OS than Linux so use 2 space indentation...
  *
- * $Log: fasttimer.c,v $
- * Revision 1.9  2005/03/04 08:16:16  starvik
- * Merge of Linux 2.6.11.
- *
- * Revision 1.8  2005/01/05 06:09:29  starvik
- * cli()/sti() will be obsolete in 2.6.11.
- *
- * Revision 1.7  2005/01/03 13:35:46  starvik
- * Removed obsolete stuff.
- * Mark fast timer IRQ as not shared.
- *
- * Revision 1.6  2004/05/14 10:18:39  starvik
- * Export fast_timer_list
- *
- * Revision 1.5  2004/05/14 07:58:01  starvik
- * Merge of changes from 2.4
- *
- * Revision 1.4  2003/07/04 08:27:41  starvik
- * Merge of Linux 2.5.74
- *
- * Revision 1.3  2002/12/12 08:26:32  starvik
- * Don't use C-comments inside CVS comments
- *
- * Revision 1.2  2002/12/11 15:42:02  starvik
- * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
- *
- * Revision 1.1  2002/11/18 07:58:06  starvik
- * Fast timers (from Linux 2.4)
- *
- * Revision 1.5  2002/10/15 06:21:39  starvik
- * Added call to init_waitqueue_head
- *
- * Revision 1.4  2002/05/28 17:47:59  johana
- * Added del_fast_timer()
- *
- * Revision 1.3  2002/05/28 16:16:07  johana
- * Handle empty fast_timer_list
- *
- * Revision 1.2  2002/05/27 15:38:42  johana
- * Made it compile without warnings on Linux 2.4.
- * (includes, wait_queue, PROC_FS and snprintf)
- *
- * Revision 1.1  2002/05/27 15:32:25  johana
- * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
- *
- * Revision 1.8  2001/11/27 13:50:40  pkj
- * Disable interrupts while stopping the timer and while modifying the
- * list of active timers in timer1_handler() as it may be interrupted
- * by other interrupts (e.g., the serial interrupt) which may add fast
- * timers.
- *
- * Revision 1.7  2001/11/22 11:50:32  pkj
- * * Only store information about the last 16 timers.
- * * proc_fasttimer_read() now uses an allocated buffer, since it
- *   requires more space than just a page even for only writing the
- *   last 16 timers. The buffer is only allocated on request, so
- *   unless /proc/fasttimer is read, it is never allocated.
- * * Renamed fast_timer_started to fast_timers_started to match
- *   fast_timers_added and fast_timers_expired.
- * * Some clean-up.
- *
- * Revision 1.6  2000/12/13 14:02:08  johana
- * Removed volatile for fast_timer_list
- *
- * Revision 1.5  2000/12/13 13:55:35  johana
- * Added DEBUG_LOG, added som cli() and cleanup
- *
- * Revision 1.4  2000/12/05 13:48:50  johana
- * Added range check when writing proc file, modified timer int handling
- *
- * Revision 1.3  2000/11/23 10:10:20  johana
- * More debug/logging possibilities.
- * Moved GET_JIFFIES_USEC() to timex.h and time.c
- *
- * Revision 1.2  2000/11/01 13:41:04  johana
- * Clean up and bugfixes.
- * Created new do_gettimeofday_fast() that gets a timeval struct
- * with time based on jiffies and *R_TIMER0_DATA, uses a table
- * for fast conversion of timer value to microseconds.
- * (Much faster the standard do_gettimeofday() and we don't really
- * want to use the true time - we want the "uptime" so timers don't screw up
- * when we change the time.
- * TODO: Add efficient support for continuous timers as well.
- *
- * Revision 1.1  2000/10/26 15:49:16  johana
- * Added fasttimer, highresolution timers.
- *
- * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
+ * Copyright (C) 2000-2007 Axis Communications AB, Lund, Sweden
  */
 
 #include <linux/errno.h>
 
 #ifdef FAST_TIMER_SANITY_CHECKS
 #define SANITYCHECK(x) x
-static int sanity_failed = 0;
+static int sanity_failed;
 #else
 #define SANITYCHECK(x)
 #endif
@@ -134,15 +46,13 @@ static int sanity_failed = 0;
 #define D2(x)
 #define DP(x)
 
-#define __INLINE__ inline
-
-static int fast_timer_running = 0;
-static int fast_timers_added = 0;
-static int fast_timers_started = 0;
-static int fast_timers_expired = 0;
-static int fast_timers_deleted = 0;
-static int fast_timer_is_init = 0;
-static int fast_timer_ints = 0;
+static unsigned int fast_timer_running;
+static unsigned int fast_timers_added;
+static unsigned int fast_timers_started;
+static unsigned int fast_timers_expired;
+static unsigned int fast_timers_deleted;
+static unsigned int fast_timer_is_init;
+static unsigned int fast_timer_ints;
 
 struct fast_timer *fast_timer_list = NULL;
 
@@ -150,8 +60,8 @@ struct fast_timer *fast_timer_list = NULL;
 #define DEBUG_LOG_MAX 128
 static const char * debug_log_string[DEBUG_LOG_MAX];
 static unsigned long debug_log_value[DEBUG_LOG_MAX];
-static int debug_log_cnt = 0;
-static int debug_log_cnt_wrapped = 0;
+static unsigned int debug_log_cnt;
+static unsigned int debug_log_cnt_wrapped;
 
 #define DEBUG_LOG(string, value) \
 { \
@@ -206,45 +116,29 @@ int timer_freq_settings[NUM_TIMER_STATS];
 int timer_delay_settings[NUM_TIMER_STATS];
 
 /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
-void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
+inline void do_gettimeofday_fast(struct fasttime_t *tv)
 {
-  unsigned long sec = jiffies;
-  unsigned long usec = GET_JIFFIES_USEC();
-
-  usec += (sec % HZ) * (1000000 / HZ);
-  sec = sec / HZ;
-
-  if (usec > 1000000)
-  {
-    usec -= 1000000;
-    sec++;
-  }
-  tv->tv_sec = sec;
-  tv->tv_usec = usec;
+       tv->tv_jiff = jiffies;
+       tv->tv_usec = GET_JIFFIES_USEC();
 }
 
-int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
+inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
 {
-  if (t0->tv_sec < t1->tv_sec)
-  {
-    return -1;
-  }
-  else if (t0->tv_sec > t1->tv_sec)
-  {
-    return 1;
-  }
-  if (t0->tv_usec < t1->tv_usec)
-  {
-    return -1;
-  }
-  else if (t0->tv_usec > t1->tv_usec)
-  {
-    return 1;
-  }
-  return 0;
+       /* Compare jiffies. Takes care of wrapping */
+       if (time_before(t0->tv_jiff, t1->tv_jiff))
+               return -1;
+       else if (time_after(t0->tv_jiff, t1->tv_jiff))
+               return 1;
+
+       /* Compare us */
+       if (t0->tv_usec < t1->tv_usec)
+               return -1;
+       else if (t0->tv_usec > t1->tv_usec)
+               return 1;
+       return 0;
 }
 
-void __INLINE__ start_timer1(unsigned long delay_us)
+inline void start_timer1(unsigned long delay_us)
 {
   int freq_index = 0; /* This is the lowest resolution */
   unsigned long upper_limit = MAX_DELAY_US;
@@ -285,7 +179,7 @@ void __INLINE__ start_timer1(unsigned long delay_us)
   timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
   timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
 
-  D1(printk("start_timer1 : %d us freq: %i div: %i\n",
+       D1(printk(KERN_DEBUG "start_timer1 : %d us freq: %i div: %i\n",
             delay_us, freq_index, div));
   /* Clear timer1 irq */
   *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
@@ -340,7 +234,7 @@ void start_one_shot_timer(struct fast_timer *t,
         printk(KERN_WARNING
                "timer name: %s data: 0x%08lX already in list!\n", name, data);
         sanity_failed++;
-        return;
+                               goto done;
       }
       else
       {
@@ -356,11 +250,11 @@ void start_one_shot_timer(struct fast_timer *t,
   t->name = name;
 
   t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
-  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
+       t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
   if (t->tv_expires.tv_usec > 1000000)
   {
     t->tv_expires.tv_usec -= 1000000;
-    t->tv_expires.tv_sec++;
+               t->tv_expires.tv_jiff += HZ;
   }
 #ifdef FAST_TIMER_LOG
   timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
@@ -368,7 +262,7 @@ void start_one_shot_timer(struct fast_timer *t,
   fast_timers_added++;
 
   /* Check if this should timeout before anything else */
-  if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
+       if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
   {
     /* Put first in list and modify the timer value */
     t->prev = NULL;
@@ -384,8 +278,8 @@ void start_one_shot_timer(struct fast_timer *t,
     start_timer1(delay_us);
   } else {
     /* Put in correct place in list */
-    while (tmp->next &&
-           timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
+               while (tmp->next && fasttime_cmp(&t->tv_expires,
+                               &tmp->next->tv_expires) > 0)
     {
       tmp = tmp->next;
     }
@@ -401,6 +295,7 @@ void start_one_shot_timer(struct fast_timer *t,
 
   D2(printk("start_one_shot_timer: %d us done\n", delay_us));
 
+done:
   local_irq_restore(flags);
 } /* start_one_shot_timer */
 
@@ -444,11 +339,18 @@ int del_fast_timer(struct fast_timer * t)
 /* Timer 1 interrupt handler */
 
 static irqreturn_t
-timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
+timer1_handler(int irq, void *dev_id)
 {
   struct fast_timer *t;
   unsigned long flags;
 
+       /* We keep interrupts disabled not only when we modify the
+        * fast timer list, but any time we hold a reference to a
+        * timer in the list, since del_fast_timer may be called
+        * from (another) interrupt context.  Thus, the only time
+        * when interrupts are enabled is when calling the timer
+        * callback function.
+        */
   local_irq_save(flags);
 
   /* Clear timer1 irq */
@@ -466,18 +368,19 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
   fast_timer_running = 0;
   fast_timer_ints++;
 
-  local_irq_restore(flags);
-
   t = fast_timer_list;
   while (t)
   {
-    struct timeval tv;
+               struct fasttime_t tv;
+               fast_timer_function_type *f;
+               unsigned long d;
 
     /* Has it really expired? */
     do_gettimeofday_fast(&tv);
-    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
+               D1(printk(KERN_DEBUG "t: %is %06ius\n",
+                       tv.tv_jiff, tv.tv_usec));
 
-    if (timeval_cmp(&t->tv_expires, &tv) <= 0)
+               if (fasttime_cmp(&t->tv_expires, &tv) <= 0)
     {
       /* Yes it has expired */
 #ifdef FAST_TIMER_LOG
@@ -486,7 +389,6 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
       fast_timers_expired++;
 
       /* Remove this timer before call, since it may reuse the timer */
-      local_irq_save(flags);
       if (t->prev)
       {
         t->prev->next = t->next;
@@ -501,16 +403,23 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
       }
       t->prev = NULL;
       t->next = NULL;
-      local_irq_restore(flags);
 
-      if (t->function != NULL)
-      {
-        t->function(t->data);
-      }
-      else
-      {
+                       /* Save function callback data before enabling
+                        * interrupts, since the timer may be removed and
+                        * we don't know how it was allocated
+                        * (e.g. ->function and ->data may become overwritten
+                        * after deletion if the timer was stack-allocated).
+                        */
+                       f = t->function;
+                       d = t->data;
+
+                       if (f != NULL) {
+                               /* Run callback with interrupts enabled. */
+                               local_irq_restore(flags);
+                               f(d);
+                               local_irq_save(flags);
+                       } else
         DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
-      }
     }
     else
     {
@@ -518,16 +427,20 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
       D1(printk(".\n"));
     }
 
-    local_irq_save(flags);
     if ((t = fast_timer_list) != NULL)
     {
       /* Start next timer.. */
-      long us;
-      struct timeval tv;
+                       long us = 0;
+                       struct fasttime_t tv;
 
       do_gettimeofday_fast(&tv);
-      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
-            t->tv_expires.tv_usec - tv.tv_usec);
+
+                       /* time_after_eq takes care of wrapping */
+                       if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
+                               us = ((t->tv_expires.tv_jiff - tv.tv_jiff) *
+                                       1000000 / HZ + t->tv_expires.tv_usec -
+                                       tv.tv_usec);
+
       if (us > 0)
       {
         if (!fast_timer_running)
@@ -537,7 +450,6 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
 #endif
           start_timer1(us);
         }
-        local_irq_restore(flags);
         break;
       }
       else
@@ -548,9 +460,10 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
         D1(printk("e! %d\n", us));
       }
     }
-    local_irq_restore(flags);
   }
 
+       local_irq_restore(flags);
+
   if (!t)
   {
     D1(printk("t1 stop!\n"));
@@ -575,28 +488,17 @@ static void wake_up_func(unsigned long data)
 void schedule_usleep(unsigned long us)
 {
   struct fast_timer t;
-#ifdef DECLARE_WAITQUEUE
   wait_queue_head_t sleep_wait;
   init_waitqueue_head(&sleep_wait);
-  {
-  DECLARE_WAITQUEUE(wait, current);
-#else
-  struct wait_queue *sleep_wait = NULL;
-  struct wait_queue wait = { current, NULL };
-#endif
 
   D1(printk("schedule_usleep(%d)\n", us));
-  add_wait_queue(&sleep_wait, &wait);
-  set_current_state(TASK_INTERRUPTIBLE);
   start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
                        "usleep");
-  schedule();
-  set_current_state(TASK_RUNNING);
-  remove_wait_queue(&sleep_wait, &wait);
+       /* Uninterruptible sleep on the fast timer. (The condition is somewhat
+        * redundant since the timer is what wakes us up.) */
+       wait_event(sleep_wait, !fast_timer_pending(&t));
+
   D1(printk("done schedule_usleep(%d)\n", us));
-#ifdef DECLARE_WAITQUEUE
-  }
-#endif  
 }
 
 #ifdef CONFIG_PROC_FS
@@ -616,7 +518,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
   unsigned long flags;
   int i = 0;
   int num_to_show;
-  struct timeval tv;
+       struct fasttime_t tv;
   struct fast_timer *t, *nextt;
   static char *bigbuf = NULL;
   static unsigned long used;
@@ -624,7 +526,8 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
   if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
   {
     used = 0;
-    bigbuf[0] = '\0';
+       if (buf)
+               buf[0] = '\0';
     return 0;
   }
 
@@ -646,7 +549,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
     used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
                     fast_timer_running ? "yes" : "no");
     used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
-                    (unsigned long)tv.tv_sec,
+                       (unsigned long)tv.tv_jiff,
                     (unsigned long)tv.tv_usec);
 #ifdef FAST_TIMER_SANITY_CHECKS
     used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
@@ -696,9 +599,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
                       "d: %6li us data: 0x%08lX"
                       "\n",
                       t->name,
-                      (unsigned long)t->tv_set.tv_sec,
+                       (unsigned long)t->tv_set.tv_jiff,
                       (unsigned long)t->tv_set.tv_usec,
-                      (unsigned long)t->tv_expires.tv_sec,
+                       (unsigned long)t->tv_expires.tv_jiff,
                       (unsigned long)t->tv_expires.tv_usec,
                       t->delay_us,
                       t->data
@@ -718,9 +621,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
                       "d: %6li us data: 0x%08lX"
                       "\n",
                       t->name,
-                      (unsigned long)t->tv_set.tv_sec,
+                       (unsigned long)t->tv_set.tv_jiff,
                       (unsigned long)t->tv_set.tv_usec,
-                      (unsigned long)t->tv_expires.tv_sec,
+                       (unsigned long)t->tv_expires.tv_jiff,
                       (unsigned long)t->tv_expires.tv_usec,
                       t->delay_us,
                       t->data
@@ -738,9 +641,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
                       "d: %6li us data: 0x%08lX"
                       "\n",
                       t->name,
-                      (unsigned long)t->tv_set.tv_sec,
+                       (unsigned long)t->tv_set.tv_jiff,
                       (unsigned long)t->tv_set.tv_usec,
-                      (unsigned long)t->tv_expires.tv_sec,
+                       (unsigned long)t->tv_expires.tv_jiff,
                       (unsigned long)t->tv_expires.tv_usec,
                       t->delay_us,
                       t->data
@@ -761,15 +664,15 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
 /*                      " func: 0x%08lX" */
                       "\n",
                       t->name,
-                      (unsigned long)t->tv_set.tv_sec,
+                       (unsigned long)t->tv_set.tv_jiff,
                       (unsigned long)t->tv_set.tv_usec,
-                      (unsigned long)t->tv_expires.tv_sec,
+                       (unsigned long)t->tv_expires.tv_jiff,
                       (unsigned long)t->tv_expires.tv_usec,
                       t->delay_us,
                       t->data
 /*                      , t->function */
                       );
-      local_irq_disable();
+       local_irq_save(flags);
       if (t->next != nextt)
       {
         printk(KERN_WARNING "timer removed!\n");
@@ -798,7 +701,7 @@ static volatile int num_test_timeout = 0;
 static struct fast_timer tr[10];
 static int exp_num[10];
 
-static struct timeval tv_exp[100];
+static struct fasttime_t tv_exp[100];
 
 static void test_timeout(unsigned long data)
 {
@@ -836,7 +739,7 @@ static void fast_timer_test(void)
   int prev_num;
   int j;
 
-  struct timeval tv, tv0, tv1, tv2;
+       struct fasttime_t tv, tv0, tv1, tv2;
 
   printk("fast_timer_test() start\n");
   do_gettimeofday_fast(&tv);
@@ -849,7 +752,8 @@ static void fast_timer_test(void)
   {
     do_gettimeofday_fast(&tv_exp[j]);
   }
-  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
+       printk(KERN_DEBUG "fast_timer_test() %is %06i\n",
+               tv.tv_jiff, tv.tv_usec);
 
   for (j = 0; j < 1000; j++)
   {
@@ -858,12 +762,12 @@ static void fast_timer_test(void)
   }
   for (j = 0; j < 100; j++)
   {
-    printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
-           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
-           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
-           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
-           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
-           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
+               printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n",
+                       tv_exp[j].tv_jiff, tv_exp[j].tv_usec,
+                       tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec,
+                       tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec,
+                       tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec,
+                       tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec);
     j += 4;
   }
   do_gettimeofday_fast(&tv0);
@@ -895,9 +799,12 @@ static void fast_timer_test(void)
     }
   }
   do_gettimeofday_fast(&tv2);
-  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
-  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
-  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
+       printk(KERN_DEBUG "Timers started    %is %06i\n",
+               tv0.tv_jiff, tv0.tv_usec);
+       printk(KERN_DEBUG "Timers started at %is %06i\n",
+               tv1.tv_jiff, tv1.tv_usec);
+       printk(KERN_DEBUG "Timers done       %is %06i\n",
+               tv2.tv_jiff, tv2.tv_usec);
   DP(printk("buf0:\n");
      printk(buf0);
      printk("buf1:\n");
@@ -919,9 +826,9 @@ static void fast_timer_test(void)
     printk("%-10s set: %6is %06ius exp: %6is %06ius "
            "data: 0x%08X func: 0x%08X\n",
            t->name,
-           t->tv_set.tv_sec,
+                       t->tv_set.tv_jiff,
            t->tv_set.tv_usec,
-           t->tv_expires.tv_sec,
+                       t->tv_expires.tv_jiff,
            t->tv_expires.tv_usec,
            t->data,
            t->function
@@ -929,10 +836,12 @@ static void fast_timer_test(void)
 
     printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
            t->delay_us,
-           tv_exp[j].tv_sec,
+                       tv_exp[j].tv_jiff,
            tv_exp[j].tv_usec,
            exp_num[j],
-           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
+                       (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) *
+                               1000000 + tv_exp[j].tv_usec -
+                               t->tv_expires.tv_usec);
   }
   proc_fasttimer_read(buf5, NULL, 0, 0, 0);
   printk("buf5 after all done:\n");
@@ -942,7 +851,7 @@ static void fast_timer_test(void)
 #endif
 
 
-void fast_timer_init(void)
+int fast_timer_init(void)
 {
   /* For some reason, request_irq() hangs when called froom time_init() */
   if (!fast_timer_is_init)
@@ -975,4 +884,6 @@ void fast_timer_init(void)
     fast_timer_test();
 #endif
   }
+       return 0;
 }
+__initcall(fast_timer_init);
index 29d48ad00df934bd96e519ec1fd847d4360d6be4..3a9114e89edfcc1f2ef6e87b8e7c7bc6ca1fd35d 100644 (file)
@@ -304,7 +304,7 @@ static unsigned char clear_group_from_set(const unsigned char groups, struct if_
 static struct if_group *get_group(const unsigned char groups)
 {
        int i;
-       for (i = 0; i < sizeof(if_groups)/sizeof(struct if_group); i++) {
+       for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
                if (groups & if_groups[i].group) {
                        return &if_groups[i];
                }
index 845c95f6e87117318511e164ada754c321d97b6d..e06ab0050d375156ff94eb3a2602a6a9493a57e5 100644 (file)
  */
 
 #include <asm/irq.h>
+#include <asm/current.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
+/* From kgdb.c. */
+extern void kgdb_init(void);
+extern void breakpoint(void);
+
 #define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
 #define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
 
@@ -75,8 +81,8 @@ BUILD_IRQ(12, 0x1000)
 BUILD_IRQ(13, 0x2000)
 void mmu_bus_fault(void);      /* IRQ 14 is the bus fault interrupt */
 void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
-BUILD_IRQ(16, 0x10000)
-BUILD_IRQ(17, 0x20000)
+BUILD_IRQ(16, 0x10000 | 0x20000)  /* ethernet tx interrupt needs to block rx */
+BUILD_IRQ(17, 0x20000 | 0x10000)  /* ...and vice versa */
 BUILD_IRQ(18, 0x40000)
 BUILD_IRQ(19, 0x80000)
 BUILD_IRQ(20, 0x100000)
@@ -147,6 +153,55 @@ void system_call(void);  /* from entry.S */
 void do_sigtrap(void); /* from entry.S */
 void gdb_handle_breakpoint(void); /* from entry.S */
 
+extern void do_IRQ(int irq, struct pt_regs * regs);
+
+/* Handle multiple IRQs */
+void do_multiple_IRQ(struct pt_regs* regs)
+{
+       int bit;
+       unsigned masked;
+       unsigned mask;
+       unsigned ethmask = 0;
+
+       /* Get interrupts to mask and handle */
+       mask = masked = *R_VECT_MASK_RD;
+
+       /* Never mask timer IRQ */
+       mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));
+
+       /*
+        * If either ethernet interrupt (rx or tx) is active then block
+        * the other one too. Unblock afterwards also.
+        */
+       if (mask &
+           (IO_STATE(R_VECT_MASK_RD, dma0, active) |
+            IO_STATE(R_VECT_MASK_RD, dma1, active))) {
+               ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
+                          IO_MASK(R_VECT_MASK_RD, dma1));
+       }
+
+       /* Block them */
+       *R_VECT_MASK_CLR = (mask | ethmask);
+
+       /* An extra irq_enter here to prevent softIRQs to run after
+        * each do_IRQ. This will decrease the interrupt latency.
+        */
+       irq_enter();
+
+       /* Handle all IRQs */
+       for (bit = 2; bit < 32; bit++) {
+               if (masked & (1 << bit)) {
+                       do_IRQ(bit, regs);
+               }
+       }
+
+       /* This irq_exit() will trigger the soft IRQs. */
+       irq_exit();
+
+       /* Unblock the IRQs again */
+       *R_VECT_MASK_SET = (masked | ethmask);
+}
+
 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
    setting the irq vector table.
 */
index 682ef955aec4b526bff04756a09d959333fc321c..de27b50b72a24fb678865d5b58a7f7d426650ad6 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
+#include <linux/param.h>
 
 #ifdef CONFIG_PROC_FS
 #define HAS_FPU                0x0001
@@ -56,8 +57,8 @@ int show_cpuinfo(struct seq_file *m, void *v)
 
        revision = rdvr();
 
-       if (revision >= sizeof cpu_info/sizeof *cpu_info)
-               info = &cpu_info[sizeof cpu_info/sizeof *cpu_info - 1];
+       if (revision >= ARRAY_SIZE(cpu_info))
+               info = &cpu_info[ARRAY_SIZE(cpu_info) - 1];
        else
                info = &cpu_info[revision];
 
index 575a14bb110613bfba8dfc3eaf8d53191fe8bbfb..5976f6199c47237937b2e7a4bd15709203472cf9 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: time.c,v 1.5 2004/09/29 06:12:46 starvik Exp $
- *
+/*
  *  linux/arch/cris/arch-v10/kernel/time.c
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
@@ -20,6 +19,7 @@
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/rtc.h>
+#include <asm/irq_regs.h>
 
 /* define this if you need to use print_timestamp */
 /* it will make jiffies at 96 hz instead of 100 hz though */
@@ -201,8 +201,9 @@ static long last_rtc_update = 0;
 extern void cris_do_profile(struct pt_regs *regs);
 
 static inline irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+timer_interrupt(int irq, void *dev_id)
 {
+       struct pt_regs *regs = get_irq_regs();
        /* acknowledge the timer irq */
 
 #ifdef USE_CASCADE_TIMERS
@@ -221,9 +222,11 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
 
        /* reset watchdog otherwise it resets us! */
-
        reset_watchdog();
        
+       /* Update statistics. */
+       update_process_times(user_mode(regs));
+
        /* call the real timer interrupt handler */
 
        do_timer(1);
index 82bb668391715279afb0619a46d3d4b208323ed5..42c1101043a3229481acf644ad947d0f427083dc 100644 (file)
@@ -66,7 +66,7 @@ void *memset(void *pdst,
 
   {
     register char *dst __asm__ ("r13") = pdst;
+
   /* This is NONPORTABLE, but since this whole routine is     */
   /* grossly nonportable that doesn't matter.                 */
 
@@ -110,52 +110,52 @@ void *memset(void *pdst,
       If you want to check that the allocation was right; then
       check the equalities in the first comment.  It should say
       "r13=r13, r12=r12, r11=r11" */
-    __asm__ volatile ("
-        ;; Check that the following is true (same register names on
-        ;; both sides of equal sign, as in r8=r8):
-        ;; %0=r13, %1=r12, %4=r11
-        ;;
-       ;; Save the registers we'll clobber in the movem process
-       ;; on the stack.  Don't mention them to gcc, it will only be
-       ;; upset.
-       subq    11*4,$sp
-        movem   $r10,[$sp]
-
-        move.d  $r11,$r0
-        move.d  $r11,$r1
-        move.d  $r11,$r2
-        move.d  $r11,$r3
-        move.d  $r11,$r4
-        move.d  $r11,$r5
-        move.d  $r11,$r6
-        move.d  $r11,$r7
-        move.d  $r11,$r8
-        move.d  $r11,$r9
-        move.d  $r11,$r10
-
-        ;; Now we've got this:
-       ;; r13 - dst
-       ;; r12 - n
-       
-        ;; Update n for the first loop
-        subq    12*4,$r12
-0:
-        subq   12*4,$r12
-        bge     0b
-       movem   $r11,[$r13+]
-
-        addq   12*4,$r12  ;; compensate for last loop underflowing n
-
-       ;; Restore registers from stack
-        movem [$sp+],$r10" 
+    __asm__ volatile ("\n\
+       ;; Check that the following is true (same register names on     \n\
+       ;; both sides of equal sign, as in r8=r8):                      \n\
+       ;; %0=r13, %1=r12, %4=r11                                       \n\
+       ;;                                                              \n\
+       ;; Save the registers we'll clobber in the movem process        \n\
+       ;; on the stack.  Don't mention them to gcc, it will only be    \n\
+       ;; upset.                                                       \n\
+       subq    11*4,$sp                                                \n\
+       movem   $r10,[$sp]                                              \n\
+                                                                       \n\
+       move.d  $r11,$r0                                                \n\
+       move.d  $r11,$r1                                                \n\
+       move.d  $r11,$r2                                                \n\
+       move.d  $r11,$r3                                                \n\
+       move.d  $r11,$r4                                                \n\
+       move.d  $r11,$r5                                                \n\
+       move.d  $r11,$r6                                                \n\
+       move.d  $r11,$r7                                                \n\
+       move.d  $r11,$r8                                                \n\
+       move.d  $r11,$r9                                                \n\
+       move.d  $r11,$r10                                               \n\
+                                                                       \n\
+       ;; Now we've got this:                                          \n\
+       ;; r13 - dst                                                    \n\
+       ;; r12 - n                                                      \n\
+                                                                       \n\
+       ;; Update n for the first loop                                  \n\
+       subq    12*4,$r12                                               \n\
+0:                                                                     \n\
+       subq    12*4,$r12                                               \n\
+       bge     0b                                                      \n\
+       movem   $r11,[$r13+]                                            \n\
+                                                                       \n\
+       addq    12*4,$r12 ;; compensate for last loop underflowing n    \n\
+                                                                       \n\
+       ;; Restore registers from stack                                 \n\
+       movem   [$sp+],$r10"
 
      /* Outputs */ : "=r" (dst), "=r" (n)
      /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
-    
+
   }
 
     /* Either we directly starts copying, using dword copying
-       in a loop, or we copy as much as possible with 'movem' 
+       in a loop, or we copy as much as possible with 'movem'
        and then the last block (<44 bytes) is copied here.
        This will work since 'movem' will have updated src,dst,n. */
 
index 15d6662b03b17212e2f57fb2588a93e0ae247859..7161a2bef4fe341e694780106ced3cccac5421c3 100644 (file)
@@ -95,33 +95,33 @@ void *memcpy(void *pdst,
       If you want to check that the allocation was right; then
       check the equalities in the first comment.  It should say
       "r13=r13, r11=r11, r12=r12" */
-    __asm__ volatile ("
-        ;; Check that the following is true (same register names on
-        ;; both sides of equal sign, as in r8=r8):
-        ;; %0=r13, %1=r11, %2=r12
-        ;;
-       ;; Save the registers we'll use in the movem process
-       ;; on the stack.
-       subq    11*4,$sp
-       movem   $r10,[$sp]
-
-        ;; Now we've got this:
-       ;; r11 - src
-       ;; r13 - dst
-       ;; r12 - n
-       
-        ;; Update n for the first loop
-        subq    44,$r12
-0:
-       movem   [$r11+],$r10
-        subq   44,$r12
-        bge     0b
-       movem   $r10,[$r13+]
-
-        addq   44,$r12  ;; compensate for last loop underflowing n
-
-       ;; Restore registers from stack
-        movem [$sp+],$r10" 
+    __asm__ volatile ("\n\
+       ;; Check that the following is true (same register names on     \n\
+       ;; both sides of equal sign, as in r8=r8):                      \n\
+       ;; %0=r13, %1=r11, %2=r12                                       \n\
+       ;;                                                              \n\
+       ;; Save the registers we'll use in the movem process            \n\
+       ;; on the stack.                                                \n\
+       subq    11*4,$sp                                                \n\
+       movem   $r10,[$sp]                                              \n\
+                                                                       \n\
+       ;; Now we've got this:                                          \n\
+       ;; r11 - src                                                    \n\
+       ;; r13 - dst                                                    \n\
+       ;; r12 - n                                                      \n\
+                                                                       \n\
+       ;; Update n for the first loop                                  \n\
+       subq    44,$r12                                                 \n\
+0:                                                                     \n\
+       movem   [$r11+],$r10                                            \n\
+       subq    44,$r12                                                 \n\
+       bge     0b                                                      \n\
+       movem   $r10,[$r13+]                                            \n\
+                                                                       \n\
+       addq    44,$r12 ;; compensate for last loop underflowing n      \n\
+                                                                       \n\
+       ;; Restore registers from stack                                 \n\
+       movem   [$sp+],$r10"
 
      /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) 
      /* Inputs */ : "0" (dst), "1" (src), "2" (n));
index a12c708afc9a46ad12d83ca1bcafa5ee22af449b..b8e6c0430e5b8832b6c9a5314c4f21a371405e57 100644 (file)
@@ -92,58 +92,58 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
        .ifnc %0%1%2%3,$r13$r11$r12$r10                                 \n\
        .err                                                            \n\
        .endif                                                          \n\
-
-       ;; Save the registers we'll use in the movem process
-       ;; on the stack.
-       subq    11*4,$sp
-       movem   $r10,[$sp]
-
-       ;; Now we've got this:
-       ;; r11 - src
-       ;; r13 - dst
-       ;; r12 - n
-
-       ;; Update n for the first loop
-       subq    44,$r12
-
-; Since the noted PC of a faulting instruction in a delay-slot of a taken
-; branch, is that of the branch target, we actually point at the from-movem
-; for this case.  There is no ambiguity here; if there was a fault in that
-; instruction (meaning a kernel oops), the faulted PC would be the address
-; after *that* movem.
-
-0:
-       movem   [$r11+],$r10
-       subq   44,$r12
-       bge     0b
-       movem   $r10,[$r13+]
-1:
-       addq   44,$r12  ;; compensate for last loop underflowing n
-
-       ;; Restore registers from stack
-       movem [$sp+],$r10
-2:
-       .section .fixup,\"ax\"
-
-; To provide a correct count in r10 of bytes that failed to be copied,
-; we jump back into the loop if the loop-branch was taken.  There is no
-; performance penalty for sany use; the program will segfault soon enough.
-
-3:
-       move.d [$sp],$r10
-       addq 44,$r10
-       move.d $r10,[$sp]
-       jump 0b
-4:
-       movem [$sp+],$r10
-       addq 44,$r10
-       addq 44,$r12
-       jump 2b
-
-       .previous
-       .section __ex_table,\"a\"
-       .dword 0b,3b
-       .dword 1b,4b
+                                                                       \n\
+       ;; Save the registers we'll use in the movem process            \n\
+       ;; on the stack.                                                \n\
+       subq    11*4,$sp                                                \n\
+       movem   $r10,[$sp]                                              \n\
+                                                                       \n\
+       ;; Now we've got this:                                          \n\
+       ;; r11 - src                                                    \n\
+       ;; r13 - dst                                                    \n\
+       ;; r12 - n                                                      \n\
+                                                                       \n\
+       ;; Update n for the first loop                                  \n\
+       subq    44,$r12                                                 \n\
+                                                                       \n\
+; Since the noted PC of a faulting instruction in a delay-slot of a taken \n\
+; branch, is that of the branch target, we actually point at the from-movem \n\
+; for this case.  There is no ambiguity here; if there was a fault in that \n\
+; instruction (meaning a kernel oops), the faulted PC would be the address \n\
+; after *that* movem.                                                  \n\
+                                                                       \n\
+0:                                                                     \n\
+       movem   [$r11+],$r10                                            \n\
+       subq   44,$r12                                                  \n\
+       bge     0b                                                      \n\
+       movem   $r10,[$r13+]                                            \n\
+1:                                                                     \n\
+       addq   44,$r12  ;; compensate for last loop underflowing n      \n\
+                                                                       \n\
+       ;; Restore registers from stack                                 \n\
+       movem [$sp+],$r10                                               \n\
+2:                                                                     \n\
+       .section .fixup,\"ax\"                                          \n\
+                                                                       \n\
+; To provide a correct count in r10 of bytes that failed to be copied, \n\
+; we jump back into the loop if the loop-branch was taken.  There is no        \n\
+; performance penalty for sany use; the program will segfault soon enough.\n\
+                                                                       \n\
+3:                                                                     \n\
+       move.d [$sp],$r10                                               \n\
+       addq 44,$r10                                                    \n\
+       move.d $r10,[$sp]                                               \n\
+       jump 0b                                                         \n\
+4:                                                                     \n\
+       movem [$sp+],$r10                                               \n\
+       addq 44,$r10                                                    \n\
+       addq 44,$r12                                                    \n\
+       jump 2b                                                         \n\
+                                                                       \n\
+       .previous                                                       \n\
+       .section __ex_table,\"a\"                                       \n\
+       .dword 0b,3b                                                    \n\
+       .dword 1b,4b                                                    \n\
        .previous"
 
      /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
@@ -253,59 +253,59 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
        If you want to check that the allocation was right; then
        check the equalities in the first comment.  It should say
        "r13=r13, r11=r11, r12=r12" */
-    __asm__ volatile ("
+    __asm__ volatile ("\n\
        .ifnc %0%1%2%3,$r13$r11$r12$r10                                 \n\
        .err                                                            \n\
        .endif                                                          \n\
-
-       ;; Save the registers we'll use in the movem process
-       ;; on the stack.
-       subq    11*4,$sp
-       movem   $r10,[$sp]
-
-       ;; Now we've got this:
-       ;; r11 - src
-       ;; r13 - dst
-       ;; r12 - n
-
-       ;; Update n for the first loop
-       subq    44,$r12
-0:
-       movem   [$r11+],$r10
-1:
-       subq   44,$r12
-       bge     0b
-       movem   $r10,[$r13+]
-
-       addq   44,$r12  ;; compensate for last loop underflowing n
-
-       ;; Restore registers from stack
-       movem [$sp+],$r10
-4:
-       .section .fixup,\"ax\"
-
-;; Do not jump back into the loop if we fail.  For some uses, we get a
-;; page fault somewhere on the line.  Without checking for page limits,
-;; we don't know where, but we need to copy accurately and keep an
-;; accurate count; not just clear the whole line.  To do that, we fall
-;; down in the code below, proceeding with smaller amounts.  It should
-;; be kept in mind that we have to cater to code like what at one time
-;; was in fs/super.c:
-;;  i = size - copy_from_user((void *)page, data, size);
-;; which would cause repeated faults while clearing the remainder of
-;; the SIZE bytes at PAGE after the first fault.
-;; A caveat here is that we must not fall through from a failing page
-;; to a valid page.
-
-3:
-       movem  [$sp+],$r10
-       addq    44,$r12 ;; Get back count before faulting point.
-       subq    44,$r11 ;; Get back pointer to faulting movem-line.
-       jump    4b      ;; Fall through, pretending the fault didn't happen.
-
-       .previous
-       .section __ex_table,\"a\"
-       .dword 1b,3b
+                                                                       \n\
+       ;; Save the registers we'll use in the movem process            \n\
+       ;; on the stack.                                                \n\
+       subq    11*4,$sp                                                \n\
+       movem   $r10,[$sp]                                              \n\
+                                                                       \n\
+       ;; Now we've got this:                                          \n\
+       ;; r11 - src                                                    \n\
+       ;; r13 - dst                                                    \n\
+       ;; r12 - n                                                      \n\
+                                                                       \n\
+       ;; Update n for the first loop                                  \n\
+       subq    44,$r12                                                 \n\
+0:                                                                     \n\
+       movem   [$r11+],$r10                                            \n\
+1:                                                                     \n\
+       subq   44,$r12                                                  \n\
+       bge     0b                                                      \n\
+       movem   $r10,[$r13+]                                            \n\
+                                                                       \n\
+       addq   44,$r12  ;; compensate for last loop underflowing n      \n\
+                                                                       \n\
+       ;; Restore registers from stack                                 \n\
+       movem [$sp+],$r10                                               \n\
+4:                                                                     \n\
+       .section .fixup,\"ax\"                                          \n\
+                                                                       \n\
+;; Do not jump back into the loop if we fail.  For some uses, we get a \n\
+;; page fault somewhere on the line.  Without checking for page limits,        \n\
+;; we don't know where, but we need to copy accurately and keep an     \n\
+;; accurate count; not just clear the whole line.  To do that, we fall \n\
+;; down in the code below, proceeding with smaller amounts.  It should \n\
+;; be kept in mind that we have to cater to code like what at one time \n\
+;; was in fs/super.c:                                                  \n\
+;;  i = size - copy_from_user((void *)page, data, size);               \n\
+;; which would cause repeated faults while clearing the remainder of   \n\
+;; the SIZE bytes at PAGE after the first fault.                       \n\
+;; A caveat here is that we must not fall through from a failing page  \n\
+;; to a valid page.                                                    \n\
+                                                                       \n\
+3:                                                                     \n\
+       movem  [$sp+],$r10                                              \n\
+       addq    44,$r12 ;; Get back count before faulting point.        \n\
+       subq    44,$r11 ;; Get back pointer to faulting movem-line.     \n\
+       jump    4b      ;; Fall through, pretending the fault didn't happen.\n\
+                                                                       \n\
+       .previous                                                       \n\
+       .section __ex_table,\"a\"                                       \n\
+       .dword 1b,3b                                                    \n\
        .previous"
 
      /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
@@ -425,64 +425,64 @@ __do_clear_user (void __user *pto, unsigned long pn)
       If you want to check that the allocation was right; then
       check the equalities in the first comment.  It should say
       something like "r13=r13, r11=r11, r12=r12". */
-    __asm__ volatile ("
+    __asm__ volatile ("\n\
        .ifnc %0%1%2,$r13$r12$r10                                       \n\
        .err                                                            \n\
        .endif                                                          \n\
-
-       ;; Save the registers we'll clobber in the movem process
-       ;; on the stack.  Don't mention them to gcc, it will only be
-       ;; upset.
-       subq    11*4,$sp
-       movem   $r10,[$sp]
-
-       clear.d $r0
-       clear.d $r1
-       clear.d $r2
-       clear.d $r3
-       clear.d $r4
-       clear.d $r5
-       clear.d $r6
-       clear.d $r7
-       clear.d $r8
-       clear.d $r9
-       clear.d $r10
-       clear.d $r11
-
-       ;; Now we've got this:
-       ;; r13 - dst
-       ;; r12 - n
-
-       ;; Update n for the first loop
-       subq    12*4,$r12
-0:
-       subq   12*4,$r12
-       bge     0b
-       movem   $r11,[$r13+]
-1:
-       addq   12*4,$r12        ;; compensate for last loop underflowing n
-
-       ;; Restore registers from stack
-       movem [$sp+],$r10
-2:
-       .section .fixup,\"ax\"
-3:
-       move.d [$sp],$r10
-       addq 12*4,$r10
-       move.d $r10,[$sp]
-       clear.d $r10
-       jump 0b
-
-4:
-       movem [$sp+],$r10
-       addq 12*4,$r10
-       addq 12*4,$r12
-       jump 2b
-
-       .previous
-       .section __ex_table,\"a\"
-       .dword 0b,3b
-       .dword 1b,4b
+                                                                       \n\
+       ;; Save the registers we'll clobber in the movem process        \n\
+       ;; on the stack.  Don't mention them to gcc, it will only be    \n\
+       ;; upset.                                                       \n\
+       subq    11*4,$sp                                                \n\
+       movem   $r10,[$sp]                                              \n\
+                                                                       \n\
+       clear.d $r0                                                     \n\
+       clear.d $r1                                                     \n\
+       clear.d $r2                                                     \n\
+       clear.d $r3                                                     \n\
+       clear.d $r4                                                     \n\
+       clear.d $r5                                                     \n\
+       clear.d $r6                                                     \n\
+       clear.d $r7                                                     \n\
+       clear.d $r8                                                     \n\
+       clear.d $r9                                                     \n\
+       clear.d $r10                                                    \n\
+       clear.d $r11                                                    \n\
+                                                                       \n\
+       ;; Now we've got this:                                          \n\
+       ;; r13 - dst                                                    \n\
+       ;; r12 - n                                                      \n\
+                                                                       \n\
+       ;; Update n for the first loop                                  \n\
+       subq    12*4,$r12                                               \n\
+0:                                                                     \n\
+       subq   12*4,$r12                                                \n\
+       bge     0b                                                      \n\
+       movem   $r11,[$r13+]                                            \n\
+1:                                                                     \n\
+       addq   12*4,$r12        ;; compensate for last loop underflowing n\n\
+                                                                       \n\
+       ;; Restore registers from stack                                 \n\
+       movem [$sp+],$r10                                               \n\
+2:                                                                     \n\
+       .section .fixup,\"ax\"                                          \n\
+3:                                                                     \n\
+       move.d [$sp],$r10                                               \n\
+       addq 12*4,$r10                                                  \n\
+       move.d $r10,[$sp]                                               \n\
+       clear.d $r10                                                    \n\
+       jump 0b                                                         \n\
+                                                                       \n\
+4:                                                                     \n\
+       movem [$sp+],$r10                                               \n\
+       addq 12*4,$r10                                                  \n\
+       addq 12*4,$r12                                                  \n\
+       jump 2b                                                         \n\
+                                                                       \n\
+       .previous                                                       \n\
+       .section __ex_table,\"a\"                                       \n\
+       .dword 0b,3b                                                    \n\
+       .dword 1b,4b                                                    \n\
        .previous"
 
      /* Outputs */ : "=r" (dst), "=r" (n), "=r" (retn)
index cc6ba542375472be1147f122b5ebd3a41e434a4b..7f72d7c9e1ce0f2bf6d29a1657d936b12de32e71 100644 (file)
@@ -362,8 +362,6 @@ config ETRAX_AXISFLASHMAP
        select MTD
        select MTD_CFI
        select MTD_CFI_AMDSTD
-       select MTD_OBSOLETE_CHIPS
-       select MTD_AMDSTD
        select MTD_CHAR
        select MTD_BLOCK
        select MTD_PARTITIONS
index 3ec12ea44e8ede39efda94ac85b3c6562243c4e7..c5ff95e18269b44220113d4187dc584b6796bce6 100644 (file)
@@ -190,13 +190,12 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
               "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
               map_cs->name, map_cs->size, map_cs->map_priv_1);
 
-#ifdef CONFIG_MTD_AMDSTD
-       mtd_cs = do_map_probe("amd_flash", map_cs);
-#endif
 #ifdef CONFIG_MTD_CFI
-       if (!mtd_cs) {
                mtd_cs = do_map_probe("cfi_probe", map_cs);
-       }
+#endif
+#ifdef CONFIG_MTD_JEDECPROBE
+       if (!mtd_cs)
+               mtd_cs = do_map_probe("jedec_probe", map_cs);
 #endif
 
        return mtd_cs;
index df89298aafc46121fb445649f0c1f50818d70b60..d581b0a92a3f10e56fc9ec340b4d249ca472ae71 100644 (file)
@@ -185,7 +185,7 @@ static struct sync_port ports[]=
        }
 };
 
-#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
+#define NUMBER_OF_PORTS ARRAY_SIZE(ports)
 
 static const struct file_operations sync_serial_fops = {
        .owner   = THIS_MODULE,
diff --git a/arch/cris/arch-v32/kernel/cache.c b/arch/cris/arch-v32/kernel/cache.c
new file mode 100644 (file)
index 0000000..80da7b8
--- /dev/null
@@ -0,0 +1,33 @@
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/arch/cache.h>
+#include <asm/arch/hwregs/dma.h>
+
+/* This file is used to workaround a cache bug, Guinness TR 106. */
+
+inline void flush_dma_descr(struct dma_descr_data *descr, int flush_buf)
+{
+       /* Flush descriptor to make sure we get correct in_eop and after. */
+       asm volatile ("ftagd [%0]" :: "r" (descr));
+       /* Flush buffer pointed out by descriptor. */
+       if (flush_buf)
+               cris_flush_cache_range(phys_to_virt((unsigned)descr->buf),
+                               (unsigned)(descr->after - descr->buf));
+}
+EXPORT_SYMBOL(flush_dma_descr);
+
+void flush_dma_list(struct dma_descr_data *descr)
+{
+       while (1) {
+               flush_dma_descr(descr, 1);
+               if (descr->eol)
+                       break;
+               descr = phys_to_virt((unsigned)descr->next);
+       }
+}
+EXPORT_SYMBOL(flush_dma_list);
+
+/* From cacheflush.S */
+EXPORT_SYMBOL(cris_flush_cache);
+/* From cacheflush.S */
+EXPORT_SYMBOL(cris_flush_cache_range);
diff --git a/arch/cris/arch-v32/kernel/cacheflush.S b/arch/cris/arch-v32/kernel/cacheflush.S
new file mode 100644 (file)
index 0000000..956e8fb
--- /dev/null
@@ -0,0 +1,94 @@
+       .global cris_flush_cache_range
+cris_flush_cache_range:
+       move.d 1024, $r12
+       cmp.d $r11, $r12
+       bhi cris_flush_1KB
+       nop
+       add.d $r10, $r11
+       ftagd [$r10]
+cris_flush_last:
+       addq 32, $r10
+       cmp.d $r11, $r10
+       blt cris_flush_last
+       ftagd [$r10]
+       ret
+       nop
+cris_flush_1KB:
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ftagd [$r10]
+       addq 32, $r10
+       ba cris_flush_cache_range
+       sub.d $r12, $r11
+
+       .global cris_flush_cache
+cris_flush_cache:
+       moveq 0, $r10
+cris_flush_line:
+       move.d 16*1024, $r11
+       addq 16, $r10
+       cmp.d $r10, $r11
+       blt cris_flush_line
+       fidxd [$r10]
+       ret
+       nop
index dfbfcb8d2585b664fe7a0ef362aae1b14d8f682c..a22a9e02e09309829b9c60448776ec85ccfd4e0c 100644 (file)
@@ -49,7 +49,7 @@ struct crisv32_ioport crisv32_ioports[] =
        }
 };
 
-#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
+#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports)
 
 struct crisv32_iopin crisv32_led1_green;
 struct crisv32_iopin crisv32_led1_red;
index 4662f363df638371dc4336d0b4233bcd9aed242a..72e9e8331f63a2aff9410a2be971250467cbf028 100644 (file)
@@ -54,12 +54,10 @@ show_cpuinfo(struct seq_file *m, void *v)
 {
        int i;
        int cpu = (int)v - 1;
-       int entries;
        unsigned long revision;
        struct cpu_info *info;
 
-       entries = sizeof cpinfo / sizeof(struct cpu_info);
-       info = &cpinfo[entries - 1];
+       info = &cpinfo[ARRAY_SIZE(cpinfo) - 1];
 
 #ifdef CONFIG_SMP
        if (!cpu_online(cpu))
@@ -68,7 +66,7 @@ show_cpuinfo(struct seq_file *m, void *v)
 
        revision = rdvr();
 
-       for (i = 0; i < entries; i++) {
+       for (i = 0; i < ARRAY_SIZE(cpinfo); i++) {
                if (cpinfo[i].rev == revision) {
                        info = &cpinfo[i];
                        break;
index 142a10818af37a4049b797ffbb6e27ba453a2ff0..9c33ae65993444d3f53fd0f69a3bff2b557e1d6d 100644 (file)
@@ -226,8 +226,6 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-CONFIG_MTD_OBSOLETE_CHIPS=y
-CONFIG_MTD_AMDSTD=y
 # CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
@@ -276,6 +274,7 @@ CONFIG_MTDRAM_ABS_POS=0x0
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -302,16 +301,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
+# CONFIG_IDE is not set
+# CONFIG_PARIDE is not set
 
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
@@ -321,7 +318,6 @@ CONFIG_BLK_DEV_IDECD=y
 #
 # CONFIG_IDE_GENERIC is not set
 # CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
@@ -329,6 +325,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # SCSI device support
 #
 # CONFIG_SCSI is not set
+# CONFIG_ISCSI_TCP is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -414,26 +411,11 @@ CONFIG_NETFILTER=y
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-# CONFIG_BT_SCO is not set
-CONFIG_BT_RFCOMM=y
-# CONFIG_BT_RFCOMM_TTY is not set
-CONFIG_BT_BNEP=y
-# CONFIG_BT_BNEP_MC_FILTER is not set
-# CONFIG_BT_BNEP_PROTO_FILTER is not set
-# CONFIG_BT_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUSB=y
-# CONFIG_BT_HCIUSB_SCO is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_AF_RXRPC_DEBUG is not set
+# CONFIG_BT is not set
+# CONFIG_I2C is not set
+
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -485,31 +467,17 @@ CONFIG_NET_ETHERNET=y
 #
 # Input device support
 #
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT is not set
 
 #
 # Input I/O drivers
 #
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
 
 #
 # Input Device Drivers
@@ -525,6 +493,7 @@ CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -542,6 +511,8 @@ CONFIG_MOUSE_PS2=y
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -559,6 +530,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
+# CONFIG_RTC_LIB is not set
+# CONFIG_RTC_CLASS is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -660,7 +633,9 @@ CONFIG_NFS_V3=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -685,10 +660,22 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_SOUND is not set
 
+#
+# Generic devices
+#
+# CONFIG_SND_MPU401_UART is not set
+# 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
+
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_NET_PCMCIA is not set
 
 #
 # PC-card bridges
@@ -734,6 +721,7 @@ CONFIG_USB_DEVICEFS=y
 # USB Input Devices
 #
 # CONFIG_USB_HID is not set
+# HID_SUPPORT is not set
 
 #
 # USB HID Boot Protocol drivers
@@ -829,7 +817,7 @@ CONFIG_USB_RTL8150=y
 
 #
 # Hardware crypto devices
-#
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
index 105bb5ed48f7d3d5ed1b3ac791b3fc1655479050..62f0e752915a253ef3e8b97dec7519e8e205e219 100644 (file)
@@ -27,6 +27,7 @@ extern void __Mod(void);
 extern void __ashldi3(void);
 extern void __ashrdi3(void);
 extern void __lshrdi3(void);
+extern void __negdi2(void);
 extern void iounmap(volatile void * __iomem);
 
 /* Platform dependent support */
@@ -34,19 +35,6 @@ EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(loops_per_usec);
 
-/* String functions */
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strcpy);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strncmp);
-EXPORT_SYMBOL(strncpy);
-
 /* Math functions */
 EXPORT_SYMBOL(__Udiv);
 EXPORT_SYMBOL(__Umod);
@@ -55,6 +43,7 @@ EXPORT_SYMBOL(__Mod);
 EXPORT_SYMBOL(__ashldi3);
 EXPORT_SYMBOL(__ashrdi3);
 EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__negdi2);
 
 /* Memory functions */
 EXPORT_SYMBOL(__ioremap);
@@ -84,4 +73,4 @@ EXPORT_SYMBOL(start_one_shot_timer);
 EXPORT_SYMBOL(del_fast_timer);
 EXPORT_SYMBOL(schedule_usleep);
 #endif
-
+EXPORT_SYMBOL(csum_partial);
index 5c27ff86121b9c40ccb39a60b9e3772d52c8a331..2dfac8c79090a248291375e8ed3f392878530ca8 100644 (file)
@@ -2,7 +2,7 @@
  *
  *     linux/arch/cris/kernel/irq.c
  *
- *      Copyright (c) 2000,2001 Axis Communications AB
+ *      Copyright (c) 2000,2007 Axis Communications AB
  *
  *      Authors: Bjorn Wesen (bjornw@axis.com)
  *
@@ -92,14 +92,16 @@ skip:
 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 {
        unsigned long sp;
+       struct pt_regs *old_regs = set_irq_regs(regs);
        irq_enter();
        sp = rdsp();
        if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
                printk("do_IRQ: stack overflow: %lX\n", sp);
                show_stack(NULL, (unsigned long *)sp);
        }
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
         irq_exit();
+       set_irq_regs(old_regs);
 }
 
 void weird_irq(void)
index 123451c44154f5961ae740e41c5117670e1fb8d1..9ca558fc5bc8454f2a2e5f3a06c919b416ff1d0a 100644 (file)
@@ -195,6 +195,11 @@ EXPORT_SYMBOL(enable_hlt);
  */
 void (*pm_idle)(void);
 
+extern void default_idle(void);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
index 1085d037027b2cd20b972b797c0a655d282911b3..3ccd20e85dce07eb8a2e54a505bfbfe2b0db1c0e 100644 (file)
 /* notification of userspace execution resumption
  * - triggered by current->work.notify_resume
  */
-extern int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal(int canrestart, struct pt_regs *regs);
 
 
-void do_notify_resume(int canrestart, sigset_t *oldset, struct pt_regs *regs, 
+void do_notify_resume(int canrestart, struct pt_regs *regs,
                      __u32 thread_info_flags  )
 {
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(canrestart,oldset,regs);
+               do_signal(canrestart,regs);
 }
index 514359b8122e5b14a2e99a8f6c0a001953f1a27a..8b9984197edcc57878356a56848c237ea06aa109 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/sem.h>
index acfd0455940590c5e5292ce86b89dde0e1b0200e..7a2cc7efbcf8be986601d8b5f31e646b7ff9afc9 100644 (file)
@@ -171,10 +171,6 @@ get_cmos_time(void)
        mon = CMOS_READ(RTC_MONTH);
        year = CMOS_READ(RTC_YEAR);
 
-       printk(KERN_DEBUG
-              "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n",
-              sec, min, hour, day, mon, year);
-
        BCD_TO_BIN(sec);
        BCD_TO_BIN(min);
        BCD_TO_BIN(hour);
@@ -207,12 +203,12 @@ void
 cris_do_profile(struct pt_regs* regs)
 {
 
-#if CONFIG_SYSTEM_PROFILER
+#ifdef CONFIG_SYSTEM_PROFILER
         cris_profile_sample(regs);
 #endif
 
-#if CONFIG_PROFILING
-        profile_tick(CPU_PROFILING, regs);
+#ifdef CONFIG_PROFILING
+        profile_tick(CPU_PROFILING);
 #endif
 }
 
index 4103c2c487f3a114654f242f16b18d0e99281447..b841ecfd5d5a991fb15a048e2bcf0c7e4f2b38a6 100644 (file)
@@ -197,7 +197,7 @@ void __init mem_init(void)
 /*
  * free the memory that was only required for initialisation
  */
-void __init free_initmem(void)
+void free_initmem(void)
 {
 #if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
        unsigned long start, end, addr;
index 1189d035d316e6f853e464b5736d81eafe72f937..bf6d9d8c802fdb9d20e087e28c05a0501f8d9896 100644 (file)
@@ -285,7 +285,7 @@ sys_fw_init (const char *args, int arglen)
        }
        cmd_line[arglen] = '\0';
 
-       memset(efi_systab, 0, sizeof(efi_systab));
+       memset(efi_systab, 0, sizeof(*efi_systab));
        efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
        efi_systab->hdr.revision  = ((1 << 16) | 00);
        efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
index 466bbcb138b2f57beed7181010beeda0d2513726..c5c872b250da5e420a661fb25223115fe2c7b424 100644 (file)
@@ -290,7 +290,6 @@ struct old_linux32_dirent {
 #define _ASM_IA64_ELF_H                /* Don't include elf.h */
 
 #include <linux/sched.h>
-#include <asm/processor.h>
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
diff --git a/arch/ia64/kernel/.gitignore b/arch/ia64/kernel/.gitignore
new file mode 100644 (file)
index 0000000..9830775
--- /dev/null
@@ -0,0 +1 @@
+gate.lds
index 3d45d24a9d613ce66215c5399d513dd24239e3c2..897e2083a3b1b4c77f8dd200d3ab593b377677e8 100644 (file)
@@ -678,9 +678,11 @@ int __init acpi_boot_init(void)
        /* I/O APIC */
 
        if (acpi_table_parse_madt
-           (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
-               printk(KERN_ERR PREFIX
-                      "Error parsing MADT - no IOSAPIC entries\n");
+           (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) {
+               if (!ia64_platform_is("sn2"))
+                       printk(KERN_ERR PREFIX
+                              "Error parsing MADT - no IOSAPIC entries\n");
+       }
 
        /* System-Level Interrupt Routing */
 
index 6216eba2e38f2a5293683e501827fcf9490a5ab9..8e8f8b6193eea5038fb9bff9a53baa03b7694f7b 100644 (file)
@@ -218,9 +218,10 @@ efi_gettimeofday (struct timespec *ts)
 {
        efi_time_t tm;
 
-       memset(ts, 0, sizeof(ts));
-       if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS)
+       if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS) {
+               memset(ts, 0, sizeof(*ts));
                return;
+       }
 
        ts->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
        ts->tv_nsec = tm.nanosecond;
@@ -1112,7 +1113,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                if (md->num_pages == 0) /* should not happen */
                        continue;
 
-               flags = IORESOURCE_MEM;
+               flags = IORESOURCE_MEM | IORESOURCE_BUSY;
                switch (md->type) {
 
                        case EFI_MEMORY_MAPPED_IO:
@@ -1134,12 +1135,11 @@ efi_initialize_iomem_resources(struct resource *code_resource,
 
                        case EFI_ACPI_MEMORY_NVS:
                                name = "ACPI Non-volatile Storage";
-                               flags |= IORESOURCE_BUSY;
                                break;
 
                        case EFI_UNUSABLE_MEMORY:
                                name = "reserved";
-                               flags |= IORESOURCE_BUSY | IORESOURCE_DISABLED;
+                               flags |= IORESOURCE_DISABLED;
                                break;
 
                        case EFI_RESERVED_TYPE:
@@ -1148,7 +1148,6 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                        case EFI_ACPI_RECLAIM_MEMORY:
                        default:
                                name = "reserved";
-                               flags |= IORESOURCE_BUSY;
                                break;
                }
 
index cfe4654838f445423455979bca494d0e8fd1394a..274a593830432ba711a32725820f520071426a3d 100644 (file)
@@ -748,6 +748,15 @@ skip_numa_setup:
 #endif
 }
 
+static inline unsigned char choose_dmode(void)
+{
+#ifdef CONFIG_SMP
+       if (smp_int_redirect & SMP_IRQ_REDIRECTION)
+               return IOSAPIC_LOWEST_PRIORITY;
+#endif
+       return IOSAPIC_FIXED;
+}
+
 /*
  * ACPI can describe IOSAPIC interrupts via static tables and namespace
  * methods.  This provides an interface to register those interrupts and
@@ -762,6 +771,7 @@ iosapic_register_intr (unsigned int gsi,
        unsigned long flags;
        struct iosapic_rte_info *rte;
        u32 low32;
+       unsigned char dmode;
 
        /*
         * If this GSI has already been registered (i.e., it's a
@@ -791,8 +801,8 @@ iosapic_register_intr (unsigned int gsi,
 
        spin_lock(&irq_desc[irq].lock);
        dest = get_target_cpu(gsi, irq);
-       err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY,
-                           polarity, trigger);
+       dmode = choose_dmode();
+       err = register_intr(gsi, irq, dmode, polarity, trigger);
        if (err < 0) {
                spin_unlock(&irq_desc[irq].lock);
                irq = err;
@@ -961,10 +971,12 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
 {
        int vector, irq;
        unsigned int dest = cpu_physical_id(smp_processor_id());
+       unsigned char dmode;
 
        irq = vector = isa_irq_to_vector(isa_irq);
        BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL));
-       register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
+       dmode = choose_dmode();
+       register_intr(gsi, irq, dmode, polarity, trigger);
 
        DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
            isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
index 44be1c952b7ca2cc6761f65c112a7f737c1f0b7f..6dee579f205fc451bcffbcbaddd0c370b6d35104 100644 (file)
@@ -61,9 +61,11 @@ int show_interrupts(struct seq_file *p, void *v)
        unsigned long flags;
 
        if (i == 0) {
-               seq_printf(p, "           ");
+               char cpuname[16];
+               seq_printf(p, "     ");
                for_each_online_cpu(j) {
-                       seq_printf(p, "CPU%d       ",j);
+                       snprintf(cpuname, 10, "CPU%d", j);
+                       seq_printf(p, "%10s ", cpuname);
                }
                seq_putc(p, '\n');
        }
index cc87025e8f54c0d2656584376949a44642432815..10b48cd15a878c399503d5bc5da4334906748978 100644 (file)
@@ -571,7 +571,7 @@ out:
  *  Outputs
  *      None
  */
-static void __init
+void
 ia64_mca_register_cpev (int cpev)
 {
        /* Register the CPE interrupt vector with SAL */
index 6ef6ffb943a0cd368c1d11c9dc79888bc4f7674c..396004e8cd1432af8fa1440ea0e2b93c385175bd 100644 (file)
@@ -470,7 +470,7 @@ register_info(char *page)
        return p - page;
 }
 
-static const char *proc_features[]={
+static char *proc_features_0[]={               /* Feature set 0 */
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
@@ -502,25 +502,92 @@ static const char *proc_features[]={
        "Enable BERR promotion"
 };
 
+static char *proc_features_16[]={              /* Feature set 16 */
+       "Disable ETM",
+       "Enable ETM",
+       "Enable MCA on half-way timer",
+       "Enable snoop WC",
+       NULL,
+       "Enable Fast Deferral",
+       "Disable MCA on memory aliasing",
+       "Enable RSB",
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       "DP system processor",
+       "Low Voltage",
+       "HT supported",
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL
+};
+
+static char **proc_features[]={
+       proc_features_0,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL,
+       proc_features_16,
+       NULL, NULL, NULL, NULL,
+};
+
+static char *
+feature_set_info(char *page, u64 avail, u64 status, u64 control, u64 set)
+{
+       char *p = page;
+       char **vf, **v;
+       int i;
+
+       vf = v = proc_features[set];
+       for(i=0; i < 64; i++, avail >>=1, status >>=1, control >>=1) {
+
+               if (!(control))         /* No remaining bits set */
+                       break;
+               if (!(avail & 0x1))     /* Print only bits that are available */
+                       continue;
+               if (vf)
+                       v = vf + i;
+               if ( v && *v ) {
+                       p += sprintf(p, "%-40s : %s %s\n", *v,
+                               avail & 0x1 ? (status & 0x1 ?
+                                               "On " : "Off"): "",
+                               avail & 0x1 ? (control & 0x1 ?
+                                               "Ctrl" : "NoCtrl"): "");
+               } else {
+                       p += sprintf(p, "Feature set %2ld bit %2d\t\t\t"
+                                       " : %s %s\n",
+                               set, i,
+                               avail & 0x1 ? (status & 0x1 ?
+                                               "On " : "Off"): "",
+                               avail & 0x1 ? (control & 0x1 ?
+                                               "Ctrl" : "NoCtrl"): "");
+               }
+       }
+       return p;
+}
 
 static int
 processor_info(char *page)
 {
        char *p = page;
-       const char **v = proc_features;
-       u64 avail=1, status=1, control=1;
-       int i;
+       u64 avail=1, status=1, control=1, feature_set=0;
        s64 ret;
 
-       if ((ret=ia64_pal_proc_get_features(&avail, &status, &control)) != 0) return 0;
+       do {
+               ret = ia64_pal_proc_get_features(&avail, &status, &control,
+                                               feature_set);
+               if (ret < 0) {
+                       return p - page;
+               }
+               if (ret == 1) {
+                       feature_set++;
+                       continue;
+               }
+
+               p = feature_set_info(p, avail, status, control, feature_set);
+
+               feature_set++;
+       } while(1);
 
-       for(i=0; i < 64; i++, v++,avail >>=1, status >>=1, control >>=1) {
-               if ( ! *v ) continue;
-               p += sprintf(p, "%-40s : %s%s %s\n", *v,
-                               avail & 0x1 ? "" : "NotImpl",
-                               avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "",
-                               avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
-       }
        return p - page;
 }
 
index e796e29f8e156df255c93f85fa5cd8f7a882dace..2cb9425e04210fed5de6e6168074f04193210971 100644 (file)
@@ -129,9 +129,6 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
                first_time = 0;
                if (need_workaround)
                        printk(KERN_INFO "Leaving McKinley Errata 9 workaround enabled\n");
-               else
-                       printk(KERN_INFO "McKinley Errata 9 workaround not needed; "
-                              "disabling it\n");
        }
        if (need_workaround)
                return;
index 59169bf7145f69f955708f49c4a9debb5c2fa713..73e7c2e40b54713e69566772b79d3b92fc44a7da 100644 (file)
@@ -558,7 +558,7 @@ static ctl_table pfm_sysctl_dir[] = {
        {
                .ctl_name       = CTL_UNNUMBERED,
                .procname       = "perfmon",
-               .mode           = 0755,
+               .mode           = 0555,
                .child          = pfm_ctl_table,
        },
        {}
@@ -567,7 +567,7 @@ static ctl_table pfm_sysctl_root[] = {
        {
                .ctl_name       = CTL_KERN,
                .procname       = "kernel",
-               .mode           = 0755,
+               .mode           = 0555,
                .child          = pfm_sysctl_dir,
        },
        {}
index d3c538be466c8e82d5e76719230de21fa3121d79..7e9c275ea148579b8b792583f497ae15e21927f3 100644 (file)
@@ -146,6 +146,46 @@ find_bootmap_location (unsigned long start, unsigned long end, void *arg)
        return 0;
 }
 
+#ifdef CONFIG_SMP
+static void *cpu_data;
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void * __cpuinit
+per_cpu_init (void)
+{
+       int cpu;
+       static int first_time=1;
+
+       /*
+        * get_free_pages() cannot be used before cpu_init() done.  BSP
+        * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
+        * get_zeroed_page().
+        */
+       if (first_time) {
+               first_time=0;
+               for (cpu = 0; cpu < NR_CPUS; cpu++) {
+                       memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
+                       __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
+                       cpu_data += PERCPU_PAGE_SIZE;
+                       per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
+               }
+       }
+       return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+}
+
+static inline void
+alloc_per_cpu_data(void)
+{
+       cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
+                                  PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+}
+#else
+#define alloc_per_cpu_data() do { } while (0)
+#endif /* CONFIG_SMP */
+
 /**
  * find_memory - setup memory map
  *
@@ -182,41 +222,9 @@ find_memory (void)
 
        find_initrd();
 
+       alloc_per_cpu_data();
 }
 
-#ifdef CONFIG_SMP
-/**
- * per_cpu_init - setup per-cpu variables
- *
- * Allocate and setup per-cpu data areas.
- */
-void * __cpuinit
-per_cpu_init (void)
-{
-       void *cpu_data;
-       int cpu;
-       static int first_time=1;
-
-       /*
-        * get_free_pages() cannot be used before cpu_init() done.  BSP
-        * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
-        * get_zeroed_page().
-        */
-       if (first_time) {
-               first_time=0;
-               cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
-                                          PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
-               for (cpu = 0; cpu < NR_CPUS; cpu++) {
-                       memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
-                       __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
-                       cpu_data += PERCPU_PAGE_SIZE;
-                       per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
-               }
-       }
-       return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-}
-#endif /* CONFIG_SMP */
-
 static int
 count_pages (u64 start, u64 end, void *arg)
 {
index 0f9b12683bf39bfb44da0adb2f1b21816a6c19c0..53351c3cd7b1ef071fb6ff53ccdfc219f135182d 100644 (file)
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/irq.h>
@@ -85,12 +85,18 @@ static void sn_shutdown_irq(unsigned int irq)
 {
 }
 
+extern void ia64_mca_register_cpev(int);
+
 static void sn_disable_irq(unsigned int irq)
 {
+       if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
+               ia64_mca_register_cpev(0);
 }
 
 static void sn_enable_irq(unsigned int irq)
 {
+       if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
+               ia64_mca_register_cpev(irq);
 }
 
 static void sn_ack_irq(unsigned int irq)
index e336e1692a734cb137734f555133a68887915e57..81785b78bc1ecc5e4c53053567d5bfffbc9aa230 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -257,7 +257,9 @@ xpc_hb_checker(void *ignore)
 
        set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU));
 
+       /* set our heartbeating to other partitions into motion */
        xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
+       xpc_hb_beater(0);
 
        while (!(volatile int) xpc_exiting) {
 
@@ -1338,16 +1340,8 @@ xpc_init(void)
                dev_warn(xpc_part, "can't register die notifier\n");
        }
 
-
-       /*
-        * Set the beating to other partitions into motion.  This is
-        * the last requirement for other partitions' discovery to
-        * initiate communications with us.
-        */
        init_timer(&xpc_hb_timer);
        xpc_hb_timer.function = xpc_hb_beater;
-       xpc_hb_beater(0);
-
 
        /*
         * The real work-horse behind xpc.  This processes incoming
index 2c7d6c240b73767118485f3b24c6fad93711aa84..2f2ce0c28bc082b0d8d2a9c65ef224ac3509630a 100644 (file)
@@ -361,10 +361,10 @@ config QEMU
        select PCSPEAKER
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_MIPS32_R1
+       select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
-       select ARCH_SPARSEMEM_ENABLE
        select GENERIC_HARDIRQS_NO__DO_IRQ
        select NR_CPUS_DEFAULT_1
        select SYS_SUPPORTS_SMP
@@ -1409,7 +1409,6 @@ config MIPS_MT_SMP
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
-       select CPU_MIPSR2_SRS
        select MIPS_MT
        select NR_CPUS_DEFAULT_2
        select SMP
@@ -1426,7 +1425,6 @@ config MIPS_MT_SMTC
        select GENERIC_CLOCKEVENTS_BROADCAST
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
-       select CPU_MIPSR2_SRS
        select MIPS_MT
        select NR_CPUS_DEFAULT_8
        select SMP
@@ -1453,7 +1451,6 @@ config MIPS_VPE_LOADER
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
-       select CPU_MIPSR2_SRS
        select MIPS_MT
        help
          Includes a loader for loading an elf relocatable object
@@ -1582,12 +1579,6 @@ config CPU_MIPSR2_IRQ_VI
 config CPU_MIPSR2_IRQ_EI
        bool
 
-#
-# Shadow registers are an R2 feature
-#
-config CPU_MIPSR2_SRS
-       bool
-
 config CPU_HAS_SYNC
        bool
        depends on !CPU_R3000
index 23c17755eca07a0b6e46f416da5316e3e6638984..a1f8d8b96b03faf5217d597ae59d28356012fb96 100644 (file)
@@ -44,7 +44,7 @@ endif
 
 ifneq ($(SUBARCH),$(ARCH))
   ifeq ($(CROSS_COMPILE),)
-    CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux-  $(tool-archpref)-gnu-linux-  $(tool-archpref)-unknown-gnu-linux-)
+    CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux-  $(tool-archpref)-linux-gnu-  $(tool-archpref)-unknown-linux-gnu-)
   endif
 endif
 
index 21e6d63eb4d191f96df5e7eb6b7a454dec39fb73..0a57f86945f1e5be7b85553cc4839ba7348d2371 100644 (file)
@@ -75,6 +75,7 @@ static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
        cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
        init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
 
+       __raw_writeq(0, cfg);
        __raw_writeq(delta - 1, init);
        __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
 
@@ -122,7 +123,7 @@ void __cpuinit sb1480_clockevent_init(void)
                                  CLOCK_EVT_FEAT_ONESHOT;
        clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
        cd->max_delta_ns        = clockevent_delta2ns(0x7fffff, cd);
-       cd->min_delta_ns        = clockevent_delta2ns(1, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(2, cd);
        cd->rating              = 200;
        cd->irq                 = irq;
        cd->cpumask             = cpumask_of_cpu(cpu);
@@ -143,7 +144,10 @@ void __cpuinit sb1480_clockevent_init(void)
 
        action->handler = sibyte_counter_handler;
        action->flags   = IRQF_DISABLED | IRQF_PERCPU;
+       action->mask    = cpumask_of_cpu(cpu);
        action->name    = name;
        action->dev_id  = cd;
+
+       irq_set_affinity(irq, cpumask_of_cpu(cpu));
        setup_irq(irq, action);
 }
index e2029d0fc39b917227e2fc8b50c8b7d97f0732e7..63ac3ad462bc61cf2aeafe817a6ea1255c3991a0 100644 (file)
@@ -73,6 +73,7 @@ static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
        cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
        init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
 
+       __raw_writeq(0, cfg);
        __raw_writeq(delta - 1, init);
        __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
 
@@ -121,7 +122,7 @@ void __cpuinit sb1250_clockevent_init(void)
                                  CLOCK_EVT_FEAT_ONESHOT;
        clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
        cd->max_delta_ns        = clockevent_delta2ns(0x7fffff, cd);
-       cd->min_delta_ns        = clockevent_delta2ns(1, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(2, cd);
        cd->rating              = 200;
        cd->irq                 = irq;
        cd->cpumask             = cpumask_of_cpu(cpu);
@@ -142,7 +143,10 @@ void __cpuinit sb1250_clockevent_init(void)
 
        action->handler = sibyte_counter_handler;
        action->flags   = IRQF_DISABLED | IRQF_PERCPU;
+       action->mask    = cpumask_of_cpu(cpu);
        action->name    = name;
        action->dev_id  = cd;
+
+       irq_set_affinity(irq, cpumask_of_cpu(cpu));
        setup_irq(irq, action);
 }
index c8c47a2d1972f5cb6c3a8dadd155ea32206b634a..5c2794391bf53423d8cd4a1282e17603701023f8 100644 (file)
@@ -943,6 +943,11 @@ __init void cpu_probe(void)
        }
 
        __cpu_name[cpu] = cpu_to_name(c);
+
+       if (cpu_has_mips_r2)
+               c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
+       else
+               c->srsets = 1;
 }
 
 __init void cpu_report(void)
index ebb16e66887769086d9706ccf16725270c1c911a..92212bbb8e4559ff04cfc0888fda6fb403868ed0 100644 (file)
@@ -43,7 +43,7 @@ static cycle_t sb1250_hpt_read(void)
 }
 
 struct clocksource bcm1250_clocksource = {
-       .name   = "MIPS",
+       .name   = "bcm1250-counter-3",
        .rating = 200,
        .read   = sb1250_hpt_read,
        .mask   = CLOCKSOURCE_MASK(23),
index c0f19d638b986c4f5be93b801a90b4e6717c6419..e76a76bf0b3de0cad4de6099e45f81884a994d53 100644 (file)
@@ -146,7 +146,7 @@ NESTED(handle_int, PT_SIZE, sp)
        and     k0, ST0_IEP
        bnez    k0, 1f
 
-       mfc0    k0, EP0_EPC
+       mfc0    k0, CP0_EPC
        .set    noreorder
        j       k0
        rfe
index 33506ff25910f4d8f8974c7a0d9b2098649e8681..5b10ac133ec837b4ccd91844a42321d6a68769fd 100644 (file)
@@ -430,6 +430,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
                        break;
 
                default:
+                       spin_unlock_irq(&current->sighand->siglock);
                        return -EINVAL;
                }
                recalc_sigpending();
index 2507328834886e7f6151799713cb1de5ae505fef..971adf6ef4f4d527b94c94dbff5edab0e57f78b1 100644 (file)
@@ -44,5 +44,5 @@ void __init rm7k_cpu_irq_init(void)
 
        for (i = base; i < base + 4; i++)
                set_irq_chip_and_handler(i, &rm7k_irq_controller,
-                                        handle_level_irq);
+                                        handle_percpu_irq);
 }
index ae83d2df6f31d51dc47a223b45622add5633bd76..7b04583bd800410a5a0d24e92865d0640c081b8d 100644 (file)
@@ -104,5 +104,5 @@ void __init rm9k_cpu_irq_init(void)
 
        rm9000_perfcount_irq = base + 1;
        set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq,
-                                handle_level_irq);
+                                handle_percpu_irq);
 }
index 7b66e03b58994e1e7f3daf6f88ead0628a1a4e12..0ee2567b780d4c4d6496eab4ff043a19bc1f3397 100644 (file)
@@ -116,5 +116,5 @@ void __init mips_cpu_irq_init(void)
 
        for (i = irq_base + 2; i < irq_base + 8; i++)
                set_irq_chip_and_handler(i, &mips_cpu_irq_controller,
-                                        handle_level_irq);
+                                        handle_percpu_irq);
 }
index efd2d1314123b54c371774af644181770f719fea..6e6e947cce1efe6fac56d54f1a795a6ac9ad7b03 100644 (file)
@@ -60,6 +60,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                      cpu_has_dsp ? " dsp" : "",
                      cpu_has_mipsmt ? " mt" : ""
                );
+       seq_printf(m, "shadow register sets\t: %d\n",
+                      cpu_data[n].srsets);
 
        sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
                cpu_has_vce ? "%u" : "not available");
index 118be24224f2a849a0fa16662daa674c66103b22..01993ec3368b5344caabcca54f8b1bc75e7641bc 100644 (file)
@@ -293,7 +293,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_ni_syscall                  /* 6170, was get_kernel_syms */
        PTR     sys_ni_syscall                  /* was query_module */
        PTR     sys_quotactl
-       PTR     sys_nfsservctl
+       PTR     compat_sys_nfsservctl
        PTR     sys_ni_syscall                  /* res. for getpmsg */
        PTR     sys_ni_syscall                  /* 6175  for putpmsg */
        PTR     sys_ni_syscall                  /* res. for afs_syscall */
index fa500787152d2cfbc40ffc38075f7ee7545ea103..23e73d0650a3bfd599a3c2dbab43dac23efa8004 100644 (file)
@@ -1100,59 +1100,6 @@ void *set_except_vector(int n, void *addr)
        return (void *)old_handler;
 }
 
-#ifdef CONFIG_CPU_MIPSR2_SRS
-/*
- * MIPSR2 shadow register set allocation
- * FIXME: SMP...
- */
-
-static struct shadow_registers {
-       /*
-        * Number of shadow register sets supported
-        */
-       unsigned long sr_supported;
-       /*
-        * Bitmap of allocated shadow registers
-        */
-       unsigned long sr_allocated;
-} shadow_registers;
-
-static void mips_srs_init(void)
-{
-       shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
-       printk(KERN_INFO "%ld MIPSR2 register sets available\n",
-              shadow_registers.sr_supported);
-       shadow_registers.sr_allocated = 1;      /* Set 0 used by kernel */
-}
-
-int mips_srs_max(void)
-{
-       return shadow_registers.sr_supported;
-}
-
-int mips_srs_alloc(void)
-{
-       struct shadow_registers *sr = &shadow_registers;
-       int set;
-
-again:
-       set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
-       if (set >= sr->sr_supported)
-               return -1;
-
-       if (test_and_set_bit(set, &sr->sr_allocated))
-               goto again;
-
-       return set;
-}
-
-void mips_srs_free(int set)
-{
-       struct shadow_registers *sr = &shadow_registers;
-
-       clear_bit(set, &sr->sr_allocated);
-}
-
 static asmlinkage void do_default_vi(void)
 {
        show_regs(get_irq_regs());
@@ -1163,6 +1110,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 {
        unsigned long handler;
        unsigned long old_handler = vi_handlers[n];
+       int srssets = current_cpu_data.srsets;
        u32 *w;
        unsigned char *b;
 
@@ -1178,7 +1126,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 
        b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
 
-       if (srs >= mips_srs_max())
+       if (srs >= srssets)
                panic("Shadow register set %d not supported", srs);
 
        if (cpu_has_veic) {
@@ -1186,7 +1134,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                        board_bind_eic_interrupt(n, srs);
        } else if (cpu_has_vint) {
                /* SRSMap is only defined if shadow sets are implemented */
-               if (mips_srs_max() > 1)
+               if (srssets > 1)
                        change_c0_srsmap(0xf << n*4, srs << n*4);
        }
 
@@ -1253,14 +1201,6 @@ void *set_vi_handler(int n, vi_handler_t addr)
        return set_vi_srs_handler(n, addr, 0);
 }
 
-#else
-
-static inline void mips_srs_init(void)
-{
-}
-
-#endif /* CONFIG_CPU_MIPSR2_SRS */
-
 /*
  * This is used by native signal handling
  */
@@ -1503,8 +1443,6 @@ void __init trap_init(void)
        else
                ebase = CAC_BASE;
 
-       mips_srs_init();
-
        per_cpu_trap_init();
 
        /*
index 436a64ff3989485feebd20b388212b832738f37f..38bd33fa2a23ae123a6bb725a58197115d3cc281 100644 (file)
@@ -1003,6 +1003,7 @@ static void cleanup_tc(struct tc *tc)
        write_tc_c0_tcstatus(tmp);
 
        write_tc_c0_tchalt(TCHALT_H);
+       mips_ihb();
 
        /* bind it to anything other than VPE1 */
 //     write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE
@@ -1235,9 +1236,12 @@ int vpe_free(vpe_handle vpe)
        settc(t->index);
        write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
 
-       /* mark the TC unallocated and halt'ed */
-       write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
+       /* halt the TC */
        write_tc_c0_tchalt(TCHALT_H);
+       mips_ihb();
+
+       /* mark the TC unallocated */
+       write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
 
        v->state = VPE_STATE_UNUSED;
 
@@ -1533,14 +1537,16 @@ static int __init vpe_module_init(void)
                                t->pvpe = get_vpe(0);   /* set the parent vpe */
                        }
 
+                       /* halt the TC */
+                       write_tc_c0_tchalt(TCHALT_H);
+                       mips_ihb();
+
                        tmp = read_tc_c0_tcstatus();
 
                        /* mark not activated and not dynamically allocatable */
                        tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
                        tmp |= TCSTATUS_IXMT;   /* interrupt exempt */
                        write_tc_c0_tcstatus(tmp);
-
-                       write_tc_c0_tchalt(TCHALT_H);
                }
        }
 
index ba9692be3564c32b48eaacb2199c54376d0b0a95..cfeab669782f04ec30e472f2b4b39476980bedbf 100644 (file)
  * Lasat boards.
  */
 #include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
+#include <linux/irq.h>
 
 #include <asm/bootinfo.h>
 #include <asm/irq_cpu.h>
 #include <asm/lasat/lasatint.h>
-#include <asm/time.h>
-#include <asm/gdb-stub.h>
+
+#include <irq.h>
 
 static volatile int *lasat_int_status;
 static volatile int *lasat_int_mask;
@@ -97,12 +94,18 @@ asmlinkage void plat_irq_dispatch(void)
 
        /* if int_status == 0, then the interrupt has already been cleared */
        if (int_status) {
-               irq = LASATINT_BASE + ls1bit32(int_status);
+               irq = LASAT_IRQ_BASE + ls1bit32(int_status);
 
                do_IRQ(irq);
        }
 }
 
+static struct irqaction cascade = {
+       .handler        = no_action,
+       .mask           = CPU_MASK_NONE,
+       .name           = "cascade",
+};
+
 void __init arch_init_irq(void)
 {
        int i;
@@ -127,6 +130,9 @@ void __init arch_init_irq(void)
        }
 
        mips_cpu_irq_init();
-       for (i = LASATINT_BASE; i <= LASATINT_END; i++)
+
+       for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++)
                set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
+
+       setup_irq(LASAT_CASCADE_IRQ, &cascade);
 }
index 6806d58211b260931e5dcacfc527b966e0e13c6e..9355f1c9325f1b7056c1be4f1af2afdf379ea891 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
+#include <linux/hardirq.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/kernel.h>
@@ -507,7 +508,11 @@ static inline void local_r4k_flush_data_cache_page(void * addr)
 
 static void r4k_flush_data_cache_page(unsigned long addr)
 {
-       r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
+       if (in_atomic())
+               local_r4k_flush_data_cache_page((void *)addr);
+       else
+               r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr,
+                               1, 1);
 }
 
 struct flush_icache_range_args {
index e7f539e3284b91c232b44bbbaa1142d334260b1d..1bd1f18ac23c5d0fe0120555051b98bb5cb7169c 100644 (file)
@@ -154,7 +154,7 @@ static void check_bus_watcher(void)
        if (status & ~(1UL << 31)) {
                l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
-               l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
+               l2_tag = in64(IOADDR(A_L2_ECC_TAG));
 #endif
                memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
                printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
@@ -183,9 +183,9 @@ asmlinkage void sb1_cache_error(void)
 #ifdef CONFIG_SIBYTE_BW_TRACE
        /* Freeze the trace buffer now */
 #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
-       csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+       csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
 #else
-       csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+       csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
 #endif
        printk("Trace buffer frozen\n");
 #endif
index 110ee7656b41a9b1ee27057604c923213700e06d..ec3b9e9f30f4fd2ae5ad9edc9951564889eae58a 100644 (file)
@@ -426,7 +426,7 @@ void __init mem_init(void)
 
 #ifdef CONFIG_HIGHMEM
        for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-               struct page *page = mem_map + tmp;
+               struct page *page = pfn_to_page(tmp);
 
                if (!page_is_ram(tmp)) {
                        SetPageReserved(page);
index a45bedd17233ce36b5959c3e533ddd24f41b4dc5..5c8a79bb26613a23cdbffd6319d6d90d3dee59dc 100644 (file)
@@ -113,6 +113,16 @@ static char irq_tab_pcit[13][5] __initdata = {
        {     0,  INTA,  INTB,  INTC,  INTD },  /* Slot 5 */
 };
 
+static char irq_tab_pcit_cplus[13][5] __initdata = {
+       /*       INTA  INTB  INTC  INTD */
+       {     0,     0,     0,     0,     0 },  /* HOST bridge */
+       {     0,  INTB,  INTC,  INTD,  INTA },  /* PCI Slot 9 */
+       {     0,     0,     0,     0,     0 },  /* PCI-EISA */
+       {     0,     0,     0,     0,     0 },  /* Unused */
+       {     0,  INTA,  INTB,  INTC,  INTD },  /* PCI-PCI bridge */
+       {     0,  INTB,  INTC,  INTD,  INTA },  /* fixup */
+};
+
 static inline int is_rm300_revd(void)
 {
        unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
@@ -123,8 +133,19 @@ static inline int is_rm300_revd(void)
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        switch (sni_brd_type) {
-       case SNI_BRD_PCI_TOWER:
        case SNI_BRD_PCI_TOWER_CPLUS:
+               if (slot == 4) {
+                       /*
+                        * SNI messed up interrupt wiring for onboard
+                        * PCI bus 1; we need to fix this up here
+                        */
+                       while (dev && dev->bus->number != 1)
+                               dev = dev->bus->self;
+                       if (dev && dev->devfn >= PCI_DEVFN(4, 0))
+                               slot = 5;
+               }
+               return irq_tab_pcit_cplus[slot][pin];
+       case SNI_BRD_PCI_TOWER:
                return irq_tab_pcit[slot][pin];
 
        case SNI_BRD_PCI_MTOWER:
index 174f314933b51931dc7c30776bb84b6d013221d7..e70ae3236e0b4d045d974c0ee9c291c3e6185dc7 100644 (file)
@@ -5,12 +5,14 @@
  *
  * Copyright (C) 2000, 2001, 04 Keith M Wesolowski
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/types.h>
+
 #include <asm/bootinfo.h>
-#include <asm/lasat/lasatint.h>
+
+#include <irq.h>
 
 extern struct pci_ops nile4_pci_ops;
 extern struct pci_ops gt64xxx_pci0_ops;
@@ -55,15 +57,15 @@ static int __init lasat_pci_setup(void)
 
 arch_initcall(lasat_pci_setup);
 
-#define LASATINT_ETH1   (LASATINT_BASE + 0)
-#define LASATINT_ETH0   (LASATINT_BASE + 1)
-#define LASATINT_HDC    (LASATINT_BASE + 2)
-#define LASATINT_COMP   (LASATINT_BASE + 3)
-#define LASATINT_HDLC   (LASATINT_BASE + 4)
-#define LASATINT_PCIA   (LASATINT_BASE + 5)
-#define LASATINT_PCIB   (LASATINT_BASE + 6)
-#define LASATINT_PCIC   (LASATINT_BASE + 7)
-#define LASATINT_PCID   (LASATINT_BASE + 8)
+#define LASAT_IRQ_ETH1   (LASAT_IRQ_BASE + 0)
+#define LASAT_IRQ_ETH0   (LASAT_IRQ_BASE + 1)
+#define LASAT_IRQ_HDC    (LASAT_IRQ_BASE + 2)
+#define LASAT_IRQ_COMP   (LASAT_IRQ_BASE + 3)
+#define LASAT_IRQ_HDLC   (LASAT_IRQ_BASE + 4)
+#define LASAT_IRQ_PCIA   (LASAT_IRQ_BASE + 5)
+#define LASAT_IRQ_PCIB   (LASAT_IRQ_BASE + 6)
+#define LASAT_IRQ_PCIC   (LASAT_IRQ_BASE + 7)
+#define LASAT_IRQ_PCID   (LASAT_IRQ_BASE + 8)
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
@@ -71,13 +73,13 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        case 1:
        case 2:
        case 3:
-               return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
+               return LASAT_IRQ_PCIA + (((slot-1) + (pin-1)) % 4);
        case 4:
-               return LASATINT_ETH1;   /* Ethernet 1 (LAN 2) */
+               return LASAT_IRQ_ETH1;   /* Ethernet 1 (LAN 2) */
        case 5:
-               return LASATINT_ETH0;   /* Ethernet 0 (LAN 1) */
+               return LASAT_IRQ_ETH0;   /* Ethernet 0 (LAN 1) */
        case 6:
-               return LASATINT_HDC;    /* IDE controller */
+               return LASAT_IRQ_HDC;    /* IDE controller */
        default:
                return 0xff;            /* Illegal */
        }
index 240df9e338132323305cb613b1e001f335381141..33c4f683d067063488115e720b3c0b83861e73e9 100644 (file)
@@ -154,6 +154,7 @@ static int __init vr41xx_pciu_init(void)
                pciu_write(PCICLKSELREG, QUARTER_VTCLOCK);
        else {
                printk(KERN_ERR "PCI Clock is over 33MHz.\n");
+               iounmap(pciu_base);
                return -EINVAL;
        }
 
index cec24c117f6e21448d42a4867f63699c57459e6a..2ba4ef34b4a76cb5bbfa5e58f93d3750833adbff 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-y          = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
 
-obj-$(CONFIG_SMP) += q-smp.o
+obj-$(CONFIG_EARLY_PRINTK)     += q-console.o
+obj-$(CONFIG_SMP)              += q-smp.o
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/qemu/q-console.c b/arch/mips/qemu/q-console.c
new file mode 100644 (file)
index 0000000..81101ae
--- /dev/null
@@ -0,0 +1,26 @@
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+
+#define PORT(offset) (0x3f8 + (offset))
+
+static inline unsigned int serial_in(int offset)
+{
+       return inb(PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+       outb(value, PORT(offset));
+}
+
+int prom_putchar(char c)
+{
+       while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+               ;
+
+       serial_out(UART_TX, c);
+
+       return 1;
+}
index c2239b417587f81c9f8b0f6ccd392d8eebfd98e3..3ed43f416cd15e0513fdb6931db9c096fd732477 100644 (file)
@@ -2,6 +2,9 @@
 #include <linux/string.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
+#include <asm/io.h>
+
+#define QEMU_PORT_BASE 0xb4000000
 
 void __init prom_init(void)
 {
@@ -15,4 +18,7 @@ void __init prom_init(void)
        } else {
                add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
        }
+
+
+       set_io_port_base(QEMU_PORT_BASE);
 }
index 23d34c1917c00fa07208f18aea99d0a482ca36b7..969cedc8d8b91d0e19e157686e3c62e6c2aa3d67 100644 (file)
@@ -6,8 +6,6 @@
 
 extern void qemu_reboot_setup(void);
 
-#define QEMU_PORT_BASE 0xb4000000
-
 const char *get_system_type(void)
 {
        return "Qemu";
@@ -20,6 +18,5 @@ void __init plat_time_init(void)
 
 void __init plat_mem_setup(void)
 {
-       set_io_port_base(QEMU_PORT_BASE);
        qemu_reboot_setup();
 }
index e28d626255a3bebd0d6a620eb413c1d185835c1d..db372a0f106d1e8631aff8c001ba2891448aebb7 100644 (file)
@@ -370,11 +370,11 @@ void __init arch_init_irq(void)
 #endif
                /* Setup uart 1 settings, mapper */
                /* QQQ FIXME */
-               __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
+               __raw_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
 
                __raw_writeq(IMR_IP6_VAL,
-                            IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
-                            (kgdb_irq<<3));
+                            IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+                            (kgdb_irq << 3)));
                bcm1480_unmask_irq(0, kgdb_irq);
 
 #ifdef CONFIG_GDB_CONSOLE
@@ -412,18 +412,6 @@ static void bcm1480_kgdb_interrupt(void)
 
 extern void bcm1480_mailbox_interrupt(void);
 
-static inline void dispatch_ip4(void)
-{
-       int cpu = smp_processor_id();
-       int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
-       /* Reset the timer */
-       __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-                   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
-       do_IRQ(irq);
-}
-
 static inline void dispatch_ip2(void)
 {
        unsigned long long mask_h, mask_l;
@@ -451,6 +439,7 @@ static inline void dispatch_ip2(void)
 
 asmlinkage void plat_irq_dispatch(void)
 {
+       unsigned int cpu = smp_processor_id();
        unsigned int pending;
 
 #ifdef CONFIG_SIBYTE_BCM1480_PROF
@@ -467,7 +456,7 @@ asmlinkage void plat_irq_dispatch(void)
 #endif
 
        if (pending & CAUSEF_IP4)
-               dispatch_ip4();
+               do_IRQ(K_BCM1480_INT_TIMER_0 + cpu);
 #ifdef CONFIG_SMP
        else if (pending & CAUSEF_IP3)
                bcm1480_mailbox_interrupt();
index 4df070f2ff5dd488736cd49af07674e6f3844f1d..834650f371e08ebb5917cd8b7ca9a1659eaaf54f 100644 (file)
@@ -244,7 +244,7 @@ static void pcimt_hwint1(void)
        if (pend & IT_EISA) {
                int irq;
                /*
-                * Note: ASIC PCI's builtin interrupt achknowledge feature is
+                * Note: ASIC PCI's builtin interrupt acknowledge feature is
                 * broken.  Using it may result in loss of some or all i8259
                 * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
                 */
index 1899601e5862210e5dd83212dc67587ea75d18d9..3f23d9fda662621e2879ff37a2d1ecbef24cf1a5 100644 (file)
@@ -525,6 +525,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
                intassign1 |= (uint16_t)assign << 9;
                break;
        default:
+               spin_unlock_irq(&desc->lock);
                return -EINVAL;
        }
 
@@ -592,6 +593,7 @@ static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
                intassign3 |= (uint16_t)assign << 12;
                break;
        default:
+               spin_unlock_irq(&desc->lock);
                return -EINVAL;
        }
 
index 4e165342210aa84b508a91e11ef6a8c44148b980..bd87626c1f6041664ed777fcd4349116bb32ea32 100644 (file)
@@ -107,6 +107,9 @@ endif
 # No AltiVec instruction when building kernel
 KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
 
+# No SPE instruction when building kernel
+KBUILD_CFLAGS += $(call cc-option,-mno-spe)
+
 # Enable unit-at-a-time mode when possible. It shrinks the
 # kernel considerably.
 KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
index fa681f5343fec196dd5a51cd029bd34097427aef..754fa3960f8331813aede79d855bf57bbf49730c 100644 (file)
                                device_type = "network";
                                compatible = "ibm,emac-405gp", "ibm,emac";
                                interrupt-parent = <&UIC0>;
-                               interrupts = <9 4 f 4>;
+                               interrupts = <
+                                       f 4 /* Ethernet */
+                                       9 4 /* Ethernet Wake Up */>;
                                local-mac-address = [000000000000]; /* Filled in by zImage */
                                reg = <ef600800 70>;
                                mal-device = <&MAL>;
index 39b27e5ef6c19a840d4b2a9fc0f87d621e72d789..31147a0377283e179b473aa4fa4c9f720ce8ed48 100755 (executable)
 #              (default ./arch/powerpc/boot)
 # -W dir       specify working directory for temporary files (default .)
 
+# Stop execution if any command fails
+set -e
+
+# Allow for verbose output
+if [ "$V" = 1 ]; then
+    set -x
+fi
+
 # defaults
 kernel=
 ofile=zImage
@@ -111,7 +119,7 @@ if [ -n "$dts" ]; then
     if [ -z "$dtb" ]; then
        dtb="$platform.dtb"
     fi
-    dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
+    dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
 fi
 
 if [ -z "$kernel" ]; then
@@ -149,7 +157,6 @@ cuboot*)
 ps3)
     platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
     lds=$object/zImage.ps3.lds
-    binary=y
     gzip=
     ext=bin
     objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
@@ -233,7 +240,7 @@ entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
 
 if [ -n "$binary" ]; then
     mv "$ofile" "$ofile".elf
-    ${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin
+    ${CROSS}objcopy -O binary "$ofile".elf "$ofile"
 fi
 
 # post-processing needed for some platforms
@@ -246,9 +253,9 @@ coff)
     $object/hack-coff "$ofile"
     ;;
 cuboot*)
-    gzip -f -9 "$ofile".bin
+    gzip -f -9 "$ofile"
     mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
-            $uboot_version -d "$ofile".bin.gz "$ofile"
+            $uboot_version -d "$ofile".gz "$ofile"
     ;;
 treeboot*)
     mv "$ofile" "$ofile.elf"
@@ -269,11 +276,11 @@ ps3)
     # then copied to offset 0x100.  At runtime the bootwrapper program
     # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
 
-    system_reset_overlay=0x`${CROSS}nm "$ofile".elf \
+    system_reset_overlay=0x`${CROSS}nm "$ofile" \
         | grep ' __system_reset_overlay$'       \
         | cut -d' ' -f1`
     system_reset_overlay=`printf "%d" $system_reset_overlay`
-    system_reset_kernel=0x`${CROSS}nm "$ofile".elf \
+    system_reset_kernel=0x`${CROSS}nm "$ofile" \
         | grep ' __system_reset_kernel$'       \
         | cut -d' ' -f1`
     system_reset_kernel=`printf "%d" $system_reset_kernel`
@@ -282,23 +289,15 @@ ps3)
 
     rm -f "$object/otheros.bld"
 
-    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
-        skip=$overlay_dest seek=$system_reset_kernel      \
-        count=$overlay_size bs=1 2>&1)
+    ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
 
-    if [ $? -ne "0" ]; then
-       echo $msg
-       exit 1
-    fi
-
-    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
-        skip=$system_reset_overlay seek=$overlay_dest     \
-        count=$overlay_size bs=1 2>&1)
+    dd if="$ofile.bin" of="$ofile.bin" conv=notrunc   \
+        skip=$overlay_dest seek=$system_reset_kernel  \
+        count=$overlay_size bs=1
 
-    if [ $? -ne "0" ]; then
-       echo $msg
-       exit 2
-    fi
+    dd if="$ofile.bin" of="$ofile.bin" conv=notrunc   \
+        skip=$system_reset_overlay seek=$overlay_dest \
+        count=$overlay_size bs=1
 
     gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
     ;;
index 1ccf3ed7693e876d8be9332693166030fbec1905..78c968aade4ed2617866b0efecfdad548557156d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:40:47 2007
+# Linux kernel version: 2.6.24-rc2
+# Tue Nov  6 23:23:50 2007
 #
 CONFIG_PPC64=y
 
@@ -10,6 +10,7 @@ CONFIG_PPC64=y
 #
 CONFIG_POWER4_ONLY=y
 CONFIG_POWER4=y
+# CONFIG_TUNE_CELL is not set
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
@@ -18,8 +19,13 @@ CONFIG_PPC_MM_SLICES=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -65,7 +71,10 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CPUSETS is not set
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -86,7 +95,6 @@ CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -107,14 +115,15 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
@@ -125,7 +134,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_EMBEDDED6xx is not set
 # CONFIG_PPC_82xx is not set
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
@@ -141,6 +149,7 @@ CONFIG_PPC_PASEMI=y
 # PA Semi PWRficient options
 #
 CONFIG_PPC_PASEMI_IOMMU=y
+# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
 CONFIG_PPC_PASEMI_MDIO=y
 CONFIG_ELECTRA_IDE=y
 # CONFIG_PPC_CELLEB is not set
@@ -156,29 +165,52 @@ CONFIG_MPIC=y
 # CONFIG_U3_DART is not set
 # CONFIG_PPC_RTAS is not set
 # CONFIG_MMIO_NVRAM is not set
+CONFIG_MPIC_BROKEN_REGREAD=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# CPU Frequency drivers
+#
+CONFIG_PPC_PASEMI_CPUFREQ=y
 # CONFIG_CPM2 is not set
 # CONFIG_FSL_ULI1575 is not set
 
 #
 # Kernel options
 #
-CONFIG_HZ_100=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_BKL is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_FORCE_MAX_ZONEORDER=9
 CONFIG_IOMMU_VMERGE=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 # CONFIG_KEXEC is not set
@@ -196,12 +228,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-# CONFIG_PPC_HAS_HASH_64K is not set
-# CONFIG_PPC_64K_PAGES is not set
+CONFIG_PPC_HAS_HASH_64K=y
+CONFIG_PPC_64K_PAGES=y
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -222,11 +255,8 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 CONFIG_PCCARD=y
 CONFIG_PCMCIA_DEBUG=y
 CONFIG_PCMCIA=y
@@ -240,6 +270,7 @@ CONFIG_CARDBUS=y
 # CONFIG_YENTA is not set
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
+# CONFIG_ELECTRA_CF is not set
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_KERNEL_START=0xc000000000000000
 
@@ -255,7 +286,7 @@ CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_XFRM_USER=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=y
@@ -281,6 +312,7 @@ CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -306,10 +338,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -338,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -361,6 +390,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -385,6 +415,7 @@ CONFIG_MTD_CFI_I2=y
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -402,7 +433,15 @@ CONFIG_MTD_PHRAM=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -455,10 +494,42 @@ CONFIG_IDE_PROC_FS=y
 # IDE chipset support/bugfixes
 #
 # CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 # CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -498,10 +569,11 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-CONFIG_BLK_DEV_3W_XXXX_RAID=y
-CONFIG_SCSI_3W_9XXX=y
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -574,9 +646,10 @@ CONFIG_ATA_GENERIC=y
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
 # CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PCMCIA is not set
+CONFIG_PATA_PCMCIA=y
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RZ1000 is not set
@@ -589,41 +662,13 @@ CONFIG_ATA_GENERIC=y
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
 # CONFIG_FIREWIRE is not set
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-
-#
-# Controllers
-#
-CONFIG_IEEE1394_PCILYNX=y
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocols
-#
-# CONFIG_IEEE1394_VIDEO1394 is not set
-CONFIG_IEEE1394_SBP2=y
-# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-# CONFIG_IEEE1394_DV1394 is not set
-CONFIG_IEEE1394_RAWIO=y
+# CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
@@ -633,6 +678,8 @@ CONFIG_DUMMY=y
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 CONFIG_PHYLIB=y
 
@@ -649,6 +696,7 @@ CONFIG_MARVELL_PHY=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
@@ -657,13 +705,16 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
@@ -682,6 +733,7 @@ CONFIG_NETDEV_1000=y
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -689,6 +741,7 @@ CONFIG_E1000_NAPI=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
@@ -697,12 +750,15 @@ CONFIG_TIGON3=y
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 CONFIG_PASEMI_MAC=y
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -749,7 +805,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_INPUT_JOYDEV=y
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -810,15 +865,12 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=4
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_PASEMI=y
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
@@ -896,8 +948,6 @@ CONFIG_SENSORS_EEPROM=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 CONFIG_HWMON_VID=y
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -905,12 +955,12 @@ CONFIG_HWMON_VID=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 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_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -946,6 +996,13 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -963,14 +1020,14 @@ CONFIG_DAB=y
 #
 # Graphics support
 #
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_AGP is not set
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+CONFIG_DRM_RADEON=y
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
 CONFIG_VGASTATE=y
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
@@ -979,6 +1036,7 @@ CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -1026,6 +1084,15 @@ CONFIG_FB_RADEON_BACKLIGHT=y
 # CONFIG_FB_PM3 is not set
 # CONFIG_FB_IBM_GXT4500 is not set
 # CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -1178,6 +1245,7 @@ CONFIG_SND_USB_USX2Y=y
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
@@ -1328,6 +1396,7 @@ CONFIG_RTC_INTF_DEV=y
 # I2C RTC drivers
 #
 CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
 # CONFIG_RTC_DRV_MAX6900 is not set
 # CONFIG_RTC_DRV_RS5C372 is not set
@@ -1356,19 +1425,6 @@ CONFIG_RTC_DRV_DS1307=y
 # on-CPU RTC drivers
 #
 
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
 #
 # Userspace I/O
 #
@@ -1388,7 +1444,6 @@ CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -1436,7 +1491,6 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=y
 
 #
@@ -1449,30 +1503,43 @@ CONFIG_CONFIGFS_FS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
 # CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
@@ -1501,10 +1568,6 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=y
@@ -1545,10 +1608,6 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 # CONFIG_UCC_SLOW is not set
 
@@ -1561,23 +1620,24 @@ CONFIG_CRC_CCITT=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 # CONFIG_KPROBES is not set
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
@@ -1586,7 +1646,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
-CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
@@ -1601,9 +1661,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1620,6 +1683,7 @@ CONFIG_XMON_DISASSEMBLY=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -1628,34 +1692,38 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
 # CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_ECB is not set
 CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_PCBC is not set
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_BLOWFISH=y
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_HW is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
index 05582af50c5beb8c45494b18c916b5848ac88678..3e90c835fe12ad21a3938720d18fff5509e6d007 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:47:09 2007
+# Linux kernel version: 2.6.24-rc2
+# Tue Nov  6 23:43:56 2007
 #
 CONFIG_PPC64=y
 
@@ -11,6 +11,7 @@ CONFIG_PPC64=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
 CONFIG_POWER4=y
+# CONFIG_TUNE_CELL is not set
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
@@ -19,8 +20,13 @@ CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -72,8 +78,15 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_CPUACCT is not set
 CONFIG_CPUSETS=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_PROC_PID_CPUSET=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -93,7 +106,6 @@ CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -114,6 +126,7 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_BLK_DEV_BSG=y
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
@@ -132,7 +145,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_EMBEDDED6xx is not set
 # CONFIG_PPC_82xx is not set
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
@@ -155,7 +167,15 @@ CONFIG_VIOPATH=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PMAC64=y
 CONFIG_PPC_MAPLE=y
-# CONFIG_PPC_PASEMI is not set
+CONFIG_PPC_PASEMI=y
+
+#
+# PA Semi PWRficient options
+#
+CONFIG_PPC_PASEMI_IOMMU=y
+# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
+CONFIG_PPC_PASEMI_MDIO=y
+CONFIG_ELECTRA_IDE=y
 CONFIG_PPC_CELLEB=y
 # CONFIG_PPC_PS3 is not set
 CONFIG_PPC_CELL=y
@@ -188,6 +208,7 @@ CONFIG_RTAS_FLASH=m
 CONFIG_PPC_PMI=m
 CONFIG_MMIO_NVRAM=y
 CONFIG_MPIC_U3_HT_IRQS=y
+CONFIG_MPIC_BROKEN_REGREAD=y
 CONFIG_IBMVIO=y
 # CONFIG_IBMEBUS is not set
 # CONFIG_PPC_MPC106 is not set
@@ -201,6 +222,8 @@ CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -211,6 +234,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CPU Frequency drivers
 #
 CONFIG_CPU_FREQ_PMAC64=y
+CONFIG_PPC_PASEMI_CPUFREQ=y
 # CONFIG_CPM2 is not set
 CONFIG_AXON_RAM=m
 # CONFIG_FSL_ULI1575 is not set
@@ -254,6 +278,8 @@ CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
@@ -268,6 +294,7 @@ CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 CONFIG_SUSPEND_SMP_POSSIBLE=y
+CONFIG_HIBERNATION_SMP_POSSIBLE=y
 CONFIG_SECCOMP=y
 # CONFIG_WANT_DEVICE_TREE is not set
 CONFIG_ISA_DMA_API=y
@@ -284,12 +311,22 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# PC-card bridges
 #
-# CONFIG_PCCARD is not set
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_ELECTRA_CF=y
 CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
@@ -319,7 +356,10 @@ CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
 CONFIG_NET_IPIP=y
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -333,6 +373,7 @@ CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -404,6 +445,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
 CONFIG_NETFILTER_XT_MATCH_U32=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
@@ -465,10 +507,6 @@ CONFIG_LLC=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
 
@@ -498,6 +536,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -539,6 +578,8 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -550,6 +591,11 @@ CONFIG_IDE_PROC_FS=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_IDEPCI_PCIBUS_ORDER=y
@@ -557,8 +603,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_ONLYDISK is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 CONFIG_BLK_DEV_AMD74XX=y
@@ -590,7 +634,7 @@ CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -631,6 +675,7 @@ CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -671,19 +716,20 @@ CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 CONFIG_ATA=y
 CONFIG_ATA_NONSTANDARD=y
 # CONFIG_SATA_AHCI is not set
 CONFIG_SATA_SVW=y
 # CONFIG_ATA_PIIX is not set
-# CONFIG_SATA_MV is not set
+CONFIG_SATA_MV=y
 # CONFIG_SATA_NV is not set
 # CONFIG_PDC_ADMA is not set
 # CONFIG_SATA_QSTOR is not set
 # CONFIG_SATA_PROMISE is not set
 # CONFIG_SATA_SX4 is not set
 # CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
+CONFIG_SATA_SIL24=y
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
@@ -713,8 +759,10 @@ CONFIG_SATA_SVW=y
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
 # CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+CONFIG_PATA_PCMCIA=y
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RZ1000 is not set
@@ -725,6 +773,7 @@ CONFIG_SATA_SVW=y
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
 CONFIG_PATA_WINBOND=y
+CONFIG_PATA_PLATFORM=y
 CONFIG_PATA_SCC=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
@@ -745,15 +794,10 @@ CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_MULTIPATH_EMC=m
 # CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -800,13 +844,15 @@ CONFIG_BONDING=m
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
+CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
+CONFIG_MARVELL_PHY=y
 # CONFIG_DAVICOM_PHY is not set
 # CONFIG_QSEMI_PHY is not set
 # CONFIG_LXT_PHY is not set
@@ -818,6 +864,9 @@ CONFIG_BROADCOM_PHY=m
 CONFIG_FIXED_PHY=m
 CONFIG_FIXED_MII_10_FDX=y
 CONFIG_FIXED_MII_100_FDX=y
+# CONFIG_FIXED_MII_1000_FDX is not set
+CONFIG_FIXED_MII_AMNT=1
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
@@ -829,6 +878,11 @@ CONFIG_VORTEX=y
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBMVETH=m
+# CONFIG_IBM_NEW_EMAC is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
 # CONFIG_PCNET32_NAPI is not set
@@ -836,7 +890,6 @@ CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
 # CONFIG_FEALNX is not set
@@ -856,6 +909,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -863,6 +917,7 @@ CONFIG_E1000=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
@@ -872,13 +927,16 @@ CONFIG_SPIDER_NET=m
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 CONFIG_IXGB=m
 # CONFIG_IXGB_NAPI is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
-CONFIG_PASEMI_MAC=m
+# CONFIG_NIU is not set
+CONFIG_PASEMI_MAC=y
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 CONFIG_TR=y
 CONFIG_IBMOL=y
 # CONFIG_3C359 is not set
@@ -899,6 +957,7 @@ CONFIG_IBMOL=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_NET_PCMCIA is not set
 # CONFIG_WAN is not set
 CONFIG_ISERIES_VETH=m
 # CONFIG_FDDI is not set
@@ -918,6 +977,7 @@ CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
@@ -939,7 +999,6 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
 
@@ -1002,6 +1061,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -1029,14 +1089,18 @@ CONFIG_HVC_RTAS=y
 CONFIG_HVC_BEAT=y
 CONFIG_HVCS=m
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 # CONFIG_HANGCHECK_TIMER is not set
@@ -1068,6 +1132,7 @@ CONFIG_I2C_POWERMAC=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PASEMI=y
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -1106,6 +1171,13 @@ CONFIG_I2C_POWERMAC=y
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -1122,18 +1194,8 @@ CONFIG_I2C_POWERMAC=y
 #
 # Graphics support
 #
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
@@ -1142,6 +1204,7 @@ CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -1192,6 +1255,19 @@ CONFIG_FB_RADEON_BACKLIGHT=y
 # CONFIG_FB_PM3 is not set
 CONFIG_FB_IBM_GXT4500=y
 # CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
 
 #
 # Console display driver support
@@ -1332,6 +1408,12 @@ CONFIG_SND_AOA_SOUNDBUS_I2S=m
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
 #
 # System on Chip audio support
 #
@@ -1348,6 +1430,7 @@ CONFIG_SND_AOA_SOUNDBUS_I2S=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
@@ -1489,19 +1572,53 @@ CONFIG_EDAC=y
 #
 # CONFIG_EDAC_DEBUG is not set
 CONFIG_EDAC_MM_EDAC=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_EDAC_PASEMI=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
 
 #
-# DMA Engine support
+# SPI RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
 
 #
-# DMA Clients
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# DMA Devices
+# on-CPU RTC drivers
 #
 
 #
@@ -1585,7 +1702,6 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1604,10 +1720,7 @@ CONFIG_CRAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
@@ -1619,6 +1732,7 @@ CONFIG_NFSD_V3=y
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
@@ -1626,6 +1740,7 @@ CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_XPRT_RDMA=m
 # CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
@@ -1662,10 +1777,6 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=y
@@ -1706,10 +1817,6 @@ CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 # CONFIG_UCC_SLOW is not set
 
@@ -1733,18 +1840,17 @@ CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 # CONFIG_KPROBES is not set
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
@@ -1768,9 +1874,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1780,6 +1889,7 @@ CONFIG_XMON=y
 # CONFIG_XMON_DEFAULT is not set
 CONFIG_XMON_DISASSEMBLY=y
 CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
 CONFIG_BOOTX_TEXT=y
 # CONFIG_PPC_EARLY_DEBUG is not set
 
@@ -1788,6 +1898,7 @@ CONFIG_BOOTX_TEXT=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
@@ -1812,6 +1923,7 @@ CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -1826,9 +1938,12 @@ CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
index 3ef51fb6f107a57d3ca82f4c18ddfd84f689ce3a..9c74fdf29eeccc8f5c56adb7b1a5c98fc09a21e3 100644 (file)
@@ -186,7 +186,9 @@ int btext_initialize(struct device_node *np)
                pitch = *prop;
        if (pitch == 1)
                pitch = 0x1000;
-       prop = of_get_property(np, "address", NULL);
+       prop = of_get_property(np, "linux,bootx-addr", NULL);
+       if (prop == NULL)
+               prop = of_get_property(np, "address", NULL);
        if (prop)
                address = *prop;
 
index d3fb7d0c6c1c255b3569dc845a671962d0e5393f..9ed351f3c96625dd6e4862cb7c40bc5d1393a8bd 100644 (file)
@@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
        {
                .pvr_mask               = 0xf0000fff,
                .pvr_value              = 0x40000850,
+               .cpu_name               = "440GR Rev. A",
+               .cpu_features           = CPU_FTRS_44X,
+               .cpu_user_features      = COMMON_USER_BOOKE,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .platform               = "ppc440",
+       },
+       { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+               .pvr_mask               = 0xf0000fff,
+               .pvr_value              = 0x40000858,
                .cpu_name               = "440EP Rev. A",
                .cpu_features           = CPU_FTRS_44X,
                .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
@@ -1115,28 +1125,27 @@ static struct cpu_spec __initdata cpu_specs[] = {
        {
                .pvr_mask               = 0xf0000fff,
                .pvr_value              = 0x400008d3,
-               .cpu_name               = "440EP Rev. B",
+               .cpu_name               = "440GR Rev. B",
                .cpu_features           = CPU_FTRS_44X,
                .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
-               .cpu_setup              = __setup_cpu_440ep,
                .platform               = "ppc440",
        },
-       { /* 440EPX */
-               .pvr_mask               = 0xf0000ffb,
-               .pvr_value              = 0x200008D0,
-               .cpu_name               = "440EPX",
+       { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+               .pvr_mask               = 0xf0000fff,
+               .pvr_value              = 0x400008db,
+               .cpu_name               = "440EP Rev. B",
                .cpu_features           = CPU_FTRS_44X,
                .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
-               .cpu_setup              = __setup_cpu_440epx,
+               .cpu_setup              = __setup_cpu_440ep,
                .platform               = "ppc440",
        },
        { /* 440GRX */
                .pvr_mask               = 0xf0000ffb,
-               .pvr_value              = 0x200008D8,
+               .pvr_value              = 0x200008D0,
                .cpu_name               = "440GRX",
                .cpu_features           = CPU_FTRS_44X,
                .cpu_user_features      = COMMON_USER_BOOKE,
@@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_setup              = __setup_cpu_440grx,
                .platform               = "ppc440",
        },
+       { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
+               .pvr_mask               = 0xf0000ffb,
+               .pvr_value              = 0x200008D8,
+               .cpu_name               = "440EPX",
+               .cpu_features           = CPU_FTRS_44X,
+               .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .cpu_setup              = __setup_cpu_440epx,
+               .platform               = "ppc440",
+       },
        {       /* 440GP Rev. B */
                .pvr_mask               = 0xf0000fff,
                .pvr_value              = 0x40000440,
index 21d889e63e87520d9e49112a99d20fc8d887da90..69a91bd46115e171bb73cf76282db673ce5d054e 100644 (file)
@@ -244,6 +244,16 @@ syscall_exit_cont:
        andis.  r10,r0,DBCR0_IC@h
        bnel-   load_dbcr0
 #endif
+#ifdef CONFIG_44x
+       lis     r4,icache_44x_need_flush@ha
+       lwz     r5,icache_44x_need_flush@l(r4)
+       cmplwi  cr0,r5,0
+       bne-    2f
+1:
+#endif /* CONFIG_44x */
+BEGIN_FTR_SECTION
+       lwarx   r7,0,r1
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
        stwcx.  r0,0,r1                 /* to clear the reservation */
        lwz     r4,_LINK(r1)
        lwz     r5,_CCR(r1)
@@ -258,6 +268,12 @@ syscall_exit_cont:
        mtspr   SPRN_SRR1,r8
        SYNC
        RFI
+#ifdef CONFIG_44x
+2:     li      r7,0
+       iccci   r0,r0
+       stw     r7,icache_44x_need_flush@l(r4)
+       b       1b
+#endif  /* CONFIG_44x */
 
 66:    li      r3,-ENOSYS
        b       ret_from_syscall
@@ -683,6 +699,16 @@ resume_kernel:
 
        /* interrupts are hard-disabled at this point */
 restore:
+#ifdef CONFIG_44x
+       lis     r4,icache_44x_need_flush@ha
+       lwz     r5,icache_44x_need_flush@l(r4)
+       cmplwi  cr0,r5,0
+       beq+    1f
+       li      r6,0
+       iccci   r0,r0
+       stw     r6,icache_44x_need_flush@l(r4)
+1:
+#endif  /* CONFIG_44x */
        lwz     r0,GPR0(r1)
        lwz     r2,GPR2(r1)
        REST_4GPRS(3, r1)
@@ -694,6 +720,9 @@ restore:
        mtctr   r11
 
        PPC405_ERR77(0,r1)
+BEGIN_FTR_SECTION
+       lwarx   r11,0,r1
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
        stwcx.  r0,0,r1                 /* to clear the reservation */
 
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
index 97c5857faf00d830d3022fdc4bd99caeefaed974..c34986835a4e6f80593ed4588b0bf681f5628c9c 100644 (file)
@@ -904,7 +904,7 @@ handle_page_fault:
  */
 12:    bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       lwz     r4,_DAR(r1)
+       l     r4,_DAR(r1)
        bl      .low_hash_fault
        b       .ret_from_except
 
index abd2957fe5378ba59c4ccf6c58a9ecdd6f892798..c3cf0e8f3ac173332a01148946ace8c43f45a5a5 100644 (file)
@@ -122,7 +122,7 @@ static ctl_table powersave_nap_sysctl_root[] = {
        {
                .ctl_name       = CTL_KERN,
                .procname       = "kernel",
-               .mode           = 0755,
+               .mode           = 0555,
                .child          = powersave_nap_ctl_table,
        },
        {}
index 8533de50347d5284b23cbe0538673ba74b6b95fe..8b642ab26d3767c23205125b1022dcad45964efd 100644 (file)
@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
  */
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
+       /* We run the search with interrupts disabled because we have to change
+        * the PID and I don't want to preempt when that happens.
+        */
+       mfmsr   r5
+       mfspr   r6,SPRN_PID
+       wrteei  0
+       mtspr   SPRN_PID,r4
        tlbsx.  r3, 0, r3
+       mtspr   SPRN_PID,r6
+       wrtee   r5
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
        tlbwe   r3, r3, TLB_TAG
        isync
 10:
+
 #elif defined(CONFIG_44x)
-       mfspr   r4,SPRN_MMUCR
-       mfspr   r5,SPRN_PID                     /* Get PID */
-       rlwimi  r4,r5,0,24,31                   /* Set TID */
+       mfspr   r5,SPRN_MMUCR
+       rlwimi  r5,r4,0,24,31                   /* Set TID */
 
        /* We have to run the search with interrupts disabled, even critical
         * and debug interrupts (in fact the only critical exceptions we have
         * are debug and machine check).  Otherwise  an interrupt which causes
         * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
-       mfmsr   r5
+       mfmsr   r4
        lis     r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
        addi    r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
-       andc    r6,r5,r6
+       andc    r6,r4,r6
        mtmsr   r6
-       mtspr   SPRN_MMUCR,r4
+       mtspr   SPRN_MMUCR,r5
        tlbsx.  r3, 0, r3
-       mtmsr   r5
+       mtmsr   r4
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64,
@@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        addi    r3,r3,L1_CACHE_BYTES
        bdnz    0b
        sync
+#ifndef CONFIG_44x
+       /* We don't flush the icache on 44x. Those have a virtual icache
+        * and we don't have access to the virtual address here (it's
+        * not the page vaddr but where it's mapped in user space). The
+        * flushing of the icache on these is handled elsewhere, when
+        * a change in the address space occurs, before returning to
+        * user space
+        */
        mtctr   r4
 1:     icbi    0,r6
        addi    r6,r6,L1_CACHE_BYTES
        bdnz    1b
        sync
        isync
+#endif /* CONFIG_44x */
        blr
 
 /*
index b9d88374f14f07abe21e51367110e6c82129ba99..41e13f4cc6e3da1e34ac662d4f558f5fa668fccd 100644 (file)
@@ -350,7 +350,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
        local_irq_save(flags);
 
        account_system_vtime(current);
-       account_process_vtime(current);
+       account_process_tick(current, 0);
        calculate_steal_time();
 
        last = _switch(old_thread, new_thread);
index 9f329a8928eaed27f3192e27c729e24bb73ac888..acc0d247d3c3a83920c92cb11f33639a86e8da1b 100644 (file)
@@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
                prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
                if (prop && (*prop & 0xff000000) == 0x0f000000)
                        identify_cpu(0, *prop);
+#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
+               /*
+                * Since 440GR(x)/440EP(x) processors have the same pvr,
+                * we check the node path and set bit 28 in the cur_cpu_spec
+                * pvr for EP(x) processor version. This bit is always 0 in
+                * the "real" pvr. Then we call identify_cpu again with
+                * the new logical pvr to enable FPU support.
+                */
+               if (strstr(uname, "440EP")) {
+                       identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
+               }
+#endif
        }
 
        check_cpu_feature_properties(node);
index 1db10f70ae69bb0d4da938d068bb81fbd434f1b3..1add6efdb315065e4b424114944911ddb89a3c0e 100644 (file)
@@ -1244,7 +1244,7 @@ static void __init prom_initialize_tce_table(void)
                        local_alloc_bottom = base;
 
                /* It seems OF doesn't null-terminate the path :-( */
-               memset(path, 0, sizeof(path));
+               memset(path, 0, PROM_SCRATCH_SIZE);
                /* Call OF to setup the TCE hardware */
                if (call_prom("package-to-path", 3, 1, node,
                              path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
index ede77dbbd4df7fa3338e343973f93a71accb7de5..3b1529c103ef4a545da877bfe4d2de81cf41abe7 100644 (file)
@@ -291,23 +291,16 @@ static void __init initialize_cache_info(void)
                if ( num_cpus == 1 ) {
                        const u32 *sizep, *lsizep;
                        u32 size, lsize;
-                       const char *dc, *ic;
-
-                       /* Then read cache informations */
-                       if (machine_is(powermac)) {
-                               dc = "d-cache-block-size";
-                               ic = "i-cache-block-size";
-                       } else {
-                               dc = "d-cache-line-size";
-                               ic = "i-cache-line-size";
-                       }
 
                        size = 0;
                        lsize = cur_cpu_spec->dcache_bsize;
                        sizep = of_get_property(np, "d-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = of_get_property(np, dc, NULL);
+                       lsizep = of_get_property(np, "d-cache-block-size", NULL);
+                       /* fallback if block size missing */
+                       if (lsizep == NULL)
+                               lsizep = of_get_property(np, "d-cache-line-size", NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
@@ -324,7 +317,9 @@ static void __init initialize_cache_info(void)
                        sizep = of_get_property(np, "i-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = of_get_property(np, ic, NULL);
+                       lsizep = of_get_property(np, "i-cache-block-size", NULL);
+                       if (lsizep == NULL)
+                               lsizep = of_get_property(np, "i-cache-line-size", NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
index 69e8f86aa4f843a2f248c9e7888a6f5283b64ad8..77fc76607ab2080d41667f3171fcdef9ee44dfd1 100644 (file)
@@ -133,10 +133,12 @@ _GLOBAL(swsusp_arch_suspend)
 /* Resume code */
 _GLOBAL(swsusp_arch_resume)
 
+#ifdef CONFIG_ALTIVEC
        /* Stop pending alitvec streams and memory accesses */
 BEGIN_FTR_SECTION
        DSSALL
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
        sync
 
        /* Disable MSR:DR to make sure we don't take a TLB or
index 9eb3284deac4e5d4e9942b5e643ab59fede4af85..c0d77723ba1141124733e05ab64b93343957a7fe 100644 (file)
@@ -259,7 +259,7 @@ void account_system_vtime(struct task_struct *tsk)
  * user and system time records.
  * Must be called with interrupts disabled.
  */
-void account_process_vtime(struct task_struct *tsk)
+void account_process_tick(struct task_struct *tsk, int user_tick)
 {
        cputime_t utime, utimescaled;
 
@@ -274,18 +274,6 @@ void account_process_vtime(struct task_struct *tsk)
        account_user_time_scaled(tsk, utimescaled);
 }
 
-static void account_process_time(struct pt_regs *regs)
-{
-       int cpu = smp_processor_id();
-
-       account_process_vtime(current);
-       run_local_timers();
-       if (rcu_pending(cpu))
-               rcu_check_callbacks(cpu, user_mode(regs));
-       scheduler_tick();
-       run_posix_cpu_timers(current);
-}
-
 /*
  * Stuff for accounting stolen time.
  */
@@ -375,7 +363,6 @@ static void snapshot_purr(void)
 
 #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
 #define calc_cputime_factors()
-#define account_process_time(regs)     update_process_times(user_mode(regs))
 #define calculate_steal_time()         do { } while (0)
 #endif
 
@@ -586,7 +573,7 @@ void timer_interrupt(struct pt_regs * regs)
                /* not time for this event yet */
                now = per_cpu(decrementer_next_tb, cpu) - now;
                if (now <= DECREMENTER_MAX)
-                       set_dec((unsigned int)now - 1);
+                       set_dec((int)now);
                return;
        }
        old_regs = set_irq_regs(regs);
@@ -599,20 +586,8 @@ void timer_interrupt(struct pt_regs * regs)
                get_lppaca()->int_dword.fields.decr_int = 0;
 #endif
 
-       /*
-        * We cannot disable the decrementer, so in the period
-        * between this cpu's being marked offline in cpu_online_map
-        * and calling stop-self, it is taking timer interrupts.
-        * Avoid calling into the scheduler rebalancing code if this
-        * is the case.
-        */
-       if (!cpu_is_offline(cpu))
-               account_process_time(regs);
-
        if (evt->event_handler)
                evt->event_handler(evt);
-       else
-               evt->set_next_event(DECREMENTER_MAX, evt);
 
 #ifdef CONFIG_PPC_ISERIES
        if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
@@ -836,9 +811,6 @@ static int decrementer_set_next_event(unsigned long evt,
                                      struct clock_event_device *dev)
 {
        __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
-       /* The decrementer interrupts on the 0 -> -1 transition */
-       if (evt)
-               --evt;
        set_dec(evt);
        return 0;
 }
@@ -857,7 +829,7 @@ static void register_decrementer_clockevent(int cpu)
        *dec = decrementer_clockevent;
        dec->cpumask = cpumask_of_cpu(cpu);
 
-       printk(KERN_INFO "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
+       printk(KERN_DEBUG "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
               dec->name, dec->mult, dec->shift, cpu);
 
        clockevents_register_device(dec);
@@ -871,7 +843,8 @@ void init_decrementer_clockevent(void)
                                             decrementer_clockevent.shift);
        decrementer_clockevent.max_delta_ns =
                clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
-       decrementer_clockevent.min_delta_ns = 1000;
+       decrementer_clockevent.min_delta_ns =
+               clockevent_delta2ns(2, &decrementer_clockevent);
 
        register_decrementer_clockevent(cpu);
 }
index 823a8cbd60b5bffd1025cff71ee2b56e0c751f76..f66fa5d966b0d75ebecf99d53ac4723e8f2622ce 100644 (file)
@@ -37,11 +37,10 @@ SECTIONS
                ALIGN_FUNCTION();
                *(.text.head)
                _text = .;
-               TEXT_TEXT
+               *(.text .fixup .text.init.refok .exit.text.refok)
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
-               *(.fixup)
 
 #ifdef CONFIG_PPC32
                *(.got1)
index e067df836be20954b319b7c2efe7aa6731f4b762..3899ea97fbdff935b23869fbe8c8db9c6de78283 100644 (file)
@@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void)
 
        v = KERNELBASE;
        p = PPC_MEMSTART;
-       s = 0;
+       s = total_lowmem;
 
-       if (__map_without_ltlbs) {
-               return s;
-       }
+       if (__map_without_ltlbs)
+               return 0;
 
-       while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+       while (s >= LARGE_PAGE_SIZE_16M) {
                pmd_t *pmdp;
                unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
 
@@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void)
 
                v += LARGE_PAGE_SIZE_16M;
                p += LARGE_PAGE_SIZE_16M;
-               s += LARGE_PAGE_SIZE_16M;
+               s -= LARGE_PAGE_SIZE_16M;
        }
 
-       while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+       while (s >= LARGE_PAGE_SIZE_4M) {
                pmd_t *pmdp;
                unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
 
@@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void)
 
                v += LARGE_PAGE_SIZE_4M;
                p += LARGE_PAGE_SIZE_4M;
-               s += LARGE_PAGE_SIZE_4M;
+               s -= LARGE_PAGE_SIZE_4M;
        }
 
-       return s;
+       return total_lowmem - s;
 }
index c3df504765393b05f01ca8a6128b1db7992adc8c..04dc08798d3d1ff9c4bdbc2da09f9fbc8ce49c02 100644 (file)
@@ -35,6 +35,7 @@
  */
 unsigned int tlb_44x_index; /* = 0 */
 unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
+int icache_44x_need_flush;
 
 /*
  * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
index a18fda361cc0fe19103add8034d5b3485b012079..8135da06e0a44e4e320e7157e3b9fec364e67793 100644 (file)
@@ -309,7 +309,7 @@ good_area:
                                        set_bit(PG_arch_1, &page->flags);
                                }
                                pte_update(ptep, 0, _PAGE_HWEXEC);
-                               _tlbie(address);
+                               _tlbie(address, mm->context.id);
                                pte_unmap_unlock(ptep, ptl);
                                up_read(&mm->mmap_sem);
                                return 0;
index ad253b959030b9720221bc2190ad4cf5b108016e..e935edd6b72b44645ddf9a6d82af9c8e0b02c13b 100644 (file)
@@ -331,7 +331,7 @@ htab_pte_insert_failure:
  *****************************************************************************/
 
 /* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
- *              pte_t *ptep, unsigned long trap, int local)
+ *              pte_t *ptep, unsigned long trap, int local, int ssize)
  */
 
 /*
@@ -557,7 +557,8 @@ htab_inval_old_hpte:
        mr      r4,r31                  /* PTE.pte */
        li      r5,0                    /* PTE.hidx */
        li      r6,MMU_PAGE_64K         /* psize */
-       ld      r7,STK_PARM(r8)(r1)     /* local */
+       ld      r7,STK_PARM(r9)(r1)     /* ssize */
+       ld      r8,STK_PARM(r8)(r1)     /* local */
        bl      .flush_hash_page
        b       htab_insert_pte
        
index c78dc912411f9f6aa57c951023a733a7370b81c7..f09730bf3a335bc20de567bd5e596b727317faca 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/cputable.h>
 #include <asm/sections.h>
 #include <asm/spu.h>
+#include <asm/udbg.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -791,8 +792,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        }
        if (user_region) {
                if (psize != get_paca()->context.user_psize) {
-                       get_paca()->context.user_psize =
-                               mm->context.user_psize;
+                       get_paca()->context = mm->context;
                        slb_flush_and_rebolt();
                }
        } else if (get_paca()->vmalloc_sllp !=
@@ -885,6 +885,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
        local_irq_restore(flags);
 }
 
+/* WARNING: This is called from hash_low_64.S, if you change this prototype,
+ *          do not forget to update the assembly call site !
+ */
 void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
                     int local)
 {
index d9c82d3d64821d4ed15fa48ec745ebb39d9fccb8..c0f5cff77035e8d1abae6fe746e96af2cbcd6dd2 100644 (file)
@@ -19,8 +19,6 @@
  *
  */
 
-#undef DEBUG
-
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 
 #include "mmu_decl.h"
 
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
 #if PGTABLE_RANGE > USER_VSID_RANGE
 #warning Limited user VSID range means pagetable space is wasted
 #endif
@@ -175,8 +167,8 @@ void pgtable_cache_init(void)
                int size = pgtable_cache_size[i];
                const char *name = pgtable_cache_name[i];
 
-               DBG("Allocating page table cache %s (#%d) "
-                   "for size: %08x...\n", name, i, size);
+               pr_debug("Allocating page table cache %s (#%d) "
+                       "for size: %08x...\n", name, i, size);
                pgtable_cache[i] = kmem_cache_create(name,
                                                     size, size,
                                                     SLAB_PANIC,
@@ -239,8 +231,8 @@ int __meminit vmemmap_populate(struct page *start_page,
                if (!p)
                        return -ENOMEM;
 
-               printk(KERN_WARNING "vmemmap %08lx allocated at %p, "
-                                   "physical %08lx.\n", start, p, __pa(p));
+               pr_debug("vmemmap %08lx allocated at %p, physical %08lx.\n",
+                       start, p, __pa(p));
 
                mapped = htab_bolt_mapping(start, start + page_size,
                                        __pa(p), mode_rw, mmu_linear_psize,
index c94a64fd3c01d2b1b4abec580c532ea634e37aa7..eb3a732e91db28a5bb17b2c1711992906e597ae4 100644 (file)
@@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
 #define mmu_mapin_ram()                (0UL)
 
 #elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg)  _tlbie(va)
+#define flush_HPTE(pid, va, pg)        _tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 
 #elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg)  _tlbie(va)
+#define flush_HPTE(pid, va, pg)        _tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 extern void adjust_total_lowmem(void);
index bbd2c512ee0530ded1aa374242b06cce5b4f319b..27922dff8b94e34614890f7764ce10c014b6fb65 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/smp.h>
 #include <asm/firmware.h>
 #include <linux/compiler.h>
+#include <asm/udbg.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -148,6 +149,35 @@ void slb_vmalloc_update(void)
        slb_flush_and_rebolt();
 }
 
+/* Helper function to compare esids.  There are four cases to handle.
+ * 1. The system is not 1T segment size capable.  Use the GET_ESID compare.
+ * 2. The system is 1T capable, both addresses are < 1T, use the GET_ESID compare.
+ * 3. The system is 1T capable, only one of the two addresses is > 1T.  This is not a match.
+ * 4. The system is 1T capable, both addresses are > 1T, use the GET_ESID_1T macro to compare.
+ */
+static inline int esids_match(unsigned long addr1, unsigned long addr2)
+{
+       int esid_1t_count;
+
+       /* System is not 1T segment size capable. */
+       if (!cpu_has_feature(CPU_FTR_1T_SEGMENT))
+               return (GET_ESID(addr1) == GET_ESID(addr2));
+
+       esid_1t_count = (((addr1 >> SID_SHIFT_1T) != 0) +
+                               ((addr2 >> SID_SHIFT_1T) != 0));
+
+       /* both addresses are < 1T */
+       if (esid_1t_count == 0)
+               return (GET_ESID(addr1) == GET_ESID(addr2));
+
+       /* One address < 1T, the other > 1T.  Not a match */
+       if (esid_1t_count == 1)
+               return 0;
+
+       /* Both addresses are > 1T. */
+       return (GET_ESID_1T(addr1) == GET_ESID_1T(addr2));
+}
+
 /* Flush all user entries from the segment table of the current processor. */
 void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 {
@@ -193,15 +223,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
                return;
        slb_allocate(pc);
 
-       if (GET_ESID(pc) == GET_ESID(stack))
+       if (esids_match(pc,stack))
                return;
 
        if (is_kernel_addr(stack))
                return;
        slb_allocate(stack);
 
-       if ((GET_ESID(pc) == GET_ESID(unmapped_base))
-           || (GET_ESID(stack) == GET_ESID(unmapped_base)))
+       if (esids_match(pc,unmapped_base) || esids_match(stack,unmapped_base))
                return;
 
        if (is_kernel_addr(unmapped_base))
index eafbca52bff9ce1e4e58cc23d5ff03943434e6a0..e2d867ce1c7eb46fb259993ebf8f99c0a177bca9 100644 (file)
@@ -54,12 +54,10 @@ unsigned long pte_freelist_forced_free;
        ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
          / sizeof(pgtable_free_t))
 
-#ifdef CONFIG_SMP
 static void pte_free_smp_sync(void *arg)
 {
        /* Do nothing, just ensure we sync with all CPUs */
 }
-#endif
 
 /* This is only called when we are critically out of memory
  * (and fail to get a page in pte_free_tlb).
index 151fd8b82d63b2e0878a7ee48118b3cda0ca0576..04f74f9f9ab67dcae27a706a7c3de449bab22ac6 100644 (file)
@@ -158,6 +158,18 @@ static unsigned int iic_get_irq(void)
        return virq;
 }
 
+void iic_setup_cpu(void)
+{
+       out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+}
+
+u8 iic_get_target_id(int cpu)
+{
+       return per_cpu(iic, cpu).target_id;
+}
+
+EXPORT_SYMBOL_GPL(iic_get_target_id);
+
 #ifdef CONFIG_SMP
 
 /* Use the highest interrupt priorities for IPI */
@@ -166,29 +178,17 @@ static inline int iic_ipi_to_irq(int ipi)
        return IIC_IRQ_TYPE_IPI + 0xf - ipi;
 }
 
-void iic_setup_cpu(void)
-{
-       out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
-}
-
 void iic_cause_IPI(int cpu, int mesg)
 {
        out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
 }
 
-u8 iic_get_target_id(int cpu)
-{
-       return per_cpu(iic, cpu).target_id;
-}
-EXPORT_SYMBOL_GPL(iic_get_target_id);
-
 struct irq_host *iic_get_irq_host(int node)
 {
        return iic_host;
 }
 EXPORT_SYMBOL_GPL(iic_get_irq_host);
 
-
 static irqreturn_t iic_ipi_action(int irq, void *dev_id)
 {
        int ipi = (int)(long)dev_id;
index 1c0acbad7425b63e194726b109e95a01422c3bc2..e4438456c8675c8917052ba9e95cdd8a9e828809 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/rtas.h>
 
 #include "interrupt.h"
+#include <asm/udbg.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
index 1769d755eff30670eee5bd58f0c498b618aec4ce..ddfb35ae741ff2abbdea105a79a2609623f67d07 100644 (file)
@@ -49,6 +49,7 @@
 #include <asm/machdep.h>
 #include <asm/cputable.h>
 #include <asm/irq.h>
+#include <asm/time.h>
 #include <asm/spu_priv1.h>
 #include <asm/firmware.h>
 #include <asm/of_platform.h>
index 69f1b437fc7bb4b90708a6d1e79facc3864a9c39..a1c2360740347478a983b7ba2df1d36a98bcc07e 100644 (file)
@@ -1,9 +1,13 @@
 #ifndef        _ISERIES_IRQ_H
 #define        _ISERIES_IRQ_H
 
+#ifdef CONFIG_PCI
 extern void iSeries_init_IRQ(void);
 extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
 extern void iSeries_activate_IRQs(void);
+#else
+#define iSeries_init_IRQ       NULL
+#endif
 extern unsigned int iSeries_get_irq(void);
 
 #endif /* _ISERIES_IRQ_H */
index 37ae07ee54a9886944d5f15e932deac4abeb9432..0877a88341100e7cdf25a49c3167f0c3a94fdffc 100644 (file)
@@ -617,10 +617,6 @@ static void iseries_dedicated_idle(void)
        }
 }
 
-#ifndef CONFIG_PCI
-void __init iSeries_init_IRQ(void) { }
-#endif
-
 static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
                                     unsigned long flags)
 {
index d6435b03971f1e9d087a7d643828a653e559e1fd..be06cfd9fa3d5e20afbeaf7f444ce5bc4ea5c172 100644 (file)
@@ -523,15 +523,16 @@ static void __init get_viotape_info(struct device_node *vio_root)
 static int __init iseries_vio_init(void)
 {
        struct device_node *vio_root;
+       int ret = -ENODEV;
 
        if (!firmware_has_feature(FW_FEATURE_ISERIES))
-               return -ENODEV;
+               goto out;
 
        iommu_vio_init();
 
        vio_root = of_find_node_by_path("/vdevice");
        if (!vio_root)
-               return -ENODEV;
+               goto out;
 
        if (viopath_hostLp == HvLpIndexInvalid) {
                vio_set_hostlp();
@@ -544,10 +545,11 @@ static int __init iseries_vio_init(void)
        get_viocd_info(vio_root);
        get_viotape_info(vio_root);
 
-       return 0;
+       ret = 0;
 
  put_node:
        of_node_put(vio_root);
-       return -ENODEV;
+ out:
+       return ret;
 }
 arch_initcall(iseries_vio_init);
index 22322b35a0ffd1224e4e0c7c9f19c64a0b7bc12f..fb3d636e088be7eaf049d5af89dcf8e72add7cee 100644 (file)
@@ -186,6 +186,11 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
        n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
        printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
 
+       if (!dev) {
+               printk(KERN_WARNING "EEH: no PCI device for this of node\n");
+               return n;
+       }
+
        /* Gather bridge-specific registers */
        if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
                rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
@@ -198,7 +203,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
        }
 
        /* Dump out the PCI-X command and status regs */
-       cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX);
+       cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
        if (cap) {
                rtas_read_config(pdn, cap, 4, &cfg);
                n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
@@ -210,7 +215,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
        }
 
        /* If PCI-E capable, dump PCI-E cap 10, and the AER */
-       cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_EXP);
+       cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
        if (cap) {
                n += scnprintf(buf+n, len-n, "pci-e cap10:\n");
                printk(KERN_WARNING
@@ -222,7 +227,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
                        printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
                }
 
-               cap = pci_find_ext_capability(pdn->pcidev, PCI_EXT_CAP_ID_ERR);
+               cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
                if (cap) {
                        n += scnprintf(buf+n, len-n, "pci-e AER:\n");
                        printk(KERN_WARNING
@@ -318,7 +323,7 @@ eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs)
 
                if (rets[2] == 0) return -1; /* permanently unavailable */
 
-               if (max_wait_msecs <= 0) return -1;
+               if (max_wait_msecs <= 0) break;
 
                mwait = rets[2];
                if (mwait <= 0) {
index 15e015ef68653f78dec23d8ca4008be911b4acb4..57e025e84ab4ae0132b3145c96689730989ef6f9 100644 (file)
@@ -105,17 +105,18 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
                return;
 
        rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
+
+       /* A driver that needs a reset trumps all others */
+       if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
        if (*res == PCI_ERS_RESULT_NONE) *res = rc;
-       if (*res == PCI_ERS_RESULT_DISCONNECT &&
-            rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 }
 
 /**
  * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
  *
- * Report an EEH error to each device driver, collect up and
- * merge the device driver responses. Cumulative response
- * passed back in "userdata".
+ * Tells each device driver that IO ports, MMIO and config space I/O
+ * are now enabled. Collects up and merges the device driver responses.
+ * Cumulative response passed back in "userdata".
  */
 
 static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
@@ -123,17 +124,16 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
        enum pci_ers_result rc, *res = userdata;
        struct pci_driver *driver = dev->driver;
 
-       // dev->error_state = pci_channel_mmio_enabled;
-
        if (!driver ||
            !driver->err_handler ||
            !driver->err_handler->mmio_enabled)
                return;
 
        rc = driver->err_handler->mmio_enabled (dev);
+
+       /* A driver that needs a reset trumps all others */
+       if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
        if (*res == PCI_ERS_RESULT_NONE) *res = rc;
-       if (*res == PCI_ERS_RESULT_DISCONNECT &&
-            rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 }
 
 /**
index 8b18a1c40092c5e7c68402c8ce78a1232a67ef41..b765b7c77b65ddacdeb806ce10904d6e5697ea42 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <asm/firmware.h>
 #include <asm/prom.h>
+#include <asm/udbg.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
index 2793a1b100e64260e062eca9ca7517a78183f7b7..f15222bbe136a1020de443d3ff6c434c152c8d4b 100644 (file)
@@ -171,6 +171,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        struct pci_dn *pdn;
        int hwirq, virq, i, rc;
        struct msi_desc *entry;
+       struct msi_msg msg;
 
        pdn = get_pdn(pdev);
        if (!pdn)
@@ -213,6 +214,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 
                dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
                set_irq_msi(virq, entry);
+
+               /* Read config space back so we can restore after reset */
+               read_msi_msg(virq, &msg);
+               entry->msg = msg;
+
                unmask_msi_irq(virq);
        }
 
index 66c8ad4cfce64075a52044238eab4b98ed28b0f8..165981c87786bc2832e2f7bef8436a69663c88de 100644 (file)
@@ -77,8 +77,6 @@ int __init cpm_muram_init(void)
        int i = 0;
        int ret = 0;
 
-       printk("cpm_muram_init\n");
-
        spin_lock_init(&cpm_muram_lock);
        /* initialize the info header */
        rh_init(&cpm_muram_info, 1,
@@ -193,7 +191,7 @@ void __iomem *cpm_muram_addr(unsigned long offset)
 EXPORT_SYMBOL(cpm_muram_addr);
 
 /**
- * cpm_muram_phys - turn a muram virtual address into a DMA address
+ * cpm_muram_dma - turn a muram virtual address into a DMA address
  * @offset: virtual address from cpm_muram_addr() to convert
  */
 dma_addr_t cpm_muram_dma(void __iomem *addr)
index 7c1b27ac7d3caf70f1cc59f0b7fff3dff05fb109..216c0f5680d25ee0b5411e6dd30ecddfb2311ed5 100644 (file)
@@ -137,6 +137,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
 static struct irq_chip i8259_pic = {
        .typename       = " i8259    ",
        .mask           = i8259_mask_irq,
+       .disable        = i8259_mask_irq,
        .unmask         = i8259_unmask_irq,
        .mask_ack       = i8259_mask_and_ack_irq,
 };
index 9b3baa7317d749ea24e698995767b75b237ae36d..6933f9c73b43accc8ec55ac26ff6190a62529669 100644 (file)
@@ -24,8 +24,9 @@
 #define MV64X60_VAL_LEN_MAX            11
 #define MV64X60_PCICFG_CPCI_HOTSWAP    0x68
 
-static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
-                                  size_t count)
+static ssize_t mv64x60_hs_reg_read(struct kobject *kobj,
+                                  struct bin_attribute *attr, char *buf,
+                                  loff_t off, size_t count)
 {
        struct pci_dev *phb;
        u32 v;
@@ -44,8 +45,9 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
        return sprintf(buf, "0x%08x\n", v);
 }
 
-static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf, loff_t off,
-                                   size_t count)
+static ssize_t mv64x60_hs_reg_write(struct kobject *kobj,
+                                   struct bin_attribute *attr, char *buf,
+                                   loff_t off, size_t count)
 {
        struct pci_dev *phb;
        u32 v;
index fba7ca17a67e1565cdb8cb83628f828b7640b77d..59e77eb63338de4ea3bab18462967a6e16d4b208 100644 (file)
@@ -244,6 +244,16 @@ syscall_exit_cont:
        andis.  r10,r0,DBCR0_IC@h
        bnel-   load_dbcr0
 #endif
+#ifdef CONFIG_44x
+       lis     r4,icache_44x_need_flush@ha
+       lwz     r5,icache_44x_need_flush@l(r4)
+       cmplwi  cr0,r5,0
+       bne-    2f
+1:
+#endif /* CONFIG_44x */
+BEGIN_FTR_SECTION
+       lwarx   r7,0,r1
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
        stwcx.  r0,0,r1                 /* to clear the reservation */
        lwz     r4,_LINK(r1)
        lwz     r5,_CCR(r1)
@@ -258,6 +268,12 @@ syscall_exit_cont:
        mtspr   SPRN_SRR1,r8
        SYNC
        RFI
+#ifdef CONFIG_44x
+2:     li      r7,0
+       iccci   r0,r0
+       stw     r7,icache_44x_need_flush@l(r4)
+       b       1b
+#endif  /* CONFIG_44x */
 
 66:    li      r3,-ENOSYS
        b       ret_from_syscall
@@ -679,6 +695,16 @@ resume_kernel:
 
        /* interrupts are hard-disabled at this point */
 restore:
+#ifdef CONFIG_44x
+       lis     r4,icache_44x_need_flush@ha
+       lwz     r5,icache_44x_need_flush@l(r4)
+       cmplwi  cr0,r5,0
+       beq+    1f
+       li      r6,0
+       iccci   r0,r0
+       stw     r6,icache_44x_need_flush@l(r4)
+1:
+#endif  /* CONFIG_44x */
        lwz     r0,GPR0(r1)
        lwz     r2,GPR2(r1)
        REST_4GPRS(3, r1)
@@ -690,6 +716,9 @@ restore:
        mtctr   r11
 
        PPC405_ERR77(0,r1)
+BEGIN_FTR_SECTION
+       lwarx   r11,0,r1
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
        stwcx.  r0,0,r1                 /* to clear the reservation */
 
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
index a22e1f4d94c82edd1c3ee92d7ea491b82a716b30..e0c850d85c530b933515a123bf66fb42d81ebed2 100644 (file)
@@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
  */
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
+       /* We run the search with interrupts disabled because we have to change
+        * the PID and I don't want to preempt when that happens.
+        */
+       mfmsr   r5
+       mfspr   r6,SPRN_PID
+       wrteei  0
+       mtspr   SPRN_PID,r4
        tlbsx.  r3, 0, r3
+       mtspr   SPRN_PID,r6
+       wrtee   r5
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
        isync
 10:
 #elif defined(CONFIG_44x)
-       mfspr   r4,SPRN_MMUCR
-       mfspr   r5,SPRN_PID                     /* Get PID */
-       rlwimi  r4,r5,0,24,31                   /* Set TID */
+       mfspr   r5,SPRN_MMUCR
+       rlwimi  r5,r4,0,24,31                   /* Set TID */
 
        /* We have to run the search with interrupts disabled, even critical
         * and debug interrupts (in fact the only critical exceptions we have
         * are debug and machine check).  Otherwise  an interrupt which causes
         * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
-       mfmsr   r5
+       mfmsr   r4
        lis     r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
        addi    r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
-       andc    r6,r5,r6
+       andc    r6,r4,r6
        mtmsr   r6
-       mtspr   SPRN_MMUCR,r4
+       mtspr   SPRN_MMUCR,r5
        tlbsx.  r3, 0, r3
-       mtmsr   r5
+       mtmsr   r4
        bne     10f
        sync
        /* There are only 64 TLB entries, so r3 < 64,
@@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        addi    r3,r3,L1_CACHE_BYTES
        bdnz    0b
        sync
+#ifndef CONFIG_44x
+       /* We don't flush the icache on 44x. Those have a virtual icache
+        * and we don't have access to the virtual address here (it's
+        * not the page vaddr but where it's mapped in user space). The
+        * flushing of the icache on these is handled elsewhere, when
+        * a change in the address space occurs, before returning to
+        * user space
+        */
        mtctr   r4
 1:     icbi    0,r6
        addi    r6,r6,L1_CACHE_BYTES
        bdnz    1b
        sync
        isync
+#endif /* CONFIG_44x */
        blr
 
 /*
index 0a0a0487b33435f350713fc730a8b370b5e43b17..6536a25cfcb8117c371aa07008ec4ce7478553ae 100644 (file)
@@ -61,6 +61,7 @@ extern char etext[], _stext[];
  */
 unsigned int tlb_44x_index = 0;
 unsigned int tlb_44x_hwater = 62;
+int icache_44x_need_flush;
 
 /*
  * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
index 838e09db71d97f56ca3721917dd2fd0ada843042..ea785dbaac7cec8441925edd6e0be9688406759d 100644 (file)
@@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void)
 
        v = KERNELBASE;
        p = PPC_MEMSTART;
-       s = 0;
+       s = total_lowmem;
 
-       if (__map_without_ltlbs) {
-               return s;
-       }
+       if (__map_without_ltlbs)
+               return 0;
 
-       while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+       while (s >= LARGE_PAGE_SIZE_16M) {
                pmd_t *pmdp;
                unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
 
@@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void)
 
                v += LARGE_PAGE_SIZE_16M;
                p += LARGE_PAGE_SIZE_16M;
-               s += LARGE_PAGE_SIZE_16M;
+               s -= LARGE_PAGE_SIZE_16M;
        }
 
-       while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+       while (s >= LARGE_PAGE_SIZE_4M) {
                pmd_t *pmdp;
                unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
 
@@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void)
 
                v += LARGE_PAGE_SIZE_4M;
                p += LARGE_PAGE_SIZE_4M;
-               s += LARGE_PAGE_SIZE_4M;
+               s -= LARGE_PAGE_SIZE_4M;
        }
 
-       return s;
+       return total_lowmem - s;
 }
index 254c23b755e689006a7073a13a57cbf35db4643b..36c0e7529edbc89f1e7c7dc8d3c000024a2f433d 100644 (file)
@@ -227,7 +227,7 @@ good_area:
                                        set_bit(PG_arch_1, &page->flags);
                                }
                                pte_update(ptep, 0, _PAGE_HWEXEC);
-                               _tlbie(address);
+                               _tlbie(address, mm->context.id);
                                pte_unmap_unlock(ptep, ptl);
                                up_read(&mm->mmap_sem);
                                return 0;
index 540f3292b2291f0c1e2cc78ccbdf87b5feac39b3..f1d4f2109a994a44eada0c0736f58c1143ff819a 100644 (file)
@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
 #define mmu_mapin_ram()                (0UL)
 
 #elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg)  _tlbie(va)
+#define flush_HPTE(pid, va, pg)        _tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 
 #elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg)  _tlbie(va)
+#define flush_HPTE(pid, va, pg)        _tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 extern void adjust_total_lowmem(void);
index 05d7184d7e1454ec2f85022fb82e4513ca38de3d..453643a0eeea04e50f12783c331f3ae509658063 100644 (file)
@@ -236,7 +236,7 @@ ebony_early_serial_map(void)
        gen550_init(0, &port);
 
        /* Purge TLB entry added in head_44x.S for early serial access */
-       _tlbie(UART0_IO_BASE);
+       _tlbie(UART0_IO_BASE, 0);
 #endif
 
        port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
index 4b169610f15425865e3993726390123c60350c30..b79ebb8a3e6cd16ccde2ff5bca8d1d1cd9a7c4ad 100644 (file)
@@ -230,9 +230,14 @@ luan_setup_hoses(void)
 
        /* Allocate hoses for PCIX1 and PCIX2 */
        hose1 = pcibios_alloc_controller();
+       if (!hose1)
+               return;
+
        hose2 = pcibios_alloc_controller();
-       if (!hose1 || !hose2)
+       if (!hose2) {
+               pcibios_free_controller(hose1);
                return;
+       }
 
        /* Setup PCIX1 */
        hose1->first_busno = 0;
index fd0f971881d67763c0b6fc36ee0708c674e14f38..28a712cd4800dbdc272e15c2ef0f582ffbce6394 100644 (file)
@@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
        gen550_init(0, &port);
 
        /* Purge TLB entry added in head_44x.S for early serial access */
-       _tlbie(UART0_IO_BASE);
+       _tlbie(UART0_IO_BASE, 0);
 #endif
 
        port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
index 888c492b4a4535dea8730f56a42d52ad66f2cc4b..f6a0c6650f3309c69a2d5194ccdef9fac08e47a8 100644 (file)
@@ -316,7 +316,7 @@ taishan_early_serial_map(void)
        gen550_init(0, &port);
 
        /* Purge TLB entry added in head_44x.S for early serial access */
-       _tlbie(UART0_IO_BASE);
+       _tlbie(UART0_IO_BASE, 0);
 #endif
 
        port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
index 1e5a00a4b5f55a5280dcc37452ccf847619b7274..559f27c6aefe823b1b53a3e29688a8d70b17f024 100644 (file)
@@ -127,6 +127,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
 static struct irq_chip i8259_pic = {
        .typename       = " i8259    ",
        .mask           = i8259_mask_irq,
+       .disable        = i8259_mask_irq,
        .unmask         = i8259_unmask_irq,
        .mask_ack       = i8259_mask_and_ack_irq,
 };
index 15f0d7323535f400b81603dd21f1bc00f2ecc50e..46588fa9438139657fc04f188d8ca258e27c5f39 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/machdep.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
+#include <asm/ppc_sys.h>
 
 #include "cpm2_pic.h"
 
@@ -61,7 +62,7 @@ m8260_setup_arch(void)
 #endif
 
        identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
-                               in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
+                       in_be32((void *)CPM_MAP_ADDR + CPM_IMMR_OFFSET));
 
        m82xx_board_setup();
 }
@@ -147,12 +148,12 @@ m8260_show_cpuinfo(struct seq_file *m)
        seq_printf(m, "vendor\t\t: %s\n"
                   "machine\t\t: %s\n"
                   "\n"
-                  "mem size\t\t: 0x%08x\n"
-                  "console baud\t\t: %d\n"
+                  "mem size\t\t: 0x%08lx\n"
+                  "console baud\t\t: %ld\n"
                   "\n"
-                  "core clock\t: %u MHz\n"
-                  "CPM  clock\t: %u MHz\n"
-                  "bus  clock\t: %u MHz\n",
+                  "core clock\t: %lu MHz\n"
+                  "CPM  clock\t: %lu MHz\n"
+                  "bus  clock\t: %lu MHz\n",
                   CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
                   bp->bi_baudrate, bp->bi_intfreq / 1000000,
                   bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
index e6289ee74ecd400bcfaf606d8f9585191225462f..8bf4ae1150be6775b2c348af2ee56a2786dd320c 100644 (file)
@@ -200,11 +200,13 @@ static noinline __init void find_memory_chunks(unsigned long memsize)
                cc = __tprot(addr);
                while (cc == old_cc) {
                        addr += CHUNK_INCR;
-                       cc = __tprot(addr);
+                       if (addr >= memsize)
+                               break;
 #ifndef CONFIG_64BIT
                        if (addr == ADDR2G)
                                break;
 #endif
+                       cc = __tprot(addr);
                }
 
                if (old_addr != addr &&
index 96492cf2d491d38d4d6000cddb1a38fb4b1463fb..29f7884b4ffad57c3f709f714959dc8c52c7f3f1 100644 (file)
@@ -92,6 +92,7 @@ EXPORT_SYMBOL(unregister_idle_notifier);
 
 void do_monitor_call(struct pt_regs *regs, long interruption_code)
 {
+#ifdef CONFIG_SMP
        struct s390_idle_data *idle;
 
        idle = &__get_cpu_var(s390_idle);
@@ -99,7 +100,7 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
        idle->idle_time += get_clock() - idle->idle_enter;
        idle->in_idle = 0;
        spin_unlock(&idle->lock);
-
+#endif
        /* disable monitor call class 0 */
        __ctl_clear_bit(8, 15);
 
@@ -114,7 +115,9 @@ extern void s390_handle_mcck(void);
 static void default_idle(void)
 {
        int cpu, rc;
+#ifdef CONFIG_SMP
        struct s390_idle_data *idle;
+#endif
 
        /* CPU is going idle. */
        cpu = smp_processor_id();
@@ -151,13 +154,14 @@ static void default_idle(void)
                s390_handle_mcck();
                return;
        }
-
+#ifdef CONFIG_SMP
        idle = &__get_cpu_var(s390_idle);
        spin_lock(&idle->lock);
        idle->idle_count++;
        idle->in_idle = 1;
        idle->idle_enter = get_clock();
        spin_unlock(&idle->lock);
+#endif
        trace_hardirqs_on();
        /* Wait for external, I/O or machine check interrupt. */
        __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
index 1d97fe1c0e538d1df29aebd133522d09dfcf08c3..b05ae8584258e3f9081da0e60f2733d8fea54436 100644 (file)
@@ -788,14 +788,14 @@ static ssize_t show_idle_time(struct sys_device *dev, char *buf)
        }
        new_time = idle->idle_time;
        spin_unlock_irq(&idle->lock);
-       return sprintf(buf, "%llu us\n", new_time >> 12);
+       return sprintf(buf, "%llu\n", new_time >> 12);
 }
-static SYSDEV_ATTR(idle_time, 0444, show_idle_time, NULL);
+static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL);
 
 static struct attribute *cpu_attrs[] = {
        &attr_capability.attr,
        &attr_idle_count.attr,
-       &attr_idle_time.attr,
+       &attr_idle_time_us.attr,
        NULL,
 };
 
index 48dae49bc1ec474ffe80f3eed427a610f48d48bf..22b800ce2126d0fed3c47400229ef95f4060310b 100644 (file)
@@ -145,12 +145,8 @@ void account_ticks(u64 time)
        do_timer(ticks);
 #endif
 
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       account_tick_vtime(current);
-#else
        while (ticks--)
                update_process_times(user_mode(get_irq_regs()));
-#endif
 
        s390_do_profile();
 }
@@ -307,7 +303,7 @@ static cycle_t read_tod_clock(void)
 
 static struct clocksource clocksource_tod = {
        .name           = "tod",
-       .rating         = 100,
+       .rating         = 400,
        .read           = read_tod_clock,
        .mask           = -1ULL,
        .mult           = 1000,
index 84ff78de6bacdeec58a16261e58fdaea24a0932e..c5f05b3fb2c30f1548a062280be08fc12411340d 100644 (file)
@@ -32,7 +32,7 @@ static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
  * Update process times based on virtual cpu times stored by entry.S
  * to the lowcore fields user_timer, system_timer & steal_clock.
  */
-void account_tick_vtime(struct task_struct *tsk)
+void account_process_tick(struct task_struct *tsk, int user_tick)
 {
        cputime_t cputime;
        __u64 timer, clock;
@@ -64,12 +64,6 @@ void account_tick_vtime(struct task_struct *tsk)
                S390_lowcore.steal_clock -= cputime << 12;
                account_steal_time(tsk, cputime);
        }
-
-       run_local_timers();
-       if (rcu_pending(smp_processor_id()))
-               rcu_check_callbacks(smp_processor_id(), rcu_user_flag);
-       scheduler_tick();
-       run_posix_cpu_timers(tsk);
 }
 
 /*
index 22a3eb38438b14e2cb2d5c5e4108c1ae779f2dfc..496d635f89b216722df77895005ab35698ec4e8f 100644 (file)
@@ -211,10 +211,12 @@ config SH_SOLUTION_ENGINE
        bool "SolutionEngine"
        select SOLUTION_ENGINE
        select CPU_HAS_IPR_IRQ
-       depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750
+       depends on CPU_SUBTYPE_SH7705 || CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7710 || \
+         CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7750S || \
+         CPU_SUBTYPE_SH7750R 
        help
-         Select SolutionEngine if configuring for a Hitachi SH7709
-         or SH7750 evaluation board.
+         Select SolutionEngine if configuring for a Hitachi SH7705, SH7709,
+         SH7710, SH7712, SH7750, SH7750S or SH7750R evaluation board.
 
 config SH_7206_SOLUTION_ENGINE
        bool "SolutionEngine7206"
@@ -603,7 +605,7 @@ config BOOT_LINK_OFFSET
 
 config UBC_WAKEUP
        bool "Wakeup UBC on startup"
-       depends on CPU_SH4
+       depends on CPU_SH4 && !CPU_SH4A
        help
          Selecting this option will wakeup the User Break Controller (UBC) on
          startup. Although the UBC is left in an awake state when the processor
index ab2f9f3c354c27df9c54081d641c9aa11b67353d..722da6851f569abe5ee44bec961ac958a2f4ad33 100644 (file)
@@ -124,12 +124,13 @@ config KGDB_NMI
 
 config SH_KGDB_CONSOLE
        bool "Console messages through GDB"
-       depends on !SERIAL_SH_SCI_CONSOLE
+       depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
        select SERIAL_CORE_CONSOLE
        default n
 
 config KGDB_SYSRQ
        bool "Allow SysRq 'G' to enter KGDB"
+       depends on MAGIC_SYSRQ
        default y
 
 comment "Serial port setup"
index 943f93aa6052cc8ddc5a3723c804819b52a84bd7..e55c6686b21fce00656724afa0b1a9fd3e35fc85 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hs7751rvoip.h>
index fa5fa39202227f97e5e23d619f0482b3e348293a..c05625975f2c7fb62c2064b628247a3b6ae0d077 100644 (file)
 #include <asm/io.h>
 #include <asm/machvec.h>
 
-static struct ipr_data hs77501rvoip_ipr_map[] = {
-#if defined(CONFIG_HS7751RVOIP_CODEC)
-       { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
-       { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
-#endif
-};
-
-static void __init hs7751rvoip_init_irq(void)
-{
-       make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map));
-
-       init_hs7751rvoip_IRQ();
-}
-
 static void hs7751rvoip_power_off(void)
 {
        ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR);
@@ -75,14 +61,13 @@ static int __init hs7751rvoip_cf_init(void)
 
        return 0;
 }
+device_initcall(hs7751rvoip_cf_init);
 
 /*
  * Initialize the board
  */
 static void __init hs7751rvoip_setup(char **cmdline_p)
 {
-       device_initcall(hs7751rvoip_cf_init);
-
        ctrl_outb(0xf0, PA_OUTPORTR);
        pm_power_off = hs7751rvoip_power_off;
 
@@ -115,6 +100,6 @@ static struct sh_machine_vector mv_hs7751rvoip __initmv = {
        .mv_outsw               = hs7751rvoip_outsw,
        .mv_outsl               = hs7751rvoip_outsl,
 
-       .mv_init_irq            = hs7751rvoip_init_irq,
+       .mv_init_irq            = init_hs7751rvoip_IRQ,
        .mv_ioport_map          = hs7751rvoip_ioport_map,
 };
index 2dce8bd97f90408a9f2229399955664d8ddffc96..0d56fd83bcba750c07c3267e30fed4565a92064f 100644 (file)
@@ -11,7 +11,6 @@
 #include <asm/machvec.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 static struct ipr_data sh7710voipgw_ipr_map[] = {
        { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY },
index 27da88486f73bb4bf84aab19787a28ce6ac68702..9d5bfc77d0de2ad62e8346158f1b97ee15bcf7fc 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <asm/se7206.h>
 
index d07a3368f5462d4253ac1d4b6ca6c5ce6cfbab6d..318bc8a3969c2d1d03fbbbb68a8b75225287302a 100644 (file)
@@ -94,6 +94,7 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
 static struct heartbeat_data heartbeat_data = {
        .bit_pos        = heartbeat_bit_pos,
        .nr_bits        = ARRAY_SIZE(heartbeat_bit_pos),
+       .regsize        = 16,
 };
 
 static struct resource heartbeat_resources[] = {
index 20f064083cc29179131a1b181a55249705c14887..eb97dca5b736c4fce596c74c55476ace350b3424 100644 (file)
 #include <asm/machvec.h>
 #include <asm/se7722.h>
 #include <asm/io.h>
+#include <asm/heartbeat.h>
 
 /* Heartbeat */
+static struct heartbeat_data heartbeat_data = {
+       .regsize = 16,
+};
+
 static struct resource heartbeat_resources[] = {
        [0] = {
                .start  = PA_LED,
@@ -29,6 +34,9 @@ static struct resource heartbeat_resources[] = {
 static struct platform_device heartbeat_device = {
        .name           = "heartbeat",
        .id             = -1,
+       .dev = {
+               .platform_data = &heartbeat_data,
+       },
        .num_resources  = ARRAY_SIZE(heartbeat_resources),
        .resource       = heartbeat_resources,
 };
index 76e53b26a808d4a8dc976acd87d7e6711c41951d..0f08ab3b2beca4ca26d6d348e114b23fd740a087 100644 (file)
 #include <asm/machvec.h>
 #include <asm/se7780.h>
 #include <asm/io.h>
+#include <asm/heartbeat.h>
 
 /* Heartbeat */
+static struct heartbeat_data heartbeat_data = {
+       .regsize = 16,
+};
+
 static struct resource heartbeat_resources[] = {
        [0] = {
                .start  = PA_LED,
@@ -27,6 +32,9 @@ static struct resource heartbeat_resources[] = {
 static struct platform_device heartbeat_device = {
        .name           = "heartbeat",
        .id             = -1,
+       .dev = {
+               .platform_data = &heartbeat_data,
+       },
        .num_resources  = ARRAY_SIZE(heartbeat_resources),
        .resource       = heartbeat_resources,
 };
index 59fc976bfc2f99bc5c4cfd424f9b47039b59ab13..d2d2f4b6a502469006440148b0d12b83bdfc7e49 100644 (file)
@@ -2,5 +2,4 @@
 # Makefile for the SnapGear specific parts of the kernel
 #
 
-obj-y   := setup.o io.o rtc.o
-
+obj-y   := setup.o io.o
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c
deleted file mode 100644 (file)
index edb3dd9..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/****************************************************************************/
-/*
- * linux/arch/sh/boards/snapgear/rtc.c -- Secureedge5410 RTC code
- *
- *  Copyright (C) 2002  David McCullough <davidm@snapgear.com>
- *  Copyright (C) 2003  Paul Mundt <lethal@linux-sh.org>
- *
- * The SecureEdge5410 can have one of 2 real time clocks, the SH
- * built in version or the preferred external DS1302.  Here we work out
- * each to see what we have and then run with it.
- */
-/****************************************************************************/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/rtc.h>
-#include <linux/mc146818rtc.h>
-#include <asm/io.h>
-
-static int use_ds1302;
-
-/****************************************************************************/
-/*
- *     we need to implement a DS1302 driver here that can operate in
- *     conjunction with the builtin rtc driver which is already quite friendly
- */
-/*****************************************************************************/
-
-#define        RTC_CMD_READ    0x81            /* Read command */
-#define        RTC_CMD_WRITE   0x80            /* Write command */
-
-#define        RTC_ADDR_YEAR   0x06            /* Address of year register */
-#define        RTC_ADDR_DAY    0x05            /* Address of day of week register */
-#define        RTC_ADDR_MON    0x04            /* Address of month register */
-#define        RTC_ADDR_DATE   0x03            /* Address of day of month register */
-#define        RTC_ADDR_HOUR   0x02            /* Address of hour register */
-#define        RTC_ADDR_MIN    0x01            /* Address of minute register */
-#define        RTC_ADDR_SEC    0x00            /* Address of second register */
-
-#define        RTC_RESET       0x1000
-#define        RTC_IODATA      0x0800
-#define        RTC_SCLK        0x0400
-
-#define set_dirp(x)
-#define get_dirp(x) 0
-#define set_dp(x)      SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
-#define get_dp(x)      SECUREEDGE_READ_IOPORT()
-
-static void ds1302_sendbits(unsigned int val)
-{
-       int     i;
-
-       for (i = 8; (i); i--, val >>= 1) {
-               set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? RTC_IODATA : 0));
-               set_dp(get_dp() | RTC_SCLK);    // clock high
-               set_dp(get_dp() & ~RTC_SCLK);   // clock low
-       }
-}
-
-static unsigned int ds1302_recvbits(void)
-{
-       unsigned int    val;
-       int             i;
-
-       for (i = 0, val = 0; (i < 8); i++) {
-               val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
-               set_dp(get_dp() | RTC_SCLK);    // clock high
-               set_dp(get_dp() & ~RTC_SCLK);   // clock low
-       }
-       return(val);
-}
-
-static unsigned int ds1302_readbyte(unsigned int addr)
-{
-       unsigned int    val;
-       unsigned long   flags;
-
-       local_irq_save(flags);
-       set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
-       set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
-
-       set_dp(get_dp() | RTC_RESET);
-       ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
-       set_dirp(get_dirp() & ~RTC_IODATA);
-       val = ds1302_recvbits();
-       set_dp(get_dp() & ~RTC_RESET);
-       local_irq_restore(flags);
-
-       return(val);
-}
-
-static void ds1302_writebyte(unsigned int addr, unsigned int val)
-{
-       unsigned long   flags;
-
-       local_irq_save(flags);
-       set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
-       set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
-       set_dp(get_dp() | RTC_RESET);
-       ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
-       ds1302_sendbits(val);
-       set_dp(get_dp() & ~RTC_RESET);
-       local_irq_restore(flags);
-}
-
-static void ds1302_reset(void)
-{
-       unsigned long   flags;
-       /* Hardware dependent reset/init */
-       local_irq_save(flags);
-       set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
-       set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
-       local_irq_restore(flags);
-}
-
-/*****************************************************************************/
-
-static inline int bcd2int(int val)
-{
-       return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
-}
-
-static inline int int2bcd(int val)
-{
-       return(((val / 10) << 4) + (val % 10));
-}
-
-/*****************************************************************************/
-/*
- *     Write and Read some RAM in the DS1302,  if it works assume it's there
- *     Otherwise use the SH4 internal RTC
- */
-
-void snapgear_rtc_gettimeofday(struct timespec *);
-int snapgear_rtc_settimeofday(const time_t);
-
-void __init secureedge5410_rtc_init(void)
-{
-       unsigned char *test = "snapgear";
-       int i;
-
-       ds1302_reset();
-
-       use_ds1302 = 1;
-
-       for (i = 0; test[i]; i++)
-               ds1302_writebyte(32 + i, test[i]);
-
-       for (i = 0; test[i]; i++)
-               if (ds1302_readbyte(32 + i) != test[i]) {
-                       use_ds1302 = 0;
-                       break;
-               }
-
-       if (use_ds1302) {
-               rtc_sh_get_time = snapgear_rtc_gettimeofday;
-               rtc_sh_set_time = snapgear_rtc_settimeofday;
-       }
-               
-       printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
-}
-
-/****************************************************************************/
-/*
- *     our generic interface that chooses the correct code to use
- */
-
-void snapgear_rtc_gettimeofday(struct timespec *ts)
-{
-       unsigned int sec, min, hr, day, mon, yr;
-
-       if (!use_ds1302)
-               return;
-
-       sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
-       min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
-       hr  = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
-       day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
-       mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
-       yr  = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
-
-bad_time:
-       if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
-           hr > 23 || min > 59 || sec > 59) {
-               printk(KERN_ERR
-                      "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n");
-               ds1302_writebyte(RTC_ADDR_MIN,  min = 0);
-               ds1302_writebyte(RTC_ADDR_HOUR, hr  = 0);
-               ds1302_writebyte(RTC_ADDR_DAY,        7);
-               ds1302_writebyte(RTC_ADDR_DATE, day = 1);
-               ds1302_writebyte(RTC_ADDR_MON,  mon = 1);
-               ds1302_writebyte(RTC_ADDR_YEAR, yr  = 0);
-               ds1302_writebyte(RTC_ADDR_SEC,  sec = 0);
-       }
-
-       ts->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec);
-       if (ts->tv_sec < 0) {
-#if 0
-               printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec);
-#endif
-               yr = 100;
-               goto bad_time;
-       }
-       ts->tv_nsec = 0;
-}
-
-int snapgear_rtc_settimeofday(const time_t secs)
-{
-       int retval = 0;
-       int real_seconds, real_minutes, cmos_minutes;
-       unsigned long nowtime;
-
-       if (!use_ds1302)
-               return 0;
-
-/*
- *     This is called direct from the kernel timer handling code.
- *     It is supposed to synchronize the kernel clock to the RTC.
- */
-
-       nowtime = secs;
-
-       /* STOP RTC */
-       ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
-
-       cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
-
-       /*
-        * since we're only adjusting minutes and seconds,
-        * don't interfere with hour overflow. This avoids
-        * messing with unknown time zones but requires your
-        * RTC not to be off by more than 15 minutes
-        */
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-               real_minutes += 30;     /* correct for half hour time zone */
-       real_minutes %= 60;
-
-       if (abs(real_minutes - cmos_minutes) < 30) {
-               ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes));
-               ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds));
-       } else {
-               printk(KERN_WARNING
-                      "SnapGear RTC: can't update from %d to %d\n",
-                      cmos_minutes, real_minutes);
-               retval = -1;
-       }
-
-       /* START RTC */
-       ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
-       return(0);
-}
-
-unsigned char secureedge5410_cmos_read(int addr)
-{
-       unsigned char val = 0;
-
-       if (!use_ds1302)
-               return(__CMOS_READ(addr, w));
-
-       switch(addr) {
-       case RTC_SECONDS:       val = ds1302_readbyte(RTC_ADDR_SEC);  break;
-       case RTC_SECONDS_ALARM:                                       break;
-       case RTC_MINUTES:       val = ds1302_readbyte(RTC_ADDR_MIN);  break;
-       case RTC_MINUTES_ALARM:                                       break;
-       case RTC_HOURS:         val = ds1302_readbyte(RTC_ADDR_HOUR); break;
-       case RTC_HOURS_ALARM:                                         break;
-       case RTC_DAY_OF_WEEK:   val = ds1302_readbyte(RTC_ADDR_DAY);  break;
-       case RTC_DAY_OF_MONTH:  val = ds1302_readbyte(RTC_ADDR_DATE); break;
-       case RTC_MONTH:         val = ds1302_readbyte(RTC_ADDR_MON);  break;
-       case RTC_YEAR:          val = ds1302_readbyte(RTC_ADDR_YEAR); break;
-       case RTC_REG_A:         /* RTC_FREQ_SELECT */                 break;
-       case RTC_REG_B:         /* RTC_CONTROL */                     break;
-       case RTC_REG_C:         /* RTC_INTR_FLAGS */                  break;
-       case RTC_REG_D:         val = RTC_VRT /* RTC_VALID */;        break;
-       default:                                                      break;
-       }
-
-       return(val);
-}
-
-void secureedge5410_cmos_write(unsigned char val, int addr)
-{
-       if (!use_ds1302) {
-               __CMOS_WRITE(val, addr, w);
-               return;
-       }
-
-       switch(addr) {
-       case RTC_SECONDS:       ds1302_writebyte(RTC_ADDR_SEC, val);  break;
-       case RTC_SECONDS_ALARM:                                       break;
-       case RTC_MINUTES:       ds1302_writebyte(RTC_ADDR_MIN, val);  break;
-       case RTC_MINUTES_ALARM:                                       break;
-       case RTC_HOURS:         ds1302_writebyte(RTC_ADDR_HOUR, val); break;
-       case RTC_HOURS_ALARM:                                         break;
-       case RTC_DAY_OF_WEEK:   ds1302_writebyte(RTC_ADDR_DAY, val);  break;
-       case RTC_DAY_OF_MONTH:  ds1302_writebyte(RTC_ADDR_DATE, val); break;
-       case RTC_MONTH:         ds1302_writebyte(RTC_ADDR_MON, val);  break;
-       case RTC_YEAR:          ds1302_writebyte(RTC_ADDR_YEAR, val); break;
-       case RTC_REG_A:         /* RTC_FREQ_SELECT */                 break;
-       case RTC_REG_B:         /* RTC_CONTROL */                     break;
-       case RTC_REG_C:         /* RTC_INTR_FLAGS */                  break;
-       case RTC_REG_D:         /* RTC_VALID */                       break;
-       default:                                                      break;
-       }
-}
index 2b594f6000022c9904ea9df0a9ab1aabb8483328..7022483f98e8d8f6e73a0e6d6dbf99b3f05e9b99 100644 (file)
 #include <asm/snapgear.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/rtc.h>
 #include <asm/cpu/timer.h>
 
-extern void secureedge5410_rtc_init(void);
-extern void pcibios_init(void);
-
-/****************************************************************************/
 /*
  * EraseConfig handling functions
  */
 
 static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
 {
-       volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000;
+       (void)ctrl_inb(0xb8000000);     /* dummy read */
 
        printk("SnapGear: erase switch interrupt!\n");
 
@@ -75,20 +70,11 @@ static void __init init_snapgear_IRQ(void)
        plat_irq_setup_pins(IRQ_MODE_IRQ);
 }
 
-/*
- * Initialize the board
- */
-static void __init snapgear_setup(char **cmdline_p)
-{
-       board_time_init = secureedge5410_rtc_init;
-}
-
 /*
  * The Machine Vector
  */
 static struct sh_machine_vector mv_snapgear __initmv = {
        .mv_name                = "SnapGear SecureEdge5410",
-       .mv_setup               = snapgear_setup,
        .mv_nr_irqs             = 72,
 
        .mv_inb                 = snapgear_inb,
index 4c5ffdcd55b675aead50a32aaffe86c095ce8456..1b0f5be01d10af623d497bf9a19d0063302a74e9 100644 (file)
@@ -39,7 +39,7 @@ KERNEL_LOAD   := $(shell /bin/bash -c 'printf "0x%8x" \
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
-                  -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \
+                  -C none -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \
                   -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
 $(obj)/uImage: $(obj)/zImage FORCE
index a106dd9db98639945396f06e8a6c4c1f5bc7e4c6..f7de4076e242de1c30097344d711389b67ab5637 100644 (file)
@@ -1,2 +1,4 @@
 obj-$(CONFIG_HD64461)  += hd64461.o
 obj-$(CONFIG_HD64465)  += hd64465/
+
+EXTRA_CFLAGS += -Werror
index 085de72fd327b8d69cacd8eaecfbe06aaa71442f..f73963cb3744d0635ce8484ac3fa0315df67b6a6 100644 (file)
@@ -6,3 +6,4 @@ obj-y   := irq.o setup.o
 
 obj-$(CONFIG_USB_OHCI_HCD)     += consistent.o
 
+EXTRA_CFLAGS += -Werror
index 2f65ac72f48ae7b1ee931ed79861c14dc373910a..fba6b5ba0b3a6519ecdf58437dc5868e59d21e53 100644 (file)
@@ -5,7 +5,6 @@
 obj-y                                  += pci.o
 obj-$(CONFIG_PCI_AUTO)                 += pci-auto.o
 
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)     += pci-st40.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)       += pci-sh7751.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751R)      += pci-sh7751.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)       += pci-sh7780.o ops-sh4.o
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
deleted file mode 100644 (file)
index 0814a5a..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/* 
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.                            
- *
- * Support functions for the ST40 PCI hardware.
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>   /* irqreturn_t */
-
-#include "pci-st40.h"
-
-/* This is in P2 of course */
-#define ST40PCI_BASE_ADDRESS     (0xb0000000)
-#define ST40PCI_MEM_ADDRESS      (ST40PCI_BASE_ADDRESS+0x0)
-#define ST40PCI_IO_ADDRESS       (ST40PCI_BASE_ADDRESS+0x06000000)
-#define ST40PCI_REG_ADDRESS      (ST40PCI_BASE_ADDRESS+0x07000000)
-
-#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
-#define ST40PCI_REG_INDEXED(reg, index)                                \
-       (ST40PCI_REG(reg##0) +                                  \
-         ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
-
-#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_INDEXED(reg, index, val)                         \
-        writel((val), ST40PCI_REG_INDEXED(reg, index));
-
-#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
-#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
-#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
-
-#define ST40PCI_SERR_IRQ       64
-#define ST40PCI_ERR_IRQ                65
-
-
-/* Macros to extract PLL params */
-#define PLL_MDIV(reg)  ( ((unsigned)reg) & 0xff )
-#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
-#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
-#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
-
-/* Build up the appropriate settings */
-#define PLL_SET(mdiv,ndiv,pdiv,setup) \
-( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
-
-#define PLLPCICR (0xbb040000+0x10)
-
-#define PLLPCICR_POWERON (1<<28)
-#define PLLPCICR_OUT_EN (1<<29)
-#define PLLPCICR_LOCKSELECT (1<<30)
-#define PLLPCICR_LOCK (1<<31)
-
-
-#define PLL_25MHZ 0x793c8512
-#define PLL_33MHZ PLL_SET(18,88,3,295)
-
-static void pci_set_rbar_region(unsigned int region,     unsigned long localAddr,
-                        unsigned long pciOffset, unsigned long regionSize);
-
-static __init void SetPCIPLL(void)
-{
-       {
-               /* Lets play with the PLL values */
-               unsigned long pll1cr1;
-               unsigned long mdiv, ndiv, pdiv;
-               unsigned long muxcr;
-               unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
-               unsigned int freq;
-
-#define CLKGENA            0xbb040000
-#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
-               pll1cr1 = ctrl_inl(PLLPCICR);
-               printk("PLL1CR1 %08lx\n", pll1cr1);
-               mdiv = PLL_MDIV(pll1cr1);
-               ndiv = PLL_NDIV(pll1cr1);
-               pdiv = PLL_PDIV(pll1cr1);
-               printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
-               freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
-               printk("PLL freq %dMHz\n", freq);
-               muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
-               printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
-       }
-}
-
-
-struct pci_err {
-  unsigned mask;
-  const char *error_string;
-};
-
-static struct pci_err int_error[]={
-  { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
-  { INT_TTADI,  "TTADI: Illegal byte enable in I/O transfer"},
-  { INT_TMTO,   "TMTO: Target memory read/write timeout"},
-  { INT_MDEI,   "MDEI: Master function disable error"},
-  { INT_APEDI,  "APEDI: Address parity error"},
-  { INT_SDI,    "SDI: SERR detected"},
-  { INT_DPEITW, "DPEITW: Data parity error target write"},
-  { INT_PEDITR, "PEDITR: PERR detected"},
-  { INT_TADIM,  "TADIM: Target abort detected"},
-  { INT_MADIM,  "MADIM: Master abort detected"},
-  { INT_MWPDI,  "MWPDI: PERR from target at data write"},
-  { INT_MRDPEI, "MRDPEI: Master read data parity error"}
-};
-#define NUM_PCI_INT_ERRS ARRAY_SIZE(int_error)
-
-static struct pci_err aint_error[]={
-  { AINT_MBI,   "MBI: Master broken"},
-  { AINT_TBTOI, "TBTOI: Target bus timeout"},
-  { AINT_MBTOI, "MBTOI: Master bus timeout"},
-  { AINT_TAI,   "TAI: Target abort"},
-  { AINT_MAI,   "MAI: Master abort"},
-  { AINT_RDPEI, "RDPEI: Read data parity"},
-  { AINT_WDPE,  "WDPE: Write data parity"}
-};
-
-#define NUM_PCI_AINT_ERRS ARRAY_SIZE(aint_error)
-
-static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
-{
-  int i;
-
-  for(i=0;i<num_errors;i++) {
-    if(reg & error[i].mask) {
-      printk("%s\n",error[i].error_string);
-    }
-  }
-
-}
-
-
-static char * pci_commands[16]={
-       "Int Ack",
-       "Special Cycle",
-       "I/O Read",
-       "I/O Write",
-       "Reserved",
-       "Reserved",
-       "Memory Read",
-       "Memory Write",
-       "Reserved",
-       "Reserved",
-       "Configuration Read",
-       "Configuration Write",
-       "Memory Read Multiple",
-       "Dual Address Cycle",
-       "Memory Read Line",
-       "Memory Write-and-Invalidate"
-};
-
-static irqreturn_t st40_pci_irq(int irq, void *dev_instance)
-{
-       unsigned pci_int, pci_air, pci_cir, pci_aint;
-       static int count=0;
-
-
-       pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
-       pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
-
-       /* Reset state to stop multiple interrupts */
-        ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
-
-
-       if(++count>1) return IRQ_HANDLED;
-
-       printk("** PCI ERROR **\n");
-
-        if(pci_int) {
-               printk("** INT register status\n");
-               print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
-       }
-
-        if(pci_aint) {
-               printk("** AINT register status\n");
-               print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
-       }
-
-       printk("** Address and command info\n");
-
-       printk("** Command  %s : Address 0x%x\n",
-              pci_commands[pci_cir&0xf],pci_air);
-
-       if(pci_cir&CIR_PIOTEM) {
-               printk("CIR_PIOTEM:PIO transfer error for master\n");
-       }
-        if(pci_cir&CIR_RWTET) {
-               printk("CIR_RWTET:Read/Write transfer error for target\n");
-       }
-
-       return IRQ_HANDLED;
-}
-
-
-/* Rounds a number UP to the nearest power of two. Used for
- * sizing the PCI window.
- */
-static u32 r2p2(u32 num)
-{
-       int i = 31;
-       u32 tmp = num;
-
-       if (num == 0)
-               return 0;
-
-       do {
-               if (tmp & (1 << 31))
-                       break;
-               i--;
-               tmp <<= 1;
-       } while (i >= 0);
-
-       tmp = 1 << i;
-       /* If the original number isn't a power of 2, round it up */
-       if (tmp != num)
-               tmp <<= 1;
-
-       return tmp;
-}
-
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
-       int i;
-
-       /*
-        * PCI IDE controllers use non-standard I/O port decoding, respect it.
-        */
-       if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
-               return;
-       printk("PCI: IDE base address fixup for %s\n", pci_name(d));
-       for(i=0; i<4; i++) {
-               struct resource *r = &d->resource[i];
-               if ((r->start & ~0x80) == 0x374) {
-                       r->start |= 2;
-                       r->end = r->start;
-               }
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
-
-int __init st40pci_init(unsigned memStart, unsigned memSize)
-{
-       u32 lsr0;
-
-       SetPCIPLL();
-
-       /* Initialises the ST40 pci subsystem, performing a reset, then programming
-        * up the address space decoders appropriately
-        */
-
-       /* Should reset core here as well methink */
-
-       ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
-
-       /* Loop while core resets */
-       while (ST40PCI_READ(CR) & CR_SOFT_RESET);
-
-       /* Switch off interrupts */
-       ST40PCI_WRITE(INTM, 0);
-       ST40PCI_WRITE(AINT, 0);
-
-       /* Now, lets reset all the cards on the bus with extreme prejudice */
-       ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
-       udelay(250);
-
-       /* Set bus active, take it out of reset */
-       ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
-
-       /* The PCI spec says that no access must be made to the bus until 1 second
-        * after reset. This seem ludicrously long, but some delay is needed here
-        */
-       mdelay(1000);
-
-       /* Switch off interrupts */
-       ST40PCI_WRITE(INTM, 0);
-       ST40PCI_WRITE(AINT, 0);
-
-       /* Allow it to be a master */
-
-       ST40PCI_WRITE_SHORT(CSR_CMD,
-                           PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-                           PCI_COMMAND_IO);
-
-       /* Access to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
-        * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
-        */
-
-
-       ST40PCI_WRITE(MBR, 0x10000000);
-       /* Always set the max size 128M (actually, it is only 96MB wide) */
-       ST40PCI_WRITE(MBMR, 0x07ff0000);
-
-       /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to 
-        * allow cards that have legacy io such as vga to function correctly. This gives a 
-        * maximum of 64K of io/space as only the bottom 16 bits of the address are copied 
-        * over to the bus  when the transaction is made. 64K of io space is more than enough
-        */
-       ST40PCI_WRITE(IOBR, 0x0);
-       /* Set up the 64K window */
-       ST40PCI_WRITE(IOBMR, 0x0);
-
-       /* Now we set up the mbars so the PCI bus can see the local memory */
-       /* Expose a 256M window starting at PCI address 0... */
-       ST40PCI_WRITE(CSR_MBAR0, 0);
-       ST40PCI_WRITE(LSR0, 0x0fff0001);
-
-       /* ... and set up the initial incoming window to expose all of RAM */
-       pci_set_rbar_region(7, memStart, memStart, memSize);
-
-       /* Maximise timeout values */
-       ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
-       ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
-       ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
-
-       ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
-
-       return 1;
-}
-
-char * __devinit pcibios_setup(char *str)
-{
-       return str;
-}
-
-
-#define SET_CONFIG_BITS(bus,devfn,where)\
-  (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
-
-#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
-
-
-static int CheckForMasterAbort(void)
-{
-       if (ST40PCI_READ(INT) & INT_MADIM) {
-               /* Should we clear config space version as well ??? */
-               ST40PCI_WRITE(INT, INT_MADIM);
-               ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
-               return 1;
-       }
-
-       return 0;
-}
-
-/* Write to config register */
-static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
-{
-       ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
-       switch (size) {
-               case 1:
-                       *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
-                       break;
-               case 2:
-                       *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
-                       break;
-               case 4:
-                       *val = ST40PCI_READ(PDR);
-                       break;
-       }
-
-       if (CheckForMasterAbort()){
-               switch (size) {
-                       case 1:
-                               *val = (u8)0xff;
-                               break;
-                       case 2:
-                               *val = (u16)0xffff;
-                               break;
-                       case 4:
-                               *val = 0xffffffff;
-                               break;
-               }
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
-{
-       ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
-
-       switch (size) {
-               case 1:
-                       ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
-                       break;
-               case 2:
-                       ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
-                       break;
-               case 4:
-                       ST40PCI_WRITE(PDR, val);
-                       break;
-       }
-
-       CheckForMasterAbort();
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops st40pci_config_ops = {
-       .read =         st40pci_read,
-       .write =        st40pci_write,
-};
-
-
-/* Everything hangs off this */
-static struct pci_bus *pci_root_bus;
-
-static int __init pcibios_init(void)
-{
-       extern unsigned long memory_start, memory_end;
-
-       printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
-
-       if (sh_mv.mv_init_pci != NULL) {
-               sh_mv.mv_init_pci();
-       }
-
-       /* The pci subsytem needs to know where memory is and how much 
-        * of it there is. I've simply made these globals. A better mechanism
-        * is probably needed.
-        */
-       st40pci_init(PHYSADDR(memory_start),
-                    PHYSADDR(memory_end) - PHYSADDR(memory_start));
-
-       if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq, 
-                        IRQF_DISABLED, "st40pci", NULL)) {
-               printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
-               return -EIO;
-       }
-
-       /* Enable the PCI interrupts on the device */
-       ST40PCI_WRITE(INTM, ~0);
-       ST40PCI_WRITE(AINT, ~0);
-
-       /* Map the io address apprioately */
-#ifdef CONFIG_HD64465
-       hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
-                        ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
-#endif
-
-       /* ok, do the scan man */
-       pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
-       pci_assign_unassigned_resources();
-
-       return 0;
-}
-subsys_initcall(pcibios_init);
-
-/*
- * Publish a region of local address space over the PCI bus
- * to other devices.
- */
-static void pci_set_rbar_region(unsigned int region,     unsigned long localAddr,
-                        unsigned long pciOffset, unsigned long regionSize)
-{
-       unsigned long mask;
-
-       if (region > 7)
-               return;
-
-       if (regionSize > (512 * 1024 * 1024))
-               return;
-
-       mask = r2p2(regionSize) - 0x10000;
-
-       /* Disable the region (in case currently in use, should never happen) */
-       ST40PCI_WRITE_INDEXED(RSR, region, 0);
-
-       /* Start of local address space to publish */
-       ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
-
-       /* Start of region in PCI address space as an offset from MBAR0 */
-       ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
-
-       /* Size of region */
-       ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
-}
-
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
deleted file mode 100644 (file)
index cf0d35b..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* 
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.                            
- *
- * Definitions for the ST40 PCI hardware.
- */
-
-#ifndef __PCI_ST40_H__
-#define __PCI_ST40_H__
-
-#define ST40PCI_VCR_STATUS    0x00
-
-#define ST40PCI_VCR_VERSION   0x08
-
-#define ST40PCI_CR            0x10
-
-#define CR_SOFT_RESET (1<<12)
-#define CR_PFCS       (1<<11)
-#define CR_PFE        (1<<9)
-#define CR_BMAM       (1<<6)
-#define CR_HOST       (1<<5)
-#define CR_CLKEN      (1<<4)
-#define CR_SOCS       (1<<3)
-#define CR_IOCS       (1<<2)
-#define CR_RSTCTL     (1<<1)
-#define CR_CFINT      (1<<0)
-#define CR_LOCK_MASK  0x5a000000
-
-
-#define ST40PCI_LSR0          0X14
-#define ST40PCI_LAR0          0x1c
-
-#define ST40PCI_INT           0x24
-#define INT_MNLTDIM           (1<<15)
-#define INT_TTADI             (1<<14)
-#define INT_TMTO              (1<<9)
-#define INT_MDEI              (1<<8)
-#define INT_APEDI             (1<<7)
-#define INT_SDI               (1<<6)
-#define INT_DPEITW            (1<<5)
-#define INT_PEDITR            (1<<4)
-#define INT_TADIM             (1<<3)
-#define INT_MADIM             (1<<2)
-#define INT_MWPDI             (1<<1)
-#define INT_MRDPEI            (1<<0)
-
-
-#define ST40PCI_INTM          0x28
-#define ST40PCI_AIR           0x2c
-
-#define ST40PCI_CIR           0x30
-#define CIR_PIOTEM            (1<<31)
-#define CIR_RWTET             (1<<26)
-
-#define ST40PCI_AINT          0x40
-#define AINT_MBI              (1<<13)
-#define AINT_TBTOI            (1<<12)
-#define AINT_MBTOI            (1<<11)
-#define AINT_TAI              (1<<3)
-#define AINT_MAI              (1<<2)
-#define AINT_RDPEI            (1<<1)
-#define AINT_WDPE             (1<<0)
-
-#define ST40PCI_AINTM         0x44
-#define ST40PCI_BMIR          0x48
-#define ST40PCI_PAR           0x4c
-#define ST40PCI_MBR           0x50
-#define ST40PCI_IOBR          0x54
-#define ST40PCI_PINT          0x58
-#define ST40PCI_PINTM         0x5c
-#define ST40PCI_MBMR          0x70
-#define ST40PCI_IOBMR         0x74
-#define ST40PCI_PDR           0x78
-
-/* H8 specific registers start here */
-#define ST40PCI_WCBAR         0x7c
-#define ST40PCI_LOCCFG_UNLOCK 0x34
-
-#define ST40PCI_RBAR0         0x100
-#define ST40PCI_RSR0          0x104
-#define ST40PCI_RLAR0         0x108
-
-#define ST40PCI_RBAR1         0x110
-#define ST40PCI_RSR1          0x114
-#define ST40PCI_RLAR1         0x118
-
-
-#define ST40PCI_RBAR2         0x120
-#define ST40PCI_RSR2          0x124
-#define ST40PCI_RLAR2         0x128
-
-#define ST40PCI_RBAR3         0x130
-#define ST40PCI_RSR3          0x134
-#define ST40PCI_RLAR3         0x138
-
-#define ST40PCI_RBAR4         0x140
-#define ST40PCI_RSR4          0x144
-#define ST40PCI_RLAR4         0x148
-
-#define ST40PCI_RBAR5         0x150
-#define ST40PCI_RSR5          0x154
-#define ST40PCI_RLAR5         0x158
-
-#define ST40PCI_RBAR6         0x160
-#define ST40PCI_RSR6          0x164
-#define ST40PCI_RLAR6         0x168
-
-#define ST40PCI_RBAR7         0x170
-#define ST40PCI_RSR7          0x174
-#define ST40PCI_RLAR7         0x178
-
-
-#define ST40PCI_RBAR(n)      (0x100+(0x10*(n)))
-#define ST40PCI_RSR(n)       (0x104+(0x10*(n)))
-#define ST40PCI_RLAR(n)      (0x108+(0x10*(n)))
-
-#define ST40PCI_PERF               0x80
-#define PERF_MASTER_WRITE_POSTING  (1<<4)
-/* H8 specific registers end here */
-
-
-/* These are configs space registers */
-#define ST40PCI_CSR_VID               0x10000
-#define ST40PCI_CSR_DID               0x10002
-#define ST40PCI_CSR_CMD               0x10004
-#define ST40PCI_CSR_STATUS            0x10006
-#define ST40PCI_CSR_MBAR0             0x10010
-#define ST40PCI_CSR_TRDY              0x10040
-#define ST40PCI_CSR_RETRY             0x10041
-#define ST40PCI_CSR_MIT               0x1000d
-
-#define ST40_IO_ADDR 0xb6000000       
-
-#endif /* __PCI_ST40_H__ */
index 1f141a8ba17c09726d026161c9579c835d9896d9..4b81d9c47b0093cdf1b097ec4d8a41c91f826241 100644 (file)
@@ -10,7 +10,6 @@ obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \
 
 obj-y                          += cpu/ timers/
 obj-$(CONFIG_VSYSCALL)         += vsyscall/
-
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_CF_ENABLER)       += cf-enabler.o
 obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
@@ -22,3 +21,5 @@ obj-$(CONFIG_KEXEC)           += machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
+
+EXTRA_CFLAGS += -Werror
index 2b2a9e02fb752d1e358f41787369cb8731412501..b6abf38d3a8d158e720e653a36d6383f1308a59f 100644 (file)
@@ -46,7 +46,7 @@ ENTRY(exception_handling_table)
        .long   exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
 ENTRY(nmi_slot)
 #if defined (CONFIG_KGDB_NMI)
-       .long   debug_enter     /* 1C0 */       ! Allow trap to debugger
+       .long   kgdb_handle_exception   /* 1C0 */       ! Allow trap to debugger
 #else
        .long   exception_none  /* 1C0 */       ! Not implemented yet
 #endif
index 21375d777e9993687da782446a3ad27e96a3b2c3..bc9c28a69bf1933bfa2fb2ceee13c370c94ff3ef 100644 (file)
@@ -139,14 +139,6 @@ int __init detect_cpu_and_cache_system(void)
                boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
                                          CPU_HAS_LLSC;
                break;
-       case 0x8000:
-               boot_cpu_data.type = CPU_ST40RA;
-               boot_cpu_data.flags |= CPU_HAS_FPU;
-               break;
-       case 0x8100:
-               boot_cpu_data.type = CPU_ST40GX1;
-               boot_cpu_data.flags |= CPU_HAS_FPU;
-               break;
        case 0x700:
                boot_cpu_data.type = CPU_SH4_501;
                boot_cpu_data.icache.ways = 2;
index 348da194ec9996617a164133ec49c9cc2a049d0a..0586bc62ad96506567549d9fe54f72837407c7a3 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
-#include <linux/irq.h>
 #include <asm/processor.h>
 #include <asm/machvec.h>
 #include <asm/uaccess.h>
index 2fdc700dfd6e72be2bed5e8c4db4489967781d6c..d453c3a1c79f485377a870456cef74488d601e27 100644 (file)
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
+#include <linux/module.h>
 #include <asm/system.h>
 #include <asm/cacheflush.h>
 #include <asm/current.h>
@@ -116,7 +117,9 @@ kgdb_debug_hook_t *kgdb_debug_hook;
 kgdb_bus_error_hook_t *kgdb_bus_err_hook;
 
 int (*kgdb_getchar)(void);
+EXPORT_SYMBOL_GPL(kgdb_getchar);
 void (*kgdb_putchar)(int);
+EXPORT_SYMBOL_GPL(kgdb_putchar);
 
 static void put_debug_char(int c)
 {
@@ -136,7 +139,7 @@ static int get_debug_char(void)
 #define NUMREGBYTES (MAXREG*4)
 #define OUTBUFMAX (NUMREGBYTES*2+512)
 
-enum regs {
+enum {
        R0 = 0, R1,  R2,  R3,   R4,   R5,  R6, R7,
        R8, R9, R10, R11, R12,  R13,  R14, R15,
        PC, PR, GBR, VBR, MACH, MACL, SR,
@@ -176,9 +179,13 @@ int kgdb_nofault;          /* Boolean to ignore bus errs (i.e. in GDB) */
 
 /* SCI/UART settings, used in kgdb_console_setup() */
 int  kgdb_portnum = CONFIG_KGDB_DEFPORT;
+EXPORT_SYMBOL_GPL(kgdb_portnum);
 int  kgdb_baud = CONFIG_KGDB_DEFBAUD;
+EXPORT_SYMBOL_GPL(kgdb_baud);
 char kgdb_parity = CONFIG_KGDB_DEFPARITY;
+EXPORT_SYMBOL_GPL(kgdb_parity);
 char kgdb_bits = CONFIG_KGDB_DEFBITS;
+EXPORT_SYMBOL_GPL(kgdb_bits);
 
 /* Jump buffer for setjmp/longjmp */
 static jmp_buf rem_com_env;
index 0b8c45d53a47ba5c75fa99a3a287d5a6b61d9887..4156aac8c27d2113b1211d97178269a58aec2d9f 100644 (file)
@@ -303,7 +303,6 @@ static const char *cpu_name[] = {
        [CPU_SH7750S]   = "SH7750S",    [CPU_SH7750R]   = "SH7750R",
        [CPU_SH7751]    = "SH7751",     [CPU_SH7751R]   = "SH7751R",
        [CPU_SH7760]    = "SH7760",
-       [CPU_ST40RA]    = "ST40RA",     [CPU_ST40GX1]   = "ST40GX1",
        [CPU_SH4_202]   = "SH4-202",    [CPU_SH4_501]   = "SH4-501",
        [CPU_SH7770]    = "SH7770",     [CPU_SH7780]    = "SH7780",
        [CPU_SH7781]    = "SH7781",     [CPU_SH7343]    = "SH7343",
index 548e4285b37569e82e731dd5ba1f8e79dff45739..e1a6de9088b5bde648fcae3f8ab0e9fcf89cb158 100644 (file)
@@ -106,7 +106,6 @@ DECLARE_EXPORT(__movmem);
 DECLARE_EXPORT(__movstr);
 #endif
 
-#ifdef CONFIG_CPU_SH4
 #if __GNUC__ == 4
 DECLARE_EXPORT(__movmem_i4_even);
 DECLARE_EXPORT(__movmem_i4_odd);
@@ -126,7 +125,6 @@ DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
 DECLARE_EXPORT(__movstrSI12_i4);
 #endif /* __GNUC__ == 4 */
-#endif
 
 #if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
        defined(CONFIG_SH7705_CACHE_32KB))
index e23dd1a3fccd8f102eba02d24ac4cf3cc46fc607..9dc7b698505294001addab04ba2aecdbc82825d2 100644 (file)
@@ -9,3 +9,5 @@ memcpy-y                        := memcpy.o
 memcpy-$(CONFIG_CPU_SH4)       := memcpy-sh4.o
 
 lib-y  += $(memcpy-y)
+
+EXTRA_CFLAGS += -Werror
index cf446bbab5b08c03aa615240791ace492cfd8957..1265f204f7d1b65698027a717f95fcd52a1c70db 100644 (file)
@@ -17,7 +17,7 @@ config CPU_SH4
        bool
        select CPU_HAS_INTEVT
        select CPU_HAS_SR_RB
-       select CPU_HAS_PTEA if (!CPU_SUBTYPE_ST40 && !CPU_SH4A) || CPU_SHX2
+       select CPU_HAS_PTEA if !CPU_SH4A || CPU_SHX2
        select CPU_HAS_FPU if !CPU_SH4AL_DSP
 
 config CPU_SH4A
@@ -29,10 +29,6 @@ config CPU_SH4AL_DSP
        select CPU_SH4A
        select CPU_HAS_DSP
 
-config CPU_SUBTYPE_ST40
-       bool
-       select CPU_SH4
-
 config CPU_SHX2
        bool
 
@@ -152,21 +148,6 @@ config CPU_SUBTYPE_SH4_202
        bool "Support SH4-202 processor"
        select CPU_SH4
 
-# ST40 Processor Support
-
-config CPU_SUBTYPE_ST40STB1
-       bool "Support ST40STB1/ST40RA processors"
-       select CPU_SUBTYPE_ST40
-       help
-         Select ST40STB1 if you have a ST40RA CPU.
-         This was previously called the ST40STB1, hence the option name.
-
-config CPU_SUBTYPE_ST40GX1
-       bool "Support ST40GX1 processor"
-       select CPU_SUBTYPE_ST40
-       help
-         Select ST40GX1 if you have a ST40GX1 CPU.
-
 # SH-4A Processor Support
 
 config CPU_SUBTYPE_SH7770
index ee30fb44dfe107d1acc1e5f70292c3d57438baf3..aa44607f072d9ae771bb8de57c230027494bd0cd 100644 (file)
@@ -33,3 +33,5 @@ endif
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 obj-$(CONFIG_32BIT)            += pmb.o
 obj-$(CONFIG_NUMA)             += numa.o
+
+EXTRA_CFLAGS += -Werror
index 8a706131e521d9c03485538bc5718130a53c57a1..7a7c81ee3f01659b14f24d818c02cb4e5f525f07 100644 (file)
@@ -150,48 +150,3 @@ ENTRY(__clear_user)
        .long   8b, .Lbad_clear_user
        .long   9b, .Lbad_clear_user
 .previous
-
-#if defined(CONFIG_CPU_SH4)
-/*
- * __clear_user_page
- * @to: P3 address (with same color)
- * @orig_to: P1 address
- *
- * void __clear_user_page(void *to, void *orig_to)
- */
-
-/*
- * r0 --- scratch 
- * r4 --- to
- * r5 --- orig_to
- * r6 --- to + PAGE_SIZE
- */
-ENTRY(__clear_user_page)
-       mov.l   .Lpsz,r0
-       mov     r4,r6
-       add     r0,r6
-       mov     #0,r0
-       !
-1:     ocbi    @r5
-       add     #32,r5
-       movca.l r0,@r4
-       mov     r4,r1
-       add     #32,r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       mov.l   r0,@-r4
-       add     #28,r4
-       cmp/eq  r6,r4
-       bf/s    1b
-        ocbwb  @r1
-       !
-       rts
-        nop
-.Lpsz: .long   PAGE_SIZE
-
-#endif
-
index 3d8409daa4beafc06d762248a85230fc5e3d6524..40685018b95294ecce543f03a6127bedad77fdc2 100644 (file)
@@ -68,67 +68,6 @@ ENTRY(copy_page_slow)
        rts
         nop
 
-#if defined(CONFIG_CPU_SH4)
-/*
- * __copy_user_page
- * @to: P1 address (with same color)
- * @from: P1 address
- * @orig_to: P1 address
- *
- * void __copy_user_page(void *to, void *from, void *orig_to)
- */
-
-/*
- * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
- * r8 --- from + PAGE_SIZE
- * r9 --- orig_to
- * r10 --- to
- * r11 --- from
- */
-ENTRY(__copy_user_page)
-       mov.l   r8,@-r15
-       mov.l   r9,@-r15
-       mov.l   r10,@-r15
-       mov.l   r11,@-r15
-       mov     r4,r10
-       mov     r5,r11
-       mov     r6,r9
-       mov     r5,r8
-       mov.l   .Lpsz,r0
-       add     r0,r8
-       !
-1:     ocbi    @r9
-       add     #32,r9
-       mov.l   @r11+,r0
-       mov.l   @r11+,r1
-       mov.l   @r11+,r2
-       mov.l   @r11+,r3
-       mov.l   @r11+,r4
-       mov.l   @r11+,r5
-       mov.l   @r11+,r6
-       mov.l   @r11+,r7
-       movca.l r0,@r10
-       mov     r10,r0
-       add     #32,r10
-       mov.l   r7,@-r10
-       mov.l   r6,@-r10
-       mov.l   r5,@-r10
-       mov.l   r4,@-r10
-       mov.l   r3,@-r10
-       mov.l   r2,@-r10
-       mov.l   r1,@-r10
-       ocbwb   @r0
-       cmp/eq  r11,r8
-       bf/s    1b
-        add    #28,r10
-       !
-       mov.l   @r15+,r11
-       mov.l   @r15+,r10
-       mov.l   @r15+,r9
-       mov.l   @r15+,r8
-       rts
-        nop
-#endif
        .align 2
 .Lpsz: .long   PAGE_SIZE
 /*
index 25f5c6f6821def36b1f796a66bb969f62044daa3..8c7a9ca79879aef2de7de1f253a6e8c8b5969121 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
@@ -50,34 +52,61 @@ static inline void kunmap_coherent(struct page *page)
 void clear_user_page(void *to, unsigned long address, struct page *page)
 {
        __set_bit(PG_mapped, &page->flags);
-       if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
-               clear_page(to);
-       else {
-               void *vto = kmap_coherent(page, address);
-               __clear_user_page(vto, to);
-               kunmap_coherent(vto);
-       }
+
+       clear_page(to);
+       if ((((address & PAGE_MASK) ^ (unsigned long)to) & CACHE_ALIAS))
+               __flush_wback_region(to, PAGE_SIZE);
 }
 
-/*
- * copy_user_page
- * @to: P1 address
- * @from: P1 address
- * @address: U0 address to be mapped
- * @page: page (virt_to_page(to))
- */
-void copy_user_page(void *to, void *from, unsigned long address,
-                   struct page *page)
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                      unsigned long vaddr, void *dst, const void *src,
+                      unsigned long len)
 {
+       void *vto;
+
        __set_bit(PG_mapped, &page->flags);
-       if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
-               copy_page(to, from);
-       else {
-               void *vfrom = kmap_coherent(page, address);
-               __copy_user_page(vfrom, from, to);
-               kunmap_coherent(vfrom);
-       }
+
+       vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+       memcpy(vto, src, len);
+       kunmap_coherent(vto);
+
+       if (vma->vm_flags & VM_EXEC)
+               flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+                        unsigned long vaddr, void *dst, const void *src,
+                        unsigned long len)
+{
+       void *vfrom;
+
+       __set_bit(PG_mapped, &page->flags);
+
+       vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+       memcpy(dst, vfrom, len);
+       kunmap_coherent(vfrom);
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+                       unsigned long vaddr, struct vm_area_struct *vma)
+{
+       void *vfrom, *vto;
+
+       __set_bit(PG_mapped, &to->flags);
+
+       vto = kmap_atomic(to, KM_USER1);
+       vfrom = kmap_coherent(from, vaddr);
+       copy_page(vto, vfrom);
+       kunmap_coherent(vfrom);
+
+       if (((vaddr ^ (unsigned long)vto) & CACHE_ALIAS))
+               __flush_wback_region(vto, PAGE_SIZE);
+
+       kunmap_atomic(vto, KM_USER1);
+       /* Make sure this page is cleared on other CPU's too before using it */
+       smp_wmb();
 }
+EXPORT_SYMBOL(copy_user_highpage);
 
 /*
  * For SH-4, we have our own implementation for ptep_get_and_clear
index 1f25d9bb7538a511d3d9ff8d9d4dc88658d84b97..2efc2e79fd297019e7f207175fba437e668b7852 100644 (file)
@@ -15,3 +15,4 @@ profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091) := op_model_sh7750.o
 
 oprofile-y                             := $(DRIVER_OBJS) $(profdrvr-y)
 
+EXTRA_CFLAGS += -Werror
index ceb9458abda4bdec2415eda4925dcd618a33c32b..0761af4d2a424a77a7409e90800bd98560bcde52 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/proc_fs.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
@@ -656,9 +657,6 @@ unsigned long get_wchan(struct task_struct *p)
    */
 
 #if defined(CONFIG_SH64_PROC_ASIDS)
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-
 static int
 asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
 {
@@ -686,10 +684,8 @@ asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void
 
 static int __init register_proc_asids(void)
 {
-  create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
-  return 0;
+       create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
+       return 0;
 }
-
 __initcall(register_proc_asids);
 #endif
-
index c03101fab467443a8b6d33e9cf0111d4d48972cb..f32df3831f45168f3c3c542d044dab1e659543bc 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
 #include <linux/module.h>
-
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -242,9 +241,6 @@ DO_ERROR(12, SIGILL,  "reserved instruction", reserved_inst, current)
 
 #endif /* CONFIG_SH64_ID2815_WORKAROUND */
 
-
-#include <asm/system.h>
-
 /* Called with interrupts disabled */
 asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
 {
@@ -984,4 +980,3 @@ asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs)
        /* Clear all DEBUGINT causes */
        poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0);
 }
-
index e1e24f31aa5463c7a55e2d30ac77a3e1900d12a5..01a6756ba3718182bdd93753ad8db4c5f1f5d0e9 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/linkage.h>
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/random.h>
index 9f472a79d37e04236add3ad9138bc0de33695bd9..eeb5a2fc788d2615e47660ae7c6962ca1777126a 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
index 579871527699ed616a7a5c838be648a88884ca1a..158484bf59993dd915b6190d0ac31eeac7938404 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/mm.h>
 
 #include <asm/processor.h>
index 78caff926737b532fc3216a8b5312d2be97375df..98c468803ce35d345e72439280485fe546906ad2 100644 (file)
@@ -51,7 +51,6 @@
 #include <linux/vfs.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/ptrace.h>
-#include <linux/highuid.h>
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
index 170d6ca8de6f0e4d36b26c81ffdd0592059acfe2..cfc22d3fe54c1cdd631ff3ffe1160d73e78aec18 100644 (file)
@@ -57,7 +57,6 @@
 #include <linux/personality.h>
 
 /* For SOCKET_I */
-#include <linux/socket.h>
 #include <net/sock.h>
 #include <net/compat.h>
 
index a2cf955294c1ae89f23a4a31c93a629e735622cb..4352ee4d8dac32863bd588f47ce91ad5f2d8859c 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/jiffies.h>
 #include <linux/cpufreq.h>
 #include <linux/percpu.h>
-#include <linux/profile.h>
 #include <linux/miscdevice.h>
 #include <linux/rtc.h>
 #include <linux/kernel_stat.h>
@@ -47,7 +46,6 @@
 #include <asm/sections.h>
 #include <asm/cpudata.h>
 #include <asm/uaccess.h>
-#include <asm/prom.h>
 #include <asm/irq_regs.h>
 
 DEFINE_SPINLOCK(mostek_lock);
index 82c2ac48040da2cddf7c645fca724796a16668ad..31999bc1c8a475eec23f88f9ceeb9b63ed8da146 100644 (file)
@@ -70,9 +70,12 @@ include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 # in KBUILD_CFLAGS.  Otherwise, it would cause ld to complain about the two different
 # errnos.
 # These apply to kernelspace only.
+#
+# strip leading and trailing whitespace to make the USER_CFLAGS removal of these
+# defines more robust
 
-KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-       -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)
+KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+                        -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
 KBUILD_CFLAGS += $(KERNEL_DEFINES)
 KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
@@ -165,7 +168,7 @@ ifneq ($(KBUILD_SRC),)
        $(Q)mkdir -p $(objtree)/include/asm-um
        $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch
 else
-       $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(HEADER_ARCH) arch
+       $(Q)cd $(TOPDIR)/include/asm-um && ln -fsn ../asm-$(SUBARCH) arch
 endif
 
 $(objtree)/$(ARCH_DIR)/include:
@@ -177,7 +180,7 @@ $(ARCH_DIR)/include/sysdep: $(objtree)/$(ARCH_DIR)/include
 ifneq ($(KBUILD_SRC),)
        $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
 else
-       $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
+       $(Q)cd $(ARCH_DIR)/include && ln -fsn sysdep-$(SUBARCH) sysdep
 endif
 
 $(ARCH_DIR)/os:
@@ -185,7 +188,7 @@ $(ARCH_DIR)/os:
 ifneq ($(KBUILD_SRC),)
        $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
 else
-       $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os
+       $(Q)cd $(ARCH_DIR) && ln -fsn os-$(OS) os
 endif
 
 # Generated files
index b01dfb00e5f8a8e16e254661e9ddf91279b429ad..67290117d90924ff0dc712af68725562b574c450 100644 (file)
@@ -22,8 +22,8 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
 endif
 endif
 
-CFLAGS                 += -DCONFIG_X86_32
-AFLAGS                 += -DCONFIG_X86_32
+KBUILD_CFLAGS          += -DCONFIG_X86_32
+KBUILD_AFLAGS          += -DCONFIG_X86_32
 CONFIG_X86_32          := y
 export CONFIG_X86_32
 
index 8c01fa81a1aec094ce6f30a10ffe5f2c8eaec954..73681f14f9fc17daaf3261fcf1562e33fb71fbfb 100644 (file)
@@ -753,6 +753,7 @@ static struct mc_device net_mc = {
        .remove         = net_remove,
 };
 
+#ifdef CONFIG_INET
 static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
                              void *ptr)
 {
@@ -789,14 +790,13 @@ struct notifier_block uml_inetaddr_notifier = {
        .notifier_call          = uml_inetaddr_event,
 };
 
-static int uml_net_init(void)
+static void inet_register(void)
 {
        struct list_head *ele;
        struct uml_net_private *lp;
        struct in_device *ip;
        struct in_ifaddr *in;
 
-       mconsole_register_dev(&net_mc);
        register_inetaddr_notifier(&uml_inetaddr_notifier);
 
        /* Devices may have been opened already, so the uml_inetaddr_notifier
@@ -816,7 +816,17 @@ static int uml_net_init(void)
                }
        }
        spin_unlock(&opened_lock);
+}
+#else
+static inline void inet_register(void)
+{
+}
+#endif
 
+static int uml_net_init(void)
+{
+       mconsole_register_dev(&net_mc);
+       inet_register();
        return 0;
 }
 
index e184b44b1011e45bce17a0cb61460f2747bbdc8f..7e6cdde62ead261e6140c30cc51d8517e0b65aac 100644 (file)
@@ -705,7 +705,7 @@ static int ubd_add(int n, char **error_out)
        ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
 
        INIT_LIST_HEAD(&ubd_dev->restart);
-       sg_init_table(&ubd_dev->sg, MAX_SG);
+       sg_init_table(ubd_dev->sg, MAX_SG);
 
        err = -ENOMEM;
        ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
index 99033ff28a78872996f64cc5e3a732ef6022d664..1723fac6f40d1eb45329133e4d9146666769076a 100644 (file)
@@ -1,11 +1,13 @@
 /* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
 #ifndef __USER_H__
 #define __USER_H__
 
+#include "uml-config.h"
+
 /*
  * The usual definition - copied here because the kernel provides its own,
  * fancier, type-safe, definition.  Using that one would require
 
 extern void panic(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
+
+#ifdef UML_CONFIG_PRINTK
 extern int printk(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
+#else
+static inline int printk(const char *fmt, ...)
+{
+       return 0;
+}
+#endif
+
 extern void schedule(void);
 extern int in_aton(char *str);
 extern int open_gdb_chan(void);
index 70c2d625b0702a284c5b72c65fa3eb4c907e4428..ba11ccd6a8a3f72e4ab641a5f79f21a740a1ad0a 100644 (file)
@@ -347,14 +347,15 @@ int um_request_irq(unsigned int irq, int fd, int type,
 {
        int err;
 
-       err = request_irq(irq, handler, irqflags, devname, dev_id);
-       if (err)
-               return err;
-
-       if (fd != -1)
+       if (fd != -1) {
                err = activate_fd(irq, fd, type, dev_id);
-       return err;
+               if (err)
+                       return err;
+       }
+
+       return request_irq(irq, handler, irqflags, devname, dev_id);
 }
+
 EXPORT_SYMBOL(um_request_irq);
 EXPORT_SYMBOL(reactivate_fd);
 
index d119f4f7d8971ee7576e6c7db57c59bd3d4704a5..8d07a7acb909c707bd5ec4d0bcf3ce6d53045db1 100644 (file)
@@ -3,7 +3,6 @@
 #include <sys/mman.h>
 #include <sys/time.h>
 #include <asm/unistd.h>
-#include <asm/page.h>
 #include "as-layout.h"
 #include "ptrace_user.h"
 #include "skas.h"
index b542a3a021bf8cee34276bd5fa4e73f599cee759..f834627586272b80c4702b499553ac24c296c9dd 100644 (file)
@@ -496,8 +496,7 @@ int os_rcv_fd(int fd, int *helper_pid_out)
        n = recvmsg(fd, &msg, 0);
        if(n < 0)
                return -errno;
-
-       else if(n != sizeof(iov.iov_len))
+       else if(n != iov.iov_len)
                *helper_pid_out = -1;
 
        cmsg = CMSG_FIRSTHDR(&msg);
similarity index 74%
rename from arch/x86/Kconfig.i386
rename to arch/x86/Kconfig
index 7331efe891a7cb5d5e0b9d4f3cafa8339b1cab00..368864dfe6eb635ef210f046ec351f04e96f42ef 100644 (file)
@@ -1,18 +1,24 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
+# x86 configuration
+mainmenu "Linux Kernel Configuration for x86"
 
-mainmenu "Linux Kernel Configuration"
+# Select 32 or 64 bit
+config 64BIT
+       bool "64-bit kernel" if ARCH = "x86"
+       default ARCH = "x86_64"
+       help
+         Say yes to build a 64-bit kernel - formerly known as x86_64
+         Say no to build a 32-bit kernel - formerly known as i386
 
 config X86_32
+       def_bool !64BIT
+
+config X86_64
+       def_bool 64BIT
+
+### Arch settings
+config X86
        bool
        default y
-       help
-         This is Linux's home port.  Linux was originally native to the Intel
-         386, and runs on all the later x86 processors including the Intel
-         486, 586, Pentiums, and various instruction-set-compatible chips by
-         AMD, Cyrix, and others.
 
 config GENERIC_TIME
        bool
@@ -33,7 +39,7 @@ config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS_BROADCAST
        bool
        default y
-       depends on X86_LOCAL_APIC
+       depends on X86_64 || (X86_32 && X86_LOCAL_APIC)
 
 config LOCKDEP_SUPPORT
        bool
@@ -47,10 +53,6 @@ config SEMAPHORE_SLEEPERS
        bool
        default y
 
-config X86
-       bool
-       default y
-
 config MMU
        bool
        default y
@@ -61,7 +63,7 @@ config ZONE_DMA
 
 config QUICKLIST
        bool
-       default y
+       default X86_32
 
 config SBUS
        bool
@@ -91,6 +93,76 @@ config DMI
        bool
        default y
 
+config RWSEM_GENERIC_SPINLOCK
+       def_bool !X86_XADD
+
+config RWSEM_XCHGADD_ALGORITHM
+       def_bool X86_XADD
+
+config ARCH_HAS_ILOG2_U32
+       def_bool n
+
+config ARCH_HAS_ILOG2_U64
+       def_bool n
+
+config GENERIC_CALIBRATE_DELAY
+       def_bool y
+
+config GENERIC_TIME_VSYSCALL
+       bool
+       default X86_64
+
+
+
+
+
+config ZONE_DMA32
+       bool
+       default X86_64
+
+config ARCH_POPULATES_NODE_MAP
+       def_bool y
+
+config AUDIT_ARCH
+       bool
+       default X86_64
+
+# Use the generic interrupt handling code in kernel/irq/:
+config GENERIC_HARDIRQS
+       bool
+       default y
+
+config GENERIC_IRQ_PROBE
+       bool
+       default y
+
+config GENERIC_PENDING_IRQ
+       bool
+       depends on GENERIC_HARDIRQS && SMP
+       default y
+
+config X86_SMP
+       bool
+       depends on X86_32 && SMP && !X86_VOYAGER
+       default y
+
+config X86_HT
+       bool
+       depends on SMP && !(X86_VISWS || X86_VOYAGER || MK8)
+       default y
+
+config X86_BIOS_REBOOT
+       bool
+       depends on X86_32 && !(X86_VISWS || X86_VOYAGER)
+       default y
+
+config X86_TRAMPOLINE
+       bool
+       depends on X86_SMP || (X86_VOYAGER && SMP)
+       default y
+
+config KTIME_SCALAR
+       def_bool X86_32
 source "init/Kconfig"
 
 menu "Processor type and features"
@@ -137,6 +209,7 @@ config X86_PC
 
 config X86_ELAN
        bool "AMD Elan"
+       depends on X86_32
        help
          Select this for an AMD Elan processor.
 
@@ -146,6 +219,7 @@ config X86_ELAN
 
 config X86_VOYAGER
        bool "Voyager (NCR)"
+       depends on X86_32
        select SMP if !BROKEN
        help
          Voyager is an MCA-based 32-way capable SMP architecture proprietary
@@ -160,6 +234,7 @@ config X86_NUMAQ
        bool "NUMAQ (IBM/Sequent)"
        select SMP
        select NUMA
+       depends on X86_32
        help
          This option is used for getting Linux to run on a (IBM/Sequent) NUMA
          multiquad box. This changes the way that processors are bootstrapped,
@@ -169,7 +244,7 @@ config X86_NUMAQ
 
 config X86_SUMMIT
        bool "Summit/EXA (IBM x440)"
-       depends on SMP
+       depends on X86_32 && SMP
        help
          This option is needed for IBM systems that use the Summit/EXA chipset.
          In particular, it is needed for the x440.
@@ -179,7 +254,7 @@ config X86_SUMMIT
 
 config X86_BIGSMP
        bool "Support for other sub-arch SMP systems with more than 8 CPUs"
-       depends on SMP
+       depends on X86_32 && SMP
        help
          This option is needed for the systems that have more than 8 CPUs
          and if the system is not of any sub-arch type above.
@@ -188,6 +263,7 @@ config X86_BIGSMP
 
 config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
+       depends on X86_32
        help
          The SGI Visual Workstation series is an IA32-based workstation
          based on SGI systems chips with some legacy PC hardware attached.
@@ -199,6 +275,7 @@ config X86_VISWS
 
 config X86_GENERICARCH
        bool "Generic architecture (Summit, bigsmp, ES7000, default)"
+       depends on X86_32
        help
           This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
          It is intended for a generic binary kernel.
@@ -206,18 +283,27 @@ config X86_GENERICARCH
 
 config X86_ES7000
        bool "Support for Unisys ES7000 IA32 series"
-       depends on SMP
+       depends on X86_32 && SMP
        help
          Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
          supposed to run on an IA32-based Unisys ES7000 system.
          Only choose this option if you have such a system, otherwise you
          should say N here.
 
+config X86_VSMP
+       bool "Support for ScaleMP vSMP"
+       depends on X86_64 && PCI
+        help
+         Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
+         supposed to run on these EM64T-based machines.  Only choose this option
+         if you have one of these machines.
+
 endchoice
 
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool "Single-depth WCHAN output"
        default y
+       depends on X86_32
        help
          Calculate simpler /proc/<PID>/wchan values. If this option
          is disabled then wchan values will recurse back to the
@@ -228,7 +314,7 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER
 
 config PARAVIRT
        bool
-       depends on !(X86_VISWS || X86_VOYAGER)
+       depends on X86_32 && !(X86_VISWS || X86_VOYAGER)
        help
          This changes the kernel so it can modify itself when it is run
          under a hypervisor, potentially improving performance significantly
@@ -237,6 +323,7 @@ config PARAVIRT
 
 menuconfig PARAVIRT_GUEST
        bool "Paravirtualized guest support"
+       depends on X86_32
        help
          Say Y here to get to see options related to running Linux under
          various hypervisors.  This option alone does not add any kernel code.
@@ -264,7 +351,7 @@ endif
 config ACPI_SRAT
        bool
        default y
-       depends on ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH)
+       depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH)
        select ACPI_NUMA
 
 config HAVE_ARCH_PARSE_SRAT
@@ -275,12 +362,12 @@ config HAVE_ARCH_PARSE_SRAT
 config X86_SUMMIT_NUMA
        bool
        default y
-       depends on NUMA && (X86_SUMMIT || X86_GENERICARCH)
+       depends on X86_32 && NUMA && (X86_SUMMIT || X86_GENERICARCH)
 
 config X86_CYCLONE_TIMER
        bool
        default y
-       depends on X86_SUMMIT || X86_GENERICARCH
+       depends on X86_32 && X86_SUMMIT || X86_GENERICARCH
 
 config ES7000_CLUSTERED_APIC
        bool
@@ -290,21 +377,89 @@ config ES7000_CLUSTERED_APIC
 source "arch/x86/Kconfig.cpu"
 
 config HPET_TIMER
-       bool "HPET Timer Support"
+       bool
+       prompt "HPET Timer Support" if X86_32
+       default X86_64
        help
-         This enables the use of the HPET for the kernel's internal timer.
-         HPET is the next generation timer replacing legacy 8254s.
-         You can safely choose Y here.  However, HPET will only be
-         activated if the platform and the BIOS support this feature.
-         Otherwise the 8254 will be used for timing services.
+         Use the IA-PC HPET (High Precision Event Timer) to manage
+         time in preference to the PIT and RTC, if a HPET is
+         present.
+         HPET is the next generation timer replacing legacy 8254s.
+         The HPET provides a stable time base on SMP
+         systems, unlike the TSC, but it is more expensive to access,
+         as it is off-chip.  You can find the HPET spec at
+         <http://www.intel.com/hardwaredesign/hpetspec.htm>.
+
+         You can safely choose Y here.  However, HPET will only be
+         activated if the platform and the BIOS support this feature.
+         Otherwise the 8254 will be used for timing services.
 
-         Choose N to continue using the legacy 8254 timer.
+         Choose N to continue using the legacy 8254 timer.
 
 config HPET_EMULATE_RTC
        bool
        depends on HPET_TIMER && RTC=y
        default y
 
+# Mark as embedded because too many people got it wrong.
+# The code disables itself when not needed.
+config GART_IOMMU
+       bool "GART IOMMU support" if EMBEDDED
+       default y
+       select SWIOTLB
+       select AGP
+       depends on X86_64 && PCI
+       help
+         Support for full DMA access of devices with 32bit memory access only
+         on systems with more than 3GB. This is usually needed for USB,
+         sound, many IDE/SATA chipsets and some other devices.
+         Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART
+         based hardware IOMMU and a software bounce buffer based IOMMU used
+         on Intel systems and as fallback.
+         The code is only active when needed (enough memory and limited
+         device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified
+         too.
+
+config CALGARY_IOMMU
+       bool "IBM Calgary IOMMU support"
+       select SWIOTLB
+       depends on X86_64 && PCI && EXPERIMENTAL
+       help
+         Support for hardware IOMMUs in IBM's xSeries x366 and x460
+         systems. Needed to run systems with more than 3GB of memory
+         properly with 32-bit PCI devices that do not support DAC
+         (Double Address Cycle). Calgary also supports bus level
+         isolation, where all DMAs pass through the IOMMU.  This
+         prevents them from going anywhere except their intended
+         destination. This catches hard-to-find kernel bugs and
+         mis-behaving drivers and devices that do not use the DMA-API
+         properly to set up their DMA buffers.  The IOMMU can be
+         turned off at boot time with the iommu=off parameter.
+         Normally the kernel will make the right choice by itself.
+         If unsure, say Y.
+
+config CALGARY_IOMMU_ENABLED_BY_DEFAULT
+       bool "Should Calgary be enabled by default?"
+       default y
+       depends on CALGARY_IOMMU
+       help
+         Should Calgary be enabled by default? if you choose 'y', Calgary
+         will be used (if it exists). If you choose 'n', Calgary will not be
+         used even if it exists. If you choose 'n' and would like to use
+         Calgary anyway, pass 'iommu=calgary' on the kernel command line.
+         If unsure, say Y.
+
+# need this always selected by IOMMU for the VIA workaround
+config SWIOTLB
+       bool
+       help
+         Support for software bounce buffers used on x86-64 systems
+         which don't have a hardware IOMMU (e.g. the current generation
+         of Intel's x86-64 CPUs). Using this PCI devices which can only
+         access 32-bits of memory can be used on systems with more than
+         3 GB of memory. If unsure, say Y.
+
+
 config NR_CPUS
        int "Maximum number of CPUs (2-255)"
        range 2 255
@@ -321,7 +476,7 @@ config NR_CPUS
 
 config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
-       depends on X86_HT
+       depends on (X86_64 && SMP) || (X86_32 && X86_HT)
        help
          SMT scheduler support improves the CPU scheduler's decision making
          when dealing with Intel Pentium 4 chips with HyperThreading at a
@@ -330,7 +485,7 @@ config SCHED_SMT
 
 config SCHED_MC
        bool "Multi-core scheduler support"
-       depends on X86_HT
+       depends on (X86_64 && SMP) || (X86_32 && X86_HT)
        default y
        help
          Multi-core scheduler support improves the CPU scheduler's decision
@@ -341,7 +496,7 @@ source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
        bool "Local APIC support on uniprocessors"
-       depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH)
+       depends on X86_32 && !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH)
        help
          A local APIC (Advanced Programmable Interrupt Controller) is an
          integrated interrupt controller in the CPU. If you have a single-CPU
@@ -366,17 +521,17 @@ config X86_UP_IOAPIC
 
 config X86_LOCAL_APIC
        bool
-       depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH
+       depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH))
        default y
 
 config X86_IO_APIC
        bool
-       depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH
+       depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH))
        default y
 
 config X86_VISWS_APIC
        bool
-       depends on X86_VISWS
+       depends on X86_32 && X86_VISWS
        default y
 
 config X86_MCE
@@ -396,9 +551,25 @@ config X86_MCE
          to disable it.  MCE support simply ignores non-MCE processors like
          the 386 and 486, so nearly everyone can say Y here.
 
+config X86_MCE_INTEL
+       bool "Intel MCE features"
+       depends on X86_64 && X86_MCE && X86_LOCAL_APIC
+       default y
+       help
+          Additional support for intel specific MCE features such as
+          the thermal monitor.
+
+config X86_MCE_AMD
+       bool "AMD MCE features"
+       depends on X86_64 && X86_MCE && X86_LOCAL_APIC
+       default y
+       help
+          Additional support for AMD specific MCE features such as
+          the DRAM Error Threshold.
+
 config X86_MCE_NONFATAL
        tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
-       depends on X86_MCE
+       depends on X86_32 && X86_MCE
        help
          Enabling this feature starts a timer that triggers every 5 seconds which
          will look at the machine check registers to see if anything happened.
@@ -411,14 +582,15 @@ config X86_MCE_NONFATAL
 
 config X86_MCE_P4THERMAL
        bool "check for P4 thermal throttling interrupt."
-       depends on X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS
+       depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS
        help
          Enabling this feature will cause a message to be printed when the P4
          enters thermal throttling.
 
 config VM86
-       default y
        bool "Enable VM86 support" if EMBEDDED
+       default y
+       depends on X86_32
        help
           This option is required by programs like DOSEMU to run 16-bit legacy
          code on X86 processors. It also may be needed by software like
@@ -427,6 +599,7 @@ config VM86
 
 config TOSHIBA
        tristate "Toshiba Laptop support"
+       depends on X86_32
        ---help---
          This adds a driver to safely access the System Management Mode of
          the CPU on Toshiba portables with a genuine Toshiba BIOS. It does
@@ -442,6 +615,7 @@ config TOSHIBA
 
 config I8K
        tristate "Dell laptop support"
+       depends on X86_32
        ---help---
          This adds a driver to safely access the System Management Mode
          of the CPU on the Dell Inspiron 8000. The System Management Mode
@@ -462,7 +636,7 @@ config I8K
 
 config X86_REBOOTFIXUPS
        bool "Enable X86 board specific fixups for reboot"
-       depends on X86
+       depends on X86_32 && X86
        default n
        ---help---
          This enables chipset and/or board specific fixups to be done
@@ -517,12 +691,11 @@ config X86_CPUID
          with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
          /dev/cpu/31/cpuid.
 
-source "drivers/firmware/Kconfig"
-
 choice
        prompt "High Memory Support"
        default HIGHMEM4G if !X86_NUMAQ
        default HIGHMEM64G if X86_NUMAQ
+       depends on X86_32
 
 config NOHIGHMEM
        bool "off"
@@ -582,6 +755,7 @@ choice
        depends on EXPERIMENTAL
        prompt "Memory split" if EMBEDDED
        default VMSPLIT_3G
+       depends on X86_32
        help
          Select the desired split between kernel and user memory.
 
@@ -619,16 +793,17 @@ config PAGE_OFFSET
        default 0x78000000 if VMSPLIT_2G_OPT
        default 0x40000000 if VMSPLIT_1G
        default 0xC0000000
+       depends on X86_32
 
 config HIGHMEM
        bool
-       depends on HIGHMEM64G || HIGHMEM4G
+       depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
        default y
 
 config X86_PAE
        bool "PAE (Physical Address Extension) Support"
        default n
-       depends on !HIGHMEM4G
+       depends on X86_32 && !HIGHMEM4G
        select RESOURCES_64BIT
        help
          PAE is required for NX support, and furthermore enables
@@ -639,46 +814,82 @@ config X86_PAE
 # Common NUMA Features
 config NUMA
        bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
-       depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL
+       depends on SMP
+       depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL)
        default n if X86_PC
        default y if (X86_NUMAQ || X86_SUMMIT)
        help
-         NUMA support for i386. This is currently highly experimental
-         and should be only used for kernel development. It might also
-         cause boot failures.
+         Enable NUMA (Non Uniform Memory Access) support.
+         The kernel will try to allocate memory used by a CPU on the
+         local memory controller of the CPU and add some more
+         NUMA awareness to the kernel.
+
+         For i386 this is currently highly experimental and should be only
+         used for kernel development. It might also cause boot failures.
+         For x86_64 this is recommended on all multiprocessor Opteron systems.
+         If the system is EM64T, you should say N unless your system is
+         EM64T NUMA.
 
 comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
-       depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
+       depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI)
+
+config K8_NUMA
+       bool "Old style AMD Opteron NUMA detection"
+       depends on X86_64 && NUMA && PCI
+       default y
+       help
+        Enable K8 NUMA node topology detection.  You should say Y here if
+        you have a multi processor AMD K8 system. This uses an old
+        method to read the NUMA configuration directly from the builtin
+        Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
+        instead, which also takes priority if both are compiled in.
+
+config X86_64_ACPI_NUMA
+       bool "ACPI NUMA detection"
+       depends on X86_64 && NUMA && ACPI && PCI
+       select ACPI_NUMA
+       default y
+       help
+         Enable ACPI SRAT based node topology detection.
+
+config NUMA_EMU
+       bool "NUMA emulation"
+       depends on X86_64 && NUMA
+       help
+         Enable NUMA emulation. A flat machine will be split
+         into virtual nodes when booted with "numa=fake=N", where N is the
+         number of nodes. This is only useful for debugging.
 
 config NODES_SHIFT
        int
+       default "6" if X86_64
        default "4" if X86_NUMAQ
        default "3"
        depends on NEED_MULTIPLE_NODES
 
 config HAVE_ARCH_BOOTMEM_NODE
        bool
-       depends on NUMA
+       depends on X86_32 && NUMA
        default y
 
 config ARCH_HAVE_MEMORY_PRESENT
        bool
-       depends on DISCONTIGMEM
+       depends on X86_32 && DISCONTIGMEM
        default y
 
 config NEED_NODE_MEMMAP_SIZE
        bool
-       depends on DISCONTIGMEM || SPARSEMEM
+       depends on X86_32 && (DISCONTIGMEM || SPARSEMEM)
        default y
 
 config HAVE_ARCH_ALLOC_REMAP
        bool
-       depends on NUMA
+       depends on X86_32 && NUMA
        default y
 
 config ARCH_FLATMEM_ENABLE
        def_bool y
-       depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC)
+       depends on (X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC) || (X86_64 && !NUMA)
 
 config ARCH_DISCONTIGMEM_ENABLE
        def_bool y
@@ -690,21 +901,23 @@ config ARCH_DISCONTIGMEM_DEFAULT
 
 config ARCH_SPARSEMEM_ENABLE
        def_bool y
-       depends on (NUMA || (X86_PC && EXPERIMENTAL))
-       select SPARSEMEM_STATIC
+       depends on NUMA || (EXPERIMENTAL && (X86_PC || X86_64))
+       select SPARSEMEM_STATIC if X86_32
+       select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 
 config ARCH_SELECT_MEMORY_MODEL
        def_bool y
-       depends on ARCH_SPARSEMEM_ENABLE
+       depends on X86_32 && ARCH_SPARSEMEM_ENABLE
 
-config ARCH_POPULATES_NODE_MAP
-       def_bool y
+config ARCH_MEMORY_PROBE
+       def_bool X86_64
+       depends on MEMORY_HOTPLUG
 
 source "mm/Kconfig"
 
 config HIGHPTE
        bool "Allocate 3rd-level pagetables from highmem"
-       depends on HIGHMEM4G || HIGHMEM64G
+       depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
        help
          The VM uses one page table entry for each page of physical memory.
          For systems with a lot of RAM, this can be wasteful of precious
@@ -712,7 +925,8 @@ config HIGHPTE
          entries in high memory.
 
 config MATH_EMULATION
-       bool "Math emulation"
+       bool
+       prompt "Math emulation" if X86_32
        ---help---
          Linux can emulate a math coprocessor (used for floating point
          operations) if you don't have one. 486DX and Pentium processors have
@@ -772,7 +986,7 @@ config MTRR
 
 config EFI
        bool "Boot from EFI support"
-       depends on ACPI
+       depends on X86_32 && ACPI
        default n
        ---help---
        This enables the kernel to boot on EFI platforms using
@@ -789,18 +1003,18 @@ config EFI
        kernel should continue to boot on existing non-EFI platforms.
 
 config IRQBALANCE
-       bool "Enable kernel irq balancing"
-       depends on SMP && X86_IO_APIC
+       bool "Enable kernel irq balancing"
+       depends on X86_32 && SMP && X86_IO_APIC
        default y
        help
-         The default yes will allow the kernel to do irq load balancing.
+         The default yes will allow the kernel to do irq load balancing.
          Saying no will keep the kernel from doing irq load balancing.
 
 # turning this on wastes a bunch of space.
 # Summit needs it only when NUMA is on
 config BOOT_IOREMAP
        bool
-       depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
+       depends on X86_32 && (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
        default y
 
 config SECCOMP
@@ -820,6 +1034,30 @@ config SECCOMP
 
          If unsure, say Y. Only embedded should say N here.
 
+config CC_STACKPROTECTOR
+       bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+       depends on X86_64 && EXPERIMENTAL
+       help
+         This option turns on the -fstack-protector GCC feature. This
+         feature puts, at the beginning of critical functions, a canary
+         value on the stack just before the return address, and validates
+         the value just before actually returning.  Stack based buffer
+         overflows (that need to overwrite this return address) now also
+         overwrite the canary, which gets detected and the attack is then
+         neutralized via a kernel panic.
+
+         This feature requires gcc version 4.2 or above, or a distribution
+         gcc with the feature backported. Older versions are automatically
+         detected and for those versions, this configuration option is ignored.
+
+config CC_STACKPROTECTOR_ALL
+       bool "Use stack-protector for all functions"
+       depends on CC_STACKPROTECTOR
+       help
+         Normally, GCC only inserts the canary value protection for
+         functions that use large-ish on-stack buffers. By enabling
+         this option, GCC will be asked to do this for ALL functions.
+
 source kernel/Kconfig.hz
 
 config KEXEC
@@ -841,7 +1079,7 @@ config KEXEC
 config CRASH_DUMP
        bool "kernel crash dumps (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       depends on HIGHMEM
+       depends on X86_64 || (X86_32 && HIGHMEM)
        help
          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
@@ -856,6 +1094,7 @@ config CRASH_DUMP
 config PHYSICAL_START
        hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
        default "0x1000000" if X86_NUMAQ
+       default "0x200000" if X86_64
        default "0x100000"
        help
          This gives the physical address where the kernel is loaded.
@@ -908,25 +1147,31 @@ config RELOCATABLE
          must live at a different physical address than the primary
          kernel.
 
+         Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address
+         it has been loaded at and the compile time physical address
+         (CONFIG_PHYSICAL_START) is ignored.
+
 config PHYSICAL_ALIGN
-       hex "Alignment value to which kernel should be aligned"
-       default "0x100000"
+       hex
+       prompt "Alignment value to which kernel should be aligned" if X86_32
+       default "0x100000" if X86_32
+       default "0x200000" if X86_64
        range 0x2000 0x400000
        help
          This value puts the alignment restrictions on physical address
-         where kernel is loaded and run from. Kernel is compiled for an
-         address which meets above alignment restriction.
-
-         If bootloader loads the kernel at a non-aligned address and
-         CONFIG_RELOCATABLE is set, kernel will move itself to nearest
-         address aligned to above value and run from there.
-
-         If bootloader loads the kernel at a non-aligned address and
-         CONFIG_RELOCATABLE is not set, kernel will ignore the run time
-         load address and decompress itself to the address it has been
-         compiled for and run from there. The address for which kernel is
-         compiled already meets above alignment restrictions. Hence the
-         end result is that kernel runs from a physical address meeting
+         where kernel is loaded and run from. Kernel is compiled for an
+         address which meets above alignment restriction.
+
+         If bootloader loads the kernel at a non-aligned address and
+         CONFIG_RELOCATABLE is set, kernel will move itself to nearest
+         address aligned to above value and run from there.
+
+         If bootloader loads the kernel at a non-aligned address and
+         CONFIG_RELOCATABLE is not set, kernel will ignore the run time
+         load address and decompress itself to the address it has been
+         compiled for and run from there. The address for which kernel is
+         compiled already meets above alignment restrictions. Hence the
+         end result is that kernel runs from a physical address meeting
          above alignment restrictions.
 
          Don't change this unless you know what you are doing.
@@ -938,10 +1183,13 @@ config HOTPLUG_CPU
          Say Y here to experiment with turning CPUs off and on, and to
          enable suspend on SMP systems. CPUs can be controlled through
          /sys/devices/system/cpu.
+         Say N if you want to disable CPU hotplug and don't need to
+         suspend.
 
 config COMPAT_VDSO
        bool "Compat VDSO support"
        default y
+       depends on X86_32
        help
          Map the VDSO to the predictable old-style address too.
        ---help---
@@ -955,18 +1203,35 @@ endmenu
 
 config ARCH_ENABLE_MEMORY_HOTPLUG
        def_bool y
-       depends on HIGHMEM
+       depends on X86_64 || (X86_32 && HIGHMEM)
+
+config MEMORY_HOTPLUG_RESERVE
+       def_bool X86_64
+       depends on (MEMORY_HOTPLUG && DISCONTIGMEM)
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+       def_bool X86_64
+       depends on NUMA
 
-menu "Power management options (ACPI, APM)"
+config OUT_OF_LINE_PFN_TO_PAGE
+       def_bool X86_64
+       depends on DISCONTIGMEM
+
+menu "Power management options"
        depends on !X86_VOYAGER
 
-source kernel/power/Kconfig
+config ARCH_HIBERNATION_HEADER
+       bool
+       depends on X86_64 && HIBERNATION
+       default y
+
+source "kernel/power/Kconfig"
 
 source "drivers/acpi/Kconfig"
 
 menuconfig APM
        tristate "APM (Advanced Power Management) BIOS support"
-       depends on PM_SLEEP && !X86_VISWS
+       depends on X86_32 && PM_SLEEP && !X86_VISWS
        ---help---
          APM is a BIOS specification for saving power using several different
          techniques. This is mostly useful for battery powered laptops with
@@ -1092,13 +1357,14 @@ config APM_REAL_MODE_POWER_OFF
 
 endif # APM
 
-source "arch/x86/kernel/cpu/cpufreq/Kconfig_32"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig"
 
 source "drivers/cpuidle/Kconfig"
 
 endmenu
 
-menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+menu "Bus options (PCI etc.)"
 
 config PCI
        bool "PCI support" if !X86_VISWS
@@ -1118,7 +1384,7 @@ config PCI
 
 choice
        prompt "PCI access mode"
-       depends on PCI && !X86_VISWS
+       depends on X86_32 && PCI && !X86_VISWS
        default PCI_GOANY
        ---help---
          On PCI systems, the BIOS can be used to detect the PCI devices and
@@ -1151,17 +1417,18 @@ endchoice
 
 config PCI_BIOS
        bool
-       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
+       depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
        default y
 
+# x86-64 doesn't support PCI BIOS access from long mode so always go direct.
 config PCI_DIRECT
        bool
-       depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
+       depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
        default y
 
 config PCI_MMCONFIG
        bool
-       depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
+       depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
        default y
 
 config PCI_DOMAINS
@@ -1169,14 +1436,52 @@ config PCI_DOMAINS
        depends on PCI
        default y
 
+config PCI_MMCONFIG
+       bool "Support mmconfig PCI config space access"
+       depends on X86_64 && PCI && ACPI
+
+config DMAR
+       bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
+       depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
+       help
+         DMA remapping (DMAR) devices support enables independent address
+         translations for Direct Memory Access (DMA) from devices.
+         These DMA remapping devices are reported via ACPI tables
+         and include PCI device scope covered by these DMA
+         remapping devices.
+
+config DMAR_GFX_WA
+       bool "Support for Graphics workaround"
+       depends on DMAR
+       default y
+       help
+        Current Graphics drivers tend to use physical address
+        for DMA and avoid using DMA APIs. Setting this config
+        option permits the IOMMU driver to set a unity map for
+        all the OS-visible memory. Hence the driver can continue
+        to use physical addresses for DMA.
+
+config DMAR_FLOPPY_WA
+       bool
+       depends on DMAR
+       default y
+       help
+        Floppy disk drivers are know to bypass DMA API calls
+        thereby failing to work when IOMMU is enabled. This
+        workaround will setup a 1:1 mapping for the first
+        16M to make floppy (an ISA device) work.
+
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
 
+# x86_64 have no ISA slots, but do have ISA-style DMA.
 config ISA_DMA_API
        bool
        default y
 
+if X86_32
+
 config ISA
        bool "ISA support"
        depends on !(X86_VOYAGER || X86_VISWS)
@@ -1248,9 +1553,11 @@ config GEODE_MFGPT_TIMER
          MFGPTs have a better resolution and max interval than the
          generic PIT, and are suitable for use as high-res timers.
 
+endif # X86_32
+
 config K8_NB
        def_bool y
-       depends on AGP_AMD64
+       depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA)))
 
 source "drivers/pcmcia/Kconfig"
 
@@ -1258,16 +1565,48 @@ source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
-menu "Executable file formats"
+
+menu "Executable file formats / Emulations"
 
 source "fs/Kconfig.binfmt"
 
+config IA32_EMULATION
+       bool "IA32 Emulation"
+       depends on X86_64
+       help
+         Include code to run 32-bit programs under a 64-bit kernel. You should
+         likely turn this on, unless you're 100% sure that you don't have any
+         32-bit programs left.
+
+config IA32_AOUT
+       tristate "IA32 a.out support"
+       depends on IA32_EMULATION
+       help
+         Support old a.out binaries in the 32bit emulation.
+
+config COMPAT
+       bool
+       depends on IA32_EMULATION
+       default y
+
+config COMPAT_FOR_U64_ALIGNMENT
+       def_bool COMPAT
+       depends on X86_64
+
+config SYSVIPC_COMPAT
+       bool
+       depends on X86_64 && COMPAT && SYSVIPC
+       default y
+
 endmenu
 
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "fs/Kconfig"
 
 source "kernel/Kconfig.instrumentation"
@@ -1279,43 +1618,3 @@ source "security/Kconfig"
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
-
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
-       bool
-       default y
-
-config GENERIC_IRQ_PROBE
-       bool
-       default y
-
-config GENERIC_PENDING_IRQ
-       bool
-       depends on GENERIC_HARDIRQS && SMP
-       default y
-
-config X86_SMP
-       bool
-       depends on SMP && !X86_VOYAGER
-       default y
-
-config X86_HT
-       bool
-       depends on SMP && !(X86_VISWS || X86_VOYAGER)
-       default y
-
-config X86_BIOS_REBOOT
-       bool
-       depends on !(X86_VISWS || X86_VOYAGER)
-       default y
-
-config X86_TRAMPOLINE
-       bool
-       depends on X86_SMP || (X86_VOYAGER && SMP)
-       default y
-
-config KTIME_SCALAR
-       bool
-       default y
index 0e2adadf59057dc906466786f4049ac8ca33aa64..c30162202dc4b10f767ee71728c13769369d1fae 100644 (file)
@@ -3,11 +3,12 @@ if !X86_ELAN
 
 choice
        prompt "Processor family"
-       default M686
+       default M686 if X86_32
+       default GENERIC_CPU if X86_64
 
 config M386
        bool "386"
-       depends on !UML
+       depends on X86_32 && !UML
        ---help---
          This is the processor type of your CPU. This information is used for
          optimizing purposes. In order to compile a kernel that can run on
@@ -49,6 +50,7 @@ config M386
 
 config M486
        bool "486"
+       depends on X86_32
        help
          Select this for a 486 series processor, either Intel or one of the
          compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
@@ -57,6 +59,7 @@ config M486
 
 config M586
        bool "586/K5/5x86/6x86/6x86MX"
+       depends on X86_32
        help
          Select this for an 586 or 686 series processor such as the AMD K5,
          the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
@@ -64,18 +67,21 @@ config M586
 
 config M586TSC
        bool "Pentium-Classic"
+       depends on X86_32
        help
          Select this for a Pentium Classic processor with the RDTSC (Read
          Time Stamp Counter) instruction for benchmarking.
 
 config M586MMX
        bool "Pentium-MMX"
+       depends on X86_32
        help
          Select this for a Pentium with the MMX graphics/multimedia
          extended instructions.
 
 config M686
        bool "Pentium-Pro"
+       depends on X86_32
        help
          Select this for Intel Pentium Pro chips.  This enables the use of
          Pentium Pro extended instructions, and disables the init-time guard
@@ -83,6 +89,7 @@ config M686
 
 config MPENTIUMII
        bool "Pentium-II/Celeron(pre-Coppermine)"
+       depends on X86_32
        help
          Select this for Intel chips based on the Pentium-II and
          pre-Coppermine Celeron core.  This option enables an unaligned
@@ -92,6 +99,7 @@ config MPENTIUMII
 
 config MPENTIUMIII
        bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
+       depends on X86_32
        help
          Select this for Intel chips based on the Pentium-III and
          Celeron-Coppermine core.  This option enables use of some
@@ -100,19 +108,14 @@ config MPENTIUMIII
 
 config MPENTIUMM
        bool "Pentium M"
+       depends on X86_32
        help
          Select this for Intel Pentium M (not Pentium-4 M)
          notebook chips.
 
-config MCORE2
-       bool "Core 2/newer Xeon"
-       help
-         Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx)
-         CPUs. You can distinguish newer from older Xeons by the CPU family
-         in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo)
-
 config MPENTIUM4
        bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon"
+       depends on X86_32
        help
          Select this for Intel Pentium 4 chips.  This includes the
          Pentium 4, Pentium D, P4-based Celeron and Xeon, and
@@ -148,6 +151,7 @@ config MPENTIUM4
 
 config MK6
        bool "K6/K6-II/K6-III"
+       depends on X86_32
        help
          Select this for an AMD K6-family processor.  Enables use of
          some extended instructions, and passes appropriate optimization
@@ -155,6 +159,7 @@ config MK6
 
 config MK7
        bool "Athlon/Duron/K7"
+       depends on X86_32
        help
          Select this for an AMD Athlon K7-family processor.  Enables use of
          some extended instructions, and passes appropriate optimization
@@ -169,6 +174,7 @@ config MK8
 
 config MCRUSOE
        bool "Crusoe"
+       depends on X86_32
        help
          Select this for a Transmeta Crusoe processor.  Treats the processor
          like a 586 with TSC, and sets some GCC optimization flags (like a
@@ -176,11 +182,13 @@ config MCRUSOE
 
 config MEFFICEON
        bool "Efficeon"
+       depends on X86_32
        help
          Select this for a Transmeta Efficeon processor.
 
 config MWINCHIPC6
        bool "Winchip-C6"
+       depends on X86_32
        help
          Select this for an IDT Winchip C6 chip.  Linux and GCC
          treat this chip as a 586TSC with some extended instructions
@@ -188,6 +196,7 @@ config MWINCHIPC6
 
 config MWINCHIP2
        bool "Winchip-2"
+       depends on X86_32
        help
          Select this for an IDT Winchip-2.  Linux and GCC
          treat this chip as a 586TSC with some extended instructions
@@ -195,6 +204,7 @@ config MWINCHIP2
 
 config MWINCHIP3D
        bool "Winchip-2A/Winchip-3"
+       depends on X86_32
        help
          Select this for an IDT Winchip-2A or 3.  Linux and GCC
          treat this chip as a 586TSC with some extended instructions
@@ -204,16 +214,19 @@ config MWINCHIP3D
 
 config MGEODEGX1
        bool "GeodeGX1"
+       depends on X86_32
        help
          Select this for a Geode GX1 (Cyrix MediaGX) chip.
 
 config MGEODE_LX
        bool "Geode GX/LX"
+       depends on X86_32
        help
          Select this for AMD Geode GX and LX processors.
 
 config MCYRIXIII
        bool "CyrixIII/VIA-C3"
+       depends on X86_32
        help
          Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
          treat this chip as a generic 586. Whilst the CPU is 686 class,
@@ -225,6 +238,7 @@ config MCYRIXIII
 
 config MVIAC3_2
        bool "VIA C3-2 (Nehemiah)"
+       depends on X86_32
        help
          Select this for a VIA C3 "Nehemiah". Selecting this enables usage
          of SSE and tells gcc to treat the CPU as a 686.
@@ -232,15 +246,42 @@ config MVIAC3_2
 
 config MVIAC7
        bool "VIA C7"
+       depends on X86_32
        help
          Select this for a VIA C7.  Selecting this uses the correct cache
          shift and tells gcc to treat the CPU as a 686.
 
+config MPSC
+       bool "Intel P4 / older Netburst based Xeon"
+       depends on X86_64
+       help
+         Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
+         Xeon CPUs with Intel 64bit which is compatible with x86-64.
+         Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
+          Netburst core and shouldn't use this option. You can distinguish them
+         using the cpu family field
+         in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
+
+config MCORE2
+       bool "Core 2/newer Xeon"
+       help
+         Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx)
+         CPUs. You can distinguish newer from older Xeons by the CPU family
+         in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo)
+
+config GENERIC_CPU
+       bool "Generic-x86-64"
+       depends on X86_64
+       help
+         Generic x86-64 CPU.
+         Run equally well on all x86-64 CPUs.
+
 endchoice
 
 config X86_GENERIC
-       bool "Generic x86 support"
-       help
+       bool "Generic x86 support"
+       depends on X86_32
+       help
          Instead of just including optimizations for the selected
          x86 variant (e.g. PII, Crusoe or Athlon), include some more
          generic optimizations as well. This will make the kernel
@@ -253,44 +294,31 @@ endif
 
 #
 # Define implied options from the CPU selection here
-#
+config X86_L1_CACHE_BYTES
+       int
+       default "128" if GENERIC_CPU || MPSC
+       default "64" if MK8 || MCORE2
+       depends on X86_64
+
+config X86_INTERNODE_CACHE_BYTES
+       int
+       default "4096" if X86_VSMP
+       default X86_L1_CACHE_BYTES if !X86_VSMP
+       depends on X86_64
+
 config X86_CMPXCHG
-       bool
-       depends on !M386
-       default y
+       def_bool X86_64 || (X86_32 && !M386)
 
 config X86_L1_CACHE_SHIFT
        int
-       default "7" if MPENTIUM4 || X86_GENERIC
+       default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC
        default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
        default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
        default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7
 
 config X86_XADD
        bool
-       depends on !M386
-       default y
-
-config RWSEM_GENERIC_SPINLOCK
-       bool
-       depends on !X86_XADD
-       default y
-
-config RWSEM_XCHGADD_ALGORITHM
-       bool
-       depends on X86_XADD
-       default y
-
-config ARCH_HAS_ILOG2_U32
-       bool
-       default n
-
-config ARCH_HAS_ILOG2_U64
-       bool
-       default n
-
-config GENERIC_CALIBRATE_DELAY
-       bool
+       depends on X86_32 && !M386
        default y
 
 config X86_PPRO_FENCE
@@ -305,22 +333,22 @@ config X86_F00F_BUG
 
 config X86_WP_WORKS_OK
        bool
-       depends on !M386
+       depends on X86_32 && !M386
        default y
 
 config X86_INVLPG
        bool
-       depends on !M386
+       depends on X86_32 && !M386
        default y
 
 config X86_BSWAP
        bool
-       depends on !M386
+       depends on X86_32 && !M386
        default y
 
 config X86_POPAD_OK
        bool
-       depends on !M386
+       depends on X86_32 && !M386
        default y
 
 config X86_ALIGNMENT_16
@@ -330,7 +358,7 @@ config X86_ALIGNMENT_16
 
 config X86_GOOD_APIC
        bool
-       depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7
+       depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
        default y
 
 config X86_INTEL_USERCOPY
@@ -355,7 +383,7 @@ config X86_OOSTORE
 
 config X86_TSC
        bool
-       depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ
+       depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
        default y
 
 # this should be set for all -march=.. options where the compiler
@@ -367,6 +395,7 @@ config X86_CMOV
 
 config X86_MINIMUM_CPU_FAMILY
        int
-       default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
+       default "64" if X86_64
+       default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
        default "3"
 
diff --git a/arch/x86/Kconfig.x86_64 b/arch/x86/Kconfig.x86_64
deleted file mode 100644 (file)
index cc468ea..0000000
+++ /dev/null
@@ -1,839 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-# Note: ISA is disabled and will hopefully never be enabled.
-# If you managed to buy an ISA x86-64 box you'll have to fix all the
-# ISA drivers you need yourself.
-#
-
-mainmenu "Linux Kernel Configuration"
-
-config X86_64
-       bool
-       default y
-       help
-         Port to the x86-64 architecture. x86-64 is a 64-bit extension to the
-         classical 32-bit x86 architecture. For details see
-         <http://www.x86-64.org/>.
-
-config 64BIT
-       def_bool y
-
-config X86
-       bool
-       default y
-
-config GENERIC_TIME
-       bool
-       default y
-
-config GENERIC_TIME_VSYSCALL
-       bool
-       default y
-
-config GENERIC_CMOS_UPDATE
-       bool
-       default y
-
-config CLOCKSOURCE_WATCHDOG
-       bool
-       default y
-
-config GENERIC_CLOCKEVENTS
-       bool
-       default y
-
-config GENERIC_CLOCKEVENTS_BROADCAST
-       bool
-       default y
-
-config ZONE_DMA32
-       bool
-       default y
-
-config LOCKDEP_SUPPORT
-       bool
-       default y
-
-config STACKTRACE_SUPPORT
-       bool
-       default y
-
-config SEMAPHORE_SLEEPERS
-       bool
-       default y
-
-config MMU
-       bool
-       default y
-
-config ZONE_DMA
-       bool
-       default y
-
-config ISA
-       bool
-
-config SBUS
-       bool
-
-config RWSEM_GENERIC_SPINLOCK
-       bool
-       default y
-
-config RWSEM_XCHGADD_ALGORITHM
-       bool
-
-config GENERIC_HWEIGHT
-       bool
-       default y
-
-config GENERIC_CALIBRATE_DELAY
-       bool
-       default y
-
-config X86_CMPXCHG
-       bool
-       default y
-
-config GENERIC_ISA_DMA
-       bool
-       default y
-
-config GENERIC_IOMAP
-       bool
-       default y
-
-config ARCH_MAY_HAVE_PC_FDC
-       bool
-       default y
-
-config ARCH_POPULATES_NODE_MAP
-       def_bool y
-
-config DMI
-       bool
-       default y
-
-config AUDIT_ARCH
-       bool
-       default y
-
-config GENERIC_BUG
-       bool
-       default y
-       depends on BUG
-
-config ARCH_HAS_ILOG2_U32
-       bool
-       default n
-
-config ARCH_HAS_ILOG2_U64
-       bool
-       default n
-
-source "init/Kconfig"
-
-
-menu "Processor type and features"
-
-source "kernel/time/Kconfig"
-
-choice
-       prompt "Subarchitecture Type"
-       default X86_PC
-
-config X86_PC
-       bool "PC-compatible"
-       help
-         Choose this option if your computer is a standard PC or compatible.
-
-config X86_VSMP
-       bool "Support for ScaleMP vSMP"
-       depends on PCI
-        help
-         Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
-         supposed to run on these EM64T-based machines.  Only choose this option
-         if you have one of these machines.
-
-endchoice
-
-choice
-       prompt "Processor family"
-       default GENERIC_CPU
-
-config MK8
-       bool "AMD-Opteron/Athlon64"
-       help
-         Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs.
-
-config MPSC
-       bool "Intel P4 / older Netburst based Xeon"
-       help
-         Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
-         Xeon CPUs with Intel 64bit which is compatible with x86-64.
-         Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
-          Netburst core and shouldn't use this option. You can distinguish them
-         using the cpu family field
-         in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
-
-config MCORE2
-       bool "Intel Core2 / newer Xeon"
-       help
-         Optimize for Intel Core2 and newer Xeons (51xx)
-         You can distinguish the newer Xeons from the older ones using
-         the cpu family field in /proc/cpuinfo. 15 is an older Xeon
-         (use CONFIG_MPSC then), 6 is a newer one.
-
-config GENERIC_CPU
-       bool "Generic-x86-64"
-       help
-         Generic x86-64 CPU.
-         Run equally well on all x86-64 CPUs.
-
-endchoice
-
-#
-# Define implied options from the CPU selection here
-#
-config X86_L1_CACHE_BYTES
-       int
-       default "128" if GENERIC_CPU || MPSC
-       default "64" if MK8 || MCORE2
-
-config X86_L1_CACHE_SHIFT
-       int
-       default "7" if GENERIC_CPU || MPSC
-       default "6" if MK8 || MCORE2
-
-config X86_INTERNODE_CACHE_BYTES
-       int
-       default "4096" if X86_VSMP
-       default X86_L1_CACHE_BYTES if !X86_VSMP
-
-config X86_TSC
-       bool
-       default y
-
-config X86_GOOD_APIC
-       bool
-       default y
-
-config MICROCODE
-       tristate "/dev/cpu/microcode - Intel CPU microcode support"
-       select FW_LOADER
-       ---help---
-         If you say Y here the 'File systems' section, you will be
-         able to update the microcode on Intel processors. You will
-         obviously need the actual microcode binary data itself which is
-         not shipped with the Linux kernel.
-
-         For latest news and information on obtaining all the required
-         ingredients for this driver, check:
-         <http://www.urbanmyth.org/microcode/>.
-
-         To compile this driver as a module, choose M here: the
-         module will be called microcode.
-         If you use modprobe or kmod you may also want to add the line
-         'alias char-major-10-184 microcode' to your /etc/modules.conf file.
-
-config MICROCODE_OLD_INTERFACE
-       bool
-       depends on MICROCODE
-       default y
-
-config X86_MSR
-       tristate "/dev/cpu/*/msr - Model-specific register support"
-       help
-         This device gives privileged processes access to the x86
-         Model-Specific Registers (MSRs).  It is a character device with
-         major 202 and minors 0 to 31 for /dev/cpu/0/msr to /dev/cpu/31/msr.
-         MSR accesses are directed to a specific CPU on multi-processor
-         systems.
-
-config X86_CPUID
-       tristate "/dev/cpu/*/cpuid - CPU information support"
-       help
-         This device gives processes access to the x86 CPUID instruction to
-         be executed on a specific processor.  It is a character device
-         with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
-         /dev/cpu/31/cpuid.
-
-config X86_HT
-       bool
-       depends on SMP && !MK8
-       default y
-
-config MATH_EMULATION
-       bool
-
-config MCA
-       bool
-
-config EISA
-       bool
-
-config X86_IO_APIC
-       bool
-       default y
-
-config X86_LOCAL_APIC
-       bool
-       default y
-
-config MTRR
-       bool "MTRR (Memory Type Range Register) support"
-       ---help---
-         On Intel P6 family processors (Pentium Pro, Pentium II and later)
-         the Memory Type Range Registers (MTRRs) may be used to control
-         processor access to memory ranges. This is most useful if you have
-         a video (VGA) card on a PCI or AGP bus. Enabling write-combining
-         allows bus write transfers to be combined into a larger transfer
-         before bursting over the PCI/AGP bus. This can increase performance
-         of image write operations 2.5 times or more. Saying Y here creates a
-         /proc/mtrr file which may be used to manipulate your processor's
-         MTRRs. Typically the X server should use this.
-
-         This code has a reasonably generic interface so that similar
-         control registers on other processors can be easily supported
-         as well.
-
-         Saying Y here also fixes a problem with buggy SMP BIOSes which only
-         set the MTRRs for the boot CPU and not for the secondary CPUs. This
-         can lead to all sorts of problems, so it's good to say Y here.
-
-         Just say Y here, all x86-64 machines support MTRRs.
-
-         See <file:Documentation/mtrr.txt> for more information.
-
-config SMP
-       bool "Symmetric multi-processing support"
-       ---help---
-         This enables support for systems with more than one CPU. If you have
-         a system with only one CPU, like most personal computers, say N. If
-         you have a system with more than one CPU, say Y.
-
-         If you say N here, the kernel will run on single and multiprocessor
-         machines, but will use only one CPU of a multiprocessor machine. If
-         you say Y here, the kernel will run on many, but not all,
-         singleprocessor machines. On a singleprocessor machine, the kernel
-         will run faster if you say N here.
-
-         If you don't know what to do here, say N.
-
-config SCHED_SMT
-       bool "SMT (Hyperthreading) scheduler support"
-       depends on SMP
-       default n
-       help
-         SMT scheduler support improves the CPU scheduler's decision making
-         when dealing with Intel Pentium 4 chips with HyperThreading at a
-         cost of slightly increased overhead in some places. If unsure say
-         N here.
-
-config SCHED_MC
-       bool "Multi-core scheduler support"
-       depends on SMP
-       default y
-       help
-         Multi-core scheduler support improves the CPU scheduler's decision
-         making when dealing with multi-core CPU chips at a cost of slightly
-         increased overhead in some places. If unsure say N here.
-
-source "kernel/Kconfig.preempt"
-
-config NUMA
-       bool "Non Uniform Memory Access (NUMA) Support"
-       depends on SMP
-       help
-        Enable NUMA (Non Uniform Memory Access) support. The kernel 
-        will try to allocate memory used by a CPU on the local memory 
-        controller of the CPU and add some more NUMA awareness to the kernel.
-        This code is recommended on all multiprocessor Opteron systems.
-        If the system is EM64T, you should say N unless your system is EM64T 
-        NUMA. 
-
-config K8_NUMA
-       bool "Old style AMD Opteron NUMA detection"
-       depends on NUMA && PCI
-       default y
-       help
-        Enable K8 NUMA node topology detection.  You should say Y here if
-        you have a multi processor AMD K8 system. This uses an old
-        method to read the NUMA configuration directly from the builtin
-        Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
-        instead, which also takes priority if both are compiled in.   
-
-config NODES_SHIFT
-       int
-       default "6"
-       depends on NEED_MULTIPLE_NODES
-
-# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig.
-
-config X86_64_ACPI_NUMA
-       bool "ACPI NUMA detection"
-       depends on NUMA
-       select ACPI 
-       select PCI
-       select ACPI_NUMA
-       default y
-       help
-        Enable ACPI SRAT based node topology detection.
-
-config NUMA_EMU
-       bool "NUMA emulation"
-       depends on NUMA
-       help
-         Enable NUMA emulation. A flat machine will be split
-         into virtual nodes when booted with "numa=fake=N", where N is the
-         number of nodes. This is only useful for debugging.
-
-config ARCH_DISCONTIGMEM_ENABLE
-       bool
-       depends on NUMA
-       default y
-
-config ARCH_DISCONTIGMEM_DEFAULT
-       def_bool y
-       depends on NUMA
-
-config ARCH_SPARSEMEM_ENABLE
-       def_bool y
-       depends on (NUMA || EXPERIMENTAL)
-       select SPARSEMEM_VMEMMAP_ENABLE
-
-config ARCH_MEMORY_PROBE
-       def_bool y
-       depends on MEMORY_HOTPLUG
-
-config ARCH_FLATMEM_ENABLE
-       def_bool y
-       depends on !NUMA
-
-source "mm/Kconfig"
-
-config MEMORY_HOTPLUG_RESERVE
-       def_bool y
-       depends on (MEMORY_HOTPLUG && DISCONTIGMEM)
-
-config HAVE_ARCH_EARLY_PFN_TO_NID
-       def_bool y
-       depends on NUMA
-
-config OUT_OF_LINE_PFN_TO_PAGE
-       def_bool y
-       depends on DISCONTIGMEM
-
-config NR_CPUS
-       int "Maximum number of CPUs (2-255)"
-       range 2 255
-       depends on SMP
-       default "8"
-       help
-         This allows you to specify the maximum number of CPUs which this
-         kernel will support. Current maximum is 255 CPUs due to
-         APIC addressing limits. Less depending on the hardware.
-
-         This is purely to save memory - each supported CPU requires
-         memory in the static kernel configuration.
-
-config PHYSICAL_ALIGN
-       hex
-       default "0x200000"
-
-config HOTPLUG_CPU
-       bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
-       depends on SMP && HOTPLUG && EXPERIMENTAL
-       help
-               Say Y here to experiment with turning CPUs off and on.  CPUs
-               can be controlled through /sys/devices/system/cpu/cpu#.
-               This is also required for suspend/hibernation on SMP systems.
-
-               Say N if you want to disable CPU hotplug and don't need to
-               suspend.
-
-config ARCH_ENABLE_MEMORY_HOTPLUG
-       def_bool y
-
-config HPET_TIMER
-       bool
-       default y
-       help
-         Use the IA-PC HPET (High Precision Event Timer) to manage
-         time in preference to the PIT and RTC, if a HPET is
-         present.  The HPET provides a stable time base on SMP
-         systems, unlike the TSC, but it is more expensive to access,
-         as it is off-chip.  You can find the HPET spec at
-         <http://www.intel.com/hardwaredesign/hpetspec.htm>.
-
-config HPET_EMULATE_RTC
-       bool
-       depends on HPET_TIMER && RTC=y
-       default y
-
-# Mark as embedded because too many people got it wrong.
-# The code disables itself when not needed.
-config GART_IOMMU
-       bool "GART IOMMU support" if EMBEDDED
-       default y
-       select SWIOTLB
-       select AGP
-       depends on PCI
-       help
-         Support for full DMA access of devices with 32bit memory access only
-         on systems with more than 3GB. This is usually needed for USB,
-         sound, many IDE/SATA chipsets and some other devices.
-         Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART
-         based hardware IOMMU and a software bounce buffer based IOMMU used
-         on Intel systems and as fallback.
-         The code is only active when needed (enough memory and limited
-         device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified
-         too.
-
-config CALGARY_IOMMU
-       bool "IBM Calgary IOMMU support"
-       select SWIOTLB
-       depends on PCI && EXPERIMENTAL
-       help
-         Support for hardware IOMMUs in IBM's xSeries x366 and x460
-         systems. Needed to run systems with more than 3GB of memory
-         properly with 32-bit PCI devices that do not support DAC
-         (Double Address Cycle). Calgary also supports bus level
-         isolation, where all DMAs pass through the IOMMU.  This
-         prevents them from going anywhere except their intended
-         destination. This catches hard-to-find kernel bugs and
-         mis-behaving drivers and devices that do not use the DMA-API
-         properly to set up their DMA buffers.  The IOMMU can be
-         turned off at boot time with the iommu=off parameter.
-         Normally the kernel will make the right choice by itself.
-         If unsure, say Y.
-
-config CALGARY_IOMMU_ENABLED_BY_DEFAULT
-       bool "Should Calgary be enabled by default?"
-       default y
-       depends on CALGARY_IOMMU
-       help
-         Should Calgary be enabled by default? if you choose 'y', Calgary
-         will be used (if it exists). If you choose 'n', Calgary will not be
-         used even if it exists. If you choose 'n' and would like to use
-         Calgary anyway, pass 'iommu=calgary' on the kernel command line.
-         If unsure, say Y.
-
-# need this always selected by IOMMU for the VIA workaround
-config SWIOTLB
-       bool
-       help
-         Support for software bounce buffers used on x86-64 systems
-         which don't have a hardware IOMMU (e.g. the current generation
-         of Intel's x86-64 CPUs). Using this PCI devices which can only
-         access 32-bits of memory can be used on systems with more than
-         3 GB of memory. If unsure, say Y.
-
-config X86_MCE
-       bool "Machine check support" if EMBEDDED
-       default y
-       help
-          Include a machine check error handler to report hardware errors.
-          This version will require the mcelog utility to decode some
-          machine check error logs. See
-          ftp://ftp.x86-64.org/pub/linux/tools/mcelog
-
-config X86_MCE_INTEL
-       bool "Intel MCE features"
-       depends on X86_MCE && X86_LOCAL_APIC
-       default y
-       help
-          Additional support for intel specific MCE features such as
-          the thermal monitor.
-
-config X86_MCE_AMD
-       bool "AMD MCE features"
-       depends on X86_MCE && X86_LOCAL_APIC
-       default y
-       help
-          Additional support for AMD specific MCE features such as
-          the DRAM Error Threshold.
-
-config KEXEC
-       bool "kexec system call"
-       help
-         kexec is a system call that implements the ability to shutdown your
-         current kernel, and to start another kernel.  It is like a reboot
-         but it is independent of the system firmware.   And like a reboot
-         you can start any kernel with it, not just Linux.
-
-         The name comes from the similarity to the exec system call.
-
-         It is an ongoing process to be certain the hardware in a machine
-         is properly shutdown, so do not be surprised if this code does not
-         initially work for you.  It may help to enable device hotplugging
-         support.  As of this writing the exact hardware interface is
-         strongly in flux, so no good recommendation can be made.
-
-config CRASH_DUMP
-       bool "kernel crash dumps (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       help
-         Generate crash dump after being started by kexec.
-         This should be normally only set in special crash dump kernels
-         which are loaded in the main kernel with kexec-tools into
-         a specially reserved region and then later executed after
-         a crash by kdump/kexec. The crash dump kernel must be compiled
-         to a memory address not used by the main kernel or BIOS using
-         PHYSICAL_START, or it must be built as a relocatable image
-         (CONFIG_RELOCATABLE=y).
-         For more details see Documentation/kdump/kdump.txt
-
-config RELOCATABLE
-       bool "Build a relocatable kernel (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       help
-         Builds a relocatable kernel. This enables loading and running
-         a kernel binary from a different physical address than it has
-         been compiled for.
-
-         One use is for the kexec on panic case where the recovery kernel
-         must live at a different physical address than the primary
-         kernel.
-
-         Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address
-         it has been loaded at and the compile time physical address
-         (CONFIG_PHYSICAL_START) is ignored.
-
-config PHYSICAL_START
-       hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
-       default "0x200000"
-       help
-         This gives the physical address where the kernel is loaded. It
-         should be aligned to 2MB boundary.
-
-         If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
-         bzImage will decompress itself to above physical address and
-         run from there. Otherwise, bzImage will run from the address where
-         it has been loaded by the boot loader and will ignore above physical
-         address.
-
-         In normal kdump cases one does not have to set/change this option
-         as now bzImage can be compiled as a completely relocatable image
-         (CONFIG_RELOCATABLE=y) and be used to load and run from a different
-         address. This option is mainly useful for the folks who don't want
-         to use a bzImage for capturing the crash dump and want to use a
-         vmlinux instead.
-
-         So if you are using bzImage for capturing the crash dump, leave
-         the value here unchanged to 0x200000 and set CONFIG_RELOCATABLE=y.
-         Otherwise if you plan to use vmlinux for capturing the crash dump
-         change this value to start of the reserved region (Typically 16MB
-         0x1000000). In other words, it can be set based on the "X" value as
-         specified in the "crashkernel=YM@XM" command line boot parameter
-         passed to the panic-ed kernel. Typically this parameter is set as
-         crashkernel=64M@16M. Please take a look at
-         Documentation/kdump/kdump.txt for more details about crash dumps.
-
-         Usage of bzImage for capturing the crash dump is advantageous as
-         one does not have to build two kernels. Same kernel can be used
-         as production kernel and capture kernel.
-
-         Don't change this unless you know what you are doing.
-
-config SECCOMP
-       bool "Enable seccomp to safely compute untrusted bytecode"
-       depends on PROC_FS
-       default y
-       help
-         This kernel feature is useful for number crunching applications
-         that may need to compute untrusted bytecode during their
-         execution. By using pipes or other transports made available to
-         the process as file descriptors supporting the read/write
-         syscalls, it's possible to isolate those applications in
-         their own address space using seccomp. Once seccomp is
-         enabled via /proc/<pid>/seccomp, it cannot be disabled
-         and the task is only allowed to execute a few safe syscalls
-         defined by each seccomp mode.
-
-         If unsure, say Y. Only embedded should say N here.
-
-config CC_STACKPROTECTOR
-       bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       help
-         This option turns on the -fstack-protector GCC feature. This
-         feature puts, at the beginning of critical functions, a canary
-         value on the stack just before the return address, and validates
-         the value just before actually returning.  Stack based buffer
-         overflows (that need to overwrite this return address) now also
-         overwrite the canary, which gets detected and the attack is then
-         neutralized via a kernel panic.
-
-         This feature requires gcc version 4.2 or above, or a distribution
-         gcc with the feature backported. Older versions are automatically
-         detected and for those versions, this configuration option is ignored.
-
-config CC_STACKPROTECTOR_ALL
-       bool "Use stack-protector for all functions"
-       depends on CC_STACKPROTECTOR
-       help
-         Normally, GCC only inserts the canary value protection for
-         functions that use large-ish on-stack buffers. By enabling
-         this option, GCC will be asked to do this for ALL functions.
-
-source kernel/Kconfig.hz
-
-config K8_NB
-       def_bool y
-       depends on AGP_AMD64 || GART_IOMMU || (PCI && NUMA)
-
-endmenu
-
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
-       bool
-       default y
-
-config GENERIC_IRQ_PROBE
-       bool
-       default y
-
-# we have no ISA slots, but we do have ISA-style DMA.
-config ISA_DMA_API
-       bool
-       default y
-
-config GENERIC_PENDING_IRQ
-       bool
-       depends on GENERIC_HARDIRQS && SMP
-       default y
-
-menu "Power management options"
-
-source kernel/power/Kconfig
-
-config ARCH_HIBERNATION_HEADER
-       bool
-       depends on HIBERNATION
-       default y
-
-source "drivers/acpi/Kconfig"
-
-source "arch/x86/kernel/cpu/cpufreq/Kconfig_64"
-
-source "drivers/cpuidle/Kconfig"
-
-endmenu
-
-menu "Bus options (PCI etc.)"
-
-config PCI
-       bool "PCI support"
-       select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
-
-# x86-64 doesn't support PCI BIOS access from long mode so always go direct.
-config PCI_DIRECT
-       bool
-       depends on PCI
-       default y
-
-config PCI_MMCONFIG
-       bool "Support mmconfig PCI config space access"
-       depends on PCI && ACPI
-
-config PCI_DOMAINS
-       bool
-       depends on PCI
-       default y
-
-config DMAR
-       bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
-       depends on PCI_MSI && ACPI && EXPERIMENTAL
-       help
-         DMA remapping (DMAR) devices support enables independent address
-         translations for Direct Memory Access (DMA) from devices.
-         These DMA remapping devices are reported via ACPI tables
-         and include PCI device scope covered by these DMA
-         remapping devices.
-
-config DMAR_GFX_WA
-       bool "Support for Graphics workaround"
-       depends on DMAR
-       default y
-       help
-        Current Graphics drivers tend to use physical address
-        for DMA and avoid using DMA APIs. Setting this config
-        option permits the IOMMU driver to set a unity map for
-        all the OS-visible memory. Hence the driver can continue
-        to use physical addresses for DMA.
-
-config DMAR_FLOPPY_WA
-       bool
-       depends on DMAR
-       default y
-       help
-        Floppy disk drivers are know to bypass DMA API calls
-        thereby failing to work when IOMMU is enabled. This
-        workaround will setup a 1:1 mapping for the first
-        16M to make floppy (an ISA device) work.
-
-source "drivers/pci/pcie/Kconfig"
-
-source "drivers/pci/Kconfig"
-
-source "drivers/pcmcia/Kconfig"
-
-source "drivers/pci/hotplug/Kconfig"
-
-endmenu
-
-
-menu "Executable file formats / Emulations"
-
-source "fs/Kconfig.binfmt"
-
-config IA32_EMULATION
-       bool "IA32 Emulation"
-       help
-         Include code to run 32-bit programs under a 64-bit kernel. You should
-         likely turn this on, unless you're 100% sure that you don't have any
-         32-bit programs left.
-
-config IA32_AOUT
-       tristate "IA32 a.out support"
-       depends on IA32_EMULATION
-       help
-         Support old a.out binaries in the 32bit emulation.
-
-config COMPAT
-       bool
-       depends on IA32_EMULATION
-       default y
-
-config COMPAT_FOR_U64_ALIGNMENT
-       def_bool COMPAT
-
-config SYSVIPC_COMPAT
-       bool
-       depends on COMPAT && SYSVIPC
-       default y
-
-endmenu
-
-source "net/Kconfig"
-
-source drivers/Kconfig
-
-source "drivers/firmware/Kconfig"
-
-source fs/Kconfig
-
-source "kernel/Kconfig.instrumentation"
-
-source "arch/x86/Kconfig.debug"
-
-source "security/Kconfig"
-
-source "crypto/Kconfig"
-
-source "lib/Kconfig"
index 309597386a77c7811ea3bc594084d5deec6a5d9c..116b03a4563608b00077707ae303106852374d8b 100644 (file)
@@ -1,12 +1,16 @@
 # Unified Makefile for i386 and x86_64
 
 # select defconfig based on actual architecture
-KBUILD_DEFCONFIG := $(ARCH)_defconfig
+ifeq ($(ARCH),x86)
+        KBUILD_DEFCONFIG := i386_defconfig
+else
+        KBUILD_DEFCONFIG := $(ARCH)_defconfig
+endif
 
-# No need to remake these files
+# No need to remake these files
 $(srctree)/arch/x86/Makefile%: ;
 
-ifeq ($(ARCH),i386)
+ifeq ($(CONFIG_X86_32),y)
         include $(srctree)/arch/x86/Makefile_32
 else
         include $(srctree)/arch/x86/Makefile_64
index 346ac07668758f2beb24450d942c039451b01056..50394da2f6c122da4bac4234a4c6ad41d7dc83e3 100644 (file)
@@ -160,7 +160,7 @@ archclean:
        $(Q)$(MAKE) $(clean)=arch/x86/boot
 
 define archhelp
-  echo  '* bzImage     - Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
+  echo  '* bzImage     - Compressed kernel image (arch/x86/boot/bzImage)'
   echo  '  install     - Install kernel using'
   echo  '                 (your) ~/bin/installkernel or'
   echo  '                 (distribution) /sbin/installkernel or'
@@ -170,6 +170,6 @@ define archhelp
   echo  '  isoimage     - Create a boot CD-ROM image'
 endef
 
-CLEAN_FILES += arch/$(ARCH)/boot/fdimage \
-              arch/$(ARCH)/boot/image.iso \
-              arch/$(ARCH)/boot/mtools.conf
+CLEAN_FILES += arch/x86/boot/fdimage \
+              arch/x86/boot/image.iso \
+              arch/x86/boot/mtools.conf
index 57e714a47af7aff0e78512860c9a004db49c1d5f..a804860022e65a7ec6c5f71a81b7011d0cee6852 100644 (file)
@@ -127,7 +127,7 @@ archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
 define archhelp
-  echo  '* bzImage     - Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
+  echo  '* bzImage     - Compressed kernel image (arch/x86/boot/bzImage)'
   echo  '  install     - Install kernel using'
   echo  '                 (your) ~/bin/installkernel or'
   echo  '                 (distribution) /sbin/installkernel or'
@@ -137,8 +137,8 @@ define archhelp
   echo  '  isoimage     - Create a boot CD-ROM image'
 endef
 
-CLEAN_FILES += arch/$(ARCH)/boot/fdimage \
-              arch/$(ARCH)/boot/image.iso \
-              arch/$(ARCH)/boot/mtools.conf
+CLEAN_FILES += arch/x86/boot/fdimage \
+              arch/x86/boot/image.iso \
+              arch/x86/boot/mtools.conf
 
 
index 89dbf970e058c845e676f8b2be9efc65dcbdfe84..7a3116ccf3878d6e3212f8d4e346a3ceef912e8b 100644 (file)
@@ -49,10 +49,10 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE)
 
 # How to compile the 16-bit code.  Note we always compile for -march=i386,
 # that way we can complain to the user if the CPU is insufficient.
-cflags-i386   := 
-cflags-x86_64 := -m32
+cflags-$(CONFIG_X86_32) :=
+cflags-$(CONFIG_X86_64) := -m32
 KBUILD_CFLAGS  := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
-                  $(cflags-$(ARCH)) \
+                  $(cflags-y) \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/code16gcc.h \
index e655a89c5510fc929f787680811eb9ae981a03e1..769065bd23d776dc6c96a171f87b7071fd3719a6 100644 (file)
@@ -42,13 +42,7 @@ static struct cpu_features cpu;
 static u32 cpu_vendor[3];
 static u32 err_flags[NCAPINTS];
 
-#ifdef CONFIG_X86_64
-static const int req_level = 64;
-#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY)
 static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
-#else
-static const int req_level = 3;
-#endif
 
 static const u32 req_flags[NCAPINTS] =
 {
index 2e559233725a453845d03e19179e8620399f15ce..fa6bed1fac14862b86936f1bc45af5c9b64aa7cf 100644 (file)
  * void protected_mode_jump(u32 entrypoint, u32 bootparams);
  */
 protected_mode_jump:
-       xorl    %ebx, %ebx              # Flag to indicate this is a boot
        movl    %edx, %esi              # Pointer to boot_params table
        movl    %eax, 2f                # Patch ljmpl instruction
-       jmp     1f                      # Short jump to flush instruction q.
 
-1:
        movw    $__BOOT_DS, %cx
+       xorl    %ebx, %ebx              # Per the 32-bit boot protocol
+       xorl    %ebp, %ebp              # Per the 32-bit boot protocol
+       xorl    %edi, %edi              # Per the 32-bit boot protocol
 
        movl    %cr0, %edx
        orb     $1, %dl                 # Protected mode (PE) bit
        movl    %edx, %cr0
+       jmp     1f                      # Short jump to serialize on 386/486
+1:
 
        movw    %cx, %ds
        movw    %cx, %es
index 18b23181090808b953f91568d6183345b8028fd1..df588f0f76e1c9c3d8027a3baced0089de612832 100644 (file)
@@ -159,20 +159,16 @@ sysenter_do_call:
 
 sysenter_tracesys:
        CFI_RESTORE_STATE
+       xchgl   %r9d,%ebp
        SAVE_REST
        CLEAR_RREGS
+       movq    %r9,R9(%rsp)
        movq    $-ENOSYS,RAX(%rsp)      /* really needed? */
        movq    %rsp,%rdi        /* &pt_regs -> arg1 */
        call    syscall_trace_enter
        LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
-       movl    %ebp, %ebp
-       /* no need to do an access_ok check here because rbp has been
-          32bit zero extended */ 
-1:     movl    (%rbp),%r9d
-       .section __ex_table,"a"
-       .quad 1b,ia32_badarg
-       .previous
+       xchgl   %ebp,%r9d
        jmp     sysenter_do_call
        CFI_ENDPROC
 ENDPROC(ia32_sysenter_target)
@@ -262,20 +258,17 @@ cstar_do_call:
        
 cstar_tracesys:        
        CFI_RESTORE_STATE
+       xchgl %r9d,%ebp
        SAVE_REST
        CLEAR_RREGS
+       movq %r9,R9(%rsp)
        movq $-ENOSYS,RAX(%rsp) /* really needed? */
        movq %rsp,%rdi        /* &pt_regs -> arg1 */
        call syscall_trace_enter
        LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
+       xchgl %ebp,%r9d
        movl RSP-ARGOFFSET(%rsp), %r8d
-       /* no need to do an access_ok check here because r8 has been
-          32bit zero extended */ 
-1:     movl    (%r8),%r9d
-       .section __ex_table,"a"
-       .quad 1b,ia32_badarg
-       .previous
        jmp cstar_do_call
 END(ia32_cstar_target)
                                
index f52770ef0ee3efea18ca5b44ebbee95117e42f91..4a233ad6269cce1f2e7408af2137f9e8e92ba39a 100644 (file)
@@ -228,8 +228,6 @@ static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
        return ret;
 }
 
-#define COMPAT_GDT_ENTRY_TLS_MIN 6
-
 asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
 {
        struct task_struct *child;
@@ -248,6 +246,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
        case PTRACE_SYSCALL:
        case PTRACE_OLDSETOPTIONS:
        case PTRACE_SETOPTIONS:
+       case PTRACE_SET_THREAD_AREA:
+       case PTRACE_GET_THREAD_AREA:
                return sys_ptrace(request, pid, addr, data); 
 
        default:
@@ -271,12 +271,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
        case PTRACE_SETSIGINFO:
        case PTRACE_GETSIGINFO:
                return ptrace32_siginfo(request, pid, addr, data);
-
-       case PTRACE_SET_THREAD_AREA:
-       case PTRACE_GET_THREAD_AREA:
-               return sys_ptrace(request, pid,
-                       addr + GDT_ENTRY_TLS_MIN - COMPAT_GDT_ENTRY_TLS_MIN,
-                       data);
        }
 
        child = ptrace_get_task_struct(pid);
index b9d679820306d10d69078d14d7cb18cfbec33c26..a7bc93c27662f058711fe5349acb44cd08876bf1 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 extra-y := head_32.o init_task.o vmlinux.lds
+CPPFLAGS_vmlinux.lds += -Ui386
 
 obj-y  := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
                ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
@@ -60,7 +61,7 @@ quiet_cmd_syscall = SYSCALL $@
       cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
                          -Wl,-T,$(filter-out FORCE,$^) -o $@
 
-export CPPFLAGS_vsyscall_32.lds += -P -C -U$(ARCH)
+export CPPFLAGS_vsyscall_32.lds += -P -C -Ui386
 
 vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
                 $(call ld-option, -Wl$(comma)--hash-style=sysv)
index 24671c3838b3bb3e8a4b301be277fcb0ef62d9ee..5a88890d8ee9a4561c956bbd4b6f293c9933cb8f 100644 (file)
@@ -3,7 +3,9 @@
 #
 
 extra-y        := head_64.o head64.o init_task.o vmlinux.lds
+CPPFLAGS_vmlinux.lds += -Ux86_64
 EXTRA_AFLAGS   := -traditional
+
 obj-y  := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
                ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
                x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
index 289247d974c60fe77ed4b989a2a2634734392ab9..0ca27c7b0e8db00335d47dc158557bf4915aede6 100644 (file)
@@ -637,6 +637,38 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table)
        }
 
        hpet_address = hpet_tbl->address.address;
+
+       /*
+        * Some broken BIOSes advertise HPET at 0x0. We really do not
+        * want to allocate a resource there.
+        */
+       if (!hpet_address) {
+               printk(KERN_WARNING PREFIX
+                      "HPET id: %#x base: %#lx is invalid\n",
+                      hpet_tbl->id, hpet_address);
+               return 0;
+       }
+#ifdef CONFIG_X86_64
+       /*
+        * Some even more broken BIOSes advertise HPET at
+        * 0xfed0000000000000 instead of 0xfed00000. Fix it up and add
+        * some noise:
+        */
+       if (hpet_address == 0xfed0000000000000UL) {
+               if (!hpet_force_user) {
+                       printk(KERN_WARNING PREFIX "HPET id: %#x "
+                              "base: 0xfed0000000000000 is bogus\n "
+                              "try hpet=force on the kernel command line to "
+                              "fix it up to 0xfed00000.\n", hpet_tbl->id);
+                       hpet_address = 0;
+                       return 0;
+               }
+               printk(KERN_WARNING PREFIX
+                      "HPET id: %#x base: 0xfed0000000000000 fixed up "
+                      "to 0xfed00000.\n", hpet_tbl->id);
+               hpet_address >>= 32;
+       }
+#endif
        printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
               hpet_tbl->id, hpet_address);
 
index f63e5ff0aca12ac5e386076772a6ea90f44a2e2d..a25db514c719ef939bbb9e8069339a50e39c4dbc 100644 (file)
@@ -49,6 +49,9 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
        if (cpu_has(c, X86_FEATURE_EST))
                buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
 
+       if (cpu_has(c, X86_FEATURE_ACPI))
+               buf[2] |= ACPI_PDC_T_FFH;
+
        obj->type = ACPI_TYPE_BUFFER;
        obj->buffer.length = 12;
        obj->buffer.pointer = (u8 *) buf;
similarity index 77%
rename from arch/x86/kernel/cpu/cpufreq/Kconfig_32
rename to arch/x86/kernel/cpu/cpufreq/Kconfig
index d8c6f132dc7a1f7ca95306e2e15ab2536f5966f1..151eda0a23fc40be379c71b409b6cf846d0d3e2f 100644 (file)
@@ -19,6 +19,9 @@ config X86_ACPI_CPUFREQ
          Processor Performance States.
          This driver also supports Intel Enhanced Speedstep.
 
+         To compile this driver as a module, choose M here: the
+         module will be called acpi-cpufreq.
+
          For details, take a look at <file:Documentation/cpu-freq/>.
 
          If in doubt, say N.
@@ -26,7 +29,7 @@ config X86_ACPI_CPUFREQ
 config ELAN_CPUFREQ
        tristate "AMD Elan SC400 and SC410"
        select CPU_FREQ_TABLE
-       depends on X86_ELAN
+       depends on X86_32 && X86_ELAN
        ---help---
          This adds the CPUFreq driver for AMD Elan SC400 and SC410
          processors.
@@ -42,7 +45,7 @@ config ELAN_CPUFREQ
 config SC520_CPUFREQ
        tristate "AMD Elan SC520"
        select CPU_FREQ_TABLE
-       depends on X86_ELAN
+       depends on X86_32 && X86_ELAN
        ---help---
          This adds the CPUFreq driver for AMD Elan SC520 processor.
 
@@ -54,6 +57,7 @@ config SC520_CPUFREQ
 config X86_POWERNOW_K6
        tristate "AMD Mobile K6-2/K6-3 PowerNow!"
        select CPU_FREQ_TABLE
+       depends on X86_32
        help
          This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
          AMD K6-3+ processors.
@@ -65,6 +69,7 @@ config X86_POWERNOW_K6
 config X86_POWERNOW_K7
        tristate "AMD Mobile Athlon/Duron PowerNow!"
        select CPU_FREQ_TABLE
+       depends on X86_32
        help
          This adds the CPUFreq driver for mobile AMD K7 mobile processors.
 
@@ -76,23 +81,27 @@ config X86_POWERNOW_K7_ACPI
        bool
        depends on X86_POWERNOW_K7 && ACPI_PROCESSOR
        depends on !(X86_POWERNOW_K7 = y && ACPI_PROCESSOR = m)
+       depends on X86_32
        default y
 
 config X86_POWERNOW_K8
        tristate "AMD Opteron/Athlon64 PowerNow!"
        select CPU_FREQ_TABLE
-       depends on EXPERIMENTAL
        help
          This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
 
+         To compile this driver as a module, choose M here: the
+         module will be called powernow-k8.
+
          For details, take a look at <file:Documentation/cpu-freq/>.
 
          If in doubt, say N.
 
 config X86_POWERNOW_K8_ACPI
-       bool "ACPI Support"
-       select ACPI_PROCESSOR
-       depends on ACPI && X86_POWERNOW_K8
+       bool
+       prompt "ACPI Support" if X86_32
+       depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR
+       depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
        default y
        help
          This provides access to the K8s Processor Performance States via ACPI.
@@ -104,7 +113,7 @@ config X86_POWERNOW_K8_ACPI
 
 config X86_GX_SUSPMOD
        tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
-       depends on PCI
+       depends on X86_32 && PCI
        help
         This add the CPUFreq driver for NatSemi Geode processors which
         support suspend modulation.
@@ -114,15 +123,20 @@ config X86_GX_SUSPMOD
         If in doubt, say N.
 
 config X86_SPEEDSTEP_CENTRINO
-       tristate "Intel Enhanced SpeedStep"
+       tristate "Intel Enhanced SpeedStep (deprecated)"
        select CPU_FREQ_TABLE
-       select X86_SPEEDSTEP_CENTRINO_TABLE
+       select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32
+       depends on X86_32 || (X86_64 && ACPI_PROCESSOR)
        help
+         This is deprecated and this functionality is now merged into
+         acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
+         speedstep_centrino.
          This adds the CPUFreq driver for Enhanced SpeedStep enabled
-         mobile CPUs.  This means Intel Pentium M (Centrino) CPUs. However,
-         you also need to say Y to "Use ACPI tables to decode..." below
-         [which might imply enabling ACPI] if you want to use this driver
-         on non-Banias CPUs.
+         mobile CPUs.  This means Intel Pentium M (Centrino) CPUs
+         or 64bit enabled Intel Xeons.
+
+         To compile this driver as a module, choose M here: the
+         module will be called speedstep-centrino.
 
          For details, take a look at <file:Documentation/cpu-freq/>.
 
@@ -130,7 +144,7 @@ config X86_SPEEDSTEP_CENTRINO
 
 config X86_SPEEDSTEP_CENTRINO_TABLE
        bool "Built-in tables for Banias CPUs"
-       depends on X86_SPEEDSTEP_CENTRINO
+       depends on X86_32 && X86_SPEEDSTEP_CENTRINO
        default y
        help
          Use built-in tables for Banias CPUs if ACPI encoding
@@ -141,6 +155,7 @@ config X86_SPEEDSTEP_CENTRINO_TABLE
 config X86_SPEEDSTEP_ICH
        tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
        select CPU_FREQ_TABLE
+       depends on X86_32
        help
          This adds the CPUFreq driver for certain mobile Intel Pentium III
          (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
@@ -154,7 +169,7 @@ config X86_SPEEDSTEP_ICH
 config X86_SPEEDSTEP_SMI
        tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
        select CPU_FREQ_TABLE
-       depends on EXPERIMENTAL
+       depends on X86_32 && EXPERIMENTAL
        help
          This adds the CPUFreq driver for certain mobile Intel Pentium III
          (Coppermine), all mobile Intel Pentium III-M (Tualatin)
@@ -169,15 +184,24 @@ config X86_P4_CLOCKMOD
        select CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for Intel Pentium 4 / XEON
-         processors.
+         processors.  When enabled it will lower CPU temperature by skipping
+         clocks.
+
+         This driver should be only used in exceptional
+         circumstances when very low power is needed because it causes severe
+         slowdowns and noticeable latencies.  Normally Speedstep should be used
+         instead.
+
+         To compile this driver as a module, choose M here: the
+         module will be called p4-clockmod.
 
          For details, take a look at <file:Documentation/cpu-freq/>.
 
-         If in doubt, say N.
+         Unless you are absolutely sure say N.
 
 config X86_CPUFREQ_NFORCE2
        tristate "nVidia nForce2 FSB changing"
-       depends on EXPERIMENTAL
+       depends on X86_32 && EXPERIMENTAL
        help
          This adds the CPUFreq driver for FSB changing on nVidia nForce2
          platforms.
@@ -188,6 +212,7 @@ config X86_CPUFREQ_NFORCE2
 
 config X86_LONGRUN
        tristate "Transmeta LongRun"
+       depends on X86_32
        help
          This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors
          which support LongRun.
@@ -199,7 +224,7 @@ config X86_LONGRUN
 config X86_LONGHAUL
        tristate "VIA Cyrix III Longhaul"
        select CPU_FREQ_TABLE
-       depends on ACPI_PROCESSOR
+       depends on X86_32 && ACPI_PROCESSOR
        help
          This adds the CPUFreq driver for VIA Samuel/CyrixIII,
          VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
@@ -212,7 +237,7 @@ config X86_LONGHAUL
 config X86_E_POWERSAVER
        tristate "VIA C7 Enhanced PowerSaver (EXPERIMENTAL)"
        select CPU_FREQ_TABLE
-       depends on EXPERIMENTAL
+       depends on X86_32 && EXPERIMENTAL
        help
          This adds the CPUFreq driver for VIA C7 processors.
 
@@ -233,11 +258,11 @@ config X86_ACPI_CPUFREQ_PROC_INTF
 
 config X86_SPEEDSTEP_LIB
        tristate
-       default X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD
+       default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
 
 config X86_SPEEDSTEP_RELAXED_CAP_CHECK
        bool "Relaxed speedstep capability checks"
-       depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH)
+       depends on X86_32 && (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH)
        help
          Don't perform all checks for a speedstep capable system which would
          normally be done. Some ancient or strange systems, though speedstep
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig_64 b/arch/x86/kernel/cpu/cpufreq/Kconfig_64
deleted file mode 100644 (file)
index 9c9699f..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# CPU Frequency scaling
-#
-
-menu "CPU Frequency scaling"
-
-source "drivers/cpufreq/Kconfig"
-
-if CPU_FREQ
-
-comment "CPUFreq processor drivers"
-
-config X86_POWERNOW_K8
-       tristate "AMD Opteron/Athlon64 PowerNow!"
-       select CPU_FREQ_TABLE
-       help
-         This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
-
-         To compile this driver as a module, choose M here: the
-         module will be called powernow-k8.
-
-         For details, take a look at <file:Documentation/cpu-freq/>.
-
-         If in doubt, say N.
-
-config X86_POWERNOW_K8_ACPI
-       bool
-       depends on X86_POWERNOW_K8 && ACPI_PROCESSOR
-       depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
-       default y
-
-config X86_SPEEDSTEP_CENTRINO
-       tristate "Intel Enhanced SpeedStep (deprecated)"
-       select CPU_FREQ_TABLE
-       depends on ACPI_PROCESSOR
-       help
-         This is deprecated and this functionality is now merged into
-         acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
-         speedstep_centrino.
-         This adds the CPUFreq driver for Enhanced SpeedStep enabled
-         mobile CPUs.  This means Intel Pentium M (Centrino) CPUs
-         or 64bit enabled Intel Xeons.
-
-         To compile this driver as a module, choose M here: the
-         module will be called speedstep-centrino.
-
-         For details, take a look at <file:Documentation/cpu-freq/>.
-
-         If in doubt, say N.
-
-config X86_ACPI_CPUFREQ
-       tristate "ACPI Processor P-States driver"
-       select CPU_FREQ_TABLE
-       depends on ACPI_PROCESSOR
-       help
-         This driver adds a CPUFreq driver which utilizes the ACPI
-         Processor Performance States.
-         This driver also supports Intel Enhanced Speedstep.
-
-         To compile this driver as a module, choose M here: the
-         module will be called acpi-cpufreq.
-
-         For details, take a look at <file:Documentation/cpu-freq/>.
-
-         If in doubt, say N.
-
-comment "shared options"
-
-config X86_ACPI_CPUFREQ_PROC_INTF
-       bool "/proc/acpi/processor/../performance interface (deprecated)"
-       depends on PROC_FS
-       depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K8_ACPI
-       help
-         This enables the deprecated /proc/acpi/processor/../performance
-         interface. While it is helpful for debugging, the generic,
-         cross-architecture cpufreq interfaces should be used.
-
-         If in doubt, say N.
-
-config X86_P4_CLOCKMOD
-       tristate "Intel Pentium 4 clock modulation"
-       depends on EMBEDDED
-       select CPU_FREQ_TABLE
-       help
-         This adds the clock modulation driver for Intel Pentium 4 / XEON
-         processors.  When enabled it will lower CPU temperature by skipping
-         clocks.
-
-         This driver should be only used in exceptional
-         circumstances when very low power is needed because it causes severe
-         slowdowns and noticeable latencies.  Normally Speedstep should be used
-         instead.
-
-         To compile this driver as a module, choose M here: the
-         module will be called p4-clockmod.
-
-         For details, take a look at <file:Documentation/cpu-freq/>.
-
-         Unless you are absolutely sure say N.
-
-
-config X86_SPEEDSTEP_LIB
-       tristate
-       default X86_P4_CLOCKMOD
-
-endif
-
-endmenu
index 9c36a53676b770830e1efffb5770788d34ab2ee4..99e1ef9939bec24bc210791eecc6f23f328c24ae 100644 (file)
@@ -46,7 +46,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 2.00.00"
+#define VERSION "version 2.20.00"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -73,33 +73,11 @@ static u32 find_khz_freq_from_fid(u32 fid)
        return 1000 * find_freq_from_fid(fid);
 }
 
-/* Return a frequency in MHz, given an input fid and did */
-static u32 find_freq_from_fiddid(u32 fid, u32 did)
+static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate)
 {
-       if (current_cpu_data.x86 == 0x10)
-               return 100 * (fid + 0x10) >> did;
-       else
-               return 100 * (fid + 0x8) >> did;
-}
-
-static u32 find_khz_freq_from_fiddid(u32 fid, u32 did)
-{
-       return 1000 * find_freq_from_fiddid(fid, did);
-}
-
-static u32 find_fid_from_pstate(u32 pstate)
-{
-       u32 hi, lo;
-       rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
-       return lo & HW_PSTATE_FID_MASK;
+       return data[pstate].frequency;
 }
 
-static u32 find_did_from_pstate(u32 pstate)
-{
-       u32 hi, lo;
-       rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
-       return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
-}
 
 /* Return the vco fid for an input fid
  *
@@ -142,9 +120,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
        if (cpu_family == CPU_HW_PSTATE) {
                rdmsr(MSR_PSTATE_STATUS, lo, hi);
                i = lo & HW_PSTATE_MASK;
-               rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi);
-               data->currfid = lo & HW_PSTATE_FID_MASK;
-               data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
+               data->currpstate = i;
                return 0;
        }
        do {
@@ -295,7 +271,7 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid,
 static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
 {
        wrmsr(MSR_PSTATE_CTRL, pstate, 0);
-       data->currfid = find_fid_from_pstate(pstate);
+       data->currpstate = pstate;
        return 0;
 }
 
@@ -845,17 +821,20 @@ err_out:
 static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
 {
        int i;
+       u32 hi = 0, lo = 0;
+       rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo);
+       data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
 
        for (i = 0; i < data->acpi_data.state_count; i++) {
                u32 index;
                u32 hi = 0, lo = 0;
-               u32 fid;
-               u32 did;
 
                index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
-               if (index > MAX_HW_PSTATE) {
+               if (index > data->max_hw_pstate) {
                        printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
                        printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
+                       powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+                       continue;
                }
                rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
                if (!(hi & HW_PSTATE_VALID_MASK)) {
@@ -864,22 +843,9 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf
                        continue;
                }
 
-               fid = lo & HW_PSTATE_FID_MASK;
-               did = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
+               powernow_table[i].index = index;
 
-               dprintk("   %d : fid 0x%x, did 0x%x\n", index, fid, did);
-
-               powernow_table[i].index = index | (fid << HW_FID_INDEX_SHIFT) | (did << HW_DID_INDEX_SHIFT);
-
-               powernow_table[i].frequency = find_khz_freq_from_fiddid(fid, did);
-
-               if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
-                       printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
-                               powernow_table[i].frequency,
-                               (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
-                       powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-                       continue;
-               }
+               powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000;
        }
        return 0;
 }
@@ -1020,22 +986,18 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i
 /* Take a frequency, and issue the hardware pstate transition command */
 static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index)
 {
-       u32 fid = 0;
-       u32 did = 0;
        u32 pstate = 0;
        int res, i;
        struct cpufreq_freqs freqs;
 
        dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
 
-       /* get fid did for hardware pstate transition */
+       /* get MSR index for hardware pstate transition */
        pstate = index & HW_PSTATE_MASK;
-       if (pstate > MAX_HW_PSTATE)
+       if (pstate > data->max_hw_pstate)
                return 0;
-       fid = (index & HW_FID_INDEX_MASK) >> HW_FID_INDEX_SHIFT;
-       did = (index & HW_DID_INDEX_MASK) >> HW_DID_INDEX_SHIFT;
-       freqs.old = find_khz_freq_from_fiddid(data->currfid, data->currdid);
-       freqs.new = find_khz_freq_from_fiddid(fid, did);
+       freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+       freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
 
        for_each_cpu_mask(i, *(data->available_cores)) {
                freqs.cpu = i;
@@ -1043,9 +1005,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i
        }
 
        res = transition_pstate(data, pstate);
-       data->currfid = find_fid_from_pstate(pstate);
-       data->currdid = find_did_from_pstate(pstate);
-       freqs.new = find_khz_freq_from_fiddid(data->currfid, data->currdid);
+       freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
 
        for_each_cpu_mask(i, *(data->available_cores)) {
                freqs.cpu = i;
@@ -1090,10 +1050,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        if (query_current_values_with_pending_wait(data))
                goto err_out;
 
-       if (cpu_family == CPU_HW_PSTATE)
-               dprintk("targ: curr fid 0x%x, did 0x%x\n",
-                       data->currfid, data->currdid);
-       else {
+       if (cpu_family != CPU_HW_PSTATE) {
                dprintk("targ: curr fid 0x%x, vid 0x%x\n",
                data->currfid, data->currvid);
 
@@ -1124,7 +1081,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        mutex_unlock(&fidvid_mutex);
 
        if (cpu_family == CPU_HW_PSTATE)
-               pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
+               pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate);
        else
                pol->cur = find_khz_freq_from_fid(data->currfid);
        ret = 0;
@@ -1223,7 +1180,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
            + (3 * (1 << data->irt) * 10)) * 1000;
 
        if (cpu_family == CPU_HW_PSTATE)
-               pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
+               pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
        else
                pol->cur = find_khz_freq_from_fid(data->currfid);
        dprintk("policy current frequency %d kHz\n", pol->cur);
@@ -1240,8 +1197,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
 
        if (cpu_family == CPU_HW_PSTATE)
-               dprintk("cpu_init done, current fid 0x%x, did 0x%x\n",
-                       data->currfid, data->currdid);
+               dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate);
        else
                dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
                        data->currfid, data->currvid);
@@ -1297,7 +1253,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
                goto out;
 
        if (cpu_family == CPU_HW_PSTATE)
-               khz = find_khz_freq_from_fiddid(data->currfid, data->currdid);
+               khz = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
        else
                khz = find_khz_freq_from_fid(data->currfid);
 
index 7c4f6e0faed4a555ac599837d347dee7958d4feb..afd2b520d35c6258a25a2bc0f804279b647ae430 100644 (file)
@@ -10,6 +10,7 @@ struct powernow_k8_data {
 
        u32 numps;  /* number of p-states */
        u32 batps;  /* number of p-states supported on battery */
+       u32 max_hw_pstate; /* maximum legal hardware pstate */
 
        /* these values are constant when the PSB is used to determine
         * vid/fid pairings, but are modified during the ->target() call
@@ -21,8 +22,8 @@ struct powernow_k8_data {
        u32 plllock; /* pll lock time, units 1 us */
         u32 exttype; /* extended interface = 1 */
 
-       /* keep track of the current fid / vid or did */
-       u32 currvid, currfid, currdid;
+       /* keep track of the current fid / vid or pstate */
+       u32 currvid, currfid, currpstate;
 
        /* the powernow_table includes all frequency and vid/fid pairings:
         * fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -87,23 +88,14 @@ struct powernow_k8_data {
 
 /* Hardware Pstate _PSS and MSR definitions */
 #define USE_HW_PSTATE          0x00000080
-#define HW_PSTATE_FID_MASK     0x0000003f
-#define HW_PSTATE_DID_MASK     0x000001c0
-#define HW_PSTATE_DID_SHIFT    6
 #define HW_PSTATE_MASK                 0x00000007
 #define HW_PSTATE_VALID_MASK   0x80000000
-#define HW_FID_INDEX_SHIFT     8
-#define HW_FID_INDEX_MASK      0x0000ff00
-#define HW_DID_INDEX_SHIFT     16
-#define HW_DID_INDEX_MASK      0x00ff0000
-#define HW_WATTS_MASK          0xff
-#define HW_PWR_DVR_MASK                0x300
-#define HW_PWR_DVR_SHIFT       8
-#define HW_PWR_MAX_MULT                3
-#define MAX_HW_PSTATE          8       /* hw pstate supports up to 8 */
+#define HW_PSTATE_MAX_MASK     0x000000f0
+#define HW_PSTATE_MAX_SHIFT    4
 #define MSR_PSTATE_DEF_BASE    0xc0010064 /* base of Pstate MSRs */
 #define MSR_PSTATE_STATUS      0xc0010063 /* Pstate Status MSR */
 #define MSR_PSTATE_CTRL        0xc0010062 /* Pstate control MSR */
+#define MSR_PSTATE_CUR_LIMIT   0xc0010061 /* pstate current limit MSR */
 
 /* define the two driver architectures */
 #define CPU_OPTERON 0
index b9f802e35209187a45045b3576027f9f0ac9de25..4b21d29fb5aa575b6146132db6dadd319ac5ca4a 100644 (file)
@@ -802,13 +802,15 @@ static struct sysdev_attribute *mce_attributes[] = {
        NULL
 };
 
+static cpumask_t mce_device_initialized = CPU_MASK_NONE;
+
 /* Per cpu sysdev init.  All of the cpus still share the same ctl bank */
 static __cpuinit int mce_create_device(unsigned int cpu)
 {
        int err;
        int i;
 
-       if (!mce_available(&cpu_data(cpu)))
+       if (!mce_available(&boot_cpu_data))
                return -EIO;
 
        memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
@@ -825,6 +827,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
                if (err)
                        goto error;
        }
+       cpu_set(cpu, mce_device_initialized);
 
        return 0;
 error:
@@ -841,10 +844,14 @@ static void mce_remove_device(unsigned int cpu)
 {
        int i;
 
+       if (!cpu_isset(cpu, mce_device_initialized))
+               return;
+
        for (i = 0; mce_attributes[i]; i++)
                sysdev_remove_file(&per_cpu(device_mce,cpu),
                        mce_attributes[i]);
        sysdev_unregister(&per_cpu(device_mce,cpu));
+       cpu_clear(cpu, mce_device_initialized);
 }
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -852,21 +859,18 @@ static int
 mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
-       int err = 0;
 
        switch (action) {
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
-               err = mce_create_device(cpu);
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               mce_create_device(cpu);
                break;
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                mce_remove_device(cpu);
                break;
        }
-       return err ? NOTIFY_BAD : NOTIFY_OK;
+       return NOTIFY_OK;
 }
 
 static struct notifier_block mce_cpu_notifier = {
index 9abbdf7562c50ffe86a3024d07cc5829f902d8d6..3b20613325dcbf88ef7cd7c3626d8a744b12ca4a 100644 (file)
@@ -139,13 +139,12 @@ struct set_mtrr_data {
        mtrr_type       smp_type;
 };
 
-#ifdef CONFIG_SMP
-
 static void ipi_handler(void *info)
 /*  [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
     [RETURNS] Nothing.
 */
 {
+#ifdef CONFIG_SMP
        struct set_mtrr_data *data = info;
        unsigned long flags;
 
@@ -168,9 +167,8 @@ static void ipi_handler(void *info)
 
        atomic_dec(&data->count);
        local_irq_restore(flags);
-}
-
 #endif
+}
 
 static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
        return type1 == MTRR_TYPE_UNCACHABLE ||
index 066f8c6af4dfa0e92370aed065f41ca3d84d83d4..3900e46d66db4c91ea8b898504af963dc3ff4df4 100644 (file)
@@ -89,8 +89,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        int fpu_exception;
 
 #ifdef CONFIG_SMP
-       if (!cpu_online(n))
-               return 0;
        n = c->cpu_index;
 #endif
        seq_printf(m, "processor\t: %d\n"
@@ -177,14 +175,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
        if (*pos == 0)  /* just in case, cpu 0 is not the first */
-               *pos = first_cpu(cpu_possible_map);
-       if ((*pos) < NR_CPUS && cpu_possible(*pos))
+               *pos = first_cpu(cpu_online_map);
+       if ((*pos) < NR_CPUS && cpu_online(*pos))
                return &cpu_data(*pos);
        return NULL;
 }
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       *pos = next_cpu(*pos, cpu_possible_map);
+       *pos = next_cpu(*pos, cpu_online_map);
        return c_start(m, pos);
 }
 static void c_stop(struct seq_file *m, void *v)
index 56c1f11471099103292b5aa291a388113d27fa9b..bfaff28fb1348f41f14b7caadf363ca86879595e 100644 (file)
@@ -92,13 +92,14 @@ int save_i387(struct _fpstate __user *buf)
        if (task_thread_info(tsk)->status & TS_USEDFPU) {
                err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
                if (err) return err;
+               task_thread_info(tsk)->status &= ~TS_USEDFPU;
                stts();
-               } else {
-               if (__copy_to_user(buf, &tsk->thread.i387.fxsave, 
+       } else {
+               if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
                                   sizeof(struct i387_fxsave_struct)))
                        return -1;
-       } 
-               return 1;
+       }
+       return 1;
 }
 
 /*
index f35c6eb33da9b7a5e0caa1dee4f0e075121349af..6bb80ea5f4eecbdee2206a1b04cd07278f0924e0 100644 (file)
@@ -962,7 +962,7 @@ static int EISA_ELCR(unsigned int irq)
 #define default_MCA_trigger(idx)       (1)
 #define default_MCA_polarity(idx)      (0)
 
-static int __init MPBIOS_polarity(int idx)
+static int MPBIOS_polarity(int idx)
 {
        int bus = mp_irqs[idx].mpc_srcbus;
        int polarity;
@@ -2830,6 +2830,25 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
        return 0;
 }
 
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+{
+       int i;
+
+       if (skip_ioapic_setup)
+               return -1;
+
+       for (i = 0; i < mp_irq_entries; i++)
+               if (mp_irqs[i].mpc_irqtype == mp_INT &&
+                   mp_irqs[i].mpc_srcbusirq == bus_irq)
+                       break;
+       if (i >= mp_irq_entries)
+               return -1;
+
+       *trigger = irq_trigger(i);
+       *polarity = irq_polarity(i);
+       return 0;
+}
+
 #endif /* CONFIG_ACPI */
 
 static int __init parse_disable_timer_pin_1(char *arg)
index 953328b55a30503c58f2f8b3ed0f30939ff4047c..435a8c9b55f854bce24e145f20e5cc04ff7b1509 100644 (file)
@@ -546,7 +546,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
 #define default_PCI_trigger(idx)       (1)
 #define default_PCI_polarity(idx)      (1)
 
-static int __init MPBIOS_polarity(int idx)
+static int MPBIOS_polarity(int idx)
 {
        int bus = mp_irqs[idx].mpc_srcbus;
        int polarity;
@@ -2222,8 +2222,27 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
        return 0;
 }
 
-#endif /* CONFIG_ACPI */
 
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+{
+       int i;
+
+       if (skip_ioapic_setup)
+               return -1;
+
+       for (i = 0; i < mp_irq_entries; i++)
+               if (mp_irqs[i].mpc_irqtype == mp_INT &&
+                   mp_irqs[i].mpc_srcbusirq == bus_irq)
+                       break;
+       if (i >= mp_irq_entries)
+               return -1;
+
+       *trigger = irq_trigger(i);
+       *polarity = irq_polarity(i);
+       return 0;
+}
+
+#endif /* CONFIG_ACPI */
 
 /*
  * This function currently is only a helper for the i386 smp boot process where
@@ -2260,3 +2279,4 @@ void __init setup_ioapic_dest(void)
        }
 }
 #endif
+
index f803ed0ed1c41ffea809a87ad70bb5e655346cfe..600fd404e4401b0901f3cba7fb80ef69aa518cbd 100644 (file)
@@ -51,13 +51,13 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
 
 static int endflag __initdata = 0;
 
-#ifdef CONFIG_SMP
 /* The performance counters used by NMI_LOCAL_APIC don't trigger when
  * the CPU is idle. To make sure the NMI watchdog really ticks on all
  * CPUs during the test make them busy.
  */
 static __init void nmi_cpu_busy(void *data)
 {
+#ifdef CONFIG_SMP
        local_irq_enable_in_hardirq();
        /* Intentionally don't use cpu_relax here. This is
           to make sure that the performance counter really ticks,
@@ -67,8 +67,8 @@ static __init void nmi_cpu_busy(void *data)
           care if they get somewhat less cycles. */
        while (endflag == 0)
                mb();
-}
 #endif
+}
 
 static int __init check_nmi_watchdog(void)
 {
index 1a07bbea7be36eadcea68843d7b727eaa03ee9a4..f452726c0fe276c2482e79b70ac1a1caedec7c5d 100644 (file)
@@ -39,6 +39,7 @@ struct device_fixup {
 static struct device_fixup fixups_table[] = {
 { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset },
+{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset },
 };
 
 /*
index 238633d3d09a7ac1d8a6427d2e26c3ce773291e8..30d94d1d5f5f38e222b8ac7e4a869a6e0ee91b01 100644 (file)
@@ -892,7 +892,6 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
 
 #ifdef CONFIG_SMP
        c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
-       c->cpu_index = 0;
 #endif
 }
 
@@ -1078,8 +1077,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
 
 #ifdef CONFIG_SMP
-       if (!cpu_online(c->cpu_index))
-               return 0;
        cpu = c->cpu_index;
 #endif
 
@@ -1171,15 +1168,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
        if (*pos == 0)  /* just in case, cpu 0 is not the first */
-               *pos = first_cpu(cpu_possible_map);
-       if ((*pos) < NR_CPUS && cpu_possible(*pos))
+               *pos = first_cpu(cpu_online_map);
+       if ((*pos) < NR_CPUS && cpu_online(*pos))
                return &cpu_data(*pos);
        return NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       *pos = next_cpu(*pos, cpu_possible_map);
+       *pos = next_cpu(*pos, cpu_online_map);
        return c_start(m, pos);
 }
 
index c821edc32216b88c674d2a704f105fdf063c1014..368b1942b39aba509cfafe7fae629ef400a7a243 100644 (file)
@@ -82,18 +82,15 @@ static int set_rtc_mmss(unsigned long nowtime)
        int retval = 0;
        int real_seconds, real_minutes, cmos_minutes;
        unsigned char control, freq_select;
+       unsigned long flags;
 
 /*
- * IRQs are disabled when we're called from the timer interrupt,
- * no need for spin_lock_irqsave()
+ * set_rtc_mmss is called when irqs are enabled, so disable irqs here
  */
-
-       spin_lock(&rtc_lock);
-
+       spin_lock_irqsave(&rtc_lock, flags);
 /*
  * Tell the clock it's being set and stop it.
  */
-
        control = CMOS_READ(RTC_CONTROL);
        CMOS_WRITE(control | RTC_SET, RTC_CONTROL);
 
@@ -138,7 +135,7 @@ static int set_rtc_mmss(unsigned long nowtime)
        CMOS_WRITE(control, RTC_CONTROL);
        CMOS_WRITE(freq_select, RTC_FREQ_SELECT);
 
-       spin_unlock(&rtc_lock);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        return retval;
 }
@@ -164,21 +161,27 @@ unsigned long read_persistent_clock(void)
        unsigned century = 0;
 
        spin_lock_irqsave(&rtc_lock, flags);
+       /*
+        * if UIP is clear, then we have >= 244 microseconds before RTC
+        * registers will be updated.  Spec sheet says that this is the
+        * reliable way to read RTC - registers invalid (off bus) during update
+        */
+       while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+               cpu_relax();
 
-       do {
-               sec = CMOS_READ(RTC_SECONDS);
-               min = CMOS_READ(RTC_MINUTES);
-               hour = CMOS_READ(RTC_HOURS);
-               day = CMOS_READ(RTC_DAY_OF_MONTH);
-               mon = CMOS_READ(RTC_MONTH);
-               year = CMOS_READ(RTC_YEAR);
+
+       /* now read all RTC registers while stable with interrupts disabled */
+       sec = CMOS_READ(RTC_SECONDS);
+       min = CMOS_READ(RTC_MINUTES);
+       hour = CMOS_READ(RTC_HOURS);
+       day = CMOS_READ(RTC_DAY_OF_MONTH);
+       mon = CMOS_READ(RTC_MONTH);
+       year = CMOS_READ(RTC_YEAR);
 #ifdef CONFIG_ACPI
-               if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
-                                       acpi_gbl_FADT.century)
-                       century = CMOS_READ(acpi_gbl_FADT.century);
+       if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
+                               acpi_gbl_FADT.century)
+               century = CMOS_READ(acpi_gbl_FADT.century);
 #endif
-       } while (sec != CMOS_READ(RTC_SECONDS));
-
        spin_unlock_irqrestore(&rtc_lock, flags);
 
        /*
index a55b0902f9d3d08637a449032e5aa89f5a7aa027..92c56117eae5ed2af3cbdc37c6086d7a7dd25120 100644 (file)
@@ -93,38 +93,7 @@ struct lguest_data lguest_data = {
 };
 static cycle_t clock_base;
 
-/*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
- * real optimization trick!
- *
- * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
- * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
- * are reasonably expensive, batching them up makes sense.  For example, a
- * large munmap might update dozens of page table entries: that code calls
- * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
- * lguest_leave_lazy_mode().
- *
- * So, when we're in lazy mode, we call async_hypercall() to store the call for
- * future processing.  When lazy mode is turned off we issue a hypercall to
- * flush the stored calls.
- */
-static void lguest_leave_lazy_mode(void)
-{
-       paravirt_leave_lazy(paravirt_get_lazy_mode());
-       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
-}
-
-static void lazy_hcall(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3)
-{
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               hcall(call, arg1, arg2, arg3);
-       else
-               async_hcall(call, arg1, arg2, arg3);
-}
-
-/* async_hcall() is pretty simple: I'm quite proud of it really.  We have a
+/*G:037 async_hcall() is pretty simple: I'm quite proud of it really.  We have a
  * ring buffer of stored hypercalls which the Host will run though next time we
  * do a normal hypercall.  Each entry in the ring has 4 slots for the hypercall
  * arguments, and a "hcall_status" word which is 0 if the call is ready to go,
@@ -134,8 +103,8 @@ static void lazy_hcall(unsigned long call,
  * full and we just make the hypercall directly.  This has the nice side
  * effect of causing the Host to run all the stored calls in the ring buffer
  * which empties it for next time! */
-void async_hcall(unsigned long call,
-                unsigned long arg1, unsigned long arg2, unsigned long arg3)
+static void async_hcall(unsigned long call, unsigned long arg1,
+                       unsigned long arg2, unsigned long arg3)
 {
        /* Note: This code assumes we're uniprocessor. */
        static unsigned int next_call;
@@ -161,7 +130,37 @@ void async_hcall(unsigned long call,
        }
        local_irq_restore(flags);
 }
-/*:*/
+
+/*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
+ * real optimization trick!
+ *
+ * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
+ * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
+ * are reasonably expensive, batching them up makes sense.  For example, a
+ * large munmap might update dozens of page table entries: that code calls
+ * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
+ * lguest_leave_lazy_mode().
+ *
+ * So, when we're in lazy mode, we call async_hcall() to store the call for
+ * future processing. */
+static void lazy_hcall(unsigned long call,
+                      unsigned long arg1,
+                      unsigned long arg2,
+                      unsigned long arg3)
+{
+       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+               hcall(call, arg1, arg2, arg3);
+       else
+               async_hcall(call, arg1, arg2, arg3);
+}
+
+/* When lazy mode is turned off reset the per-cpu lazy mode variable and then
+ * issue a hypercall to flush any stored calls. */
+static void lguest_leave_lazy_mode(void)
+{
+       paravirt_leave_lazy(paravirt_get_lazy_mode());
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
+}
 
 /*G:033
  * After that diversion we return to our first native-instruction
index 952e7a89c2ac4f0cc218b310e6a0f84da3845d99..aad9d95469dc68dcb25b9fac93b743d44b7d9038 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/preempt.h>
 #include <linux/delay.h>
 
 #include <asm/processor.h>
@@ -42,11 +43,13 @@ static void delay_tsc(unsigned long loops)
 {
        unsigned long bclock, now;
 
+       preempt_disable();              /* TSC's are per-cpu */
        rdtscl(bclock);
        do {
                rep_nop();
                rdtscl(now);
        } while ((now-bclock) < loops);
+       preempt_enable();
 }
 
 /*
index 0ebbfb9e7c7f8d2b86abeb23f07b0cfbf0ebe56f..45cdd3fbd91c514f38e2c2782f7dbc0dcecd8e90 100644 (file)
@@ -10,7 +10,9 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/preempt.h>
 #include <linux/delay.h>
+
 #include <asm/delay.h>
 #include <asm/msr.h>
 
@@ -27,14 +29,15 @@ int read_current_timer(unsigned long *timer_value)
 void __delay(unsigned long loops)
 {
        unsigned bclock, now;
-       
+
+       preempt_disable();              /* TSC's are pre-cpu */
        rdtscl(bclock);
-       do
-       {
+       do {
                rep_nop(); 
                rdtscl(now);
        }
-       while((now-bclock) < loops);
+       while ((now-bclock) < loops);
+       preempt_enable();
 }
 EXPORT_SYMBOL(__delay);
 
index 26a2d4c54b684e8d3da8f451ad3c2be9e1ce262c..2132ca652df1d65de50fefab33bb81bde854c3db 100644 (file)
@@ -568,7 +568,7 @@ static voyager_module_t *voyager_initial_module;
  * boot cpu *after* all memory initialisation has been done (so we can
  * use kmalloc) but before smp initialisation, so we can probe the SMP
  * configuration and pick up necessary information.  */
-void
+void __init
 voyager_cat_init(void)
 {
        voyager_module_t **modpp = &voyager_initial_module;
index 69371434b0cfe9b3f2622b539423faa93cb44939..88124dd35406d2484f999c837833d4a9c270ba03 100644 (file)
@@ -1900,7 +1900,7 @@ voyager_smp_prepare_cpus(unsigned int max_cpus)
        smp_boot_cpus();
 }
 
-static void __devinit voyager_smp_prepare_boot_cpu(void)
+static void __cpuinit voyager_smp_prepare_boot_cpu(void)
 {
        init_gdt(smp_processor_id());
        switch_to_new_gdt();
@@ -1911,7 +1911,7 @@ static void __devinit voyager_smp_prepare_boot_cpu(void)
        cpu_set(smp_processor_id(), cpu_present_map);
 }
 
-static int __devinit
+static int __cpuinit
 voyager_cpu_up(unsigned int cpu)
 {
        /* This only works at boot for x86.  See "rewrite" above. */
index 2d88f7c6d6ac901a3f2f2ffe2f64f680706b435a..7e35078673a4a43f83fb70143cfb131eeb1e88c9 100644 (file)
@@ -77,6 +77,9 @@ count_resource(struct acpi_resource *acpi_res, void *data)
        struct acpi_resource_address64 addr;
        acpi_status status;
 
+       if (info->res_num >= PCI_BUS_NUM_RESOURCES)
+               return AE_OK;
+
        status = resource_to_addr(acpi_res, &addr);
        if (ACPI_SUCCESS(status))
                info->res_num++;
@@ -93,6 +96,9 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        unsigned long flags;
        struct resource *root;
 
+       if (info->res_num >= PCI_BUS_NUM_RESOURCES)
+               return AE_OK;
+
        status = resource_to_addr(acpi_res, &addr);
        if (!ACPI_SUCCESS(status))
                return AE_OK;
index 7a2ba4583939672ff39de6236172dafd1b14228a..e7bff0fbac235715ca5e8601d510414c38e56a9c 100644 (file)
@@ -20,7 +20,7 @@ quiet_cmd_syscall = SYSCALL $@
       cmd_syscall = $(CC) -m elf_x86_64 -nostdlib $(SYSCFLAGS_$(@F)) \
                          -Wl,-T,$(filter-out FORCE,$^) -o $@
 
-export CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+export CPPFLAGS_vdso.lds += -P -C
 
 vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \
                 $(call ld-option, -Wl$(comma)--hash-style=sysv) \
index 91f6e85d0fc2d7219c15816749337c64041ea3a2..3b1ae1abfba9abc1f00332ccb6c7af0805a8e403 100644 (file)
 #include <asm/vgtod.h>
 #include "vextern.h"
 
-long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
+long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
 {
        unsigned int dummy, p;
-       unsigned long j = 0;
 
-       /* Fast cache - only recompute value once per jiffies and avoid
-          relatively costly rdtscp/cpuid otherwise.
-          This works because the scheduler usually keeps the process
-          on the same CPU and this syscall doesn't guarantee its
-          results anyways.
-          We do this here because otherwise user space would do it on
-          its own in a likely inferior way (no access to jiffies).
-          If you don't like it pass NULL. */
-       if (tcache && tcache->blob[0] == (j = *vdso_jiffies)) {
-               p = tcache->blob[1];
-       } else if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) {
+       if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) {
                /* Load per CPU data from RDTSCP */
                rdtscp(dummy, dummy, p);
        } else {
                /* Load per CPU data from GDT */
                asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
        }
-       if (tcache) {
-               tcache->blob[0] = j;
-               tcache->blob[1] = p;
-       }
        if (cpu)
                *cpu = p & 0xfff;
        if (node)
index e47a9309eb485058b72d4649f631cf0029ee3dcb..0b4a47905575f2ee658d8a2f1e373aec71e935e5 100644 (file)
@@ -789,6 +789,20 @@ static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out)
                __cfq_slice_expired(cfqd, cfqq, timed_out);
 }
 
+static int start_idle_class_timer(struct cfq_data *cfqd)
+{
+       unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
+       unsigned long now = jiffies;
+
+       if (time_before(now, end) &&
+           time_after_eq(now, cfqd->last_end_request)) {
+               mod_timer(&cfqd->idle_class_timer, end);
+               return 1;
+       }
+
+       return 0;
+}
+
 /*
  * Get next queue for service. Unless we have a queue preemption,
  * we'll simply select the first cfqq in the service tree.
@@ -805,19 +819,14 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
        cfqq = rb_entry(n, struct cfq_queue, rb_node);
 
        if (cfq_class_idle(cfqq)) {
-               unsigned long end;
-
                /*
                 * if we have idle queues and no rt or be queues had
                 * pending requests, either allow immediate service if
                 * the grace period has passed or arm the idle grace
                 * timer
                 */
-               end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-               if (time_before(jiffies, end)) {
-                       mod_timer(&cfqd->idle_class_timer, end);
+               if (start_idle_class_timer(cfqd))
                        cfqq = NULL;
-               }
        }
 
        return cfqq;
@@ -2036,17 +2045,14 @@ out_cont:
 static void cfq_idle_class_timer(unsigned long data)
 {
        struct cfq_data *cfqd = (struct cfq_data *) data;
-       unsigned long flags, end;
+       unsigned long flags;
 
        spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 
        /*
         * race with a non-idle queue, reset timer
         */
-       end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-       if (!time_after_eq(jiffies, end))
-               mod_timer(&cfqd->idle_class_timer, end);
-       else
+       if (!start_idle_class_timer(cfqd))
                cfq_schedule_dispatch(cfqd);
 
        spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2068,9 +2074,10 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
                        cfq_put_queue(cfqd->async_cfqq[0][i]);
                if (cfqd->async_cfqq[1][i])
                        cfq_put_queue(cfqd->async_cfqq[1][i]);
-               if (cfqd->async_idle_cfqq)
-                       cfq_put_queue(cfqd->async_idle_cfqq);
        }
+
+       if (cfqd->async_idle_cfqq)
+               cfq_put_queue(cfqd->async_idle_cfqq);
 }
 
 static void cfq_exit_queue(elevator_t *e)
@@ -2125,6 +2132,7 @@ static void *cfq_init_queue(struct request_queue *q)
 
        INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
 
+       cfqd->last_end_request = jiffies;
        cfqd->cfq_quantum = cfq_quantum;
        cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
        cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
index 75c98d58f4ddf7252e2717e0924b9d6a8925b4e5..3b927be038501f178577da45ebb447c6dc27b90f 100644 (file)
@@ -1143,22 +1143,9 @@ EXPORT_SYMBOL(blk_queue_start_tag);
 void blk_queue_invalidate_tags(struct request_queue *q)
 {
        struct list_head *tmp, *n;
-       struct request *rq;
-
-       list_for_each_safe(tmp, n, &q->tag_busy_list) {
-               rq = list_entry_rq(tmp);
 
-               if (rq->tag == -1) {
-                       printk(KERN_ERR
-                              "%s: bad tag found on list\n", __FUNCTION__);
-                       list_del_init(&rq->queuelist);
-                       rq->cmd_flags &= ~REQ_QUEUED;
-               } else
-                       blk_queue_end_tag(q, rq);
-
-               rq->cmd_flags &= ~REQ_STARTED;
-               __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
-       }
+       list_for_each_safe(tmp, n, &q->tag_busy_list)
+               blk_requeue_request(q, list_entry_rq(tmp));
 }
 
 EXPORT_SYMBOL(blk_queue_invalidate_tags);
@@ -1634,15 +1621,7 @@ static void blk_backing_dev_unplug(struct backing_dev_info *bdi,
 {
        struct request_queue *q = bdi->unplug_io_data;
 
-       /*
-        * devices don't necessarily have an ->unplug_fn defined
-        */
-       if (q->unplug_fn) {
-               blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
-                                       q->rq.count[READ] + q->rq.count[WRITE]);
-
-               q->unplug_fn(q);
-       }
+       blk_unplug(q);
 }
 
 static void blk_unplug_work(struct work_struct *work)
@@ -1666,6 +1645,20 @@ static void blk_unplug_timeout(unsigned long data)
        kblockd_schedule_work(&q->unplug_work);
 }
 
+void blk_unplug(struct request_queue *q)
+{
+       /*
+        * devices don't necessarily have an ->unplug_fn defined
+        */
+       if (q->unplug_fn) {
+               blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
+                                       q->rq.count[READ] + q->rq.count[WRITE]);
+
+               q->unplug_fn(q);
+       }
+}
+EXPORT_SYMBOL(blk_unplug);
+
 /**
  * blk_start_queue - restart a previously stopped queue
  * @q:    The &struct request_queue in question
index da3a08fa9e4ff4f58a8337c502a776ed0c8fd1c0..b9f923ef173d8fc283e2122bc600e59039f0f396 100644 (file)
@@ -67,7 +67,21 @@ config ACPI_PROCFS
          and functions which do not yet exist in /sys.
 
          Say N to delete /proc/acpi/ files that have moved to /sys/
-
+config ACPI_PROCFS_POWER
+       bool "Deprecated power /proc/acpi folders"
+       depends on PROC_FS
+       default y
+       ---help---
+         For backwards compatibility, this option allows
+          deprecated power /proc/acpi/ folders to exist, even when
+          they have been replaced by functions in /sys.
+          The deprecated folders (and their replacements) include:
+         /proc/acpi/battery/* (/sys/class/power_supply/*)
+         /proc/acpi/ac_adapter/* (sys/class/power_supply/*)
+         This option has no effect on /proc/acpi/ folders
+         and functions, which do not yet exist in /sys
+
+         Say N to delete power /proc/acpi/ folders that have moved to /sys/
 config ACPI_PROC_EVENT
        bool "Deprecated /proc/acpi/event support"
        depends on PROC_FS
index 54e3ab0e5fc011e3a807eec08304a2603251fbbb..456446f9007780eac345479b5fc9d173ddfdbe7c 100644 (file)
@@ -58,6 +58,6 @@ obj-$(CONFIG_ACPI_NUMA)               += numa.o
 obj-$(CONFIG_ACPI_ASUS)                += asus_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)     += toshiba_acpi.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)      += acpi_memhotplug.o
-obj-y                          += cm_sbs.o
+obj-$(CONFIG_ACPI_PROCFS_POWER)        += cm_sbs.o
 obj-$(CONFIG_ACPI_SBS)         += sbs.o
 obj-$(CONFIG_ACPI_SBS)         += sbshc.o
index e03de37a750d547d7e69d91264b224500dc063b8..76ed4f52bebd6df84be95abc388fa45a8d5e35d0 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#endif
 #include <linux/power_supply.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -49,12 +51,15 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
 extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
+static int acpi_ac_open_fs(struct inode *inode, struct file *file);
+#endif
 
 static int acpi_ac_add(struct acpi_device *device);
 static int acpi_ac_remove(struct acpi_device *device, int type);
-static int acpi_ac_open_fs(struct inode *inode, struct file *file);
+static int acpi_ac_resume(struct acpi_device *device);
 
 const static struct acpi_device_id ac_device_ids[] = {
        {"ACPI0003", 0},
@@ -69,6 +74,7 @@ static struct acpi_driver acpi_ac_driver = {
        .ops = {
                .add = acpi_ac_add,
                .remove = acpi_ac_remove,
+               .resume = acpi_ac_resume,
                },
 };
 
@@ -80,12 +86,15 @@ struct acpi_ac {
 
 #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
 static const struct file_operations acpi_ac_fops = {
        .open = acpi_ac_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
 };
+#endif
+
 static int get_ac_property(struct power_supply *psy,
                           enum power_supply_property psp,
                           union power_supply_propval *val)
@@ -127,6 +136,7 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
        return 0;
 }
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -206,6 +216,7 @@ static int acpi_ac_remove_fs(struct acpi_device *device)
 
        return 0;
 }
+#endif
 
 /* --------------------------------------------------------------------------
                                    Driver Model
@@ -264,7 +275,9 @@ static int acpi_ac_add(struct acpi_device *device)
        if (result)
                goto end;
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
        result = acpi_ac_add_fs(device);
+#endif
        if (result)
                goto end;
        ac->charger.name = acpi_device_bid(device);
@@ -287,13 +300,30 @@ static int acpi_ac_add(struct acpi_device *device)
 
       end:
        if (result) {
+#ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_ac_remove_fs(device);
+#endif
                kfree(ac);
        }
 
        return result;
 }
 
+static int acpi_ac_resume(struct acpi_device *device)
+{
+       struct acpi_ac *ac;
+       unsigned old_state;
+       if (!device || !acpi_driver_data(device))
+               return -EINVAL;
+       ac = acpi_driver_data(device);
+       old_state = ac->state;
+       if (acpi_ac_get_state(ac))
+               return 0;
+       if (old_state != ac->state)
+               kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
+       return 0;
+}
+
 static int acpi_ac_remove(struct acpi_device *device, int type)
 {
        acpi_status status = AE_OK;
@@ -309,7 +339,9 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
                                            ACPI_ALL_NOTIFY, acpi_ac_notify);
        if (ac->charger.dev)
                power_supply_unregister(&ac->charger);
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_ac_remove_fs(device);
+#endif
 
        kfree(ac);
 
@@ -323,13 +355,17 @@ static int __init acpi_ac_init(void)
        if (acpi_disabled)
                return -ENODEV;
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_ac_dir = acpi_lock_ac_dir();
        if (!acpi_ac_dir)
                return -ENODEV;
+#endif
 
        result = acpi_bus_register_driver(&acpi_ac_driver);
        if (result < 0) {
+#ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_unlock_ac_dir(acpi_ac_dir);
+#endif
                return -ENODEV;
        }
 
@@ -341,7 +377,9 @@ static void __exit acpi_ac_exit(void)
 
        acpi_bus_unregister_driver(&acpi_ac_driver);
 
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_unlock_ac_dir(acpi_ac_dir);
+#endif
 
        return;
 }
index c2ce0ad21693c0279adcc2b9529c00b77c4fc0ff..7d6be23eff89f49a81b5ce55c3f44596bd7e4d8c 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/types.h>
 #include <linux/jiffies.h>
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
@@ -63,7 +63,7 @@ static unsigned int cache_time = 1000;
 module_param(cache_time, uint, 0644);
 MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
@@ -132,7 +132,7 @@ static int acpi_battery_technology(struct acpi_battery *battery)
        return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
-static int acpi_battery_update(struct acpi_battery *battery);
+static int acpi_battery_get_state(struct acpi_battery *battery);
 
 static int acpi_battery_get_property(struct power_supply *psy,
                                     enum power_supply_property psp,
@@ -140,10 +140,11 @@ static int acpi_battery_get_property(struct power_supply *psy,
 {
        struct acpi_battery *battery = to_acpi_battery(psy);
 
-       if ((!acpi_battery_present(battery)) &&
-            psp != POWER_SUPPLY_PROP_PRESENT)
+       if (acpi_battery_present(battery)) {
+               /* run battery update only if it is present */
+               acpi_battery_get_state(battery);
+       } else if (psp != POWER_SUPPLY_PROP_PRESENT)
                return -ENODEV;
-       acpi_battery_update(battery);
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
                if (battery->state & 0x01)
@@ -152,6 +153,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else if (battery->state == 0)
                        val->intval = POWER_SUPPLY_STATUS_FULL;
+               else
+                       val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
                break;
        case POWER_SUPPLY_PROP_PRESENT:
                val->intval = acpi_battery_present(battery);
@@ -220,7 +223,7 @@ static enum power_supply_property energy_battery_props[] = {
        POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 inline char *acpi_battery_units(struct acpi_battery *battery)
 {
        return (battery->power_unit)?"mA":"mW";
@@ -457,6 +460,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
                return;
        device_remove_file(battery->bat.dev, &alarm_attr);
        power_supply_unregister(&battery->bat);
+       battery->bat.dev = NULL;
 }
 
 static int acpi_battery_update(struct acpi_battery *battery)
@@ -477,7 +481,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 static struct proc_dir_entry *acpi_battery_dir;
 
 static int acpi_battery_print_info(struct seq_file *seq, int result)
@@ -784,7 +788,7 @@ static int acpi_battery_add(struct acpi_device *device)
        acpi_driver_data(device) = battery;
        mutex_init(&battery->lock);
        acpi_battery_update(battery);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        result = acpi_battery_add_fs(device);
        if (result)
                goto end;
@@ -802,7 +806,7 @@ static int acpi_battery_add(struct acpi_device *device)
               device->status.battery_present ? "present" : "absent");
       end:
        if (result) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_battery_remove_fs(device);
 #endif
                kfree(battery);
@@ -821,7 +825,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_ALL_NOTIFY,
                                            acpi_battery_notify);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_battery_remove_fs(device);
 #endif
        sysfs_remove_battery(battery);
@@ -857,13 +861,13 @@ static int __init acpi_battery_init(void)
 {
        if (acpi_disabled)
                return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir)
                return -ENODEV;
 #endif
        if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_unlock_battery_dir(acpi_battery_dir);
 #endif
                return -ENODEV;
@@ -874,7 +878,7 @@ static int __init acpi_battery_init(void)
 static void __exit acpi_battery_exit(void)
 {
        acpi_bus_unregister_driver(&acpi_battery_driver);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_unlock_battery_dir(acpi_battery_dir);
 #endif
 }
index 06b78e5e33a11b8a13a0b0874311f2bb7faf075a..d6ddb547f2d9667dfcdf62e7d8160b5faf79ceaa 100644 (file)
@@ -75,7 +75,8 @@ enum {
        EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
        EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
-       EC_FLAGS_ONLY_IBF_GPE,          /* Expect GPE only for IBF = 0 event */
+       EC_FLAGS_NO_ADDRESS_GPE,        /* Expect GPE only for non-address event */
+       EC_FLAGS_ADDRESS,               /* Address is being written */
 };
 
 static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -166,38 +167,45 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
 
 static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
 {
+       int ret = 0;
+       if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
+                    test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
+               force_poll = 1;
        if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
            likely(!force_poll)) {
                if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
                                       msecs_to_jiffies(ACPI_EC_DELAY)))
-                       return 0;
+                       goto end;
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                if (acpi_ec_check_status(ec, event)) {
-                       if (event == ACPI_EC_EVENT_OBF_1) {
-                               /* miss OBF = 1 GPE, don't expect it anymore */
-                               printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
-                                       "switching to degraded mode.\n");
-                               set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
+                       if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
+                               /* miss address GPE, don't expect it anymore */
+                               printk(KERN_INFO PREFIX "missing address confirmation,"
+                                       "don't expect it any longer.\n");
+                               set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
                        } else {
                                /* missing GPEs, switch back to poll mode */
-                               printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
+                               printk(KERN_INFO PREFIX "missing confirmations,"
                                        "switch off interrupt mode.\n");
                                clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
                        }
-                       return 0;
+                       goto end;
                }
        } else {
                unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                while (time_before(jiffies, delay)) {
                        if (acpi_ec_check_status(ec, event))
-                               return 0;
+                               goto end;
                }
        }
        printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
                               " status = %d, expect_event = %d\n",
                               acpi_ec_read_status(ec), event);
-       return -ETIME;
+       ret = -ETIME;
+      end:
+       clear_bit(EC_FLAGS_ADDRESS, &ec->flags);
+       return ret;
 }
 
 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
@@ -216,6 +224,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
                               "write_cmd timeout, command = %d\n", command);
                        goto end;
                }
+               /* mark the address byte written to EC */
+               if (rdata_len + wdata_len > 1)
+                       set_bit(EC_FLAGS_ADDRESS, &ec->flags);
                set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                acpi_ec_write_data(ec, *(wdata++));
        }
@@ -231,8 +242,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
                clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 
        for (; rdata_len > 0; --rdata_len) {
-               if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags))
-                       force_poll = 1;
                result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
                if (result) {
                        printk(KERN_ERR PREFIX "read timeout, command = %d\n",
@@ -881,12 +890,20 @@ int __init acpi_ec_ecdt_probe(void)
                boot_ec->gpe = ecdt_ptr->gpe;
                boot_ec->handle = ACPI_ROOT_OBJECT;
        } else {
+               /* This workaround is needed only on some broken machines,
+                * which require early EC, but fail to provide ECDT */
+               acpi_handle x;
                printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
                status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
                                                boot_ec, NULL);
                /* Check that acpi_get_devices actually find something */
                if (ACPI_FAILURE(status) || !boot_ec->handle)
                        goto error;
+               /* We really need to limit this workaround, the only ASUS,
+                * which needs it, has fake EC._INI method, so use it as flag.
+                */
+               if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x)))
+                       goto error;
        }
 
        ret = ec_install_handlers(boot_ec);
index aabc6ca4a81c72463529c3e711b012f8b6e909a7..e3a673a008453dfda694aab503dad0c89b19cb1e 100644 (file)
@@ -387,17 +387,14 @@ acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
        if (!value)
                value = &dummy;
 
-       switch (width) {
-       case 8:
+       *value = 0;
+       if (width <= 8) {
                *(u8 *) value = inb(port);
-               break;
-       case 16:
+       } else if (width <= 16) {
                *(u16 *) value = inw(port);
-               break;
-       case 32:
+       } else if (width <= 32) {
                *(u32 *) value = inl(port);
-               break;
-       default:
+       } else {
                BUG();
        }
 
@@ -408,17 +405,13 @@ EXPORT_SYMBOL(acpi_os_read_port);
 
 acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
 {
-       switch (width) {
-       case 8:
+       if (width <= 8) {
                outb(value, port);
-               break;
-       case 16:
+       } else if (width <= 16) {
                outw(value, port);
-               break;
-       case 32:
+       } else if (width <= 32) {
                outl(value, port);
-               break;
-       default:
+       } else {
                BUG();
        }
 
index 235a51e328c3467522e16ac1d4bb26c5a7227537..e93318bb029eceb1dc78a755ff76396dff1c0243 100644 (file)
@@ -612,12 +612,6 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
                request_region(pr->throttling.address, 6, "ACPI CPU throttle");
        }
 
-#ifdef CONFIG_CPU_FREQ
-       acpi_processor_ppc_has_changed(pr);
-#endif
-       acpi_processor_get_throttling_info(pr);
-       acpi_processor_get_limit_info(pr);
-
        return 0;
 }
 
@@ -665,6 +659,12 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
        /* _PDC call should be done before doing anything else (if reqd.). */
        arch_acpi_processor_init_pdc(pr);
        acpi_processor_set_pdc(pr);
+#ifdef CONFIG_CPU_FREQ
+       acpi_processor_ppc_has_changed(pr);
+#endif
+       acpi_processor_get_throttling_info(pr);
+       acpi_processor_get_limit_info(pr);
+
 
        acpi_processor_power_init(pr, device);
 
index f996d0e37689c402642a0c884b0126ad15a505bc..7b6c20eeeaffd738a673ac294c15b4d3f4a629ec 100644 (file)
@@ -197,6 +197,19 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
                return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
 }
 
+static void acpi_safe_halt(void)
+{
+       current_thread_info()->status &= ~TS_POLLING;
+       /*
+        * TS_POLLING-cleared state must be visible before we
+        * test NEED_RESCHED:
+        */
+       smp_mb();
+       if (!need_resched())
+               safe_halt();
+       current_thread_info()->status |= TS_POLLING;
+}
+
 #ifndef CONFIG_CPU_IDLE
 
 static void
@@ -239,19 +252,6 @@ acpi_processor_power_activate(struct acpi_processor *pr,
        return;
 }
 
-static void acpi_safe_halt(void)
-{
-       current_thread_info()->status &= ~TS_POLLING;
-       /*
-        * TS_POLLING-cleared state must be visible before we
-        * test NEED_RESCHED:
-        */
-       smp_mb();
-       if (!need_resched())
-               safe_halt();
-       current_thread_info()->status |= TS_POLLING;
-}
-
 static atomic_t c3_cpu_count;
 
 /* Common C-state entry for C2, C3, .. */
@@ -1373,15 +1373,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
        if (pr->flags.bm_check)
                acpi_idle_update_bm_rld(pr, cx);
 
-       current_thread_info()->status &= ~TS_POLLING;
-       /*
-        * TS_POLLING-cleared state must be visible before we test
-        * NEED_RESCHED:
-        */
-       smp_mb();
-       if (!need_resched())
-               safe_halt();
-       current_thread_info()->status |= TS_POLLING;
+       acpi_safe_halt();
 
        cx->usage++;
 
@@ -1399,6 +1391,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
        struct acpi_processor *pr;
        struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
        u32 t1, t2;
+       int sleep_ticks = 0;
+
        pr = processors[smp_processor_id()];
 
        if (unlikely(!pr))
@@ -1428,6 +1422,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                ACPI_FLUSH_CPU_CACHE();
 
        t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       /* Tell the scheduler that we are going deep-idle: */
+       sched_clock_idle_sleep_event();
        acpi_state_timer_broadcast(pr, cx, 1);
        acpi_idle_do_entry(cx);
        t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1436,6 +1432,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
        /* TSC could halt in idle, so notify users */
        mark_tsc_unstable("TSC halts in idle");;
 #endif
+       sleep_ticks = ticks_elapsed(t1, t2);
+
+       /* Tell the scheduler how much we idled: */
+       sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
        local_irq_enable();
        current_thread_info()->status |= TS_POLLING;
@@ -1443,7 +1443,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
        cx->usage++;
 
        acpi_state_timer_broadcast(pr, cx, 0);
-       cx->time += ticks_elapsed(t1, t2);
+       cx->time += sleep_ticks;
        return ticks_elapsed_in_us(t1, t2);
 }
 
@@ -1463,6 +1463,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        struct acpi_processor *pr;
        struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
        u32 t1, t2;
+       int sleep_ticks = 0;
+
        pr = processors[smp_processor_id()];
 
        if (unlikely(!pr))
@@ -1471,6 +1473,15 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        if (acpi_idle_suspend)
                return(acpi_idle_enter_c1(dev, state));
 
+       if (acpi_idle_bm_check()) {
+               if (dev->safe_state) {
+                       return dev->safe_state->enter(dev, dev->safe_state);
+               } else {
+                       acpi_safe_halt();
+                       return 0;
+               }
+       }
+
        local_irq_disable();
        current_thread_info()->status &= ~TS_POLLING;
        /*
@@ -1485,38 +1496,45 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
                return 0;
        }
 
+       /* Tell the scheduler that we are going deep-idle: */
+       sched_clock_idle_sleep_event();
        /*
         * Must be done before busmaster disable as we might need to
         * access HPET !
         */
        acpi_state_timer_broadcast(pr, cx, 1);
 
-       if (acpi_idle_bm_check()) {
-               cx = pr->power.bm_state;
-
-               acpi_idle_update_bm_rld(pr, cx);
-
-               t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-               acpi_idle_do_entry(cx);
-               t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-       } else {
-               acpi_idle_update_bm_rld(pr, cx);
+       acpi_idle_update_bm_rld(pr, cx);
 
+       /*
+        * disable bus master
+        * bm_check implies we need ARB_DIS
+        * !bm_check implies we need cache flush
+        * bm_control implies whether we can do ARB_DIS
+        *
+        * That leaves a case where bm_check is set and bm_control is
+        * not set. In that case we cannot do much, we enter C3
+        * without doing anything.
+        */
+       if (pr->flags.bm_check && pr->flags.bm_control) {
                spin_lock(&c3_lock);
                c3_cpu_count++;
                /* Disable bus master arbitration when all CPUs are in C3 */
                if (c3_cpu_count == num_online_cpus())
                        acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
                spin_unlock(&c3_lock);
+       } else if (!pr->flags.bm_check) {
+               ACPI_FLUSH_CPU_CACHE();
+       }
 
-               t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-               acpi_idle_do_entry(cx);
-               t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       acpi_idle_do_entry(cx);
+       t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
+       /* Re-enable bus master arbitration */
+       if (pr->flags.bm_check && pr->flags.bm_control) {
                spin_lock(&c3_lock);
-               /* Re-enable bus master arbitration */
-               if (c3_cpu_count == num_online_cpus())
-                       acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+               acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
                c3_cpu_count--;
                spin_unlock(&c3_lock);
        }
@@ -1525,6 +1543,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        /* TSC could halt in idle, so notify users */
        mark_tsc_unstable("TSC halts in idle");
 #endif
+       sleep_ticks = ticks_elapsed(t1, t2);
+       /* Tell the scheduler how much we idled: */
+       sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
        local_irq_enable();
        current_thread_info()->status |= TS_POLLING;
@@ -1532,7 +1553,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        cx->usage++;
 
        acpi_state_timer_broadcast(pr, cx, 0);
-       cx->time += ticks_elapsed(t1, t2);
+       cx->time += sleep_ticks;
        return ticks_elapsed_in_us(t1, t2);
 }
 
@@ -1584,12 +1605,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                        case ACPI_STATE_C1:
                        state->flags |= CPUIDLE_FLAG_SHALLOW;
                        state->enter = acpi_idle_enter_c1;
+                       dev->safe_state = state;
                        break;
 
                        case ACPI_STATE_C2:
                        state->flags |= CPUIDLE_FLAG_BALANCED;
                        state->flags |= CPUIDLE_FLAG_TIME_VALID;
                        state->enter = acpi_idle_enter_simple;
+                       dev->safe_state = state;
                        break;
 
                        case ACPI_STATE_C3:
@@ -1610,14 +1633,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
        if (!count)
                return -EINVAL;
 
-       /* find the deepest state that can handle active BM */
-       if (pr->flags.bm_check) {
-               for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
-                       if (pr->power.states[i].type == ACPI_STATE_C3)
-                               break;
-               pr->power.bm_state = &pr->power.states[i-1];
-       }
-
        return 0;
 }
 
index 0b8204e7082a366232b3d29121926ff0892f57cd..c26c61fb36c3ac0a16f719016f1a8634bfda71db 100644 (file)
@@ -70,7 +70,55 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 
 int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
 {
-       return acpi_processor_get_platform_limit(pr);
+       int result = 0;
+       int throttling_limit;
+       int current_state;
+       struct acpi_processor_limit *limit;
+       int target_state;
+
+       result = acpi_processor_get_platform_limit(pr);
+       if (result) {
+               /* Throttling Limit is unsupported */
+               return result;
+       }
+
+       throttling_limit = pr->throttling_platform_limit;
+       if (throttling_limit >= pr->throttling.state_count) {
+               /* Uncorrect Throttling Limit */
+               return -EINVAL;
+       }
+
+       current_state = pr->throttling.state;
+       if (current_state > throttling_limit) {
+               /*
+                * The current state can meet the requirement of
+                * _TPC limit. But it is reasonable that OSPM changes
+                * t-states from high to low for better performance.
+                * Of course the limit condition of thermal
+                * and user should be considered.
+                */
+               limit = &pr->limit;
+               target_state = throttling_limit;
+               if (limit->thermal.tx > target_state)
+                       target_state = limit->thermal.tx;
+               if (limit->user.tx > target_state)
+                       target_state = limit->user.tx;
+       } else if (current_state == throttling_limit) {
+               /*
+                * Unnecessary to change the throttling state
+                */
+               return 0;
+       } else {
+               /*
+                * If the current state is lower than the limit of _TPC, it
+                * will be forced to switch to the throttling state defined
+                * by throttling_platfor_limit.
+                * Because the previous state meets with the limit condition
+                * of thermal and user, it is unnecessary to check it again.
+                */
+               target_state = throttling_limit;
+       }
+       return acpi_processor_set_throttling(pr, target_state);
 }
 
 /*
@@ -83,6 +131,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *ptc = NULL;
        union acpi_object obj = { 0 };
+       struct acpi_processor_throttling *throttling;
 
        status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
@@ -134,6 +183,22 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
        memcpy(&pr->throttling.status_register, obj.buffer.pointer,
               sizeof(struct acpi_ptc_register));
 
+       throttling = &pr->throttling;
+
+       if ((throttling->control_register.bit_width +
+               throttling->control_register.bit_offset) > 32) {
+               printk(KERN_ERR PREFIX "Invalid _PTC control register\n");
+               result = -EFAULT;
+               goto end;
+       }
+
+       if ((throttling->status_register.bit_width +
+               throttling->status_register.bit_offset) > 32) {
+               printk(KERN_ERR PREFIX "Invalid _PTC status register\n");
+               result = -EFAULT;
+               goto end;
+       }
+
       end:
        kfree(buffer.pointer);
 
@@ -328,44 +393,132 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
        return 0;
 }
 
-static int acpi_read_throttling_status(struct acpi_processor_throttling
-                                      *throttling)
+#ifdef CONFIG_X86
+static int acpi_throttling_rdmsr(struct acpi_processor *pr,
+                                       acpi_integer * value)
 {
-       int value = -1;
+       struct cpuinfo_x86 *c;
+       u64 msr_high, msr_low;
+       unsigned int cpu;
+       u64 msr = 0;
+       int ret = -1;
+
+       cpu = pr->id;
+       c = &cpu_data(cpu);
+
+       if ((c->x86_vendor != X86_VENDOR_INTEL) ||
+               !cpu_has(c, X86_FEATURE_ACPI)) {
+               printk(KERN_ERR PREFIX
+                       "HARDWARE addr space,NOT supported yet\n");
+       } else {
+               msr_low = 0;
+               msr_high = 0;
+               rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+                       (u32 *)&msr_low , (u32 *) &msr_high);
+               msr = (msr_high << 32) | msr_low;
+               *value = (acpi_integer) msr;
+               ret = 0;
+       }
+       return ret;
+}
+
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+{
+       struct cpuinfo_x86 *c;
+       unsigned int cpu;
+       int ret = -1;
+       u64 msr;
+
+       cpu = pr->id;
+       c = &cpu_data(cpu);
+
+       if ((c->x86_vendor != X86_VENDOR_INTEL) ||
+               !cpu_has(c, X86_FEATURE_ACPI)) {
+               printk(KERN_ERR PREFIX
+                       "HARDWARE addr space,NOT supported yet\n");
+       } else {
+               msr = value;
+               wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+                       msr & 0xffffffff, msr >> 32);
+               ret = 0;
+       }
+       return ret;
+}
+#else
+static int acpi_throttling_rdmsr(struct acpi_processor *pr,
+                               acpi_integer * value)
+{
+       printk(KERN_ERR PREFIX
+               "HARDWARE addr space,NOT supported yet\n");
+       return -1;
+}
+
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+{
+       printk(KERN_ERR PREFIX
+               "HARDWARE addr space,NOT supported yet\n");
+       return -1;
+}
+#endif
+
+static int acpi_read_throttling_status(struct acpi_processor *pr,
+                                       acpi_integer *value)
+{
+       u32 bit_width, bit_offset;
+       u64 ptc_value;
+       u64 ptc_mask;
+       struct acpi_processor_throttling *throttling;
+       int ret = -1;
+
+       throttling = &pr->throttling;
        switch (throttling->status_register.space_id) {
        case ACPI_ADR_SPACE_SYSTEM_IO:
+               ptc_value = 0;
+               bit_width = throttling->status_register.bit_width;
+               bit_offset = throttling->status_register.bit_offset;
+
                acpi_os_read_port((acpi_io_address) throttling->status_register.
-                                 address, &value,
-                                 (u32) throttling->status_register.bit_width *
-                                 8);
+                                 address, (u32 *) &ptc_value,
+                                 (u32) (bit_width + bit_offset));
+               ptc_mask = (1 << bit_width) - 1;
+               *value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask);
+               ret = 0;
                break;
        case ACPI_ADR_SPACE_FIXED_HARDWARE:
-               printk(KERN_ERR PREFIX
-                      "HARDWARE addr space,NOT supported yet\n");
+               ret = acpi_throttling_rdmsr(pr, value);
                break;
        default:
                printk(KERN_ERR PREFIX "Unknown addr space %d\n",
                       (u32) (throttling->status_register.space_id));
        }
-       return value;
+       return ret;
 }
 
-static int acpi_write_throttling_state(struct acpi_processor_throttling
-                                      *throttling, int value)
+static int acpi_write_throttling_state(struct acpi_processor *pr,
+                               acpi_integer value)
 {
+       u32 bit_width, bit_offset;
+       u64 ptc_value;
+       u64 ptc_mask;
+       struct acpi_processor_throttling *throttling;
        int ret = -1;
 
+       throttling = &pr->throttling;
        switch (throttling->control_register.space_id) {
        case ACPI_ADR_SPACE_SYSTEM_IO:
+               bit_width = throttling->control_register.bit_width;
+               bit_offset = throttling->control_register.bit_offset;
+               ptc_mask = (1 << bit_width) - 1;
+               ptc_value = value & ptc_mask;
+
                acpi_os_write_port((acpi_io_address) throttling->
-                                  control_register.address, value,
-                                  (u32) throttling->control_register.
-                                  bit_width * 8);
+                                       control_register.address,
+                                       (u32) (ptc_value << bit_offset),
+                                       (u32) (bit_width + bit_offset));
                ret = 0;
                break;
        case ACPI_ADR_SPACE_FIXED_HARDWARE:
-               printk(KERN_ERR PREFIX
-                      "HARDWARE addr space,NOT supported yet\n");
+               ret = acpi_throttling_wrmsr(pr, value);
                break;
        default:
                printk(KERN_ERR PREFIX "Unknown addr space %d\n",
@@ -374,7 +527,8 @@ static int acpi_write_throttling_state(struct acpi_processor_throttling
        return ret;
 }
 
-static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
+static int acpi_get_throttling_state(struct acpi_processor *pr,
+                               acpi_integer value)
 {
        int i;
 
@@ -390,22 +544,26 @@ static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
        return i;
 }
 
-static int acpi_get_throttling_value(struct acpi_processor *pr, int state)
+static int acpi_get_throttling_value(struct acpi_processor *pr,
+                       int state, acpi_integer *value)
 {
-       int value = -1;
+       int ret = -1;
+
        if (state >= 0 && state <= pr->throttling.state_count) {
                struct acpi_processor_tx_tss *tx =
                    (struct acpi_processor_tx_tss *)&(pr->throttling.
                                                      states_tss[state]);
-               value = tx->control;
+               *value = tx->control;
+               ret = 0;
        }
-       return value;
+       return ret;
 }
 
 static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
 {
        int state = 0;
-       u32 value = 0;
+       int ret;
+       acpi_integer value;
 
        if (!pr)
                return -EINVAL;
@@ -415,8 +573,9 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
 
        pr->throttling.state = 0;
        local_irq_disable();
-       value = acpi_read_throttling_status(&pr->throttling);
-       if (value >= 0) {
+       value = 0;
+       ret = acpi_read_throttling_status(pr, &value);
+       if (ret >= 0) {
                state = acpi_get_throttling_state(pr, value);
                pr->throttling.state = state;
        }
@@ -430,6 +589,40 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
        return pr->throttling.acpi_processor_get_throttling(pr);
 }
 
+static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
+{
+       int i, step;
+
+       if (!pr->throttling.address) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
+               return -EINVAL;
+       } else if (!pr->throttling.duty_width) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
+               return -EINVAL;
+       }
+       /* TBD: Support duty_cycle values that span bit 4. */
+       else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
+               printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
+               return -EINVAL;
+       }
+
+       pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
+
+       /*
+        * Compute state values. Note that throttling displays a linear power
+        * performance relationship (at 50% performance the CPU will consume
+        * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
+        */
+
+       step = (1000 / pr->throttling.state_count);
+
+       for (i = 0; i < pr->throttling.state_count; i++) {
+               pr->throttling.states[i].performance = 1000 - step * i;
+               pr->throttling.states[i].power = 1000 - step * i;
+       }
+       return 0;
+}
+
 static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
                                              int state)
 {
@@ -506,7 +699,8 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
 static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
                                             int state)
 {
-       u32 value = 0;
+       int ret;
+       acpi_integer value;
 
        if (!pr)
                return -EINVAL;
@@ -524,10 +718,10 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
                return -EPERM;
 
        local_irq_disable();
-
-       value = acpi_get_throttling_value(pr, state);
-       if (value >= 0) {
-               acpi_write_throttling_state(&pr->throttling, value);
+       value = 0;
+       ret = acpi_get_throttling_value(pr, state, &value);
+       if (ret >= 0) {
+               acpi_write_throttling_state(pr, value);
                pr->throttling.state = state;
        }
        local_irq_enable();
@@ -543,8 +737,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 {
        int result = 0;
-       int step = 0;
-       int i = 0;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -563,6 +755,8 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
                acpi_processor_get_throttling_states(pr) ||
                acpi_processor_get_platform_limit(pr))
        {
+               if (acpi_processor_get_fadt_info(pr))
+                       return 0;
                pr->throttling.acpi_processor_get_throttling =
                    &acpi_processor_get_throttling_fadt;
                pr->throttling.acpi_processor_set_throttling =
@@ -576,19 +770,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 
        acpi_processor_get_tsd(pr);
 
-       if (!pr->throttling.address) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
-               return 0;
-       } else if (!pr->throttling.duty_width) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
-               return 0;
-       }
-       /* TBD: Support duty_cycle values that span bit 4. */
-       else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
-               printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
-               return 0;
-       }
-
        /*
         * PIIX4 Errata: We don't support throttling on the original PIIX4.
         * This shouldn't be an issue as few (if any) mobile systems ever
@@ -600,21 +781,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
                return 0;
        }
 
-       pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
-
-       /*
-        * Compute state values. Note that throttling displays a linear power/
-        * performance relationship (at 50% performance the CPU will consume
-        * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
-        */
-
-       step = (1000 / pr->throttling.state_count);
-
-       for (i = 0; i < pr->throttling.state_count; i++) {
-               pr->throttling.states[i].performance = step * i;
-               pr->throttling.states[i].power = step * i;
-       }
-
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
                          pr->throttling.state_count));
 
index 90fd09c65f95eed69d07fc624277d20fb9c44f8b..6045cdbe176beafe7f250c65a0bf93b3fa428da7 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
@@ -88,7 +88,7 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
 struct acpi_battery {
        struct power_supply bat;
        struct acpi_sbs *sbs;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        struct proc_dir_entry *proc_entry;
 #endif
        unsigned long update_time;
@@ -113,6 +113,7 @@ struct acpi_battery {
        u16 spec;
        u8 id;
        u8 present:1;
+       u8 have_sysfs_alarm:1;
 };
 
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -122,7 +123,7 @@ struct acpi_sbs {
        struct acpi_device *device;
        struct acpi_smb_hc *hc;
        struct mutex lock;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        struct proc_dir_entry *charger_entry;
 #endif
        struct acpi_battery battery[MAX_SBS_BAT];
@@ -468,7 +469,7 @@ static struct device_attribute alarm_attr = {
                               FS Interface (/proc/acpi)
    -------------------------------------------------------------------------- */
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 /* Generic Routines */
 static int
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
@@ -789,7 +790,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
                return result;
 
        sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
                        battery->name, &acpi_battery_info_fops,
                        &acpi_battery_state_fops, &acpi_battery_alarm_fops,
@@ -808,7 +809,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
        }
        battery->bat.get_property = acpi_sbs_battery_get_property;
        result = power_supply_register(&sbs->device->dev, &battery->bat);
-       device_create_file(battery->bat.dev, &alarm_attr);
+       if (result)
+               goto end;
+       result = device_create_file(battery->bat.dev, &alarm_attr);
+       if (result)
+               goto end;
+       battery->have_sysfs_alarm = 1;
+      end:
        printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
               battery->name, sbs->battery->present ? "present" : "absent");
@@ -817,14 +824,16 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
-       if (sbs->battery[id].bat.dev)
-               device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
-               power_supply_unregister(&sbs->battery[id].bat);
-#ifdef CONFIG_ACPI_PROCFS
-       if (sbs->battery[id].proc_entry) {
-               acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
-                                  acpi_battery_dir);
+       struct acpi_battery *battery = &sbs->battery[id];
+
+       if (battery->bat.dev) {
+               if (battery->have_sysfs_alarm)
+                       device_remove_file(battery->bat.dev, &alarm_attr);
+               power_supply_unregister(&battery->bat);
        }
+#ifdef CONFIG_ACPI_PROCFS_POWER
+       if (battery->proc_entry)
+               acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
 #endif
 }
 
@@ -835,7 +844,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
        result = acpi_ac_get_present(sbs);
        if (result)
                goto end;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
                                 ACPI_AC_DIR_NAME, NULL,
                                 &acpi_ac_state_fops, NULL, sbs);
@@ -859,7 +868,7 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
        if (sbs->charger.dev)
                power_supply_unregister(&sbs->charger);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        if (sbs->charger_entry)
                acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
 #endif
@@ -965,7 +974,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 
 static void acpi_sbs_rmdirs(void)
 {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        if (acpi_ac_dir) {
                acpi_unlock_ac_dir(acpi_ac_dir);
                acpi_ac_dir = NULL;
@@ -1004,7 +1013,7 @@ static int __init acpi_sbs_init(void)
 
        if (acpi_disabled)
                return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_ac_dir = acpi_lock_ac_dir();
        if (!acpi_ac_dir)
                return -ENODEV;
index a736ef7bdee4726e3ef03c50b8fd1100c4b7b6ad..9e8c20c6a0b7243e708876a4dfffa30dd8f47506 100644 (file)
@@ -591,9 +591,12 @@ static int __init toshiba_acpi_init(void)
                                                NULL,
                                                &toshiba_backlight_data);
         if (IS_ERR(toshiba_backlight_device)) {
+               int ret = PTR_ERR(toshiba_backlight_device);
+
                printk(KERN_ERR "Could not register toshiba backlight device\n");
                toshiba_backlight_device = NULL;
                toshiba_acpi_exit();
+               return ret;
        }
         toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
 
index a4b2cb29f46c8f32df1a4162894ee4b6390814e4..328ce8a08426a9b626d05cd62703fed60414ab64 100644 (file)
@@ -621,6 +621,7 @@ struct ich_laptop {
 static const struct ich_laptop ich_laptop[] = {
        /* devid, subvendor, subdev */
        { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
+       { 0x27DF, 0x1025, 0x0102 },     /* ICH7 on Acer 5602aWLMi */
        { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
        { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
        { 0x27DF, 0x103C, 0x30A1 },     /* ICH7 on HP Compaq nc2400 */
@@ -958,6 +959,13 @@ static int piix_broken_suspend(void)
                                DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"),
                        },
                },
+               {
+                       .ident = "Satellite Pro U200",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE PRO U200"),
+                       },
+               },
                {
                        .ident = "Satellite U205",
                        .matches = {
index 08a52dd45fb6a4bd686ee0ef05f1cc069f863713..545ea865ceb522bf37b675558f9eedab1da7332d 100644 (file)
@@ -312,7 +312,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
  *
  * RETURNS:
  * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
- * contain valid data.  -errno on other errors.
+ * contain valid data.
  */
 static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
                           void **ptr_to_free)
@@ -339,7 +339,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
                        ata_dev_printk(dev, KERN_WARNING,
                                       "_GTF evaluation failed (AE 0x%x)\n",
                                       status);
-                       rc = -EIO;
                }
                goto out_free;
        }
@@ -359,7 +358,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
                ata_dev_printk(dev, KERN_WARNING,
                               "_GTF unexpected object type 0x%x\n",
                               out_obj->type);
-               rc = -EINVAL;
                goto out_free;
        }
 
@@ -367,7 +365,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
                ata_dev_printk(dev, KERN_WARNING,
                               "unexpected _GTF length (%d)\n",
                               out_obj->buffer.length);
-               rc = -EINVAL;
                goto out_free;
        }
 
@@ -511,10 +508,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)
        int gtf_count, i, rc;
 
        /* get taskfiles */
-       rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
-       if (rc < 0)
-               return rc;
-       gtf_count = rc;
+       gtf_count = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
 
        /* execute them */
        for (i = 0, rc = 0; i < gtf_count; i++) {
index 164c7d9514f9f0ce32088d1681a090c4c630875c..81898036dbcaa8badff43fb0a95089a5c3402164 100644 (file)
@@ -676,10 +676,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
                if (rc)
                        return rc;
 
-               /* disable DIPM */
-               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
-                       err_mask = ata_dev_set_feature(dev,
-                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               /*
+                * we don't have to disable DIPM since IPM flags
+                * disallow transitions to SLUMBER, which effectively
+                * disable DIPM if it does not support PARTIAL
+                */
                break;
        case NOT_AVAILABLE:
        case MAX_PERFORMANCE:
@@ -689,10 +690,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
                if (rc)
                        return rc;
 
-               /* disable DIPM */
-               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
-                       err_mask = ata_dev_set_feature(dev,
-                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               /*
+                * we don't have to disable DIPM since IPM flags
+                * disallow all transitions which effectively
+                * disable DIPM anyway.
+                */
                break;
        }
 
@@ -3371,14 +3373,20 @@ void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
         * to clear 0xff after reset.  For example, HHD424020F7SV00
         * iVDR needs >= 800ms while.  Quantum GoVault needs even more
         * than that.
+        *
+        * Note that some PATA controllers (pata_ali) explode if
+        * status register is read more than once when there's no
+        * device attached.
         */
-       while (1) {
-               u8 status = ata_chk_status(ap);
+       if (ap->flags & ATA_FLAG_SATA) {
+               while (1) {
+                       u8 status = ata_chk_status(ap);
 
-               if (status != 0xff || time_after(jiffies, deadline))
-                       return;
+                       if (status != 0xff || time_after(jiffies, deadline))
+                               return;
 
-               msleep(50);
+                       msleep(50);
+               }
        }
 }
 
@@ -4239,6 +4247,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ST340823A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
        { "ST320413A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
 
+       /* Devices which get the IVB wrong */
+       { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202J", "SB00",     ATA_HORKAGE_IVB, },
+
        /* End Marker */
        { }
 };
@@ -4299,6 +4311,21 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
        return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
 }
 
+/**
+ *     ata_is_40wire           -       check drive side detection
+ *     @dev: device
+ *
+ *     Perform drive side detection decoding, allowing for device vendors
+ *     who can't follow the documentation.
+ */
+
+static int ata_is_40wire(struct ata_device *dev)
+{
+       if (dev->horkage & ATA_HORKAGE_IVB)
+               return ata_drive_40wire_relaxed(dev->id);
+       return ata_drive_40wire(dev->id);
+}
+
 /**
  *     ata_dev_xfermask - Compute supported xfermask of the given device
  *     @dev: Device to compute xfermask for
@@ -4368,7 +4395,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
        if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
                /* UDMA/44 or higher would be available */
                if ((ap->cbl == ATA_CBL_PATA40) ||
-                   (ata_drive_40wire(dev->id) &&
+                   (ata_is_40wire(dev) &&
                    (ap->cbl == ATA_CBL_PATA_UNK ||
                     ap->cbl == ATA_CBL_PATA80))) {
                        ata_dev_printk(dev, KERN_WARNING,
@@ -6794,19 +6821,6 @@ static void ata_host_release(struct device *gendev, void *res)
        struct ata_host *host = dev_get_drvdata(gendev);
        int i;
 
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               if (!ap)
-                       continue;
-
-               if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
-                       ap->ops->port_stop(ap);
-       }
-
-       if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
-               host->ops->host_stop(host);
-
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
 
@@ -6939,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
        return host;
 }
 
+static void ata_host_stop(struct device *gendev, void *res)
+{
+       struct ata_host *host = dev_get_drvdata(gendev);
+       int i;
+
+       WARN_ON(!(host->flags & ATA_HOST_STARTED));
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
+       }
+
+       if (host->ops->host_stop)
+               host->ops->host_stop(host);
+}
+
 /**
  *     ata_host_start - start and freeze ports of an ATA host
  *     @host: ATA host to start ports for
@@ -6957,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
  */
 int ata_host_start(struct ata_host *host)
 {
+       int have_stop = 0;
+       void *start_dr = NULL;
        int i, rc;
 
        if (host->flags & ATA_HOST_STARTED)
@@ -6968,6 +7002,22 @@ int ata_host_start(struct ata_host *host)
                if (!host->ops && !ata_port_is_dummy(ap))
                        host->ops = ap->ops;
 
+               if (ap->ops->port_stop)
+                       have_stop = 1;
+       }
+
+       if (host->ops->host_stop)
+               have_stop = 1;
+
+       if (have_stop) {
+               start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
+               if (!start_dr)
+                       return -ENOMEM;
+       }
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
                if (ap->ops->port_start) {
                        rc = ap->ops->port_start(ap);
                        if (rc) {
@@ -6980,6 +7030,8 @@ int ata_host_start(struct ata_host *host)
                ata_eh_freeze_port(ap);
        }
 
+       if (start_dr)
+               devres_add(host->dev, start_dr);
        host->flags |= ATA_HOST_STARTED;
        return 0;
 
@@ -6990,6 +7042,7 @@ int ata_host_start(struct ata_host *host)
                if (ap->ops->port_stop)
                        ap->ops->port_stop(ap);
        }
+       devres_free(start_dr);
        return rc;
 }
 
@@ -7157,6 +7210,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
  *     request IRQ and register it.  This helper takes necessasry
  *     arguments and performs the three steps in one go.
  *
+ *     An invalid IRQ skips the IRQ registration and expects the host to
+ *     have set polling mode on the port. In this case, @irq_handler
+ *     should be NULL.
+ *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
  *
@@ -7173,6 +7230,12 @@ int ata_host_activate(struct ata_host *host, int irq,
        if (rc)
                return rc;
 
+       /* Special case for polling mode */
+       if (!irq) {
+               WARN_ON(irq_handler);
+               return ata_host_register(host, sht);
+       }
+
        rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
                              dev_driver_string(host->dev), host);
        if (rc)
index e61cb1fd57b209d518665a6798e0f5d03ed7e1b9..3816b8605e0d60631b5fe1c4496db8e7e8f1379e 100644 (file)
@@ -295,7 +295,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
 
 static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
 {
-       if (adev->class != ATA_DEV_ATA) {
+       if (adev->class == ATA_DEV_ATA) {
                if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
                        mask &= ~ (0x1F << ATA_SHIFT_UDMA);
        }
@@ -359,28 +359,25 @@ static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline)
                { 0x50, 1, 0x04, 0x04 },
                { 0x54, 1, 0x04, 0x04 }
        };
-       u16 mcr3, mcr6;
+       u16 mcr3;
        u8 ata66;
        struct ata_port *ap = link->ap;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       unsigned int mcrbase = 0x50 + 4 * ap->port_no;
 
        if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
                return -ENOENT;
 
        /* Do the extra channel work */
-       pci_read_config_word(pdev, 0x52, &mcr3);
-       pci_read_config_word(pdev, 0x56, &mcr6);
+       pci_read_config_word(pdev, mcrbase + 2, &mcr3);
        /* Set bit 15 of 0x52 to enable TCBLID as input
-          Set bit 15 of 0x56 to enable FCBLID as input
         */
-       pci_write_config_word(pdev, 0x52, mcr3 | 0x8000);
-       pci_write_config_word(pdev, 0x56, mcr6 | 0x8000);
+       pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000);
        pci_read_config_byte(pdev, 0x5A, &ata66);
        /* Reset TCBLID/FCBLID to output */
        pci_write_config_word(pdev, 0x52, mcr3);
-       pci_write_config_word(pdev, 0x56, mcr6);
 
-       if (ata66 & (1 << ap->port_no))
+       if (ata66 & (2 >> ap->port_no))
                ap->cbl = ATA_CBL_PATA40;
        else
                ap->cbl = ATA_CBL_PATA80;
@@ -844,6 +841,25 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
        /* Never went stable */
        return 0;
 }
+
+static u32 hpt374_read_freq(struct pci_dev *pdev)
+{
+       u32 freq;
+       unsigned long io_base = pci_resource_start(pdev, 4);
+       if (PCI_FUNC(pdev->devfn) & 1) {
+               struct pci_dev *pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1);
+               /* Someone hot plugged the controller on us ? */
+               if (pdev_0 == NULL)
+                       return 0;
+               io_base = pci_resource_start(pdev_0, 4);
+               freq = inl(io_base + 0x90);
+               pci_dev_put(pdev_0);
+       }
+       else
+               freq = inl(io_base + 0x90);
+       return freq;
+}
+
 /**
  *     hpt37x_init_one         -       Initialise an HPT37X/302
  *     @dev: PCI device
@@ -902,7 +918,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x0f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370_port_ops
        };
        /* HPT370A - UDMA100 */
@@ -911,7 +927,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x0f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370a_port_ops
        };
        /* HPT371, 372 and friends - UDMA133 */
@@ -1047,9 +1063,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                outb(0x0e, iobase + 0x9c);
 
        /* Some devices do not let this value be accessed via PCI space
-          according to the old driver */
+          according to the old driver. In addition we must use the value
+          from FN 0 on the HPT374 */
+
+       if (chip_table == &hpt374) {
+               freq = hpt374_read_freq(dev);
+               if (freq == 0)
+                       return -ENODEV;
+       } else
+               freq = inl(iobase + 0x90);
 
-       freq = inl(iobase + 0x90);
        if ((freq >> 12) != 0xABCDE) {
                int i;
                u8 sr;
index fc72a965643d8951f45e5957d98fc5924fefae24..ac03a90a616829cc1b04d58f8b624caddff070f4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Generic platform device PATA driver
  *
- * Copyright (C) 2006  Paul Mundt
+ * Copyright (C) 2006 - 2007  Paul Mundt
  *
  * Based on pata_pcmcia:
  *
@@ -22,7 +22,7 @@
 #include <linux/pata_platform.h>
 
 #define DRV_NAME "pata_platform"
-#define DRV_VERSION "1.1"
+#define DRV_VERSION "1.2"
 
 static int pio_mask = 1;
 
@@ -120,15 +120,20 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
  *     Register a platform bus IDE interface. Such interfaces are PIO and we
  *     assume do not support IRQ sharing.
  *
- *     Platform devices are expected to contain 3 resources per port:
+ *     Platform devices are expected to contain at least 2 resources per port:
  *
  *             - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
  *             - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
+ *
+ *     and optionally:
+ *
  *             - IRQ      (IORESOURCE_IRQ)
  *
  *     If the base resources are both mem types, the ioremap() is handled
  *     here. For IORESOURCE_IO, it's assumed that there's no remapping
  *     necessary.
+ *
+ *     If no IRQ resource is present, PIO polling mode is used instead.
  */
 static int __devinit pata_platform_probe(struct platform_device *pdev)
 {
@@ -137,11 +142,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        struct ata_port *ap;
        struct pata_platform_info *pp_info;
        unsigned int mmio;
+       int irq;
 
        /*
         * Simple resource validation ..
         */
-       if (unlikely(pdev->num_resources != 3)) {
+       if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
                dev_err(&pdev->dev, "invalid number of resources\n");
                return -EINVAL;
        }
@@ -172,6 +178,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        mmio = (( io_res->flags == IORESOURCE_MEM) &&
                (ctl_res->flags == IORESOURCE_MEM));
 
+       /*
+        * And the IRQ
+        */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               irq = 0;        /* no irq */
+
        /*
         * Now that that's out of the way, wire up the port..
         */
@@ -184,6 +197,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        ap->pio_mask = pio_mask;
        ap->flags |= ATA_FLAG_SLAVE_POSS;
 
+       /*
+        * Use polling mode if there's no IRQ
+        */
+       if (!irq) {
+               ap->flags |= ATA_FLAG_PIO_POLLING;
+               ata_port_desc(ap, "no IRQ, using PIO polling");
+       }
+
        /*
         * Handle the MMIO case
         */
@@ -213,9 +234,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
                      (unsigned long long)ctl_res->start);
 
        /* activate */
-       return ata_host_activate(host, platform_get_irq(pdev, 0),
-                                ata_interrupt, pp_info ? pp_info->irq_flags
-                                : 0, &pata_platform_sht);
+       return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
+                                pp_info ? pp_info->irq_flags : 0,
+                                &pata_platform_sht);
 }
 
 /**
index df68806df4be195e07295c58e113f60defdcdc7d..8bed888737206cae257c43ae9f0a600568bf91cc 100644 (file)
@@ -274,28 +274,27 @@ static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev
 {
        static const u8 dma_mode[] = { 0x77, 0x21, 0x20 };
        int offset = 1 + 2 * ap->port_no - adev->devno;
-       int devbits = (2 * ap->port_no + adev->devno);
+       int devbits = 2 * ap->port_no + adev->devno;
        u8 ultra;
        u8 ultra_cfg;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
        pci_read_config_byte(pdev, 0x54, &ultra_cfg);
+       pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra);
+       ultra &= ~(0x0F << (adev->devno * 4));
 
        if (adev->dma_mode >= XFER_UDMA_0) {
                pci_write_config_byte(pdev, 0x44 + offset,  0x20);
 
-               pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra);
-               ultra &= ~(0x0F << (ap->port_no * 4));
                ultra |= (adev->dma_mode - XFER_UDMA_0)
-                                       << (ap->port_no * 4);
-               pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra);
-
+                                       << (adev->devno * 4);
                ultra_cfg |=  (1 << devbits);
        } else {
                pci_write_config_byte(pdev, 0x44 + offset,
                        dma_mode[adev->dma_mode - XFER_MW_DMA_0]);
                ultra_cfg &= ~(1 << devbits);
        }
+       pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra);
        pci_write_config_byte(pdev, 0x54, ultra_cfg);
 }
 
index 35b2df297527fc191b1dd988aa35b7ca0f313d10..44f9e5d9e36238e00b45de0cf2840f1489b052c6 100644 (file)
@@ -1629,7 +1629,7 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
 
        /* SATA hardreset fails to retrieve proper device signature on
         * some controllers.  Don't classify on hardreset.  For more
-        * info, see http://bugme.osdl.org/show_bug.cgi?id=3352
+        * info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352
         */
        return sata_std_hardreset(link, &dummy, deadline);
 }
index 6d43ba79e154b70ba035e524f88b64ba9b846448..2f1de6ec044c52f2dd5a4318ba5d2812e00db382 100644 (file)
@@ -103,7 +103,7 @@ enum {
        QS_DMA_BOUNDARY         = ~0UL
 };
 
-typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
+typedef enum { qs_state_mmio, qs_state_pkt } qs_state_t;
 
 struct qs_port_priv {
        u8                      *pkt;
@@ -116,14 +116,15 @@ static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
-static void qs_phy_reset(struct ata_port *ap);
 static void qs_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
 static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
 static void qs_bmdma_stop(struct ata_queued_cmd *qc);
 static u8 qs_bmdma_status(struct ata_port *ap);
 static void qs_irq_clear(struct ata_port *ap);
-static void qs_eng_timeout(struct ata_port *ap);
+static void qs_freeze(struct ata_port *ap);
+static void qs_thaw(struct ata_port *ap);
+static void qs_error_handler(struct ata_port *ap);
 
 static struct scsi_host_template qs_ata_sht = {
        .module                 = THIS_MODULE,
@@ -150,11 +151,12 @@ static const struct ata_port_operations qs_ata_ops = {
        .check_atapi_dma        = qs_check_atapi_dma,
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
-       .phy_reset              = qs_phy_reset,
        .qc_prep                = qs_qc_prep,
        .qc_issue               = qs_qc_issue,
        .data_xfer              = ata_data_xfer,
-       .eng_timeout            = qs_eng_timeout,
+       .freeze                 = qs_freeze,
+       .thaw                   = qs_thaw,
+       .error_handler          = qs_error_handler,
        .irq_clear              = qs_irq_clear,
        .irq_on                 = ata_irq_on,
        .scr_read               = qs_scr_read,
@@ -169,8 +171,6 @@ static const struct ata_port_info qs_port_info[] = {
        /* board_2068_idx */
        {
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SATA_RESET |
-                                 //FIXME ATA_FLAG_SRST |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
                .pio_mask       = 0x10, /* pio4 */
                .udma_mask      = ATA_UDMA6,
@@ -219,7 +219,9 @@ static void qs_irq_clear(struct ata_port *ap)
 static inline void qs_enter_reg_mode(struct ata_port *ap)
 {
        u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
+       struct qs_port_priv *pp = ap->private_data;
 
+       pp->state = qs_state_mmio;
        writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
        readb(chan + QS_CCT_CTR0);        /* flush */
 }
@@ -233,23 +235,28 @@ static inline void qs_reset_channel_logic(struct ata_port *ap)
        qs_enter_reg_mode(ap);
 }
 
-static void qs_phy_reset(struct ata_port *ap)
+static void qs_freeze(struct ata_port *ap)
 {
-       struct qs_port_priv *pp = ap->private_data;
+       u8 __iomem *mmio_base = qs_mmio_base(ap->host);
 
-       pp->state = qs_state_idle;
-       qs_reset_channel_logic(ap);
-       sata_phy_reset(ap);
+       writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
+       qs_enter_reg_mode(ap);
 }
 
-static void qs_eng_timeout(struct ata_port *ap)
+static void qs_thaw(struct ata_port *ap)
 {
-       struct qs_port_priv *pp = ap->private_data;
+       u8 __iomem *mmio_base = qs_mmio_base(ap->host);
+
+       qs_enter_reg_mode(ap);
+       writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
+}
+
+static int qs_prereset(struct ata_link *link, unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
 
-       if (pp->state != qs_state_idle) /* healthy paranoia */
-               pp->state = qs_state_mmio;
        qs_reset_channel_logic(ap);
-       ata_eng_timeout(ap);
+       return ata_std_prereset(link, deadline);
 }
 
 static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -260,6 +267,13 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return 0;
 }
 
+static void qs_error_handler(struct ata_port *ap)
+{
+       qs_enter_reg_mode(ap);
+       ata_do_eh(ap, qs_prereset, ata_std_softreset, NULL,
+                 ata_std_postreset);
+}
+
 static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
@@ -358,7 +372,6 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
 
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
-
                pp->state = qs_state_pkt;
                qs_packet_start(qc);
                return 0;
@@ -375,6 +388,26 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
        return ata_qc_issue_prot(qc);
 }
 
+static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status)
+{
+       qc->err_mask |= ac_err_mask(status);
+
+       if (!qc->err_mask) {
+               ata_qc_complete(qc);
+       } else {
+               struct ata_port    *ap  = qc->ap;
+               struct ata_eh_info *ehi = &ap->link.eh_info;
+
+               ata_ehi_clear_desc(ehi);
+               ata_ehi_push_desc(ehi, "status 0x%02X", status);
+
+               if (qc->err_mask == AC_ERR_DEV)
+                       ata_port_abort(ap);
+               else
+                       ata_port_freeze(ap);
+       }
+}
+
 static inline unsigned int qs_intr_pkt(struct ata_host *host)
 {
        unsigned int handled = 0;
@@ -406,10 +439,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
                                        switch (sHST) {
                                        case 0: /* successful CPB */
                                        case 3: /* device error */
-                                               pp->state = qs_state_idle;
                                                qs_enter_reg_mode(qc->ap);
-                                               qc->err_mask |= ac_err_mask(sDST);
-                                               ata_qc_complete(qc);
+                                               qs_do_or_die(qc, sDST);
                                                break;
                                        default:
                                                break;
@@ -431,25 +462,27 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
                if (ap &&
                    !(ap->flags & ATA_FLAG_DISABLED)) {
                        struct ata_queued_cmd *qc;
-                       struct qs_port_priv *pp = ap->private_data;
-                       if (!pp || pp->state != qs_state_mmio)
-                               continue;
+                       struct qs_port_priv *pp;
                        qc = ata_qc_from_tag(ap, ap->link.active_tag);
-                       if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
-
-                               /* check main status, clearing INTRQ */
-                               u8 status = ata_check_status(ap);
-                               if ((status & ATA_BUSY))
-                                       continue;
-                               DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
-                                       ap->print_id, qc->tf.protocol, status);
-
-                               /* complete taskfile transaction */
-                               pp->state = qs_state_idle;
-                               qc->err_mask |= ac_err_mask(status);
-                               ata_qc_complete(qc);
+                       if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) {
+                               /*
+                                * The qstor hardware generates spurious
+                                * interrupts from time to time when switching
+                                * in and out of packet mode.
+                                * There's no obvious way to know if we're
+                                * here now due to that, so just ack the irq
+                                * and pretend we knew it was ours.. (ugh).
+                                * This does not affect packet mode.
+                                */
+                               ata_check_status(ap);
                                handled = 1;
+                               continue;
                        }
+                       pp = ap->private_data;
+                       if (!pp || pp->state != qs_state_mmio)
+                               continue;
+                       if (!(qc->tf.flags & ATA_TFLAG_POLLING))
+                               handled |= ata_host_intr(ap, qc);
                }
        }
        return handled;
@@ -459,12 +492,13 @@ static irqreturn_t qs_intr(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int handled = 0;
+       unsigned long flags;
 
        VPRINTK("ENTER\n");
 
-       spin_lock(&host->lock);
+       spin_lock_irqsave(&host->lock, flags);
        handled  = qs_intr_pkt(host) | qs_intr_mmio(host);
-       spin_unlock(&host->lock);
+       spin_unlock_irqrestore(&host->lock, flags);
 
        VPRINTK("EXIT\n");
 
@@ -501,7 +535,6 @@ static int qs_port_start(struct ata_port *ap)
        rc = ata_port_start(ap);
        if (rc)
                return rc;
-       qs_enter_reg_mode(ap);
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
                return -ENOMEM;
@@ -512,6 +545,7 @@ static int qs_port_start(struct ata_port *ap)
        memset(pp->pkt, 0, QS_PKT_BYTES);
        ap->private_data = pp;
 
+       qs_enter_reg_mode(ap);
        addr = (u64)pp->pkt_dma;
        writel((u32) addr,        chan + QS_CCF_CPBA);
        writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
index 6332acad078c5f6976854b0f394e3496dc1f4e81..b4c0888aedc3113c8eb442726a4237c9f7d9dd92 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <net/sock.h>
+#include <linux/net.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -126,7 +127,7 @@ static void sock_shutdown(struct nbd_device *lo, int lock)
        if (lo->sock) {
                printk(KERN_WARNING "%s: shutting down socket\n",
                        lo->disk->disk_name);
-               lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN);
+               kernel_sock_shutdown(lo->sock, SHUT_RDWR);
                lo->sock = NULL;
        }
        if (lock)
index ceffa6034e2044f81340a3fadb2241f9053d0abf..e7fe6ca97dd8a4027142a763bcc8cdc4018e52f4 100644 (file)
@@ -488,13 +488,11 @@ static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fu
        return r;
 }
 
-#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
-
 static void pf_lock(struct pf_unit *pf, int func)
 {
        char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 };
 
-       pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "unlock" : "lock");
+       pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "lock" : "unlock");
 }
 
 static void pf_eject(struct pf_unit *pf)
@@ -555,7 +553,7 @@ static void pf_mode_sense(struct pf_unit *pf)
            { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 };
        char buf[8];
 
-       pf_atapi(pf, ms_cmd, 8, buf, DBMSG("mode sense"));
+       pf_atapi(pf, ms_cmd, 8, buf, "mode sense");
        pf->media_status = PF_RW;
        if (buf[3] & 0x80)
                pf->media_status = PF_RO;
@@ -591,7 +589,7 @@ static void pf_get_capacity(struct pf_unit *pf)
        char buf[8];
        int bs;
 
-       if (pf_atapi(pf, rc_cmd, 8, buf, DBMSG("get capacity"))) {
+       if (pf_atapi(pf, rc_cmd, 8, buf, "get capacity")) {
                pf->media_status = PF_NM;
                return;
        }
@@ -804,13 +802,18 @@ static int pf_next_buf(void)
        pf_buf += 512;
        pf_block++;
        if (!pf_run)
-               return 0;
-       if (!pf_count)
                return 1;
-       spin_lock_irqsave(&pf_spin_lock, saved_flags);
-       pf_end_request(1);
-       spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
-       return 1;
+       if (!pf_count) {
+               spin_lock_irqsave(&pf_spin_lock, saved_flags);
+               pf_end_request(1);
+               pf_req = elv_next_request(pf_queue);
+               spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
+               if (!pf_req)
+                       return 1;
+               pf_count = pf_req->current_nr_sectors;
+               pf_buf = pf_req->buffer;
+       }
+       return 0;
 }
 
 static inline void next_request(int success)
index 9f4e67ee1eb0628917155e99c31810bcbb4a6404..b91accf12656581066811fa68c18e78cfb655018 100644 (file)
@@ -664,7 +664,7 @@ static int pt_open(struct inode *inode, struct file *file)
                goto out;
 
        err = -EROFS;
-       if ((!tape->flags & PT_WRITE_OK) && (file->f_mode & 2))
+       if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & 2))
                goto out;
 
        if (!(iminor(inode) & 128))
index a8130a4ad6d4329572b722b2947059db776fa8e2..a5ee21319d37fa2633bd5625099fb429a5c353ca 100644 (file)
@@ -358,10 +358,19 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
                                        size_t count)
 {
        unsigned int major, minor;
+
        if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
+               /* pkt_setup_dev() expects caller to hold reference to self */
+               if (!try_module_get(THIS_MODULE))
+                       return -ENODEV;
+
                pkt_setup_dev(MKDEV(major, minor), NULL);
+
+               module_put(THIS_MODULE);
+
                return count;
        }
+
        return -EINVAL;
 }
 
index 47f8ac6cce574c81b1e845099000e019a0098468..82f4eecc8699d19e42e899b043e2c45842cdbcc1 100644 (file)
@@ -189,6 +189,18 @@ static int ramdisk_set_page_dirty(struct page *page)
        return 0;
 }
 
+/*
+ * releasepage is called by pagevec_strip/try_to_release_page if
+ * buffers_heads_over_limit is true. Without a releasepage function
+ * try_to_free_buffers is called instead. That can unset the dirty
+ * bit of our ram disk pages, which will be eventually freed, even
+ * if the page is still in use.
+ */
+static int ramdisk_releasepage(struct page *page, gfp_t dummy)
+{
+       return 0;
+}
+
 static const struct address_space_operations ramdisk_aops = {
        .readpage       = ramdisk_readpage,
        .prepare_write  = ramdisk_prepare_write,
@@ -196,6 +208,7 @@ static const struct address_space_operations ramdisk_aops = {
        .writepage      = ramdisk_writepage,
        .set_page_dirty = ramdisk_set_page_dirty,
        .writepages     = ramdisk_writepages,
+       .releasepage    = ramdisk_releasepage,
 };
 
 static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector,
index 9dd0760dd87a7e89b405f2f83172cc26d803962c..dde02a15fa59d0f584dbf4bd63feaede1803afe6 100644 (file)
@@ -559,8 +559,6 @@ struct drm_mm {
  * a family of cards. There will one drm_device for each card present
  * in this family
  */
-struct drm_device;
-
 struct drm_driver {
        int (*load) (struct drm_device *, unsigned long flags);
        int (*firstopen) (struct drm_device *);
index d9be14624526e9553279f61f9c788526c6562894..3cbebf868e6832c2e61fa1885da3b970132be038 100644 (file)
@@ -272,7 +272,7 @@ int drm_getstats(struct drm_device *dev, void *data,
        struct drm_stats *stats = data;
        int i;
 
-       memset(stats, 0, sizeof(stats));
+       memset(stats, 0, sizeof(*stats));
 
        mutex_lock(&dev->struct_mutex);
 
index 76e44ac94fb52f4315a6c3498359d1e7d523ec69..daa69c9d8977b9cf8055c082eca364abd13b5635 100644 (file)
@@ -62,14 +62,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
 
 #endif
 
-/** For data going into the kernel through the ioctl argument */
-#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3)     \
-       if ( copy_from_user(&arg1, arg2, arg3) )        \
-               return -EFAULT
-/** For data going from the kernel through the ioctl argument */
-#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3)       \
-       if ( copy_to_user(arg1, &arg2, arg3) )          \
-               return -EFAULT
 /** Other copying of data to kernel space */
 #define DRM_COPY_FROM_USER(arg1, arg2, arg3)           \
        copy_from_user(arg1, arg2, arg3)
index 59484d56b3338e1e8533cf4c5c04f013785ddccd..d465b2f9c1cdb999a3ec168d910a0c60db5580fa 100644 (file)
@@ -968,9 +968,6 @@ static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_
 
        DRM_DEBUG("\n");
 
-       DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *) data,
-                                sizeof(event));
-
        UPDATE_EVENT_COUNTER();
        if (dev_priv->status_ptr)
                hw_e = dev_priv->status_ptr[1] & 0xffff;
index cc5d77797defc66781da7c8c390bbfdc693b09a8..02518da6a386a934ef7c3af885c4630e3c46741f 100644 (file)
@@ -47,7 +47,7 @@
 /* #define ATR_CSUM */
 
 #ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)       (&handle_to_dev(x->p_dev->handle))
+#define reader_to_dev(x)       (&handle_to_dev(x->p_dev))
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0600);
 #define DEBUGP(n, rdr, x, args...) do {                                \
index a0b9c8728d5685c80b51807ee7faa377ca2cf456..5f291bf739a627901dbad1fbebfe970311f538a3 100644 (file)
@@ -41,7 +41,7 @@
 
 
 #ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)       (&handle_to_dev(x->p_dev->handle))
+#define reader_to_dev(x)       (&handle_to_dev(x->p_dev))
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0600);
 #define DEBUGP(n, rdr, x, args...) do {                                \
index 1756b1f7cb7252b8a596ff25767c1d9155fab5f4..5fee05661823766a0ed5651724d81fad0ee951b8 100644 (file)
@@ -1494,7 +1494,7 @@ __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
        seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK;
        seq += keyptr->count;
 
-       seq += ktime_get_real().tv64;
+       seq += ktime_to_ns(ktime_get_real());
 
        return seq;
 }
@@ -1556,7 +1556,7 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
         *      overlaps less than one time per MSL (2 minutes).
         *      Choosing a clock of 64 ns period is OK. (period of 274 s)
         */
-       seq += ktime_get_real().tv64 >> 6;
+       seq += ktime_to_ns(ktime_get_real()) >> 6;
 #if 0
        printk("init_seq(%lx, %lx, %d, %d) = %d\n",
               saddr, daddr, sport, dport, seq);
@@ -1616,7 +1616,7 @@ u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
        seq = half_md4_transform(hash, keyptr->secret);
        seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
 
-       seq += ktime_get_real().tv64;
+       seq += ktime_to_ns(ktime_get_real());
        seq &= (1ull << 48) - 1;
 #if 0
        printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n",
index ec6b65ec69ea6f1726e400667c2462c5af7d5028..0c66b802736a10540bca3ed9d7ef34f5b0208b4a 100644 (file)
@@ -918,6 +918,31 @@ static const struct file_operations rtc_proc_fops = {
 };
 #endif
 
+static resource_size_t rtc_size;
+
+static struct resource * __init rtc_request_region(resource_size_t size)
+{
+       struct resource *r;
+
+       if (RTC_IOMAPPED)
+               r = request_region(RTC_PORT(0), size, "rtc");
+       else
+               r = request_mem_region(RTC_PORT(0), size, "rtc");
+
+       if (r)
+               rtc_size = size;
+
+       return r;
+}
+
+static void rtc_release_region(void)
+{
+       if (RTC_IOMAPPED)
+               release_region(RTC_PORT(0), rtc_size);
+       else
+               release_mem_region(RTC_PORT(0), rtc_size);
+}
+
 static int __init rtc_init(void)
 {
 #ifdef CONFIG_PROC_FS
@@ -968,10 +993,17 @@ found:
        }
 no_irq:
 #else
-       if (RTC_IOMAPPED)
-               r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
-       else
-               r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+       r = rtc_request_region(RTC_IO_EXTENT);
+
+       /*
+        * If we've already requested a smaller range (for example, because
+        * PNPBIOS or ACPI told us how the device is configured), the request
+        * above might fail because it's too big.
+        *
+        * If so, request just the range we actually use.
+        */
+       if (!r)
+               r = rtc_request_region(RTC_IO_EXTENT_USED);
        if (!r) {
 #ifdef RTC_IRQ
                rtc_has_irq = 0;
@@ -992,10 +1024,7 @@ no_irq:
                /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
                rtc_has_irq = 0;
                printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
-               if (RTC_IOMAPPED)
-                       release_region(RTC_PORT(0), RTC_IO_EXTENT);
-               else
-                       release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
+               rtc_release_region();
                return -EIO;
        }
        hpet_rtc_timer_init();
@@ -1009,7 +1038,7 @@ no_irq:
                free_irq(RTC_IRQ, NULL);
                rtc_has_irq = 0;
 #endif
-               release_region(RTC_PORT(0), RTC_IO_EXTENT);
+               rtc_release_region();
                return -ENODEV;
        }
 
@@ -1091,10 +1120,7 @@ static void __exit rtc_exit (void)
        if (rtc_has_irq)
                free_irq (rtc_irq, &rtc_port);
 #else
-       if (RTC_IOMAPPED)
-               release_region(RTC_PORT(0), RTC_IO_EXTENT);
-       else
-               release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
+       rtc_release_region();
 #ifdef RTC_IRQ
        if (rtc_has_irq)
                free_irq (RTC_IRQ, NULL);
index 7a003504c265f73ee5f99aaffb140d97d1853991..1bdd2bf4f37d74808bd60bcce01e67a2c6d57f5d 100644 (file)
@@ -730,13 +730,23 @@ static int send_prio_char(struct tty_struct *tty, char ch)
        return 0;
 }
 
-int n_tty_ioctl(struct tty_struct * tty, struct file * file,
-                      unsigned int cmd, unsigned long arg)
+/**
+ *     tty_mode_ioctl          -       mode related ioctls
+ *     @tty: tty for the ioctl
+ *     @file: file pointer for the tty
+ *     @cmd: command
+ *     @arg: ioctl argument
+ *
+ *     Perform non line discipline specific mode control ioctls. This
+ *     is designed to be called by line disciplines to ensure they provide
+ *     consistent mode setting.
+ */
+
+int tty_mode_ioctl(struct tty_struct * tty, struct file *file,
+                       unsigned int cmd, unsigned long arg)
 {
        struct tty_struct * real_tty;
        void __user *p = (void __user *)arg;
-       int retval;
-       struct tty_ldisc *ld;
 
        if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
            tty->driver->subtype == PTY_TYPE_MASTER)
@@ -799,6 +809,93 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                        return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
                case TCSETA:
                        return set_termios(real_tty, p, TERMIOS_TERMIO);
+#ifndef TCGETS2
+               case TIOCGLCKTRMIOS:
+                       if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
+                               return -EFAULT;
+                       return 0;
+
+               case TIOCSLCKTRMIOS:
+                       if (!capable(CAP_SYS_ADMIN))
+                               return -EPERM;
+                       if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
+                               return -EFAULT;
+                       return 0;
+#else
+               case TIOCGLCKTRMIOS:
+                       if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
+                               return -EFAULT;
+                       return 0;
+
+               case TIOCSLCKTRMIOS:
+                       if (!capable(CAP_SYS_ADMIN))
+                               return -EPERM;
+                       if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
+                               return -EFAULT;
+                       return 0;
+#endif
+               case TIOCGSOFTCAR:
+                       return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
+               case TIOCSSOFTCAR:
+                       if (get_user(arg, (unsigned int __user *) arg))
+                               return -EFAULT;
+                       mutex_lock(&tty->termios_mutex);
+                       tty->termios->c_cflag =
+                               ((tty->termios->c_cflag & ~CLOCAL) |
+                                (arg ? CLOCAL : 0));
+                       mutex_unlock(&tty->termios_mutex);
+                       return 0;
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+EXPORT_SYMBOL_GPL(tty_mode_ioctl);
+
+int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
+{
+       struct tty_ldisc *ld;
+       int retval = tty_check_change(tty);
+       if (retval)
+               return retval;
+
+       ld = tty_ldisc_ref(tty);
+       switch (arg) {
+       case TCIFLUSH:
+               if (ld && ld->flush_buffer)
+                       ld->flush_buffer(tty);
+               break;
+       case TCIOFLUSH:
+               if (ld && ld->flush_buffer)
+                       ld->flush_buffer(tty);
+               /* fall through */
+       case TCOFLUSH:
+               if (tty->driver->flush_buffer)
+                       tty->driver->flush_buffer(tty);
+               break;
+       default:
+               tty_ldisc_deref(ld);
+               return -EINVAL;
+       }
+       tty_ldisc_deref(ld);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tty_perform_flush);
+
+int n_tty_ioctl(struct tty_struct * tty, struct file * file,
+                      unsigned int cmd, unsigned long arg)
+{
+       struct tty_struct * real_tty;
+       int retval;
+
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_MASTER)
+               real_tty = tty->link;
+       else
+               real_tty = tty;
+
+       switch (cmd) {
                case TCXONC:
                        retval = tty_check_change(tty);
                        if (retval)
@@ -829,30 +926,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                        }
                        return 0;
                case TCFLSH:
-                       retval = tty_check_change(tty);
-                       if (retval)
-                               return retval;
-                               
-                       ld = tty_ldisc_ref(tty);
-                       switch (arg) {
-                       case TCIFLUSH:
-                               if (ld && ld->flush_buffer)
-                                       ld->flush_buffer(tty);
-                               break;
-                       case TCIOFLUSH:
-                               if (ld && ld->flush_buffer)
-                                       ld->flush_buffer(tty);
-                               /* fall through */
-                       case TCOFLUSH:
-                               if (tty->driver->flush_buffer)
-                                       tty->driver->flush_buffer(tty);
-                               break;
-                       default:
-                               tty_ldisc_deref(ld);
-                               return -EINVAL;
-                       }
-                       tty_ldisc_deref(ld);
-                       return 0;
+                       return tty_perform_flush(tty, arg);
                case TIOCOUTQ:
                        return put_user(tty->driver->chars_in_buffer ?
                                        tty->driver->chars_in_buffer(tty) : 0,
@@ -862,32 +936,6 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                        if (L_ICANON(tty))
                                retval = inq_canon(tty);
                        return put_user(retval, (unsigned int __user *) arg);
-#ifndef TCGETS2
-               case TIOCGLCKTRMIOS:
-                       if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
-                               return -EFAULT;
-                       return 0;
-
-               case TIOCSLCKTRMIOS:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
-                               return -EFAULT;
-                       return 0;
-#else
-               case TIOCGLCKTRMIOS:
-                       if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
-                               return -EFAULT;
-                       return 0;
-
-               case TIOCSLCKTRMIOS:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
-                               return -EFAULT;
-                       return 0;
-#endif
-
                case TIOCPKT:
                {
                        int pktmode;
@@ -906,19 +954,9 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                                tty->packet = 0;
                        return 0;
                }
-               case TIOCGSOFTCAR:
-                       return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
-               case TIOCSSOFTCAR:
-                       if (get_user(arg, (unsigned int __user *) arg))
-                               return -EFAULT;
-                       mutex_lock(&tty->termios_mutex);
-                       tty->termios->c_cflag =
-                               ((tty->termios->c_cflag & ~CLOCAL) |
-                                (arg ? CLOCAL : 0));
-                       mutex_unlock(&tty->termios_mutex);
-                       return 0;
                default:
-                       return -ENOIOCTLCMD;
+                       /* Try the mode commands */
+                       return tty_mode_ioctl(tty, file, cmd, arg);
                }
 }
 
index 100e8a201e3aa5d2a8890cb79b171373dc829afe..e34da5c971966fc87d68b40588ea4f22e3f94189 100644 (file)
@@ -141,7 +141,7 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
  * never remove the console device we never need this pointer again.
  *
  * Finally we put our input buffer in the input queue, ready to receive. */
-static int virtcons_probe(struct virtio_device *dev)
+static int __devinit virtcons_probe(struct virtio_device *dev)
 {
        int err;
        struct hvc_struct *hvc;
index 4bd33ce8a6f3398a0aa37995582e619c3b938590..1bba99747f5b3da806fea25aa991d3ac151673be 100644 (file)
 #define DEF_FREQUENCY_UP_THRESHOLD             (80)
 #define DEF_FREQUENCY_DOWN_THRESHOLD           (20)
 
-/* 
- * The polling frequency of this governor depends on the capability of 
+/*
+ * The polling frequency of this governor depends on the capability of
  * the processor. Default polling frequency is 1000 times the transition
- * latency of the processor. The governor will work on any processor with 
- * transition latency <= 10mS, using appropriate sampling 
+ * latency of the processor. The governor will work on any processor with
+ * transition latency <= 10mS, using appropriate sampling
  * rate.
  * For CPUs with transition latency > 10mS (mostly drivers
  * with CPUFREQ_ETERNAL), this governor will not work.
  * All times here are in uS.
  */
-static unsigned int                            def_sampling_rate;
+static unsigned int def_sampling_rate;
 #define MIN_SAMPLING_RATE_RATIO                        (2)
 /* for correct statistics, we need at least 10 ticks between each measure */
 #define MIN_STAT_SAMPLING_RATE                 \
@@ -63,12 +63,12 @@ static unsigned int                                 def_sampling_rate;
 static void do_dbs_timer(struct work_struct *work);
 
 struct cpu_dbs_info_s {
-       struct cpufreq_policy   *cur_policy;
-       unsigned int            prev_cpu_idle_up;
-       unsigned int            prev_cpu_idle_down;
-       unsigned int            enable;
-       unsigned int            down_skip;
-       unsigned int            requested_freq;
+       struct cpufreq_policy *cur_policy;
+       unsigned int prev_cpu_idle_up;
+       unsigned int prev_cpu_idle_down;
+       unsigned int enable;
+       unsigned int down_skip;
+       unsigned int requested_freq;
 };
 static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
 
@@ -82,24 +82,24 @@ static unsigned int dbs_enable;     /* number of CPUs using this policy */
  * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
  * is recursive for the same process. -Venki
  */
-static DEFINE_MUTEX    (dbs_mutex);
+static DEFINE_MUTEX (dbs_mutex);
 static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer);
 
 struct dbs_tuners {
-       unsigned int            sampling_rate;
-       unsigned int            sampling_down_factor;
-       unsigned int            up_threshold;
-       unsigned int            down_threshold;
-       unsigned int            ignore_nice;
-       unsigned int            freq_step;
+       unsigned int sampling_rate;
+       unsigned int sampling_down_factor;
+       unsigned int up_threshold;
+       unsigned int down_threshold;
+       unsigned int ignore_nice;
+       unsigned int freq_step;
 };
 
 static struct dbs_tuners dbs_tuners_ins = {
-       .up_threshold           = DEF_FREQUENCY_UP_THRESHOLD,
-       .down_threshold         = DEF_FREQUENCY_DOWN_THRESHOLD,
-       .sampling_down_factor   = DEF_SAMPLING_DOWN_FACTOR,
-       .ignore_nice            = 0,
-       .freq_step              = 5,
+       .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
+       .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
+       .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
+       .ignore_nice = 0,
+       .freq_step = 5,
 };
 
 static inline unsigned int get_cpu_idle_time(unsigned int cpu)
@@ -109,13 +109,34 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
        if (dbs_tuners_ins.ignore_nice)
                add_nice = kstat_cpu(cpu).cpustat.nice;
 
-       ret =   kstat_cpu(cpu).cpustat.idle +
+       ret = kstat_cpu(cpu).cpustat.idle +
                kstat_cpu(cpu).cpustat.iowait +
                add_nice;
 
        return ret;
 }
 
+/* keep track of frequency transitions */
+static int
+dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+                    void *data)
+{
+       struct cpufreq_freqs *freq = data;
+       struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info,
+                                                       freq->cpu);
+
+       if (!this_dbs_info->enable)
+               return 0;
+
+       this_dbs_info->requested_freq = freq->new;
+
+       return 0;
+}
+
+static struct notifier_block dbs_cpufreq_notifier_block = {
+       .notifier_call = dbs_cpufreq_notifier
+};
+
 /************************** sysfs interface ************************/
 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
 {
@@ -127,8 +148,8 @@ static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
        return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
 }
 
-#define define_one_ro(_name)                                   \
-static struct freq_attr _name =                                \
+#define define_one_ro(_name)                           \
+static struct freq_attr _name =                                \
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -148,7 +169,7 @@ show_one(down_threshold, down_threshold);
 show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
-static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
+static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -164,7 +185,7 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_sampling_rate(struct cpufreq_policy *unused, 
+static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -183,7 +204,7 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_up_threshold(struct cpufreq_policy *unused, 
+static ssize_t store_up_threshold(struct cpufreq_policy *unused,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -202,7 +223,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_down_threshold(struct cpufreq_policy *unused, 
+static ssize_t store_down_threshold(struct cpufreq_policy *unused,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -228,16 +249,16 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
        int ret;
 
        unsigned int j;
-       
-       ret = sscanf (buf, "%u", &input);
-       if ( ret != 1 )
+
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
                return -EINVAL;
 
-       if ( input > 1 )
+       if (input > 1)
                input = 1;
-       
+
        mutex_lock(&dbs_mutex);
-       if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
+       if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
                mutex_unlock(&dbs_mutex);
                return count;
        }
@@ -261,14 +282,14 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy,
        unsigned int input;
        int ret;
 
-       ret = sscanf (buf, "%u", &input);
+       ret = sscanf(buf, "%u", &input);
 
-       if ( ret != 1 )
+       if (ret != 1)
                return -EINVAL;
 
-       if ( input > 100 )
+       if (input > 100)
                input = 100;
-       
+
        /* no need to test here if freq_step is zero as the user might actually
         * want this, they would be crazy though :) */
        mutex_lock(&dbs_mutex);
@@ -322,18 +343,18 @@ static void dbs_check_cpu(int cpu)
 
        policy = this_dbs_info->cur_policy;
 
-       /* 
-        * The default safe range is 20% to 80% 
+       /*
+        * The default safe range is 20% to 80%
         * Every sampling_rate, we check
-        *      - If current idle time is less than 20%, then we try to 
-        *        increase frequency
+        *      - If current idle time is less than 20%, then we try to
+        *        increase frequency
         * Every sampling_rate*sampling_down_factor, we check
-        *      - If current idle time is more than 80%, then we try to
-        *        decrease frequency
+        *      - If current idle time is more than 80%, then we try to
+        *        decrease frequency
         *
-        * Any frequency increase takes it to the maximum frequency. 
-        * Frequency reduction happens at minimum steps of 
-        * 5% (default) of max_frequency 
+        * Any frequency increase takes it to the maximum frequency.
+        * Frequency reduction happens at minimum steps of
+        * 5% (default) of max_frequency
         */
 
        /* Check for frequency increase */
@@ -361,13 +382,13 @@ static void dbs_check_cpu(int cpu)
                /* if we are already at full speed then break out early */
                if (this_dbs_info->requested_freq == policy->max)
                        return;
-               
+
                freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100;
 
                /* max freq cannot be less than 100. But who knows.... */
                if (unlikely(freq_step == 0))
                        freq_step = 5;
-               
+
                this_dbs_info->requested_freq += freq_step;
                if (this_dbs_info->requested_freq > policy->max)
                        this_dbs_info->requested_freq = policy->max;
@@ -427,15 +448,15 @@ static void dbs_check_cpu(int cpu)
 }
 
 static void do_dbs_timer(struct work_struct *work)
-{ 
+{
        int i;
        mutex_lock(&dbs_mutex);
        for_each_online_cpu(i)
                dbs_check_cpu(i);
-       schedule_delayed_work(&dbs_work, 
+       schedule_delayed_work(&dbs_work,
                        usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
        mutex_unlock(&dbs_mutex);
-} 
+}
 
 static inline void dbs_timer_init(void)
 {
@@ -462,13 +483,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
        switch (event) {
        case CPUFREQ_GOV_START:
-               if ((!cpu_online(cpu)) || 
-                   (!policy->cur))
+               if ((!cpu_online(cpu)) || (!policy->cur))
                        return -EINVAL;
 
                if (this_dbs_info->enable) /* Already enabled */
                        break;
-                
+
                mutex_lock(&dbs_mutex);
 
                rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
@@ -481,7 +501,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        struct cpu_dbs_info_s *j_dbs_info;
                        j_dbs_info = &per_cpu(cpu_dbs_info, j);
                        j_dbs_info->cur_policy = policy;
-               
+
                        j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu);
                        j_dbs_info->prev_cpu_idle_down
                                = j_dbs_info->prev_cpu_idle_up;
@@ -511,8 +531,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        dbs_tuners_ins.sampling_rate = def_sampling_rate;
 
                        dbs_timer_init();
+                       cpufreq_register_notifier(
+                                       &dbs_cpufreq_notifier_block,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
                }
-               
+
                mutex_unlock(&dbs_mutex);
                break;
 
@@ -525,9 +548,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                 * Stop the timerschedule work, when this governor
                 * is used for first time
                 */
-               if (dbs_enable == 0) 
+               if (dbs_enable == 0) {
                        dbs_timer_exit();
-               
+                       cpufreq_unregister_notifier(
+                                       &dbs_cpufreq_notifier_block,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+               }
+
                mutex_unlock(&dbs_mutex);
 
                break;
@@ -537,11 +564,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                if (policy->max < this_dbs_info->cur_policy->cur)
                        __cpufreq_driver_target(
                                        this_dbs_info->cur_policy,
-                                       policy->max, CPUFREQ_RELATION_H);
+                                       policy->max, CPUFREQ_RELATION_H);
                else if (policy->min > this_dbs_info->cur_policy->cur)
                        __cpufreq_driver_target(
                                        this_dbs_info->cur_policy,
-                                       policy->min, CPUFREQ_RELATION_L);
+                                       policy->min, CPUFREQ_RELATION_L);
                mutex_unlock(&dbs_mutex);
                break;
        }
index f9a34abbf4faed143e8597f2769f114534acaa64..711e246e1ef021ee66fd297105482328580b0cd8 100644 (file)
@@ -110,8 +110,7 @@ geode_aes_crypt(struct geode_aes_op *op)
         * we don't need to worry
         */
 
-       if (op->src == op->dst)
-               flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
+       flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
 
        if (op->dir == AES_DIR_ENCRYPT)
                flags |= AES_CTRL_ENCRYPT;
index 82489923af09a6ae048a50c1bf471e43f9260492..d59b2f417306f91af453962991c5c681aa20381b 100644 (file)
@@ -182,10 +182,9 @@ static void dma_client_chan_alloc(struct dma_client *client)
                                /* we are done once this client rejects
                                 * an available resource
                                 */
-                               if (ack == DMA_ACK) {
+                               if (ack == DMA_ACK)
                                        dma_chan_get(chan);
-                                       kref_get(&device->refcount);
-                               } else if (ack == DMA_NAK)
+                               else if (ack == DMA_NAK)
                                        return;
                        }
                }
@@ -272,11 +271,8 @@ static void dma_clients_notify_removed(struct dma_chan *chan)
                /* client was holding resources for this channel so
                 * free it
                 */
-               if (ack == DMA_ACK) {
+               if (ack == DMA_ACK)
                        dma_chan_put(chan);
-                       kref_put(&chan->device->refcount,
-                               dma_async_device_cleanup);
-               }
        }
 
        mutex_unlock(&dma_list_mutex);
@@ -316,11 +312,8 @@ void dma_async_client_unregister(struct dma_client *client)
                        ack = client->event_callback(client, chan,
                                DMA_RESOURCE_REMOVED);
 
-                       if (ack == DMA_ACK) {
+                       if (ack == DMA_ACK)
                                dma_chan_put(chan);
-                               kref_put(&chan->device->refcount,
-                                       dma_async_device_cleanup);
-                       }
                }
 
        list_del(&client->global_node);
@@ -397,6 +390,8 @@ int dma_async_device_register(struct dma_device *device)
                        goto err_out;
                }
 
+               /* One for the channel, one of the class device */
+               kref_get(&device->refcount);
                kref_get(&device->refcount);
                kref_init(&chan->refcount);
                chan->slow_ref = 0;
index f204c39fb412e2c25469ffbe41dc7e483d65096d..16e0fd8facfb8ca30aaa4427815f165b0f60317f 100644 (file)
@@ -39,10 +39,14 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Intel Corporation");
 
 static struct pci_device_id ioat_pci_tbl[] = {
+       /* I/OAT v1 platforms */
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB)  },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
        { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
+
+       /* I/OAT v2 platforms */
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB) },
        { 0, }
 };
 
@@ -74,10 +78,17 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
                if (device->dma && ioat_dca_enabled)
                        device->dca = ioat_dca_init(pdev, iobase);
                break;
+       case IOAT_VER_2_0:
+               device->dma = ioat_dma_probe(pdev, iobase);
+               if (device->dma && ioat_dca_enabled)
+                       device->dca = ioat2_dca_init(pdev, iobase);
+               break;
        default:
                err = -ENODEV;
                break;
        }
+       if (!device->dma)
+               err = -ENODEV;
        return err;
 }
 
index ba985715b80306fe568018c59ffe016a1404db24..0fa8a98051a8b05f8f0b1705e1ca430c2c91bbf8 100644 (file)
@@ -261,3 +261,167 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
        return dca;
 }
 
+
+static int ioat2_dca_add_requester(struct dca_provider *dca, struct device *dev)
+{
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       struct pci_dev *pdev;
+       int i;
+       u16 id;
+       u16 global_req_table;
+
+       /* This implementation only supports PCI-Express */
+       if (dev->bus != &pci_bus_type)
+               return -ENODEV;
+       pdev = to_pci_dev(dev);
+       id = dcaid_from_pcidev(pdev);
+
+       if (ioatdca->requester_count == ioatdca->max_requesters)
+               return -ENODEV;
+
+       for (i = 0; i < ioatdca->max_requesters; i++) {
+               if (ioatdca->req_slots[i].pdev == NULL) {
+                       /* found an empty slot */
+                       ioatdca->requester_count++;
+                       ioatdca->req_slots[i].pdev = pdev;
+                       ioatdca->req_slots[i].rid = id;
+                       global_req_table =
+                             readw(ioatdca->dca_base + IOAT_DCA_GREQID_OFFSET);
+                       writel(id | IOAT_DCA_GREQID_VALID,
+                              ioatdca->iobase + global_req_table + (i * 4));
+                       return i;
+               }
+       }
+       /* Error, ioatdma->requester_count is out of whack */
+       return -EFAULT;
+}
+
+static int ioat2_dca_remove_requester(struct dca_provider *dca,
+                                     struct device *dev)
+{
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       struct pci_dev *pdev;
+       int i;
+       u16 global_req_table;
+
+       /* This implementation only supports PCI-Express */
+       if (dev->bus != &pci_bus_type)
+               return -ENODEV;
+       pdev = to_pci_dev(dev);
+
+       for (i = 0; i < ioatdca->max_requesters; i++) {
+               if (ioatdca->req_slots[i].pdev == pdev) {
+                       global_req_table =
+                             readw(ioatdca->dca_base + IOAT_DCA_GREQID_OFFSET);
+                       writel(0, ioatdca->iobase + global_req_table + (i * 4));
+                       ioatdca->req_slots[i].pdev = NULL;
+                       ioatdca->req_slots[i].rid = 0;
+                       ioatdca->requester_count--;
+                       return i;
+               }
+       }
+       return -ENODEV;
+}
+
+static u8 ioat2_dca_get_tag(struct dca_provider *dca, int cpu)
+{
+       u8 tag;
+
+       tag = ioat_dca_get_tag(dca, cpu);
+       tag = (~tag) & 0x1F;
+       return tag;
+}
+
+static struct dca_ops ioat2_dca_ops = {
+       .add_requester          = ioat2_dca_add_requester,
+       .remove_requester       = ioat2_dca_remove_requester,
+       .get_tag                = ioat2_dca_get_tag,
+};
+
+static int ioat2_dca_count_dca_slots(void *iobase, u16 dca_offset)
+{
+       int slots = 0;
+       u32 req;
+       u16 global_req_table;
+
+       global_req_table = readw(iobase + dca_offset + IOAT_DCA_GREQID_OFFSET);
+       if (global_req_table == 0)
+               return 0;
+       do {
+               req = readl(iobase + global_req_table + (slots * sizeof(u32)));
+               slots++;
+       } while ((req & IOAT_DCA_GREQID_LASTID) == 0);
+
+       return slots;
+}
+
+struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase)
+{
+       struct dca_provider *dca;
+       struct ioat_dca_priv *ioatdca;
+       int slots;
+       int i;
+       int err;
+       u32 tag_map;
+       u16 dca_offset;
+       u16 csi_fsb_control;
+       u16 pcie_control;
+       u8 bit;
+
+       if (!system_has_dca_enabled(pdev))
+               return NULL;
+
+       dca_offset = readw(iobase + IOAT_DCAOFFSET_OFFSET);
+       if (dca_offset == 0)
+               return NULL;
+
+       slots = ioat2_dca_count_dca_slots(iobase, dca_offset);
+       if (slots == 0)
+               return NULL;
+
+       dca = alloc_dca_provider(&ioat2_dca_ops,
+                                sizeof(*ioatdca)
+                                     + (sizeof(struct ioat_dca_slot) * slots));
+       if (!dca)
+               return NULL;
+
+       ioatdca = dca_priv(dca);
+       ioatdca->iobase = iobase;
+       ioatdca->dca_base = iobase + dca_offset;
+       ioatdca->max_requesters = slots;
+
+       /* some bios might not know to turn these on */
+       csi_fsb_control = readw(ioatdca->dca_base + IOAT_FSB_CAP_ENABLE_OFFSET);
+       if ((csi_fsb_control & IOAT_FSB_CAP_ENABLE_PREFETCH) == 0) {
+               csi_fsb_control |= IOAT_FSB_CAP_ENABLE_PREFETCH;
+               writew(csi_fsb_control,
+                      ioatdca->dca_base + IOAT_FSB_CAP_ENABLE_OFFSET);
+       }
+       pcie_control = readw(ioatdca->dca_base + IOAT_PCI_CAP_ENABLE_OFFSET);
+       if ((pcie_control & IOAT_PCI_CAP_ENABLE_MEMWR) == 0) {
+               pcie_control |= IOAT_PCI_CAP_ENABLE_MEMWR;
+               writew(pcie_control,
+                      ioatdca->dca_base + IOAT_PCI_CAP_ENABLE_OFFSET);
+       }
+
+
+       /* TODO version, compatibility and configuration checks */
+
+       /* copy out the APIC to DCA tag map */
+       tag_map = readl(ioatdca->dca_base + IOAT_APICID_TAG_MAP_OFFSET);
+       for (i = 0; i < 5; i++) {
+               bit = (tag_map >> (4 * i)) & 0x0f;
+               if (bit < 8)
+                       ioatdca->tag_map[i] = bit | DCA_TAG_MAP_VALID;
+               else
+                       ioatdca->tag_map[i] = 0;
+       }
+
+       err = register_dca_provider(dca, &pdev->dev);
+       if (err) {
+               free_dca_provider(dca);
+               return NULL;
+       }
+
+       return dca;
+}
index 7e4a785c2dff6fdb5d1640e9b0499974f27f8cc5..c1c2dcc6fc2eea413ed8367a4e839b93a7f2362e 100644 (file)
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 
-#define INITIAL_IOAT_DESC_COUNT 128
-
 #define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
 #define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common)
 #define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
 #define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
 
+static int ioat_pending_level = 4;
+module_param(ioat_pending_level, int, 0644);
+MODULE_PARM_DESC(ioat_pending_level,
+                "high-water mark for pushing ioat descriptors (default: 4)");
+
 /* internal functions */
 static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
 static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
+
+static struct ioat_desc_sw *
+ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
 static struct ioat_desc_sw *
-ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
+ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
 
 static inline struct ioat_dma_chan *ioat_lookup_chan_by_index(
                                                struct ioatdma_device *device,
@@ -130,6 +136,12 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
                ioat_chan->device = device;
                ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1));
                ioat_chan->xfercap = xfercap;
+               ioat_chan->desccount = 0;
+               if (ioat_chan->device->version != IOAT_VER_1_2) {
+                       writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE
+                                       | IOAT_DMA_DCA_ANY_CPU,
+                               ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
+               }
                spin_lock_init(&ioat_chan->cleanup_lock);
                spin_lock_init(&ioat_chan->desc_lock);
                INIT_LIST_HEAD(&ioat_chan->free_desc);
@@ -161,13 +173,17 @@ static void ioat_set_dest(dma_addr_t addr,
        tx_to_ioat_desc(tx)->dst = addr;
 }
 
-static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
+static inline void __ioat1_dma_memcpy_issue_pending(
+                                              struct ioat_dma_chan *ioat_chan);
+static inline void __ioat2_dma_memcpy_issue_pending(
+                                              struct ioat_dma_chan *ioat_chan);
+
+static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
        struct ioat_desc_sw *first = tx_to_ioat_desc(tx);
        struct ioat_desc_sw *prev, *new;
        struct ioat_dma_descriptor *hw;
-       int append = 0;
        dma_cookie_t cookie;
        LIST_HEAD(new_chain);
        u32 copy;
@@ -209,7 +225,7 @@ static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
                list_add_tail(&new->node, &new_chain);
                desc_count++;
                prev = new;
-       } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan)));
+       } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
 
        hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
        if (new->async_tx.callback) {
@@ -246,20 +262,98 @@ static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
                                                        first->async_tx.phys;
        __list_splice(&new_chain, ioat_chan->used_desc.prev);
 
+       ioat_chan->dmacount += desc_count;
        ioat_chan->pending += desc_count;
-       if (ioat_chan->pending >= 4) {
-               append = 1;
-               ioat_chan->pending = 0;
-       }
+       if (ioat_chan->pending >= ioat_pending_level)
+               __ioat1_dma_memcpy_issue_pending(ioat_chan);
        spin_unlock_bh(&ioat_chan->desc_lock);
 
-       if (append)
-               writeb(IOAT_CHANCMD_APPEND,
-                       ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+       return cookie;
+}
+
+static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+       struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
+       struct ioat_desc_sw *first = tx_to_ioat_desc(tx);
+       struct ioat_desc_sw *new;
+       struct ioat_dma_descriptor *hw;
+       dma_cookie_t cookie;
+       u32 copy;
+       size_t len;
+       dma_addr_t src, dst;
+       int orig_ack;
+       unsigned int desc_count = 0;
+
+       /* src and dest and len are stored in the initial descriptor */
+       len = first->len;
+       src = first->src;
+       dst = first->dst;
+       orig_ack = first->async_tx.ack;
+       new = first;
+
+       /* ioat_chan->desc_lock is still in force in version 2 path */
+
+       do {
+               copy = min((u32) len, ioat_chan->xfercap);
+
+               new->async_tx.ack = 1;
+
+               hw = new->hw;
+               hw->size = copy;
+               hw->ctl = 0;
+               hw->src_addr = src;
+               hw->dst_addr = dst;
+
+               len -= copy;
+               dst += copy;
+               src += copy;
+               desc_count++;
+       } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
+
+       hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+       if (new->async_tx.callback) {
+               hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+               if (first != new) {
+                       /* move callback into to last desc */
+                       new->async_tx.callback = first->async_tx.callback;
+                       new->async_tx.callback_param
+                                       = first->async_tx.callback_param;
+                       first->async_tx.callback = NULL;
+                       first->async_tx.callback_param = NULL;
+               }
+       }
+
+       new->tx_cnt = desc_count;
+       new->async_tx.ack = orig_ack; /* client is in control of this ack */
+
+       /* store the original values for use in later cleanup */
+       if (new != first) {
+               new->src = first->src;
+               new->dst = first->dst;
+               new->len = first->len;
+       }
+
+       /* cookie incr and addition to used_list must be atomic */
+       cookie = ioat_chan->common.cookie;
+       cookie++;
+       if (cookie < 0)
+               cookie = 1;
+       ioat_chan->common.cookie = new->async_tx.cookie = cookie;
+
+       ioat_chan->dmacount += desc_count;
+       ioat_chan->pending += desc_count;
+       if (ioat_chan->pending >= ioat_pending_level)
+               __ioat2_dma_memcpy_issue_pending(ioat_chan);
+       spin_unlock_bh(&ioat_chan->desc_lock);
 
        return cookie;
 }
 
+/**
+ * ioat_dma_alloc_descriptor - allocate and return a sw and hw descriptor pair
+ * @ioat_chan: the channel supplying the memory pool for the descriptors
+ * @flags: allocation flags
+ */
 static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
                                        struct ioat_dma_chan *ioat_chan,
                                        gfp_t flags)
@@ -284,15 +378,57 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
        dma_async_tx_descriptor_init(&desc_sw->async_tx, &ioat_chan->common);
        desc_sw->async_tx.tx_set_src = ioat_set_src;
        desc_sw->async_tx.tx_set_dest = ioat_set_dest;
-       desc_sw->async_tx.tx_submit = ioat_tx_submit;
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               desc_sw->async_tx.tx_submit = ioat1_tx_submit;
+               break;
+       case IOAT_VER_2_0:
+               desc_sw->async_tx.tx_submit = ioat2_tx_submit;
+               break;
+       }
        INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
+
        desc_sw->hw = desc;
        desc_sw->async_tx.phys = phys;
 
        return desc_sw;
 }
 
-/* returns the actual number of allocated descriptors */
+static int ioat_initial_desc_count = 256;
+module_param(ioat_initial_desc_count, int, 0644);
+MODULE_PARM_DESC(ioat_initial_desc_count,
+                "initial descriptors per channel (default: 256)");
+
+/**
+ * ioat2_dma_massage_chan_desc - link the descriptors into a circle
+ * @ioat_chan: the channel to be massaged
+ */
+static void ioat2_dma_massage_chan_desc(struct ioat_dma_chan *ioat_chan)
+{
+       struct ioat_desc_sw *desc, *_desc;
+
+       /* setup used_desc */
+       ioat_chan->used_desc.next = ioat_chan->free_desc.next;
+       ioat_chan->used_desc.prev = NULL;
+
+       /* pull free_desc out of the circle so that every node is a hw
+        * descriptor, but leave it pointing to the list
+        */
+       ioat_chan->free_desc.prev->next = ioat_chan->free_desc.next;
+       ioat_chan->free_desc.next->prev = ioat_chan->free_desc.prev;
+
+       /* circle link the hw descriptors */
+       desc = to_ioat_desc(ioat_chan->free_desc.next);
+       desc->hw->next = to_ioat_desc(desc->node.next)->async_tx.phys;
+       list_for_each_entry_safe(desc, _desc, ioat_chan->free_desc.next, node) {
+               desc->hw->next = to_ioat_desc(desc->node.next)->async_tx.phys;
+       }
+}
+
+/**
+ * ioat_dma_alloc_chan_resources - returns the number of allocated descriptors
+ * @chan: the channel to be filled out
+ */
 static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
@@ -304,7 +440,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
 
        /* have we already been set up? */
        if (!list_empty(&ioat_chan->free_desc))
-               return INITIAL_IOAT_DESC_COUNT;
+               return ioat_chan->desccount;
 
        /* Setup register to interrupt and write completion status on error */
        chanctrl = IOAT_CHANCTRL_ERR_INT_EN |
@@ -320,7 +456,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
        }
 
        /* Allocate descriptors */
-       for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
+       for (i = 0; i < ioat_initial_desc_count; i++) {
                desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
                if (!desc) {
                        dev_err(&ioat_chan->device->pdev->dev,
@@ -330,7 +466,10 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
                list_add_tail(&desc->node, &tmp_list);
        }
        spin_lock_bh(&ioat_chan->desc_lock);
+       ioat_chan->desccount = i;
        list_splice(&tmp_list, &ioat_chan->free_desc);
+       if (ioat_chan->device->version != IOAT_VER_1_2)
+               ioat2_dma_massage_chan_desc(ioat_chan);
        spin_unlock_bh(&ioat_chan->desc_lock);
 
        /* allocate a completion writeback area */
@@ -347,10 +486,14 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
               ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
 
        tasklet_enable(&ioat_chan->cleanup_task);
-       ioat_dma_start_null_desc(ioat_chan);
-       return i;
+       ioat_dma_start_null_desc(ioat_chan);  /* give chain to dma device */
+       return ioat_chan->desccount;
 }
 
+/**
+ * ioat_dma_free_chan_resources - release all the descriptors
+ * @chan: the channel to be cleaned
+ */
 static void ioat_dma_free_chan_resources(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
@@ -364,22 +507,45 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        /* Delay 100ms after reset to allow internal DMA logic to quiesce
         * before removing DMA descriptor resources.
         */
-       writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+       writeb(IOAT_CHANCMD_RESET,
+              ioat_chan->reg_base
+                       + IOAT_CHANCMD_OFFSET(ioat_chan->device->version));
        mdelay(100);
 
        spin_lock_bh(&ioat_chan->desc_lock);
-       list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
-               in_use_descs++;
-               list_del(&desc->node);
-               pci_pool_free(ioatdma_device->dma_pool, desc->hw,
-                             desc->async_tx.phys);
-               kfree(desc);
-       }
-       list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
-               list_del(&desc->node);
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               list_for_each_entry_safe(desc, _desc,
+                                        &ioat_chan->used_desc, node) {
+                       in_use_descs++;
+                       list_del(&desc->node);
+                       pci_pool_free(ioatdma_device->dma_pool, desc->hw,
+                                     desc->async_tx.phys);
+                       kfree(desc);
+               }
+               list_for_each_entry_safe(desc, _desc,
+                                        &ioat_chan->free_desc, node) {
+                       list_del(&desc->node);
+                       pci_pool_free(ioatdma_device->dma_pool, desc->hw,
+                                     desc->async_tx.phys);
+                       kfree(desc);
+               }
+               break;
+       case IOAT_VER_2_0:
+               list_for_each_entry_safe(desc, _desc,
+                                        ioat_chan->free_desc.next, node) {
+                       list_del(&desc->node);
+                       pci_pool_free(ioatdma_device->dma_pool, desc->hw,
+                                     desc->async_tx.phys);
+                       kfree(desc);
+               }
+               desc = to_ioat_desc(ioat_chan->free_desc.next);
                pci_pool_free(ioatdma_device->dma_pool, desc->hw,
                              desc->async_tx.phys);
                kfree(desc);
+               INIT_LIST_HEAD(&ioat_chan->free_desc);
+               INIT_LIST_HEAD(&ioat_chan->used_desc);
+               break;
        }
        spin_unlock_bh(&ioat_chan->desc_lock);
 
@@ -395,6 +561,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
 
        ioat_chan->last_completion = ioat_chan->completion_addr = 0;
        ioat_chan->pending = 0;
+       ioat_chan->dmacount = 0;
 }
 
 /**
@@ -406,7 +573,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
  * has run out.
  */
 static struct ioat_desc_sw *
-ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
+ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
 {
        struct ioat_desc_sw *new = NULL;
 
@@ -425,7 +592,82 @@ ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
        return new;
 }
 
-static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
+static struct ioat_desc_sw *
+ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
+{
+       struct ioat_desc_sw *new = NULL;
+
+       /*
+        * used.prev points to where to start processing
+        * used.next points to next free descriptor
+        * if used.prev == NULL, there are none waiting to be processed
+        * if used.next == used.prev.prev, there is only one free descriptor,
+        *      and we need to use it to as a noop descriptor before
+        *      linking in a new set of descriptors, since the device
+        *      has probably already read the pointer to it
+        */
+       if (ioat_chan->used_desc.prev &&
+           ioat_chan->used_desc.next == ioat_chan->used_desc.prev->prev) {
+
+               struct ioat_desc_sw *desc = NULL;
+               struct ioat_desc_sw *noop_desc = NULL;
+               int i;
+
+               /* set up the noop descriptor */
+               noop_desc = to_ioat_desc(ioat_chan->used_desc.next);
+               noop_desc->hw->size = 0;
+               noop_desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
+               noop_desc->hw->src_addr = 0;
+               noop_desc->hw->dst_addr = 0;
+
+               ioat_chan->used_desc.next = ioat_chan->used_desc.next->next;
+               ioat_chan->pending++;
+               ioat_chan->dmacount++;
+
+               /* get a few more descriptors */
+               for (i = 16; i; i--) {
+                       desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
+                       BUG_ON(!desc);
+                       list_add_tail(&desc->node, ioat_chan->used_desc.next);
+
+                       desc->hw->next
+                               = to_ioat_desc(desc->node.next)->async_tx.phys;
+                       to_ioat_desc(desc->node.prev)->hw->next
+                               = desc->async_tx.phys;
+                       ioat_chan->desccount++;
+               }
+
+               ioat_chan->used_desc.next = noop_desc->node.next;
+       }
+       new = to_ioat_desc(ioat_chan->used_desc.next);
+       prefetch(new);
+       ioat_chan->used_desc.next = new->node.next;
+
+       if (ioat_chan->used_desc.prev == NULL)
+               ioat_chan->used_desc.prev = &new->node;
+
+       prefetch(new->hw);
+       return new;
+}
+
+static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
+                                               struct ioat_dma_chan *ioat_chan)
+{
+       if (!ioat_chan)
+               return NULL;
+
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               return ioat1_dma_get_next_descriptor(ioat_chan);
+               break;
+       case IOAT_VER_2_0:
+               return ioat2_dma_get_next_descriptor(ioat_chan);
+               break;
+       }
+       return NULL;
+}
+
+static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy(
                                                struct dma_chan *chan,
                                                size_t len,
                                                int int_en)
@@ -441,19 +683,62 @@ static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
        return new ? &new->async_tx : NULL;
 }
 
+static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
+                                               struct dma_chan *chan,
+                                               size_t len,
+                                               int int_en)
+{
+       struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+       struct ioat_desc_sw *new;
+
+       spin_lock_bh(&ioat_chan->desc_lock);
+       new = ioat2_dma_get_next_descriptor(ioat_chan);
+       new->len = len;
+
+       /* leave ioat_chan->desc_lock set in version 2 path */
+       return new ? &new->async_tx : NULL;
+}
+
+
 /**
  * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
  *                                 descriptors to hw
  * @chan: DMA channel handle
  */
-static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
+static inline void __ioat1_dma_memcpy_issue_pending(
+                                               struct ioat_dma_chan *ioat_chan)
+{
+       ioat_chan->pending = 0;
+       writeb(IOAT_CHANCMD_APPEND, ioat_chan->reg_base + IOAT1_CHANCMD_OFFSET);
+}
+
+static void ioat1_dma_memcpy_issue_pending(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
 
        if (ioat_chan->pending != 0) {
-               ioat_chan->pending = 0;
-               writeb(IOAT_CHANCMD_APPEND,
-                      ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+               spin_lock_bh(&ioat_chan->desc_lock);
+               __ioat1_dma_memcpy_issue_pending(ioat_chan);
+               spin_unlock_bh(&ioat_chan->desc_lock);
+       }
+}
+
+static inline void __ioat2_dma_memcpy_issue_pending(
+                                               struct ioat_dma_chan *ioat_chan)
+{
+       ioat_chan->pending = 0;
+       writew(ioat_chan->dmacount,
+              ioat_chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
+}
+
+static void ioat2_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+       struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+       if (ioat_chan->pending != 0) {
+               spin_lock_bh(&ioat_chan->desc_lock);
+               __ioat2_dma_memcpy_issue_pending(ioat_chan);
+               spin_unlock_bh(&ioat_chan->desc_lock);
        }
 }
 
@@ -465,11 +750,17 @@ static void ioat_dma_cleanup_tasklet(unsigned long data)
               chan->reg_base + IOAT_CHANCTRL_OFFSET);
 }
 
+/**
+ * ioat_dma_memcpy_cleanup - cleanup up finished descriptors
+ * @chan: ioat channel to be cleaned up
+ */
 static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
 {
        unsigned long phys_complete;
        struct ioat_desc_sw *desc, *_desc;
        dma_cookie_t cookie = 0;
+       unsigned long desc_phys;
+       struct ioat_desc_sw *latest_desc;
 
        prefetch(ioat_chan->completion_virt);
 
@@ -507,56 +798,115 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
 
        cookie = 0;
        spin_lock_bh(&ioat_chan->desc_lock);
-       list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
-
-               /*
-                * Incoming DMA requests may use multiple descriptors, due to
-                * exceeding xfercap, perhaps. If so, only the last one will
-                * have a cookie, and require unmapping.
-                */
-               if (desc->async_tx.cookie) {
-                       cookie = desc->async_tx.cookie;
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               list_for_each_entry_safe(desc, _desc,
+                                        &ioat_chan->used_desc, node) {
 
                        /*
-                        * yes we are unmapping both _page and _single alloc'd
-                        * regions with unmap_page. Is this *really* that bad?
+                        * Incoming DMA requests may use multiple descriptors,
+                        * due to exceeding xfercap, perhaps. If so, only the
+                        * last one will have a cookie, and require unmapping.
                         */
-                       pci_unmap_page(ioat_chan->device->pdev,
-                                       pci_unmap_addr(desc, dst),
-                                       pci_unmap_len(desc, len),
-                                       PCI_DMA_FROMDEVICE);
-                       pci_unmap_page(ioat_chan->device->pdev,
-                                       pci_unmap_addr(desc, src),
-                                       pci_unmap_len(desc, len),
-                                       PCI_DMA_TODEVICE);
-                       if (desc->async_tx.callback) {
-                               desc->async_tx.callback(
-                                               desc->async_tx.callback_param);
-                               desc->async_tx.callback = NULL;
+                       if (desc->async_tx.cookie) {
+                               cookie = desc->async_tx.cookie;
+
+                               /*
+                                * yes we are unmapping both _page and _single
+                                * alloc'd regions with unmap_page. Is this
+                                * *really* that bad?
+                                */
+                               pci_unmap_page(ioat_chan->device->pdev,
+                                               pci_unmap_addr(desc, dst),
+                                               pci_unmap_len(desc, len),
+                                               PCI_DMA_FROMDEVICE);
+                               pci_unmap_page(ioat_chan->device->pdev,
+                                               pci_unmap_addr(desc, src),
+                                               pci_unmap_len(desc, len),
+                                               PCI_DMA_TODEVICE);
+
+                               if (desc->async_tx.callback) {
+                                       desc->async_tx.callback(desc->async_tx.callback_param);
+                                       desc->async_tx.callback = NULL;
+                               }
                        }
-               }
 
-               if (desc->async_tx.phys != phys_complete) {
-                       /*
-                        * a completed entry, but not the last, so cleanup
-                        * if the client is done with the descriptor
-                        */
-                       if (desc->async_tx.ack) {
-                               list_del(&desc->node);
-                               list_add_tail(&desc->node,
-                                             &ioat_chan->free_desc);
-                       } else
+                       if (desc->async_tx.phys != phys_complete) {
+                               /*
+                                * a completed entry, but not the last, so clean
+                                * up if the client is done with the descriptor
+                                */
+                               if (desc->async_tx.ack) {
+                                       list_del(&desc->node);
+                                       list_add_tail(&desc->node,
+                                                     &ioat_chan->free_desc);
+                               } else
+                                       desc->async_tx.cookie = 0;
+                       } else {
+                               /*
+                                * last used desc. Do not remove, so we can
+                                * append from it, but don't look at it next
+                                * time, either
+                                */
                                desc->async_tx.cookie = 0;
-               } else {
-                       /*
-                        * last used desc. Do not remove, so we can append from
-                        * it, but don't look at it next time, either
-                        */
-                       desc->async_tx.cookie = 0;
 
-                       /* TODO check status bits? */
+                               /* TODO check status bits? */
+                               break;
+                       }
+               }
+               break;
+       case IOAT_VER_2_0:
+               /* has some other thread has already cleaned up? */
+               if (ioat_chan->used_desc.prev == NULL)
                        break;
+
+               /* work backwards to find latest finished desc */
+               desc = to_ioat_desc(ioat_chan->used_desc.next);
+               latest_desc = NULL;
+               do {
+                       desc = to_ioat_desc(desc->node.prev);
+                       desc_phys = (unsigned long)desc->async_tx.phys
+                                      & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+                       if (desc_phys == phys_complete) {
+                               latest_desc = desc;
+                               break;
+                       }
+               } while (&desc->node != ioat_chan->used_desc.prev);
+
+               if (latest_desc != NULL) {
+
+                       /* work forwards to clear finished descriptors */
+                       for (desc = to_ioat_desc(ioat_chan->used_desc.prev);
+                            &desc->node != latest_desc->node.next &&
+                            &desc->node != ioat_chan->used_desc.next;
+                            desc = to_ioat_desc(desc->node.next)) {
+                               if (desc->async_tx.cookie) {
+                                       cookie = desc->async_tx.cookie;
+                                       desc->async_tx.cookie = 0;
+
+                                       pci_unmap_page(ioat_chan->device->pdev,
+                                                     pci_unmap_addr(desc, dst),
+                                                     pci_unmap_len(desc, len),
+                                                     PCI_DMA_FROMDEVICE);
+                                       pci_unmap_page(ioat_chan->device->pdev,
+                                                     pci_unmap_addr(desc, src),
+                                                     pci_unmap_len(desc, len),
+                                                     PCI_DMA_TODEVICE);
+
+                                       if (desc->async_tx.callback) {
+                                               desc->async_tx.callback(desc->async_tx.callback_param);
+                                               desc->async_tx.callback = NULL;
+                                       }
+                               }
+                       }
+
+                       /* move used.prev up beyond those that are finished */
+                       if (&desc->node == ioat_chan->used_desc.next)
+                               ioat_chan->used_desc.prev = NULL;
+                       else
+                               ioat_chan->used_desc.prev = &desc->node;
                }
+               break;
        }
 
        spin_unlock_bh(&ioat_chan->desc_lock);
@@ -621,8 +971,6 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
        return dma_async_is_complete(cookie, last_complete, last_used);
 }
 
-/* PCI API */
-
 static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
 {
        struct ioat_desc_sw *desc;
@@ -633,21 +981,34 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
        desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL
                                | IOAT_DMA_DESCRIPTOR_CTL_INT_GN
                                | IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       desc->hw->next = 0;
        desc->hw->size = 0;
        desc->hw->src_addr = 0;
        desc->hw->dst_addr = 0;
        desc->async_tx.ack = 1;
-
-       list_add_tail(&desc->node, &ioat_chan->used_desc);
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               desc->hw->next = 0;
+               list_add_tail(&desc->node, &ioat_chan->used_desc);
+
+               writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
+                      ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_LOW);
+               writel(((u64) desc->async_tx.phys) >> 32,
+                      ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_HIGH);
+
+               writeb(IOAT_CHANCMD_START, ioat_chan->reg_base
+                       + IOAT_CHANCMD_OFFSET(ioat_chan->device->version));
+               break;
+       case IOAT_VER_2_0:
+               writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
+                      ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW);
+               writel(((u64) desc->async_tx.phys) >> 32,
+                      ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_HIGH);
+
+               ioat_chan->dmacount++;
+               __ioat2_dma_memcpy_issue_pending(ioat_chan);
+               break;
+       }
        spin_unlock_bh(&ioat_chan->desc_lock);
-
-       writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
-              ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_LOW);
-       writel(((u64) desc->async_tx.phys) >> 32,
-              ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_HIGH);
-
-       writeb(IOAT_CHANCMD_START, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
 }
 
 /*
@@ -693,14 +1054,14 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
+       if (device->common.device_alloc_chan_resources(dma_chan) < 1) {
                dev_err(&device->pdev->dev,
                        "selftest cannot allocate chan resource\n");
                err = -ENODEV;
                goto out;
        }
 
-       tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
+       tx = device->common.device_prep_dma_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
        if (!tx) {
                dev_err(&device->pdev->dev,
                        "Self-test prep failed, disabling\n");
@@ -710,24 +1071,25 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
 
        async_tx_ack(tx);
        addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE,
-                       DMA_TO_DEVICE);
-       ioat_set_src(addr, tx, 0);
+                             DMA_TO_DEVICE);
+       tx->tx_set_src(addr, tx, 0);
        addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
-                       DMA_FROM_DEVICE);
-       ioat_set_dest(addr, tx, 0);
+                             DMA_FROM_DEVICE);
+       tx->tx_set_dest(addr, tx, 0);
        tx->callback = ioat_dma_test_callback;
        tx->callback_param = (void *)0x8086;
-       cookie = ioat_tx_submit(tx);
+       cookie = tx->tx_submit(tx);
        if (cookie < 0) {
                dev_err(&device->pdev->dev,
                        "Self-test setup failed, disabling\n");
                err = -ENODEV;
                goto free_resources;
        }
-       ioat_dma_memcpy_issue_pending(dma_chan);
+       device->common.device_issue_pending(dma_chan);
        msleep(1);
 
-       if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+       if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
+                                       != DMA_SUCCESS) {
                dev_err(&device->pdev->dev,
                        "Self-test copy timed out, disabling\n");
                err = -ENODEV;
@@ -741,7 +1103,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        }
 
 free_resources:
-       ioat_dma_free_chan_resources(dma_chan);
+       device->common.device_free_chan_resources(dma_chan);
 out:
        kfree(src);
        kfree(dest);
@@ -941,16 +1303,28 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
        INIT_LIST_HEAD(&device->common.channels);
        ioat_dma_enumerate_channels(device);
 
-       dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
        device->common.device_alloc_chan_resources =
                                                ioat_dma_alloc_chan_resources;
        device->common.device_free_chan_resources =
                                                ioat_dma_free_chan_resources;
-       device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy;
+       device->common.dev = &pdev->dev;
+
+       dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
        device->common.device_is_tx_complete = ioat_dma_is_complete;
-       device->common.device_issue_pending = ioat_dma_memcpy_issue_pending;
        device->common.device_dependency_added = ioat_dma_dependency_added;
-       device->common.dev = &pdev->dev;
+       switch (device->version) {
+       case IOAT_VER_1_2:
+               device->common.device_prep_dma_memcpy = ioat1_dma_prep_memcpy;
+               device->common.device_issue_pending =
+                                               ioat1_dma_memcpy_issue_pending;
+               break;
+       case IOAT_VER_2_0:
+               device->common.device_prep_dma_memcpy = ioat2_dma_prep_memcpy;
+               device->common.device_issue_pending =
+                                               ioat2_dma_memcpy_issue_pending;
+               break;
+       }
+
        dev_err(&device->pdev->dev,
                "Intel(R) I/OAT DMA Engine found,"
                " %d channels, device version 0x%02x, driver version %s\n",
index 5f9881e7b0ed25bc2722ac67c3f2b2cd10a1ed4d..b668234ef654b2590e88d752c4cf83d53a4d2585 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,7 @@
 #include <linux/cache.h>
 #include <linux/pci_ids.h>
 
-#define IOAT_DMA_VERSION "1.26"
+#define IOAT_DMA_VERSION  "2.04"
 
 enum ioat_interrupt {
        none = 0,
@@ -39,6 +39,8 @@ enum ioat_interrupt {
 };
 
 #define IOAT_LOW_COMPLETION_MASK       0xffffffc0
+#define IOAT_DMA_DCA_ANY_CPU           ~0
+
 
 /**
  * struct ioatdma_device - internal representation of a IOAT device
@@ -47,6 +49,9 @@ enum ioat_interrupt {
  * @dma_pool: for allocating DMA descriptors
  * @common: embedded struct dma_device
  * @version: version of ioatdma device
+ * @irq_mode: which style irq to use
+ * @msix_entries: irq handlers
+ * @idx: per channel data
  */
 
 struct ioatdma_device {
@@ -63,23 +68,7 @@ struct ioatdma_device {
 
 /**
  * struct ioat_dma_chan - internal representation of a DMA channel
- * @device:
- * @reg_base:
- * @sw_in_use:
- * @completion:
- * @completion_low:
- * @completion_high:
- * @completed_cookie: last cookie seen completed on cleanup
- * @cookie: value of last cookie given to client
- * @last_completion:
- * @xfercap:
- * @desc_lock:
- * @free_desc:
- * @used_desc:
- * @resource:
- * @device_node:
  */
-
 struct ioat_dma_chan {
 
        void __iomem *reg_base;
@@ -95,6 +84,8 @@ struct ioat_dma_chan {
        struct list_head used_desc;
 
        int pending;
+       int dmacount;
+       int desccount;
 
        struct ioatdma_device *device;
        struct dma_chan common;
@@ -134,12 +125,13 @@ struct ioat_desc_sw {
 struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
                                      void __iomem *iobase);
 void ioat_dma_remove(struct ioatdma_device *device);
-struct dca_provider *ioat_dca_init(struct pci_dev *pdev,
-                                  void __iomem *iobase);
+struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase);
+struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase);
 #else
 #define ioat_dma_probe(pdev, iobase)    NULL
 #define ioat_dma_remove(device)         do { } while (0)
 #define ioat_dca_init(pdev, iobase)    NULL
+#define ioat2_dca_init(pdev, iobase)   NULL
 #endif
 
 #endif /* IOATDMA_H */
index 9e7434e1551f9b02ba5bae19dd96b55821622184..dd470fa91d86a4e10d8187e63d095125fb5a8526 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
 #define _IOAT_HW_H_
 
 /* PCI Configuration Space Values */
-#define IOAT_PCI_VID                   0x8086
-#define IOAT_PCI_DID                   0x1A38
-#define IOAT_PCI_RID                   0x00
-#define IOAT_PCI_SVID                  0x8086
-#define IOAT_PCI_SID                   0x8086
-#define IOAT_VER_1_2                   0x12    /* Version 1.2 */
+#define IOAT_PCI_VID            0x8086
+
+/* CB device ID's */
+#define IOAT_PCI_DID_5000       0x1A38
+#define IOAT_PCI_DID_CNB        0x360B
+#define IOAT_PCI_DID_SCNB       0x65FF
+#define IOAT_PCI_DID_SNB        0x402F
+
+#define IOAT_PCI_RID            0x00
+#define IOAT_PCI_SVID           0x8086
+#define IOAT_PCI_SID            0x8086
+#define IOAT_VER_1_2            0x12    /* Version 1.2 */
+#define IOAT_VER_2_0            0x20    /* Version 2.0 */
 
 struct ioat_dma_descriptor {
        uint32_t        size;
@@ -47,6 +54,16 @@ struct ioat_dma_descriptor {
 #define IOAT_DMA_DESCRIPTOR_CTL_CP_STS 0x00000008
 #define IOAT_DMA_DESCRIPTOR_CTL_FRAME  0x00000010
 #define IOAT_DMA_DESCRIPTOR_NUL                0x00000020
-#define IOAT_DMA_DESCRIPTOR_OPCODE     0xFF000000
+#define IOAT_DMA_DESCRIPTOR_CTL_SP_BRK 0x00000040
+#define IOAT_DMA_DESCRIPTOR_CTL_DP_BRK 0x00000080
+#define IOAT_DMA_DESCRIPTOR_CTL_BNDL   0x00000100
+#define IOAT_DMA_DESCRIPTOR_CTL_DCA    0x00000200
+#define IOAT_DMA_DESCRIPTOR_CTL_BUFHINT        0x00000400
+
+#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_CONTEXT 0xFF000000
+#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_DMA     0x00000000
+
+#define IOAT_DMA_DESCRIPTOR_CTL_CONTEXT_DCA    0x00000001
+#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_MASK    0xFF000000
 
 #endif
index baaab5ea146a757e4faf3ec98ffe9d54d1f18d9b..9832d7ebd931a0a76dafc6d66948b37e4a16da52 100644 (file)
 #define IOAT_INTRCTRL_MASTER_INT_EN            0x01    /* Master Interrupt Enable */
 #define IOAT_INTRCTRL_INT_STATUS               0x02    /* ATTNSTATUS -or- Channel Int */
 #define IOAT_INTRCTRL_INT                      0x04    /* INT_STATUS -and- MASTER_INT_EN */
-#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL      0x08    /* Enable all MSI-X vectors */
+#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL      0x08    /* Enable all MSI-X vectors */
 
 #define IOAT_ATTNSTATUS_OFFSET                 0x04    /* Each bit is a channel */
 
 #define IOAT_VER_OFFSET                                0x08    /*  8-bit */
 #define IOAT_VER_MAJOR_MASK                    0xF0
 #define IOAT_VER_MINOR_MASK                    0x0F
-#define GET_IOAT_VER_MAJOR(x)                  ((x) & IOAT_VER_MAJOR_MASK)
+#define GET_IOAT_VER_MAJOR(x)                  (((x) & IOAT_VER_MAJOR_MASK) >> 4)
 #define GET_IOAT_VER_MINOR(x)                  ((x) & IOAT_VER_MINOR_MASK)
 
 #define IOAT_PERPORTOFFSET_OFFSET              0x0A    /* 16-bit */
 
 #define IOAT_INTRDELAY_OFFSET                  0x0C    /* 16-bit */
 #define IOAT_INTRDELAY_INT_DELAY_MASK          0x3FFF  /* Interrupt Delay Time */
-#define IOAT_INTRDELAY_COALESE_SUPPORT         0x8000  /* Interrupt Coalesing Supported */
+#define IOAT_INTRDELAY_COALESE_SUPPORT         0x8000  /* Interrupt Coalescing Supported */
 
 #define IOAT_DEVICE_STATUS_OFFSET              0x0E    /* 16-bit */
 #define IOAT_DEVICE_STATUS_DEGRADED_MODE       0x0001
 
-
 #define IOAT_CHANNEL_MMIO_SIZE                 0x80    /* Each Channel MMIO space is this size */
 
 /* DMA Channel Registers */
 #define IOAT_CHANCTRL_ERR_COMPLETION_EN                0x0004
 #define IOAT_CHANCTRL_INT_DISABLE              0x0001
 
-#define IOAT_DMA_COMP_OFFSET                   0x02    /* 16-bit DMA channel compatability */
-#define IOAT_DMA_COMP_V1                       0x0001  /* Compatability with DMA version 1 */
-
-#define IOAT_CHANSTS_OFFSET                    0x04    /* 64-bit Channel Status Register */
-#define IOAT_CHANSTS_OFFSET_LOW                        0x04
-#define IOAT_CHANSTS_OFFSET_HIGH               0x08
-#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR 0xFFFFFFFFFFFFFFC0UL
+#define IOAT_DMA_COMP_OFFSET                   0x02    /* 16-bit DMA channel compatibility */
+#define IOAT_DMA_COMP_V1                       0x0001  /* Compatibility with DMA version 1 */
+#define IOAT_DMA_COMP_V2                       0x0002  /* Compatibility with DMA version 2 */
+
+
+#define IOAT1_CHANSTS_OFFSET           0x04    /* 64-bit Channel Status Register */
+#define IOAT2_CHANSTS_OFFSET           0x08    /* 64-bit Channel Status Register */
+#define IOAT_CHANSTS_OFFSET(ver)               ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHANSTS_OFFSET : IOAT2_CHANSTS_OFFSET)
+#define IOAT1_CHANSTS_OFFSET_LOW       0x04
+#define IOAT2_CHANSTS_OFFSET_LOW       0x08
+#define IOAT_CHANSTS_OFFSET_LOW(ver)           ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHANSTS_OFFSET_LOW : IOAT2_CHANSTS_OFFSET_LOW)
+#define IOAT1_CHANSTS_OFFSET_HIGH      0x08
+#define IOAT2_CHANSTS_OFFSET_HIGH      0x0C
+#define IOAT_CHANSTS_OFFSET_HIGH(ver)          ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHANSTS_OFFSET_HIGH : IOAT2_CHANSTS_OFFSET_HIGH)
+#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR ~0x3F
 #define IOAT_CHANSTS_SOFT_ERR                  0x0000000000000010
+#define IOAT_CHANSTS_UNAFFILIATED_ERR          0x0000000000000008
 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS       0x0000000000000007
 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE        0x0
 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE  0x1
 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_SUSPENDED     0x2
 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED        0x3
 
-#define IOAT_CHAINADDR_OFFSET                  0x0C    /* 64-bit Descriptor Chain Address Register */
-#define IOAT_CHAINADDR_OFFSET_LOW              0x0C
-#define IOAT_CHAINADDR_OFFSET_HIGH             0x10
 
-#define IOAT_CHANCMD_OFFSET                    0x14    /*  8-bit DMA Channel Command Register */
+
+#define IOAT_CHAN_DMACOUNT_OFFSET      0x06    /* 16-bit DMA Count register */
+
+#define IOAT_DCACTRL_OFFSET         0x30   /* 32 bit Direct Cache Access Control Register */
+#define IOAT_DCACTRL_CMPL_WRITE_ENABLE 0x10000
+#define IOAT_DCACTRL_TARGET_CPU_MASK   0xFFFF /* APIC ID */
+
+/* CB DCA Memory Space Registers */
+#define IOAT_DCAOFFSET_OFFSET       0x14
+/* CB_BAR + IOAT_DCAOFFSET value */
+#define IOAT_DCA_VER_OFFSET         0x00
+#define IOAT_DCA_VER_MAJOR_MASK     0xF0
+#define IOAT_DCA_VER_MINOR_MASK     0x0F
+
+#define IOAT_DCA_COMP_OFFSET        0x02
+#define IOAT_DCA_COMP_V1            0x1
+
+#define IOAT_FSB_CAPABILITY_OFFSET  0x04
+#define IOAT_FSB_CAPABILITY_PREFETCH    0x1
+
+#define IOAT_PCI_CAPABILITY_OFFSET  0x06
+#define IOAT_PCI_CAPABILITY_MEMWR   0x1
+
+#define IOAT_FSB_CAP_ENABLE_OFFSET  0x08
+#define IOAT_FSB_CAP_ENABLE_PREFETCH    0x1
+
+#define IOAT_PCI_CAP_ENABLE_OFFSET  0x0A
+#define IOAT_PCI_CAP_ENABLE_MEMWR   0x1
+
+#define IOAT_APICID_TAG_MAP_OFFSET  0x0C
+#define IOAT_APICID_TAG_MAP_TAG0    0x0000000F
+#define IOAT_APICID_TAG_MAP_TAG0_SHIFT 0
+#define IOAT_APICID_TAG_MAP_TAG1    0x000000F0
+#define IOAT_APICID_TAG_MAP_TAG1_SHIFT 4
+#define IOAT_APICID_TAG_MAP_TAG2    0x00000F00
+#define IOAT_APICID_TAG_MAP_TAG2_SHIFT 8
+#define IOAT_APICID_TAG_MAP_TAG3    0x0000F000
+#define IOAT_APICID_TAG_MAP_TAG3_SHIFT 12
+#define IOAT_APICID_TAG_MAP_TAG4    0x000F0000
+#define IOAT_APICID_TAG_MAP_TAG4_SHIFT 16
+#define IOAT_APICID_TAG_CB2_VALID   0x8080808080
+
+#define IOAT_DCA_GREQID_OFFSET      0x10
+#define IOAT_DCA_GREQID_SIZE        0x04
+#define IOAT_DCA_GREQID_MASK        0xFFFF
+#define IOAT_DCA_GREQID_IGNOREFUN   0x10000000
+#define IOAT_DCA_GREQID_VALID       0x20000000
+#define IOAT_DCA_GREQID_LASTID      0x80000000
+
+
+
+#define IOAT1_CHAINADDR_OFFSET         0x0C    /* 64-bit Descriptor Chain Address Register */
+#define IOAT2_CHAINADDR_OFFSET         0x10    /* 64-bit Descriptor Chain Address Register */
+#define IOAT_CHAINADDR_OFFSET(ver)             ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHAINADDR_OFFSET : IOAT2_CHAINADDR_OFFSET)
+#define IOAT1_CHAINADDR_OFFSET_LOW     0x0C
+#define IOAT2_CHAINADDR_OFFSET_LOW     0x10
+#define IOAT_CHAINADDR_OFFSET_LOW(ver)         ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHAINADDR_OFFSET_LOW : IOAT2_CHAINADDR_OFFSET_LOW)
+#define IOAT1_CHAINADDR_OFFSET_HIGH    0x10
+#define IOAT2_CHAINADDR_OFFSET_HIGH    0x14
+#define IOAT_CHAINADDR_OFFSET_HIGH(ver)                ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHAINADDR_OFFSET_HIGH : IOAT2_CHAINADDR_OFFSET_HIGH)
+
+#define IOAT1_CHANCMD_OFFSET           0x14    /*  8-bit DMA Channel Command Register */
+#define IOAT2_CHANCMD_OFFSET           0x04    /*  8-bit DMA Channel Command Register */
+#define IOAT_CHANCMD_OFFSET(ver)               ((ver) < IOAT_VER_2_0 \
+                                               ? IOAT1_CHANCMD_OFFSET : IOAT2_CHANCMD_OFFSET)
 #define IOAT_CHANCMD_RESET                     0x20
 #define IOAT_CHANCMD_RESUME                    0x10
 #define IOAT_CHANCMD_ABORT                     0x08
 #define IOAT_CHANERR_COMPLETION_ADDR_ERR       0x1000
 #define IOAT_CHANERR_INT_CONFIGURATION_ERR     0x2000
 #define IOAT_CHANERR_SOFT_ERR                  0x4000
+#define IOAT_CHANERR_UNAFFILIATED_ERR          0x8000
 
 #define IOAT_CHANERR_MASK_OFFSET               0x2C    /* 32-bit Channel Error Register */
 
index 96f7e63e39969122ef132fc9a266d575944598c5..a1f24c42d5ff45176984727961c245df1d0908fc 100644 (file)
@@ -1462,7 +1462,7 @@ MODULE_DEVICE_TABLE(pci, i5000_pci_tbl);
  *
  */
 static struct pci_driver i5000_driver = {
-       .name = __stringify(KBUILD_BASENAME),
+       .name = KBUILD_BASENAME,
        .probe = i5000_init_one,
        .remove = __devexit_p(i5000_remove_one),
        .id_table = i5000_pci_tbl,
index 5596df65c8ed3b11d49c91d97cc36f3e858478c0..624ff3e082f68116f4efe158c80fcdd0c7f27a74 100644 (file)
@@ -650,13 +650,14 @@ static void sbp2_login(struct work_struct *work)
        if (sbp2_send_management_orb(lu, node_id, generation,
                                SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
                if (lu->retries++ < 5) {
-                       queue_delayed_work(sbp2_wq, &lu->work,
-                                          DIV_ROUND_UP(HZ, 5));
+                       if (queue_delayed_work(sbp2_wq, &lu->work,
+                                              DIV_ROUND_UP(HZ, 5)))
+                               kref_get(&lu->tgt->kref);
                } else {
                        fw_error("failed to login to %s LUN %04x\n",
                                 unit->device.bus_id, lu->lun);
-                       kref_put(&lu->tgt->kref, sbp2_release_target);
                }
+               kref_put(&lu->tgt->kref, sbp2_release_target);
                return;
        }
 
@@ -914,7 +915,9 @@ static void sbp2_reconnect(struct work_struct *work)
                        lu->retries = 0;
                        PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
                }
-               queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5));
+               if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5)))
+                       kref_get(&lu->tgt->kref);
+               kref_put(&lu->tgt->kref, sbp2_release_target);
                return;
        }
 
index 700a1657554f4b3b5f4910268343790ddb33c1eb..a0445bea9f75ade0411a2949fe0ff43f1ad75b32 100644 (file)
@@ -216,6 +216,16 @@ config SENSORS_DS1621
          This driver can also be built as a module.  If so, the module
          will be called ds1621.
 
+config SENSORS_I5K_AMB
+       tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
+       depends on PCI && EXPERIMENTAL
+       help
+         If you say yes here you get support for FB-DIMM AMB temperature
+         monitoring chips on systems with the Intel 5000 series chipset.
+
+         This driver can also be built as a module. If so, the module
+         will be called i5k_amb.
+
 config SENSORS_F71805F
        tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG"
        depends on EXPERIMENTAL
index 6da3eef943064a82302fda6ae75b68dc6f5f2e64..55595f6e1aa632a8ecb05eb1306540905ac5a729 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_SENSORS_FSCPOS)  += fscpos.o
 obj-$(CONFIG_SENSORS_GL518SM)  += gl518sm.o
 obj-$(CONFIG_SENSORS_GL520SM)  += gl520sm.o
 obj-$(CONFIG_SENSORS_HDAPS)    += hdaps.o
+obj-$(CONFIG_SENSORS_I5K_AMB)  += i5k_amb.o
 obj-$(CONFIG_SENSORS_IBMPEX)   += ibmpex.o
 obj-$(CONFIG_SENSORS_IT87)     += it87.o
 obj-$(CONFIG_SENSORS_K8TEMP)   += k8temp.o
index cb2331bfd9d5a0f040c49e61fdba8fe0daca7111..d9f04ce903273e7b214eac1659f0086186550d7e 100644 (file)
@@ -503,7 +503,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 FAN",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x001A, "unknown", {
+       { 0x001A, "Abit IP35 Pro", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -530,6 +530,60 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
+       { 0x001B, "unknown", {
+               { "CPU Core",            0, 0, 10, 1, 0 },
+               { "DDR3",                1, 0, 20, 1, 0 },
+               { "DDR3 VTT",            2, 0, 10, 1, 0 },
+               { "CPU VTT",             3, 0, 10, 1, 0 },
+               { "MCH 1.25V",           4, 0, 10, 1, 0 },
+               { "ICHIO 1.5V",          5, 0, 10, 1, 0 },
+               { "ICH 1.05V",           6, 0, 10, 1, 0 },
+               { "ATX +12V (24-Pin)",   7, 0, 60, 1, 0 },
+               { "ATX +12V (8-pin)",    8, 0, 60, 1, 0 },
+               { "ATX +5V",             9, 0, 30, 1, 0 },
+               { "+3.3V",              10, 0, 20, 1, 0 },
+               { "5VSB",               11, 0, 30, 1, 0 },
+               { "CPU",                24, 1, 1, 1, 0 },
+               { "System",             25, 1, 1, 1, 0 },
+               { "PWM Phase1",         26, 1, 1, 1, 0 },
+               { "PWM Phase2",         27, 1, 1, 1, 0 },
+               { "PWM Phase3",         28, 1, 1, 1, 0 },
+               { "PWM Phase4",         29, 1, 1, 1, 0 },
+               { "PWM Phase5",         30, 1, 1, 1, 0 },
+               { "CPU Fan",            32, 2, 60, 1, 0 },
+               { "SYS Fan",            34, 2, 60, 1, 0 },
+               { "AUX1 Fan",           33, 2, 60, 1, 0 },
+               { "AUX2 Fan",           35, 2, 60, 1, 0 },
+               { "AUX3 Fan",           36, 2, 60, 1, 0 },
+               { NULL, 0, 0, 0, 0, 0 } }
+       },
+       { 0x001C, "unknown", {
+               { "CPU Core",            0, 0, 10, 1, 0 },
+               { "DDR2",                1, 0, 20, 1, 0 },
+               { "DDR2 VTT",            2, 0, 10, 1, 0 },
+               { "CPU VTT",             3, 0, 10, 1, 0 },
+               { "MCH 1.25V",           4, 0, 10, 1, 0 },
+               { "ICHIO 1.5V",          5, 0, 10, 1, 0 },
+               { "ICH 1.05V",           6, 0, 10, 1, 0 },
+               { "ATX +12V (24-Pin)",   7, 0, 60, 1, 0 },
+               { "ATX +12V (8-pin)",    8, 0, 60, 1, 0 },
+               { "ATX +5V",             9, 0, 30, 1, 0 },
+               { "+3.3V",              10, 0, 20, 1, 0 },
+               { "5VSB",               11, 0, 30, 1, 0 },
+               { "CPU",                24, 1, 1, 1, 0 },
+               { "System",             25, 1, 1, 1, 0 },
+               { "PWM Phase1",         26, 1, 1, 1, 0 },
+               { "PWM Phase2",         27, 1, 1, 1, 0 },
+               { "PWM Phase3",         28, 1, 1, 1, 0 },
+               { "PWM Phase4",         29, 1, 1, 1, 0 },
+               { "PWM Phase5",         30, 1, 1, 1, 0 },
+               { "CPU Fan",            32, 2, 60, 1, 0 },
+               { "SYS Fan",            34, 2, 60, 1, 0 },
+               { "AUX1 Fan",           33, 2, 60, 1, 0 },
+               { "AUX2 Fan",           35, 2, 60, 1, 0 },
+               { "AUX3 Fan",           36, 2, 60, 1, 0 },
+               { NULL, 0, 0, 0, 0, 0 } }
+       },
        { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
 };
 
index 1001d2e122a262eafa72bb80857260bcc1659472..86c66c345f8b76f8274272796917c740ba312e26 100644 (file)
@@ -80,7 +80,7 @@
 /*
  * Temperature sensors keys (sp78 - 2 bytes).
  */
-static const char* temperature_sensors_sets[][13] = {
+static const char* temperature_sensors_sets[][36] = {
 /* Set 0: Macbook Pro */
        { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
          "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
@@ -88,7 +88,13 @@ static const char* temperature_sensors_sets[][13] = {
        { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
          "Th1H", "Ts0P", NULL },
 /* Set 2: Macmini set */
-       { "TC0D", "TC0P", NULL }
+       { "TC0D", "TC0P", NULL },
+/* Set 3: Mac Pro (2 x Quad-Core) */
+       { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
+         "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
+         "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
+         "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
+         "TM9S", "TN0H", "TS0C", NULL },
 };
 
 /* List of keys used to read/write fan speeds */
@@ -990,14 +996,18 @@ static struct attribute *fan##offset##_attributes[] = { \
 
 /*
  * Create the needed functions for each fan using the macro defined above
- * (2 fans are supported)
+ * (4 fans are supported)
  */
 sysfs_fan_speeds_offset(1);
 sysfs_fan_speeds_offset(2);
+sysfs_fan_speeds_offset(3);
+sysfs_fan_speeds_offset(4);
 
 static const struct attribute_group fan_attribute_groups[] = {
        { .attrs = fan1_attributes },
-       { .attrs = fan2_attributes }
+       { .attrs = fan2_attributes },
+       { .attrs = fan3_attributes },
+       { .attrs = fan4_attributes },
 };
 
 /*
@@ -1027,6 +1037,52 @@ static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
                                        applesmc_show_temperature, NULL, 10);
 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
                                        applesmc_show_temperature, NULL, 11);
+static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 12);
+static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 13);
+static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 14);
+static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 15);
+static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 16);
+static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 17);
+static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 18);
+static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 19);
+static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 20);
+static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 21);
+static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 22);
+static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 23);
+static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 24);
+static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 25);
+static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 26);
+static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 27);
+static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 28);
+static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 29);
+static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 30);
+static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 31);
+static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 32);
+static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 33);
+static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
+                                       applesmc_show_temperature, NULL, 34);
 
 static struct attribute *temperature_attributes[] = {
        &sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1041,6 +1097,29 @@ static struct attribute *temperature_attributes[] = {
        &sensor_dev_attr_temp10_input.dev_attr.attr,
        &sensor_dev_attr_temp11_input.dev_attr.attr,
        &sensor_dev_attr_temp12_input.dev_attr.attr,
+       &sensor_dev_attr_temp13_input.dev_attr.attr,
+       &sensor_dev_attr_temp14_input.dev_attr.attr,
+       &sensor_dev_attr_temp15_input.dev_attr.attr,
+       &sensor_dev_attr_temp16_input.dev_attr.attr,
+       &sensor_dev_attr_temp17_input.dev_attr.attr,
+       &sensor_dev_attr_temp18_input.dev_attr.attr,
+       &sensor_dev_attr_temp19_input.dev_attr.attr,
+       &sensor_dev_attr_temp20_input.dev_attr.attr,
+       &sensor_dev_attr_temp21_input.dev_attr.attr,
+       &sensor_dev_attr_temp22_input.dev_attr.attr,
+       &sensor_dev_attr_temp23_input.dev_attr.attr,
+       &sensor_dev_attr_temp24_input.dev_attr.attr,
+       &sensor_dev_attr_temp25_input.dev_attr.attr,
+       &sensor_dev_attr_temp26_input.dev_attr.attr,
+       &sensor_dev_attr_temp27_input.dev_attr.attr,
+       &sensor_dev_attr_temp28_input.dev_attr.attr,
+       &sensor_dev_attr_temp29_input.dev_attr.attr,
+       &sensor_dev_attr_temp30_input.dev_attr.attr,
+       &sensor_dev_attr_temp31_input.dev_attr.attr,
+       &sensor_dev_attr_temp32_input.dev_attr.attr,
+       &sensor_dev_attr_temp33_input.dev_attr.attr,
+       &sensor_dev_attr_temp34_input.dev_attr.attr,
+       &sensor_dev_attr_temp35_input.dev_attr.attr,
        NULL
 };
 
@@ -1137,6 +1216,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
        { .accelerometer = 1, .light = 0, .temperature_set = 1 },
 /* MacMini: temperature set 2 */
        { .accelerometer = 0, .light = 0, .temperature_set = 2 },
+/* MacPro: temperature set 3 */
+       { .accelerometer = 0, .light = 0, .temperature_set = 3 },
 };
 
 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1154,6 +1235,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
                (void*)&applesmc_dmi_data[2]},
+       { applesmc_dmi_match, "Apple MacPro2", {
+         DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+         DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
+               (void*)&applesmc_dmi_data[3]},
        { .ident = NULL }
 };
 
@@ -1204,9 +1289,19 @@ static int __init applesmc_init(void)
 
                switch (count) {
                default:
-                       printk(KERN_WARNING "applesmc: More than 2 fans found,"
-                                       " but at most 2 fans are supported"
+                       printk(KERN_WARNING "applesmc: More than 4 fans found,"
+                                       " but at most 4 fans are supported"
                                                " by the driver.\n");
+               case 4:
+                       ret = sysfs_create_group(&pdev->dev.kobj,
+                                                &fan_attribute_groups[3]);
+                       if (ret)
+                               goto out_key_enumeration;
+               case 3:
+                       ret = sysfs_create_group(&pdev->dev.kobj,
+                                                &fan_attribute_groups[2]);
+                       if (ret)
+                               goto out_key_enumeration;
                case 2:
                        ret = sysfs_create_group(&pdev->dev.kobj,
                                                 &fan_attribute_groups[1]);
index 13a041326a04643c63324357acb2c9e4e45e65d7..6892f76fc18ab42190168efab9a61a857a8d02a7 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/f75375s.h>
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
@@ -86,7 +87,7 @@ I2C_CLIENT_INSMOD_2(f75373, f75375);
 
 struct f75375_data {
        unsigned short addr;
-       struct i2c_client client;
+       struct i2c_client *client;
        struct device *hwmon_dev;
 
        const char *name;
@@ -116,15 +117,25 @@ struct f75375_data {
 static int f75375_attach_adapter(struct i2c_adapter *adapter);
 static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
 static int f75375_detach_client(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client);
+static int f75375_remove(struct i2c_client *client);
 
-static struct i2c_driver f75375_driver = {
+static struct i2c_driver f75375_legacy_driver = {
        .driver = {
-               .name = "f75375",
+               .name = "f75375_legacy",
        },
        .attach_adapter = f75375_attach_adapter,
        .detach_client = f75375_detach_client,
 };
 
+static struct i2c_driver f75375_driver = {
+       .driver = {
+               .name = "f75375",
+       },
+       .probe = f75375_probe,
+       .remove = f75375_remove,
+};
+
 static inline int f75375_read8(struct i2c_client *client, u8 reg)
 {
        return i2c_smbus_read_byte_data(client, reg);
@@ -276,19 +287,14 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
        return sprintf(buf, "%d\n", data->pwm_enable[nr]);
 }
 
-static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
+static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
 {
-       int nr = to_sensor_dev_attr(attr)->index;
-       struct i2c_client *client = to_i2c_client(dev);
        struct f75375_data *data = i2c_get_clientdata(client);
-       int val = simple_strtoul(buf, NULL, 10);
        u8 fanmode;
 
        if (val < 0 || val > 4)
                return -EINVAL;
 
-       mutex_lock(&data->update_lock);
        fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
        fanmode = ~(3 << FAN_CTRL_MODE(nr));
 
@@ -310,8 +316,22 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
        }
        f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
        data->pwm_enable[nr] = val;
+       return 0;
+}
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       int nr = to_sensor_dev_attr(attr)->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct f75375_data *data = i2c_get_clientdata(client);
+       int val = simple_strtoul(buf, NULL, 10);
+       int err = 0;
+
+       mutex_lock(&data->update_lock);
+       err = set_pwm_enable_direct(client, nr, val);
        mutex_unlock(&data->update_lock);
-       return count;
+       return err ? err : count;
 }
 
 static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
@@ -323,7 +343,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
        int val = simple_strtoul(buf, NULL, 10);
        u8 conf = 0;
 
-       if (val != 0 || val != 1 || data->kind == f75373)
+       if (!(val == 0 || val == 1))
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
@@ -529,13 +549,13 @@ static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR,
        show_pwm, set_pwm, 0);
 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR,
        show_pwm_enable, set_pwm_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO|S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO,
        show_pwm_mode, set_pwm_mode, 0);
 static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR,
        show_pwm, set_pwm, 1);
 static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR,
        show_pwm_enable, set_pwm_enable, 1);
-static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO|S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO,
        show_pwm_mode, set_pwm_mode, 1);
 
 static struct attribute *f75375_attributes[] = {
@@ -580,12 +600,9 @@ static const struct attribute_group f75375_group = {
 
 static int f75375_detach_client(struct i2c_client *client)
 {
-       struct f75375_data *data = i2c_get_clientdata(client);
        int err;
 
-       hwmon_device_unregister(data->hwmon_dev);
-       sysfs_remove_group(&client->dev.kobj, &f75375_group);
-
+       f75375_remove(client);
        err = i2c_detach_client(client);
        if (err) {
                dev_err(&client->dev,
@@ -593,7 +610,91 @@ static int f75375_detach_client(struct i2c_client *client)
                        "client not detached.\n");
                return err;
        }
+       kfree(client);
+       return 0;
+}
+
+static void f75375_init(struct i2c_client *client, struct f75375_data *data,
+               struct f75375s_platform_data *f75375s_pdata)
+{
+       int nr;
+       set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
+       set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
+       for (nr = 0; nr < 2; nr++) {
+               data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
+               f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
+                       data->pwm[nr]);
+       }
+
+}
+
+static int f75375_probe(struct i2c_client *client)
+{
+       struct f75375_data *data = i2c_get_clientdata(client);
+       struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
+       int err;
+
+       if (!i2c_check_functionality(client->adapter,
+                               I2C_FUNC_SMBUS_BYTE_DATA))
+               return -EIO;
+       if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL)))
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, data);
+       data->client = client;
+       mutex_init(&data->update_lock);
+
+       if (strcmp(client->name, "f75375") == 0)
+               data->kind = f75375;
+       else if (strcmp(client->name, "f75373") == 0)
+               data->kind = f75373;
+       else {
+               dev_err(&client->dev, "Unsupported device: %s\n", client->name);
+               return -ENODEV;
+       }
+
+       if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
+               goto exit_free;
+
+       if (data->kind == f75375) {
+               err = sysfs_chmod_file(&client->dev.kobj,
+                       &sensor_dev_attr_pwm1_mode.dev_attr.attr,
+                       S_IRUGO | S_IWUSR);
+               if (err)
+                       goto exit_remove;
+               err = sysfs_chmod_file(&client->dev.kobj,
+                       &sensor_dev_attr_pwm2_mode.dev_attr.attr,
+                       S_IRUGO | S_IWUSR);
+               if (err)
+                       goto exit_remove;
+       }
+
+       data->hwmon_dev = hwmon_device_register(&client->dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               err = PTR_ERR(data->hwmon_dev);
+               goto exit_remove;
+       }
+
+       if (f75375s_pdata != NULL)
+               f75375_init(client, data, f75375s_pdata);
+
+       return 0;
+
+exit_remove:
+       sysfs_remove_group(&client->dev.kobj, &f75375_group);
+exit_free:
        kfree(data);
+       i2c_set_clientdata(client, NULL);
+       return err;
+}
+
+static int f75375_remove(struct i2c_client *client)
+{
+       struct f75375_data *data = i2c_get_clientdata(client);
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&client->dev.kobj, &f75375_group);
+       kfree(data);
+       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
@@ -608,20 +709,17 @@ static int f75375_attach_adapter(struct i2c_adapter *adapter)
 static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
 {
        struct i2c_client *client;
-       struct f75375_data *data;
        u8 version = 0;
        int err = 0;
        const char *name = "";
 
-       if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) {
+       if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
                err = -ENOMEM;
                goto exit;
        }
-       client = &data->client;
-       i2c_set_clientdata(client, data);
        client->addr = address;
        client->adapter = adapter;
-       client->driver = &f75375_driver;
+       client->driver = &f75375_legacy_driver;
 
        if (kind < 0) {
                u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
@@ -644,42 +742,42 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
        } else if (kind == f75373) {
                name = "f75373";
        }
-
        dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
        strlcpy(client->name, name, I2C_NAME_SIZE);
-       data->kind = kind;
-       mutex_init(&data->update_lock);
+
        if ((err = i2c_attach_client(client)))
                goto exit_free;
 
-       if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
+       if ((err = f75375_probe(client)) < 0)
                goto exit_detach;
 
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove;
-       }
-
        return 0;
 
-exit_remove:
-       sysfs_remove_group(&client->dev.kobj, &f75375_group);
 exit_detach:
        i2c_detach_client(client);
 exit_free:
-       kfree(data);
+       kfree(client);
 exit:
        return err;
 }
 
 static int __init sensors_f75375_init(void)
 {
-       return i2c_add_driver(&f75375_driver);
+       int status;
+       status = i2c_add_driver(&f75375_driver);
+       if (status)
+               return status;
+
+       status = i2c_add_driver(&f75375_legacy_driver);
+       if (status)
+               i2c_del_driver(&f75375_driver);
+
+       return status;
 }
 
 static void __exit sensors_f75375_exit(void)
 {
+       i2c_del_driver(&f75375_legacy_driver);
        i2c_del_driver(&f75375_driver);
 }
 
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
new file mode 100644 (file)
index 0000000..6ac5c6f
--- /dev/null
@@ -0,0 +1,552 @@
+/*
+ * A hwmon driver for the Intel 5000 series chipset FB-DIMM AMB
+ * temperature sensors
+ * Copyright (C) 2007 IBM
+ *
+ * Author: Darrick J. Wong <djwong@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#define DRVNAME "i5k_amb"
+
+#define I5K_REG_AMB_BASE_ADDR          0x48
+#define I5K_REG_AMB_LEN_ADDR           0x50
+#define I5K_REG_CHAN0_PRESENCE_ADDR    0x64
+#define I5K_REG_CHAN1_PRESENCE_ADDR    0x66
+
+#define AMB_REG_TEMP_MIN_ADDR          0x80
+#define AMB_REG_TEMP_MID_ADDR          0x81
+#define AMB_REG_TEMP_MAX_ADDR          0x82
+#define AMB_REG_TEMP_STATUS_ADDR       0x84
+#define AMB_REG_TEMP_ADDR              0x85
+
+#define AMB_CONFIG_SIZE                        2048
+#define AMB_FUNC_3_OFFSET              768
+
+static unsigned long amb_reg_temp_status(unsigned int amb)
+{
+       return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_STATUS_ADDR +
+              AMB_CONFIG_SIZE * amb;
+}
+
+static unsigned long amb_reg_temp_min(unsigned int amb)
+{
+       return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MIN_ADDR +
+              AMB_CONFIG_SIZE * amb;
+}
+
+static unsigned long amb_reg_temp_mid(unsigned int amb)
+{
+       return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MID_ADDR +
+              AMB_CONFIG_SIZE * amb;
+}
+
+static unsigned long amb_reg_temp_max(unsigned int amb)
+{
+       return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MAX_ADDR +
+              AMB_CONFIG_SIZE * amb;
+}
+
+static unsigned long amb_reg_temp(unsigned int amb)
+{
+       return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_ADDR +
+              AMB_CONFIG_SIZE * amb;
+}
+
+#define MAX_MEM_CHANNELS               4
+#define MAX_AMBS_PER_CHANNEL           16
+#define MAX_AMBS                       (MAX_MEM_CHANNELS * \
+                                        MAX_AMBS_PER_CHANNEL)
+/*
+ * Ugly hack: For some reason the highest bit is set if there
+ * are _any_ DIMMs in the channel.  Attempting to read from
+ * this "high-order" AMB results in a memory bus error, so
+ * for now we'll just ignore that top bit, even though that
+ * might prevent us from seeing the 16th DIMM in the channel.
+ */
+#define REAL_MAX_AMBS_PER_CHANNEL      15
+#define KNOBS_PER_AMB                  5
+
+static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit)
+{
+       return byte_num * MAX_AMBS_PER_CHANNEL + bit;
+}
+
+#define AMB_SYSFS_NAME_LEN             16
+struct i5k_device_attribute {
+       struct sensor_device_attribute s_attr;
+       char name[AMB_SYSFS_NAME_LEN];
+};
+
+struct i5k_amb_data {
+       struct device *hwmon_dev;
+
+       unsigned long amb_base;
+       unsigned long amb_len;
+       u16 amb_present[MAX_MEM_CHANNELS];
+       void __iomem *amb_mmio;
+       struct i5k_device_attribute *attrs;
+       unsigned int num_attrs;
+};
+
+static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
+                        char *buf)
+{
+       return sprintf(buf, "%s\n", DRVNAME);
+}
+
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static struct platform_device *amb_pdev;
+
+static u8 amb_read_byte(struct i5k_amb_data *data, unsigned long offset)
+{
+       return ioread8(data->amb_mmio + offset);
+}
+
+static void amb_write_byte(struct i5k_amb_data *data, unsigned long offset,
+                          u8 val)
+{
+       iowrite8(val, data->amb_mmio + offset);
+}
+
+static ssize_t show_amb_alarm(struct device *dev,
+                            struct device_attribute *devattr,
+                            char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+
+       if (!(amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x20) &&
+            (amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x8))
+               return sprintf(buf, "1\n");
+       else
+               return sprintf(buf, "0\n");
+}
+
+static ssize_t store_amb_min(struct device *dev,
+                            struct device_attribute *devattr,
+                            const char *buf,
+                            size_t count)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+
+       if (temp > 255)
+               temp = 255;
+
+       amb_write_byte(data, amb_reg_temp_min(attr->index), temp);
+       return count;
+}
+
+static ssize_t store_amb_mid(struct device *dev,
+                            struct device_attribute *devattr,
+                            const char *buf,
+                            size_t count)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+
+       if (temp > 255)
+               temp = 255;
+
+       amb_write_byte(data, amb_reg_temp_mid(attr->index), temp);
+       return count;
+}
+
+static ssize_t store_amb_max(struct device *dev,
+                            struct device_attribute *devattr,
+                            const char *buf,
+                            size_t count)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+
+       if (temp > 255)
+               temp = 255;
+
+       amb_write_byte(data, amb_reg_temp_max(attr->index), temp);
+       return count;
+}
+
+static ssize_t show_amb_min(struct device *dev,
+                            struct device_attribute *devattr,
+                            char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n",
+               500 * amb_read_byte(data, amb_reg_temp_min(attr->index)));
+}
+
+static ssize_t show_amb_mid(struct device *dev,
+                            struct device_attribute *devattr,
+                            char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n",
+               500 * amb_read_byte(data, amb_reg_temp_mid(attr->index)));
+}
+
+static ssize_t show_amb_max(struct device *dev,
+                            struct device_attribute *devattr,
+                            char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n",
+               500 * amb_read_byte(data, amb_reg_temp_max(attr->index)));
+}
+
+static ssize_t show_amb_temp(struct device *dev,
+                            struct device_attribute *devattr,
+                            char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct i5k_amb_data *data = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n",
+               500 * amb_read_byte(data, amb_reg_temp(attr->index)));
+}
+
+static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev)
+{
+       int i, j, k, d = 0;
+       u16 c;
+       int res = 0;
+       int num_ambs = 0;
+       struct i5k_amb_data *data = platform_get_drvdata(pdev);
+
+       /* Count the number of AMBs found */
+       /* ignore the high-order bit, see "Ugly hack" comment above */
+       for (i = 0; i < MAX_MEM_CHANNELS; i++)
+               num_ambs += hweight16(data->amb_present[i] & 0x7fff);
+
+       /* Set up sysfs stuff */
+       data->attrs = kzalloc(sizeof(*data->attrs) * num_ambs * KNOBS_PER_AMB,
+                               GFP_KERNEL);
+       if (!data->attrs)
+               return -ENOMEM;
+       data->num_attrs = 0;
+
+       for (i = 0; i < MAX_MEM_CHANNELS; i++) {
+               c = data->amb_present[i];
+               for (j = 0; j < REAL_MAX_AMBS_PER_CHANNEL; j++, c >>= 1) {
+                       struct i5k_device_attribute *iattr;
+
+                       k = amb_num_from_reg(i, j);
+                       if (!(c & 0x1))
+                               continue;
+                       d++;
+
+                       /* Temperature sysfs knob */
+                       iattr = data->attrs + data->num_attrs;
+                       snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
+                                "temp%d_input", d);
+                       iattr->s_attr.dev_attr.attr.name = iattr->name;
+                       iattr->s_attr.dev_attr.attr.mode = S_IRUGO;
+                       iattr->s_attr.dev_attr.show = show_amb_temp;
+                       iattr->s_attr.index = k;
+                       res = device_create_file(&pdev->dev,
+                                                &iattr->s_attr.dev_attr);
+                       if (res)
+                               goto exit_remove;
+                       data->num_attrs++;
+
+                       /* Temperature min sysfs knob */
+                       iattr = data->attrs + data->num_attrs;
+                       snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
+                                "temp%d_min", d);
+                       iattr->s_attr.dev_attr.attr.name = iattr->name;
+                       iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO;
+                       iattr->s_attr.dev_attr.show = show_amb_min;
+                       iattr->s_attr.dev_attr.store = store_amb_min;
+                       iattr->s_attr.index = k;
+                       res = device_create_file(&pdev->dev,
+                                                &iattr->s_attr.dev_attr);
+                       if (res)
+                               goto exit_remove;
+                       data->num_attrs++;
+
+                       /* Temperature mid sysfs knob */
+                       iattr = data->attrs + data->num_attrs;
+                       snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
+                                "temp%d_mid", d);
+                       iattr->s_attr.dev_attr.attr.name = iattr->name;
+                       iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO;
+                       iattr->s_attr.dev_attr.show = show_amb_mid;
+                       iattr->s_attr.dev_attr.store = store_amb_mid;
+                       iattr->s_attr.index = k;
+                       res = device_create_file(&pdev->dev,
+                                                &iattr->s_attr.dev_attr);
+                       if (res)
+                               goto exit_remove;
+                       data->num_attrs++;
+
+                       /* Temperature max sysfs knob */
+                       iattr = data->attrs + data->num_attrs;
+                       snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
+                                "temp%d_max", d);
+                       iattr->s_attr.dev_attr.attr.name = iattr->name;
+                       iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO;
+                       iattr->s_attr.dev_attr.show = show_amb_max;
+                       iattr->s_attr.dev_attr.store = store_amb_max;
+                       iattr->s_attr.index = k;
+                       res = device_create_file(&pdev->dev,
+                                                &iattr->s_attr.dev_attr);
+                       if (res)
+                               goto exit_remove;
+                       data->num_attrs++;
+
+                       /* Temperature alarm sysfs knob */
+                       iattr = data->attrs + data->num_attrs;
+                       snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
+                                "temp%d_alarm", d);
+                       iattr->s_attr.dev_attr.attr.name = iattr->name;
+                       iattr->s_attr.dev_attr.attr.mode = S_IRUGO;
+                       iattr->s_attr.dev_attr.show = show_amb_alarm;
+                       iattr->s_attr.index = k;
+                       res = device_create_file(&pdev->dev,
+                                                &iattr->s_attr.dev_attr);
+                       if (res)
+                               goto exit_remove;
+                       data->num_attrs++;
+               }
+       }
+
+       res = device_create_file(&pdev->dev, &dev_attr_name);
+       if (res)
+               goto exit_remove;
+
+       data->hwmon_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               res = PTR_ERR(data->hwmon_dev);
+               goto exit_remove;
+       }
+
+       return res;
+
+exit_remove:
+       device_remove_file(&pdev->dev, &dev_attr_name);
+       for (i = 0; i < data->num_attrs; i++)
+               device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr);
+       kfree(data->attrs);
+
+       return res;
+}
+
+static int __devinit i5k_amb_add(void)
+{
+       int res = -ENODEV;
+
+       /* only ever going to be one of these */
+       amb_pdev = platform_device_alloc(DRVNAME, 0);
+       if (!amb_pdev)
+               return -ENOMEM;
+
+       res = platform_device_add(amb_pdev);
+       if (res)
+               goto err;
+       return 0;
+
+err:
+       platform_device_put(amb_pdev);
+       return res;
+}
+
+static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data)
+{
+       struct pci_dev *pcidev;
+       u32 val32;
+       int res = -ENODEV;
+
+       /* Find AMB register memory space */
+       pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+                               PCI_DEVICE_ID_INTEL_5000_ERR,
+                               NULL);
+       if (!pcidev)
+               return -ENODEV;
+
+       if (pci_read_config_dword(pcidev, I5K_REG_AMB_BASE_ADDR, &val32))
+               goto out;
+       data->amb_base = val32;
+
+       if (pci_read_config_dword(pcidev, I5K_REG_AMB_LEN_ADDR, &val32))
+               goto out;
+       data->amb_len = val32;
+
+       /* Is it big enough? */
+       if (data->amb_len < AMB_CONFIG_SIZE * MAX_AMBS) {
+               dev_err(&pcidev->dev, "AMB region too small!\n");
+               goto out;
+       }
+
+       res = 0;
+out:
+       pci_dev_put(pcidev);
+       return res;
+}
+
+static int __devinit i5k_channel_probe(u16 *amb_present, unsigned long dev_id)
+{
+       struct pci_dev *pcidev;
+       u16 val16;
+       int res = -ENODEV;
+
+       /* Copy the DIMM presence map for these two channels */
+       pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
+       if (!pcidev)
+               return -ENODEV;
+
+       if (pci_read_config_word(pcidev, I5K_REG_CHAN0_PRESENCE_ADDR, &val16))
+               goto out;
+       amb_present[0] = val16;
+
+       if (pci_read_config_word(pcidev, I5K_REG_CHAN1_PRESENCE_ADDR, &val16))
+               goto out;
+       amb_present[1] = val16;
+
+       res = 0;
+
+out:
+       pci_dev_put(pcidev);
+       return res;
+}
+
+static int __devinit i5k_amb_probe(struct platform_device *pdev)
+{
+       struct i5k_amb_data *data;
+       struct resource *reso;
+       int res = -ENODEV;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       /* Figure out where the AMB registers live */
+       res = i5k_find_amb_registers(data);
+       if (res)
+               goto err;
+
+       /* Copy the DIMM presence map for the first two channels */
+       res = i5k_channel_probe(&data->amb_present[0],
+                               PCI_DEVICE_ID_INTEL_5000_FBD0);
+       if (res)
+               goto err;
+
+       /* Copy the DIMM presence map for the optional second two channels */
+       i5k_channel_probe(&data->amb_present[2],
+                         PCI_DEVICE_ID_INTEL_5000_FBD1);
+
+       /* Set up resource regions */
+       reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME);
+       if (!reso) {
+               res = -EBUSY;
+               goto err;
+       }
+
+       data->amb_mmio = ioremap_nocache(data->amb_base, data->amb_len);
+       if (!data->amb_mmio) {
+               res = -EBUSY;
+               goto err_map_failed;
+       }
+
+       platform_set_drvdata(pdev, data);
+
+       res = i5k_amb_hwmon_init(pdev);
+       if (res)
+               goto err_init_failed;
+
+       return res;
+
+err_init_failed:
+       iounmap(data->amb_mmio);
+       platform_set_drvdata(pdev, NULL);
+err_map_failed:
+       release_mem_region(data->amb_base, data->amb_len);
+err:
+       kfree(data);
+       return res;
+}
+
+static int __devexit i5k_amb_remove(struct platform_device *pdev)
+{
+       int i;
+       struct i5k_amb_data *data = platform_get_drvdata(pdev);
+
+       hwmon_device_unregister(data->hwmon_dev);
+       device_remove_file(&pdev->dev, &dev_attr_name);
+       for (i = 0; i < data->num_attrs; i++)
+               device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr);
+       kfree(data->attrs);
+       iounmap(data->amb_mmio);
+       release_mem_region(data->amb_base, data->amb_len);
+       platform_set_drvdata(pdev, NULL);
+       kfree(data);
+       return 0;
+}
+
+static struct platform_driver i5k_amb_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = DRVNAME,
+       },
+       .probe = i5k_amb_probe,
+       .remove = __devexit_p(i5k_amb_remove),
+};
+
+static int __init i5k_amb_init(void)
+{
+       int res;
+
+       res = platform_driver_register(&i5k_amb_driver);
+       if (res)
+               return res;
+
+       res = i5k_amb_add();
+       if (res)
+               platform_driver_unregister(&i5k_amb_driver);
+
+       return res;
+}
+
+static void __exit i5k_amb_exit(void)
+{
+       platform_device_unregister(amb_pdev);
+       platform_driver_unregister(&i5k_amb_driver);
+}
+
+MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
+MODULE_DESCRIPTION("Intel 5000 chipset FB-DIMM AMB temperature sensor");
+MODULE_LICENSE("GPL");
+
+module_init(i5k_amb_init);
+module_exit(i5k_amb_exit);
index c462824ffccfe9936d0f6236dc8788a3d5d2dacf..9c9cdb0685e43511928c400ce89a1205d20ec8c9 100644 (file)
@@ -140,10 +140,10 @@ static int ibmpex_send_message(struct ibmpex_bmc_data *data)
 
        return 0;
 out1:
-       printk(KERN_ERR "%s: request_settime=%x\n", __FUNCTION__, err);
+       dev_err(data->bmc_device, "request_settime=%x\n", err);
        return err;
 out:
-       printk(KERN_ERR "%s: validate_addr=%x\n", __FUNCTION__, err);
+       dev_err(data->bmc_device, "validate_addr=%x\n", err);
        return err;
 }
 
@@ -161,14 +161,14 @@ static int ibmpex_ver_check(struct ibmpex_bmc_data *data)
        data->sensor_major = data->rx_msg_data[0];
        data->sensor_minor = data->rx_msg_data[1];
 
-       printk(KERN_INFO DRVNAME ": Found BMC with sensor interface "
-              "v%d.%d %d-%02d-%02d on interface %d\n",
-              data->sensor_major,
-              data->sensor_minor,
-              extract_value(data->rx_msg_data, 2),
-              data->rx_msg_data[4],
-              data->rx_msg_data[5],
-              data->interface);
+       dev_info(data->bmc_device, "Found BMC with sensor interface "
+                "v%d.%d %d-%02d-%02d on interface %d\n",
+                data->sensor_major,
+                data->sensor_minor,
+                extract_value(data->rx_msg_data, 2),
+                data->rx_msg_data[4],
+                data->rx_msg_data[5],
+                data->interface);
 
        return 0;
 }
@@ -212,8 +212,8 @@ static int ibmpex_query_sensor_data(struct ibmpex_bmc_data *data, int sensor)
        wait_for_completion(&data->read_complete);
 
        if (data->rx_result || data->rx_msg_len < 26) {
-               printk(KERN_ERR "Error reading sensor %d, please check.\n",
-                      sensor);
+               dev_err(data->bmc_device, "Error reading sensor %d.\n",
+                       sensor);
                return -ENOENT;
        }
 
@@ -456,8 +456,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
-               printk(KERN_ERR DRVNAME ": Insufficient memory for BMC "
-                      "interface %d.\n", data->interface);
+               dev_err(dev, "Insufficient memory for BMC interface.\n");
                return;
        }
 
@@ -471,9 +470,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
        err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs,
                               data, &data->user);
        if (err < 0) {
-               printk(KERN_ERR DRVNAME ": Error, unable to register user with "
-                      "ipmi interface %d\n",
-                      data->interface);
+               dev_err(dev, "Unable to register user with IPMI "
+                       "interface %d\n", data->interface);
                goto out;
        }
 
@@ -495,9 +493,9 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
        data->hwmon_dev = hwmon_device_register(data->bmc_device);
 
        if (IS_ERR(data->hwmon_dev)) {
-               printk(KERN_ERR DRVNAME ": Error, unable to register hwmon "
-                      "class device for interface %d\n",
-                      data->interface);
+               dev_err(data->bmc_device, "Unable to register hwmon "
+                       "device for IPMI interface %d\n",
+                       data->interface);
                goto out_user;
        }
 
@@ -508,7 +506,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
        /* Now go find all the sensors */
        err = ibmpex_find_sensors(data);
        if (err) {
-               printk(KERN_ERR "Error %d allocating memory\n", err);
+               dev_err(data->bmc_device, "Error %d finding sensors\n", err);
                goto out_register;
        }
 
@@ -561,10 +559,10 @@ static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
        struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data;
 
        if (msg->msgid != data->tx_msgid) {
-               printk(KERN_ERR "Received msgid (%02x) and transmitted "
-                      "msgid (%02x) mismatch!\n",
-                      (int)msg->msgid,
-                      (int)data->tx_msgid);
+               dev_err(data->bmc_device, "Mismatch between received msgid "
+                       "(%02x) and transmitted msgid (%02x)!\n",
+                       (int)msg->msgid,
+                       (int)data->tx_msgid);
                ipmi_free_recv_msg(msg);
                return;
        }
index dd366889ce9b8038c2e59342a70b8c7d340c818b..d435f003292dfd290a2d89fda730fa597c45eef2 100644 (file)
 #include <linux/err.h>
 #include <linux/sysfs.h>
 #include <linux/hwmon.h>
+#include <linux/mutex.h>
 #include <linux/spi/spi.h>
-#include <asm/semaphore.h>
+
 
 #define DRVNAME                "lm70"
 
 struct lm70 {
        struct device *hwmon_dev;
-       struct semaphore sem;
+       struct mutex lock;
 };
 
 /* sysfs hook function */
@@ -51,7 +52,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
        s16 raw=0;
        struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
 
-       if (down_interruptible(&p_lm70->sem))
+       if (mutex_lock_interruptible(&p_lm70->lock))
                return -ERESTARTSYS;
 
        /*
@@ -83,7 +84,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
        val = ((int)raw/32) * 250;
        status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
 out:
-       up(&p_lm70->sem);
+       mutex_unlock(&p_lm70->lock);
        return status;
 }
 
@@ -112,7 +113,7 @@ static int __devinit lm70_probe(struct spi_device *spi)
        if (!p_lm70)
                return -ENOMEM;
 
-       init_MUTEX(&p_lm70->sem);
+       mutex_init(&p_lm70->lock);
 
        /* sysfs hook */
        p_lm70->hwmon_dev = hwmon_device_register(&spi->dev);
index 7e2d9787babc4b5776ea262a84473f0d36824331..a276806f3d53cd8b9ab192f3283019b7550531c5 100644 (file)
@@ -435,6 +435,22 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
 }
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
+                         char *buf)
+{
+       struct sis5595_data *data = sis5595_update_device(dev);
+       int nr = to_sensor_dev_attr(da)->index;
+       return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
+}
+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 15);
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 15);
+
 static ssize_t show_name(struct device *dev, struct device_attribute *attr,
                         char *buf)
 {
@@ -447,22 +463,28 @@ static struct attribute *sis5595_attributes[] = {
        &sensor_dev_attr_in0_input.dev_attr.attr,
        &sensor_dev_attr_in0_min.dev_attr.attr,
        &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in0_alarm.dev_attr.attr,
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_min.dev_attr.attr,
        &sensor_dev_attr_in1_max.dev_attr.attr,
+       &sensor_dev_attr_in1_alarm.dev_attr.attr,
        &sensor_dev_attr_in2_input.dev_attr.attr,
        &sensor_dev_attr_in2_min.dev_attr.attr,
        &sensor_dev_attr_in2_max.dev_attr.attr,
+       &sensor_dev_attr_in2_alarm.dev_attr.attr,
        &sensor_dev_attr_in3_input.dev_attr.attr,
        &sensor_dev_attr_in3_min.dev_attr.attr,
        &sensor_dev_attr_in3_max.dev_attr.attr,
+       &sensor_dev_attr_in3_alarm.dev_attr.attr,
 
        &sensor_dev_attr_fan1_input.dev_attr.attr,
        &sensor_dev_attr_fan1_min.dev_attr.attr,
        &sensor_dev_attr_fan1_div.dev_attr.attr,
+       &sensor_dev_attr_fan1_alarm.dev_attr.attr,
        &sensor_dev_attr_fan2_input.dev_attr.attr,
        &sensor_dev_attr_fan2_min.dev_attr.attr,
        &sensor_dev_attr_fan2_div.dev_attr.attr,
+       &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 
        &dev_attr_alarms.attr,
        &dev_attr_name.attr,
@@ -473,19 +495,28 @@ static const struct attribute_group sis5595_group = {
        .attrs = sis5595_attributes,
 };
 
-static struct attribute *sis5595_attributes_opt[] = {
+static struct attribute *sis5595_attributes_in4[] = {
        &sensor_dev_attr_in4_input.dev_attr.attr,
        &sensor_dev_attr_in4_min.dev_attr.attr,
        &sensor_dev_attr_in4_max.dev_attr.attr,
+       &sensor_dev_attr_in4_alarm.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group sis5595_group_in4 = {
+       .attrs = sis5595_attributes_in4,
+};
 
+static struct attribute *sis5595_attributes_temp1[] = {
        &dev_attr_temp1_input.attr,
        &dev_attr_temp1_max.attr,
        &dev_attr_temp1_max_hyst.attr,
+       &sensor_dev_attr_temp1_alarm.dev_attr.attr,
        NULL
 };
 
-static const struct attribute_group sis5595_group_opt = {
-       .attrs = sis5595_attributes_opt,
+static const struct attribute_group sis5595_group_temp1 = {
+       .attrs = sis5595_attributes_temp1,
 };
  
 /* This is called when the module is loaded */
@@ -540,20 +571,12 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
        if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group)))
                goto exit_free;
        if (data->maxins == 4) {
-               if ((err = device_create_file(&pdev->dev,
-                                       &sensor_dev_attr_in4_input.dev_attr))
-                || (err = device_create_file(&pdev->dev,
-                                       &sensor_dev_attr_in4_min.dev_attr))
-                || (err = device_create_file(&pdev->dev,
-                                       &sensor_dev_attr_in4_max.dev_attr)))
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &sis5595_group_in4)))
                        goto exit_remove_files;
        } else {
-               if ((err = device_create_file(&pdev->dev,
-                                             &dev_attr_temp1_input))
-                || (err = device_create_file(&pdev->dev,
-                                             &dev_attr_temp1_max))
-                || (err = device_create_file(&pdev->dev,
-                                             &dev_attr_temp1_max_hyst)))
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &sis5595_group_temp1)))
                        goto exit_remove_files;
        }
 
@@ -567,7 +590,8 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
 
 exit_remove_files:
        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group);
-       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt);
+       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4);
+       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1);
 exit_free:
        kfree(data);
 exit_release:
@@ -582,7 +606,8 @@ static int __devexit sis5595_remove(struct platform_device *pdev)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group);
-       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt);
+       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4);
+       sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1);
 
        release_region(data->addr, SIS5595_EXTENT);
        platform_set_drvdata(pdev, NULL);
index 20ae425a1980ce7add4c6a29b055279908a54a60..879d0a6544ccfb865ef0c6ddeead32e542f3a0bd 100644 (file)
@@ -170,20 +170,16 @@ superio_exit(void)
 #define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
                                           (0x550 + (nr) - 7))
 
-#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
-#define W83781D_REG_FAN(nr) (0x27 + (nr))
-
-#define W83781D_REG_TEMP2_CONFIG 0x152
-#define W83781D_REG_TEMP3_CONFIG 0x252
-#define W83781D_REG_TEMP(nr)           ((nr == 3) ? (0x0250) : \
-                                       ((nr == 2) ? (0x0150) : \
-                                                    (0x27)))
-#define W83781D_REG_TEMP_HYST(nr)      ((nr == 3) ? (0x253) : \
-                                       ((nr == 2) ? (0x153) : \
-                                                    (0x3A)))
-#define W83781D_REG_TEMP_OVER(nr)      ((nr == 3) ? (0x255) : \
-                                       ((nr == 2) ? (0x155) : \
-                                                    (0x39)))
+/* nr:0-2 for fans:1-3 */
+#define W83627HF_REG_FAN_MIN(nr)       (0x3b + (nr))
+#define W83627HF_REG_FAN(nr)           (0x28 + (nr))
+
+#define W83627HF_REG_TEMP2_CONFIG 0x152
+#define W83627HF_REG_TEMP3_CONFIG 0x252
+/* these are zero-based, unlike config constants above */
+static const u16 w83627hf_reg_temp[]           = { 0x27, 0x150, 0x250 };
+static const u16 w83627hf_reg_temp_hyst[]      = { 0x3A, 0x153, 0x253 };
+static const u16 w83627hf_reg_temp_over[]      = { 0x39, 0x155, 0x255 };
 
 #define W83781D_REG_BANK 0x4E
 
@@ -360,12 +356,9 @@ struct w83627hf_data {
        u8 in_min[9];           /* Register value */
        u8 fan[3];              /* Register value */
        u8 fan_min[3];          /* Register value */
-       u8 temp;
-       u8 temp_max;            /* Register value */
-       u8 temp_max_hyst;       /* Register value */
-       u16 temp_add[2];        /* Register value */
-       u16 temp_max_add[2];    /* Register value */
-       u16 temp_max_hyst_add[2]; /* Register value */
+       u16 temp[3];            /* Register value */
+       u16 temp_max[3];        /* Register value */
+       u16 temp_max_hyst[3];   /* Register value */
        u8 fan_div[3];          /* Register encoding, shifted right */
        u8 vid;                 /* Register encoding, combined */
        u32 alarms;             /* Register encoding, combined */
@@ -590,7 +583,7 @@ store_fan_min(struct device *dev, struct device_attribute *devattr,
 
        mutex_lock(&data->update_lock);
        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-       w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1),
+       w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr),
                             data->fan_min[nr]);
 
        mutex_unlock(&data->update_lock);
@@ -611,12 +604,10 @@ show_temp(struct device *dev, struct device_attribute *devattr, char *buf)
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->temp));
-       }
+
+       u16 tmp = data->temp[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -625,13 +616,10 @@ show_temp_max(struct device *dev, struct device_attribute *devattr,
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_max_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n",
-                       (long)TEMP_FROM_REG(data->temp_max));
-       }
+
+       u16 tmp = data->temp_max[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -640,13 +628,10 @@ show_temp_max_hyst(struct device *dev, struct device_attribute *devattr,
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_max_hyst_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n",
-                       (long)TEMP_FROM_REG(data->temp_max_hyst));
-       }
+
+       u16 tmp = data->temp_max_hyst[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -656,18 +641,11 @@ store_temp_max(struct device *dev, struct device_attribute *devattr,
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = dev_get_drvdata(dev);
        long val = simple_strtol(buf, NULL, 10);
+       u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 
        mutex_lock(&data->update_lock);
-
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               data->temp_max_add[nr-2] = LM75_TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr),
-                               data->temp_max_add[nr-2]);
-       } else {        /* TEMP1 */
-               data->temp_max = TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr),
-                       data->temp_max);
-       }
+       data->temp_max[nr] = tmp;
+       w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp);
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -679,29 +657,22 @@ store_temp_max_hyst(struct device *dev, struct device_attribute *devattr,
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = dev_get_drvdata(dev);
        long val = simple_strtol(buf, NULL, 10);
+       u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 
        mutex_lock(&data->update_lock);
-
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               data->temp_max_hyst_add[nr-2] = LM75_TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr),
-                               data->temp_max_hyst_add[nr-2]);
-       } else {        /* TEMP1 */
-               data->temp_max_hyst = TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr),
-                       data->temp_max_hyst);
-       }
+       data->temp_max_hyst[nr] = tmp;
+       w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp);
        mutex_unlock(&data->update_lock);
        return count;
 }
 
 #define sysfs_temp_decl(offset) \
 static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,               \
-                         show_temp, NULL, offset);                     \
+                         show_temp, NULL, offset - 1);                 \
 static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR,         \
-                         show_temp_max, store_temp_max, offset);       \
+                         show_temp_max, store_temp_max, offset - 1);   \
 static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR,    \
-                         show_temp_max_hyst, store_temp_max_hyst, offset);
+                         show_temp_max_hyst, store_temp_max_hyst, offset - 1);
 
 sysfs_temp_decl(1);
 sysfs_temp_decl(2);
@@ -844,7 +815,7 @@ store_fan_div(struct device *dev, struct device_attribute *devattr,
 
        /* Restore fan_min */
        data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-       w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+       w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), data->fan_min[nr]);
 
        mutex_unlock(&data->update_lock);
        return count;
@@ -1170,7 +1141,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
        struct w83627hf_sio_data *sio_data = dev->platform_data;
        struct w83627hf_data *data;
        struct resource *res;
-       int err;
+       int err, i;
 
        static const char *names[] = {
                "w83627hf",
@@ -1204,9 +1175,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
        w83627hf_init_device(pdev);
 
        /* A few vars need to be filled upon startup */
-       data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1));
-       data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2));
-       data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3));
+       for (i = 0; i <= 2; i++)
+               data->fan_min[i] = w83627hf_read_value(
+                                       data, W83627HF_REG_FAN_MIN(i));
        w83627hf_update_fan_div(data);
 
        /* Register common device attributes */
@@ -1514,23 +1485,23 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev)
 
        if(init) {
                /* Enable temp2 */
-               tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG);
+               tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG);
                if (tmp & 0x01) {
                        dev_warn(&pdev->dev, "Enabling temp2, readings "
                                 "might not make sense\n");
-                       w83627hf_write_value(data, W83781D_REG_TEMP2_CONFIG,
+                       w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG,
                                tmp & 0xfe);
                }
 
                /* Enable temp3 */
                if (type != w83697hf) {
                        tmp = w83627hf_read_value(data,
-                               W83781D_REG_TEMP3_CONFIG);
+                               W83627HF_REG_TEMP3_CONFIG);
                        if (tmp & 0x01) {
                                dev_warn(&pdev->dev, "Enabling temp3, "
                                         "readings might not make sense\n");
                                w83627hf_write_value(data,
-                                       W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
+                                       W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe);
                        }
                }
        }
@@ -1563,7 +1534,7 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data)
 static struct w83627hf_data *w83627hf_update_device(struct device *dev)
 {
        struct w83627hf_data *data = dev_get_drvdata(dev);
-       int i;
+       int i, num_temps = (data->type == w83697hf) ? 2 : 3;
 
        mutex_lock(&data->update_lock);
 
@@ -1584,12 +1555,12 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
                            w83627hf_read_value(data,
                                               W83781D_REG_IN_MAX(i));
                }
-               for (i = 1; i <= 3; i++) {
-                       data->fan[i - 1] =
-                           w83627hf_read_value(data, W83781D_REG_FAN(i));
-                       data->fan_min[i - 1] =
+               for (i = 0; i <= 2; i++) {
+                       data->fan[i] =
+                           w83627hf_read_value(data, W83627HF_REG_FAN(i));
+                       data->fan_min[i] =
                            w83627hf_read_value(data,
-                                              W83781D_REG_FAN_MIN(i));
+                                              W83627HF_REG_FAN_MIN(i));
                }
                for (i = 0; i <= 2; i++) {
                        u8 tmp = w83627hf_read_value(data,
@@ -1616,25 +1587,13 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
                                        break;
                        }
                }
-
-               data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1));
-               data->temp_max =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1));
-               data->temp_max_hyst =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1));
-               data->temp_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP(2));
-               data->temp_max_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_OVER(2));
-               data->temp_max_hyst_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_HYST(2));
-               if (data->type != w83697hf) {
-                       data->temp_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP(3));
-                       data->temp_max_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP_OVER(3));
-                       data->temp_max_hyst_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3));
+               for (i = 0; i < num_temps; i++) {
+                       data->temp[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp[i]);
+                       data->temp_max[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp_over[i]);
+                       data->temp_max_hyst[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp_hyst[i]);
                }
 
                w83627hf_update_fan_div(data);
index a6a1edfe76141e8a9fb5fb058a13014d90787ac9..e0fa7520400d8c565f0b7c77034a6c0e35cf4a1a 100644 (file)
@@ -1122,12 +1122,13 @@ w83781d_create_files(struct device *dev, int kind, int is_isa)
                                &sensor_dev_attr_temp3_beep.dev_attr)))
                        return err;
 
-               if (kind != w83781d)
+               if (kind != w83781d) {
                        err = sysfs_chmod_file(&dev->kobj,
                                &sensor_dev_attr_temp3_alarm.dev_attr.attr,
                                S_IRUGO | S_IWUSR);
                        if (err)
                                return err;
+               }
        }
 
        if (kind != w83781d && kind != as99127f) {
index 58e32714afb5b881068c9ca096d8ec271a448cd7..ca18e0be4901a52b2881c1f0e2b996bc2612abe3 100644 (file)
@@ -51,6 +51,7 @@ struct pasemi_smbus {
 #define MRXFIFO_DATA_M 0x000000ff
 
 #define SMSTA_XEN      0x08000000
+#define SMSTA_MTN      0x00200000
 
 #define CTL_MRR                0x00000400
 #define CTL_MTR                0x00000200
@@ -98,6 +99,10 @@ static unsigned int pasemi_smb_waitready(struct pasemi_smbus *smbus)
                status = reg_read(smbus, REG_SMSTA);
        }
 
+       /* Got NACK? */
+       if (status & SMSTA_MTN)
+               return -ENXIO;
+
        if (timeout < 0) {
                dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
                reg_write(smbus, REG_SMSTA, status);
@@ -364,7 +369,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
 
-       /* set up the driverfs linkage to our parent device */
+       /* set up the sysfs linkage to our parent device */
        smbus->adapter.dev.parent = &dev->dev;
 
        reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
index d3da1fb05b9bebe13d342f7d3a09fbbda585e58d..1a7eeebac506d63b05d8f1c96e98c29040bd5f41 100644 (file)
@@ -128,13 +128,20 @@ static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr,
        for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
                eeprom_update_client(client, slice);
 
-       /* Hide Vaio security settings to regular users (16 first bytes) */
-       if (data->nature == VAIO && off < 16 && !capable(CAP_SYS_ADMIN)) {
-               size_t in_row1 = 16 - off;
-               in_row1 = min(in_row1, count);
-               memset(buf, 0, in_row1);
-               if (count - in_row1 > 0)
-                       memcpy(buf + in_row1, &data->data[16], count - in_row1);
+       /* Hide Vaio private settings to regular users:
+          - BIOS passwords: bytes 0x00 to 0x0f
+          - UUID: bytes 0x10 to 0x1f
+          - Serial number: 0xc0 to 0xdf */
+       if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
+               int i;
+
+               for (i = 0; i < count; i++) {
+                       if ((off + i <= 0x1f) ||
+                           (off + i >= 0xc0 && off + i <= 0xdf))
+                               buf[i] = 0;
+                       else
+                               buf[i] = data->data[off + i];
+               }
        } else {
                memcpy(buf, &data->data[off], count);
        }
@@ -197,14 +204,18 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
                goto exit_kfree;
 
        /* Detect the Vaio nature of EEPROMs.
-          We use the "PCG-" prefix as the signature. */
+          We use the "PCG-" or "VGN-" prefix as the signature. */
        if (address == 0x57) {
-               if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
-                && i2c_smbus_read_byte(new_client) == 'C'
-                && i2c_smbus_read_byte(new_client) == 'G'
-                && i2c_smbus_read_byte(new_client) == '-') {
+               char name[4];
+
+               name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
+               name[1] = i2c_smbus_read_byte(new_client);
+               name[2] = i2c_smbus_read_byte(new_client);
+               name[3] = i2c_smbus_read_byte(new_client);
+
+               if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
                        dev_info(&new_client->dev, "Vaio EEPROM detected, "
-                               "enabling password protection\n");
+                                "enabling privacy protection\n");
                        data->nature = VAIO;
                }
        }
index 1a4e8dc03b365dfb2e5b99fd3e56d617bbe4b113..b5e13e405e72f8b3339f6701482ee336ae6ad2fe 100644 (file)
@@ -673,7 +673,7 @@ static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
        return 0;
 }
 
-int i2c_check_addr(struct i2c_adapter *adapter, int addr)
+static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
 {
        int rval;
 
@@ -683,7 +683,6 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
 
        return rval;
 }
-EXPORT_SYMBOL(i2c_check_addr);
 
 int i2c_attach_client(struct i2c_client *client)
 {
index 5a15e50748de11076202b2c91bc8c0afc9974701..c21ae20ae362b059a2c347238f0e063616e0411e 100644 (file)
 
 static struct i2c_driver i2cdev_driver;
 
+/*
+ * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a
+ * slave (i2c_client) with which messages will be exchanged.  It's coupled
+ * with a character special file which is accessed by user mode drivers.
+ *
+ * The list of i2c_dev structures is parallel to the i2c_adapter lists
+ * maintained by the driver model, and is updated using notifications
+ * delivered to the i2cdev_driver.
+ */
 struct i2c_dev {
        struct list_head list;
        struct i2c_adapter *adap;
@@ -103,6 +112,25 @@ static ssize_t show_adapter_name(struct device *dev,
 }
 static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
 
+/* ------------------------------------------------------------------------- */
+
+/*
+ * After opening an instance of this character special file, a file
+ * descriptor starts out associated only with an i2c_adapter (and bus).
+ *
+ * Using the I2C_RDWR ioctl(), you can then *immediately* issue i2c_msg
+ * traffic to any devices on the bus used by that adapter.  That's because
+ * the i2c_msg vectors embed all the addressing information they need, and
+ * are submitted directly to an i2c_adapter.  However, SMBus-only adapters
+ * don't support that interface.
+ *
+ * To use read()/write() system calls on that file descriptor, or to use
+ * SMBus interfaces (and work with SMBus-only hosts!), you must first issue
+ * an I2C_SLAVE (or I2C_SLAVE_FORCE) ioctl.  That configures an anonymous
+ * (never registered) i2c_client so it holds the addressing information
+ * needed by those system calls and by this SMBus interface.
+ */
+
 static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
                             loff_t *offset)
 {
@@ -154,6 +182,29 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
        return ret;
 }
 
+/* This address checking function differs from the one in i2c-core
+   in that it considers an address with a registered device, but no
+   bounded driver, as NOT busy. */
+static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
+{
+       struct list_head *item;
+       struct i2c_client *client;
+       int res = 0;
+
+       mutex_lock(&adapter->clist_lock);
+       list_for_each(item, &adapter->clients) {
+               client = list_entry(item, struct i2c_client, list);
+               if (client->addr == addr) {
+                       if (client->driver)
+                               res = -EBUSY;
+                       break;
+               }
+       }
+       mutex_unlock(&adapter->clist_lock);
+
+       return res;
+}
+
 static int i2cdev_ioctl(struct inode *inode, struct file *file,
                unsigned int cmd, unsigned long arg)
 {
@@ -172,11 +223,22 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
        switch ( cmd ) {
        case I2C_SLAVE:
        case I2C_SLAVE_FORCE:
+               /* NOTE:  devices set up to work with "new style" drivers
+                * can't use I2C_SLAVE, even when the device node is not
+                * bound to a driver.  Only I2C_SLAVE_FORCE will work.
+                *
+                * Setting the PEC flag here won't affect kernel drivers,
+                * which will be using the i2c_client node registered with
+                * the driver model core.  Likewise, when that client has
+                * the PEC flag already set, the i2c-dev driver won't see
+                * (or use) this setting.
+                */
                if ((arg > 0x3ff) ||
                    (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
                        return -EINVAL;
-               if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
+               if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
                        return -EBUSY;
+               /* REVISIT: address could become busy later */
                client->addr = arg;
                return 0;
        case I2C_TENBIT:
@@ -386,6 +448,13 @@ static int i2cdev_open(struct inode *inode, struct file *file)
        if (!adap)
                return -ENODEV;
 
+       /* This creates an anonymous i2c_client, which may later be
+        * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
+        *
+        * This client is ** NEVER REGISTERED ** with the driver model
+        * or I2C core code!!  It just holds private copies of addressing
+        * information and maybe a PEC flag.
+        */
        client = kzalloc(sizeof(*client), GFP_KERNEL);
        if (!client) {
                i2c_put_adapter(adap);
@@ -394,7 +463,6 @@ static int i2cdev_open(struct inode *inode, struct file *file)
        snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
        client->driver = &i2cdev_driver;
 
-       /* registered with adapter, passed as client to user */
        client->adapter = adap;
        file->private_data = client;
 
@@ -422,6 +490,14 @@ static const struct file_operations i2cdev_fops = {
        .release        = i2cdev_release,
 };
 
+/* ------------------------------------------------------------------------- */
+
+/*
+ * The legacy "i2cdev_driver" is used primarily to get notifications when
+ * I2C adapters are added or removed, so that each one gets an i2c_dev
+ * and is thus made available to userspace driver code.
+ */
+
 static struct class *i2c_dev_class;
 
 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
@@ -486,6 +562,12 @@ static struct i2c_driver i2cdev_driver = {
        .detach_client  = i2cdev_detach_client,
 };
 
+/* ------------------------------------------------------------------------- */
+
+/*
+ * module load/unload record keeping
+ */
+
 static int __init i2c_dev_init(void)
 {
        int res;
index 6eaece96524eac2c9e7d709559c4c99f4eb8a2a1..e445fe6e4ba9d7df6f39ff141f6b699c1481cf63 100644 (file)
@@ -152,9 +152,22 @@ config BLK_DEV_IDEDISK
          If unsure, say Y.
 
 config IDEDISK_MULTI_MODE
-       bool "Use multi-mode by default"
-       help
-         If you get this error, try to say Y here:
+       bool "Use multiple sector mode for Programmed Input/Output by default"
+       help
+         This setting is irrelevant for most IDE disks, with direct memory
+         access, to which multiple sector mode does not apply. Multiple sector
+         mode is a feature of most modern IDE hard drives, permitting the
+         transfer of multiple sectors per Programmed Input/Output interrupt,
+         rather than the usual one sector per interrupt. When this feature is
+         enabled, it can reduce operating system overhead for disk Programmed
+         Input/Output. On some systems, it also can increase the data
+         throughput of Programmed Input/Output. Some drives, however, seemed
+         to run slower with multiple sector mode enabled. Some drives claimed
+         to support multiple sector mode, but lost data at some settings.
+         Under rare circumstances, such failures could result in massive
+         filesystem corruption.
+
+         If you get the following error, try to say Y here:
 
          hda: set_multmode: status=0x51 { DriveReady SeekComplete Error }
          hda: set_multmode: error=0x04 { DriveStatusError }
@@ -190,10 +203,6 @@ config BLK_DEV_IDECD
          CD-ROM drive, you can say N to all other CD-ROM options, but be sure
          to say Y or M to "ISO 9660 CD-ROM file system support".
 
-         Note that older versions of LILO (LInux LOader) cannot properly deal
-         with IDE/ATAPI CD-ROMs, so install LILO 16 or higher, available from
-         <http://lilo.go.dyndns.org/>.
-
          To compile this driver as a module, choose M here: the
          module will be called ide-cd.
 
@@ -380,9 +389,10 @@ config IDEPCI_SHARE_IRQ
 config IDEPCI_PCIBUS_ORDER
        def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI
 
+# TODO: split it on per host driver config options (or module parameters)
 config BLK_DEV_OFFBOARD
        bool "Boot off-board chipsets first support"
-       depends on BLK_DEV_IDEPCI
+       depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001)
        help
          Normally, IDE controllers built into the motherboard (on-board
          controllers) are assigned to ide0 and ide1 while those on add-in PCI
index e196aefa2070c2f2c54e79498cfc1dcf5e19e419..7f5bc2ee6c7e554d631ea6c0c1e8f42cc3a66940 100644 (file)
@@ -748,8 +748,7 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
                        hold = ATA_DMA2_HOLD;
                        break;
                default:
-                       BUG();
-                       break;
+                       return;
        }
 
        if (speed >= XFER_UDMA_0)
index 428f7a8a00b628715d86d7f9c27007db33952d3d..e3add70b9cd8b29f45156e4ad9b6d4ad2b4d8adc 100644 (file)
@@ -340,7 +340,7 @@ static int config_drive_for_dma (ide_drive_t *drive)
 
        if (drive->media != ide_disk) {
                if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
-                       return -1;
+                       return 0;
        }
 
        /*
@@ -752,7 +752,8 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
                        mode = XFER_MW_DMA_1;
        }
 
-       printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
+       printk(KERN_DEBUG "%s: %s mode selected\n", drive->name,
+                         mode ? ide_xfer_verbose(mode) : "no DMA");
 
        return min(mode, req_mode);
 }
index c89f0d3058e934767bc1c2a3b8b7e2231b43a587..db22d1ff4e559ff1eb2652de98b23e5c6ae22267 100644 (file)
@@ -340,6 +340,8 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
                if (args) {
                        args[0] = stat;
                        args[1] = err;
+                       /* be sure we're looking at the low order bits */
+                       hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
                        args[2] = hwif->INB(IDE_NSECTOR_REG);
                        args[3] = hwif->INB(IDE_SECTOR_REG);
                        args[4] = hwif->INB(IDE_LCYL_REG);
@@ -654,7 +656,8 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
        int retries = 10;
 
        local_irq_enable_in_hardirq();
-       if ((stat & DRQ_STAT) && args && args[3]) {
+       if (rq->cmd_type == REQ_TYPE_ATA_CMD &&
+           (stat & DRQ_STAT) && args && args[3]) {
                u8 io_32bit = drive->io_32bit;
                drive->io_32bit = 0;
                hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
@@ -882,7 +885,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
                return do_rw_taskfile(drive, args);
        } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) {
                u8 *args = rq->buffer;
-               u8 sel;
  
                if (!args)
                        goto done;
@@ -900,10 +902,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
                hwif->OUTB(args[3], IDE_SECTOR_REG);
                hwif->OUTB(args[4], IDE_LCYL_REG);
                hwif->OUTB(args[5], IDE_HCYL_REG);
-               sel = (args[6] & ~0x10);
-               if (drive->select.b.unit)
-                       sel |= 0x10;
-               hwif->OUTB(sel, IDE_SELECT_REG);
+               hwif->OUTB((args[6] & 0xEF)|drive->select.all, IDE_SELECT_REG);
                ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
                return ide_started;
        } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
index dcda0f109df5a31eec201d3b3bbca2109f81748f..e17a9ee120ead8182c24cdc8fca7b81a043ed288 100644 (file)
@@ -403,8 +403,12 @@ void ide_fix_driveid (struct hd_driveid *id)
 #endif
 }
 
-/* FIXME: exported for use by the USB storage (isd200.c) code only */
-EXPORT_SYMBOL(ide_fix_driveid);
+/*
+ * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
+ * removing leading/trailing blanks and compressing internal blanks.
+ * It is primarily used to tidy up the model name/number fields as
+ * returned by the WIN_[P]IDENTIFY commands.
+ */
 
 void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
 {
index af86433baede6c7011d2a24adf39af490bae6be2..1609b8604f567b8c976848e3a8e97f2861c27f2f 100644 (file)
@@ -514,6 +514,7 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
                        if (drive->addressing == 1) {
                                __u64 sectors = 0;
                                u32 low = 0, high = 0;
+                               hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG);
                                low = ide_read_24(drive);
                                hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
                                high = ide_read_24(drive);
index 6a6f2e066b4679b7c1a2ff16704af8a67bbc7673..56fb0b84342959d9a51e116ff3b0686d47998251 100644 (file)
@@ -172,11 +172,12 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        ide_fixstring(id->fw_rev,    sizeof(id->fw_rev),    bswap);
        ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);
 
+       /* we depend on this a lot! */
+       id->model[sizeof(id->model)-1] = '\0';
+
        if (strstr(id->model, "E X A B Y T E N E S T"))
                goto err_misc;
 
-       /* we depend on this a lot! */
-       id->model[sizeof(id->model)-1] = '\0';
        printk("%s: %s, ", drive->name, id->model);
        drive->present = 1;
        drive->dead = 0;
index d066546f2831e8cab14800c4602f406e39c21302..2b60f1b0437e9aa790d446369ac285243bd6719f 100644 (file)
@@ -471,6 +471,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
        struct request rq;
 
        memset(&rq, 0, sizeof(rq));
+       rq.ref_count = 1;
        rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
        rq.buffer = buf;
 
@@ -511,6 +512,7 @@ int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
 
 EXPORT_SYMBOL(ide_raw_taskfile);
 
+#ifdef CONFIG_IDE_TASK_IOCTL
 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
        ide_task_request_t      *req_task;
@@ -660,6 +662,7 @@ abort:
 
        return err;
 }
+#endif
 
 int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
 {
index ea0143ef5fe5aee02df0e09442f790f5f68a6fcd..51fca441c2946c59e69b0b9638ab88dee7f808c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cmd64x.c              Version 1.50    May 10, 2007
+ * linux/drivers/ide/pci/cmd64x.c              Version 1.51    Nov 8, 2007
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Due to massive hardware bugs, UltraDMA is only supported
@@ -339,7 +339,8 @@ static int cmd648_ide_dma_end (ide_drive_t *drive)
        u8  mrdmode             = inb(hwif->dma_master + 0x01);
 
        /* clear the interrupt bit */
-       outb(mrdmode | irq_mask, hwif->dma_master + 0x01);
+       outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,
+            hwif->dma_master + 0x01);
 
        return err;
 }
index 599408952bd4cbae54410f3de2e306eda9c101b4..547690395eee6e3b07bf0c597843ab3a1b0fc106 100644 (file)
@@ -117,8 +117,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
                case XFER_MW_DMA_1:     timings = 0x00012121; break;
                case XFER_MW_DMA_2:     timings = 0x00002020; break;
                default:
-                       BUG();
-                       break;
+                       return;
        }
        basereg = CS5530_BASEREG(drive->hwif);
        reg = inl(basereg + 4);                 /* get drive0 config register */
index 5c99754353194478890a3ae073bddcdd509e07f5..99b7d763b6c7a445445e14e038716bbb3d8e9d57 100644 (file)
@@ -653,8 +653,7 @@ static const struct ide_port_info it821x_chipsets[] __devinitdata = {
 
 static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);
-       return 0;
+       return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);
 }
 
 static const struct pci_device_id it821x_pci_tbl[] = {
index bdf64d99770805313647814c848cedc5d43ff600..0083eaf89c773ca61760b4a180d870e77f9fa8e4 100644 (file)
@@ -139,8 +139,7 @@ static const struct ide_port_info jmicron_chipset __devinitdata = {
 
 static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &jmicron_chipset);
-       return 0;
+       return ide_setup_pci_device(dev, &jmicron_chipset);
 }
 
 /* All JMB PATA controllers have and will continue to have the same
index 9329d4a810e50fe4a25b45c5f9b6e8b26640e6c6..63625a0be71298b114b276a38125e3fba51b7863 100644 (file)
@@ -302,6 +302,7 @@ struct ich_laptop {
 
 static const struct ich_laptop ich_laptop[] = {
        /* devid, subvendor, subdev */
+       { 0x27DF, 0x1025, 0x0102 },     /* ICH7 on Acer 5602aWLMi */
        { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
        { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
        { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
index 0a7b3202066d99ee88c78902b4b4b03ee2904151..707d5ff66b0300941429177d1beed7a26905e229 100644 (file)
@@ -186,8 +186,7 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
                        }
                        break;
                default:
-                       BUG();
-                       break;
+                       return;
        }
 
        if (unit == 0) {                        /* are we configuring drive0? */
index 6b7bb53acefdc68d1928bd0bd85eb3d0c3e4a5c3..f6e2ab3dd1664d2003986906226a384b5379a5fb 100644 (file)
@@ -356,7 +356,6 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
                        sis_program_timings(drive, speed);
                        break;
                default:
-                       BUG();
                        break;
        }
 }
index 816b5311dad647febb4577991f53102c4e537d1b..5afdfef7264c512bc4594f8e1f21da3581bc42b4 100644 (file)
@@ -1138,6 +1138,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->drives[0].autotune = IDE_TUNE_AUTO;
        hwif->drives[1].autotune = IDE_TUNE_AUTO;
        hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
+                          IDE_HFLAG_PIO_NO_DOWNGRADE |
                           IDE_HFLAG_POST_SET_MODE;
        hwif->pio_mask = ATA_PIO4;
        hwif->set_pio_mode = pmac_ide_set_pio_mode;
index 02d14bf85ab2112b11a589e8fad9c73d428686bb..25fd090532206197212576093088ebbcbeced62b 100644 (file)
@@ -7,11 +7,6 @@
  *  May be copied or modified under the terms of the GNU General Public License
  */
 
-/*
- *  This module provides support for automatic detection and
- *  configuration of all PCI IDE interfaces present in a system.  
- */
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index f0c777589374cccf1af919534805675246e05f2c..b5436ca92e68cdb8d09063861ecd7af6bb89eeb5 100644 (file)
@@ -1000,6 +1000,7 @@ static int iwch_query_device(struct ib_device *ibdev,
        props->max_sge = dev->attr.max_sge_per_wr;
        props->max_sge_rd = 1;
        props->max_qp_rd_atom = dev->attr.max_rdma_reads_per_qp;
+       props->max_qp_init_rd_atom = dev->attr.max_rdma_reads_per_qp;
        props->max_cq = dev->attr.max_cqs;
        props->max_cqe = dev->attr.max_cqes_per_cq;
        props->max_mr = dev->attr.max_mem_regs;
index 97d108634c5830c27012869d494be6656f92c23d..453eb995c1d47b59255e46d4fcad70147d83c9e5 100644 (file)
 
 static struct kmem_cache *av_cache;
 
+int ehca_calc_ipd(struct ehca_shca *shca, int port,
+                 enum ib_rate path_rate, u32 *ipd)
+{
+       int path = ib_rate_to_mult(path_rate);
+       int link, ret;
+       struct ib_port_attr pa;
+
+       if (path_rate == IB_RATE_PORT_CURRENT) {
+               *ipd = 0;
+               return 0;
+       }
+
+       if (unlikely(path < 0)) {
+               ehca_err(&shca->ib_device, "Invalid static rate! path_rate=%x",
+                        path_rate);
+               return -EINVAL;
+       }
+
+       ret = ehca_query_port(&shca->ib_device, port, &pa);
+       if (unlikely(ret < 0)) {
+               ehca_err(&shca->ib_device, "Failed to query port  ret=%i", ret);
+               return ret;
+       }
+
+       link = ib_width_enum_to_int(pa.active_width) * pa.active_speed;
+
+       /* IPD = round((link / path) - 1) */
+       *ipd = ((link + (path >> 1)) / path) - 1;
+
+       return 0;
+}
+
 struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
 {
        int ret;
@@ -69,15 +101,13 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
        av->av.slid_path_bits = ah_attr->src_path_bits;
 
        if (ehca_static_rate < 0) {
-               int ah_mult = ib_rate_to_mult(ah_attr->static_rate);
-               int ehca_mult =
-                       ib_rate_to_mult(shca->sport[ah_attr->port_num].rate );
-
-               if (ah_mult >= ehca_mult)
-                       av->av.ipd = 0;
-               else
-                       av->av.ipd = (ah_mult > 0) ?
-                               ((ehca_mult - 1) / ah_mult) : 0;
+               u32 ipd;
+               if (ehca_calc_ipd(shca, ah_attr->port_num,
+                                 ah_attr->static_rate, &ipd)) {
+                       ret = -EINVAL;
+                       goto create_ah_exit1;
+               }
+               av->av.ipd = ipd;
        } else
                av->av.ipd = ehca_static_rate;
 
index 2d660ae189e544b54b3895cc4f0fc2f7d58312ea..87f12d4312a70be74fd5d68196793ec869cdf033 100644 (file)
@@ -95,7 +95,6 @@ struct ehca_sma_attr {
 struct ehca_sport {
        struct ib_cq *ibcq_aqp1;
        struct ib_qp *ibqp_aqp1;
-       enum ib_rate  rate;
        enum ib_port_state port_state;
        struct ehca_sma_attr saved_attr;
 };
index 15806d1404612d1b34c849080ef4fb2d26627b94..5bd7b591987ed3c77b545197714858a62a470108 100644 (file)
@@ -151,7 +151,6 @@ int ehca_query_port(struct ib_device *ibdev,
        }
 
        memset(props, 0, sizeof(struct ib_port_attr));
-       props->state = rblock->state;
 
        switch (rblock->max_mtu) {
        case 0x1:
@@ -188,11 +187,20 @@ int ehca_query_port(struct ib_device *ibdev,
        props->subnet_timeout  = rblock->subnet_timeout;
        props->init_type_reply = rblock->init_type_reply;
 
-       props->active_width    = IB_WIDTH_12X;
-       props->active_speed    = 0x1;
-
-       /* at the moment (logical) link state is always LINK_UP */
-       props->phys_state      = 0x5;
+       if (rblock->state && rblock->phys_width) {
+               props->phys_state      = rblock->phys_pstate;
+               props->state           = rblock->phys_state;
+               props->active_width    = rblock->phys_width;
+               props->active_speed    = rblock->phys_speed;
+       } else {
+               /* old firmware releases don't report physical
+                * port info, so use default values
+                */
+               props->phys_state      = 5;
+               props->state           = rblock->state;
+               props->active_width    = IB_WIDTH_12X;
+               props->active_speed    = 0x1;
+       }
 
 query_port1:
        ehca_free_fw_ctrlblock(rblock);
index dce503bb7d6b471315ed6d3a55190cfda2273193..5485799cdc8d633360b0174c350a42fa16956f0b 100644 (file)
@@ -189,6 +189,9 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 
 void ehca_poll_eqs(unsigned long data);
 
+int ehca_calc_ipd(struct ehca_shca *shca, int port,
+                 enum ib_rate path_rate, u32 *ipd);
+
 #ifdef CONFIG_PPC_64K_PAGES
 void *ehca_alloc_fw_ctrlblock(gfp_t flags);
 void ehca_free_fw_ctrlblock(void *ptr);
index c6cd38c5321fb2a11c553bd7754a9dad88b58a44..90d4334179bf2e5466a108c184af10e6d9ecd59b 100644 (file)
@@ -327,9 +327,6 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
                shca->hw_level = ehca_hw_level;
        ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
 
-       shca->sport[0].rate = IB_RATE_30_GBPS;
-       shca->sport[1].rate = IB_RATE_30_GBPS;
-
        shca->hca_cap = rblock->hca_cap_indicators;
        ehca_gen_dbg(" ... HCA capabilities:");
        for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
index de182648b2823404ebfc6188f1a68508e9972c00..2e3e6547cb784318859da7efa40059a689a0e266 100644 (file)
@@ -1196,10 +1196,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                update_mask |= EHCA_BMASK_SET(MQPCB_MASK_QKEY, 1);
        }
        if (attr_mask & IB_QP_AV) {
-               int ah_mult = ib_rate_to_mult(attr->ah_attr.static_rate);
-               int ehca_mult = ib_rate_to_mult(shca->sport[my_qp->
-                                               init_attr.port_num].rate);
-
                mqpcb->dlid = attr->ah_attr.dlid;
                update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID, 1);
                mqpcb->source_path_bits = attr->ah_attr.src_path_bits;
@@ -1207,11 +1203,12 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                mqpcb->service_level = attr->ah_attr.sl;
                update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL, 1);
 
-               if (ah_mult < ehca_mult)
-                       mqpcb->max_static_rate = (ah_mult > 0) ?
-                       ((ehca_mult - 1) / ah_mult) : 0;
-               else
-                       mqpcb->max_static_rate = 0;
+               if (ehca_calc_ipd(shca, my_qp->init_attr.port_num,
+                                 attr->ah_attr.static_rate,
+                                 &mqpcb->max_static_rate)) {
+                       ret = -EINVAL;
+                       goto modify_qp_exit2;
+               }
                update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1);
 
                /*
@@ -1280,10 +1277,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                        (MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP, 1);
        }
        if (attr_mask & IB_QP_ALT_PATH) {
-               int ah_mult = ib_rate_to_mult(attr->alt_ah_attr.static_rate);
-               int ehca_mult = ib_rate_to_mult(
-                       shca->sport[my_qp->init_attr.port_num].rate);
-
                if (attr->alt_port_num < 1
                    || attr->alt_port_num > shca->num_ports) {
                        ret = -EINVAL;
@@ -1309,10 +1302,12 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits;
                mqpcb->service_level_al = attr->alt_ah_attr.sl;
 
-               if (ah_mult > 0 && ah_mult < ehca_mult)
-                       mqpcb->max_static_rate_al = (ehca_mult - 1) / ah_mult;
-               else
-                       mqpcb->max_static_rate_al = 0;
+               if (ehca_calc_ipd(shca, my_qp->init_attr.port_num,
+                                 attr->alt_ah_attr.static_rate,
+                                 &mqpcb->max_static_rate_al)) {
+                       ret = -EINVAL;
+                       goto modify_qp_exit2;
+               }
 
                /* OpenIB doesn't support alternate retry counts - copy them */
                mqpcb->retry_count_al = mqpcb->retry_count;
index d9739e554515eb7796803f55b88e82bf80572925..485b8400359e756898f864f767695e3292affe35 100644 (file)
@@ -402,7 +402,11 @@ struct hipz_query_port {
        u64 max_msg_sz;
        u32 max_mtu;
        u32 vl_cap;
-       u8  reserved2[1900];
+       u32 phys_pstate;
+       u32 phys_state;
+       u32 phys_speed;
+       u32 phys_width;
+       u8  reserved2[1884];
        u64 guid_entries[255];
 } __attribute__ ((packed));
 
index 645ed71fd7972f58a73980f8910798423a2b291c..08d8ae148cd030ca99896d885e4d7a38af8804fd 100644 (file)
@@ -404,7 +404,7 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
 
                ret = ib_copy_to_udata(udata, &offset, sizeof(offset));
                if (ret)
-                       goto bail;
+                       goto bail_free;
        }
 
        spin_lock_irq(&cq->lock);
@@ -424,10 +424,8 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
        else
                n = head - tail;
        if (unlikely((u32)cqe < n)) {
-               spin_unlock_irq(&cq->lock);
-               vfree(wc);
                ret = -EOVERFLOW;
-               goto bail;
+               goto bail_unlock;
        }
        for (n = 0; tail != head; n++) {
                if (cq->ip)
@@ -459,7 +457,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
        }
 
        ret = 0;
+       goto bail;
 
+bail_unlock:
+       spin_unlock_irq(&cq->lock);
+bail_free:
+       vfree(wc);
 bail:
        return ret;
 }
index 5c29b2bfea17b7c6236181f214b4224fbf4cb60d..120a61b03bc4846de8423c436767806e563e97d6 100644 (file)
@@ -959,8 +959,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
                /* If this is a partial ACK, reset the retransmit timer. */
                if (qp->s_last != qp->s_tail) {
                        spin_lock(&dev->pending_lock);
-                       list_add_tail(&qp->timerwait,
-                                     &dev->pending[dev->pending_index]);
+                       if (list_empty(&qp->timerwait))
+                               list_add_tail(&qp->timerwait,
+                                       &dev->pending[dev->pending_index]);
                        spin_unlock(&dev->pending_lock);
                        /*
                         * If we get a partial ACK for a resent operation,
index a3b945ac32565be264096637b88901e1f6bfc0fe..7832d8ba8e444d9ae47a1af89b15f1756f7e8632 100644 (file)
@@ -109,7 +109,7 @@ config HISAX_16_3
 
 config HISAX_TELESPCI
        bool "Teles PCI"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+       depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
        help
          This enables HiSax support for the Teles PCI.
          See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -237,7 +237,7 @@ config HISAX_MIC
 
 config HISAX_NETJET
        bool "NETjet card"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+       depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
        help
          This enables HiSax support for the NetJet from Traverse
          Technologies.
@@ -248,7 +248,7 @@ config HISAX_NETJET
 
 config HISAX_NETJET_U
        bool "NETspider U card"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+       depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
        help
          This enables HiSax support for the Netspider U interface ISDN card
          from Traverse Technologies.
@@ -287,7 +287,7 @@ config HISAX_HSTSAPHIR
 
 config HISAX_BKM_A4T
        bool "Telekom A4T card"
-       depends on PCI
+       depends on PCI && PCI_LEGACY
        help
          This enables HiSax support for the Telekom A4T card.
 
@@ -297,7 +297,7 @@ config HISAX_BKM_A4T
 
 config HISAX_SCT_QUADRO
        bool "Scitel Quadro card"
-       depends on PCI
+       depends on PCI && PCI_LEGACY
        help
          This enables HiSax support for the Scitel Quadro card.
 
@@ -316,7 +316,7 @@ config HISAX_GAZEL
 
 config HISAX_HFC_PCI
        bool "HFC PCI-Bus cards"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+       depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
        help
          This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
@@ -325,7 +325,7 @@ config HISAX_HFC_PCI
 
 config HISAX_W6692
        bool "Winbond W6692 based cards"
-       depends on PCI
+       depends on PCI && PCI_LEGACY
        help
          This enables HiSax support for Winbond W6692 based PCI ISDN cards.
 
@@ -341,7 +341,7 @@ config HISAX_HFC_SX
 
 config HISAX_ENTERNOW_PCI
        bool "Formula-n enter:now PCI card"
-       depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+       depends on HISAX_NETJET && PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
        help
          This enables HiSax support for the Formula-n enter:now PCI
          ISDN card.
@@ -411,7 +411,7 @@ config HISAX_HFC4S8S
 
 config HISAX_FRITZ_PCIPNP
        tristate "AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
+       depends on PCI && PCI_LEGACY && EXPERIMENTAL
        help
          This enables the driver for the AVM Fritz!Card PCI,
          Fritz!Card PCI v2 and Fritz!Card PnP.
index f8b79783c8b375128a50bf119785e849e1b3e7f1..035d158779df75f328eca89c77a3e968497fb0ba 100644 (file)
@@ -830,7 +830,7 @@ static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
 
 #endif /* __ISAPNP__ */
 
-#ifndef CONFIG_PCI
+#ifndef CONFIG_PCI_LEGACY
 
 static int __devinit avm_pci_setup(struct IsdnCardState *cs)
 {
@@ -872,7 +872,7 @@ static int __devinit avm_pci_setup(struct IsdnCardState *cs)
        return (1);
 }
 
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCI_LEGACY */
 
 int __devinit
 setup_avm_pcipnp(struct IsdnCard *card)
index 82674507874647a07504e295c1a890962ce2dd98..2d670856d141bcb0a9668faabba046ca40d0a9f7 100644 (file)
@@ -1148,7 +1148,7 @@ static int __devinit setup_diva_isapnp(struct IsdnCard *card)
 
 #endif /* ISAPNP */
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCI_LEGACY
 static struct pci_dev *dev_diva __devinitdata = NULL;
 static struct pci_dev *dev_diva_u __devinitdata = NULL;
 static struct pci_dev *dev_diva201 __devinitdata = NULL;
@@ -1229,14 +1229,14 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
        return (1);             /* card found */
 }
 
-#else  /* if !CONFIG_PCI */
+#else  /* if !CONFIG_PCI_LEGACY */
 
 static int __devinit setup_diva_pci(struct IsdnCard *card)
 {
        return (-1);    /* card not found; continue search */
 }
 
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCI_LEGACY */
 
 int __devinit
 setup_diva(struct IsdnCard *card)
index 948a9b290fd1146933a9d1cb38a9d6993db989a2..d272d8ce65375a5d3159688c19a8559c8db4f872 100644 (file)
@@ -883,7 +883,7 @@ setup_elsa_isa(struct IsdnCard *card)
        val += 'A' - 3;
        if (val == 'B' || val == 'C')
                val ^= 1;
-       if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))
+       if ((cs->subtyp == ELSA_PCFPRO) && (val == 'G'))
                val = 'C';
        printk(KERN_INFO
               "Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
@@ -1025,7 +1025,7 @@ setup_elsa_pcmcia(struct IsdnCard *card)
               cs->irq);
 }
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCI_LEGACY
 static         struct pci_dev *dev_qs1000 __devinitdata = NULL;
 static         struct pci_dev *dev_qs3000 __devinitdata = NULL;
 
@@ -1093,7 +1093,7 @@ setup_elsa_pci(struct IsdnCard *card)
 {
        return (1);
 }
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCI_LEGACY */
 
 static int __devinit
 setup_elsa_common(struct IsdnCard *card)
index 3efa719b6d29f73ef38890bbeb0ba9224cddf168..f66620ad8e7c998f89c74084cffec895b78c463f 100644 (file)
@@ -532,6 +532,7 @@ setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
        return (0);
 }
 
+#ifdef CONFIG_PCI_LEGACY
 static struct pci_dev *dev_tel __devinitdata = NULL;
 
 static int __devinit
@@ -620,6 +621,7 @@ setup_gazelpci(struct IsdnCardState *cs)
 
        return (0);
 }
+#endif /* CONFIG_PCI_LEGACY */
 
 int __devinit
 setup_gazel(struct IsdnCard *card)
@@ -639,7 +641,7 @@ setup_gazel(struct IsdnCard *card)
                        return (0);
        } else {
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCI_LEGACY
                if (setup_gazelpci(cs))
                        return (0);
 #else
index e5918c6fe73d09bfb99a4dc91f05ca2c4b09646b..bd9921128aa862f15add2ee1fe63fc60e0f24d93 100644 (file)
@@ -223,7 +223,6 @@ static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
        return 0;
 }
 
-static struct pci_dev *niccy_dev __devinitdata = NULL;
 #ifdef __ISAPNP__
 static struct pnp_card *pnp_c __devinitdata = NULL;
 #endif
@@ -299,7 +298,9 @@ int __devinit setup_niccy(struct IsdnCard *card)
                        return 0;
                }
        } else {
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCI_LEGACY
+               static struct pci_dev *niccy_dev __devinitdata;
+
                u_int pci_ioaddr;
                cs->subtyp = 0;
                if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
@@ -356,7 +357,7 @@ int __devinit setup_niccy(struct IsdnCard *card)
                printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
                printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
                return 0;
-#endif                         /* CONFIG_PCI */
+#endif                         /* CONFIG_PCI_LEGACY */
        }
        printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
                CardType[cs->typ], (cs->subtyp == 1) ? "PnP" : "PCI",
index 03dfc32166a09ea057e861d8eaa93d47e6239dfe..95425f3d22209291620bc57cb2646885f2b71acf 100644 (file)
@@ -600,7 +600,7 @@ setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
 }
 #endif /* __ISAPNP__ */
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCI_LEGACY
 static struct pci_dev *dev_sedl __devinitdata = NULL;
 
 static int __devinit
@@ -675,7 +675,7 @@ setup_sedlbauer_pci(struct IsdnCard *card)
        return (1);
 }
 
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCI_LEGACY */
 
 int __devinit
 setup_sedlbauer(struct IsdnCard *card)
index 5992f63c383edd2fc6fc32a833544e0bbb5fee87..0120bcf883110fc974c5148eddb34c6f07de6081 100644 (file)
@@ -109,7 +109,7 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n);
 int get_card_from_id(int driver);
 int indicate_status(int card, int event, ulong Channel, char *Data);
 irqreturn_t interrupt_handler(int interrupt, void *cardptr);
-int sndpkt(int devId, int channel, struct sk_buff *data);
+int sndpkt(int devId, int channel, int ack, struct sk_buff *data);
 void rcvpkt(int card, RspMessage *rcvmsg);
 int command(isdn_ctrl *cmd);
 int reset(int card);
index 92016a2608e9516663c238e0f8ca08493c48199c..5ff6ae8684403fd83e48050d6e56552a473a7336 100644 (file)
@@ -20,7 +20,7 @@
 #include "message.h"
 #include "card.h"
 
-int sndpkt(int devId, int channel, struct sk_buff *data)
+int sndpkt(int devId, int channel, int ack, struct sk_buff *data)
 {
        LLData  ReqLnkWrite;
        int status;
index e0331e0094f1d582ad621bed719196aa1634503b..712220cef139469f93bd82ad5c97239c932d4841 100644 (file)
@@ -50,7 +50,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
 
        outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
                sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
-       memcpy_toio(sc_adapter[card]->rambase + dest_rem, src, n);
+       memcpy_toio((void __iomem *)(sc_adapter[card]->rambase + dest_rem), src, n);
        spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
        pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
                ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
index 729f1cd93606e86315b0330e0c2af7c740b22de6..7a6eead63a6bc14537d36fb09756ba5001bc8634 100644 (file)
@@ -494,6 +494,7 @@ static void init_vmcb(struct vmcb *vmcb)
                 */
                /*              (1ULL << INTERCEPT_SELECTIVE_CR0) | */
                                (1ULL << INTERCEPT_CPUID) |
+                               (1ULL << INTERCEPT_INVD) |
                                (1ULL << INTERCEPT_HLT) |
                                (1ULL << INTERCEPT_INVLPGA) |
                                (1ULL << INTERCEPT_IOIO_PROT) |
@@ -507,6 +508,7 @@ static void init_vmcb(struct vmcb *vmcb)
                                (1ULL << INTERCEPT_STGI) |
                                (1ULL << INTERCEPT_CLGI) |
                                (1ULL << INTERCEPT_SKINIT) |
+                               (1ULL << INTERCEPT_WBINVD) |
                                (1ULL << INTERCEPT_MONITOR) |
                                (1ULL << INTERCEPT_MWAIT);
 
@@ -561,6 +563,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu)
        struct vcpu_svm *svm = to_svm(vcpu);
 
        init_vmcb(svm->vmcb);
+
+       if (vcpu->vcpu_id != 0) {
+               svm->vmcb->save.rip = 0;
+               svm->vmcb->save.cs.base = svm->vcpu.sipi_vector << 12;
+               svm->vmcb->save.cs.selector = svm->vcpu.sipi_vector << 8;
+       }
 }
 
 static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
@@ -1241,6 +1249,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
        [SVM_EXIT_VINTR]                        = interrupt_window_interception,
        /* [SVM_EXIT_CR0_SEL_WRITE]             = emulate_on_interception, */
        [SVM_EXIT_CPUID]                        = cpuid_interception,
+       [SVM_EXIT_INVD]                         = emulate_on_interception,
        [SVM_EXIT_HLT]                          = halt_interception,
        [SVM_EXIT_INVLPG]                       = emulate_on_interception,
        [SVM_EXIT_INVLPGA]                      = invalid_op_interception,
@@ -1255,6 +1264,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
        [SVM_EXIT_STGI]                         = invalid_op_interception,
        [SVM_EXIT_CLGI]                         = invalid_op_interception,
        [SVM_EXIT_SKINIT]                       = invalid_op_interception,
+       [SVM_EXIT_WBINVD]                       = emulate_on_interception,
        [SVM_EXIT_MONITOR]                      = invalid_op_interception,
        [SVM_EXIT_MWAIT]                        = invalid_op_interception,
 };
@@ -1579,10 +1589,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 #endif
                : "cc", "memory" );
 
-       local_irq_disable();
-
-       stgi();
-
        if ((svm->vmcb->save.dr7 & 0xff))
                load_db_regs(svm->host_db_regs);
 
@@ -1599,6 +1605,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
        reload_tss(vcpu);
 
+       local_irq_disable();
+
+       stgi();
+
        svm->next_rip = 0;
 }
 
index a6ace302e0cd454f1f413306013b0920305e4a67..33b181451557ad926df9c09a4a401c7fc71ae933 100644 (file)
@@ -167,7 +167,7 @@ static u8 opcode_table[256] = {
 static u16 twobyte_table[256] = {
        /* 0x00 - 0x0F */
        0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0,
-       0, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+       ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
        /* 0x10 - 0x1F */
        0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
        /* 0x20 - 0x2F */
@@ -980,17 +980,6 @@ done_prefixes:
                        goto cannot_emulate;
                dst.val = (s32) src.val;
                break;
-       case 0x6a: /* push imm8 */
-               src.val = 0L;
-               src.val = insn_fetch(s8, 1, _eip);
-push:
-               dst.type  = OP_MEM;
-               dst.bytes = op_bytes;
-               dst.val = src.val;
-               register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
-               dst.ptr = (void *) register_address(ctxt->ss_base,
-                                                       _regs[VCPU_REGS_RSP]);
-               break;
        case 0x80 ... 0x83:     /* Grp1 */
                switch (modrm_reg) {
                case 0:
@@ -1243,6 +1232,17 @@ special_insn:
                register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
                no_wb = 1; /* Disable writeback. */
                break;
+       case 0x6a: /* push imm8 */
+               src.val = 0L;
+               src.val = insn_fetch(s8, 1, _eip);
+       push:
+               dst.type  = OP_MEM;
+               dst.bytes = op_bytes;
+               dst.val = src.val;
+               register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
+               dst.ptr = (void *) register_address(ctxt->ss_base,
+                                                       _regs[VCPU_REGS_RSP]);
+               break;
        case 0x6c:              /* insb */
        case 0x6d:              /* insw/insd */
                 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
@@ -1532,6 +1532,8 @@ twobyte_special_insn:
        case 0x06:
                emulate_clts(ctxt->vcpu);
                break;
+       case 0x08:              /* invd */
+               break;
        case 0x09:              /* wbinvd */
                break;
        case 0x0d:              /* GrpP (prefetch) */
index 47d90db280ceb5a2485e34dcc18c3cf3c704cd02..99bc50059d3531499fa78ca369129a5f7d8c0e39 100644 (file)
@@ -60,7 +60,7 @@ static void gpio_led_set(struct led_classdev *led_cdev,
                gpio_set_value(led_dat->gpio, level);
 }
 
-static int __init gpio_led_probe(struct platform_device *pdev)
+static int gpio_led_probe(struct platform_device *pdev)
 {
        struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
        struct gpio_led *cur_led;
@@ -93,13 +93,13 @@ static int __init gpio_led_probe(struct platform_device *pdev)
 
                gpio_direction_output(led_dat->gpio, led_dat->active_low);
 
+               INIT_WORK(&led_dat->work, gpio_led_work);
+
                ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
                if (ret < 0) {
                        gpio_free(led_dat->gpio);
                        goto err;
                }
-
-               INIT_WORK(&led_dat->work, gpio_led_work);
        }
 
        platform_set_drvdata(pdev, leds_data);
@@ -110,17 +110,17 @@ err:
        if (i > 0) {
                for (i = i - 1; i >= 0; i--) {
                        led_classdev_unregister(&leds_data[i].cdev);
+                       cancel_work_sync(&leds_data[i].work);
                        gpio_free(leds_data[i].gpio);
                }
        }
 
-       flush_scheduled_work();
        kfree(leds_data);
 
        return ret;
 }
 
-static int __exit gpio_led_remove(struct platform_device *pdev)
+static int __devexit gpio_led_remove(struct platform_device *pdev)
 {
        int i;
        struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
@@ -130,9 +130,10 @@ static int __exit gpio_led_remove(struct platform_device *pdev)
 
        for (i = 0; i < pdata->num_leds; i++) {
                led_classdev_unregister(&leds_data[i].cdev);
+               cancel_work_sync(&leds_data[i].work);
                gpio_free(leds_data[i].gpio);
        }
-       
+
        kfree(leds_data);
 
        return 0;
@@ -144,7 +145,7 @@ static int gpio_led_suspend(struct platform_device *pdev, pm_message_t state)
        struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
        struct gpio_led_data *leds_data;
        int i;
-       
+
        leds_data = platform_get_drvdata(pdev);
 
        for (i = 0; i < pdata->num_leds; i++)
@@ -172,7 +173,8 @@ static int gpio_led_resume(struct platform_device *pdev)
 #endif
 
 static struct platform_driver gpio_led_driver = {
-       .remove         = __exit_p(gpio_led_remove),
+       .probe          = gpio_led_probe,
+       .remove         = __devexit_p(gpio_led_remove),
        .suspend        = gpio_led_suspend,
        .resume         = gpio_led_resume,
        .driver         = {
@@ -183,7 +185,7 @@ static struct platform_driver gpio_led_driver = {
 
 static int __init gpio_led_init(void)
 {
-       return platform_driver_probe(&gpio_led_driver, gpio_led_probe);
+       return platform_driver_register(&gpio_led_driver);
 }
 
 static void __exit gpio_led_exit(void)
index 8904f72f97c6fd00ff60c0b7a904d632983db03e..66f38722253adedf3b45c8caa65f3d25742c3f34 100644 (file)
@@ -200,7 +200,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
 
        /* Figure out how many pages the ring will take, and map that memory */
        lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
-                               DIV_ROUND_UP(vring_size(lvq->config.num),
+                               DIV_ROUND_UP(vring_size(lvq->config.num,
+                                                       PAGE_SIZE),
                                             PAGE_SIZE));
        if (!lvq->pages) {
                err = -ENOMEM;
index 9d716fa42cad39f00dc2e20cdc364c752679409e..3b92a61ba8d23b14e1ac8e5b342929a314b669be 100644 (file)
@@ -184,7 +184,7 @@ static int initialize(struct file *file, const unsigned long __user *input)
 free_regs:
        free_page(lg->regs_page);
 release_guest:
-       memset(lg, 0, sizeof(*lg));
+       kfree(lg);
 unlock:
        mutex_unlock(&lguest_lock);
        return err;
index 516d943227e240750475c482c221de5dbdd066cb..075b4d99e35497c9a8f505af04d1fdf617489680 100644 (file)
@@ -94,7 +94,9 @@ static int wf_thread_func(void *data)
        DBG("wf: thread started\n");
 
        set_freezable();
-       while(!kthread_should_stop()) {
+       while (!kthread_should_stop()) {
+               try_to_freeze();
+
                if (time_after_eq(jiffies, next)) {
                        wf_notify(WF_EVENT_TICK, NULL);
                        if (wf_overtemp) {
@@ -116,12 +118,6 @@ static int wf_thread_func(void *data)
                delay = next - jiffies;
                if (delay <= HZ)
                        schedule_timeout_interruptible(delay);
-
-               /* there should be no non-suspend signal, but oh well */
-               if (signal_pending(current) && !try_to_freeze()) {
-                       printk(KERN_WARNING "windfarm: thread got sigl !\n");
-                       break;
-               }
        }
 
        DBG("wf: thread stopped\n");
index 7c426d07a555c0426855571552289c6ed9fcaaaa..1b1ef3130e6e8cbbe32ea6d659882b92a408d59e 100644 (file)
@@ -1207,8 +1207,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
                        prepare_to_wait(&bitmap->overflow_wait, &__wait,
                                        TASK_UNINTERRUPTIBLE);
                        spin_unlock_irq(&bitmap->lock);
-                       bitmap->mddev->queue
-                               ->unplug_fn(bitmap->mddev->queue);
+                       blk_unplug(bitmap->mddev->queue);
                        schedule();
                        finish_wait(&bitmap->overflow_wait, &__wait);
                        continue;
index 5a7eb650181e140b85d0ba8367e9f82c0e492923..e298d8d11f24bb1892d959833dbd84cf4f9e16e6 100644 (file)
@@ -1000,8 +1000,7 @@ void dm_table_unplug_all(struct dm_table *t)
                struct dm_dev *dd = list_entry(d, struct dm_dev, list);
                struct request_queue *q = bdev_get_queue(dd->bdev);
 
-               if (q->unplug_fn)
-                       q->unplug_fn(q);
+               blk_unplug(q);
        }
 }
 
index 56a11f6c127b888f0518b8da9c2dd838d70fc74c..3dac1cfb81896655f953939a447bb731e9539747 100644 (file)
@@ -87,8 +87,7 @@ static void linear_unplug(struct request_queue *q)
 
        for (i=0; i < mddev->raid_disks; i++) {
                struct request_queue *r_queue = bdev_get_queue(conf->disks[i].rdev->bdev);
-               if (r_queue->unplug_fn)
-                       r_queue->unplug_fn(r_queue);
+               blk_unplug(r_queue);
        }
 }
 
index 808cd95494563d260456733e0d1e9ba80cbee21e..cef9ebd5a04652d4c3e9f293448c45425531d775 100644 (file)
@@ -5445,7 +5445,7 @@ void md_do_sync(mddev_t *mddev)
                 * about not overloading the IO subsystem. (things like an
                 * e2fsck being done on the RAID array should execute fast)
                 */
-               mddev->queue->unplug_fn(mddev->queue);
+               blk_unplug(mddev->queue);
                cond_resched();
 
                currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
@@ -5464,7 +5464,7 @@ void md_do_sync(mddev_t *mddev)
         * this also signals 'finished resyncing' to md_stop
         */
  out:
-       mddev->queue->unplug_fn(mddev->queue);
+       blk_unplug(mddev->queue);
 
        wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
 
index b35731cceac671ee647e108174a44cacfa82c381..eb631ebed6860b3f19ae8c3161a10e509d448d3e 100644 (file)
@@ -125,8 +125,7 @@ static void unplug_slaves(mddev_t *mddev)
                        atomic_inc(&rdev->nr_pending);
                        rcu_read_unlock();
 
-                       if (r_queue->unplug_fn)
-                               r_queue->unplug_fn(r_queue);
+                       blk_unplug(r_queue);
 
                        rdev_dec_pending(rdev, mddev);
                        rcu_read_lock();
index c111105fc2dc66ae162cb44039b27ccd100ad352..f8e591708d1fa7768fda354aa8da006b1f26d549 100644 (file)
@@ -35,8 +35,7 @@ static void raid0_unplug(struct request_queue *q)
        for (i=0; i<mddev->raid_disks; i++) {
                struct request_queue *r_queue = bdev_get_queue(devlist[i]->bdev);
 
-               if (r_queue->unplug_fn)
-                       r_queue->unplug_fn(r_queue);
+               blk_unplug(r_queue);
        }
 }
 
index 85478d6a9c1af645dfdfdb824aa1b6c7286e9daf..4a69c416e045c97f24ef4582c9d3b9f83588ba15 100644 (file)
@@ -549,8 +549,7 @@ static void unplug_slaves(mddev_t *mddev)
                        atomic_inc(&rdev->nr_pending);
                        rcu_read_unlock();
 
-                       if (r_queue->unplug_fn)
-                               r_queue->unplug_fn(r_queue);
+                       blk_unplug(r_queue);
 
                        rdev_dec_pending(rdev, mddev);
                        rcu_read_lock();
index fc6607acb6e4734f12c4dbed23bf9e82ab5816ec..5cdcc938620050b39fb30593565847859d6ad1a4 100644 (file)
@@ -593,8 +593,7 @@ static void unplug_slaves(mddev_t *mddev)
                        atomic_inc(&rdev->nr_pending);
                        rcu_read_unlock();
 
-                       if (r_queue->unplug_fn)
-                               r_queue->unplug_fn(r_queue);
+                       blk_unplug(r_queue);
 
                        rdev_dec_pending(rdev, mddev);
                        rcu_read_lock();
index 80a67d789b7252c4311fc1adc54a1af06a519787..a5aad8cad84332a138e741d56ed49bbcf58e1c6c 100644 (file)
@@ -688,7 +688,8 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
 }
 
 static struct dma_async_tx_descriptor *
-ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
+ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
+                unsigned long pending)
 {
        int disks = sh->disks;
        int pd_idx = sh->pd_idx, i;
@@ -696,7 +697,7 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
        /* check if prexor is active which means only process blocks
         * that are part of a read-modify-write (Wantprexor)
         */
-       int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
+       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
 
        pr_debug("%s: stripe %llu\n", __FUNCTION__,
                (unsigned long long)sh->sector);
@@ -773,7 +774,8 @@ static void ops_complete_write(void *stripe_head_ref)
 }
 
 static void
-ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
+ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
+               unsigned long pending)
 {
        /* kernel stack size limits the total number of disks */
        int disks = sh->disks;
@@ -781,7 +783,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
 
        int count = 0, pd_idx = sh->pd_idx, i;
        struct page *xor_dest;
-       int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
+       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
        unsigned long flags;
        dma_async_tx_callback callback;
 
@@ -808,7 +810,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
        }
 
        /* check whether this postxor is part of a write */
-       callback = test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending) ?
+       callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ?
                ops_complete_write : ops_complete_postxor;
 
        /* 1/ if we prexor'd then the dest is reused as a source
@@ -896,12 +898,12 @@ static void raid5_run_ops(struct stripe_head *sh, unsigned long pending)
                tx = ops_run_prexor(sh, tx);
 
        if (test_bit(STRIPE_OP_BIODRAIN, &pending)) {
-               tx = ops_run_biodrain(sh, tx);
+               tx = ops_run_biodrain(sh, tx, pending);
                overlap_clear++;
        }
 
        if (test_bit(STRIPE_OP_POSTXOR, &pending))
-               ops_run_postxor(sh, tx);
+               ops_run_postxor(sh, tx, pending);
 
        if (test_bit(STRIPE_OP_CHECK, &pending))
                ops_run_check(sh);
@@ -2624,6 +2626,13 @@ static void handle_stripe5(struct stripe_head *sh)
        s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
        /* Now to look around and see what can be done */
 
+       /* clean-up completed biofill operations */
+       if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) {
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
+       }
+
        rcu_read_lock();
        for (i=disks; i--; ) {
                mdk_rdev_t *rdev;
@@ -2897,13 +2906,6 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
        s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
        /* Now to look around and see what can be done */
 
-       /* clean-up completed biofill operations */
-       if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) {
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
-       }
-
        rcu_read_lock();
        for (i=disks; i--; ) {
                mdk_rdev_t *rdev;
@@ -3186,8 +3188,7 @@ static void unplug_slaves(mddev_t *mddev)
                        atomic_inc(&rdev->nr_pending);
                        rcu_read_unlock();
 
-                       if (r_queue->unplug_fn)
-                               r_queue->unplug_fn(r_queue);
+                       blk_unplug(r_queue);
 
                        rdev_dec_pending(rdev, mddev);
                        rcu_read_lock();
index dd9bd4310c848cabf6c5a6b415695ef299209868..1604f049040494dff638038665dd61c1de9586f3 100644 (file)
@@ -151,6 +151,7 @@ config VIDEO_IR_I2C
 
 config VIDEO_IR
        tristate
+       depends on INPUT
        select VIDEO_IR_I2C if I2C
 
 config VIDEO_TVEEPROM
index cb034ead95ab8e5b88d2867cecdf7a7d5fe566fc..7d04a6fd1acb03affddb06faada0a40018066a19 100644 (file)
@@ -59,43 +59,89 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
 }
 
 /* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
-int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
+static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
+                               unsigned long us1, unsigned long us2)
 {
-       unsigned long start;
+       unsigned long timeout;
        int err;
 
        /* wait for registers to be programmed */
-       start = jiffies;
+       timeout = jiffies + usecs_to_jiffies(us1);
        while (1) {
-               err = time_after(jiffies, start + HZ/20);
+               err = time_after(jiffies, timeout);
                if (saa7146_read(dev, MC2) & 2)
                        break;
                if (err) {
-                       DEB_S(("timed out while waiting for registers getting programmed\n"));
+                       printk(KERN_ERR "%s: %s timed out while waiting for "
+                                       "registers getting programmed\n",
+                                       dev->name, __FUNCTION__);
                        return -ETIMEDOUT;
                }
-               if (nobusyloop)
-                       msleep(1);
+               msleep(1);
        }
 
        /* wait for transfer to complete */
-       start = jiffies;
+       timeout = jiffies + usecs_to_jiffies(us2);
        while (1) {
-               err = time_after(jiffies, start + HZ/4);
+               err = time_after(jiffies, timeout);
                if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
                        break;
                saa7146_read(dev, MC2);
                if (err) {
-                       DEB_S(("timed out while waiting for transfer completion\n"));
+                       DEB_S(("%s: %s timed out while waiting for transfer "
+                               "completion\n", dev->name, __FUNCTION__));
                        return -ETIMEDOUT;
                }
-               if (nobusyloop)
-                       msleep(1);
+               msleep(1);
        }
 
        return 0;
 }
 
+static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
+                               unsigned long us1, unsigned long us2)
+{
+       unsigned long loops;
+
+       /* wait for registers to be programmed */
+       loops = us1;
+       while (1) {
+               if (saa7146_read(dev, MC2) & 2)
+                       break;
+               if (!loops--) {
+                       printk(KERN_ERR "%s: %s timed out while waiting for "
+                                       "registers getting programmed\n",
+                                       dev->name, __FUNCTION__);
+                       return -ETIMEDOUT;
+               }
+               udelay(1);
+       }
+
+       /* wait for transfer to complete */
+       loops = us2 / 5;
+       while (1) {
+               if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
+                       break;
+               saa7146_read(dev, MC2);
+               if (!loops--) {
+                       DEB_S(("%s: %s timed out while waiting for transfer "
+                               "completion\n", dev->name, __FUNCTION__));
+                       return -ETIMEDOUT;
+               }
+               udelay(5);
+       }
+
+       return 0;
+}
+
+int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
+{
+       if (nobusyloop)
+               return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
+       else
+               return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
+}
+
 /****************************************************************************
  * general helper functions
  ****************************************************************************/
index 4b93931de4e1c44aabaa308c1e9b67f01afc0976..13cf16668171bb611b73ac143e7a77bfcf34b89e 100644 (file)
@@ -116,7 +116,7 @@ static int mt2131_set_params(struct dvb_frontend *fe,
        f_lo1 = (f_lo1 / 250) * 250;
        f_lo2 = f_lo1 - freq - MT2131_IF2;
 
-       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000,
+       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
 
        /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
        num1 = f_lo1 * 64 / (MT2131_FREF / 128);
index 30e8a705fad4d7bb8f83a19c9fa2e6a4eb3fb7c4..8dee7ec9456ae02d919581fb1a034ff5f8a51dff 100644 (file)
@@ -42,6 +42,9 @@ struct s5h1409_state {
        fe_modulation_t current_modulation;
 
        u32 current_frequency;
+
+       u32 is_qam_locked;
+       u32 qam_state;
 };
 
 static int debug = 0;
@@ -94,6 +97,7 @@ static struct init_tab {
        { 0xac, 0x1003, },
        { 0xad, 0x103f, },
        { 0xe2, 0x0100, },
+       { 0xe3, 0x0000, },
        { 0x28, 0x1010, },
        { 0xb1, 0x000e, },
 };
@@ -335,6 +339,8 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
 
        s5h1409_writereg(state, 0xf5, 0);
        s5h1409_writereg(state, 0xf5, 1);
+       state->is_qam_locked = 0;
+       state->qam_state = 0;
        return 0;
 }
 
@@ -349,6 +355,11 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
                s5h1409_writereg(state, 0x87, 0x01be);
                s5h1409_writereg(state, 0x88, 0x0436);
                s5h1409_writereg(state, 0x89, 0x054d);
+       } else
+       if (KHz == 4000) {
+               s5h1409_writereg(state, 0x87, 0x014b);
+               s5h1409_writereg(state, 0x88, 0x0cb5);
+               s5h1409_writereg(state, 0x89, 0x03e2);
        } else {
                printk("%s() Invalid arg = %d KHz\n", __FUNCTION__, KHz);
                ret = -1;
@@ -361,7 +372,7 @@ static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
 {
        struct s5h1409_state* state = fe->demodulator_priv;
 
-       dprintk("%s()\n", __FUNCTION__);
+       dprintk("%s(%d)\n", __FUNCTION__, inverted);
 
        if(inverted == 1)
                return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
@@ -382,14 +393,10 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
                s5h1409_writereg(state, 0xf4, 0);
                break;
        case QAM_64:
-               dprintk("%s() QAM_64\n", __FUNCTION__);
-               s5h1409_writereg(state, 0xf4, 1);
-               s5h1409_writereg(state, 0x85, 0x100);
-               break;
        case QAM_256:
-               dprintk("%s() QAM_256\n", __FUNCTION__);
+               dprintk("%s() QAM_AUTO (64/256)\n", __FUNCTION__);
                s5h1409_writereg(state, 0xf4, 1);
-               s5h1409_writereg(state, 0x85, 0x101);
+               s5h1409_writereg(state, 0x85, 0x110);
                break;
        default:
                dprintk("%s() Invalid modulation\n", __FUNCTION__);
@@ -423,7 +430,7 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
        if (enable)
                return s5h1409_writereg(state, 0xe3, 0x1100);
        else
-               return s5h1409_writereg(state, 0xe3, 0);
+               return s5h1409_writereg(state, 0xe3, 0x1000);
 }
 
 static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
@@ -444,6 +451,66 @@ static int s5h1409_register_reset(struct dvb_frontend* fe)
        return s5h1409_writereg(state, 0xfa, 0);
 }
 
+static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg;
+
+       if (state->is_qam_locked)
+               return;
+
+       /* QAM EQ lock check */
+       reg = s5h1409_readreg(state, 0xf0);
+
+       if ((reg >> 13) & 0x1) {
+
+               state->is_qam_locked = 1;
+               reg &= 0xff;
+
+               s5h1409_writereg(state, 0x96, 0x00c);
+               if ((reg < 0x38) || (reg > 0x68) ) {
+                       s5h1409_writereg(state, 0x93, 0x3332);
+                       s5h1409_writereg(state, 0x9e, 0x2c37);
+               } else {
+                       s5h1409_writereg(state, 0x93, 0x3130);
+                       s5h1409_writereg(state, 0x9e, 0x2836);
+               }
+
+       } else {
+               s5h1409_writereg(state, 0x96, 0x0008);
+               s5h1409_writereg(state, 0x93, 0x3332);
+               s5h1409_writereg(state, 0x9e, 0x2c37);
+       }
+}
+
+static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg, reg1, reg2;
+
+       reg = s5h1409_readreg(state, 0xf1);
+
+       /* Master lock */
+       if ((reg >> 15) & 0x1) {
+               if (state->qam_state != 2) {
+                       state->qam_state = 2;
+                       reg1 = s5h1409_readreg(state, 0xb2);
+                       reg2 = s5h1409_readreg(state, 0xad);
+
+                       s5h1409_writereg(state, 0x96, 0x20);
+                       s5h1409_writereg(state, 0xad,
+                               ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) );
+                       s5h1409_writereg(state, 0xab, 0x1100);
+               }
+       } else {
+               if (state->qam_state != 1) {
+                       state->qam_state = 1;
+                       s5h1409_writereg(state, 0x96, 0x08);
+                       s5h1409_writereg(state, 0xab, 0x1101);
+               }
+       }
+}
+
 /* Talk to the demod, set the FEC, GUARD, QAM settings etc */
 static int s5h1409_set_frontend (struct dvb_frontend* fe,
                                 struct dvb_frontend_parameters *p)
@@ -458,12 +525,21 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
 
        s5h1409_enable_modulation(fe, p->u.vsb.modulation);
 
+       /* Allow the demod to settle */
+       msleep(100);
+
        if (fe->ops.tuner_ops.set_params) {
                if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
                fe->ops.tuner_ops.set_params(fe, p);
                if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
        }
 
+       /* Optimize the demod for QAM */
+       if (p->u.vsb.modulation != VSB_8) {
+               s5h1409_set_qam_amhum_mode(fe);
+               s5h1409_set_qam_interleave_mode(fe);
+       }
+
        return 0;
 }
 
@@ -495,8 +571,8 @@ static int s5h1409_init (struct dvb_frontend* fe)
        s5h1409_set_gpio(fe, state->config->gpio);
        s5h1409_softreset(fe);
 
-       /* Note: Leaving the I2C gate open here. */
-       s5h1409_i2c_gate_ctrl(fe, 1);
+       /* Note: Leaving the I2C gate closed. */
+       s5h1409_i2c_gate_ctrl(fe, 0);
 
        return 0;
 }
index 17e5cb561cd8569a77752f0a3df7984648f056d3..7c23775f77dbe0582734c49ee9ffe5e9f1904cbc 100644 (file)
@@ -358,11 +358,23 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
 static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
 {
        struct stv0297_state *state = fe->demodulator_priv;
-       u8 STRENGTH[2];
-
-       stv0297_readregs(state, 0x41, STRENGTH, 2);
-       *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
-
+       u8 STRENGTH[3];
+       u16 tmp;
+
+       stv0297_readregs(state, 0x41, STRENGTH, 3);
+       tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
+       if (STRENGTH[2] & 0x20) {
+               if (tmp < 0x200)
+                       tmp = 0;
+               else
+                       tmp = tmp - 0x200;
+       } else {
+               if (tmp > 0x1ff)
+                       tmp = 0;
+               else
+                       tmp = 0x1ff - tmp;
+       }
+       *strength = (tmp << 7) | (tmp >> 2);
        return 0;
 }
 
index 4cd9e82c4669fd857eb07d37981c2483e12f876c..45137d2ebfb9846b3462e20981eb0dd91adc0973 100644 (file)
@@ -301,6 +301,8 @@ static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
        u32 _ber = tda10021_readreg(state, 0x14) |
                (tda10021_readreg(state, 0x15) << 8) |
                ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
+       _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0)
+                                       | (tda10021_inittab[0x10] & 0xc0));
        *ber = 10 * _ber;
 
        return 0;
@@ -310,7 +312,11 @@ static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
        struct tda10021_state* state = fe->demodulator_priv;
 
+       u8 config = tda10021_readreg(state, 0x02);
        u8 gain = tda10021_readreg(state, 0x17);
+       if (config & 0x02)
+               /* the agc value is inverted */
+               gain = ~gain;
        *strength = (gain << 8) | gain;
 
        return 0;
index 066b73b75698e88e674ab4f0534b3e76835fc1f7..60433b5011fde27e1ddaadc6279a40165352e379 100644 (file)
@@ -47,7 +47,7 @@ struct ves1820_state {
 static int verbose;
 
 static u8 ves1820_inittab[] = {
-       0x69, 0x6A, 0x93, 0x12, 0x12, 0x46, 0x26, 0x1A,
+       0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A,
        0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
        0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
index 6d53289b327693887881714e3ee79ad5a5602df2..54b91f26ca63a233515c04d16615be787c5e4b48 100644 (file)
@@ -84,7 +84,7 @@ config DVB_BUDGET
 
 config DVB_BUDGET_CI
        tristate "Budget cards with onboard CI connector"
-       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
+       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 && INPUT
        select VIDEO_SAA7146
        select DVB_STV0297 if !DVB_FE_CUSTOMISE
        select DVB_STV0299 if !DVB_FE_CUSTOMISE
index 2e571eb9313ae6d5b8e49b5829c83ec8a590c354..c9f14bfc85441cf28ce522875ba9169a6b82f56e 100644 (file)
@@ -363,7 +363,7 @@ endmenu # encoder / decoder chips
 
 config VIDEO_VIVI
        tristate "Virtual Video Driver"
-       depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
+       depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
        select VIDEOBUF_VMALLOC
        default n
        ---help---
index 9feeb636ff9b6e4e05c9913c06a77975de232cc9..a88b56e6ca05c3c2d990e2313c2bd79b857124f6 100644 (file)
@@ -2881,10 +2881,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (NULL == fmt)
                        return -EINVAL;
                mutex_lock(&fh->cap.lock);
-               if (fmt->depth != pic->depth) {
-                       retval = -EINVAL;
-                       goto fh_unlock_and_return;
-               }
                if (fmt->flags & FORMAT_FLAGS_RAW) {
                        /* VIDIOCMCAPTURE uses gbufsize, not RAW_BPL *
                           RAW_LINES * 2. F1 is stored at offset 0, F2
@@ -3117,6 +3113,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                                             vm->width,vm->height,field);
                if (0 != retval)
                        goto fh_unlock_and_return;
+               btv->init.width = vm->width;
+               btv->init.height = vm->height;
                spin_lock_irqsave(&btv->s_lock,flags);
                buffer_queue(&fh->cap,&buf->vb);
                spin_unlock_irqrestore(&btv->s_lock,flags);
index b63cab33692072a6163463211aaace9fb29619e1..7ae499c9c54c8785e497e9ddabdcde740c017f01 100644 (file)
@@ -3,6 +3,9 @@
  * multifunction chip.  Currently works with the Omnivision OV7670
  * sensor.
  *
+ * The data sheet for this device can be found at:
+ *    http://www.marvell.com/products/pcconn/88ALP01.jsp
+ *
  * Copyright 2006 One Laptop Per Child Association, Inc.
  * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
  *
@@ -2232,13 +2235,16 @@ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct cafe_camera *cam = cafe_find_by_pdev(pdev);
        int ret;
+       enum cafe_state cstate;
 
        ret = pci_save_state(pdev);
        if (ret)
                return ret;
+       cstate = cam->state; /* HACK - stop_dma sets to idle */
        cafe_ctlr_stop_dma(cam);
        cafe_ctlr_power_down(cam);
        pci_disable_device(pdev);
+       cam->state = cstate;
        return 0;
 }
 
index 72004a07b2d5c85199e9a06150c2f6110aa795a9..d8b1ccb44913bcdba7692dc48406ed0f7f068aa9 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_CX23885
        tristate "Conexant cx23885 (2388x successor) support"
-       depends on DVB_CORE && VIDEO_DEV && PCI && I2C
+       depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
        select I2C_ALGOBIT
        select FW_LOADER
        select VIDEO_BTCX
index eeb5224ca1018fda4708c8e4fbf29ecb552b46c1..ceb31d4a251267f66d5d2baf265d6463e2d05f95 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_CX88
        tristate "Conexant 2388x (bt878 successor) support"
-       depends on VIDEO_DEV && PCI && I2C
+       depends on VIDEO_DEV && PCI && I2C && INPUT
        select I2C_ALGOBIT
        select FW_LOADER
        select VIDEO_BTCX
index 5b6a4037160245e848119eda244cd64b9b58f20e..c1127802ad9cd3cf1f6f2f7baacf4dc23f25509d 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_EM28XX
        tristate "Empia EM2800/2820/2840 USB video capture support"
-       depends on VIDEO_V4L1 && I2C
+       depends on VIDEO_V4L1 && I2C && INPUT
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
        select VIDEO_IR
index 997d067e32e07e839eaa548a112639c99cd4d73a..e3a4aa7a9df414769bf0b8e208e3487a154fd200 100644 (file)
@@ -416,8 +416,10 @@ static int attach_inform(struct i2c_client *client)
        struct em28xx *dev = client->adapter->algo_data;
 
        switch (client->addr << 1) {
-               case 0x43:
-               case 0x4b:
+               case 0x86:
+               case 0x84:
+               case 0x96:
+               case 0x94:
                {
                        struct tuner_setup tun_setup;
 
index a4c2a907124a6529c38e143e2eeb60ed3958746d..2529c298b862a4c80c83404894783af34ca4534a 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/version.h>
+#include <linux/mm.h>
 #include <linux/video_decoder.h>
 #include <linux/mutex.h>
 
index ce4b2f9791ee5718535435f59f9e833ce4087c01..36047d4e70f625d1fa693e210c60eebbb9d20fc8 100644 (file)
@@ -91,7 +91,6 @@ static void planb_close(struct video_device *);
 static int planb_ioctl(struct video_device *, unsigned int, void *);
 static int planb_init_done(struct video_device *);
 static int planb_mmap(struct video_device *, const char *, unsigned long);
-static void planb_irq(int, void *);
 static void release_planb(void);
 int init_planbs(struct video_init *);
 
@@ -1315,7 +1314,7 @@ cmd_tab_data_end:
        return c1;
 }
 
-static void planb_irq(int irq, void *dev_id)
+static irqreturn_t planb_irq(int irq, void *dev_id)
 {
        unsigned int stat, astat;
        struct planb *pb = (struct planb *)dev_id;
@@ -1358,13 +1357,14 @@ static void planb_irq(int irq, void *dev_id)
                pb->frame_stat[fr] = GBUFFER_DONE;
                pb->grabbing--;
                wake_up_interruptible(&pb->capq);
-               return;
+               return IRQ_HANDLED;
        }
        /* incorrect interrupts? */
        pb->intr_mask = PLANB_CLR_IRQ;
        out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
        printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
                                                        " unconditionally\n");
+       return IRQ_HANDLED;
 }
 
 /*******************************
@@ -2090,7 +2090,7 @@ static int init_planb(struct planb *pb)
        /* clear interrupt mask */
        pb->intr_mask = PLANB_CLR_IRQ;
 
-       result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
+       result = request_irq(pb->irq, planb_irq, 0, "PlanB", pb);
        if (result < 0) {
                if (result==-EINVAL)
                        printk(KERN_ERR "PlanB: Bad irq number (%d) "
index f569b00201ddb09924e854cf84f4977795fee729..46f156fb108c79ffe2506470b857466f03ea6d10 100644 (file)
@@ -410,7 +410,7 @@ static int parse_mtoken(const char *ptr,unsigned int len,
        int msk;
        *valptr = 0;
        for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
-               if (!msk & valid_bits) continue;
+               if (!(msk & valid_bits)) continue;
                valid_bits &= ~msk;
                if (!names[idx]) continue;
                slen = strlen(names[idx]);
index ca9e2789c8ca58d5c00988cb56158a4cbffb519b..11b3b2e84b9092da3983fab9ab130a8f485a85d8 100644 (file)
@@ -136,14 +136,13 @@ static int __init pvr_init(void)
 
 static void __exit pvr_exit(void)
 {
-
        pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
 
+       usb_deregister(&pvr_driver);
+
 #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
        pvr2_sysfs_class_destroy(class_ptr);
 #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-
-       usb_deregister(&pvr_driver);
 }
 
 module_init(pvr_init);
index 2ee3c3049e8f3dd1a9154821cbfdf1b989305c5d..3c57a7d8200bfd9724c96f50707e217b50fbb4b1 100644 (file)
@@ -905,13 +905,6 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
 }
 
 
-static int pvr2_sysfs_hotplug(struct device *d,
-                             struct kobj_uevent_env *env)
-{
-       /* Even though we don't do anything here, we still need this function
-          because sysfs will still try to call it. */
-       return 0;
-}
 
 struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
 {
@@ -922,7 +915,6 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
        clp->class.name = "pvrusb2";
        clp->class.class_release = pvr2_sysfs_class_release;
        clp->class.dev_release = pvr2_sysfs_release;
-       clp->class.dev_uevent = pvr2_sysfs_hotplug;
        if (class_register(&clp->class)) {
                pvr2_sysfs_trace(
                        "Registration failed for pvr2_sysfs_class id=%p",clp);
index d6d8d660196d992c6fad885c30fb7c7b0661eda5..3aa8cb2b860ae3d570ca051a275cea1bff9942e2 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_SAA7134
        tristate "Philips SAA7134 support"
-       depends on VIDEO_DEV && PCI && I2C
+       depends on VIDEO_DEV && PCI && I2C && INPUT
        select VIDEOBUF_DMA_SG
        select VIDEO_IR
        select VIDEO_TUNER
index c6f7279669c184257dbcd8961478edced7f1627f..b9c5cf7dc849224c1cfcd83da1f20ff074a29e1c 100644 (file)
@@ -543,8 +543,10 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
           V4L functions, and force ALSA to use that as the DMA area */
 
        substream->runtime->dma_area = dev->dmasound.dma.vmalloc;
+       substream->runtime->dma_bytes = dev->dmasound.bufsize;
+       substream->runtime->dma_addr = 0;
 
-       return 1;
+       return 0;
 
 }
 
@@ -651,6 +653,17 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
        return 0;
 }
 
+/*
+ * page callback (needed for mmap)
+ */
+
+static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream,
+                                       unsigned long offset)
+{
+       void *pageptr = substream->runtime->dma_area + offset;
+       return vmalloc_to_page(pageptr);
+}
+
 /*
  * ALSA capture callbacks definition
  */
@@ -664,6 +677,7 @@ static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
        .prepare =              snd_card_saa7134_capture_prepare,
        .trigger =              snd_card_saa7134_capture_trigger,
        .pointer =              snd_card_saa7134_capture_pointer,
+       .page =                 snd_card_saa7134_page,
 };
 
 /*
index a4c192fb4e41172cb97e7a8104aecdda16341d74..4f3dad9ae6d6a3193434ee9ccfabad677b2791e1 100644 (file)
@@ -2996,11 +2996,11 @@ struct saa7134_board saa7134_boards[] = {
                },{
                        .name   = name_comp1,
                        .vmux   = 0,
-                       .amux   = LINE2,
+                       .amux   = LINE1,
                },{
                        .name   = name_svideo,
                        .vmux   = 8,
-                       .amux   = LINE2,
+                       .amux   = LINE1,
                }},
        },
        [SAA7134_BOARD_FLYDVBS_LR300] = {
index 6a777604f0708d36570a74fd96c704ec71fa3733..9e99f3636d3dc36a407f46007486b8fe7af252b2 100644 (file)
@@ -30,7 +30,7 @@
 
 /* standard i2c insmod options */
 static unsigned short normal_i2c[] = {
-#ifdef CONFIG_TUNER_TEA5761
+#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE))
        0x10,
 #endif
        0x42, 0x43, 0x4a, 0x4b,                 /* tda8290 */
@@ -292,7 +292,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
                }
                t->mode_mask = T_RADIO;
                break;
-#ifdef CONFIG_TUNER_TEA5761
        case TUNER_TEA5761:
                if (tea5761_attach(&t->fe, t->i2c.adapter, t->i2c.addr) == NULL) {
                        t->type = TUNER_ABSENT;
@@ -301,7 +300,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
                }
                t->mode_mask = T_RADIO;
                break;
-#endif
        case TUNER_PHILIPS_FMD1216ME_MK3:
                buffer[0] = 0x0b;
                buffer[1] = 0xdc;
@@ -594,7 +592,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
        /* autodetection code based on the i2c addr */
        if (!no_autodetect) {
                switch (addr) {
-#ifdef CONFIG_TUNER_TEA5761
                case 0x10:
                        if (tea5761_autodetection(t->i2c.adapter, t->i2c.addr) != EINVAL) {
                                t->type = TUNER_TEA5761;
@@ -606,7 +603,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                                goto register_client;
                        }
                        break;
-#endif
                case 0x42:
                case 0x43:
                case 0x4a:
index e2f1c972754bc56487222b023c2a63b5d914d4bf..25d0aef88ef51392c69e15992cbc0fbcb93414f9 100644 (file)
@@ -799,10 +799,10 @@ static inline void tvp5150_reset(struct i2c_client *c)
        tvp5150_write_inittab(c, tvp5150_init_enable);
 
        /* Initialize image preferences */
-       tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
-       tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
-       tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
-       tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
+       tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright);
+       tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast);
+       tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast);
+       tvp5150_write(c, TVP5150_HUE_CTL, decoder->hue);
 
        tvp5150_set_std(c, decoder->norm);
 };
@@ -1077,10 +1077,10 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
        core->norm = V4L2_STD_ALL;      /* Default is autodetect */
        core->route.input = TVP5150_COMPOSITE1;
        core->enable = 1;
-       core->bright = 32768;
-       core->contrast = 32768;
-       core->hue = 32768;
-       core->sat = 32768;
+       core->bright = 128;
+       core->contrast = 128;
+       core->hue = 0;
+       core->sat = 128;
 
        if (rv) {
                kfree(c);
index 682406168de9fca39e8581cdaca638019c9ad5da..e4ad7a1c4fbddaae4670478162728f6dbdff4c17 100644 (file)
@@ -1077,8 +1077,8 @@ static int i2o_block_probe(struct device *dev)
        blk_queue_max_sectors(queue, max_sectors);
        blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size));
 
-       osm_debug("max sectors = %d\n", queue->max_phys_segments);
-       osm_debug("phys segments = %d\n", queue->max_sectors);
+       osm_debug("max sectors = %d\n", queue->max_sectors);
+       osm_debug("phys segments = %d\n", queue->max_phys_segments);
        osm_debug("max hw segments = %d\n", queue->max_hw_segments);
 
        /*
index 6a5a05d1f3923d81ee54ce2df63a0e2fca7f4d37..05172d2613d66d3f980c2b2c148bd40992c4e64d 100644 (file)
@@ -244,10 +244,11 @@ ioc4_variant(struct ioc4_driver_data *idd)
                    idd->idd_pdev->bus->number == pdev->bus->number &&
                    3 == PCI_SLOT(pdev->devfn))
                        found = 1;
-               pci_dev_put(pdev);
        } while (pdev && !found);
-       if (NULL != pdev)
+       if (NULL != pdev) {
+               pci_dev_put(pdev);
                return IOC4_VARIANT_IO9;
+       }
 
        /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
        pdev = NULL;
@@ -258,10 +259,11 @@ ioc4_variant(struct ioc4_driver_data *idd)
                    idd->idd_pdev->bus->number == pdev->bus->number &&
                    3 == PCI_SLOT(pdev->devfn))
                        found = 1;
-               pci_dev_put(pdev);
        } while (pdev && !found);
-       if (NULL != pdev)
+       if (NULL != pdev) {
+               pci_dev_put(pdev);
                return IOC4_VARIANT_IO10;
+       }
 
        /* PCI-RT: No SCSI/SATA controller will be present */
        return IOC4_VARIANT_PCI_RT;
index 9203a0b221b3364b47531f0af4e963e23e17a49d..1b9c9b6da5b7349b39148129c7a6ce4a709e7717 100644 (file)
@@ -310,7 +310,7 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
                }
 
                if (src_size == 0) {
-                       src_buf = sg_virt(dst);
+                       src_buf = sg_virt(src);
                        src_size = src->length;
                }
 
index 6b80bf77a4efda8f0738bc9e1c1a56df4b0a839e..ff59d2e0475bfe620bb71dca843219bd76cf79f9 100644 (file)
@@ -1301,7 +1301,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
 
        if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
                (host->flags & SDHCI_USE_DMA)) {
-               DBG("Disabling DMA as it is marked broken");
+               DBG("Disabling DMA as it is marked broken\n");
                host->flags &= ~SDHCI_USE_DMA;
        }
 
index bb30d5be7824c0f51ece10e49b3c5ee9e2ecf807..2797da7eeee665c4c99a3eb9c6ffbc350460e812 100644 (file)
@@ -1192,6 +1192,8 @@ struct net_device * __init i82596_probe(int unit)
                        goto out;
                }
 
+               dev->base_addr = ioaddr;
+
                for (i = 0; i < 8; i++) {
                        eth_addr[i] = inb(ioaddr + 8 + i);
                        checksum += eth_addr[i];
@@ -1209,7 +1211,6 @@ struct net_device * __init i82596_probe(int unit)
                        goto out1;
                }
 
-               dev->base_addr = ioaddr;
                dev->irq = 10;
        }
 #endif
index 5f800a6dd978083583fd8592329f43eb4f19f19d..e8d69b0adf90a8efc47adde0b54875b44d19c5eb 100644 (file)
@@ -136,10 +136,11 @@ config TUN
          If you don't know what to use this for, you don't need it.
 
 config VETH
-       tristate "Virtual ethernet device"
+       tristate "Virtual ethernet pair device"
        ---help---
-         The device is an ethernet tunnel. Devices are created in pairs. When
-         one end receives the packet it appears on its pair and vice versa.
+         This device is a local ethernet tunnel. Devices are created in pairs.
+         When one end receives the packet it appears on its pair and vice
+         versa.
 
 config NET_SB1000
        tristate "General Instruments Surfboard 1000"
@@ -234,7 +235,7 @@ source "drivers/net/arm/Kconfig"
 
 config AX88796
        tristate "ASIX AX88796 NE2000 clone support"
-       depends on ARM || MIPS
+       depends on ARM || MIPS || SUPERH
        select CRC32
        select MII
        help
@@ -365,8 +366,7 @@ config MAC89x0
          read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  This module will
+         To compile this driver as a module, choose M here. This module will
          be called mac89x0.
 
 config MACSONIC
@@ -379,8 +379,7 @@ config MACSONIC
          one of these say Y and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  This module will
+         To compile this driver as a module, choose M here. This module will
          be called macsonic.
 
 config MACMACE
@@ -618,8 +617,7 @@ config EL1
          have problems.  Some people suggest to ping ("man ping") a nearby
          machine every minute ("man cron") when using this card.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c501.
 
 config EL2
@@ -631,8 +629,7 @@ config EL2
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c503.
 
 config ELPLUS
@@ -644,8 +641,7 @@ config ELPLUS
          this type, say Y and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c505.
 
 config EL16
@@ -656,8 +652,7 @@ config EL16
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c507.
 
 config EL3
@@ -672,8 +667,7 @@ config EL3
          setup disk to disable Plug & Play mode, and to select the default
          media type.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c509.
 
 config 3C515
@@ -684,8 +678,7 @@ config 3C515
          network card, say Y and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c515.
 
 config ELMC
@@ -696,8 +689,7 @@ config ELMC
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c523.
 
 config ELMC_II
@@ -708,8 +700,7 @@ config ELMC_II
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called 3c527.
 
 config VORTEX
@@ -732,8 +723,7 @@ config VORTEX
          <file:Documentation/networking/vortex.txt> and in the comments at
          the beginning of <file:drivers/net/3c59x.c>.
 
-         To compile this support as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.
+         To compile this support as a module, choose M here.
 
 config TYPHOON
        tristate "3cr990 series \"Typhoon\" support"
@@ -750,8 +740,7 @@ config TYPHOON
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called typhoon.
 
 config LANCE
@@ -788,8 +777,7 @@ config WD80x3
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called wd.
 
 config ULTRAMCA
@@ -801,8 +789,7 @@ config ULTRAMCA
          an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
          available from <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called smc-mca.
 
 config ULTRA
@@ -821,8 +808,7 @@ config ULTRA
          this but keep it in mind if you have such a SCSI card and have
          problems.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called smc-ultra.
 
 config ULTRA32
@@ -834,8 +820,7 @@ config ULTRA32
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called smc-ultra32.
 
 config BFIN_MAC
@@ -896,8 +881,7 @@ config SMC9194
          <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
          available from <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called smc9194.
 
 config SMC91X
@@ -915,8 +899,7 @@ config SMC91X
          This driver is also available as a module ( = code which can be
          inserted in and removed from the running kernel whenever you want).
          The module will be called smc91x.  If you want to compile it as a
-         module, say M here and read <file:Documentation/kbuild/modules.txt>
-         as well as <file:Documentation/networking/net-modules.txt>.
+         module, say M here and read <file:Documentation/kbuild/modules.txt>.
 
 config NET_NETX
        tristate "NetX Ethernet support"
@@ -925,8 +908,7 @@ config NET_NETX
        help
          This is support for the Hilscher netX builtin Ethernet ports
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called netx-eth.
 
 config DM9000
@@ -937,9 +919,8 @@ config DM9000
        ---help---
          Support for DM9000 chipset.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called dm9000.
+         To compile this driver as a module, choose M here.  The module
+         will be called dm9000.
 
 config SMC911X
        tristate "SMSC LAN911[5678] support"
@@ -979,8 +960,7 @@ config NI5010
          <http://www.tldp.org/docs.html#howto>. Note that this is still
          experimental code.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ni5010.
 
 config NI52
@@ -991,8 +971,7 @@ config NI52
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ni52.
 
 config NI65
@@ -1003,8 +982,7 @@ config NI65
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ni65.
 
 source "drivers/net/tulip/Kconfig"
@@ -1018,8 +996,7 @@ config AT1700
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called at1700.
 
 config DEPCA
@@ -1032,8 +1009,7 @@ config DEPCA
          <http://www.tldp.org/docs.html#howto> as well as
          <file:drivers/net/depca.c>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called depca.
 
 config HP100
@@ -1044,8 +1020,7 @@ config HP100
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called hp100.
 
 config NET_ISA
@@ -1074,8 +1049,7 @@ config E2100
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called e2100.
 
 config EWRK3
@@ -1089,8 +1063,7 @@ config EWRK3
          well as the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ewrk3.
 
 config EEXPRESS
@@ -1104,8 +1077,7 @@ config EEXPRESS
          because the driver was very unreliable. We now have a new driver
          that should do better.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called eexpress.
 
 config EEXPRESS_PRO
@@ -1118,8 +1090,7 @@ config EEXPRESS_PRO
          driver.  Please read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called eepro.
 
 config HPLAN_PLUS
@@ -1131,8 +1102,7 @@ config HPLAN_PLUS
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called hp-plus.
 
 config HPLAN
@@ -1144,8 +1114,7 @@ config HPLAN
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called hp.
 
 config LP486E
@@ -1164,8 +1133,7 @@ config ETH16I
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called eth16i.
 
 config NE2000
@@ -1185,8 +1153,7 @@ config NE2000
          laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
          below.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ne.
 
 config ZNET
@@ -1207,8 +1174,7 @@ config SEEQ8005
          is for you, read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called seeq8005.
 
 config NE2_MCA
@@ -1220,8 +1186,7 @@ config NE2_MCA
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ne2.
 
 config IBMLANA
@@ -1232,8 +1197,7 @@ config IBMLANA
          CONFIG_MCA to use this driver.  It is both available as an in-kernel
          driver and as a module.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The only
+         To compile this driver as a module, choose M here. The only
          currently supported card is the IBM LAN Adapter/A for Ethernet.  It
          will both support 16K and 32K memory windows, however a 32K window
          gives a better security against packet losses.  Usage of multiple
@@ -1247,8 +1211,7 @@ config IBMVETH
          This driver supports virtual ethernet adapters on newer IBM iSeries
          and pSeries systems.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module will
+         To compile this driver as a module, choose M here. The module will
          be called ibmveth.
 
 source "drivers/net/ibm_emac/Kconfig"
@@ -1278,8 +1241,7 @@ config PCNET32
          answer Y here and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called pcnet32.
 
 config PCNET32_NAPI
@@ -1306,8 +1268,7 @@ config AMD8111_ETH
          answer Y here and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called amd8111e.
 
 config AMD8111E_NAPI
@@ -1361,8 +1322,7 @@ config AC3200
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called ac3200.
 
 config APRICOT
@@ -1373,9 +1333,8 @@ config APRICOT
          read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called apricot.
+         To compile this driver as a module, choose M here. The module
+         will be called apricot.
 
 config B44
        tristate "Broadcom 440x/47xx ethernet support"
@@ -1387,9 +1346,8 @@ config B44
          or M and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called b44.
+         To compile this driver as a module, choose M here. The module
+         will be called b44.
 
 # Auto-select SSB PCI-HOST support, if possible
 config B44_PCI_AUTOSELECT
@@ -1418,9 +1376,8 @@ config FORCEDETH
          read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called forcedeth.
+         To compile this driver as a module, choose M here. The module
+         will be called forcedeth.
 
 config FORCEDETH_NAPI
        bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
@@ -1446,9 +1403,8 @@ config CS89x0
          <http://www.tldp.org/docs.html#howto> as well as
          <file:Documentation/networking/cs89x0.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called cs89x0.
+         To compile this driver as a module, choose M here. The module
+         will be called cs89x0.
 
 config TC35815
        tristate "TOSHIBA TC35815 Ethernet support"
@@ -1464,8 +1420,7 @@ config EEPRO100
          card, say Y and read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called eepro100.
 
 
@@ -1492,8 +1447,7 @@ config E100
          More specific information on configuring the driver is in 
          <file:Documentation/networking/e100.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called e100.
 
 config LNE390
@@ -1505,8 +1459,7 @@ config LNE390
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called lne390.
 
 config FEALNX
@@ -1546,8 +1499,7 @@ config NE2K_PCI
          NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond
          Holtek HT80232    Holtek HT80229
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called ne2k-pci.
 
 config NE3210
@@ -1560,8 +1512,7 @@ config NE3210
          <http://www.tldp.org/docs.html#howto>.  Note that this driver
          will NOT WORK for NE3200 cards as they are completely different.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called ne3210.
 
 config ES3210
@@ -1573,8 +1524,7 @@ config ES3210
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called es3210.
 
 config 8139CP
@@ -1704,8 +1654,7 @@ config TLAN
          Compaq NetFlex and Olicom cards.  Please read the file
          <file:Documentation/networking/tlan.txt> for more details.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
+         To compile this driver as a module, choose M here. The module
          will be called tlan.
 
          Please email feedback to <torben.mathiasen@compaq.com>.
@@ -1995,8 +1944,7 @@ config E1000
          More specific information on configuring the driver is in 
          <file:Documentation/networking/e1000.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called e1000.
 
 config E1000_NAPI
@@ -2041,8 +1989,7 @@ config E1000E
          More specific information on configuring the driver is in
          <file:Documentation/networking/e1000e.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called e1000e.
 
 source "drivers/net/ixp2000/Kconfig"
@@ -2075,8 +2022,7 @@ config HAMACHI
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
+         To compile this driver as a module, choose M here. The module will be
          called hamachi.
 
 config YELLOWFIN
@@ -2525,8 +2471,7 @@ config IXGBE
          More specific information on configuring the driver is in
          <file:Documentation/networking/ixgbe.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called ixgbe.
 
 config IXGB
@@ -2548,8 +2493,7 @@ config IXGB
          More specific information on configuring the driver is in 
          <file:Documentation/networking/ixgb.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called ixgb.
 
 config IXGB_NAPI
@@ -2602,8 +2546,7 @@ config MYRI10GE
 
          <http://www.myri.com/scs/download-Myri10GE.html>
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module
+         To compile this driver as a module, choose M here. The module
          will be called myri10ge.
 
 config NETXEN_NIC
@@ -2827,10 +2770,9 @@ config PLIP
          with the PLIP support in Linux versions 1.0.x.  This option enlarges
          your kernel by about 8 KB.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will be
-         called plip.  If unsure, say Y or M, in case you buy a laptop
-         later.
+         To compile this driver as a module, choose M here. The module
+         will be called plip. If unsure, say Y or M, in case you buy
+         a laptop later.
 
 config PPP
        tristate "PPP (point-to-point protocol) support"
@@ -2860,8 +2802,7 @@ config PPP
          If you said Y to "Version information on all symbols" above, then
          you cannot compile the PPP driver into the kernel; you can then only
          compile it as a module. To compile this driver as a module, choose M
-         here and read <file:Documentation/networking/net-modules.txt>.
-         The module will be called ppp_generic.
+         here. The module will be called ppp_generic.
 
 config PPP_MULTILINK
        bool "PPP multilink support (EXPERIMENTAL)"
@@ -3022,9 +2963,8 @@ config SLIP
          <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP
          support will enlarge your kernel by about 4 KB. If unsure, say N.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module will be
-         called slip.
+         To compile this driver as a module, choose M here. The module
+         will be called slip.
 
 config SLIP_COMPRESSED
        bool "CSLIP compressed headers"
index 4030274fe788d1bf3f1e7f0fdc3f589965856bb0..3b2f7f11546489aaf48bb016d0469020b511b724 100644 (file)
@@ -19,8 +19,7 @@ menuconfig ARCNET
          from <http://www.tldp.org/docs.html#howto>(even though ARCnet
          is not really Ethernet).
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called arcnet.
 
 if ARCNET
@@ -81,8 +80,7 @@ config ARCNET_COM90xx
          have always used the old ARCnet driver without knowing what type of
          card you had, this is probably the one for you.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called com90xx.
 
 config ARCNET_COM90xxIO
@@ -93,8 +91,7 @@ config ARCNET_COM90xxIO
          the normal driver. Only use it if your card doesn't support shared
          memory.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called com90io.
 
 config ARCNET_RIM_I
@@ -105,8 +102,7 @@ config ARCNET_RIM_I
          driver is completely untested, so if you have one of these cards,
          please mail <dwmw2@infradead.org>, especially if it works!
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called arc-rimi.
 
 config ARCNET_COM20020
@@ -116,8 +112,7 @@ config ARCNET_COM20020
          things as promiscuous mode, so packet sniffing is possible, and
          extra diagnostic information.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called com20020.
 
 config ARCNET_COM20020_ISA
index 7f016f3d5bf0ea3cd4f7675d50e0dd1c24d8f5f9..91a6590d107b181177a74e0bcd71003e9c4a906c 100644 (file)
@@ -417,7 +417,7 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id)
 
        if (status & REG_INTSTS_RX) {
                spin_lock(&ep->rx_lock);
-               if (likely(__netif_rx_schedule_prep(dev, &ep->napi))) {
+               if (likely(netif_rx_schedule_prep(dev, &ep->napi))) {
                        wrl(ep, REG_INTEN, REG_INTEN_TX);
                        __netif_rx_schedule(dev, &ep->napi);
                }
index 6937ef0e7275f40a14b227055f0f65886b24a052..423298c84a1da7a9f36668a15e1178d30ee163a5 100644 (file)
@@ -1847,9 +1847,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 */
 void bond_destroy(struct bonding *bond)
 {
-       unregister_netdevice(bond->dev);
        bond_deinit(bond->dev);
        bond_destroy_sysfs_entry(bond);
+       unregister_netdevice(bond->dev);
 }
 
 /*
@@ -4405,6 +4405,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
        bond_dev->set_multicast_list = bond_set_multicast_list;
        bond_dev->change_mtu = bond_change_mtu;
        bond_dev->set_mac_address = bond_set_mac_address;
+       bond_dev->validate_addr = NULL;
 
        bond_set_mode_ops(bond, bond->params.mode);
 
@@ -4474,8 +4475,8 @@ static void bond_free_all(void)
                bond_mc_list_destroy(bond);
                /* Release the bonded slaves */
                bond_release_all(bond_dev);
-               unregister_netdevice(bond_dev);
                bond_deinit(bond_dev);
+               unregister_netdevice(bond_dev);
        }
 
 #ifdef CONFIG_PROC_FS
index 7a06ade85b02e79279244da770921243f83bfd0f..b29330d8e309955a4f85008cbbddf8b7aea4465d 100644 (file)
@@ -1193,8 +1193,6 @@ static ssize_t bonding_show_active_slave(struct device *d,
        struct bonding *bond = to_bond(d);
        int count;
 
-       rtnl_lock();
-
        read_lock(&bond->curr_slave_lock);
        curr = bond->curr_active_slave;
        read_unlock(&bond->curr_slave_lock);
@@ -1216,7 +1214,9 @@ static ssize_t bonding_store_active_slave(struct device *d,
         struct slave *new_active = NULL;
        struct bonding *bond = to_bond(d);
 
+       rtnl_lock();
        write_lock_bh(&bond->lock);
+
        if (!USES_PRIMARY(bond->params.mode)) {
                printk(KERN_INFO DRV_NAME
                       ": %s: Unable to change active slave; %s is in mode %d\n",
index ffa7e649a6ef37514333cd225ab07c6e1fe61d12..443666292a5ce44ea9ce21c0a15a8de6adfdc511 100644 (file)
@@ -1379,11 +1379,11 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
        }
        __skb_pull(skb, sizeof(*p));
 
-       skb->dev->last_rx = jiffies;
        st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id());
        st->rx_packets++;
 
        skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
+       skb->dev->last_rx = jiffies;
        if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
            skb->protocol == htons(ETH_P_IP) &&
            (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
index edd6828f0a78c594649b3f354836cffe56066939..917b7b46f1a72d409d7babfb3fa0ca369bb83da2 100644 (file)
 #include <asm/system.h>
 #include <asm/ethernet.h>
 #include <asm/cache.h>
+#include <asm/arch/io_interface_mux.h>
 
 //#define ETHDEBUG
 #define D(x)
@@ -279,6 +280,9 @@ struct net_local {
         * by this lock as well.
         */
        spinlock_t lock;
+
+       spinlock_t led_lock; /* Protect LED state */
+       spinlock_t transceiver_lock; /* Protect transceiver state. */
 };
 
 typedef struct etrax_eth_descr
@@ -295,8 +299,6 @@ struct transceiver_ops
        void (*check_duplex)(struct net_device* dev);
 };
 
-struct transceiver_ops* transceiver;
-
 /* Duplex settings */
 enum duplex
 {
@@ -307,7 +309,7 @@ enum duplex
 
 /* Dma descriptors etc. */
 
-#define MAX_MEDIA_DATA_SIZE 1518
+#define MAX_MEDIA_DATA_SIZE 1522
 
 #define MIN_PACKET_LEN      46
 #define ETHER_HEAD_LEN      14
@@ -332,8 +334,8 @@ enum duplex
 
 /*Intel LXT972A specific*/
 #define MDIO_INT_STATUS_REG_2                  0x0011
-#define MDIO_INT_FULL_DUPLEX_IND               ( 1 << 9 )
-#define MDIO_INT_SPEED                         ( 1 << 14 )
+#define MDIO_INT_FULL_DUPLEX_IND       (1 << 9)
+#define MDIO_INT_SPEED                (1 << 14)
 
 /* Network flash constants */
 #define NET_FLASH_TIME                  (HZ/50) /* 20 ms */
@@ -344,8 +346,8 @@ enum duplex
 #define NO_NETWORK_ACTIVITY 0
 #define NETWORK_ACTIVITY    1
 
-#define NBR_OF_RX_DESC     64
-#define NBR_OF_TX_DESC     256
+#define NBR_OF_RX_DESC     32
+#define NBR_OF_TX_DESC     16
 
 /* Large packets are sent directly to upper layers while small packets are */
 /* copied (to reduce memory waste). The following constant decides the breakpoint */
@@ -367,7 +369,6 @@ enum duplex
 static etrax_eth_descr *myNextRxDesc;  /* Points to the next descriptor to
                                           to be processed */
 static etrax_eth_descr *myLastRxDesc;  /* The last processed descriptor */
-static etrax_eth_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
 
 static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32)));
 
@@ -377,7 +378,6 @@ static etrax_eth_descr* myNextTxDesc;  /* Next descriptor to use */
 static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32)));
 
 static unsigned int network_rec_config_shadow = 0;
-static unsigned int mdio_phy_addr; /* Transciever address */
 
 static unsigned int network_tr_ctrl_shadow = 0;
 
@@ -411,7 +411,7 @@ static int e100_set_config(struct net_device* dev, struct ifmap* map);
 static void e100_tx_timeout(struct net_device *dev);
 static struct net_device_stats *e100_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
-static void e100_hardware_send_packet(char *buf, int length);
+static void e100_hardware_send_packet(struct net_local* np, char *buf, int length);
 static void update_rx_stats(struct net_device_stats *);
 static void update_tx_stats(struct net_device_stats *);
 static int e100_probe_transceiver(struct net_device* dev);
@@ -434,7 +434,10 @@ static void e100_clear_network_leds(unsigned long dummy);
 static void e100_set_network_leds(int active);
 
 static const struct ethtool_ops e100_ethtool_ops;
-
+#if defined(CONFIG_ETRAX_NO_PHY)
+static void dummy_check_speed(struct net_device* dev);
+static void dummy_check_duplex(struct net_device* dev);
+#else
 static void broadcom_check_speed(struct net_device* dev);
 static void broadcom_check_duplex(struct net_device* dev);
 static void tdk_check_speed(struct net_device* dev);
@@ -443,16 +446,28 @@ static void intel_check_speed(struct net_device* dev);
 static void intel_check_duplex(struct net_device* dev);
 static void generic_check_speed(struct net_device* dev);
 static void generic_check_duplex(struct net_device* dev);
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void e100_netpoll(struct net_device* dev);
+#endif
+
+static int autoneg_normal = 1;
 
 struct transceiver_ops transceivers[] =
 {
+#if defined(CONFIG_ETRAX_NO_PHY)
+       {0x0000, dummy_check_speed, dummy_check_duplex}        /* Dummy */
+#else
        {0x1018, broadcom_check_speed, broadcom_check_duplex},  /* Broadcom */
        {0xC039, tdk_check_speed, tdk_check_duplex},            /* TDK 2120 */
        {0x039C, tdk_check_speed, tdk_check_duplex},            /* TDK 2120C */
         {0x04de, intel_check_speed, intel_check_duplex},       /* Intel LXT972A*/
        {0x0000, generic_check_speed, generic_check_duplex}     /* Generic, must be last */
+#endif
 };
 
+struct transceiver_ops* transceiver = &transceivers[0];
+
 #define tx_done(dev) (*R_DMA_CH0_CMD == 0)
 
 /*
@@ -471,14 +486,22 @@ etrax_ethernet_init(void)
        int i, err;
 
        printk(KERN_INFO
-              "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n");
+              "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 1998-2007 Axis Communications AB\n");
 
-       dev = alloc_etherdev(sizeof(struct net_local));
-       np = dev->priv;
+       if (cris_request_io_interface(if_eth, cardname)) {
+               printk(KERN_CRIT "etrax_ethernet_init failed to get IO interface\n");
+               return -EBUSY;
+       }
 
+       dev = alloc_etherdev(sizeof(struct net_local));
        if (!dev)
                return -ENOMEM;
 
+       np = netdev_priv(dev);
+
+       /* we do our own locking */
+       dev->features |= NETIF_F_LLTX;
+
        dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
 
        /* now setup our etrax specific stuff */
@@ -498,14 +521,22 @@ etrax_ethernet_init(void)
        dev->do_ioctl           = e100_ioctl;
        dev->set_config         = e100_set_config;
        dev->tx_timeout         = e100_tx_timeout;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = e100_netpoll;
+#endif
+
+       spin_lock_init(&np->lock);
+       spin_lock_init(&np->led_lock);
+       spin_lock_init(&np->transceiver_lock);
 
        /* Initialise the list of Etrax DMA-descriptors */
 
        /* Initialise receive descriptors */
 
        for (i = 0; i < NBR_OF_RX_DESC; i++) {
-               /* Allocate two extra cachelines to make sure that buffer used by DMA
-                * does not share cacheline with any other data (to avoid cache bug)
+               /* Allocate two extra cachelines to make sure that buffer used
+                * by DMA does not share cacheline with any other data (to
+                * avoid cache bug)
                 */
                RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
                if (!RxDescList[i].skb)
@@ -541,7 +572,6 @@ etrax_ethernet_init(void)
 
        myNextRxDesc  = &RxDescList[0];
        myLastRxDesc  = &RxDescList[NBR_OF_RX_DESC - 1];
-       myPrevRxDesc  = &RxDescList[NBR_OF_RX_DESC - 1];
        myFirstTxDesc = &TxDescList[0];
        myNextTxDesc  = &TxDescList[0];
        myLastTxDesc  = &TxDescList[NBR_OF_TX_DESC - 1];
@@ -562,10 +592,11 @@ etrax_ethernet_init(void)
        current_speed = 10;
        current_speed_selection = 0; /* Auto */
        speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
-        duplex_timer.data = (unsigned long)dev;
+       speed_timer.data = (unsigned long)dev;
        speed_timer.function = e100_check_speed;
 
        clear_led_timer.function = e100_clear_network_leds;
+       clear_led_timer.data = (unsigned long)dev;
 
        full_duplex = 0;
        current_duplex = autoneg;
@@ -574,7 +605,6 @@ etrax_ethernet_init(void)
        duplex_timer.function = e100_check_duplex;
 
         /* Initialize mii interface */
-       np->mii_if.phy_id = mdio_phy_addr;
        np->mii_if.phy_id_mask = 0x1f;
        np->mii_if.reg_num_mask = 0x1f;
        np->mii_if.dev = dev;
@@ -585,6 +615,9 @@ etrax_ethernet_init(void)
        /* unwanted addresses are matched */
        *R_NETWORK_GA_0 = 0x00000000;
        *R_NETWORK_GA_1 = 0x00000000;
+
+       /* Initialize next time the led can flash */
+       led_next_time = jiffies;
        return 0;
 }
 
@@ -595,9 +628,9 @@ etrax_ethernet_init(void)
 static int
 e100_set_mac_address(struct net_device *dev, void *p)
 {
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
        struct sockaddr *addr = p;
-       int i;
+       DECLARE_MAC_BUF(mac);
 
        spin_lock(&np->lock); /* preemption protection */
 
@@ -686,6 +719,25 @@ e100_open(struct net_device *dev)
                goto grace_exit2;
        }
 
+       /*
+        * Always allocate the DMA channels after the IRQ,
+        * and clean up on failure.
+        */
+
+       if (cris_request_dma(NETWORK_TX_DMA_NBR,
+                            cardname,
+                            DMA_VERBOSE_ON_ERROR,
+                            dma_eth)) {
+               goto grace_exit3;
+        }
+
+       if (cris_request_dma(NETWORK_RX_DMA_NBR,
+                            cardname,
+                            DMA_VERBOSE_ON_ERROR,
+                            dma_eth)) {
+               goto grace_exit4;
+        }
+
        /* give the HW an idea of what MAC address we want */
 
        *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) |
@@ -700,6 +752,7 @@ e100_open(struct net_device *dev)
 
        *R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */
 #else
+       SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, max_size, size1522);
        SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, broadcast, receive);
        SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, ma0, enable);
        SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex);
@@ -719,8 +772,7 @@ e100_open(struct net_device *dev)
        SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable);
        *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
 
        /* enable the irq's for ethernet DMA */
 
@@ -752,12 +804,13 @@ e100_open(struct net_device *dev)
 
        *R_DMA_CH0_FIRST = 0;
        *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);
+       netif_start_queue(dev);
 
-       restore_flags(flags);
+       local_irq_restore(flags);
 
        /* Probe for transceiver */
        if (e100_probe_transceiver(dev))
-               goto grace_exit3;
+               goto grace_exit5;
 
        /* Start duplex/speed timers */
        add_timer(&speed_timer);
@@ -766,10 +819,14 @@ e100_open(struct net_device *dev)
        /* We are now ready to accept transmit requeusts from
         * the queueing layer of the networking.
         */
-       netif_start_queue(dev);
+       netif_carrier_on(dev);
 
        return 0;
 
+grace_exit5:
+       cris_free_dma(NETWORK_RX_DMA_NBR, cardname);
+grace_exit4:
+       cris_free_dma(NETWORK_TX_DMA_NBR, cardname);
 grace_exit3:
        free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 grace_exit2:
@@ -780,12 +837,20 @@ grace_exit0:
        return -EAGAIN;
 }
 
-
+#if defined(CONFIG_ETRAX_NO_PHY)
+static void
+dummy_check_speed(struct net_device* dev)
+{
+       current_speed = 100;
+}
+#else
 static void
 generic_check_speed(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE);
        if ((data & ADVERTISE_100FULL) ||
            (data & ADVERTISE_100HALF))
                current_speed = 100;
@@ -797,7 +862,10 @@ static void
 tdk_check_speed(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_TDK_DIAGNOSTIC_REG);
        current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10);
 }
 
@@ -805,7 +873,10 @@ static void
 broadcom_check_speed(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_AUX_CTRL_STATUS_REG);
        current_speed = (data & MDIO_BC_SPEED ? 100 : 10);
 }
 
@@ -813,46 +884,62 @@ static void
 intel_check_speed(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_INT_STATUS_REG_2);
        current_speed = (data & MDIO_INT_SPEED ? 100 : 10);
 }
-
+#endif
 static void
 e100_check_speed(unsigned long priv)
 {
        struct net_device* dev = (struct net_device*)priv;
+       struct net_local *np = netdev_priv(dev);
        static int led_initiated = 0;
        unsigned long data;
        int old_speed = current_speed;
 
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR);
+       spin_lock(&np->transceiver_lock);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMSR);
        if (!(data & BMSR_LSTATUS)) {
                current_speed = 0;
        } else {
                transceiver->check_speed(dev);
        }
 
+       spin_lock(&np->led_lock);
        if ((old_speed != current_speed) || !led_initiated) {
                led_initiated = 1;
                e100_set_network_leds(NO_NETWORK_ACTIVITY);
+               if (current_speed)
+                       netif_carrier_on(dev);
+               else
+                       netif_carrier_off(dev);
        }
+       spin_unlock(&np->led_lock);
 
        /* Reinitialize the timer. */
        speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
        add_timer(&speed_timer);
+
+       spin_unlock(&np->transceiver_lock);
 }
 
 static void
 e100_negotiate(struct net_device* dev)
 {
-       unsigned short data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
+       struct net_local *np = netdev_priv(dev);
+       unsigned short data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                               MII_ADVERTISE);
 
        /* Discard old speed and duplex settings */
        data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL |
                  ADVERTISE_10HALF | ADVERTISE_10FULL);
 
        switch (current_speed_selection) {
-               case 10 :
+               case 10:
                        if (current_duplex == full)
                                data |= ADVERTISE_10FULL;
                        else if (current_duplex == half)
@@ -861,7 +948,7 @@ e100_negotiate(struct net_device* dev)
                                data |= ADVERTISE_10HALF | ADVERTISE_10FULL;
                        break;
 
-               case 100 :
+               case 100:
                         if (current_duplex == full)
                                data |= ADVERTISE_100FULL;
                        else if (current_duplex == half)
@@ -870,7 +957,7 @@ e100_negotiate(struct net_device* dev)
                                data |= ADVERTISE_100HALF | ADVERTISE_100FULL;
                        break;
 
-               case 0 : /* Auto */
+               case 0: /* Auto */
                         if (current_duplex == full)
                                data |= ADVERTISE_100FULL | ADVERTISE_10FULL;
                        else if (current_duplex == half)
@@ -880,35 +967,44 @@ e100_negotiate(struct net_device* dev)
                                  ADVERTISE_100HALF | ADVERTISE_100FULL;
                        break;
 
-               default : /* assume autoneg speed and duplex */
+               default: /* assume autoneg speed and duplex */
                        data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
                                  ADVERTISE_100HALF | ADVERTISE_100FULL;
+                       break;
        }
 
-       e100_set_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE, data);
+       e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data);
 
        /* Renegotiate with link partner */
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR);
+       if (autoneg_normal) {
+         data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
        data |= BMCR_ANENABLE | BMCR_ANRESTART;
-
-       e100_set_mdio_reg(dev, mdio_phy_addr, MII_BMCR, data);
+       }
+       e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data);
 }
 
 static void
 e100_set_speed(struct net_device* dev, unsigned long speed)
 {
+       struct net_local *np = netdev_priv(dev);
+
+       spin_lock(&np->transceiver_lock);
        if (speed != current_speed_selection) {
                current_speed_selection = speed;
                e100_negotiate(dev);
        }
+       spin_unlock(&np->transceiver_lock);
 }
 
 static void
 e100_check_duplex(unsigned long priv)
 {
        struct net_device *dev = (struct net_device *)priv;
-       struct net_local *np = (struct net_local *)dev->priv;
-       int old_duplex = full_duplex;
+       struct net_local *np = netdev_priv(dev);
+       int old_duplex;
+
+       spin_lock(&np->transceiver_lock);
+       old_duplex = full_duplex;
        transceiver->check_duplex(dev);
        if (old_duplex != full_duplex) {
                /* Duplex changed */
@@ -920,13 +1016,22 @@ e100_check_duplex(unsigned long priv)
        duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL;
        add_timer(&duplex_timer);
        np->mii_if.full_duplex = full_duplex;
+       spin_unlock(&np->transceiver_lock);
 }
-
+#if defined(CONFIG_ETRAX_NO_PHY)
+static void
+dummy_check_duplex(struct net_device* dev)
+{
+       full_duplex = 1;
+}
+#else
 static void
 generic_check_duplex(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE);
        if ((data & ADVERTISE_10FULL) ||
            (data & ADVERTISE_100FULL))
                full_duplex = 1;
@@ -938,7 +1043,10 @@ static void
 tdk_check_duplex(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_TDK_DIAGNOSTIC_REG);
        full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0;
 }
 
@@ -946,7 +1054,10 @@ static void
 broadcom_check_duplex(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_AUX_CTRL_STATUS_REG);
        full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0;
 }
 
@@ -954,38 +1065,55 @@ static void
 intel_check_duplex(struct net_device* dev)
 {
        unsigned long data;
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2);
+       struct net_local *np = netdev_priv(dev);
+
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id,
+                                MDIO_INT_STATUS_REG_2);
        full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0;
 }
-
+#endif
 static void
 e100_set_duplex(struct net_device* dev, enum duplex new_duplex)
 {
+       struct net_local *np = netdev_priv(dev);
+
+       spin_lock(&np->transceiver_lock);
        if (new_duplex != current_duplex) {
                current_duplex = new_duplex;
                e100_negotiate(dev);
        }
+       spin_unlock(&np->transceiver_lock);
 }
 
 static int
 e100_probe_transceiver(struct net_device* dev)
 {
+       int ret = 0;
+
+#if !defined(CONFIG_ETRAX_NO_PHY)
        unsigned int phyid_high;
        unsigned int phyid_low;
        unsigned int oui;
        struct transceiver_ops* ops = NULL;
+       struct net_local *np = netdev_priv(dev);
+
+       spin_lock(&np->transceiver_lock);
 
        /* Probe MDIO physical address */
-       for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) {
-               if (e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR) != 0xffff)
+       for (np->mii_if.phy_id = 0; np->mii_if.phy_id <= 31;
+            np->mii_if.phy_id++) {
+               if (e100_get_mdio_reg(dev,
+                                     np->mii_if.phy_id, MII_BMSR) != 0xffff)
                        break;
        }
-       if (mdio_phy_addr == 32)
-                return -ENODEV;
+       if (np->mii_if.phy_id == 32) {
+               ret = -ENODEV;
+               goto out;
+       }
 
        /* Get manufacturer */
-       phyid_high = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID1);
-       phyid_low = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID2);
+       phyid_high = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID1);
+       phyid_low = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID2);
        oui = (phyid_high << 6) | (phyid_low >> 10);
 
        for (ops = &transceivers[0]; ops->oui; ops++) {
@@ -993,8 +1121,10 @@ e100_probe_transceiver(struct net_device* dev)
                        break;
        }
        transceiver = ops;
-
-       return 0;
+out:
+       spin_unlock(&np->transceiver_lock);
+#endif
+       return ret;
 }
 
 static int
@@ -1088,13 +1218,14 @@ e100_receive_mdio_bit()
 static void
 e100_reset_transceiver(struct net_device* dev)
 {
+       struct net_local *np = netdev_priv(dev);
        unsigned short cmd;
        unsigned short data;
        int bitCounter;
 
-       data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR);
+       data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
 
-       cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MII_BMCR << 2);
+       cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (np->mii_if.phy_id << 7) | (MII_BMCR << 2);
 
        e100_send_mdio_cmd(cmd, 1);
 
@@ -1112,7 +1243,7 @@ e100_reset_transceiver(struct net_device* dev)
 static void
 e100_tx_timeout(struct net_device *dev)
 {
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&np->lock, flags);
@@ -1134,8 +1265,7 @@ e100_tx_timeout(struct net_device *dev)
        e100_reset_transceiver(dev);
 
        /* and get rid of the packets that never got an interrupt */
-       while (myFirstTxDesc != myNextTxDesc)
-       {
+       while (myFirstTxDesc != myNextTxDesc) {
                dev_kfree_skb(myFirstTxDesc->skb);
                myFirstTxDesc->skb = 0;
                myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next);
@@ -1161,7 +1291,7 @@ e100_tx_timeout(struct net_device *dev)
 static int
 e100_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
        unsigned char *buf = skb->data;
        unsigned long flags;
 
@@ -1174,7 +1304,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
 
-       e100_hardware_send_packet(buf, skb->len);
+       e100_hardware_send_packet(np, buf, skb->len);
 
        myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next);
 
@@ -1197,13 +1327,15 @@ static irqreturn_t
 e100rxtx_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
-       struct net_local *np = (struct net_local *)dev->priv;
-       unsigned long irqbits = *R_IRQ_MASK2_RD;
+       struct net_local *np = netdev_priv(dev);
+       unsigned long irqbits;
 
-       /* Disable RX/TX IRQs to avoid reentrancy */
-       *R_IRQ_MASK2_CLR =
-         IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
-         IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr);
+       /*
+        * Note that both rx and tx interrupts are blocked at this point,
+        * regardless of which got us here.
+        */
+
+       irqbits = *R_IRQ_MASK2_RD;
 
        /* Handle received packets */
        if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) {
@@ -1219,7 +1351,7 @@ e100rxtx_interrupt(int irq, void *dev_id)
                         * allocate a new buffer to put a packet in.
                         */
                        e100_rx(dev);
-                       ((struct net_local *)dev->priv)->stats.rx_packets++;
+                       np->stats.rx_packets++;
                        /* restart/continue on the channel, for safety */
                        *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
                        /* clear dma channel 1 eop/descr irq bits */
@@ -1233,9 +1365,8 @@ e100rxtx_interrupt(int irq, void *dev_id)
        }
 
        /* Report any packets that have been sent */
-       while (myFirstTxDesc != phys_to_virt(*R_DMA_CH0_FIRST) &&
-              myFirstTxDesc != myNextTxDesc)
-       {
+       while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST &&
+              (netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) {
                np->stats.tx_bytes += myFirstTxDesc->skb->len;
                np->stats.tx_packets++;
 
@@ -1244,19 +1375,15 @@ e100rxtx_interrupt(int irq, void *dev_id)
                dev_kfree_skb_irq(myFirstTxDesc->skb);
                myFirstTxDesc->skb = 0;
                myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next);
+                /* Wake up queue. */
+               netif_wake_queue(dev);
        }
 
        if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) {
-               /* acknowledge the eop interrupt and wake up queue */
+               /* acknowledge the eop interrupt. */
                *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
-               netif_wake_queue(dev);
        }
 
-       /* Enable RX/TX IRQs again */
-       *R_IRQ_MASK2_SET =
-         IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
-         IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set);
-
        return IRQ_HANDLED;
 }
 
@@ -1264,7 +1391,7 @@ static irqreturn_t
 e100nw_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
        unsigned long irqbits = *R_IRQ_MASK0_RD;
 
        /* check for underrun irq */
@@ -1286,7 +1413,6 @@ e100nw_interrupt(int irq, void *dev_id)
                SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
                *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
                SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
-               *R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr);
                np->stats.tx_errors++;
                D(printk("ethernet excessive collisions!\n"));
        }
@@ -1299,12 +1425,13 @@ e100_rx(struct net_device *dev)
 {
        struct sk_buff *skb;
        int length = 0;
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
        unsigned char *skb_data_ptr;
 #ifdef ETHDEBUG
        int i;
 #endif
-
+       etrax_eth_descr *prevRxDesc;  /* The descriptor right before myNextRxDesc */
+       spin_lock(&np->led_lock);
        if (!led_active && time_after(jiffies, led_next_time)) {
                /* light the network leds depending on the current speed. */
                e100_set_network_leds(NETWORK_ACTIVITY);
@@ -1314,9 +1441,10 @@ e100_rx(struct net_device *dev)
                led_active = 1;
                mod_timer(&clear_led_timer, jiffies + HZ/10);
        }
+       spin_unlock(&np->led_lock);
 
        length = myNextRxDesc->descr.hw_len - 4;
-       ((struct net_local *)dev->priv)->stats.rx_bytes += length;
+       np->stats.rx_bytes += length;
 
 #ifdef ETHDEBUG
        printk("Got a packet of length %d:\n", length);
@@ -1336,7 +1464,7 @@ e100_rx(struct net_device *dev)
                if (!skb) {
                        np->stats.rx_errors++;
                        printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
-                       return;
+                       goto update_nextrxdesc;
                }
 
                skb_put(skb, length - ETHER_HEAD_LEN);        /* allocate room for the packet body */
@@ -1354,15 +1482,15 @@ e100_rx(struct net_device *dev)
        else {
                /* Large packet, send directly to upper layers and allocate new
                 * memory (aligned to cache line boundary to avoid bug).
-                * Before sending the skb to upper layers we must make sure that
-                * skb->data points to the aligned start of the packet.
+                * Before sending the skb to upper layers we must make sure
+                * that skb->data points to the aligned start of the packet.
                 */
                int align;
                struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
                if (!new_skb) {
                        np->stats.rx_errors++;
                        printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
-                       return;
+                       goto update_nextrxdesc;
                }
                skb = myNextRxDesc->skb;
                align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data;
@@ -1377,9 +1505,10 @@ e100_rx(struct net_device *dev)
        /* Send the packet to the upper layers */
        netif_rx(skb);
 
+  update_nextrxdesc:
        /* Prepare for next packet */
        myNextRxDesc->descr.status = 0;
-       myPrevRxDesc = myNextRxDesc;
+       prevRxDesc = myNextRxDesc;
        myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next);
 
        rx_queue_len++;
@@ -1387,9 +1516,9 @@ e100_rx(struct net_device *dev)
        /* Check if descriptors should be returned */
        if (rx_queue_len == RX_QUEUE_THRESHOLD) {
                flush_etrax_cache();
-               myPrevRxDesc->descr.ctrl |= d_eol;
+               prevRxDesc->descr.ctrl |= d_eol;
                myLastRxDesc->descr.ctrl &= ~d_eol;
-               myLastRxDesc = myPrevRxDesc;
+               myLastRxDesc = prevRxDesc;
                rx_queue_len = 0;
        }
 }
@@ -1398,7 +1527,7 @@ e100_rx(struct net_device *dev)
 static int
 e100_close(struct net_device *dev)
 {
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
 
        printk(KERN_INFO "Closing %s.\n", dev->name);
 
@@ -1426,6 +1555,9 @@ e100_close(struct net_device *dev)
        free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev);
        free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 
+       cris_free_dma(NETWORK_TX_DMA_NBR, cardname);
+       cris_free_dma(NETWORK_RX_DMA_NBR, cardname);
+
        /* Update the statistics here. */
 
        update_rx_stats(&np->stats);
@@ -1443,18 +1575,11 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct mii_ioctl_data *data = if_mii(ifr);
        struct net_local *np = netdev_priv(dev);
+       int rc = 0;
+        int old_autoneg;
 
        spin_lock(&np->lock); /* Preempt protection */
        switch (cmd) {
-               case SIOCGMIIPHY: /* Get PHY address */
-                       data->phy_id = mdio_phy_addr;
-                       break;
-               case SIOCGMIIREG: /* Read MII register */
-                       data->val_out = e100_get_mdio_reg(dev, mdio_phy_addr, data->reg_num);
-                       break;
-               case SIOCSMIIREG: /* Write MII register */
-                       e100_set_mdio_reg(dev, mdio_phy_addr, data->reg_num, data->val_in);
-                       break;
                /* The ioctls below should be considered obsolete but are */
                /* still present for compatability with old scripts/apps  */
                case SET_ETH_SPEED_10:                  /* 10 Mbps */
@@ -1463,60 +1588,47 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                case SET_ETH_SPEED_100:                /* 100 Mbps */
                        e100_set_speed(dev, 100);
                        break;
-               case SET_ETH_SPEED_AUTO:              /* Auto negotiate speed */
+               case SET_ETH_SPEED_AUTO:        /* Auto-negotiate speed */
                        e100_set_speed(dev, 0);
                        break;
-               case SET_ETH_DUPLEX_HALF:              /* Half duplex. */
+               case SET_ETH_DUPLEX_HALF:       /* Half duplex */
                        e100_set_duplex(dev, half);
                        break;
-               case SET_ETH_DUPLEX_FULL:              /* Full duplex. */
+               case SET_ETH_DUPLEX_FULL:       /* Full duplex */
                        e100_set_duplex(dev, full);
                        break;
-               case SET_ETH_DUPLEX_AUTO:             /* Autonegotiate duplex*/
+               case SET_ETH_DUPLEX_AUTO:       /* Auto-negotiate duplex */
                        e100_set_duplex(dev, autoneg);
                        break;
+               case SET_ETH_AUTONEG:
+                       old_autoneg = autoneg_normal;
+                       autoneg_normal = *(int*)data;
+                       if (autoneg_normal != old_autoneg)
+                               e100_negotiate(dev);
+                       break;
                default:
-                       return -EINVAL;
+                       rc = generic_mii_ioctl(&np->mii_if, if_mii(ifr),
+                                               cmd, NULL);
+                       break;
        }
        spin_unlock(&np->lock);
-       return 0;
+       return rc;
 }
 
-static int e100_set_settings(struct net_device *dev,
-                            struct ethtool_cmd *ecmd)
+static int e100_get_settings(struct net_device *dev,
+                            struct ethtool_cmd *cmd)
 {
-       ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
-                         SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
-                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
-       ecmd->port = PORT_TP;
-       ecmd->transceiver = XCVR_EXTERNAL;
-       ecmd->phy_address = mdio_phy_addr;
-       ecmd->speed = current_speed;
-       ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
-       ecmd->advertising = ADVERTISED_TP;
+       struct net_local *np = netdev_priv(dev);
+       int err;
 
-       if (current_duplex == autoneg && current_speed_selection == 0)
-               ecmd->advertising |= ADVERTISED_Autoneg;
-       else {
-               ecmd->advertising |=
-                       ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
-                       ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
-               if (current_speed_selection == 10)
-                       ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
-                                              ADVERTISED_100baseT_Full);
-               else if (current_speed_selection == 100)
-                       ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
-                                              ADVERTISED_10baseT_Full);
-               if (current_duplex == half)
-                       ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
-                                              ADVERTISED_100baseT_Full);
-               else if (current_duplex == full)
-                       ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
-                                              ADVERTISED_100baseT_Half);
-       }
+       spin_lock_irq(&np->lock);
+       err = mii_ethtool_gset(&np->mii_if, cmd);
+       spin_unlock_irq(&np->lock);
 
-       ecmd->autoneg = AUTONEG_ENABLE;
-       return 0;
+       /* The PHY may support 1000baseT, but the Etrax100 does not.  */
+       cmd->supported &= ~(SUPPORTED_1000baseT_Half
+                           | SUPPORTED_1000baseT_Full);
+       return err;
 }
 
 static int e100_set_settings(struct net_device *dev,
@@ -1560,7 +1672,8 @@ static const struct ethtool_ops e100_ethtool_ops = {
 static int
 e100_set_config(struct net_device *dev, struct ifmap *map)
 {
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct net_local *np = netdev_priv(dev);
+
        spin_lock(&np->lock); /* Preempt protection */
 
        switch(map->port) {
@@ -1612,7 +1725,6 @@ update_tx_stats(struct net_device_stats *es)
        es->collisions +=
                IO_EXTRACT(R_TR_COUNTERS, single_col, r) +
                IO_EXTRACT(R_TR_COUNTERS, multiple_col, r);
-       es->tx_errors += IO_EXTRACT(R_TR_COUNTERS, deferred, r);
 }
 
 /*
@@ -1622,8 +1734,9 @@ update_tx_stats(struct net_device_stats *es)
 static struct net_device_stats *
 e100_get_stats(struct net_device *dev)
 {
-       struct net_local *lp = (struct net_local *)dev->priv;
+       struct net_local *lp = netdev_priv(dev);
        unsigned long flags;
+
        spin_lock_irqsave(&lp->lock, flags);
 
        update_rx_stats(&lp->stats);
@@ -1643,13 +1756,13 @@ e100_get_stats(struct net_device *dev)
 static void
 set_multicast_list(struct net_device *dev)
 {
-       struct net_local *lp = (struct net_local *)dev->priv;
+       struct net_local *lp = netdev_priv(dev);
        int num_addr = dev->mc_count;
        unsigned long int lo_bits;
        unsigned long int hi_bits;
+
        spin_lock(&lp->lock);
-       if (dev->flags & IFF_PROMISC)
-       {
+       if (dev->flags & IFF_PROMISC) {
                /* promiscuous mode */
                lo_bits = 0xfffffffful;
                hi_bits = 0xfffffffful;
@@ -1679,9 +1792,10 @@ set_multicast_list(struct net_device *dev)
                struct dev_mc_list *dmi = dev->mc_list;
                int i;
                char *baddr;
+
                lo_bits = 0x00000000ul;
                hi_bits = 0x00000000ul;
-               for (i=0; i<num_addr; i++) {
+               for (i = 0; i < num_addr; i++) {
                        /* Calculate the hash index for the GA registers */
 
                        hash_ix = 0;
@@ -1708,8 +1822,7 @@ set_multicast_list(struct net_device *dev)
 
                        if (hash_ix >= 32) {
                                hi_bits |= (1 << (hash_ix-32));
-                       }
-                       else {
+                       } else {
                                lo_bits |= (1 << hash_ix);
                        }
                        dmi = dmi->next;
@@ -1724,10 +1837,11 @@ set_multicast_list(struct net_device *dev)
 }
 
 void
-e100_hardware_send_packet(char *buf, int length)
+e100_hardware_send_packet(struct net_local *np, char *buf, int length)
 {
        D(printk("e100 send pack, buf 0x%x len %d\n", buf, length));
 
+       spin_lock(&np->led_lock);
        if (!led_active && time_after(jiffies, led_next_time)) {
                /* light the network leds depending on the current speed. */
                e100_set_network_leds(NETWORK_ACTIVITY);
@@ -1737,6 +1851,7 @@ e100_hardware_send_packet(char *buf, int length)
                led_active = 1;
                mod_timer(&clear_led_timer, jiffies + HZ/10);
        }
+       spin_unlock(&np->led_lock);
 
        /* configure the tx dma descriptor */
        myNextTxDesc->descr.sw_len = length;
@@ -1754,6 +1869,11 @@ e100_hardware_send_packet(char *buf, int length)
 static void
 e100_clear_network_leds(unsigned long dummy)
 {
+       struct net_device *dev = (struct net_device *)dummy;
+       struct net_local *np = netdev_priv(dev);
+
+       spin_lock(&np->led_lock);
+
        if (led_active && time_after(jiffies, led_next_time)) {
                e100_set_network_leds(NO_NETWORK_ACTIVITY);
 
@@ -1761,6 +1881,8 @@ e100_clear_network_leds(unsigned long dummy)
                led_next_time = jiffies + NET_FLASH_PAUSE;
                led_active = 0;
        }
+
+       spin_unlock(&np->led_lock);
 }
 
 static void
@@ -1781,19 +1903,25 @@ e100_set_network_leds(int active)
 #else
                LED_NETWORK_SET(LED_OFF);
 #endif
-       }
-       else if (light_leds) {
+       } else if (light_leds) {
                if (current_speed == 10) {
                        LED_NETWORK_SET(LED_ORANGE);
                } else {
                        LED_NETWORK_SET(LED_GREEN);
                }
-       }
-       else {
+       } else {
                LED_NETWORK_SET(LED_OFF);
        }
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+e100_netpoll(struct net_device* netdev)
+{
+       e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL);
+}
+#endif
+
 static int
 etrax_init_module(void)
 {
index 72deff0d4d90b769afc12278442bee0a445e3c6e..cf39473ef90a5e04ea65c04ac247a30bc6f06915 100644 (file)
@@ -4804,6 +4804,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                        spin_unlock_irqrestore(&adapter->stats_lock, flags);
                        return -EIO;
                }
+               spin_unlock_irqrestore(&adapter->stats_lock, flags);
                if (adapter->hw.media_type == e1000_media_type_copper) {
                        switch (data->reg_num) {
                        case PHY_CTRL:
@@ -4824,12 +4825,8 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                                                   DUPLEX_HALF;
                                        retval = e1000_set_spd_dplx(adapter,
                                                                    spddplx);
-                                       if (retval) {
-                                               spin_unlock_irqrestore(
-                                                       &adapter->stats_lock,
-                                                       flags);
+                                       if (retval)
                                                return retval;
-                                       }
                                }
                                if (netif_running(adapter->netdev))
                                        e1000_reinit_locked(adapter);
@@ -4838,11 +4835,8 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                                break;
                        case M88E1000_PHY_SPEC_CTRL:
                        case M88E1000_EXT_PHY_SPEC_CTRL:
-                               if (e1000_phy_reset(&adapter->hw)) {
-                                       spin_unlock_irqrestore(
-                                               &adapter->stats_lock, flags);
+                               if (e1000_phy_reset(&adapter->hw))
                                        return -EIO;
-                               }
                                break;
                        }
                } else {
@@ -4857,7 +4851,6 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                                break;
                        }
                }
-               spin_unlock_irqrestore(&adapter->stats_lock, flags);
                break;
        default:
                return -EOPNOTSUPP;
index 2765e49e07df121982e8c4ebe5bc4f0bff2f28b8..562ea68ed99b3f2f4c00d0e69e8e10640a0c6b88 100644 (file)
@@ -2,6 +2,7 @@ config FS_ENET
        tristate "Freescale Ethernet Driver"
        depends on CPM1 || CPM2
        select MII
+       select PHYLIB
 
 config FS_ENET_HAS_SCC
        bool "Chip has an SCC usable for ethernet"
@@ -11,11 +12,19 @@ config FS_ENET_HAS_SCC
 config FS_ENET_HAS_FCC
        bool "Chip has an FCC usable for ethernet"
        depends on FS_ENET && CPM2
-       select MDIO_BITBANG
        default y
 
 config FS_ENET_HAS_FEC
        bool "Chip has an FEC usable for ethernet"
        depends on FS_ENET && CPM1
+       select FS_ENET_MDIO_FEC
        default y
 
+config FS_ENET_MDIO_FEC
+       tristate "MDIO driver for FEC"
+       depends on FS_ENET && CPM1
+
+config FS_ENET_MDIO_FCC
+       tristate "MDIO driver for FCC"
+       depends on FS_ENET && CPM2
+       select MDIO_BITBANG
index 02d4dc18ba693c0f7daa0c3d0a2edc478a0a5241..1ffbe0756a0c6bde820e736b4e5ae424ffbace70 100644 (file)
@@ -4,7 +4,16 @@
 
 obj-$(CONFIG_FS_ENET) += fs_enet.o
 
-obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o mii-fec.o
-obj-$(CONFIG_CPM2) += mac-fcc.o mii-bitbang.o
+fs_enet-$(CONFIG_FS_ENET_HAS_SCC) += mac-scc.o
+fs_enet-$(CONFIG_FS_ENET_HAS_FEC) += mac-fec.o
+fs_enet-$(CONFIG_FS_ENET_HAS_FCC) += mac-fcc.o
 
-fs_enet-objs := fs_enet-main.o
+ifeq ($(CONFIG_PPC_CPM_NEW_BINDING),y)
+obj-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
+obj-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
+else
+fs_enet-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
+fs_enet-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
+endif
+
+fs_enet-objs := fs_enet-main.o $(fs_enet-m)
index e0119f6a3319b2fca40af251d7bd3bf09dcde038..580cb4ab2af10042fccc2d94e5fad7448944cac1 100644 (file)
@@ -762,26 +762,20 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
 
                if (copy_from_user(&addr,
                                   (void __user *) arg, AX25_ADDR_LEN)) {
-                       err = -EFAULT;
-                       break;
-               }
+                               err = -EFAULT;
+                               break;
+                       }
 
-               netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
-               netif_tx_unlock_bh(dev);
+                       netif_tx_lock_bh(dev);
+                       memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+                       netif_tx_unlock_bh(dev);
 
-               err = 0;
-               break;
-       }
-
-       /* Allow stty to read, but not set, the serial port */
-       case TCGETS:
-       case TCGETA:
-               err = n_tty_ioctl(tty, (struct file *) file, cmd, arg);
-               break;
+                       err = 0;
+                       break;
+               }
 
        default:
-               err = -ENOIOCTLCMD;
+               err = tty_mode_ioctl(tty, file, cmd, arg);
        }
 
        sp_put(sp);
index 2c6f7be36e8aa8eb9d712c44fd7c84be92b9530a..fc753d7f674e41b0a231ac45663806c7b84ab06a 100644 (file)
@@ -434,11 +434,6 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
        IRDA_ASSERT(dev != NULL, return -1;);
 
        switch (cmd) {
-       case TCGETS:
-       case TCGETA:
-               err = n_tty_ioctl(tty, file, cmd, arg);
-               break;
-
        case IRTTY_IOCTDONGLE:
                /* this call blocks for completion */
                err = sirdev_set_dongle(dev, (IRDA_DONGLE) arg);
@@ -454,7 +449,7 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
                        err = -EFAULT;
                break;
        default:
-               err = -ENOIOCTLCMD;
+               err = tty_mode_ioctl(tty, file, cmd, arg);
                break;
        }
        return err;
index 45f30a2974b8f49405ec5ab07e4e605c6be60cb8..662b8d16803ce7fec85f59af645b60aabee75c41 100644 (file)
@@ -284,7 +284,7 @@ static __net_exit void loopback_net_exit(struct net *net)
        unregister_netdev(dev);
 }
 
-static struct pernet_operations loopback_net_ops = {
+static struct pernet_operations __net_initdata loopback_net_ops = {
        .init = loopback_net_init,
        .exit = loopback_net_exit,
 };
index f8d63d39f59246bc80da046ee72963e2303c8644..b226e019bc8b70ab18fee4d8a8c6f6540f40711e 100644 (file)
@@ -171,9 +171,10 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf)
                                  buf->u.direct.map);
        else {
                for (i = 0; i < buf->nbufs; ++i)
-                       dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
-                                         buf->u.page_list[i].buf,
-                                         buf->u.page_list[i].map);
+                       if (buf->u.page_list[i].buf)
+                               dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+                                                 buf->u.page_list[i].buf,
+                                                 buf->u.page_list[i].map);
                kfree(buf->u.page_list);
        }
 }
index cc4b1be182196c8b11836def9387215272d4bba8..42b47639c81cb6f4753ea728bd86d81d060c5792 100644 (file)
@@ -240,7 +240,7 @@ void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
        mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
        mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
 
-       if (qp->qpn < dev->caps.sqp_start + 8)
+       if (qp->qpn >= dev->caps.sqp_start + 8)
                mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_free);
index 8d29319cc5cb39b88b3f13a37cb017bf28b595b2..656a260fc956b1cf52912da2b3c8aa108d7154c9 100644 (file)
@@ -134,7 +134,7 @@ static int myri_do_handshake(struct myri_eth *mp)
 
        myri_disable_irq(mp->lregs, cregs);
 
-       while (tick++ <= 25) {
+       while (tick++ < 25) {
                u32 softstate;
 
                /* Wake it up. */
index eb0aff787dfda8e5c910c45f752d4bb07c82eef4..5267e031daa0b3ab27d3d1dde092cb2fdc8e6159 100644 (file)
@@ -128,8 +128,8 @@ netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                   FIFO_PTR_FRAMELEN(len));
 
        ndev->trans_start = jiffies;
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += skb->len;
+       ndev->stats.tx_packets++;
+       ndev->stats.tx_bytes += skb->len;
 
        netif_stop_queue(ndev);
        spin_unlock_irq(&priv->lock);
@@ -155,7 +155,7 @@ static void netx_eth_receive(struct net_device *ndev)
        if (unlikely(skb == NULL)) {
                printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
                        ndev->name);
-               dev->stats.rx_dropped++;
+               ndev->stats.rx_dropped++;
                return;
        }
 
index ab4d309a858fab572782a534b334d4a8b35babf4..09b4fde8d924978d05a63d8e57b834dea02ecea9 100644 (file)
@@ -580,6 +580,16 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
 
+               pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
+
+               if (macrx & XCT_MACRX_CRC) {
+                       /* CRC error flagged */
+                       mac->netdev->stats.rx_errors++;
+                       mac->netdev->stats.rx_crc_errors++;
+                       dev_kfree_skb_irq(skb);
+                       goto next;
+               }
+
                if (len < 256) {
                        struct sk_buff *new_skb;
 
@@ -595,11 +605,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                } else
                        info->skb = NULL;
 
-               pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
-
                info->dma = 0;
 
-               skb_put(skb, len);
+               /* Don't include CRC */
+               skb_put(skb, len-4);
 
                if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -614,6 +623,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                skb->protocol = eth_type_trans(skb, mac->netdev);
                netif_receive_skb(skb);
 
+next:
                RX_RING(mac, n) = 0;
                RX_RING(mac, n+1) = 0;
 
@@ -1126,7 +1136,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
        int i, nfrags;
 
-       dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
+       dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                const unsigned char *nh = skb_network_header(skb);
index d2ede5ff9fffc5e70136207738c7fada30ca31e4..035fd41fb61f01408517d7fef176b8e42f8173d7 100644 (file)
@@ -265,7 +265,7 @@ static struct phy_driver marvell_drivers[] = {
                .read_status = &genphy_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
-               .driver = {.owner = THIS_MODULE,},
+               .driver = { .owner = THIS_MODULE },
        },
        {
                .phy_id = 0x01410c90,
@@ -278,7 +278,7 @@ static struct phy_driver marvell_drivers[] = {
                .read_status = &genphy_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
-               .driver = {.owner = THIS_MODULE,},
+               .driver = { .owner = THIS_MODULE },
        },
        {
                .phy_id = 0x01410cc0,
@@ -291,7 +291,7 @@ static struct phy_driver marvell_drivers[] = {
                .read_status = &genphy_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
-               .driver = {.owner = THIS_MODULE,},
+               .driver = { .owner = THIS_MODULE },
        },
        {
                .phy_id = 0x01410cd0,
@@ -304,8 +304,21 @@ static struct phy_driver marvell_drivers[] = {
                .read_status = &genphy_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
-               .driver = {.owner = THIS_MODULE,},
-       }
+               .driver = { .owner = THIS_MODULE },
+       },
+       {
+               .phy_id = 0x01410e30,
+               .phy_id_mask = 0xfffffff0,
+               .name = "Marvell 88E1240",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_init = &m88e1111_config_init,
+               .config_aneg = &marvell_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = { .owner = THIS_MODULE },
+       },
 };
 
 static int __init marvell_init(void)
index c0461217b1084e9ed1264ee82b357cc770ce6321..f6e484812a98f73df8541aebd6835fe11ff54196 100644 (file)
@@ -706,7 +706,7 @@ int phy_driver_register(struct phy_driver *new_driver)
                return retval;
        }
 
-       pr_info("%s: Registered new driver\n", new_driver->name);
+       pr_debug("%s: Registered new driver\n", new_driver->name);
 
        return 0;
 }
index 27f5b904f48ec403f2008a27a1e292f98a8d211f..f023d5b67e6efcc38d1673ef56b9de8536371392 100644 (file)
@@ -160,7 +160,7 @@ ppp_asynctty_open(struct tty_struct *tty)
 
        err = -ENOMEM;
        ap = kzalloc(sizeof(*ap), GFP_KERNEL);
-       if (ap == 0)
+       if (!ap)
                goto out;
 
        /* initialize the asyncppp structure */
@@ -215,7 +215,7 @@ ppp_asynctty_close(struct tty_struct *tty)
        ap = tty->disc_data;
        tty->disc_data = NULL;
        write_unlock_irq(&disc_data_lock);
-       if (ap == 0)
+       if (!ap)
                return;
 
        /*
@@ -230,10 +230,10 @@ ppp_asynctty_close(struct tty_struct *tty)
        tasklet_kill(&ap->tsk);
 
        ppp_unregister_channel(&ap->chan);
-       if (ap->rpkt != 0)
+       if (ap->rpkt)
                kfree_skb(ap->rpkt);
        skb_queue_purge(&ap->rqueue);
-       if (ap->tpkt != 0)
+       if (ap->tpkt)
                kfree_skb(ap->tpkt);
        kfree(ap);
 }
@@ -285,13 +285,13 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
        int err, val;
        int __user *p = (int __user *)arg;
 
-       if (ap == 0)
+       if (!ap)
                return -ENXIO;
        err = -EFAULT;
        switch (cmd) {
        case PPPIOCGCHAN:
                err = -ENXIO;
-               if (ap == 0)
+               if (!ap)
                        break;
                err = -EFAULT;
                if (put_user(ppp_channel_index(&ap->chan), p))
@@ -301,7 +301,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
 
        case PPPIOCGUNIT:
                err = -ENXIO;
-               if (ap == 0)
+               if (!ap)
                        break;
                err = -EFAULT;
                if (put_user(ppp_unit_number(&ap->chan), p))
@@ -309,16 +309,11 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
                err = 0;
                break;
 
-       case TCGETS:
-       case TCGETA:
-               err = n_tty_ioctl(tty, file, cmd, arg);
-               break;
-
        case TCFLSH:
                /* flush our buffers and the serial port's buffer */
                if (arg == TCIOFLUSH || arg == TCOFLUSH)
                        ppp_async_flush_output(ap);
-               err = n_tty_ioctl(tty, file, cmd, arg);
+               err = tty_perform_flush(tty, arg);
                break;
 
        case FIONREAD:
@@ -329,7 +324,8 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
                break;
 
        default:
-               err = -ENOIOCTLCMD;
+               /* Try the various mode ioctls */
+               err = tty_mode_ioctl(tty, file, cmd, arg);
        }
 
        ap_put(ap);
@@ -354,7 +350,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
        struct asyncppp *ap = ap_get(tty);
        unsigned long flags;
 
-       if (ap == 0)
+       if (!ap)
                return;
        spin_lock_irqsave(&ap->recv_lock, flags);
        ppp_async_input(ap, buf, cflags, count);
@@ -373,7 +369,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
        struct asyncppp *ap = ap_get(tty);
 
        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       if (ap == 0)
+       if (!ap)
                return;
        set_bit(XMIT_WAKEUP, &ap->xmit_flags);
        tasklet_schedule(&ap->tsk);
@@ -688,7 +684,7 @@ ppp_async_push(struct asyncppp *ap)
                                tty_stuffed = 1;
                        continue;
                }
-               if (ap->optr >= ap->olim && ap->tpkt != 0) {
+               if (ap->optr >= ap->olim && ap->tpkt) {
                        if (ppp_async_encode(ap)) {
                                /* finished processing ap->tpkt */
                                clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -708,7 +704,7 @@ ppp_async_push(struct asyncppp *ap)
                clear_bit(XMIT_BUSY, &ap->xmit_flags);
                /* any more work to do? if not, exit the loop */
                if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-                     || (!tty_stuffed && ap->tpkt != 0)))
+                     || (!tty_stuffed && ap->tpkt)))
                        break;
                /* more work to do, see if we can do it now */
                if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
@@ -719,7 +715,7 @@ ppp_async_push(struct asyncppp *ap)
 
 flush:
        clear_bit(XMIT_BUSY, &ap->xmit_flags);
-       if (ap->tpkt != 0) {
+       if (ap->tpkt) {
                kfree_skb(ap->tpkt);
                ap->tpkt = NULL;
                clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -852,7 +848,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                s = 0;
                for (i = 0; i < count; ++i) {
                        c = buf[i];
-                       if (flags != 0 && flags[i] != 0)
+                       if (flags && flags[i] != 0)
                                continue;
                        s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0;
                        c = ((c >> 4) ^ c) & 0xf;
@@ -869,7 +865,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                        n = scan_ordinary(ap, buf, count);
 
                f = 0;
-               if (flags != 0 && (ap->state & SC_TOSS) == 0) {
+               if (flags && (ap->state & SC_TOSS) == 0) {
                        /* check the flags to see if any char had an error */
                        for (j = 0; j < n; ++j)
                                if ((f = flags[j]) != 0)
@@ -882,9 +878,9 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                } else if (n > 0 && (ap->state & SC_TOSS) == 0) {
                        /* stuff the chars in the skb */
                        skb = ap->rpkt;
-                       if (skb == 0) {
+                       if (!skb) {
                                skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
-                               if (skb == 0)
+                               if (!skb)
                                        goto nomem;
                                ap->rpkt = skb;
                        }
@@ -931,7 +927,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                ++n;
 
                buf += n;
-               if (flags != 0)
+               if (flags)
                        flags += n;
                count -= n;
        }
index 4b49d0e8c7ebcf911a7ebe55fb53529e32692782..4f690378bb77119f58eb3c18bbfb7ecf88fbf004 100644 (file)
@@ -367,7 +367,7 @@ static int ppp_release(struct inode *inode, struct file *file)
        struct ppp_file *pf = file->private_data;
        struct ppp *ppp;
 
-       if (pf != 0) {
+       if (pf) {
                file->private_data = NULL;
                if (pf->kind == INTERFACE) {
                        ppp = PF_TO_PPP(pf);
@@ -398,7 +398,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
 
        ret = count;
 
-       if (pf == 0)
+       if (!pf)
                return -ENXIO;
        add_wait_queue(&pf->rwait, &wait);
        for (;;) {
@@ -431,7 +431,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&pf->rwait, &wait);
 
-       if (skb == 0)
+       if (!skb)
                goto out;
 
        ret = -EOVERFLOW;
@@ -455,11 +455,11 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
        struct sk_buff *skb;
        ssize_t ret;
 
-       if (pf == 0)
+       if (!pf)
                return -ENXIO;
        ret = -ENOMEM;
        skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL);
-       if (skb == 0)
+       if (!skb)
                goto out;
        skb_reserve(skb, pf->hdrlen);
        ret = -EFAULT;
@@ -491,11 +491,11 @@ static unsigned int ppp_poll(struct file *file, poll_table *wait)
        struct ppp_file *pf = file->private_data;
        unsigned int mask;
 
-       if (pf == 0)
+       if (!pf)
                return 0;
        poll_wait(file, &pf->rwait, wait);
        mask = POLLOUT | POLLWRNORM;
-       if (skb_peek(&pf->rq) != 0)
+       if (skb_peek(&pf->rq))
                mask |= POLLIN | POLLRDNORM;
        if (pf->dead)
                mask |= POLLHUP;
@@ -559,7 +559,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
 
-       if (pf == 0)
+       if (!pf)
                return ppp_unattached_ioctl(pf, file, cmd, arg);
 
        if (cmd == PPPIOCDETACH) {
@@ -689,13 +689,13 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
                        val &= 0xffff;
                }
                vj = slhc_init(val2+1, val+1);
-               if (vj == 0) {
+               if (!vj) {
                        printk(KERN_ERR "PPP: no memory (VJ compressor)\n");
                        err = -ENOMEM;
                        break;
                }
                ppp_lock(ppp);
-               if (ppp->vj != 0)
+               if (ppp->vj)
                        slhc_free(ppp->vj);
                ppp->vj = vj;
                ppp_unlock(ppp);
@@ -786,7 +786,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
                if (get_user(unit, p))
                        break;
                ppp = ppp_create_interface(unit, &err);
-               if (ppp == 0)
+               if (!ppp)
                        break;
                file->private_data = &ppp->file;
                ppp->owner = file;
@@ -803,7 +803,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
                mutex_lock(&all_ppp_mutex);
                err = -ENXIO;
                ppp = ppp_find_unit(unit);
-               if (ppp != 0) {
+               if (ppp) {
                        atomic_inc(&ppp->file.refcnt);
                        file->private_data = &ppp->file;
                        err = 0;
@@ -817,7 +817,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
                spin_lock_bh(&all_channels_lock);
                err = -ENXIO;
                chan = ppp_find_channel(unit);
-               if (chan != 0) {
+               if (chan) {
                        atomic_inc(&chan->file.refcnt);
                        file->private_data = &chan->file;
                        err = 0;
@@ -946,9 +946,9 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        case SIOCGPPPCSTATS:
                memset(&cstats, 0, sizeof(cstats));
-               if (ppp->xc_state != 0)
+               if (ppp->xc_state)
                        ppp->xcomp->comp_stat(ppp->xc_state, &cstats.c);
-               if (ppp->rc_state != 0)
+               if (ppp->rc_state)
                        ppp->rcomp->decomp_stat(ppp->rc_state, &cstats.d);
                if (copy_to_user(addr, &cstats, sizeof(cstats)))
                        break;
@@ -993,14 +993,14 @@ ppp_xmit_process(struct ppp *ppp)
        struct sk_buff *skb;
 
        ppp_xmit_lock(ppp);
-       if (ppp->dev != 0) {
+       if (ppp->dev) {
                ppp_push(ppp);
-               while (ppp->xmit_pending == 0
-                      && (skb = skb_dequeue(&ppp->file.xq)) != 0)
+               while (!ppp->xmit_pending
+                      && (skb = skb_dequeue(&ppp->file.xq)))
                        ppp_send_frame(ppp, skb);
                /* If there's no work left to do, tell the core net
                   code that we can accept some more. */
-               if (ppp->xmit_pending == 0 && skb_peek(&ppp->file.xq) == 0)
+               if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
                        netif_wake_queue(ppp->dev);
        }
        ppp_xmit_unlock(ppp);
@@ -1100,12 +1100,12 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
 
        switch (proto) {
        case PPP_IP:
-               if (ppp->vj == 0 || (ppp->flags & SC_COMP_TCP) == 0)
+               if (!ppp->vj || (ppp->flags & SC_COMP_TCP) == 0)
                        break;
                /* try to do VJ TCP header compression */
                new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2,
                                    GFP_ATOMIC);
-               if (new_skb == 0) {
+               if (!new_skb) {
                        printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n");
                        goto drop;
                }
@@ -1140,7 +1140,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
        }
 
        /* try to do packet compression */
-       if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
+       if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state
            && proto != PPP_LCP && proto != PPP_CCP) {
                if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
                        if (net_ratelimit())
@@ -1185,7 +1185,7 @@ ppp_push(struct ppp *ppp)
        struct channel *pch;
        struct sk_buff *skb = ppp->xmit_pending;
 
-       if (skb == 0)
+       if (!skb)
                return;
 
        list = &ppp->channels;
@@ -1355,7 +1355,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                if (flen == len && nfree == 0)
                        bits |= E;
                frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
-               if (frag == 0)
+               if (!frag)
                        goto noskb;
                q = skb_put(frag, flen + hdrlen);
 
@@ -1425,7 +1425,7 @@ ppp_channel_push(struct channel *pch)
        struct ppp *ppp;
 
        spin_lock_bh(&pch->downl);
-       if (pch->chan != 0) {
+       if (pch->chan) {
                while (!skb_queue_empty(&pch->file.xq)) {
                        skb = skb_dequeue(&pch->file.xq);
                        if (!pch->chan->ops->start_xmit(pch->chan, skb)) {
@@ -1443,7 +1443,7 @@ ppp_channel_push(struct channel *pch)
        if (skb_queue_empty(&pch->file.xq)) {
                read_lock_bh(&pch->upl);
                ppp = pch->ppp;
-               if (ppp != 0)
+               if (ppp)
                        ppp_xmit_process(ppp);
                read_unlock_bh(&pch->upl);
        }
@@ -1462,7 +1462,7 @@ ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
        ppp_recv_lock(ppp);
        /* ppp->dev == 0 means interface is closing down */
-       if (ppp->dev != 0)
+       if (ppp->dev)
                ppp_receive_frame(ppp, skb, pch);
        else
                kfree_skb(skb);
@@ -1475,19 +1475,19 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        struct channel *pch = chan->ppp;
        int proto;
 
-       if (pch == 0 || skb->len == 0) {
+       if (!pch || skb->len == 0) {
                kfree_skb(skb);
                return;
        }
 
        proto = PPP_PROTO(skb);
        read_lock_bh(&pch->upl);
-       if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) {
+       if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
                /* put it on the channel queue */
                skb_queue_tail(&pch->file.rq, skb);
                /* drop old frames if queue too long */
                while (pch->file.rq.qlen > PPP_MAX_RQLEN
-                      && (skb = skb_dequeue(&pch->file.rq)) != 0)
+                      && (skb = skb_dequeue(&pch->file.rq)))
                        kfree_skb(skb);
                wake_up_interruptible(&pch->file.rwait);
        } else {
@@ -1503,13 +1503,13 @@ ppp_input_error(struct ppp_channel *chan, int code)
        struct channel *pch = chan->ppp;
        struct sk_buff *skb;
 
-       if (pch == 0)
+       if (!pch)
                return;
 
        read_lock_bh(&pch->upl);
-       if (pch->ppp != 0) {
+       if (pch->ppp) {
                skb = alloc_skb(0, GFP_ATOMIC);
-               if (skb != 0) {
+               if (skb) {
                        skb->len = 0;           /* probably unnecessary */
                        skb->cb[0] = code;
                        ppp_do_recv(pch->ppp, skb, pch);
@@ -1548,7 +1548,7 @@ static void
 ppp_receive_error(struct ppp *ppp)
 {
        ++ppp->stats.rx_errors;
-       if (ppp->vj != 0)
+       if (ppp->vj)
                slhc_toss(ppp->vj);
 }
 
@@ -1563,7 +1563,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
         * Note that some decompressors need to see uncompressed frames
         * that come in as well as compressed frames.
         */
-       if (ppp->rc_state != 0 && (ppp->rstate & SC_DECOMP_RUN)
+       if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)
            && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
                skb = ppp_decompress_frame(ppp, skb);
 
@@ -1574,13 +1574,13 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
        switch (proto) {
        case PPP_VJC_COMP:
                /* decompress VJ compressed packets */
-               if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
+               if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
                        goto err;
 
                if (skb_tailroom(skb) < 124 || skb_cloned(skb)) {
                        /* copy to a new sk_buff with more tailroom */
                        ns = dev_alloc_skb(skb->len + 128);
-                       if (ns == 0) {
+                       if (!ns) {
                                printk(KERN_ERR"PPP: no memory (VJ decomp)\n");
                                goto err;
                        }
@@ -1606,7 +1606,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                break;
 
        case PPP_VJC_UNCOMP:
-               if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
+               if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
                        goto err;
 
                /* Until we fix the decompressor need to make sure
@@ -1636,7 +1636,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                skb_queue_tail(&ppp->file.rq, skb);
                /* limit queue length by dropping old frames */
                while (ppp->file.rq.qlen > PPP_MAX_RQLEN
-                      && (skb = skb_dequeue(&ppp->file.rq)) != 0)
+                      && (skb = skb_dequeue(&ppp->file.rq)))
                        kfree_skb(skb);
                /* wake up any process polling or blocking on read */
                wake_up_interruptible(&ppp->file.rwait);
@@ -1718,7 +1718,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb)
                }
 
                ns = dev_alloc_skb(obuff_size);
-               if (ns == 0) {
+               if (!ns) {
                        printk(KERN_ERR "ppp_decompress_frame: no memory\n");
                        goto err;
                }
@@ -1836,7 +1836,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
                ppp->minseq = ppp->mrq.next->sequence;
 
        /* Pull completed packets off the queue and receive them. */
-       while ((skb = ppp_mp_reconstruct(ppp)) != 0)
+       while ((skb = ppp_mp_reconstruct(ppp)))
                ppp_receive_nonmp_frame(ppp, skb);
 
        return;
@@ -2002,7 +2002,7 @@ ppp_register_channel(struct ppp_channel *chan)
        struct channel *pch;
 
        pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
-       if (pch == 0)
+       if (!pch)
                return -ENOMEM;
        pch->ppp = NULL;
        pch->chan = chan;
@@ -2030,7 +2030,7 @@ int ppp_channel_index(struct ppp_channel *chan)
 {
        struct channel *pch = chan->ppp;
 
-       if (pch != 0)
+       if (pch)
                return pch->file.index;
        return -1;
 }
@@ -2043,9 +2043,9 @@ int ppp_unit_number(struct ppp_channel *chan)
        struct channel *pch = chan->ppp;
        int unit = -1;
 
-       if (pch != 0) {
+       if (pch) {
                read_lock_bh(&pch->upl);
-               if (pch->ppp != 0)
+               if (pch->ppp)
                        unit = pch->ppp->file.index;
                read_unlock_bh(&pch->upl);
        }
@@ -2061,7 +2061,7 @@ ppp_unregister_channel(struct ppp_channel *chan)
 {
        struct channel *pch = chan->ppp;
 
-       if (pch == 0)
+       if (!pch)
                return;         /* should never happen */
        chan->ppp = NULL;
 
@@ -2093,7 +2093,7 @@ ppp_output_wakeup(struct ppp_channel *chan)
 {
        struct channel *pch = chan->ppp;
 
-       if (pch == 0)
+       if (!pch)
                return;
        ppp_channel_push(pch);
 }
@@ -2124,18 +2124,18 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 
        cp = find_compressor(ccp_option[0]);
 #ifdef CONFIG_KMOD
-       if (cp == 0) {
+       if (!cp) {
                request_module("ppp-compress-%d", ccp_option[0]);
                cp = find_compressor(ccp_option[0]);
        }
 #endif /* CONFIG_KMOD */
-       if (cp == 0)
+       if (!cp)
                goto out;
 
        err = -ENOBUFS;
        if (data.transmit) {
                state = cp->comp_alloc(ccp_option, data.length);
-               if (state != 0) {
+               if (state) {
                        ppp_xmit_lock(ppp);
                        ppp->xstate &= ~SC_COMP_RUN;
                        ocomp = ppp->xcomp;
@@ -2143,7 +2143,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
                        ppp->xcomp = cp;
                        ppp->xc_state = state;
                        ppp_xmit_unlock(ppp);
-                       if (ostate != 0) {
+                       if (ostate) {
                                ocomp->comp_free(ostate);
                                module_put(ocomp->owner);
                        }
@@ -2153,7 +2153,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 
        } else {
                state = cp->decomp_alloc(ccp_option, data.length);
-               if (state != 0) {
+               if (state) {
                        ppp_recv_lock(ppp);
                        ppp->rstate &= ~SC_DECOMP_RUN;
                        ocomp = ppp->rcomp;
@@ -2161,7 +2161,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
                        ppp->rcomp = cp;
                        ppp->rc_state = state;
                        ppp_recv_unlock(ppp);
-                       if (ostate != 0) {
+                       if (ostate) {
                                ocomp->decomp_free(ostate);
                                module_put(ocomp->owner);
                        }
@@ -2228,7 +2228,7 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
                        break;
                if (inbound) {
                        /* we will start receiving compressed packets */
-                       if (ppp->rc_state == 0)
+                       if (!ppp->rc_state)
                                break;
                        if (ppp->rcomp->decomp_init(ppp->rc_state, dp, len,
                                        ppp->file.index, 0, ppp->mru, ppp->debug)) {
@@ -2237,7 +2237,7 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
                        }
                } else {
                        /* we will soon start sending compressed packets */
-                       if (ppp->xc_state == 0)
+                       if (!ppp->xc_state)
                                break;
                        if (ppp->xcomp->comp_init(ppp->xc_state, dp, len,
                                        ppp->file.index, 0, ppp->debug))
@@ -2320,11 +2320,11 @@ ppp_register_compressor(struct compressor *cp)
        int ret;
        spin_lock(&compressor_list_lock);
        ret = -EEXIST;
-       if (find_comp_entry(cp->compress_proto) != 0)
+       if (find_comp_entry(cp->compress_proto))
                goto out;
        ret = -ENOMEM;
        ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC);
-       if (ce == 0)
+       if (!ce)
                goto out;
        ret = 0;
        ce->comp = cp;
@@ -2342,7 +2342,7 @@ ppp_unregister_compressor(struct compressor *cp)
 
        spin_lock(&compressor_list_lock);
        ce = find_comp_entry(cp->compress_proto);
-       if (ce != 0 && ce->comp == cp) {
+       if (ce && ce->comp == cp) {
                list_del(&ce->list);
                kfree(ce);
        }
@@ -2358,7 +2358,7 @@ find_compressor(int type)
 
        spin_lock(&compressor_list_lock);
        ce = find_comp_entry(type);
-       if (ce != 0) {
+       if (ce) {
                cp = ce->comp;
                if (!try_module_get(cp->owner))
                        cp = NULL;
@@ -2383,7 +2383,7 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
        st->p.ppp_opackets = ppp->stats.tx_packets;
        st->p.ppp_oerrors = ppp->stats.tx_errors;
        st->p.ppp_obytes = ppp->stats.tx_bytes;
-       if (vj == 0)
+       if (!vj)
                return;
        st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;
        st->vj.vjs_compressed = vj->sls_o_compressed;
@@ -2604,11 +2604,11 @@ ppp_connect_channel(struct channel *pch, int unit)
 
        mutex_lock(&all_ppp_mutex);
        ppp = ppp_find_unit(unit);
-       if (ppp == 0)
+       if (!ppp)
                goto out;
        write_lock_bh(&pch->upl);
        ret = -EINVAL;
-       if (pch->ppp != 0)
+       if (pch->ppp)
                goto outl;
 
        ppp_lock(ppp);
@@ -2644,7 +2644,7 @@ ppp_disconnect_channel(struct channel *pch)
        ppp = pch->ppp;
        pch->ppp = NULL;
        write_unlock_bh(&pch->upl);
-       if (ppp != 0) {
+       if (ppp) {
                /* remove it from the ppp unit's list */
                ppp_lock(ppp);
                list_del(&pch->clist);
index ce64032a465af512dae7b961ce80f1cc2203a4de..f0c6a1926a02970c9a5573f97276c217d87157bb 100644 (file)
@@ -209,7 +209,7 @@ ppp_sync_open(struct tty_struct *tty)
 
        ap = kzalloc(sizeof(*ap), GFP_KERNEL);
        err = -ENOMEM;
-       if (ap == 0)
+       if (!ap)
                goto out;
 
        /* initialize the syncppp structure */
@@ -262,7 +262,7 @@ ppp_sync_close(struct tty_struct *tty)
        ap = tty->disc_data;
        tty->disc_data = NULL;
        write_unlock_irq(&disc_data_lock);
-       if (ap == 0)
+       if (!ap)
                return;
 
        /*
@@ -278,7 +278,7 @@ ppp_sync_close(struct tty_struct *tty)
 
        ppp_unregister_channel(&ap->chan);
        skb_queue_purge(&ap->rqueue);
-       if (ap->tpkt != 0)
+       if (ap->tpkt)
                kfree_skb(ap->tpkt);
        kfree(ap);
 }
@@ -325,13 +325,13 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
        int __user *p = (int __user *)arg;
        int err, val;
 
-       if (ap == 0)
+       if (!ap)
                return -ENXIO;
        err = -EFAULT;
        switch (cmd) {
        case PPPIOCGCHAN:
                err = -ENXIO;
-               if (ap == 0)
+               if (!ap)
                        break;
                err = -EFAULT;
                if (put_user(ppp_channel_index(&ap->chan), p))
@@ -341,7 +341,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
 
        case PPPIOCGUNIT:
                err = -ENXIO;
-               if (ap == 0)
+               if (!ap)
                        break;
                err = -EFAULT;
                if (put_user(ppp_unit_number(&ap->chan), p))
@@ -349,16 +349,11 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
                err = 0;
                break;
 
-       case TCGETS:
-       case TCGETA:
-               err = n_tty_ioctl(tty, file, cmd, arg);
-               break;
-
        case TCFLSH:
                /* flush our buffers and the serial port's buffer */
                if (arg == TCIOFLUSH || arg == TCOFLUSH)
                        ppp_sync_flush_output(ap);
-               err = n_tty_ioctl(tty, file, cmd, arg);
+               err = tty_perform_flush(tty, arg);
                break;
 
        case FIONREAD:
@@ -369,7 +364,8 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
                break;
 
        default:
-               err = -ENOIOCTLCMD;
+               err = tty_mode_ioctl(tty, file, cmd, arg);
+               break;
        }
 
        sp_put(ap);
@@ -394,7 +390,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
        struct syncppp *ap = sp_get(tty);
        unsigned long flags;
 
-       if (ap == 0)
+       if (!ap)
                return;
        spin_lock_irqsave(&ap->recv_lock, flags);
        ppp_sync_input(ap, buf, cflags, count);
@@ -413,7 +409,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
        struct syncppp *ap = sp_get(tty);
 
        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       if (ap == 0)
+       if (!ap)
                return;
        set_bit(XMIT_WAKEUP, &ap->xmit_flags);
        tasklet_schedule(&ap->tsk);
@@ -655,7 +651,7 @@ ppp_sync_push(struct syncppp *ap)
        for (;;) {
                if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))
                        tty_stuffed = 0;
-               if (!tty_stuffed && ap->tpkt != 0) {
+               if (!tty_stuffed && ap->tpkt) {
                        set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
                        sent = tty->driver->write(tty, ap->tpkt->data, ap->tpkt->len);
                        if (sent < 0)
@@ -673,7 +669,7 @@ ppp_sync_push(struct syncppp *ap)
                /* haven't made any progress */
                spin_unlock_bh(&ap->xmit_lock);
                if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-                     || (!tty_stuffed && ap->tpkt != 0)))
+                     || (!tty_stuffed && ap->tpkt)))
                        break;
                if (!spin_trylock_bh(&ap->xmit_lock))
                        break;
@@ -681,7 +677,7 @@ ppp_sync_push(struct syncppp *ap)
        return done;
 
 flush:
-       if (ap->tpkt != 0) {
+       if (ap->tpkt) {
                kfree_skb(ap->tpkt);
                ap->tpkt = NULL;
                clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -736,7 +732,8 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
                ppp_print_buffer ("receive buffer", buf, count);
 
        /* stuff the chars in the skb */
-       if ((skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2)) == 0) {
+       skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
+       if (!skb) {
                printk(KERN_ERR "PPPsync: no memory (input pkt)\n");
                goto err;
        }
@@ -744,7 +741,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
        if (buf[0] != PPP_ALLSTATIONS)
                skb_reserve(skb, 2 + (buf[0] & 1));
 
-       if (flags != 0 && *flags) {
+       if (flags && *flags) {
                /* error flag set, ignore frame */
                goto err;
        } else if (count > skb_tailroom(skb)) {
index f8904fd92369be8ee2ded044f8c55856f31960ac..a7556cd2df7939cbfd37fb3c1e57e8c9e82632dc 100644 (file)
@@ -488,7 +488,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
 {
        struct pppol2tp_session *session = NULL;
        struct pppol2tp_tunnel *tunnel;
-       unsigned char *ptr;
+       unsigned char *ptr, *optr;
        u16 hdrflags;
        u16 tunnel_id, session_id;
        int length;
@@ -496,7 +496,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
 
        tunnel = pppol2tp_sock_to_tunnel(sock);
        if (tunnel == NULL)
-               goto error;
+               goto no_tunnel;
 
        /* UDP always verifies the packet length. */
        __skb_pull(skb, sizeof(struct udphdr));
@@ -509,7 +509,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
        }
 
        /* Point to L2TP header */
-       ptr = skb->data;
+       optr = ptr = skb->data;
 
        /* Get L2TP header flags */
        hdrflags = ntohs(*(__be16*)ptr);
@@ -637,12 +637,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
        /* If offset bit set, skip it. */
        if (hdrflags & L2TP_HDRFLAG_O) {
                offset = ntohs(*(__be16 *)ptr);
-               skb->transport_header += 2 + offset;
-               if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2))
-                       goto discard;
+               ptr += 2 + offset;
        }
 
-       __skb_pull(skb, skb_transport_offset(skb));
+       offset = ptr - optr;
+       if (!pskb_may_pull(skb, offset))
+               goto discard;
+
+       __skb_pull(skb, offset);
 
        /* Skip PPP header, if present.  In testing, Microsoft L2TP clients
         * don't send the PPP header (PPP header compression enabled), but
@@ -652,6 +654,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
         * Note that skb->data[] isn't dereferenced from a u16 ptr here since
         * the field may be unaligned.
         */
+       if (!pskb_may_pull(skb, 2))
+               goto discard;
+
        if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03))
                skb_pull(skb, 2);
 
@@ -709,6 +714,10 @@ discard:
        return 0;
 
 error:
+       /* Put UDP header back */
+       __skb_push(skb, sizeof(struct udphdr));
+
+no_tunnel:
        return 1;
 }
 
@@ -1050,6 +1059,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        /* Get routing info from the tunnel socket */
        dst_release(skb->dst);
        skb->dst = sk_dst_get(sk_tun);
+       skb_orphan(skb);
+       skb->sk = sk_tun;
 
        /* Queue the packet to IP for output */
        len = skb->len;
index 30adf726743cba4993b2936e4f4d9ae2f092f182..a5791114b7bde59eddd6aed9c0dc79c590a8d688 100644 (file)
@@ -1456,16 +1456,11 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
                           PHYAddr[qdev->mac_index]);
        reg &= ~PHY_GIG_ALL_PARAMS;
 
-       if(portConfiguration &
-          PORT_CONFIG_FULL_DUPLEX_ENABLED &
-          PORT_CONFIG_1000MB_SPEED) {
-               reg |= PHY_GIG_ADV_1000F;
-       }
-
-       if(portConfiguration &
-          PORT_CONFIG_HALF_DUPLEX_ENABLED &
-          PORT_CONFIG_1000MB_SPEED) {
-               reg |= PHY_GIG_ADV_1000H;
+       if(portConfiguration & PORT_CONFIG_1000MB_SPEED) {
+               if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) 
+                       reg |= PHY_GIG_ADV_1000F;
+               else 
+                       reg |= PHY_GIG_ADV_1000H;
        }
 
        ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
@@ -1645,8 +1640,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev)
        return 0;
 }
 
-static void ql_link_state_machine(struct ql3_adapter *qdev)
+static void ql_link_state_machine_work(struct work_struct *work)
 {
+       struct ql3_adapter *qdev =
+               container_of(work, struct ql3_adapter, link_state_work.work);
+
        u32 curr_link_state;
        unsigned long hw_flags;
 
@@ -1661,6 +1659,10 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
                               "state.\n", qdev->ndev->name);
 
                spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+
+               /* Restart timer on 2 second interval. */
+               mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\
+
                return;
        }
 
@@ -1705,6 +1707,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
                break;
        }
        spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+
+       /* Restart timer on 2 second interval. */
+       mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
 }
 
 /*
@@ -3941,19 +3946,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev)
 static void ql3xxx_timer(unsigned long ptr)
 {
        struct ql3_adapter *qdev = (struct ql3_adapter *)ptr;
-
-       if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) {
-               printk(KERN_DEBUG PFX
-                      "%s: Reset in progress.\n",
-                      qdev->ndev->name);
-               goto end;
-       }
-
-       ql_link_state_machine(qdev);
-
-       /* Restart timer on 2 second interval. */
-end:
-       mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
+       queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0);
 }
 
 static int __devinit ql3xxx_probe(struct pci_dev *pdev,
@@ -4103,6 +4096,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
        qdev->workqueue = create_singlethread_workqueue(ndev->name);
        INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
        INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
+       INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work);
 
        init_timer(&qdev->adapter_timer);
        qdev->adapter_timer.function = ql3xxx_timer;
index fbcb0b9496390247b20e3f626e611b5a9b086c3b..d0ffb30ef371a10d91732a446dc5a7ac4a4a1e40 100644 (file)
@@ -1286,6 +1286,7 @@ struct ql3_adapter {
        struct workqueue_struct *workqueue;
        struct delayed_work reset_work;
        struct delayed_work tx_timeout_work;
+       struct delayed_work link_state_work;
        u32 max_frame_size;
        u32 device_id;
        u16 phyType;
index b94fa7ef1955ccc8036a46370102e366fb4b153c..1f647b9ce352128ae65fbc3d15d15062615adeea 100644 (file)
@@ -171,6 +171,8 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
        { PCI_DEVICE(0x16ec,                    0x0116), 0, 0, RTL_CFG_0 },
        { PCI_VENDOR_ID_LINKSYS,                0x1032,
                PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
+       { 0x0001,                               0x8168,
+               PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 },
        {0,},
 };
 
@@ -468,7 +470,7 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 {
        int i;
 
-       RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value);
+       RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
 
        for (i = 20; i > 0; i--) {
                /*
@@ -485,7 +487,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
 {
        int i, value = -1;
 
-       RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16);
+       RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
 
        for (i = 20; i > 0; i--) {
                /*
@@ -493,7 +495,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
                 * the specified MII register.
                 */
                if (RTL_R32(PHYAR) & 0x80000000) {
-                       value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+                       value = RTL_R32(PHYAR) & 0xffff;
                        break;
                }
                udelay(25);
@@ -1245,16 +1247,6 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
 
        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
-static void rtl8168b_hw_phy_config(void __iomem *ioaddr)
-{
-       struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0000 },
-               { 0x10, 0xf41b },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
-}
 
 static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
 {
@@ -1324,11 +1316,6 @@ static void rtl_hw_phy_config(struct net_device *dev)
        case RTL_GIGA_MAC_VER_04:
                rtl8169sb_hw_phy_config(ioaddr);
                break;
-       case RTL_GIGA_MAC_VER_11:
-       case RTL_GIGA_MAC_VER_12:
-       case RTL_GIGA_MAC_VER_17:
-               rtl8168b_hw_phy_config(ioaddr);
-               break;
        case RTL_GIGA_MAC_VER_18:
                rtl8168cp_hw_phy_config(ioaddr);
                break;
@@ -1739,7 +1726,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->features |= rtl_try_msi(pdev, ioaddr, cfg);
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
-       if (RTL_R8(PHYstatus) & TBI_Enable) {
+       if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
+           (RTL_R8(PHYstatus) & TBI_Enable)) {
                tp->set_speed = rtl8169_set_speed_tbi;
                tp->get_settings = rtl8169_gset_tbi;
                tp->phy_reset_enable = rtl8169_tbi_reset_enable;
index b822859c8de31079dbb100c4cf91a1947fc87184..73a7e6529ee0f91abb46f1bda1e05bcd21330bef 100644 (file)
@@ -78,12 +78,6 @@ static char version[] __devinitdata = "rrunner.c: v0.50 11/11/2002  Jes Sorensen
  * stack will need to know about I/O vectors or something similar.
  */
 
-/*
- * sysctl_[wr]mem_max are checked at init time to see if they are at
- * least 256KB and increased to 256KB if they are not. This is done to
- * avoid ending up with socket buffers smaller than the MTU size,
- */
-
 static int __devinit rr_init_one(struct pci_dev *pdev,
        const struct pci_device_id *ent)
 {
@@ -561,18 +555,6 @@ static int __devinit rr_init(struct net_device *dev)
        sram_size = rr_read_eeprom_word(rrpriv, (void *)8);
        printk("  SRAM size 0x%06x\n", sram_size);
 
-       if (sysctl_rmem_max < 262144){
-               printk("  Receive socket buffer limit too low (%i), "
-                      "setting to 262144\n", sysctl_rmem_max);
-               sysctl_rmem_max = 262144;
-       }
-
-       if (sysctl_wmem_max < 262144){
-               printk("  Transmit socket buffer limit too low (%i), "
-                      "setting to 262144\n", sysctl_wmem_max);
-               sysctl_wmem_max = 262144;
-       }
-
        return 0;
 }
 
index b8c0e7b4ca1cdd0e0d4d3a9251af47cff784a326..632666706247708e88574805f9023f6f616ffdce 100644 (file)
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.5"
+#define DRV_VERSION "2.0.26.6"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -3775,6 +3775,40 @@ static int __devinit s2io_test_msi(struct s2io_nic *sp)
 
        return err;
 }
+
+static void remove_msix_isr(struct s2io_nic *sp)
+{
+       int i;
+       u16 msi_control;
+
+       for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
+               if (sp->s2io_entries[i].in_use ==
+                       MSIX_REGISTERED_SUCCESS) {
+                       int vector = sp->entries[i].vector;
+                       void *arg = sp->s2io_entries[i].arg;
+                       free_irq(vector, arg);
+               }
+       }
+
+       kfree(sp->entries);
+       kfree(sp->s2io_entries);
+       sp->entries = NULL;
+       sp->s2io_entries = NULL;
+
+       pci_read_config_word(sp->pdev, 0x42, &msi_control);
+       msi_control &= 0xFFFE; /* Disable MSI */
+       pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+       pci_disable_msix(sp->pdev);
+}
+
+static void remove_inta_isr(struct s2io_nic *sp)
+{
+       struct net_device *dev = sp->dev;
+
+       free_irq(sp->pdev->irq, dev);
+}
+
 /* ********************************************************* *
  * Functions defined below concern the OS part of the driver *
  * ********************************************************* */
@@ -3809,28 +3843,9 @@ static int s2io_open(struct net_device *dev)
                int ret = s2io_enable_msi_x(sp);
 
                if (!ret) {
-                       u16 msi_control;
-
                        ret = s2io_test_msi(sp);
-
                        /* rollback MSI-X, will re-enable during add_isr() */
-                       kfree(sp->entries);
-                       sp->mac_control.stats_info->sw_stat.mem_freed +=
-                               (MAX_REQUESTED_MSI_X *
-                               sizeof(struct msix_entry));
-                       kfree(sp->s2io_entries);
-                       sp->mac_control.stats_info->sw_stat.mem_freed +=
-                               (MAX_REQUESTED_MSI_X *
-                               sizeof(struct s2io_msix_entry));
-                       sp->entries = NULL;
-                       sp->s2io_entries = NULL;
-
-                       pci_read_config_word(sp->pdev, 0x42, &msi_control);
-                       msi_control &= 0xFFFE; /* Disable MSI */
-                       pci_write_config_word(sp->pdev, 0x42, msi_control);
-
-                       pci_disable_msix(sp->pdev);
-
+                       remove_msix_isr(sp);
                }
                if (ret) {
 
@@ -6719,15 +6734,22 @@ static int s2io_add_isr(struct s2io_nic * sp)
                                }
                        }
                        if (err) {
+                               remove_msix_isr(sp);
                                DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration "
                                          "failed\n", dev->name, i);
-                               DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
-                               return -1;
+                               DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n",
+                                                dev->name);
+                               sp->config.intr_type = INTA;
+                               break;
                        }
                        sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
                }
-               printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt);
-               printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt);
+               if (!err) {
+                       printk(KERN_INFO "MSI-X-TX %d entries enabled\n",
+                               msix_tx_cnt);
+                       printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
+                               msix_rx_cnt);
+               }
        }
        if (sp->config.intr_type == INTA) {
                err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED,
@@ -6742,40 +6764,10 @@ static int s2io_add_isr(struct s2io_nic * sp)
 }
 static void s2io_rem_isr(struct s2io_nic * sp)
 {
-       struct net_device *dev = sp->dev;
-       struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
-
-       if (sp->config.intr_type == MSI_X) {
-               int i;
-               u16 msi_control;
-
-               for (i=1; (sp->s2io_entries[i].in_use ==
-                       MSIX_REGISTERED_SUCCESS); i++) {
-                       int vector = sp->entries[i].vector;
-                       void *arg = sp->s2io_entries[i].arg;
-
-                       synchronize_irq(vector);
-                       free_irq(vector, arg);
-               }
-
-               kfree(sp->entries);
-               stats->mem_freed +=
-                       (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
-               kfree(sp->s2io_entries);
-               stats->mem_freed +=
-                       (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
-               sp->entries = NULL;
-               sp->s2io_entries = NULL;
-
-               pci_read_config_word(sp->pdev, 0x42, &msi_control);
-               msi_control &= 0xFFFE; /* Disable MSI */
-               pci_write_config_word(sp->pdev, 0x42, msi_control);
-
-               pci_disable_msix(sp->pdev);
-       } else {
-               synchronize_irq(sp->pdev->irq);
-               free_irq(sp->pdev->irq, dev);
-       }
+       if (sp->config.intr_type == MSI_X)
+               remove_msix_isr(sp);
+       else
+               remove_inta_isr(sp);
 }
 
 static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
index b9961dc47606bb28b9528c8764e95e488ff1ca36..6d62250fba07944fab02a67dc9b93dc6fcdf36de 100644 (file)
@@ -2512,31 +2512,32 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return err;
 }
 
-/* Assign Ram Buffer allocation to queue */
-static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, u32 space)
+static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
 {
        u32 end;
 
-       /* convert from K bytes to qwords used for hw register */
-       start *= 1024/8;
-       space *= 1024/8;
-       end = start + space - 1;
+       start /= 8;
+       len /= 8;
+       end = start + len - 1;
 
        skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
        skge_write32(hw, RB_ADDR(q, RB_START), start);
-       skge_write32(hw, RB_ADDR(q, RB_END), end);
        skge_write32(hw, RB_ADDR(q, RB_WP), start);
        skge_write32(hw, RB_ADDR(q, RB_RP), start);
+       skge_write32(hw, RB_ADDR(q, RB_END), end);
 
        if (q == Q_R1 || q == Q_R2) {
-               u32 tp = space - space/4;
-
                /* Set thresholds on receive queue's */
-               skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
-               skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
-       } else if (hw->chip_id != CHIP_ID_GENESIS)
-               /* Genesis Tx Fifo is too small for normal store/forward */
+               skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
+                            start + (2*len)/3);
+               skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
+                            start + (len/3));
+       } else {
+               /* Enable store & forward on Tx queue's because
+                * Tx FIFO is only 4K on Genesis and 1K on Yukon
+                */
                skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+       }
 
        skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
 }
@@ -2564,7 +2565,7 @@ static int skge_up(struct net_device *dev)
        struct skge_port *skge = netdev_priv(dev);
        struct skge_hw *hw = skge->hw;
        int port = skge->port;
-       u32 ramaddr, ramsize, rxspace;
+       u32 chunk, ram_addr;
        size_t rx_size, tx_size;
        int err;
 
@@ -2619,15 +2620,14 @@ static int skge_up(struct net_device *dev)
        spin_unlock_bh(&hw->phy_lock);
 
        /* Configure RAMbuffers */
-       ramsize = (hw->ram_size - hw->ram_offset) / hw->ports;
-       ramaddr = hw->ram_offset + port * ramsize;
-       rxspace = 8 + (2*(ramsize - 16))/3;
-
-       skge_ramset(hw, rxqaddr[port], ramaddr, rxspace);
-       skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace);
+       chunk = hw->ram_size / ((hw->ports + 1)*2);
+       ram_addr = hw->ram_offset + 2 * chunk * port;
 
+       skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
        skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
+
        BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
+       skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
        skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
 
        /* Start receiver BMU */
@@ -3591,12 +3591,15 @@ static int skge_reset(struct skge_hw *hw)
        if (hw->chip_id == CHIP_ID_GENESIS) {
                if (t8 == 3) {
                        /* special case: 4 x 64k x 36, offset = 0x80000 */
-                       hw->ram_size = 1024;
-                       hw->ram_offset = 512;
+                       hw->ram_size = 0x100000;
+                       hw->ram_offset = 0x80000;
                } else
                        hw->ram_size = t8 * 512;
-       } else /* Yukon */
-               hw->ram_size = t8 ? t8 * 4 : 128;
+       }
+       else if (t8 == 0)
+               hw->ram_size = 0x20000;
+       else
+               hw->ram_size = t8 * 4096;
 
        hw->intr_mask = IS_HW_ERR;
 
index c27c7d63b6a56abc88d7ebda8d14a02795ce81ea..a2070db725c903ced2fae8079cf71fd2ae32d182 100644 (file)
@@ -52,7 +52,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.19"
+#define DRV_VERSION            "1.20"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -121,6 +121,7 @@ static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
@@ -134,6 +135,7 @@ static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
        { 0 }
 };
 
@@ -156,7 +158,7 @@ static const char *yukon2_name[] = {
 
 static void sky2_set_multicast(struct net_device *dev);
 
-/* Access to external PHY */
+/* Access to PHY via serial interconnect */
 static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
 {
        int i;
@@ -166,13 +168,22 @@ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
                    GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
 
        for (i = 0; i < PHY_RETRIES; i++) {
-               if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+               u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+               if (ctrl == 0xffff)
+                       goto io_error;
+
+               if (!(ctrl & GM_SMI_CT_BUSY))
                        return 0;
-               udelay(1);
+
+               udelay(10);
        }
 
-       printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
+       dev_warn(&hw->pdev->dev,"%s: phy write timeout\n", hw->dev[port]->name);
        return -ETIMEDOUT;
+
+io_error:
+       dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+       return -EIO;
 }
 
 static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
@@ -183,23 +194,29 @@ static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
                    | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
 
        for (i = 0; i < PHY_RETRIES; i++) {
-               if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
+               u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+               if (ctrl == 0xffff)
+                       goto io_error;
+
+               if (ctrl & GM_SMI_CT_RD_VAL) {
                        *val = gma_read16(hw, port, GM_SMI_DATA);
                        return 0;
                }
 
-               udelay(1);
+               udelay(10);
        }
 
+       dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
        return -ETIMEDOUT;
+io_error:
+       dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+       return -EIO;
 }
 
-static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
 {
        u16 v;
-
-       if (__gm_phy_read(hw, port, reg, &v) != 0)
-               printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+       __gm_phy_read(hw, port, reg, &v);
        return v;
 }
 
@@ -273,8 +290,6 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
 
        /* disable all GMAC IRQ's */
        sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
-       /* disable PHY IRQs */
-       gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
 
        gma_write16(hw, port, GM_MC_ADDR_H1, 0);        /* clear MC hash */
        gma_write16(hw, port, GM_MC_ADDR_H2, 0);
@@ -1805,29 +1820,6 @@ static void sky2_link_up(struct sky2_port *sky2)
        sky2_write8(hw, SK_REG(port, LNK_LED_REG),
                    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
 
-       if (hw->flags & SKY2_HW_NEWER_PHY) {
-               u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-               u16 led = PHY_M_LEDC_LOS_CTRL(1);       /* link active */
-
-               switch(sky2->speed) {
-               case SPEED_10:
-                       led |= PHY_M_LEDC_INIT_CTRL(7);
-                       break;
-
-               case SPEED_100:
-                       led |= PHY_M_LEDC_STA1_CTRL(7);
-                       break;
-
-               case SPEED_1000:
-                       led |= PHY_M_LEDC_STA0_CTRL(7);
-                       break;
-               }
-
-               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led);
-               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-       }
-
        if (netif_msg_link(sky2))
                printk(KERN_INFO PFX
                       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
@@ -2247,20 +2239,26 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
        do {
                struct sky2_port *sky2;
                struct sky2_status_le *le  = hw->st_le + hw->st_idx;
-               unsigned port = le->css & CSS_LINK_BIT;
+               unsigned port;
                struct net_device *dev;
                struct sk_buff *skb;
                u32 status;
                u16 length;
+               u8 opcode = le->opcode;
+
+               if (!(opcode & HW_OWNER))
+                       break;
 
                hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
 
+               port = le->css & CSS_LINK_BIT;
                dev = hw->dev[port];
                sky2 = netdev_priv(dev);
                length = le16_to_cpu(le->length);
                status = le32_to_cpu(le->status);
 
-               switch (le->opcode & ~HW_OWNER) {
+               le->opcode = 0;
+               switch (opcode & ~HW_OWNER) {
                case OP_RXSTAT:
                        ++rx[port];
                        skb = sky2_receive(dev, length, status);
@@ -2353,7 +2351,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
                default:
                        if (net_ratelimit())
                                printk(KERN_WARNING PFX
-                                      "unknown status opcode 0x%x\n", le->opcode);
+                                      "unknown status opcode 0x%x\n", opcode);
                }
        } while (hw->st_idx != idx);
 
@@ -2439,13 +2437,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
        if (status & Y2_IS_PCI_EXP) {
                /* PCI-Express uncorrectable Error occurred */
-               int pos = pci_find_aer_capability(hw->pdev);
+               int aer = pci_find_aer_capability(hw->pdev);
                u32 err;
 
-               pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
+               if (aer) {
+                       pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS,
+                                             &err);
+                       pci_cleanup_aer_uncorrect_error_status(pdev);
+               } else {
+                       /* Either AER not configured, or not working
+                        * because of bad MMCONFIG, so just do recover
+                        * manually.
+                        */
+                       err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
+                       sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+                                    0xfffffffful);
+               }
+
                if (net_ratelimit())
                        dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
-               pci_cleanup_aer_uncorrect_error_status(pdev);
+
        }
 
        if (status & Y2_HWE_L1_MASK)
@@ -2791,6 +2802,9 @@ static void sky2_reset(struct sky2_hw *hw)
        sky2_write8(hw, B0_CTST, CS_RST_SET);
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
+       /* allow writes to PCI config */
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
        /* clear PCI errors, if any */
        pci_read_config_word(pdev, PCI_STATUS, &status);
        status |= PCI_STATUS_ERROR_BITS;
@@ -2800,9 +2814,18 @@ static void sky2_reset(struct sky2_hw *hw)
 
        cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
        if (cap) {
-               /* Check for advanced error reporting */
-               pci_cleanup_aer_uncorrect_error_status(pdev);
-               pci_cleanup_aer_correct_error_status(pdev);
+               if (pci_find_aer_capability(pdev)) {
+                       /* Check for advanced error reporting */
+                       pci_cleanup_aer_uncorrect_error_status(pdev);
+                       pci_cleanup_aer_correct_error_status(pdev);
+               } else {
+                       dev_warn(&pdev->dev,
+                               "PCI Express Advanced Error Reporting"
+                               " not configured or MMCONFIG problem?\n");
+
+                       sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+                                    0xfffffffful);
+               }
 
                /* If error bit is stuck on ignore it */
                if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
@@ -3974,7 +3997,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        dev->tx_timeout = sky2_tx_timeout;
        dev->watchdog_timeo = TX_WATCHDOG;
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = sky2_netpoll;
+       if (port == 0)
+               dev->poll_controller = sky2_netpoll;
 #endif
 
        sky2 = netdev_priv(dev);
index 49ee264064ab85dc95ac522b93e72b8e240e7fa1..69525fd7908db70e898d51768b0c3dd6a557becb 100644 (file)
@@ -247,7 +247,8 @@ enum csr_regs {
        B3_PA_CTRL      = 0x01f0,
        B3_PA_TEST      = 0x01f2,
 
-       Y2_CFG_SPC      = 0x1c00,
+       Y2_CFG_SPC      = 0x1c00,       /* PCI config space region */
+       Y2_CFG_AER      = 0x1d00,       /* PCI Advanced Error Report region */
 };
 
 /*     B0_CTST                 16 bit  Control/Status register */
index 335b7cc80ebaf3aaf430af776f08d716dd215dbf..251a3ce376ac60828fea0389b97316c649b6adcc 100644 (file)
@@ -1218,14 +1218,8 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                return 0;
        /* VSV changes end */
 #endif
-
-       /* Allow stty to read, but not set, the serial port */
-       case TCGETS:
-       case TCGETA:
-               return n_tty_ioctl(tty, file, cmd, arg);
-
        default:
-               return -ENOIOCTLCMD;
+               return tty_mode_ioctl(tty, file, cmd, arg);
        }
 }
 
index 729fd28c08b56f071050f30723bc2256730d7f36..db34e1eb67e98e678c08c61ae4dd19daded4b073 100644 (file)
@@ -224,6 +224,21 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
        }
 }
 
+#elif defined(CONFIG_MACH_ZYLONITE)
+
+#define SMC_CAN_USE_8BIT        1
+#define SMC_CAN_USE_16BIT       1
+#define SMC_CAN_USE_32BIT       0
+#define SMC_IO_SHIFT            0
+#define SMC_NOWAIT              1
+#define SMC_USE_PXA_DMA                1
+#define SMC_inb(a, r)           readb((a) + (r))
+#define SMC_inw(a, r)           readw((a) + (r))
+#define SMC_insw(a, r, p, l)    insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)   outsw((a) + (r), p, l)
+#define SMC_outb(v, a, r)       writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)       writew(v, (a) + (r))
+
 #elif  defined(CONFIG_ARCH_OMAP)
 
 /* We can only do 16-bit reads and writes in the static memory space. */
index 53b8344a68effd0766ec73c262d0aab7bf3c4f61..f6fedcc32de17ce8bca604068d736e38fda45927 100644 (file)
@@ -2333,10 +2333,10 @@ static int gem_close(struct net_device *dev)
 {
        struct gem *gp = dev->priv;
 
-       napi_disable(&gp->napi);
-
        mutex_lock(&gp->pm_mutex);
 
+       napi_disable(&gp->napi);
+
        gp->opened = 0;
        if (!gp->asleep)
                gem_do_stop(dev, 0);
@@ -2355,8 +2355,6 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 
        mutex_lock(&gp->pm_mutex);
 
-       napi_disable(&gp->napi);
-
        printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
               dev->name,
               (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
@@ -2370,6 +2368,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 
        /* If the driver is opened, we stop the MAC */
        if (gp->opened) {
+               napi_disable(&gp->napi);
+
                /* Stop traffic, mark us closed */
                netif_device_detach(dev);
 
@@ -2460,6 +2460,7 @@ static int gem_resume(struct pci_dev *pdev)
                /* Re-attach net device */
                netif_device_attach(dev);
 
+               napi_enable(&gp->napi);
        }
 
        spin_lock_irqsave(&gp->lock, flags);
@@ -2479,8 +2480,6 @@ static int gem_resume(struct pci_dev *pdev)
        spin_unlock(&gp->tx_lock);
        spin_unlock_irqrestore(&gp->lock, flags);
 
-       napi_enable(&gp->napi);
-
        mutex_unlock(&gp->pm_mutex);
 
        return 0;
index 120c8affe83dba36f29f972657fc05954af6284d..9cc13dd8a82182cd2718ebf01d9c45fc255e9610 100644 (file)
@@ -1281,7 +1281,7 @@ static void happy_meal_init_rings(struct happy_meal *hp)
                skb->dev = dev;
 
                /* Because we reserve afterwards. */
-               skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET));
+               skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
                hme_write_rxd(hp, &hb->happy_meal_rxd[i],
                              (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
                              hme_dma_map(hp, skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
@@ -1700,6 +1700,11 @@ static int happy_meal_init(struct happy_meal *hp)
        HMD(("tx old[%08x] and rx [%08x] ON!\n",
             hme_read32(hp, bregs + BMAC_TXCFG),
             hme_read32(hp, bregs + BMAC_RXCFG)));
+
+       /* Set larger TX/RX size to allow for 802.1q */
+       hme_write32(hp, bregs + BMAC_TXMAX, ETH_FRAME_LEN + 8);
+       hme_write32(hp, bregs + BMAC_RXMAX, ETH_FRAME_LEN + 8);
+
        hme_write32(hp, bregs + BMAC_TXCFG,
                    hme_read32(hp, bregs + BMAC_TXCFG) | BIGMAC_TXCFG_ENABLE);
        hme_write32(hp, bregs + BMAC_RXCFG,
@@ -2039,7 +2044,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
                        hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE);
                        hp->rx_skbs[elem] = new_skb;
                        new_skb->dev = dev;
-                       skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
+                       skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
                        hme_write_rxd(hp, this,
                                      (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
                                      hme_dma_map(hp, new_skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
@@ -2809,8 +2814,8 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
        dev->watchdog_timeo = 5*HZ;
        dev->ethtool_ops = &hme_ethtool_ops;
 
-       /* Happy Meal can do it all... except VLAN. */
-       dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED;
+       /* Happy Meal can do it all... */
+       dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
        dev->irq = sdev->irqs[0];
 
index 4e1b84e6d66ab308330184a034ba7f52d82fb91a..21230c97b2a0fc7513af353faf8a42c5781602e8 100644 (file)
@@ -2168,10 +2168,10 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 {
        struct bdx_priv *priv = netdev->priv;
 
-       strncat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver));
-       strncat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version));
-       strncat(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strncat(drvinfo->bus_info, pci_name(priv->pdev),
+       strlcat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver));
+       strlcat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version));
+       strlcat(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcat(drvinfo->bus_info, pci_name(priv->pdev),
                sizeof(drvinfo->bus_info));
 
        drvinfo->n_stats = ((priv->stats_flag) ?
index 09440d783e65542912bac932fa727a288df1891c..4942f7d18937b9cbbe94fd37607c2d331bb11c70 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.85"
-#define DRV_MODULE_RELDATE     "October 18, 2007"
+#define DRV_MODULE_VERSION     "3.86"
+#define DRV_MODULE_RELDATE     "November 9, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -1106,6 +1106,24 @@ static int tg3_phy_reset(struct tg3 *tp)
        if (err)
                return err;
 
+       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+               u32 val;
+
+               val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
+               if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) ==
+                   CPMU_LSPD_1000MB_MACCLK_12_5) {
+                       val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
+                       udelay(40);
+                       tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
+               }
+
+               /* Disable GPHY autopowerdown. */
+               tg3_writephy(tp, MII_TG3_MISC_SHDW,
+                            MII_TG3_MISC_SHDW_WREN |
+                            MII_TG3_MISC_SHDW_APD_SEL |
+                            MII_TG3_MISC_SHDW_APD_WKTM_84MS);
+       }
+
 out:
        if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
@@ -1297,6 +1315,8 @@ static void tg3_nvram_unlock(struct tg3 *);
 
 static void tg3_power_down_phy(struct tg3 *tp)
 {
+       u32 val;
+
        if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
                        u32 sg_dig_ctrl = tr32(SG_DIG_CTRL);
@@ -1311,8 +1331,6 @@ static void tg3_power_down_phy(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-               u32 val;
-
                tg3_bmcr_reset(tp);
                val = tr32(GRC_MISC_CFG);
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
@@ -1332,6 +1350,14 @@ static void tg3_power_down_phy(struct tg3 *tp)
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
             (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
                return;
+
+       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+               val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
+               val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
+               val |= CPMU_LSPD_1000MB_MACCLK_12_5;
+               tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
+       }
+
        tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 }
 
@@ -3126,6 +3152,23 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
                err = tg3_setup_copper_phy(tp, force_reset);
        }
 
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
+               u32 val, scale;
+
+               val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
+               if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
+                       scale = 65;
+               else if (val == CPMU_CLCK_STAT_MAC_CLCK_6_25)
+                       scale = 6;
+               else
+                       scale = 12;
+
+               val = tr32(GRC_MISC_CFG) & ~GRC_MISC_CFG_PRESCALAR_MASK;
+               val |= (scale << GRC_MISC_CFG_PRESCALAR_SHIFT);
+               tw32(GRC_MISC_CFG, val);
+       }
+
        if (tp->link_config.active_speed == SPEED_1000 &&
            tp->link_config.active_duplex == DUPLEX_HALF)
                tw32(MAC_TX_LENGTHS,
@@ -5054,12 +5097,15 @@ static void tg3_restore_pci_state(struct tg3 *tp)
 
        pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+       if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+               pcie_set_readrq(tp->pdev, 4096);
+       else {
                pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
                                      tp->pci_cacheline_sz);
                pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
                                      tp->pci_lat_timer);
        }
+
        /* Make sure PCI-X relaxed ordering bit is clear. */
        if (tp->pcix_cap) {
                u16 pcix_cmd;
@@ -6343,10 +6389,26 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        tg3_write_sig_legacy(tp, RESET_KIND_INIT);
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0) {
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
                val = tr32(TG3_CPMU_CTRL);
                val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
                tw32(TG3_CPMU_CTRL, val);
+
+               val = tr32(TG3_CPMU_LSPD_10MB_CLK);
+               val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
+               val |= CPMU_LSPD_10MB_MACCLK_6_25;
+               tw32(TG3_CPMU_LSPD_10MB_CLK, val);
+
+               val = tr32(TG3_CPMU_LNK_AWARE_PWRMD);
+               val &= ~CPMU_LNK_AWARE_MACCLK_MASK;
+               val |= CPMU_LNK_AWARE_MACCLK_6_25;
+               tw32(TG3_CPMU_LNK_AWARE_PWRMD, val);
+
+               val = tr32(TG3_CPMU_HST_ACC);
+               val &= ~CPMU_HST_ACC_MACCLK_MASK;
+               val |= CPMU_HST_ACC_MACCLK_6_25;
+               tw32(TG3_CPMU_HST_ACC, val);
        }
 
        /* This works around an issue with Athlon chipsets on
@@ -7365,10 +7427,6 @@ static int tg3_open(struct net_device *dev)
                } else if (pci_enable_msi(tp->pdev) == 0) {
                        u32 msi_mode;
 
-                       /* Hardware bug - MSI won't work if INTX disabled. */
-                       if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
-                               pci_intx(tp->pdev, 1);
-
                        msi_mode = tr32(MSGINT_MODE);
                        tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
                        tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
@@ -8271,7 +8329,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                  SUPPORTED_100baseT_Full |
                                  SUPPORTED_10baseT_Half |
                                  SUPPORTED_10baseT_Full |
-                                 SUPPORTED_MII);
+                                 SUPPORTED_TP);
                cmd->port = PORT_TP;
        } else {
                cmd->supported |= SUPPORTED_FIBRE;
@@ -8668,7 +8726,9 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
 }
 
 #define NVRAM_TEST_SIZE 0x100
-#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
+#define NVRAM_SELFBOOT_FORMAT1_0_SIZE  0x14
+#define NVRAM_SELFBOOT_FORMAT1_2_SIZE  0x18
+#define NVRAM_SELFBOOT_FORMAT1_3_SIZE  0x1c
 #define NVRAM_SELFBOOT_HW_SIZE 0x20
 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c
 
@@ -8683,9 +8743,22 @@ static int tg3_test_nvram(struct tg3 *tp)
        if (magic == TG3_EEPROM_MAGIC)
                size = NVRAM_TEST_SIZE;
        else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) {
-               if ((magic & 0xe00000) == 0x200000)
-                       size = NVRAM_SELFBOOT_FORMAT1_SIZE;
-               else
+               if ((magic & TG3_EEPROM_SB_FORMAT_MASK) ==
+                   TG3_EEPROM_SB_FORMAT_1) {
+                       switch (magic & TG3_EEPROM_SB_REVISION_MASK) {
+                       case TG3_EEPROM_SB_REVISION_0:
+                               size = NVRAM_SELFBOOT_FORMAT1_0_SIZE;
+                               break;
+                       case TG3_EEPROM_SB_REVISION_2:
+                               size = NVRAM_SELFBOOT_FORMAT1_2_SIZE;
+                               break;
+                       case TG3_EEPROM_SB_REVISION_3:
+                               size = NVRAM_SELFBOOT_FORMAT1_3_SIZE;
+                               break;
+                       default:
+                               return 0;
+                       }
+               } else
                        return 0;
        } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
                size = NVRAM_SELFBOOT_HW_SIZE;
@@ -8712,8 +8785,17 @@ static int tg3_test_nvram(struct tg3 *tp)
            TG3_EEPROM_MAGIC_FW) {
                u8 *buf8 = (u8 *) buf, csum8 = 0;
 
-               for (i = 0; i < size; i++)
-                       csum8 += buf8[i];
+               if ((cpu_to_be32(buf[0]) & TG3_EEPROM_SB_REVISION_MASK) ==
+                   TG3_EEPROM_SB_REVISION_2) {
+                       /* For rev 2, the csum doesn't include the MBA. */
+                       for (i = 0; i < TG3_EEPROM_SB_F1R2_MBA_OFF; i++)
+                               csum8 += buf8[i];
+                       for (i = TG3_EEPROM_SB_F1R2_MBA_OFF + 4; i < size; i++)
+                               csum8 += buf8[i];
+               } else {
+                       for (i = 0; i < size; i++)
+                               csum8 += buf8[i];
+               }
 
                if (csum8 == 0) {
                        err = 0;
@@ -9297,7 +9379,7 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (err)
                return TG3_LOOPBACK_FAILED;
 
-       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
                int i;
                u32 status;
 
@@ -9314,17 +9396,17 @@ static int tg3_test_loopback(struct tg3 *tp)
                if (status != CPMU_MUTEX_GNT_DRIVER)
                        return TG3_LOOPBACK_FAILED;
 
-               cpmuctrl = tr32(TG3_CPMU_CTRL);
-
                /* Turn off power management based on link speed. */
+               cpmuctrl = tr32(TG3_CPMU_CTRL);
                tw32(TG3_CPMU_CTRL,
-                    cpmuctrl & ~CPMU_CTRL_LINK_SPEED_MODE);
+                    cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE |
+                                 CPMU_CTRL_LINK_AWARE_MODE));
        }
 
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
 
-       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
 
                /* Release the mutex */
@@ -10545,6 +10627,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
                        tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
+               if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+                   tp->pci_chip_rev_id == CHIPREV_ID_5784_A1)
+                       tp->led_ctrl = LED_CTRL_MODE_MAC;
+
                if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
                        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
                        if ((tp->pdev->subsystem_vendor ==
@@ -10863,7 +10949,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
        }
 
        if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-            (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
+            (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
                return;
 
        for (offset = TG3_NVM_DIR_START;
@@ -11131,6 +11217,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
        if (pcie_cap != 0) {
                tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+
+               pcie_set_readrq(tp->pdev, 4096);
+
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        u16 lnkctl;
 
@@ -11311,9 +11400,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
+               if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+                   tp->pci_chip_rev_id == CHIPREV_ID_5784_A1 ||
+                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A0 ||
+                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A1)
+                       tp->tg3_flags3 |= TG3_FLG3_5761_5784_AX_FIXES;
+       }
+
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
         * GPIO1 driven high will bring 5700's external PHY out of reset.
         * It is also used as eeprom write protect on LOMs.
@@ -12468,6 +12564,28 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+               if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+                       printk(KERN_ERR PFX "Cannot find proper PCI device "
+                              "base address for APE, aborting.\n");
+                       err = -ENODEV;
+                       goto err_out_iounmap;
+               }
+
+               tg3reg_base = pci_resource_start(pdev, 2);
+               tg3reg_len = pci_resource_len(pdev, 2);
+
+               tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
+               if (tp->aperegs == 0UL) {
+                       printk(KERN_ERR PFX "Cannot map APE registers, "
+                              "aborting.\n");
+                       err = -ENOMEM;
+                       goto err_out_iounmap;
+               }
+
+               tg3_ape_lock_init(tp);
+       }
+
        /*
         * Reset chip in case UNDI or EFI driver did not shutdown
         * DMA self test will enable WDMAC and we'll see (spurious)
@@ -12482,7 +12600,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        err = tg3_test_dma(tp);
        if (err) {
                printk(KERN_ERR PFX "DMA engine test failed, aborting.\n");
-               goto err_out_iounmap;
+               goto err_out_apeunmap;
        }
 
        /* Tigon3 can do ipv4 only... and some chips have buggy
@@ -12505,28 +12623,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        tg3_init_coal(tp);
 
-       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-               if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
-                       printk(KERN_ERR PFX "Cannot find proper PCI device "
-                              "base address for APE, aborting.\n");
-                       err = -ENODEV;
-                       goto err_out_iounmap;
-               }
-
-               tg3reg_base = pci_resource_start(pdev, 2);
-               tg3reg_len = pci_resource_len(pdev, 2);
-
-               tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
-               if (tp->aperegs == 0UL) {
-                       printk(KERN_ERR PFX "Cannot map APE registers, "
-                              "aborting.\n");
-                       err = -ENOMEM;
-                       goto err_out_iounmap;
-               }
-
-               tg3_ape_lock_init(tp);
-       }
-
        pci_set_drvdata(pdev, dev);
 
        err = register_netdev(dev);
@@ -12681,11 +12777,6 @@ static int tg3_resume(struct pci_dev *pdev)
        if (err)
                return err;
 
-       /* Hardware bug - MSI won't work if INTX disabled. */
-       if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
-           (tp->tg3_flags2 & TG3_FLG2_USING_MSI))
-               pci_intx(tp->pdev, 1);
-
        netif_device_attach(dev);
 
        tg3_full_lock(tp, 0);
index 1d5b2a3dd29dff6c335f8d8174cdfe3955fd9319..da18fb2207126810a8b1f74faf1e26cb36393d55 100644 (file)
 #define  CHIPREV_ID_5714_A2             0x9002
 #define  CHIPREV_ID_5906_A1             0xc001
 #define  CHIPREV_ID_5784_A0             0x5784000
+#define  CHIPREV_ID_5784_A1             0x5784001
+#define  CHIPREV_ID_5761_A0             0x5761000
+#define  CHIPREV_ID_5761_A1             0x5761001
 #define  GET_ASIC_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700                         0x07
 #define   ASIC_REV_5701                         0x00
 #define  CPMU_CTRL_LINK_IDLE_MODE       0x00000200
 #define  CPMU_CTRL_LINK_AWARE_MODE      0x00000400
 #define  CPMU_CTRL_LINK_SPEED_MODE      0x00004000
-/* 0x3604 --> 0x365c unused */
+#define TG3_CPMU_LSPD_10MB_CLK         0x00003604
+#define  CPMU_LSPD_10MB_MACCLK_MASK     0x001f0000
+#define  CPMU_LSPD_10MB_MACCLK_6_25     0x00130000
+/* 0x3608 --> 0x360c unused */
+
+#define TG3_CPMU_LSPD_1000MB_CLK       0x0000360c
+#define  CPMU_LSPD_1000MB_MACCLK_62_5   0x00000000
+#define  CPMU_LSPD_1000MB_MACCLK_12_5   0x00110000
+#define  CPMU_LSPD_1000MB_MACCLK_MASK   0x001f0000
+#define TG3_CPMU_LNK_AWARE_PWRMD       0x00003610
+#define  CPMU_LNK_AWARE_MACCLK_MASK     0x001f0000
+#define  CPMU_LNK_AWARE_MACCLK_6_25     0x00130000
+/* 0x3614 --> 0x361c unused */
+
+#define TG3_CPMU_HST_ACC               0x0000361c
+#define  CPMU_HST_ACC_MACCLK_MASK       0x001f0000
+#define  CPMU_HST_ACC_MACCLK_6_25       0x00130000
+/* 0x3620 --> 0x3630 unused */
+
+#define TG3_CPMU_CLCK_STAT             0x00003630
+#define  CPMU_CLCK_STAT_MAC_CLCK_MASK   0x001f0000
+#define  CPMU_CLCK_STAT_MAC_CLCK_62_5   0x00000000
+#define  CPMU_CLCK_STAT_MAC_CLCK_12_5   0x00110000
+#define  CPMU_CLCK_STAT_MAC_CLCK_6_25   0x00130000
+/* 0x3634 --> 0x365c unused */
 
 #define TG3_CPMU_MUTEX_REQ             0x0000365c
 #define  CPMU_MUTEX_REQ_DRIVER          0x00001000
 #define TG3_EEPROM_MAGIC               0x669955aa
 #define TG3_EEPROM_MAGIC_FW            0xa5000000
 #define TG3_EEPROM_MAGIC_FW_MSK                0xff000000
+#define TG3_EEPROM_SB_FORMAT_MASK      0x00e00000
+#define TG3_EEPROM_SB_FORMAT_1         0x00200000
+#define TG3_EEPROM_SB_REVISION_MASK    0x001f0000
+#define TG3_EEPROM_SB_REVISION_0       0x00000000
+#define TG3_EEPROM_SB_REVISION_2       0x00020000
+#define TG3_EEPROM_SB_REVISION_3       0x00030000
 #define TG3_EEPROM_MAGIC_HW            0xabcd
 #define TG3_EEPROM_MAGIC_HW_MSK                0xffff
 
 #define MII_TG3_ISTAT                  0x1a /* IRQ status register */
 #define MII_TG3_IMASK                  0x1b /* IRQ mask register */
 
+#define MII_TG3_MISC_SHDW              0x1c
+#define MII_TG3_MISC_SHDW_WREN         0x8000
+#define MII_TG3_MISC_SHDW_APD_SEL      0x2800
+
+#define MII_TG3_MISC_SHDW_APD_WKTM_84MS        0x0001
+
 /* ISTAT/IMASK event bits */
 #define MII_TG3_INT_LINKCHG            0x0002
 #define MII_TG3_INT_SPEEDCHG           0x0004
 /* APE convenience enumerations. */
 #define TG3_APE_LOCK_MEM                4
 
+#define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
+
 
 /* There are two ways to manage the TX descriptors on the tigon3.
  * Either the descriptors are in host DMA'able memory, or they
@@ -2352,6 +2393,7 @@ struct tg3 {
        u32                             tg3_flags3;
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS   0x00000001
 #define TG3_FLG3_ENABLE_APE            0x00000002
+#define TG3_FLG3_5761_5784_AX_FIXES    0x00000004
 
        struct timer_list               timer;
        u16                             timer_counter;
index 49d7a290dbbcfa93bdb94eba8e147ce5d7b5d406..20ac1503021e38cec7ffb995efbff4f1cfc31c4a 100644 (file)
@@ -24,8 +24,7 @@ config DE2104X
          will say Y here.) Do read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called de2104x.
 
 config TULIP
@@ -42,8 +41,7 @@ config TULIP
          will say Y here.) Do read the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called tulip.
 
 config TULIP_MWI
@@ -104,8 +102,7 @@ config DE4X5
          information is contained in
          <file:Documentation/networking/de4x5.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called de4x5.
 
 config WINBOND_840
@@ -129,8 +126,7 @@ config DM9102
          (Ethernet) card, say Y.  Some information is contained in the file
          <file:Documentation/networking/dmfe.txt>.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called dmfe.
 
 config ULI526X
@@ -141,8 +137,7 @@ config ULI526X
          This driver is for ULi M5261/M5263 10/100M Ethernet Controller
          (<http://www.uli.com.tw/>).
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called uli526x.
          
 config PCMCIA_XIRCOM
@@ -154,8 +149,7 @@ config PCMCIA_XIRCOM
          as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
          ASIX.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called xircom_cb.  If unsure, say N.
 
 config PCMCIA_XIRTULIP
@@ -168,8 +162,7 @@ config PCMCIA_XIRTULIP
          as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
          ASIX.
 
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>.  The module will
+         To compile this driver as a module, choose M here. The module will
          be called xircom_tulip_cb.  If unsure, say N.
 
 endif # NET_TULIP
index 5a96d74e4ce8b89a2d3e2c5b6276c5e2ce725030..a12c9c41b217e582b43a4a36b11d747821b5f6fe 100644 (file)
@@ -93,13 +93,9 @@ config USB_RTL8150
          To compile this driver as a module, choose M here: the
          module will be called rtl8150.
 
-config USB_USBNET_MII
-       tristate
-       default n
-
 config USB_USBNET
        tristate "Multi-purpose USB Networking Framework"
-       select MII if USB_USBNET_MII != n
+       select MII
        ---help---
          This driver supports several kinds of network links over USB,
          with "minidrivers" built around a common network driver core
@@ -135,7 +131,6 @@ config USB_NET_AX8817X
        tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
        depends on USB_USBNET && NET_ETHERNET
        select CRC32
-       select USB_USBNET_MII
        default y
        help
          This option adds support for ASIX AX88xxx based USB 2.0
@@ -190,7 +185,6 @@ config USB_NET_DM9601
        tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
        depends on USB_USBNET
        select CRC32
-       select USB_USBNET_MII
        help
          This option adds support for Davicom DM9601 based USB 1.1
          10/100 Ethernet adapters.
@@ -225,7 +219,6 @@ config USB_NET_PLUSB
 config USB_NET_MCS7830
        tristate "MosChip MCS7830 based Ethernet adapters"
        depends on USB_USBNET
-       select USB_USBNET_MII
        help
          Choose this option if you're using a 10/100 Ethernet USB2
          adapter based on the MosChip 7830 controller. This includes
index acd5f1c0e63a4c79eb4057d39a559ff20166b56a..8ed1fc5cbc7025127ec289b494f433e6545f7ed3 100644 (file)
@@ -683,9 +683,6 @@ done_nopm:
  * they'll probably want to use this base set.
  */
 
-#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE)
-#define HAVE_MII
-
 int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
 {
        struct usbnet *dev = netdev_priv(net);
@@ -744,8 +741,6 @@ int usbnet_nway_reset(struct net_device *net)
 }
 EXPORT_SYMBOL_GPL(usbnet_nway_reset);
 
-#endif /* HAVE_MII */
-
 void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
 {
        struct usbnet *dev = netdev_priv(net);
@@ -776,12 +771,10 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
 /* drivers may override default ethtool_ops in their bind() routine */
 static struct ethtool_ops usbnet_ethtool_ops = {
-#ifdef HAVE_MII
        .get_settings           = usbnet_get_settings,
        .set_settings           = usbnet_set_settings,
        .get_link               = usbnet_get_link,
        .nway_reset             = usbnet_nway_reset,
-#endif
        .get_drvinfo            = usbnet_get_drvinfo,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
index 5c4a92de9a076b703fd63708a3793311d8a5cbd1..450e29d7a9f34118bc24455abcec788e596e9dff 100644 (file)
@@ -1963,6 +1963,11 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
                return -EINVAL;
        }
 
+       if (!netif_running(dev)) {
+               dev->mtu = new_mtu;
+               return 0;
+       }
+
        if (new_mtu != oldmtu) {
                spin_lock_irqsave(&vptr->lock, flags);
 
index e396c9d2af8d8a1aa9b9ca3d8b59a3577de7665f..a75be57fb2097374f0af1e69cc371f6559d8fbdc 100644 (file)
@@ -146,6 +146,7 @@ static void try_fill_recv(struct virtnet_info *vi)
        struct scatterlist sg[1+MAX_SKB_FRAGS];
        int num, err;
 
+       sg_init_table(sg, 1+MAX_SKB_FRAGS);
        for (;;) {
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
                if (unlikely(!skb))
@@ -231,6 +232,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
        const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
        DECLARE_MAC_BUF(mac);
 
+       sg_init_table(sg, 1+MAX_SKB_FRAGS);
+
        pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
 
        free_old_xmit_skbs(vi);
index c48b1cc63fd59d1865d290a9ee0520fb577a9d04..1e89d4de1bb7de00299dab3d4c2792b573ab87f8 100644 (file)
@@ -719,12 +719,8 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
                return 0;
        case SIOCSIFHWADDR:
                return -EINVAL;
-       /* Allow stty to read, but not set, the serial port */
-       case TCGETS:
-       case TCGETA:
-               return n_tty_ioctl(tty, file, cmd, arg);
        default:
-               return -ENOIOCTLCMD;
+               return tty_mode_ioctl(tty, file, cmd, arg);
        }
 }
 
index dae5c8d5a318d96bbd8f4be0603eec001570b5d5..2b733c5829152e37c78aee1ba069d86f0d3f22e6 100644 (file)
@@ -325,7 +325,7 @@ config HERMES
          Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
          IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
          MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
-         PRO/Wireless, and Symbol Spectrum24 High Rate amongst others.
+         IPW2011, and Symbol Spectrum24 High Rate amongst others.
 
          This option includes the guts of the driver, but in order to
          actually use a card you will also need to enable support for PCMCIA
index e3c573e56b6368b72cf25751df30016b1ece3a6b..fdbc351ac333fa8fe61a2134f4e30f221084274b 100644 (file)
@@ -61,16 +61,18 @@ config B43_PCMCIA
 
          If unsure, say N.
 
-# LED support
+# This config option automatically enables b43 LEDS support,
+# if it's possible.
 config B43_LEDS
        bool
-       depends on B43 && MAC80211_LEDS
+       depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43)
        default y
 
-# RFKILL support
+# This config option automatically enables b43 RFKILL support,
+# if it's possible.
 config B43_RFKILL
        bool
-       depends on B43 && RFKILL && RFKILL_INPUT && INPUT_POLLDEV
+       depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
        default y
 
 config B43_DEBUG
index 734e70e1a06d557411b0273d24cf3399d1c6f6be..ef0075d9f9cb81b323425baf56b18fd5523ac067 100644 (file)
@@ -128,7 +128,7 @@ static ssize_t shm_read_file(struct b43_wldev *dev,
        __le16 *le16buf = (__le16 *)buf;
 
        for (i = 0; i < 0x1000; i++) {
-               if (bufsize <= 0)
+               if (bufsize < sizeof(tmp))
                        break;
                tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
                le16buf[i] = cpu_to_le16(tmp);
index 5058e60e5703de6d668d384f5f0d47638994a80b..2b17c1dc46f1e69e30535a74f6b69ed5053ea9a4 100644 (file)
@@ -2985,6 +2985,16 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
 
        if (b43_status(dev) < B43_STAT_STARTED)
                return;
+
+       /* Disable and sync interrupts. We must do this before than
+        * setting the status to INITIALIZED, as the interrupt handler
+        * won't care about IRQs then. */
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+       b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+       b43_synchronize_irq(dev);
+
        b43_set_status(dev, B43_STAT_INITIALIZED);
 
        mutex_unlock(&wl->mutex);
@@ -2995,13 +3005,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
 
        ieee80211_stop_queues(wl->hw);  //FIXME this could cause a deadlock, as mac80211 seems buggy.
 
-       /* Disable and sync interrupts. */
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
-       b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       b43_synchronize_irq(dev);
-
        b43_mac_suspend(dev);
        free_irq(dev->dev->irq, dev);
        b43dbg(wl, "Wireless interface stopped\n");
@@ -3661,7 +3664,6 @@ static int b43_setup_modes(struct b43_wldev *dev,
 
 static void b43_wireless_core_detach(struct b43_wldev *dev)
 {
-       b43_rfkill_free(dev);
        /* We release firmware that late to not be required to re-request
         * is all the time when we reinit the core. */
        b43_release_firmware(dev);
@@ -3747,7 +3749,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        if (!wl->current_dev)
                wl->current_dev = dev;
        INIT_WORK(&dev->restart_work, b43_chip_reset);
-       b43_rfkill_alloc(dev);
 
        b43_radio_turn_off(dev, 1);
        b43_switch_analog(dev, 0);
index b242a9a90dd2309d0f0f8b95de5dd64ab1c6e015..b79a6bd5396d8a050d3f69f4fe8a215e0376825c 100644 (file)
@@ -65,12 +65,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        tuple_t tuple;
        cisparse_t parse;
        int err = -ENOMEM;
-       int res;
+       int res = 0;
        unsigned char buf[64];
 
        ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
        if (!ssb)
-               goto out;
+               goto out_error;
 
        err = -ENODEV;
        tuple.DesiredTuple = CISTPL_CONFIG;
@@ -96,10 +96,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        dev->io.NumPorts2 = 0;
        dev->io.Attributes2 = 0;
 
-       win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+       win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
+                        WIN_ENABLE | WIN_DATA_WIDTH_16 |
+                        WIN_USE_WAIT;
        win.Base = 0;
        win.Size = SSB_CORE_SIZE;
-       win.AccessSpeed = 1000;
+       win.AccessSpeed = 250;
        res = pcmcia_request_window(&dev, &win, &dev->win);
        if (res != CS_SUCCESS)
                goto err_kfree_ssb;
@@ -108,21 +110,34 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        mem.Page = 0;
        res = pcmcia_map_mem_page(dev->win, &mem);
        if (res != CS_SUCCESS)
-               goto err_kfree_ssb;
+               goto err_disable;
+
+       dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
+       dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
+       dev->irq.Handler = NULL; /* The handler is registered later. */
+       dev->irq.Instance = NULL;
+       res = pcmcia_request_irq(dev, &dev->irq);
+       if (res != CS_SUCCESS)
+               goto err_disable;
 
        res = pcmcia_request_configuration(dev, &dev->conf);
        if (res != CS_SUCCESS)
                goto err_disable;
 
        err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
+       if (err)
+               goto err_disable;
        dev->priv = ssb;
 
-      out:
-       return err;
-      err_disable:
+       return 0;
+
+err_disable:
        pcmcia_disable_device(dev);
-      err_kfree_ssb:
+err_kfree_ssb:
        kfree(ssb);
+out_error:
+       printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
+              res, err);
        return err;
 }
 
@@ -131,22 +146,21 @@ static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
        struct ssb_bus *ssb = dev->priv;
 
        ssb_bus_unregister(ssb);
-       pcmcia_release_window(dev->win);
        pcmcia_disable_device(dev);
        kfree(ssb);
        dev->priv = NULL;
 }
 
 static struct pcmcia_driver b43_pcmcia_driver = {
-       .owner = THIS_MODULE,
-       .drv = {
-               .name = "b43-pcmcia",
-               },
-       .id_table = b43_pcmcia_tbl,
-       .probe = b43_pcmcia_probe,
-       .remove = b43_pcmcia_remove,
-       .suspend = b43_pcmcia_suspend,
-       .resume = b43_pcmcia_resume,
+       .owner          = THIS_MODULE,
+       .drv            = {
+                               .name = "b43-pcmcia",
+                       },
+       .id_table       = b43_pcmcia_tbl,
+       .probe          = b43_pcmcia_probe,
+       .remove         = __devexit_p(b43_pcmcia_remove),
+       .suspend        = b43_pcmcia_suspend,
+       .resume         = b43_pcmcia_resume,
 };
 
 int b43_pcmcia_init(void)
index 800e0a61a7f589f1f649b7f6417cf6488267f4d5..9b1f905ffbf4a7a1c61b9b5f4d2463cac78719c7 100644 (file)
@@ -47,32 +47,35 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
        struct b43_wldev *dev = poll_dev->private;
        struct b43_wl *wl = dev->wl;
        bool enabled;
+       bool report_change = 0;
 
        mutex_lock(&wl->mutex);
        B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
        enabled = b43_is_hw_radio_enabled(dev);
        if (unlikely(enabled != dev->radio_hw_enable)) {
                dev->radio_hw_enable = enabled;
+               report_change = 1;
                b43info(wl, "Radio hardware status changed to %s\n",
                        enabled ? "ENABLED" : "DISABLED");
-               mutex_unlock(&wl->mutex);
+       }
+       mutex_unlock(&wl->mutex);
+
+       if (unlikely(report_change))
                input_report_key(poll_dev->input, KEY_WLAN, enabled);
-       } else
-               mutex_unlock(&wl->mutex);
 }
 
-/* Called when the RFKILL toggled in software.
- * This is called without locking. */
+/* Called when the RFKILL toggled in software. */
 static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
 {
        struct b43_wldev *dev = data;
        struct b43_wl *wl = dev->wl;
        int err = 0;
 
-       mutex_lock(&wl->mutex);
-       if (b43_status(dev) < B43_STAT_INITIALIZED)
-               goto out_unlock;
+       if (!wl->rfkill.registered)
+               return 0;
 
+       mutex_lock(&wl->mutex);
+       B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
        switch (state) {
        case RFKILL_STATE_ON:
                if (!dev->radio_hw_enable) {
@@ -89,7 +92,6 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
                        b43_radio_turn_off(dev, 0);
                break;
        }
-
 out_unlock:
        mutex_unlock(&wl->mutex);
 
@@ -98,11 +100,11 @@ out_unlock:
 
 char * b43_rfkill_led_name(struct b43_wldev *dev)
 {
-       struct b43_wl *wl = dev->wl;
+       struct b43_rfkill *rfk = &(dev->wl->rfkill);
 
-       if (!wl->rfkill.rfkill)
+       if (!rfk->registered)
                return NULL;
-       return rfkill_get_led_name(wl->rfkill.rfkill);
+       return rfkill_get_led_name(rfk->rfkill);
 }
 
 void b43_rfkill_init(struct b43_wldev *dev)
@@ -111,53 +113,13 @@ void b43_rfkill_init(struct b43_wldev *dev)
        struct b43_rfkill *rfk = &(wl->rfkill);
        int err;
 
-       if (rfk->rfkill) {
-               err = rfkill_register(rfk->rfkill);
-               if (err) {
-                       b43warn(wl, "Failed to register RF-kill button\n");
-                       goto err_free_rfk;
-               }
-       }
-       if (rfk->poll_dev) {
-               err = input_register_polled_device(rfk->poll_dev);
-               if (err) {
-                       b43warn(wl, "Failed to register RF-kill polldev\n");
-                       goto err_free_polldev;
-               }
-       }
-
-       return;
-err_free_rfk:
-       rfkill_free(rfk->rfkill);
-       rfk->rfkill = NULL;
-err_free_polldev:
-       input_free_polled_device(rfk->poll_dev);
-       rfk->poll_dev = NULL;
-}
-
-void b43_rfkill_exit(struct b43_wldev *dev)
-{
-       struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (rfk->poll_dev)
-               input_unregister_polled_device(rfk->poll_dev);
-       if (rfk->rfkill)
-               rfkill_unregister(rfk->rfkill);
-}
-
-void b43_rfkill_alloc(struct b43_wldev *dev)
-{
-       struct b43_wl *wl = dev->wl;
-       struct b43_rfkill *rfk = &(wl->rfkill);
+       rfk->registered = 0;
 
+       rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
+       if (!rfk->rfkill)
+               goto out_error;
        snprintf(rfk->name, sizeof(rfk->name),
                 "b43-%s", wiphy_name(wl->hw->wiphy));
-
-       rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
-       if (!rfk->rfkill) {
-               b43warn(wl, "Failed to allocate RF-kill button\n");
-               return;
-       }
        rfk->rfkill->name = rfk->name;
        rfk->rfkill->state = RFKILL_STATE_ON;
        rfk->rfkill->data = dev;
@@ -165,18 +127,45 @@ void b43_rfkill_alloc(struct b43_wldev *dev)
        rfk->rfkill->user_claim_unsupported = 1;
 
        rfk->poll_dev = input_allocate_polled_device();
-       if (rfk->poll_dev) {
-               rfk->poll_dev->private = dev;
-               rfk->poll_dev->poll = b43_rfkill_poll;
-               rfk->poll_dev->poll_interval = 1000; /* msecs */
-       } else
-               b43warn(wl, "Failed to allocate RF-kill polldev\n");
+       if (!rfk->poll_dev)
+               goto err_free_rfk;
+       rfk->poll_dev->private = dev;
+       rfk->poll_dev->poll = b43_rfkill_poll;
+       rfk->poll_dev->poll_interval = 1000; /* msecs */
+
+       err = rfkill_register(rfk->rfkill);
+       if (err)
+               goto err_free_polldev;
+       err = input_register_polled_device(rfk->poll_dev);
+       if (err)
+               goto err_unreg_rfk;
+
+       rfk->registered = 1;
+
+       return;
+err_unreg_rfk:
+       rfkill_unregister(rfk->rfkill);
+err_free_polldev:
+       input_free_polled_device(rfk->poll_dev);
+       rfk->poll_dev = NULL;
+err_free_rfk:
+       rfkill_free(rfk->rfkill);
+       rfk->rfkill = NULL;
+out_error:
+       rfk->registered = 0;
+       b43warn(wl, "RF-kill button init failed\n");
 }
 
-void b43_rfkill_free(struct b43_wldev *dev)
+void b43_rfkill_exit(struct b43_wldev *dev)
 {
        struct b43_rfkill *rfk = &(dev->wl->rfkill);
 
+       if (!rfk->registered)
+               return;
+       rfk->registered = 0;
+
+       input_unregister_polled_device(rfk->poll_dev);
+       rfkill_unregister(rfk->rfkill);
        input_free_polled_device(rfk->poll_dev);
        rfk->poll_dev = NULL;
        rfkill_free(rfk->rfkill);
index 29544e8c9e5f41e45878fda6d80941aaa264f0dd..adacf936d815be2170b973da1cbb997fff7b974b 100644 (file)
@@ -15,14 +15,14 @@ struct b43_rfkill {
        struct rfkill *rfkill;
        /* The poll device for the RFKILL input button */
        struct input_polled_dev *poll_dev;
+       /* Did initialization succeed? Used for freeing. */
+       bool registered;
        /* The unique name of this rfkill switch */
-       char name[32];
+       char name[sizeof("b43-phy4294967295")];
 };
 
-/* All the init functions return void, because we are not interested
+/* The init function returns void, because we are not interested
  * in failing the b43 init process when rfkill init failed. */
-void b43_rfkill_alloc(struct b43_wldev *dev);
-void b43_rfkill_free(struct b43_wldev *dev);
 void b43_rfkill_init(struct b43_wldev *dev);
 void b43_rfkill_exit(struct b43_wldev *dev);
 
@@ -36,12 +36,6 @@ struct b43_rfkill {
        /* empty */
 };
 
-static inline void b43_rfkill_alloc(struct b43_wldev *dev)
-{
-}
-static inline void b43_rfkill_free(struct b43_wldev *dev)
-{
-}
 static inline void b43_rfkill_init(struct b43_wldev *dev)
 {
 }
index eefa6fb79685d3b5f2c20eb0d312cc05220f66fe..619b4534ef09b24a9c1512106c2002c83ad7354e 100644 (file)
@@ -124,7 +124,7 @@ static ssize_t shm_read_file(struct b43legacy_wldev *dev, char *buf, size_t bufs
        __le16 *le16buf = (__le16 *)buf;
 
        for (i = 0; i < 0x1000; i++) {
-               if (bufsize <= 0)
+               if (bufsize < sizeof(tmp))
                        break;
                tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 2 * i);
                le16buf[i] = cpu_to_le16(tmp);
index f0e56dfc9ecf7520928e089d197907fd3fe1f527..3bde1e9ab4282e00b34353da4185923a4d0fdacc 100644 (file)
@@ -2781,6 +2781,17 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
 
        if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
                return;
+
+       /* Disable and sync interrupts. We must do this before than
+        * setting the status to INITIALIZED, as the interrupt handler
+        * won't care about IRQs then. */
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       dev->irq_savedstate = b43legacy_interrupt_disable(dev,
+                                                         B43legacy_IRQ_ALL);
+       b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+       b43legacy_synchronize_irq(dev);
+
        b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
 
        mutex_unlock(&wl->mutex);
@@ -2791,14 +2802,6 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
 
        ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */
 
-       /* Disable and sync interrupts. */
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       dev->irq_savedstate = b43legacy_interrupt_disable(dev,
-                                                         B43legacy_IRQ_ALL);
-       b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       b43legacy_synchronize_irq(dev);
-
        b43legacy_mac_suspend(dev);
        free_irq(dev->dev->irq, dev);
        b43legacydbg(wl, "Wireless interface stopped\n");
@@ -3332,7 +3335,7 @@ out_mutex_unlock:
        return err;
 }
 
-void b43legacy_stop(struct ieee80211_hw *hw)
+static void b43legacy_stop(struct ieee80211_hw *hw)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
index 7da3664b85156a2541728f2f68ce82d887267d0f..fc876ba185721533649f6fa3a31565afdd7e117c 100644 (file)
@@ -444,7 +444,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
 
 MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
 
-static struct pci_driver prism2_pci_drv_id = {
+static struct pci_driver prism2_pci_driver = {
        .name           = "hostap_pci",
        .id_table       = prism2_pci_id_table,
        .probe          = prism2_pci_probe,
@@ -458,13 +458,13 @@ static struct pci_driver prism2_pci_drv_id = {
 
 static int __init init_prism2_pci(void)
 {
-       return pci_register_driver(&prism2_pci_drv_id);
+       return pci_register_driver(&prism2_pci_driver);
 }
 
 
 static void __exit exit_prism2_pci(void)
 {
-       pci_unregister_driver(&prism2_pci_drv_id);
+       pci_unregister_driver(&prism2_pci_driver);
 }
 
 
index 8d53d08b9691773ac36f1e2e3274d85a0a940853..fc6cdd8086c1b2c49da2d7857682cda1870ee3e1 100644 (file)
@@ -1267,7 +1267,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
                                       IPW2100_INTA_FATAL_ERROR |
                                       IPW2100_INTA_PARITY_ERROR);
                }
-       } while (i--);
+       } while (--i);
 
        /* Clear out any pending INTAs since we aren't supposed to have
         * interrupts enabled at this point... */
@@ -1339,7 +1339,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
 
                if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
                        break;
-       } while (i--);
+       } while (--i);
 
        priv->status &= ~STATUS_RESET_PENDING;
 
index 262ab0b55824d907048d1081db1a473ad02d4852..c48b1b537d2b412fa5ccbc8cf1f156e911d44908 100644 (file)
@@ -71,19 +71,19 @@ struct iwl_rate_scale_priv {
 };
 
 static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
-       0, 0, 76, 104, 130, 168, 191, 202, 7, 13, 35, 58
+       7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
 };
 
 static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
-       0, 0, 0, 80, 93, 113, 123, 125, 7, 13, 35, 58
+       7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
 };
 
 static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
-       40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0, 0
+       0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
 };
 
 static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 7, 13, 35, 58
+       7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 struct iwl_tpt_entry {
@@ -350,6 +350,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 
        sta->last_txrate = sta->txrate;
 
+       /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */
+        if (local->hw.conf.phymode == MODE_IEEE80211A)
+                sta->last_txrate += IWL_FIRST_OFDM_RATE;
+
        IWL_DEBUG_RATE("leave\n");
 }
 
@@ -417,6 +421,33 @@ static void rs_free_sta(void *priv, void *priv_sta)
        IWL_DEBUG_RATE("leave\n");
 }
 
+
+/*
+ * get ieee prev rate from rate scale table.
+ * for A and B mode we need to overright prev
+ * value
+ */
+static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
+{
+       int next_rate = iwl_get_prev_ieee_rate(rate);
+
+       switch (priv->phymode) {
+       case MODE_IEEE80211A:
+               if (rate == IWL_RATE_12M_INDEX)
+                       next_rate = IWL_RATE_9M_INDEX;
+               else if (rate == IWL_RATE_6M_INDEX)
+                       next_rate = IWL_RATE_6M_INDEX;
+               break;
+       case MODE_IEEE80211B:
+               if (rate == IWL_RATE_11M_INDEX_TABLE)
+                       next_rate = IWL_RATE_5M_INDEX_TABLE;
+               break;
+       default:
+               break;
+       }
+
+       return next_rate;
+}
 /**
  * rs_tx_status - Update rate control values based on Tx results
  *
@@ -479,7 +510,8 @@ static void rs_tx_status(void *priv_rate,
                        last_index = scale_rate_index;
                } else {
                        current_count = priv->retry_rate;
-                       last_index = iwl_get_prev_ieee_rate(scale_rate_index);
+                       last_index = rs_adjust_next_rate(priv,
+                                                        scale_rate_index);
                }
 
                /* Update this rate accounting for as many retries
@@ -494,9 +526,10 @@ static void rs_tx_status(void *priv_rate,
 
                if (retries)
                        scale_rate_index =
-                           iwl_get_prev_ieee_rate(scale_rate_index);
+                           rs_adjust_next_rate(priv, scale_rate_index);
        }
 
+
        /* Update the last index window with success/failure based on ACK */
        IWL_DEBUG_RATE("Update rate %d with %s.\n",
                       last_index,
@@ -672,7 +705,10 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
        }
 
        rate_mask = sta->supp_rates;
-       index = min(sta->txrate & 0xffff, IWL_RATE_COUNT - 1);
+       index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1);
+
+       if (priv->phymode == (u8) MODE_IEEE80211A)
+               rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
 
        rs_priv = (void *)sta->rate_ctrl_priv;
 
@@ -801,7 +837,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
  out:
 
        sta->last_txrate = index;
-       sta->txrate = sta->last_txrate;
+       if (priv->phymode == (u8) MODE_IEEE80211A)
+               sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE;
+       else
+               sta->txrate = sta->last_txrate;
+
        sta_info_put(sta);
 
        IWL_DEBUG_RATE("leave: %d\n", index);
index b926738e0ea1b8725356e875d4a90f4c4972d44a..bec4d3ffca1d033c36e0888108c365777821da4b 100644 (file)
@@ -36,10 +36,17 @@ struct iwl_rate_info {
        u8 next_rs;             /* next rate used in rs algo */
        u8 prev_rs_tgg;         /* previous rate used in TGG rs algo */
        u8 next_rs_tgg;         /* next rate used in TGG rs algo */
+        u8 table_rs_index;     /* index in rate scale table cmd */
+        u8 prev_table_rs;      /* prev in rate table cmd */
+
 };
 
 enum {
-       IWL_RATE_6M_INDEX = 0,
+       IWL_RATE_1M_INDEX = 0,
+       IWL_RATE_2M_INDEX,
+       IWL_RATE_5M_INDEX,
+       IWL_RATE_11M_INDEX,
+       IWL_RATE_6M_INDEX,
        IWL_RATE_9M_INDEX,
        IWL_RATE_12M_INDEX,
        IWL_RATE_18M_INDEX,
@@ -47,15 +54,27 @@ enum {
        IWL_RATE_36M_INDEX,
        IWL_RATE_48M_INDEX,
        IWL_RATE_54M_INDEX,
-       IWL_RATE_1M_INDEX,
-       IWL_RATE_2M_INDEX,
-       IWL_RATE_5M_INDEX,
-       IWL_RATE_11M_INDEX,
        IWL_RATE_COUNT,
        IWL_RATE_INVM_INDEX,
        IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
 };
 
+enum {
+       IWL_RATE_6M_INDEX_TABLE = 0,
+       IWL_RATE_9M_INDEX_TABLE,
+       IWL_RATE_12M_INDEX_TABLE,
+       IWL_RATE_18M_INDEX_TABLE,
+       IWL_RATE_24M_INDEX_TABLE,
+       IWL_RATE_36M_INDEX_TABLE,
+       IWL_RATE_48M_INDEX_TABLE,
+       IWL_RATE_54M_INDEX_TABLE,
+       IWL_RATE_1M_INDEX_TABLE,
+       IWL_RATE_2M_INDEX_TABLE,
+       IWL_RATE_5M_INDEX_TABLE,
+       IWL_RATE_11M_INDEX_TABLE,
+       IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
+};
+
 enum {
        IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
        IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
index 19bcb01e278429c83053b1dbd891a4307a668c0e..3a45fe99a83e72c4a3786787e347e12f4a480103 100644 (file)
@@ -54,7 +54,9 @@
                                    IWL_RATE_##rp##M_INDEX, \
                                    IWL_RATE_##rn##M_INDEX, \
                                    IWL_RATE_##pp##M_INDEX, \
-                                   IWL_RATE_##np##M_INDEX }
+                                   IWL_RATE_##np##M_INDEX, \
+                                   IWL_RATE_##r##M_INDEX_TABLE, \
+                                   IWL_RATE_##ip##M_INDEX_TABLE }
 
 /*
  * Parameter order:
  *
  */
 const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+       IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),    /*  1mbps */
+       IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),          /*  2mbps */
+       IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
+       IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18),      /* 11mbps */
        IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
        IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11),       /*  9mbps */
        IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
@@ -73,10 +79,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
        IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
        IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
        IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
-       IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),    /*  1mbps */
-       IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),          /*  2mbps */
-       IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
-       IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18),      /* 11mbps */
 };
 
 /* 1 = enable the iwl_disable_events() function */
@@ -662,10 +664,11 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
        cmd->cmd.tx.tx_flags = tx_flags;
 
        /* OFDM */
-       cmd->cmd.tx.supp_rates[0] = rate_mask & IWL_OFDM_RATES_MASK;
+       cmd->cmd.tx.supp_rates[0] =
+          ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
 
        /* CCK */
-       cmd->cmd.tx.supp_rates[1] = (rate_mask >> 8) & 0xF;
+       cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
 
        IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
                       "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
@@ -1432,7 +1435,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
        /* use this channel group's 6Mbit clipping/saturation pwr,
         *   but cap at regulatory scan power restriction (set during init
         *   based on eeprom channel data) for this channel.  */
-       power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX]);
+       power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]);
 
        /* further limit to user's max power preference.
         * FIXME:  Other spectrum management power limitations do not
@@ -1447,7 +1450,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
         *   *index*. */
        power_index = ch_info->power_info[rate_index].power_table_index
            - (power - ch_info->power_info
-              [IWL_RATE_6M_INDEX].requested_power) * 2;
+              [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2;
 
        /* store reference index that we use when adjusting *all* scan
         *   powers.  So we can accommodate user (all channel) or spectrum
@@ -1476,7 +1479,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
  */
 int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
 {
-       int rate_idx;
+       int rate_idx, i;
        const struct iwl_channel_info *ch_info = NULL;
        struct iwl_txpowertable_cmd txpower = {
                .channel = priv->active_rxon.channel,
@@ -1500,20 +1503,36 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
        }
 
        /* fill cmd with power settings for all rates for current channel */
-       for (rate_idx = 0; rate_idx < IWL_RATE_COUNT; rate_idx++) {
-               txpower.power[rate_idx].tpc = ch_info->power_info[rate_idx].tpc;
-               txpower.power[rate_idx].rate = iwl_rates[rate_idx].plcp;
+       /* Fill OFDM rate */
+       for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
+            rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
+
+               txpower.power[i].tpc = ch_info->power_info[i].tpc;
+               txpower.power[i].rate = iwl_rates[rate_idx].plcp;
 
                IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
                                le16_to_cpu(txpower.channel),
                                txpower.band,
-                               txpower.power[rate_idx].tpc.tx_gain,
-                               txpower.power[rate_idx].tpc.dsp_atten,
-                               txpower.power[rate_idx].rate);
+                               txpower.power[i].tpc.tx_gain,
+                               txpower.power[i].tpc.dsp_atten,
+                               txpower.power[i].rate);
+       }
+       /* Fill CCK rates */
+       for (rate_idx = IWL_FIRST_CCK_RATE;
+            rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) {
+               txpower.power[i].tpc = ch_info->power_info[i].tpc;
+               txpower.power[i].rate = iwl_rates[rate_idx].plcp;
+
+               IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+                               le16_to_cpu(txpower.channel),
+                               txpower.band,
+                               txpower.power[i].tpc.tx_gain,
+                               txpower.power[i].tpc.dsp_atten,
+                               txpower.power[i].rate);
        }
 
        return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
-                               sizeof(struct iwl_txpowertable_cmd), &txpower);
+                       sizeof(struct iwl_txpowertable_cmd), &txpower);
 
 }
 
@@ -1549,7 +1568,7 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
        power_info = ch_info->power_info;
 
        /* update OFDM Txpower settings */
-       for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_OFDM_RATE;
+       for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE;
             i++, ++power_info) {
                int delta_idx;
 
@@ -1573,14 +1592,14 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
         *    ... all CCK power settings for a given channel are the *same*. */
        if (power_changed) {
                power =
-                   ch_info->power_info[IWL_RATE_12M_INDEX].
+                   ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
                    requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF;
 
                /* do all CCK rates' iwl_channel_power_info structures */
-               for (i = IWL_FIRST_CCK_RATE; i <= IWL_LAST_CCK_RATE; i++) {
+               for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) {
                        power_info->requested_power = power;
                        power_info->base_power_index =
-                           ch_info->power_info[IWL_RATE_12M_INDEX].
+                           ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
                            base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF;
                        ++power_info;
                }
@@ -1674,7 +1693,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
                for (scan_tbl_index = 0;
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
                        s32 actual_index = (scan_tbl_index == 0) ?
-                           IWL_RATE_1M_INDEX : IWL_RATE_6M_INDEX;
+                           IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
                        iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
                                           actual_index, clip_pwrs,
                                           ch_info, a_band);
@@ -1905,19 +1924,19 @@ static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv)
                for (rate_index = 0;
                     rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
                        switch (rate_index) {
-                       case IWL_RATE_36M_INDEX:
+                       case IWL_RATE_36M_INDEX_TABLE:
                                if (i == 0)     /* B/G */
                                        *clip_pwrs = satur_pwr;
                                else    /* A */
                                        *clip_pwrs = satur_pwr - 5;
                                break;
-                       case IWL_RATE_48M_INDEX:
+                       case IWL_RATE_48M_INDEX_TABLE:
                                if (i == 0)
                                        *clip_pwrs = satur_pwr - 7;
                                else
                                        *clip_pwrs = satur_pwr - 10;
                                break;
-                       case IWL_RATE_54M_INDEX:
+                       case IWL_RATE_54M_INDEX_TABLE:
                                if (i == 0)
                                        *clip_pwrs = satur_pwr - 9;
                                else
@@ -2031,7 +2050,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                }
 
                /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/
-               pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX];
+               pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE];
                power = pwr_info->requested_power +
                        IWL_CCK_FROM_OFDM_POWER_DIFF;
                pwr_index = pwr_info->power_table_index +
@@ -2047,9 +2066,9 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                /* fill each CCK rate's iwl_channel_power_info structure
                 * NOTE:  All CCK-rate Txpwrs are the same for a given chnl!
                 * NOTE:  CCK rates start at end of OFDM rates! */
-               for (rate_index = IWL_OFDM_RATES;
-                    rate_index < IWL_RATE_COUNT; rate_index++) {
-                       pwr_info = &ch_info->power_info[rate_index];
+               for (rate_index = 0;
+                    rate_index < IWL_CCK_RATES; rate_index++) {
+                       pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES];
                        pwr_info->requested_power = power;
                        pwr_info->power_table_index = pwr_index;
                        pwr_info->base_power_index = base_pwr_index;
@@ -2061,7 +2080,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                for (scan_tbl_index = 0;
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
                        s32 actual_index = (scan_tbl_index == 0) ?
-                               IWL_RATE_1M_INDEX : IWL_RATE_6M_INDEX;
+                               IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
                        iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
                                actual_index, clip_pwrs, ch_info, a_band);
                }
@@ -2139,17 +2158,20 @@ int iwl_hw_get_rx_read(struct iwl_priv *priv)
  */
 int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
 {
-       int rc, i;
+       int rc, i, index, prev_index;
        struct iwl_rate_scaling_cmd rate_cmd = {
                .reserved = {0, 0, 0},
        };
        struct iwl_rate_scaling_info *table = rate_cmd.table;
 
        for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) {
-               table[i].rate_n_flags =
+               index = iwl_rates[i].table_rs_index;
+
+               table[index].rate_n_flags =
                        iwl_hw_set_rate_n_flags(iwl_rates[i].plcp, 0);
-               table[i].try_cnt = priv->retry_rate;
-               table[i].next_rate_index = iwl_get_prev_ieee_rate(i);
+               table[index].try_cnt = priv->retry_rate;
+               prev_index = iwl_get_prev_ieee_rate(i);
+               table[index].next_rate_index = iwl_rates[prev_index].table_rs_index;
        }
 
        switch (priv->phymode) {
@@ -2157,26 +2179,26 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
                IWL_DEBUG_RATE("Select A mode rate scale\n");
                /* If one of the following CCK rates is used,
                 * have it fall back to the 6M OFDM rate */
-               for (i = IWL_FIRST_CCK_RATE; i <= IWL_LAST_CCK_RATE; i++)
-                       table[i].next_rate_index = IWL_FIRST_OFDM_RATE;
+               for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
+                       table[i].next_rate_index = iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
 
                /* Don't fall back to CCK rates */
-               table[IWL_RATE_12M_INDEX].next_rate_index = IWL_RATE_9M_INDEX;
+               table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
 
                /* Don't drop out of OFDM rates */
-               table[IWL_FIRST_OFDM_RATE].next_rate_index =
-                   IWL_FIRST_OFDM_RATE;
+               table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
+                   iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
                break;
 
        case MODE_IEEE80211B:
                IWL_DEBUG_RATE("Select B mode rate scale\n");
                /* If an OFDM rate is used, have it fall back to the
                 * 1M CCK rates */
-               for (i = IWL_FIRST_OFDM_RATE; i <= IWL_LAST_OFDM_RATE; i++)
-                       table[i].next_rate_index = IWL_FIRST_CCK_RATE;
+               for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
+                       table[i].next_rate_index = iwl_rates[IWL_FIRST_CCK_RATE].table_rs_index;
 
                /* CCK shouldn't fall back to OFDM... */
-               table[IWL_RATE_11M_INDEX].next_rate_index = IWL_RATE_5M_INDEX;
+               table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
                break;
 
        default:
@@ -2248,22 +2270,12 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
        tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
                                      TX_CMD_FLG_TSF_MSK);
 
-       /* supp_rates[0] == OFDM  */
-       tx_beacon_cmd->tx.supp_rates[0] = IWL_OFDM_BASIC_RATES_MASK;
-
-       /* supp_rates[1] == CCK
-        *
-        * NOTE:  IWL_*_RATES_MASK are not in the order that supp_rates
-        * expects so we have to shift them around.
-        *
-        * supp_rates expects:
-        * CCK rates are bit0..3
-        *
-        * However IWL_*_RATES_MASK has:
-        * CCK rates are bit8..11
-        */
+       /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/
+       tx_beacon_cmd->tx.supp_rates[0] =
+               (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+
        tx_beacon_cmd->tx.supp_rates[1] =
-               (IWL_CCK_BASIC_RATES_MASK >> 8) & 0xF;
+               (IWL_CCK_BASIC_RATES_MASK & 0xF);
 
        return (sizeof(struct iwl_tx_beacon_cmd) + frame_size);
 }
index 4f22a7174caff31747511ced655ac0ce12a375cc..465da4f67ce73d0fcfb9b1b9c7440d1b131dd2af 100644 (file)
@@ -4850,7 +4850,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
                /* Hardware disappeared */
                IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
-               goto none;
+               goto unplugged;
        }
 
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -4858,6 +4858,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        tasklet_schedule(&priv->irq_tasklet);
+unplugged:
        spin_unlock(&priv->lock);
 
        return IRQ_HANDLED;
@@ -5331,13 +5332,13 @@ static int iwl_init_geos(struct iwl_priv *priv)
        /* 5.2GHz channels start after the 2.4GHz channels */
        modes[A].mode = MODE_IEEE80211A;
        modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
-       modes[A].rates = rates;
+       modes[A].rates = &rates[4];
        modes[A].num_rates = 8; /* just OFDM */
        modes[A].num_channels = 0;
 
        modes[B].mode = MODE_IEEE80211B;
        modes[B].channels = channels;
-       modes[B].rates = &rates[8];
+       modes[B].rates = rates;
        modes[B].num_rates = 4; /* just CCK */
        modes[B].num_channels = 0;
 
@@ -8354,6 +8355,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
+       hw->rate_control_algorithm = "iwl-3945-rs";
+
        IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
index d60adcb9bd4ac1e93b70c5268dea7400e84976f2..9918780f5e866fe8286fb85c970b815c981b4968 100644 (file)
@@ -5156,9 +5156,10 @@ static irqreturn_t iwl_isr(int irq, void *data)
        }
 
        if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
-               /* Hardware disappeared */
+               /* Hardware disappeared. It might have already raised
+                * an interrupt */
                IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
-               goto none;
+               goto unplugged;
        }
 
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -5166,8 +5167,9 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        tasklet_schedule(&priv->irq_tasklet);
-       spin_unlock(&priv->lock);
 
+ unplugged:
+       spin_unlock(&priv->lock);
        return IRQ_HANDLED;
 
  none:
@@ -8955,6 +8957,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
+       hw->rate_control_algorithm = "iwl-4965-rs";
+
        IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
index 1cbbd96fdbde913200fac048a1b2c62fef54fb36..be5cfd8402c7bae331e2105b08f946484d2cd729 100644 (file)
@@ -912,6 +912,10 @@ static int wlan_cmd_set_boot2_ver(wlan_private * priv,
        return 0;
 }
 
+/*
+ * Note: NEVER use libertas_queue_cmd() with addtail==0 other than for
+ * the command timer, because it does not account for queued commands.
+ */
 void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
 {
        unsigned long flags;
@@ -941,10 +945,11 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
 
        spin_lock_irqsave(&adapter->driver_lock, flags);
 
-       if (addtail)
+       if (addtail) {
                list_add_tail((struct list_head *)cmdnode,
                              &adapter->cmdpendingq);
-       else
+               adapter->nr_cmd_pending++;
+       } else
                list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
 
        spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1412,7 +1417,6 @@ int libertas_prepare_and_send_command(wlan_private * priv,
        cmdnode->cmdwaitqwoken = 0;
 
        libertas_queue_cmd(adapter, cmdnode, 1);
-       adapter->nr_cmd_pending++;
        wake_up_interruptible(&priv->waitq);
 
        if (wait_option & CMD_OPTION_WAITFORRSP) {
index 0360cad363a8dacd314be2fb57272daed142c1af..ec89dabc412c6560a290ac1f833f339e1da5445d 100644 (file)
@@ -148,11 +148,11 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
 {
        int i;
 
-       for (i = 0; i < 500; i++) {
+       for (i = 0; i < 1000; i++) {
                u8 val = if_cs_read8(card, addr);
                if (val == reg)
                        return i;
-               udelay(100);
+               udelay(500);
        }
        return -ETIME;
 }
@@ -878,6 +878,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
                goto out3;
        }
 
+       /* Clear any interrupt cause that happend while sending
+        * firmware/initializing card */
+       if_cs_write16(card, IF_CS_C_INT_CAUSE, IF_CS_C_IC_MASK);
        if_cs_enable_ints(card);
 
        /* And finally bring the card up */
index a8e17076e7def898a6aa477deef931d9f0ac624a..b24425f748830b9767a290d3aac038cf6b64caf9 100644 (file)
@@ -182,12 +182,14 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
                goto out;
        }
 
-       skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+       skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN);
        if (!skb) {
                ret = -ENOMEM;
                goto out;
        }
 
+       skb_reserve(skb, NET_IP_ALIGN);
+
        data = skb_put(skb, size);
 
        memcpy(data, buffer, size);
index ff2d63267b19e8acb41b356e8524e3451014f291..702321c30164d6e46310b9f959c4497a27d68bb9 100644 (file)
@@ -620,7 +620,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
         * up to version C the link tuning should halt after 20
         * seconds.
         */
-       if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
+       if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
            rt2x00dev->link.count > 20)
                return;
 
@@ -630,7 +630,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
         * Chipset versions C and lower should directly continue
         * to the dynamic CCA tuning.
         */
-       if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
+       if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
                goto dynamic_cca_tune;
 
        /*
index 7cdc80a122bb9aaa10b9f9eb514fad6c1d0005de..277a020b35e9039c994e583c1c0a276c11511e1a 100644 (file)
@@ -753,7 +753,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
        rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
-       if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
+       if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
                rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
                reg &= ~0x0002;
        } else {
@@ -1257,7 +1257,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
 
-       if (rt2x00_rev(&rt2x00dev->chip, 0xffff0)) {
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
index 9845e584b731a48454ebf0ccf08ef606dffb8ea8..d1ad5251a77a89d1f0afbee37c2ebf1dd77f328a 100644 (file)
@@ -751,14 +751,16 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
        return (chipset->rf == chip);
 }
 
-static inline u16 rt2x00_get_rev(const struct rt2x00_chip *chipset)
+static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
 {
        return chipset->rev;
 }
 
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset, const u32 mask)
+static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
+                                  const u32 rev)
 {
-       return chipset->rev & mask;
+       return (((chipset->rev & 0xffff0) == rev) &&
+               !!(chipset->rev & 0x0000f));
 }
 
 /*
index 4a6a0bd01ff192ead09ab3b929f33f57f7c18882..85ea8a8e658ef52641702a614d4d75b4e2857e60 100644 (file)
@@ -196,6 +196,14 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct interface *intf = &rt2x00dev->interface;
 
+       /* FIXME: Beaconing is broken in rt2x00. */
+       if (conf->type == IEEE80211_IF_TYPE_IBSS ||
+           conf->type == IEEE80211_IF_TYPE_AP) {
+               ERROR(rt2x00dev,
+                     "rt2x00 does not support Adhoc or Master mode");
+               return -EOPNOTSUPP;
+       }
+
        /*
         * Don't allow interfaces to be added while
         * either the device has disappeared or when
index 46c8c0840a6531703ed85d31a0604598502f4baf..dc640bf6b5ebe86f3b4ee99cb29e871949e8da8c 100644 (file)
@@ -1486,7 +1486,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
 
-       if (!rt2x00_rev(&rt2x00dev->chip, 0x25730)) {
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
index 4bd14b331862948f558a74955b9c191b7f4502f4..88efe1bae58f5333d933c93ec21ac0b6aa09c42b 100644 (file)
@@ -2735,16 +2735,8 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
                        return -EFAULT;
                return set_mac_address(strip_info, &addr);
        }
-       /*
-        * Allow stty to read, but not set, the serial port
-        */
-
-       case TCGETS:
-       case TCGETA:
-               return n_tty_ioctl(tty, file, cmd, arg);
-               break;
        default:
-               return -ENOIOCTLCMD;
+               return tty_mode_ioctl(tty, file, cmd, arg);
                break;
        }
        return 0;
index a83c3db7d18fb81a1cd58347ea22ce12a8f9b29c..c93d3d2640ab884b2a4d43a4339afd2613cd149d 100644 (file)
@@ -64,6 +64,8 @@ int alloc_cpu_buffers(void)
                b->head_pos = 0;
                b->sample_received = 0;
                b->sample_lost_overflow = 0;
+               b->backtrace_aborted = 0;
+               b->sample_invalid_eip = 0;
                b->cpu = i;
                INIT_DELAYED_WORK(&b->work, wq_sync_buffer);
        }
@@ -175,6 +177,11 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
 
        cpu_buf->sample_received++;
 
+       if (pc == ESCAPE_CODE) {
+               cpu_buf->sample_invalid_eip++;
+               return 0;
+       }
+
        if (nr_available_slots(cpu_buf) < 3) {
                cpu_buf->sample_lost_overflow++;
                return 0;
index 49900d9e3235e613cde4e7387a3ce0acd9a10f45..c66c025abe757804f3cea7cfc389103293762c58 100644 (file)
@@ -42,6 +42,7 @@ struct oprofile_cpu_buffer {
        unsigned long sample_received;
        unsigned long sample_lost_overflow;
        unsigned long backtrace_aborted;
+       unsigned long sample_invalid_eip;
        int cpu;
        struct delayed_work work;
 } ____cacheline_aligned;
index f0acb661c25391dc81902543210067a3e40c9248..d1f6d776e9e441ea31272d4b3b4bd58a6a927c6a 100644 (file)
@@ -26,6 +26,8 @@ void oprofile_reset_stats(void)
                cpu_buf = &cpu_buffer[i]; 
                cpu_buf->sample_received = 0;
                cpu_buf->sample_lost_overflow = 0;
+               cpu_buf->backtrace_aborted = 0;
+               cpu_buf->sample_invalid_eip = 0;
        }
  
        atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
@@ -61,6 +63,8 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root)
                        &cpu_buf->sample_lost_overflow);
                oprofilefs_create_ro_ulong(sb, cpudir, "backtrace_aborted",
                        &cpu_buf->backtrace_aborted);
+               oprofilefs_create_ro_ulong(sb, cpudir, "sample_invalid_eip",
+                       &cpu_buf->sample_invalid_eip);
        }
  
        oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm",
index 7a1d6d51283747825aeb9eba5faca5f6440e5cf9..e1ca42591ac463b36e3de6fee4ff829e7040abf3 100644 (file)
@@ -21,6 +21,17 @@ config PCI_MSI
 
           If you don't know what to do here, say N.
 
+config PCI_LEGACY
+       bool "Enable deprecated pci_find_* API"
+       depends on PCI
+       default y
+       help
+         Say Y here if you want to include support for the deprecated
+         pci_find_slot() and pci_find_device() APIs.  Most drivers have
+         been converted over to using the proper hotplug APIs, so this
+         option serves to include/exclude only a few drivers that are
+         still using this API.
+
 config PCI_DEBUG
        bool "PCI Debugging"
        depends on PCI && DEBUG_KERNEL
index 63d62752fb913afd7b9de146f7437bf9622c94e3..a64449d489d635b9743ce79f2cf52c8904feb125 100644 (file)
@@ -41,7 +41,7 @@ config HOTPLUG_PCI_FAKE
 
 config HOTPLUG_PCI_COMPAQ
        tristate "Compaq PCI Hotplug driver"
-       depends on X86 && PCI_BIOS
+       depends on X86 && PCI_BIOS && PCI_LEGACY
        help
          Say Y here if you have a motherboard with a Compaq PCI Hotplug
          controller.
@@ -63,7 +63,7 @@ config HOTPLUG_PCI_COMPAQ_NVRAM
 
 config HOTPLUG_PCI_IBM
        tristate "IBM PCI Hotplug driver"
-       depends on X86_IO_APIC && X86 && PCI_BIOS
+       depends on X86_IO_APIC && X86 && PCI_BIOS && PCI_LEGACY
        help
          Say Y here if you have a motherboard with a IBM PCI Hotplug
          controller.
@@ -119,7 +119,7 @@ config HOTPLUG_PCI_CPCI_ZT5550
 
 config HOTPLUG_PCI_CPCI_GENERIC
        tristate "Generic port I/O CompactPCI Hotplug driver"
-       depends on HOTPLUG_PCI_CPCI && X86
+       depends on HOTPLUG_PCI_CPCI && X86 && PCI_LEGACY
        help
          Say Y here if you have a CompactPCI system card that exposes the #ENUM
          hotswap signal as a bit in a system register that can be read through
index 3ef0a4875a62a21ee4eff4d44e568f8632364918..856d57b4d6044539c50b4f631107c03f1df5891d 100644 (file)
@@ -1931,16 +1931,14 @@ void cpqhp_pushbutton_thread(unsigned long slot)
                        return ;
                }
 
-               if (func != NULL && ctrl != NULL) {
-                       if (cpqhp_process_SS(ctrl, func) != 0) {
-                               amber_LED_on (ctrl, hp_slot);
-                               green_LED_on (ctrl, hp_slot);
-                               
-                               set_SOGO(ctrl);
+               if (cpqhp_process_SS(ctrl, func) != 0) {
+                       amber_LED_on(ctrl, hp_slot);
+                       green_LED_on(ctrl, hp_slot);
 
-                               /* Wait for SOBS to be unset */
-                               wait_for_ctrl_irq (ctrl);
-                       }
+                       set_SOGO(ctrl);
+
+                       /* Wait for SOBS to be unset */
+                       wait_for_ctrl_irq(ctrl);
                }
 
                p_slot->state = STATIC_STATE;
index 87e01615053dc1fb228b05473e1bdac2d32b8e6c..07c9f09c856dba943a15f7e794ba8e1eaef78387 100644 (file)
@@ -224,6 +224,12 @@ static struct msi_desc* alloc_msi_entry(void)
        return entry;
 }
 
+static void pci_intx_for_msi(struct pci_dev *dev, int enable)
+{
+       if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG))
+               pci_intx(dev, enable);
+}
+
 #ifdef CONFIG_PM
 static void __pci_restore_msi_state(struct pci_dev *dev)
 {
@@ -237,7 +243,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
        entry = get_irq_msi(dev->irq);
        pos = entry->msi_attrib.pos;
 
-       pci_intx(dev, 0);               /* disable intx */
+       pci_intx_for_msi(dev, 0);
        msi_set_enable(dev, 0);
        write_msi_msg(dev->irq, &entry->msg);
        if (entry->msi_attrib.maskbit)
@@ -260,7 +266,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
                return;
 
        /* route the table */
-       pci_intx(dev, 0);               /* disable intx */
+       pci_intx_for_msi(dev, 0);
        msix_set_enable(dev, 0);
 
        list_for_each_entry(entry, &dev->msi_list, list) {
@@ -343,7 +349,7 @@ static int msi_capability_init(struct pci_dev *dev)
        }
 
        /* Set MSI enabled bits  */
-       pci_intx(dev, 0);               /* disable intx */
+       pci_intx_for_msi(dev, 0);
        msi_set_enable(dev, 1);
        dev->msi_enabled = 1;
 
@@ -433,7 +439,7 @@ static int msix_capability_init(struct pci_dev *dev,
                i++;
        }
        /* Set MSI-X enabled bits */
-       pci_intx(dev, 0);               /* disable intx */
+       pci_intx_for_msi(dev, 0);
        msix_set_enable(dev, 1);
        dev->msix_enabled = 1;
 
@@ -528,7 +534,7 @@ void pci_disable_msi(struct pci_dev* dev)
                return;
 
        msi_set_enable(dev, 0);
-       pci_intx(dev, 1);               /* enable intx */
+       pci_intx_for_msi(dev, 1);
        dev->msi_enabled = 0;
 
        BUG_ON(list_empty(&dev->msi_list));
@@ -640,7 +646,7 @@ void pci_disable_msix(struct pci_dev* dev)
                return;
 
        msix_set_enable(dev, 0);
-       pci_intx(dev, 1);               /* enable intx */
+       pci_intx_for_msi(dev, 1);
        dev->msix_enabled = 0;
 
        msix_free_all_irqs(dev);
index 6e2760b6c20a4cc1d1ce08ebb4d64dd87872c2d0..6d1a21611818b92c5cd4524e61d046984cf4c476 100644 (file)
@@ -143,8 +143,8 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
  * system is in its list of supported devices.  Returns the matching
  * pci_device_id structure or %NULL if there is no match.
  */
-const struct pci_device_id *pci_match_device(struct pci_driver *drv,
-                                            struct pci_dev *dev)
+static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
+                                                   struct pci_dev *dev)
 {
        struct pci_dynid *dynid;
 
@@ -559,7 +559,6 @@ static int __init pci_driver_init(void)
 postcore_initcall(pci_driver_init);
 
 EXPORT_SYMBOL(pci_match_id);
-EXPORT_SYMBOL(pci_match_device);
 EXPORT_SYMBOL(__pci_register_driver);
 EXPORT_SYMBOL(pci_unregister_driver);
 EXPORT_SYMBOL(pci_dev_driver);
index d0bb5b9d2120925605f6aab89ce25fc78d2a0133..26cc4dcf4f0e381c791c6dba3e6bb28ce3b5e236 100644 (file)
@@ -1621,12 +1621,8 @@ static void __init quirk_disable_all_msi(struct pci_dev *dev)
        printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
@@ -1678,6 +1674,9 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE,
                        quirk_msi_ht_cap);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS,
+                       PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
+                       quirk_msi_ht_cap);
 
 /* The nVidia CK804 chipset may have 2 HT MSI mappings.
  * MSI are supported if the MSI capability set in any of these mappings.
@@ -1705,4 +1704,48 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_msi_ht_cap);
+
+static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
+{
+       dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5780,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5780S,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5714,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5714S,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5715,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
+                       PCI_DEVICE_ID_TIGON3_5715S,
+                       quirk_msi_intx_disable_bug);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4395,
+                       quirk_msi_intx_disable_bug);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4374,
+                       quirk_msi_intx_disable_bug);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
+                       quirk_msi_intx_disable_bug);
+
 #endif /* CONFIG_PCI_MSI */
index b001b5922e3349088ac2e47b9ee3acb1d934a46e..8541034021f0d5eaf168d83e425bb66d1b03a2e1 100644 (file)
@@ -113,6 +113,8 @@ pci_find_next_bus(const struct pci_bus *from)
        return b;
 }
 
+#ifdef CONFIG_PCI_LEGACY
+
 /**
  * pci_find_slot - locate PCI device from a given PCI slot
  * @bus: number of PCI bus on which desired PCI device resides
@@ -137,6 +139,8 @@ pci_find_slot(unsigned int bus, unsigned int devfn)
        return NULL;
 }
 
+#endif /* CONFIG_PCI_LEGACY */
+
 /**
  * pci_get_slot - locate PCI device for a given PCI slot
  * @bus: PCI bus on which desired PCI device resides
@@ -200,6 +204,7 @@ struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
        return NULL;
 }
 
+#ifdef CONFIG_PCI_LEGACY
 /**
  * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
@@ -278,6 +283,7 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *
 {
        return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
 }
+#endif /* CONFIG_PCI_LEGACY */
 
 /**
  * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
@@ -468,8 +474,11 @@ int pci_dev_present(const struct pci_device_id *ids)
 EXPORT_SYMBOL(pci_dev_present);
 EXPORT_SYMBOL(pci_find_present);
 
+#ifdef CONFIG_PCI_LEGACY
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_slot);
+#endif /* CONFIG_PCI_LEGACY */
+
 /* For boot time work */
 EXPORT_SYMBOL(pci_find_bus);
 EXPORT_SYMBOL(pci_find_next_bus);
index cd0a204d96d14e9ffdc7d19e5597f47e89fe6b8a..11adab13f2b724e0c94e5561c6b47b5fde175e21 100644 (file)
@@ -75,6 +75,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
 {
        int i = 0;
        int irq;
+       int p, t;
 
        if (!valid_IRQ(gsi))
                return;
@@ -85,15 +86,22 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
        if (i >= PNP_MAX_IRQ)
                return;
 
-#ifdef CONFIG_X86
-       if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE ||
-                               polarity != ACPI_ACTIVE_HIGH)) {
-               pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, "
-                               "active high", gsi);
-               triggering = ACPI_EDGE_SENSITIVE;
-               polarity = ACPI_ACTIVE_HIGH;
+       /*
+        * in IO-APIC mode, use overrided attribute. Two reasons:
+        * 1. BIOS bug in DSDT
+        * 2. BIOS uses IO-APIC mode Interrupt Source Override
+        */
+       if (!acpi_get_override_irq(gsi, &t, &p)) {
+               t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+               p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+               if (triggering != t || polarity != p) {
+                       pnp_warn("IRQ %d override to %s, %s",
+                               gsi, t ? "edge":"level", p ? "low":"high");
+                       triggering = t;
+                       polarity = p;
+               }
        }
-#endif
 
        res->irq_resource[i].flags = IORESOURCE_IRQ;    // Also clears _UNSET flag
        res->irq_resource[i].flags |= irq_flags(triggering, polarity);
index cbde770eb121062fcfa67f8dd562f827814cacc1..e5cdc0294aaa96f236e72c81d8c6f46751ae36a8 100644 (file)
@@ -36,7 +36,9 @@ config RTC_HCTOSYS_DEVICE
        help
          The RTC device that will be used to (re)initialize the system
          clock, usually rtc0.  Initialization is done when the system
-         starts up, and when it resumes from a low power state.
+         starts up, and when it resumes from a low power state.  This
+         device should record time in UTC, since the kernel won't do
+         timezone correction.
 
          The driver for this RTC device must be loaded before late_initcall
          functions run, so it must usually be statically linked.
@@ -133,8 +135,8 @@ config RTC_DRV_DS1307
 
          The first seven registers on these chips hold an RTC, and other
          registers may add features such as NVRAM, a trickle charger for
-         the RTC/NVRAM backup power, and alarms.  This driver may not
-         expose all those available chip features.
+         the RTC/NVRAM backup power, and alarms.  NVRAM is visible in
+         sysfs, but other chip features may not be available.
 
          This driver can also be built as a module. If so, the module
          will be called rtc-ds1307.
index 178527252c6a6d04c8dbd55c1ca1ab22aa938e69..33c0e98243eef9ab397b840c1f8265c5c9e31baf 100644 (file)
@@ -47,8 +47,8 @@ static int __init rtc_hctosys(void)
                        do_settimeofday(&tv);
 
                        dev_info(rtc->dev.parent,
-                               "setting the system clock to "
-                               "%d-%02d-%02d %02d:%02d:%02d (%u)\n",
+                               "setting system clock to "
+                               "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
                                tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
                                tm.tm_hour, tm.tm_min, tm.tm_sec,
                                (unsigned int) tv.tv_sec);
index db6f3f0d8982e685b7e48cc78e2f2db6040c4742..bc1c7fe94ad3eceaf352e49eb2e6843de924a6e5 100644 (file)
@@ -89,6 +89,7 @@ enum ds_type {
 
 struct ds1307 {
        u8                      reg_addr;
+       bool                    has_nvram;
        u8                      regs[8];
        enum ds_type            type;
        struct i2c_msg          msg[2];
@@ -242,6 +243,87 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
        .set_time       = ds1307_set_time,
 };
 
+/*----------------------------------------------------------------------*/
+
+#define NVRAM_SIZE     56
+
+static ssize_t
+ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
+               char *buf, loff_t off, size_t count)
+{
+       struct i2c_client       *client;
+       struct ds1307           *ds1307;
+       struct i2c_msg          msg[2];
+       int                     result;
+
+       client = to_i2c_client(container_of(kobj, struct device, kobj));
+       ds1307 = i2c_get_clientdata(client);
+
+       if (unlikely(off >= NVRAM_SIZE))
+               return 0;
+       if ((off + count) > NVRAM_SIZE)
+               count = NVRAM_SIZE - off;
+       if (unlikely(!count))
+               return count;
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 1;
+       msg[0].buf = buf;
+
+       buf[0] = 8 + off;
+
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = count;
+       msg[1].buf = buf;
+
+       result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2);
+       if (result != 2) {
+               dev_err(&client->dev, "%s error %d\n", "nvram read", result);
+               return -EIO;
+       }
+       return count;
+}
+
+static ssize_t
+ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
+               char *buf, loff_t off, size_t count)
+{
+       struct i2c_client       *client;
+       u8                      buffer[NVRAM_SIZE + 1];
+       int                     ret;
+
+       client = to_i2c_client(container_of(kobj, struct device, kobj));
+
+       if (unlikely(off >= NVRAM_SIZE))
+               return -EFBIG;
+       if ((off + count) > NVRAM_SIZE)
+               count = NVRAM_SIZE - off;
+       if (unlikely(!count))
+               return count;
+
+       buffer[0] = 8 + off;
+       memcpy(buffer + 1, buf, count);
+
+       ret = i2c_master_send(client, buffer, count + 1);
+       return (ret < 0) ? ret : (ret - 1);
+}
+
+static struct bin_attribute nvram = {
+       .attr = {
+               .name   = "nvram",
+               .mode   = S_IRUGO | S_IWUSR,
+               .owner  = THIS_MODULE,
+       },
+
+       .read   = ds1307_nvram_read,
+       .write  = ds1307_nvram_write,
+       .size   = NVRAM_SIZE,
+};
+
+/*----------------------------------------------------------------------*/
+
 static struct i2c_driver ds1307_driver;
 
 static int __devinit ds1307_probe(struct i2c_client *client)
@@ -413,6 +495,14 @@ read_rtc:
                goto exit_free;
        }
 
+       if (chip->nvram56) {
+               err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
+               if (err == 0) {
+                       ds1307->has_nvram = true;
+                       dev_info(&client->dev, "56 bytes nvram\n");
+               }
+       }
+
        return 0;
 
 exit_bad:
@@ -432,6 +522,9 @@ static int __devexit ds1307_remove(struct i2c_client *client)
 {
        struct ds1307   *ds1307 = i2c_get_clientdata(client);
 
+       if (ds1307->has_nvram)
+               sysfs_remove_bin_file(&client->dev.kobj, &nvram);
+
        rtc_device_unregister(ds1307->rtc);
        kfree(ds1307);
        return 0;
index bb53c09bad169beb8427755a3de4e0aaf665dbf7..d9e848dcd450c520000f21a687b3a7e349240094 100644 (file)
@@ -291,7 +291,7 @@ static ssize_t ds1553_nvram_write(struct kobject *kobj,
 static struct bin_attribute ds1553_nvram_attr = {
        .attr = {
                .name = "nvram",
-               .mode = S_IRUGO | S_IWUGO,
+               .mode = S_IRUGO | S_IWUSR,
        },
        .size = RTC_OFFSET,
        .read = ds1553_nvram_read,
index c535b78698e22634377c049e3c5c91fe2c77ad89..2e73f0b183b2fd94540cc6624c0d2281cfc72950 100644 (file)
@@ -160,10 +160,13 @@ static ssize_t ds1742_nvram_write(struct kobject *kobj,
 static struct bin_attribute ds1742_nvram_attr = {
        .attr = {
                .name = "nvram",
-               .mode = S_IRUGO | S_IWUGO,
+               .mode = S_IRUGO | S_IWUSR,
        },
        .read = ds1742_nvram_read,
        .write = ds1742_nvram_write,
+       /* REVISIT: size in sysfs won't match actual size... if it's
+        * not a constant, each RTC should have its own attribute.
+        */
 };
 
 static int __devinit ds1742_rtc_probe(struct platform_device *pdev)
index bf60d35f580b55e98495af3e6c7ab8157135be78..cd0bbc0e8038c68c6b31798f30f820a5c558a66b 100644 (file)
@@ -353,11 +353,12 @@ static ssize_t m48t59_nvram_write(struct kobject *kobj,
 static struct bin_attribute m48t59_nvram_attr = {
        .attr = {
                .name = "nvram",
-               .mode = S_IRUGO | S_IWUGO,
+               .mode = S_IRUGO | S_IWUSR,
                .owner = THIS_MODULE,
        },
        .read = m48t59_nvram_read,
        .write = m48t59_nvram_write,
+       .size = M48T59_NVRAM_SIZE,
 };
 
 static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
@@ -464,7 +465,7 @@ static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct platform_driver m48t59_rtc_platdrv = {
+static struct platform_driver m48t59_rtc_driver = {
        .driver         = {
                .name   = "rtc-m48t59",
                .owner  = THIS_MODULE,
@@ -475,12 +476,12 @@ static struct platform_driver m48t59_rtc_platdrv = {
 
 static int __init m48t59_rtc_init(void)
 {
-       return platform_driver_register(&m48t59_rtc_platdrv);
+       return platform_driver_register(&m48t59_rtc_driver);
 }
 
 static void __exit m48t59_rtc_exit(void)
 {
-       platform_driver_unregister(&m48t59_rtc_platdrv);
+       platform_driver_unregister(&m48t59_rtc_driver);
 }
 
 module_init(m48t59_rtc_init);
index 78277a118b6773268d7813b33d3fbe19dc79d6d0..8e8c8b8e81ee8ae934a0966380de7e2de1e68cd0 100644 (file)
@@ -351,8 +351,10 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
                tm->tm_sec, tm->tm_min, tm->tm_hour,
                tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
 
-       if (rtc_valid_tm(tm) < 0)
+       if (rtc_valid_tm(tm) < 0) {
                dev_err(dev, "invalid date\n");
+               rtc_time_to_tm(0, tm);
+       }
 
        return 0;
 }
@@ -588,7 +590,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 
        rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
                                           &sh_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
+       if (IS_ERR(rtc->rtc_dev)) {
                ret = PTR_ERR(rtc->rtc_dev);
                goto err_badmap;
        }
index 8288b6b2bf2b2c9971efe99a74a08e579ee8c659..a265da7c6ff8db2908b0686bf376157a3017157f 100644 (file)
@@ -291,7 +291,7 @@ static ssize_t stk17ta8_nvram_write(struct kobject *kobj,
 static struct bin_attribute stk17ta8_nvram_attr = {
        .attr = {
                .name = "nvram",
-               .mode = S_IRUGO | S_IWUGO,
+               .mode = S_IRUGO | S_IWUSR,
                .owner = THIS_MODULE,
        },
        .size = RTC_OFFSET,
index 859f870552e3e019752e20274ec5144d7e556d8b..5e083d1f57e70a115dac935895d4e40bcd6a5624 100644 (file)
@@ -193,6 +193,12 @@ dcssblk_segment_warn(int rc, char* seg_name)
        }
 }
 
+static void dcssblk_unregister_callback(struct device *dev)
+{
+       device_unregister(dev);
+       put_device(dev);
+}
+
 /*
  * device attribute for switching shared/nonshared (exclusive)
  * operation (show + store)
@@ -276,8 +282,7 @@ removeseg:
        blk_cleanup_queue(dev_info->dcssblk_queue);
        dev_info->gd->queue = NULL;
        put_disk(dev_info->gd);
-       device_unregister(dev);
-       put_device(dev);
+       rc = device_schedule_callback(dev, dcssblk_unregister_callback);
 out:
        up_write(&dcssblk_devices_sem);
        return rc;
index 725b0dd142699f0f613aece0341cb67af9036867..f4c132ab39edef112c72faad0c492dd3971d0ed7 100644 (file)
@@ -343,10 +343,10 @@ static int cmf_copy_block(struct ccw_device *cdev)
 
        if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) {
                /* Don't copy if a start function is in progress. */
-               if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) &&
+               if ((!(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED)) &&
                    (sch->schib.scsw.actl &
                     (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) &&
-                   (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS))
+                   (!(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)))
                        return -EBUSY;
        }
        cmb_data = cdev->private->cmb;
index 7ee57f084a89cd79c6f7afcd2caea817633f5877..74f6b539974a1d0310875e3cad4298ea3cf7ba82 100644 (file)
@@ -738,7 +738,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch,
        atomic_set(&cdev->private->onoff, 0);
        cdev->dev.parent = &sch->dev;
        cdev->dev.release = ccw_device_release;
-       INIT_LIST_HEAD(&cdev->private->kick_work.entry);
+       INIT_WORK(&cdev->private->kick_work, NULL);
        cdev->dev.groups = ccwdev_attr_groups;
        /* Do first half of device_register. */
        device_initialize(&cdev->dev);
index 3ccca5871fdfc002a922e17fea4c4dcb574808cb..47bb47b485814497e12201b3e4dd2f0697859504 100644 (file)
@@ -148,6 +148,10 @@ static int __init smsg_init(void)
 {
        int rc;
 
+       if (!MACHINE_IS_VM) {
+               rc = -EPROTONOSUPPORT;
+               goto out;
+       }
        rc = driver_register(&smsg_driver);
        if (rc != 0)
                goto out;
index 86cf10efb0c1048ec7efc1d0ae1210537398c8d7..a6676be87843ad43d0c0fc57ff441993ac7a3985 100644 (file)
@@ -725,7 +725,7 @@ config SCSI_FD_MCS
 
 config SCSI_GDTH
        tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
-       depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
+       depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API && PCI_LEGACY
        ---help---
          Formerly called GDT SCSI Disk Array Controller Support.
 
index 5b0932f6147389c5c0919a799036b75b2b69b3ed..06509bff71f7b5fa23cbd37295ba0294c4e99cee 100644 (file)
@@ -377,7 +377,7 @@ out:
 
 #define FLASH_RESET                    0xF0
 
-#define FLASH_SIZE                      0x200000
+#define ASD_FLASH_SIZE                  0x200000
 #define FLASH_DIR_COOKIE                "*** ADAPTEC FLASH DIRECTORY *** "
 #define FLASH_NEXT_ENTRY_OFFS          0x2000
 #define FLASH_MAX_DIR_ENTRIES          32
@@ -609,7 +609,7 @@ static int asd_find_flash_dir(struct asd_ha_struct *asd_ha,
                              struct asd_flash_dir *flash_dir)
 {
        u32 v;
-       for (v = 0; v < FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) {
+       for (v = 0; v < ASD_FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) {
                asd_read_flash_seg(asd_ha, flash_dir, v,
                                   sizeof(FLASH_DIR_COOKIE)-1);
                if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE,
index 22d91ee173c594f1d101f6f1d97e9395aac00ccb..5f2396c03958924393864718485d1de683bda6b1 100644 (file)
@@ -556,7 +556,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
                                   unsigned long timeout)
 {
        u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
-       int request_status;
+       int request_status = 0;
        int rc;
 
        /* If we have exhausted our request limit, just fail this request,
@@ -574,6 +574,13 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
                if (request_status < -1)
                        goto send_error;
                /* Otherwise, we may have run out of requests. */
+               /* If request limit was 0 when we started the adapter is in the
+                * process of performing a login with the server adapter, or
+                * we may have run out of requests.
+                */
+               else if (request_status == -1 &&
+                        evt_struct->iu.srp.login_req.opcode != SRP_LOGIN_REQ)
+                       goto send_busy;
                /* Abort and reset calls should make it through.
                 * Nothing except abort and reset should use the last two
                 * slots unless we had two or less to begin with.
@@ -633,7 +640,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
        unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
 
        free_event_struct(&hostdata->pool, evt_struct);
-       atomic_inc(&hostdata->request_limit);
+       if (request_status != -1)
+               atomic_inc(&hostdata->request_limit);
        return SCSI_MLQUEUE_HOST_BUSY;
 
  send_error:
@@ -927,10 +935,11 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata)
        login->req_buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
        
        spin_lock_irqsave(hostdata->host->host_lock, flags);
-       /* Start out with a request limit of 1, since this is negotiated in
-        * the login request we are just sending
+       /* Start out with a request limit of 0, since this is negotiated in
+        * the login request we are just sending and login requests always
+        * get sent by the driver regardless of request_limit.
         */
-       atomic_set(&hostdata->request_limit, 1);
+       atomic_set(&hostdata->request_limit, 0);
 
        rc = ibmvscsi_send_srp_event(evt_struct, hostdata, init_timeout * 2);
        spin_unlock_irqrestore(hostdata->host->host_lock, flags);
index c0755565fae9da39f9173fbfcd5d92e85db5229e..4e46045dea6d4e3fe6c970ddb18cceec5e0a2ada 100644 (file)
@@ -682,6 +682,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
        IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
        struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq);
        int datadir = scsi_cmnd->sc_data_direction;
+       char tag[2];
 
        lpfc_cmd->fcp_rsp->rspSnsLen = 0;
        /* clear task management bits */
@@ -692,8 +693,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 
        memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, 16);
 
-       if (scsi_cmnd->device->tagged_supported) {
-               switch (scsi_cmnd->tag) {
+       if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
+               switch (tag[0]) {
                case HEAD_OF_QUEUE_TAG:
                        fcp_cmnd->fcpCntl1 = HEAD_OF_Q;
                        break;
index 4652ad22516be010f0c9c46bd1612dc9dbf833c0..abef7048f25b32dffb1586cab131c7cac1817438 100644 (file)
@@ -593,10 +593,11 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
        if (aux->frame_type != OS_FRAME_TYPE_DATA &&
            aux->frame_type != OS_FRAME_TYPE_EOD &&
            aux->frame_type != OS_FRAME_TYPE_MARKER) {
-               if (!quiet)
+               if (!quiet) {
 #if DEBUG
                        printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
 #endif
+               }
                goto err_out;
        }
        if (aux->frame_type == OS_FRAME_TYPE_EOD &&
@@ -606,11 +607,12 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
                goto err_out;
        }
         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
-               if (!quiet)
+               if (!quiet) {
 #if DEBUG
                        printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 
                                            name, ntohl(aux->frame_seq_num), frame_seq_number);
 #endif
+               }
                goto err_out;
        }
        if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
index 4d4c9f01be8da7dbde5fa1951cbfbf5ab8bfb593..1f16de719962829e181f4860040a83a6094dcfa7 100644 (file)
@@ -76,7 +76,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
        }
 }
 
-static void __init putc(struct uart_port *port, int c)
+static void __init serial_putc(struct uart_port *port, int c)
 {
        wait_for_xmitr(port);
        serial_out(port, UART_TX, c);
@@ -91,7 +91,7 @@ static void __init early_serial8250_write(struct console *console, const char *s
        ier = serial_in(port, UART_IER);
        serial_out(port, UART_IER, 0);
 
-       uart_console_write(port, s, count, putc);
+       uart_console_write(port, s, count, serial_putc);
 
        /* Wait for transmitter to become empty and restore the IER */
        wait_for_xmitr(port);
index 0e357562ce9e37e080c6f5e84ed8f630e92966c7..ceb03c9e749f8f918732d88c635de618d1f04125 100644 (file)
@@ -1986,6 +1986,7 @@ static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
 
 static int pciserial_resume_one(struct pci_dev *dev)
 {
+       int err;
        struct serial_private *priv = pci_get_drvdata(dev);
 
        pci_set_power_state(dev, PCI_D0);
@@ -1995,7 +1996,9 @@ static int pciserial_resume_one(struct pci_dev *dev)
                /*
                 * The device may have been disabled.  Re-enable it.
                 */
-               pci_enable_device(dev);
+               err = pci_enable_device(dev);
+               if (err)
+                       return err;
 
                pciserial_resume_ports(priv);
        }
index 926f58a674a15043f64ff25095bade80efca17e9..1de098e754978810db03ea655480bb4c9e213e45 100644 (file)
@@ -69,6 +69,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
        {       "CTL3001",              0       },
        /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
        {       "CTL3011",              0       },
+       /* Davicom ISA 33.6K Modem */
+       {       "DAV0336",              0       },
        /* Creative */
        /* Creative Modem Blaster Flash56 DI5601-1 */
        {       "DMB1032",              0       },
@@ -345,6 +347,11 @@ static const struct pnp_device_id pnp_dev_table[] = {
        /* Fujitsu Wacom Tablet PC devices */
        {       "FUJ02E5",              0       },
        {       "FUJ02E6",              0       },
+       /*
+        * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
+        * disguise)
+        */
+       {       "LTS0001",              0       },
        /* Rockwell's (PORALiNK) 33600 INT PNP */
        {       "WCI0003",              0       },
        /* Unkown PnP modems */
@@ -432,7 +439,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
        }
 
        memset(&port, 0, sizeof(struct uart_port));
-       port.irq = pnp_irq(dev, 0);
+       if (pnp_irq_valid(dev, 0))
+               port.irq = pnp_irq(dev, 0);
        if (pnp_port_valid(dev, 0)) {
                port.iobase = pnp_port_start(dev, 0);
                port.iotype = UPIO_PORT;
index 4d6b3c56d20e7df9ea1262ae89cae2e24d18f901..111da57f533414671f9a924456ebcf1d08b32553 100644 (file)
@@ -204,8 +204,6 @@ static u_int atmel_get_mctrl(struct uart_port *port)
  */
 static void atmel_stop_tx(struct uart_port *port)
 {
-       struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
-
        UART_PUT_IDR(port, ATMEL_US_TXRDY);
 }
 
@@ -214,8 +212,6 @@ static void atmel_stop_tx(struct uart_port *port)
  */
 static void atmel_start_tx(struct uart_port *port)
 {
-       struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
-
        UART_PUT_IER(port, ATMEL_US_TXRDY);
 }
 
@@ -224,8 +220,6 @@ static void atmel_start_tx(struct uart_port *port)
  */
 static void atmel_stop_rx(struct uart_port *port)
 {
-       struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
-
        UART_PUT_IDR(port, ATMEL_US_RXRDY);
 }
 
@@ -409,7 +403,6 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
  */
 static int atmel_startup(struct uart_port *port)
 {
-       struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
        int retval;
 
        /*
@@ -456,8 +449,6 @@ static int atmel_startup(struct uart_port *port)
  */
 static void atmel_shutdown(struct uart_port *port)
 {
-       struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
-
        /*
         * Disable all interrupts, port and break condition.
         */
index f523cdf4b02b52a3a439a0a80d8cf52af4612842..a4e23cf47906960ba53396984d6e0d3e531619b3 100644 (file)
-/* $Id: serial.c,v 1.25 2004/09/29 10:33:49 starvik Exp $
- *
+/*
  * Serial port driver for the ETRAX 100LX chip
  *
- *    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Axis Communications AB
+ *    Copyright (C) 1998-2007  Axis Communications AB
  *
  *    Many, many authors. Based once upon a time on serial.c for 16x50.
  *
- * $Log: serial.c,v $
- * Revision 1.25  2004/09/29 10:33:49  starvik
- * Resolved a dealock when printing debug from kernel.
- *
- * Revision 1.24  2004/08/27 23:25:59  johana
- * rs_set_termios() must call change_speed() if c_iflag has changed or
- * automatic XOFF handling will be enabled and transmitter will stop
- * if 0x13 is received.
- *
- * Revision 1.23  2004/08/24 06:57:13  starvik
- * More whitespace cleanup
- *
- * Revision 1.22  2004/08/24 06:12:20  starvik
- * Whitespace cleanup
- *
- * Revision 1.20  2004/05/24 12:00:20  starvik
- * Big merge of stuff from Linux 2.4 (e.g. manual mode for the serial port).
- *
- * Revision 1.19  2004/05/17 13:12:15  starvik
- * Kernel console hook
- * Big merge from Linux 2.4 still pending.
- *
- * Revision 1.18  2003/10/28 07:18:30  starvik
- * Compiles with debug info
- *
- * Revision 1.17  2003/07/04 08:27:37  starvik
- * Merge of Linux 2.5.74
- *
- * Revision 1.16  2003/06/13 10:05:19  johana
- * Help the user to avoid trouble by:
- * Forcing mixed mode for status/control lines if not all pins are used.
- *
- * Revision 1.15  2003/06/13 09:43:01  johana
- * Merged in the following changes from os/linux/arch/cris/drivers/serial.c
- * + some minor changes to reduce diff.
- *
- * Revision 1.49  2003/05/30 11:31:54  johana
- * Merged in change-branch--serial9bit that adds CMSPAR support for sticky
- * parity (mark/space)
- *
- * Revision 1.48  2003/05/30 11:03:57  johana
- * Implemented rs_send_xchar() by disabling the DMA and writing manually.
- * Added e100_disable_txdma_channel() and e100_enable_txdma_channel().
- * Fixed rs_throttle() and rs_unthrottle() to properly call rs_send_xchar
- * instead of setting info->x_char and check the CRTSCTS flag before
- * controlling the rts pin.
- *
- * Revision 1.14  2003/04/09 08:12:44  pkj
- * Corrected typo changes made upstream.
- *
- * Revision 1.13  2003/04/09 05:20:47  starvik
- * Merge of Linux 2.5.67
- *
- * Revision 1.11  2003/01/22 06:48:37  starvik
- * Fixed warnings issued by GCC 3.2.1
- *
- * Revision 1.9  2002/12/13 09:07:47  starvik
- * Alert user that RX_TIMEOUT_TICKS==0 doesn't work
- *
- * Revision 1.8  2002/12/11 13:13:57  starvik
- * Added arch/ to v10 specific includes
- * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
- *
- * Revision 1.7  2002/12/06 07:13:57  starvik
- * Corrected work queue stuff
- * Removed CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
- *
- * Revision 1.6  2002/11/21 07:17:46  starvik
- * Change static inline to extern inline where otherwise outlined with gcc-3.2
- *
- * Revision 1.5  2002/11/14 15:59:49  starvik
- * Linux 2.5 port of the latest serial driver from 2.4. The work queue stuff
- * probably doesn't work yet.
- *
- * Revision 1.42  2002/11/05 09:08:47  johana
- * Better implementation of rs_stop() and rs_start() that uses the XOFF
- * register to start/stop transmission.
- * change_speed() also initilises XOFF register correctly so that
- * auto_xoff is enabled when IXON flag is set by user.
- * This gives fast XOFF response times.
- *
- * Revision 1.41  2002/11/04 18:40:57  johana
- * Implemented rs_stop() and rs_start().
- * Simple tests using hwtestserial indicates that this should be enough
- * to make it work.
- *
- * Revision 1.40  2002/10/14 05:33:18  starvik
- * RS-485 uses fast timers even if SERIAL_FAST_TIMER is disabled
- *
- * Revision 1.39  2002/09/30 21:00:57  johana
- * Support for CONFIG_ETRAX_SERx_DTR_RI_DSR_CD_MIXED where the status and
- * control pins can be mixed between PA and PB.
- * If no serial port uses MIXED old solution is used
- * (saves a few bytes and cycles).
- * control_pins struct uses masks instead of bit numbers.
- * Corrected dummy values and polarity in line_info() so
- * /proc/tty/driver/serial is now correct.
- * (the E100_xxx_GET() macros is really active low - perhaps not obvious)
- *
- * Revision 1.38  2002/08/23 11:01:36  starvik
- * Check that serial port is enabled in all interrupt handlers to avoid
- * restarts of DMA channels not assigned to serial ports
- *
- * Revision 1.37  2002/08/13 13:02:37  bjornw
- * Removed some warnings because of unused code
- *
- * Revision 1.36  2002/08/08 12:50:01  starvik
- * Serial interrupt is shared with synchronous serial port driver
- *
- * Revision 1.35  2002/06/03 10:40:49  starvik
- * Increased RS-485 RTS toggle timer to 2 characters
- *
- * Revision 1.34  2002/05/28 18:59:36  johana
- * Whitespace and comment fixing to be more like etrax100ser.c 1.71.
- *
- * Revision 1.33  2002/05/28 17:55:43  johana
- * RS-485 uses FAST_TIMER if enabled, and starts a short (one char time)
- * timer from tranismit_chars (interrupt context).
- * The timer toggles RTS in interrupt context when expired giving minimum
- * latencies.
- *
- * Revision 1.32  2002/05/22 13:58:00  johana
- * Renamed rs_write() to raw_write() and made it inline.
- * New rs_write() handles RS-485 if configured and enabled
- * (moved code from e100_write_rs485()).
- * RS-485 ioctl's uses copy_from_user() instead of verify_area().
- *
- * Revision 1.31  2002/04/22 11:20:03  johana
- * Updated copyright years.
- *
- * Revision 1.30  2002/04/22 09:39:12  johana
- * RS-485 support compiles.
- *
- * Revision 1.29  2002/01/14 16:10:01  pkj
- * Allocate the receive buffers dynamically. The static 4kB buffer was
- * too small for the peaks. This means that we can get rid of the extra
- * buffer and the copying to it. It also means we require less memory
- * under normal operations, but can use more when needed (there is a
- * cap at 64kB for safety reasons). If there is no memory available
- * we panic(), and die a horrible death...
- *
- * Revision 1.28  2001/12/18 15:04:53  johana
- * Cleaned up write_rs485() - now it works correctly without padding extra
- * char.
- * Added sane default initialisation of rs485.
- * Added #ifdef around dummy variables.
- *
- * Revision 1.27  2001/11/29 17:00:41  pkj
- * 2kB seems to be too small a buffer when using 921600 bps,
- * so increase it to 4kB (this was already done for the elinux
- * version of the serial driver).
- *
- * Revision 1.26  2001/11/19 14:20:41  pkj
- * Minor changes to comments and unused code.
- *
- * Revision 1.25  2001/11/12 20:03:43  pkj
- * Fixed compiler warnings.
- *
- * Revision 1.24  2001/11/12 15:10:05  pkj
- * Total redesign of the receiving part of the serial driver.
- * Uses eight chained descriptors to write to a 4kB buffer.
- * This data is then serialised into a 2kB buffer. From there it
- * is copied into the TTY's flip buffers when they become available.
- * A lot of copying, and the sizes of the buffers might need to be
- * tweaked, but all in all it should work better than the previous
- * version, without the need to modify the TTY code in any way.
- * Also note that erroneous bytes are now correctly marked in the
- * flag buffers (instead of always marking the first byte).
- *
- * Revision 1.23  2001/10/30 17:53:26  pkj
- * * Set info->uses_dma to 0 when a port is closed.
- * * Mark the timer1 interrupt as a fast one (SA_INTERRUPT).
- * * Call start_flush_timer() in start_receive() if
- *   CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is defined.
- *
- * Revision 1.22  2001/10/30 17:44:03  pkj
- * Use %lu for received and transmitted counters in line_info().
- *
- * Revision 1.21  2001/10/30 17:40:34  pkj
- * Clean-up. The only change to functionality is that
- * CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS(=5) is used instead of
- * MAX_FLUSH_TIME(=8).
- *
- * Revision 1.20  2001/10/30 15:24:49  johana
- * Added char_time stuff from 2.0 driver.
- *
- * Revision 1.19  2001/10/30 15:23:03  johana
- * Merged with 1.13.2 branch + fixed indentation
- * and changed CONFIG_ETRAX100_XYS to CONFIG_ETRAX_XYZ
- *
- * Revision 1.18  2001/09/24 09:27:22  pkj
- * Completed ext_baud_table[] in cflag_to_baud() and cflag_to_etrax_baud().
- *
- * Revision 1.17  2001/08/24 11:32:49  ronny
- * More fixes for the CONFIG_ETRAX_SERIAL_PORT0 define.
- *
- * Revision 1.16  2001/08/24 07:56:22  ronny
- * Added config ifdefs around ser0 irq requests.
- *
- * Revision 1.15  2001/08/16 09:10:31  bjarne
- * serial.c - corrected the initialization of rs_table, the wrong defines
- *            where used.
- *            Corrected a test in timed_flush_handler.
- *            Changed configured to enabled.
- * serial.h - Changed configured to enabled.
- *
- * Revision 1.14  2001/08/15 07:31:23  bjarne
- * Introduced two new members to the e100_serial struct.
- * configured - Will be set to 1 if the port has been configured in .config
- * uses_dma   - Should be set to 1 if the port uses DMA. Currently it is set
- *              to 1
- *              when a port is opened. This is used to limit the DMA interrupt
- *              routines to only manipulate DMA channels actually used by the
- *              serial driver.
- *
- * Revision 1.13.2.2  2001/10/17 13:57:13  starvik
- * Receiver was broken by the break fixes
- *
- * Revision 1.13.2.1  2001/07/20 13:57:39  ronny
- * Merge with new stuff from etrax100ser.c. Works but haven't checked stuff
- * like break handling.
- *
- * Revision 1.13  2001/05/09 12:40:31  johana
- * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
- *
- * Revision 1.12  2001/04/19 12:23:07  bjornw
- * CONFIG_RS485 -> CONFIG_ETRAX_RS485
- *
- * Revision 1.11  2001/04/05 14:29:48  markusl
- * Updated according to review remarks i.e.
- * -Use correct types in port structure to avoid compiler warnings
- * -Try to use IO_* macros whenever possible
- * -Open should never return -EBUSY
- *
- * Revision 1.10  2001/03/05 13:14:07  bjornw
- * Another spelling fix
- *
- * Revision 1.9  2001/02/23 13:46:38  bjornw
- * Spellling check
- *
- * Revision 1.8  2001/01/23 14:56:35  markusl
- * Made use of ser1 optional
- * Needed by USB
- *
- * Revision 1.7  2001/01/19 16:14:48  perf
- * Added kernel options for serial ports 234.
- * Changed option names from CONFIG_ETRAX100_XYZ to CONFIG_ETRAX_XYZ.
- *
- * Revision 1.6  2000/11/22 16:36:09  bjornw
- * Please marketing by using the correct case when spelling Etrax.
- *
- * Revision 1.5  2000/11/21 16:43:37  bjornw
- * Fixed so it compiles under CONFIG_SVINTO_SIM
- *
- * Revision 1.4  2000/11/15 17:34:12  bjornw
- * Added a timeout timer for flushing input channels. The interrupt-based
- * fast flush system should be easy to merge with this later (works the same
- * way, only with an irq instead of a system timer_list)
- *
- * Revision 1.3  2000/11/13 17:19:57  bjornw
- * * Incredibly, this almost complete rewrite of serial.c worked (at least
- *   for output) the first time.
- *
- *   Items worth noticing:
- *
- *      No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now)
- *      RS485 is not ported (why can't it be done in userspace as on x86 ?)
- *      Statistics done through async_icount - if any more stats are needed,
- *      that's the place to put them or in an arch-dep version of it.
- *      timeout_interrupt and the other fast timeout stuff not ported yet
- *      There be dragons in this 3k+ line driver
- *
- * Revision 1.2  2000/11/10 16:50:28  bjornw
- * First shot at a 2.4 port, does not compile totally yet
- *
- * Revision 1.1  2000/11/10 16:47:32  bjornw
- * Added verbatim copy of rev 1.49 etrax100ser.c from elinux
- *
- * Revision 1.49  2000/10/30 15:47:14  tobiasa
- * Changed version number.
- *
- * Revision 1.48  2000/10/25 11:02:43  johana
- * Changed %ul to %lu in printf's
- *
- * Revision 1.47  2000/10/18 15:06:53  pkj
- * Compile correctly with CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST and
- * CONFIG_ETRAX_SERIAL_PROC_ENTRY together.
- * Some clean-up of the /proc/serial file.
- *
- * Revision 1.46  2000/10/16 12:59:40  johana
- * Added CONFIG_ETRAX_SERIAL_PROC_ENTRY for statistics and debug info.
- *
- * Revision 1.45  2000/10/13 17:10:59  pkj
- * Do not flush DMAs while flipping TTY buffers.
- *
- * Revision 1.44  2000/10/13 16:34:29  pkj
- * Added a delay in ser_interrupt() for 2.3ms when an error is detected.
- * We do not know why this delay is required yet, but without it the
- * irmaflash program does not work (this was the program that needed
- * the ser_interrupt() to be needed in the first place). This should not
- * affect normal use of the serial ports.
- *
- * Revision 1.43  2000/10/13 16:30:44  pkj
- * New version of the fast flush of serial buffers code. This time
- * it is localized to the serial driver and uses a fast timer to
- * do the work.
- *
- * Revision 1.42  2000/10/13 14:54:26  bennyo
- * Fix for switching RTS when using rs485
- *
- * Revision 1.41  2000/10/12 11:43:44  pkj
- * Cleaned up a number of comments.
- *
- * Revision 1.40  2000/10/10 11:58:39  johana
- * Made RS485 support generic for all ports.
- * Toggle rts in interrupt if no delay wanted.
- * WARNING: No true transmitter empty check??
- * Set d_wait bit when sending data so interrupt is delayed until
- * fifo flushed. (Fix tcdrain() problem)
- *
- * Revision 1.39  2000/10/04 16:08:02  bjornw
- * * Use virt_to_phys etc. for DMA addresses
- * * Removed CONFIG_FLUSH_DMA_FAST hacks
- * * Indentation fix
- *
- * Revision 1.38  2000/10/02 12:27:10  mattias
- * * added variable used when using fast flush on serial dma.
- *   (CONFIG_FLUSH_DMA_FAST)
- *
- * Revision 1.37  2000/09/27 09:44:24  pkj
- * Uncomment definition of SERIAL_HANDLE_EARLY_ERRORS.
- *
- * Revision 1.36  2000/09/20 13:12:52  johana
- * Support for CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS:
- *   Number of timer ticks between flush of receive fifo (1 tick = 10ms).
- *   Try 0-3 for low latency applications. Approx 5 for high load
- *   applications (e.g. PPP). Maybe this should be more adaptive some day...
- *
- * Revision 1.35  2000/09/20 10:36:08  johana
- * Typo in get_lsr_info()
- *
- * Revision 1.34  2000/09/20 10:29:59  johana
- * Let rs_chars_in_buffer() check fifo content as well.
- * get_lsr_info() might work now (not tested).
- * Easier to change the port to debug.
- *
- * Revision 1.33  2000/09/13 07:52:11  torbjore
- * Support RS485
- *
- * Revision 1.32  2000/08/31 14:45:37  bjornw
- * After sending a break we need to reset the transmit DMA channel
- *
- * Revision 1.31  2000/06/21 12:13:29  johana
- * Fixed wait for all chars sent when closing port.
- * (Used to always take 1 second!)
- * Added shadows for directions of status/ctrl signals.
- *
- * Revision 1.30  2000/05/29 16:27:55  bjornw
- * Simulator ifdef moved a bit
- *
- * Revision 1.29  2000/05/09 09:40:30  mattias
- * * Added description of dma registers used in timeout_interrupt
- * * Removed old code
- *
- * Revision 1.28  2000/05/08 16:38:58  mattias
- * * Bugfix for flushing fifo in timeout_interrupt
- *   Problem occurs when bluetooth stack waits for a small number of bytes
- *   containing an event acknowledging free buffers in bluetooth HW
- *   As before, data was stuck in fifo until more data came on uart and
- *   flushed it up to the stack.
- *
- * Revision 1.27  2000/05/02 09:52:28  jonasd
- * Added fix for peculiar etrax behaviour when eop is forced on an empty
- * fifo. This is used when flashing the IRMA chip. Disabled by default.
- *
- * Revision 1.26  2000/03/29 15:32:02  bjornw
- * 2.0.34 updates
- *
- * Revision 1.25  2000/02/16 16:59:36  bjornw
- * * Receive DMA directly into the flip-buffer, eliminating an intermediary
- *   receive buffer and a memcpy. Will avoid some overruns.
- * * Error message on debug port if an overrun or flip buffer overrun occurs.
- * * Just use the first byte in the flag flip buffer for errors.
- * * Check for timeout on the serial ports only each 5/100 s, not 1/100.
- *
- * Revision 1.24  2000/02/09 18:02:28  bjornw
- * * Clear serial errors (overrun, framing, parity) correctly. Before, the
- *   receiver would get stuck if an error occurred and we did not restart
- *   the input DMA.
- * * Cosmetics (indentation, some code made into inlines)
- * * Some more debug options
- * * Actually shut down the serial port (DMA irq, DMA reset, receiver stop)
- *   when the last open is closed. Corresponding fixes in startup().
- * * rs_close() "tx FIFO wait" code moved into right place, bug & -> && fixed
- *   and make a special case out of port 1 (R_DMA_CHx_STATUS is broken for that)
- * * e100_disable_rx/enable_rx just disables/enables the receiver, not RTS
- *
- * Revision 1.23  2000/01/24 17:46:19  johana
- * Wait for flush of DMA/FIFO when closing port.
- *
- * Revision 1.22  2000/01/20 18:10:23  johana
- * Added TIOCMGET ioctl to return modem status.
- * Implemented modem status/control that works with the extra signals
- * (DTR, DSR, RI,CD) as well.
- * 3 different modes supported:
- * ser0 on PB (Bundy), ser1 on PB (Lisa) and ser2 on PA (Bundy)
- * Fixed DEF_TX value that caused the serial transmitter pin (txd) to go to 0 when
- * closing the last filehandle, NASTY!.
- * Added break generation, not tested though!
- * Use IRQF_SHARED when request_irq() for ser2 and ser3 (shared with) par0 and par1.
- * You can't use them at the same time (yet..), but you can hopefully switch
- * between ser2/par0, ser3/par1 with the same kernel config.
- * Replaced some magic constants with defines
- *
- *
  */
 
 static char *serial_version = "$Revision: 1.25 $";
@@ -446,6 +30,7 @@ static char *serial_version = "$Revision: 1.25 $";
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/dma.h>
 #include <asm/system.h>
 #include <linux/delay.h>
 
@@ -454,8 +39,9 @@ static char *serial_version = "$Revision: 1.25 $";
 /* non-arch dependent serial structures are in linux/serial.h */
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
-#include "serial.h"
+#include "crisv10.h"
 #include <asm/fasttimer.h>
+#include <asm/arch/io_interface_mux.h>
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 #ifndef CONFIG_ETRAX_FAST_TIMER
@@ -504,18 +90,6 @@ struct tty_driver *serial_driver;
    from eLinux */
 #define SERIAL_HANDLE_EARLY_ERRORS
 
-/* Defined and used in n_tty.c, but we need it here as well */
-#define TTY_THRESHOLD_THROTTLE 128
-
-/* Due to buffersizes and threshold values, our SERIAL_DESCR_BUF_SIZE
- * must not be to high or flow control won't work if we leave it to the tty
- * layer so we have our own throttling in flush_to_flip
- * TTY_FLIPBUF_SIZE=512,
- * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128
- * BUF_SIZE can't be > 128
- */
-#define CRIS_BUF_SIZE  512
-
 /* Currently 16 descriptors x 128 bytes = 2048 bytes */
 #define SERIAL_DESCR_BUF_SIZE 256
 
@@ -588,13 +162,13 @@ unsigned long timer_data_to_ns(unsigned long timer_data);
 static void change_speed(struct e100_serial *info);
 static void rs_throttle(struct tty_struct * tty);
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-static int rs_write(struct tty_struct * tty, int from_user,
-                    const unsigned char *buf, int count);
+static int rs_write(struct tty_struct *tty,
+               const unsigned char *buf, int count);
 #ifdef CONFIG_ETRAX_RS485
-static int e100_write_rs485(struct tty_struct * tty, int from_user,
-                            const unsigned char *buf, int count);
+static int e100_write_rs485(struct tty_struct *tty,
+               const unsigned char *buf, int count);
 #endif
-static int get_lsr_info(struct e100_serial * info, unsigned int *value);
+static int get_lsr_info(struct e100_serial *info, unsigned int *value);
 
 
 #define DEF_BAUD 115200   /* 115.2 kbit/s */
@@ -679,20 +253,39 @@ static struct e100_serial rs_table[] = {
          .rx_ctrl     = DEF_RX,
          .tx_ctrl     = DEF_TX,
          .iseteop     = 2,
+         .dma_owner   = dma_ser0,
+         .io_if       = if_serial_0,
 #ifdef CONFIG_ETRAX_SERIAL_PORT0
           .enabled  = 1,
 #ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
          .dma_out_enabled = 1,
+         .dma_out_nbr = SER0_TX_DMA_NBR,
+         .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR,
+         .dma_out_irq_flags = IRQF_DISABLED,
+         .dma_out_irq_description = "serial 0 dma tr",
 #else
          .dma_out_enabled = 0,
+         .dma_out_nbr = UINT_MAX,
+         .dma_out_irq_nbr = 0,
+         .dma_out_irq_flags = 0,
+         .dma_out_irq_description = NULL,
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
          .dma_in_enabled = 1,
+         .dma_in_nbr = SER0_RX_DMA_NBR,
+         .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR,
+         .dma_in_irq_flags = IRQF_DISABLED,
+         .dma_in_irq_description = "serial 0 dma rec",
 #else
-         .dma_in_enabled = 0
+         .dma_in_enabled = 0,
+         .dma_in_nbr = UINT_MAX,
+         .dma_in_irq_nbr = 0,
+         .dma_in_irq_flags = 0,
+         .dma_in_irq_description = NULL,
 #endif
 #else
           .enabled  = 0,
+         .io_if_description = NULL,
          .dma_out_enabled = 0,
          .dma_in_enabled = 0
 #endif
@@ -714,20 +307,42 @@ static struct e100_serial rs_table[] = {
          .rx_ctrl     = DEF_RX,
          .tx_ctrl     = DEF_TX,
          .iseteop     = 3,
+         .dma_owner   = dma_ser1,
+         .io_if       = if_serial_1,
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
           .enabled  = 1,
+         .io_if_description = "ser1",
 #ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
          .dma_out_enabled = 1,
+         .dma_out_nbr = SER1_TX_DMA_NBR,
+         .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR,
+         .dma_out_irq_flags = IRQF_DISABLED,
+         .dma_out_irq_description = "serial 1 dma tr",
 #else
          .dma_out_enabled = 0,
+         .dma_out_nbr = UINT_MAX,
+         .dma_out_irq_nbr = 0,
+         .dma_out_irq_flags = 0,
+         .dma_out_irq_description = NULL,
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
          .dma_in_enabled = 1,
+         .dma_in_nbr = SER1_RX_DMA_NBR,
+         .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR,
+         .dma_in_irq_flags = IRQF_DISABLED,
+         .dma_in_irq_description = "serial 1 dma rec",
 #else
-         .dma_in_enabled = 0
+         .dma_in_enabled = 0,
+         .dma_in_enabled = 0,
+         .dma_in_nbr = UINT_MAX,
+         .dma_in_irq_nbr = 0,
+         .dma_in_irq_flags = 0,
+         .dma_in_irq_description = NULL,
 #endif
 #else
           .enabled  = 0,
+         .io_if_description = NULL,
+         .dma_in_irq_nbr = 0,
          .dma_out_enabled = 0,
          .dma_in_enabled = 0
 #endif
@@ -748,20 +363,40 @@ static struct e100_serial rs_table[] = {
          .rx_ctrl     = DEF_RX,
          .tx_ctrl     = DEF_TX,
          .iseteop     = 0,
+         .dma_owner   = dma_ser2,
+         .io_if       = if_serial_2,
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
           .enabled  = 1,
+         .io_if_description = "ser2",
 #ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
          .dma_out_enabled = 1,
+         .dma_out_nbr = SER2_TX_DMA_NBR,
+         .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR,
+         .dma_out_irq_flags = IRQF_DISABLED,
+         .dma_out_irq_description = "serial 2 dma tr",
 #else
          .dma_out_enabled = 0,
+         .dma_out_nbr = UINT_MAX,
+         .dma_out_irq_nbr = 0,
+         .dma_out_irq_flags = 0,
+         .dma_out_irq_description = NULL,
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
          .dma_in_enabled = 1,
+         .dma_in_nbr = SER2_RX_DMA_NBR,
+         .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR,
+         .dma_in_irq_flags = IRQF_DISABLED,
+         .dma_in_irq_description = "serial 2 dma rec",
 #else
-         .dma_in_enabled = 0
+         .dma_in_enabled = 0,
+         .dma_in_nbr = UINT_MAX,
+         .dma_in_irq_nbr = 0,
+         .dma_in_irq_flags = 0,
+         .dma_in_irq_description = NULL,
 #endif
 #else
           .enabled  = 0,
+         .io_if_description = NULL,
          .dma_out_enabled = 0,
          .dma_in_enabled = 0
 #endif
@@ -782,20 +417,40 @@ static struct e100_serial rs_table[] = {
          .rx_ctrl     = DEF_RX,
          .tx_ctrl     = DEF_TX,
          .iseteop     = 1,
+         .dma_owner   = dma_ser3,
+         .io_if       = if_serial_3,
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
           .enabled  = 1,
+         .io_if_description = "ser3",
 #ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
          .dma_out_enabled = 1,
+         .dma_out_nbr = SER3_TX_DMA_NBR,
+         .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR,
+         .dma_out_irq_flags = IRQF_DISABLED,
+         .dma_out_irq_description = "serial 3 dma tr",
 #else
          .dma_out_enabled = 0,
+         .dma_out_nbr = UINT_MAX,
+         .dma_out_irq_nbr = 0,
+         .dma_out_irq_flags = 0,
+         .dma_out_irq_description = NULL,
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
          .dma_in_enabled = 1,
+         .dma_in_nbr = SER3_RX_DMA_NBR,
+         .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR,
+         .dma_in_irq_flags = IRQF_DISABLED,
+         .dma_in_irq_description = "serial 3 dma rec",
 #else
-         .dma_in_enabled = 0
+         .dma_in_enabled = 0,
+         .dma_in_nbr = UINT_MAX,
+         .dma_in_irq_nbr = 0,
+         .dma_in_irq_flags = 0,
+         .dma_in_irq_description = NULL
 #endif
 #else
           .enabled  = 0,
+         .io_if_description = NULL,
          .dma_out_enabled = 0,
          .dma_in_enabled = 0
 #endif
@@ -1416,12 +1071,11 @@ e100_dtr(struct e100_serial *info, int set)
        {
                unsigned long flags;
 
-               save_flags(flags);
-               cli();
+               local_irq_save(flags);
                *e100_modem_pins[info->line].dtr_shadow &= ~mask;
                *e100_modem_pins[info->line].dtr_shadow |= (set ? 0 : mask);
                *e100_modem_pins[info->line].dtr_port = *e100_modem_pins[info->line].dtr_shadow;
-               restore_flags(flags);
+               local_irq_restore(flags);
        }
 
 #ifdef SERIAL_DEBUG_IO
@@ -1440,12 +1094,11 @@ e100_rts(struct e100_serial *info, int set)
 {
 #ifndef CONFIG_SVINTO_SIM
        unsigned long flags;
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        info->rx_ctrl &= ~E100_RTS_MASK;
        info->rx_ctrl |= (set ? 0 : E100_RTS_MASK);  /* RTS is active low */
        info->port[REG_REC_CTRL] = info->rx_ctrl;
-       restore_flags(flags);
+       local_irq_restore(flags);
 #ifdef SERIAL_DEBUG_IO
        printk("ser%i rts %i\n", info->line, set);
 #endif
@@ -1463,12 +1116,11 @@ e100_ri_out(struct e100_serial *info, int set)
                unsigned char mask = e100_modem_pins[info->line].ri_mask;
                unsigned long flags;
 
-               save_flags(flags);
-               cli();
+               local_irq_save(flags);
                *e100_modem_pins[info->line].ri_shadow &= ~mask;
                *e100_modem_pins[info->line].ri_shadow |= (set ? 0 : mask);
                *e100_modem_pins[info->line].ri_port = *e100_modem_pins[info->line].ri_shadow;
-               restore_flags(flags);
+               local_irq_restore(flags);
        }
 #endif
 }
@@ -1481,12 +1133,11 @@ e100_cd_out(struct e100_serial *info, int set)
                unsigned char mask = e100_modem_pins[info->line].cd_mask;
                unsigned long flags;
 
-               save_flags(flags);
-               cli();
+               local_irq_save(flags);
                *e100_modem_pins[info->line].cd_shadow &= ~mask;
                *e100_modem_pins[info->line].cd_shadow |= (set ? 0 : mask);
                *e100_modem_pins[info->line].cd_port = *e100_modem_pins[info->line].cd_shadow;
-               restore_flags(flags);
+               local_irq_restore(flags);
        }
 #endif
 }
@@ -1560,8 +1211,7 @@ static void e100_disable_txdma_channel(struct e100_serial *info)
        /* Disable output DMA channel for the serial port in question
         * ( set to something other then serialX)
         */
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line));
        if (info->line == 0) {
                if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) ==
@@ -1589,7 +1239,7 @@ static void e100_disable_txdma_channel(struct e100_serial *info)
                }
        }
        *R_GEN_CONFIG = genconfig_shadow;
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 
@@ -1597,8 +1247,7 @@ static void e100_enable_txdma_channel(struct e100_serial *info)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line));
        /* Enable output DMA channel for the serial port in question */
        if (info->line == 0) {
@@ -1615,7 +1264,7 @@ static void e100_enable_txdma_channel(struct e100_serial *info)
                genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3);
        }
        *R_GEN_CONFIG = genconfig_shadow;
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 static void e100_disable_rxdma_channel(struct e100_serial *info)
@@ -1625,8 +1274,7 @@ static void e100_disable_rxdma_channel(struct e100_serial *info)
        /* Disable input DMA channel for the serial port in question
         * ( set to something other then serialX)
         */
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        if (info->line == 0) {
                if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) ==
                    IO_STATE(R_GEN_CONFIG, dma7, serial0)) {
@@ -1653,7 +1301,7 @@ static void e100_disable_rxdma_channel(struct e100_serial *info)
                }
        }
        *R_GEN_CONFIG = genconfig_shadow;
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 
@@ -1661,8 +1309,7 @@ static void e100_enable_rxdma_channel(struct e100_serial *info)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        /* Enable input DMA channel for the serial port in question */
        if (info->line == 0) {
                genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma7);
@@ -1678,7 +1325,7 @@ static void e100_enable_rxdma_channel(struct e100_serial *info)
                genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3);
        }
        *R_GEN_CONFIG = genconfig_shadow;
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
@@ -1785,7 +1432,7 @@ e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r)
 }
 
 static int
-e100_write_rs485(struct tty_struct *tty, int from_user,
+e100_write_rs485(struct tty_struct *tty,
                  const unsigned char *buf, int count)
 {
        struct e100_serial * info = (struct e100_serial *)tty->driver_data;
@@ -1798,7 +1445,7 @@ e100_write_rs485(struct tty_struct *tty, int from_user,
         */
        info->rs485.enabled = 1;
        /* rs_write now deals with RS485 if enabled */
-       count = rs_write(tty, from_user, buf, count);
+       count = rs_write(tty, buf, count);
        info->rs485.enabled = old_enabled;
        return count;
 }
@@ -1836,7 +1483,7 @@ rs_stop(struct tty_struct *tty)
                unsigned long flags;
                unsigned long xoff;
 
-               save_flags(flags); cli();
+               local_irq_save(flags);
                DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n",
                                CIRC_CNT(info->xmit.head,
                                         info->xmit.tail,SERIAL_XMIT_SIZE)));
@@ -1848,7 +1495,7 @@ rs_stop(struct tty_struct *tty)
                }
 
                *((unsigned long *)&info->port[REG_XOFF]) = xoff;
-               restore_flags(flags);
+               local_irq_restore(flags);
        }
 }
 
@@ -1860,7 +1507,7 @@ rs_start(struct tty_struct *tty)
                unsigned long flags;
                unsigned long xoff;
 
-               save_flags(flags); cli();
+               local_irq_save(flags);
                DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n",
                                CIRC_CNT(info->xmit.head,
                                         info->xmit.tail,SERIAL_XMIT_SIZE)));
@@ -1875,7 +1522,7 @@ rs_start(struct tty_struct *tty)
                    info->xmit.head != info->xmit.tail && info->xmit.buf)
                        e100_enable_serial_tx_ready_irq(info);
 
-               restore_flags(flags);
+               local_irq_restore(flags);
        }
 }
 
@@ -2055,8 +1702,7 @@ static int serial_fast_timer_expired = 0;
 static void flush_timeout_function(unsigned long data);
 #define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\
   unsigned long timer_flags; \
-  save_flags(timer_flags); \
-  cli(); \
+  local_irq_save(timer_flags); \
   if (fast_timers[info->line].function == NULL) { \
     serial_fast_timer_started++; \
     TIMERD(DEBUG_LOG(info->line, "start_timer %i ", info->line)); \
@@ -2070,7 +1716,7 @@ static void flush_timeout_function(unsigned long data);
   else { \
     TIMERD(DEBUG_LOG(info->line, "timer %i already running\n", info->line)); \
   } \
-  restore_flags(timer_flags); \
+  local_irq_restore(timer_flags); \
 }
 #define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec)
 
@@ -2099,8 +1745,7 @@ append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
 
        if (!info->first_recv_buffer)
                info->first_recv_buffer = buffer;
@@ -2113,7 +1758,7 @@ append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer)
        if (info->recv_cnt > info->max_recv_cnt)
                info->max_recv_cnt = info->recv_cnt;
 
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 static int
@@ -2133,11 +1778,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl
                info->icount.rx++;
        } else {
                struct tty_struct *tty = info->tty;
-               *tty->flip.char_buf_ptr = data;
-               *tty->flip.flag_buf_ptr = flag;
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
+               tty_insert_flip_char(tty, data, flag);
                info->icount.rx++;
        }
 
@@ -2322,7 +1963,6 @@ start_receive(struct e100_serial *info)
         */
        return;
 #endif
-       info->tty->flip.count = 0;
        if (info->uses_dma_in) {
                /* reset the input dma channel to be sure it works */
 
@@ -2484,32 +2124,20 @@ static void flush_to_flip_buffer(struct e100_serial *info)
 {
        struct tty_struct *tty;
        struct etrax_recv_buffer *buffer;
-       unsigned int length;
        unsigned long flags;
-       int max_flip_size;
-
-       if (!info->first_recv_buffer)
-               return;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
+       tty = info->tty;
 
-       if (!(tty = info->tty)) {
-               restore_flags(flags);
+       if (!tty) {
+               local_irq_restore(flags);
                return;
        }
 
        while ((buffer = info->first_recv_buffer) != NULL) {
                unsigned int count = buffer->length;
 
-               count = tty_buffer_request_room(tty, count);
-               if (count == 0) /* Throttle ?? */
-                       break;
-
-               if (count > 1)
-                       tty_insert_flip_strings(tty, buffer->buffer, count - 1);
-               tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error);
-
+               tty_insert_flip_string(tty, buffer->buffer, count);
                info->recv_cnt -= count;
 
                if (count == buffer->length) {
@@ -2525,18 +2153,9 @@ static void flush_to_flip_buffer(struct e100_serial *info)
        if (!info->first_recv_buffer)
                info->last_recv_buffer = NULL;
 
-       restore_flags(flags);
-
-       DFLIP(
-         if (1) {
-                 DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx);
-                 DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty));
-                 DEBUG_LOG(info->line, "room  %lu\n", tty->ldisc.receive_room(tty));
-         }
+       local_irq_restore(flags);
 
-       );
-
-       /* this includes a check for low-latency */
+       /* This includes a check for low-latency */
        tty_flip_buffer_push(tty);
 }
 
@@ -2679,21 +2298,7 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
                printk("!NO TTY!\n");
                return info;
        }
-       if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) {
-               /* check TTY_THROTTLED first so it indicates our state */
-               if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
-                       DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count));
-                       rs_throttle(tty);
-               }
-       }
-       if (tty->flip.count >= CRIS_BUF_SIZE) {
-               DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count);
-               tty->flip.work.func((void *) tty);
-               if (tty->flip.count >= CRIS_BUF_SIZE) {
-                       DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count);
-                       return info;            /* if TTY_DONT_FLIP is set */
-               }
-       }
+
        /* Read data and status at the same time */
        data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
 more_data:
@@ -2746,27 +2351,26 @@ more_data:
                                DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt);
                                info->errorcode = ERRCODE_INSERT_BREAK;
                        } else {
+                               unsigned char data = IO_EXTRACT(R_SERIAL0_READ,
+                                       data_in, data_read);
+                               char flag = TTY_NORMAL;
                                if (info->errorcode == ERRCODE_INSERT_BREAK) {
-                                       info->icount.brk++;
-                                       *tty->flip.char_buf_ptr = 0;
-                                       *tty->flip.flag_buf_ptr = TTY_BREAK;
-                                       tty->flip.flag_buf_ptr++;
-                                       tty->flip.char_buf_ptr++;
-                                       tty->flip.count++;
+                                       struct tty_struct *tty = info->tty;
+                                       tty_insert_flip_char(tty, 0, flag);
                                        info->icount.rx++;
                                }
-                               *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read);
 
                                if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) {
                                        info->icount.parity++;
-                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) {
                                        info->icount.overrun++;
-                                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+                                       flag = TTY_OVERRUN;
                                } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) {
                                        info->icount.frame++;
-                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
+                                       flag = TTY_FRAME;
                                }
+                               tty_insert_flip_char(tty, data, flag);
                                info->errorcode = 0;
                        }
                        info->break_detected_cnt = 0;
@@ -2782,16 +2386,14 @@ more_data:
                        log_int(rdpc(), 0, 0);
                }
                );
-               *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read);
-               *tty->flip.flag_buf_ptr = 0;
+               tty_insert_flip_char(tty,
+                       IO_EXTRACT(R_SERIAL0_READ, data_in, data_read),
+                       TTY_NORMAL);
        } else {
                DEBUG_LOG(info->line, "ser_rx int but no data_avail  %08lX\n", data_read);
        }
 
 
-       tty->flip.flag_buf_ptr++;
-       tty->flip.char_buf_ptr++;
-       tty->flip.count++;
        info->icount.rx++;
        data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
        if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
@@ -2929,7 +2531,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
        if (info->x_char) {
                unsigned char rstat;
                DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
-               save_flags(flags); cli();
+               local_irq_save(flags);
                rstat = info->port[REG_STATUS];
                DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
 
@@ -2938,7 +2540,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
                info->x_char = 0;
                /* We must enable since it is disabled in ser_interrupt */
                e100_enable_serial_tx_ready_irq(info);
-               restore_flags(flags);
+               local_irq_restore(flags);
                return;
        }
        if (info->uses_dma_out) {
@@ -2946,7 +2548,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
                int i;
                /* We only use normal tx interrupt when sending x_char */
                DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
-               save_flags(flags); cli();
+               local_irq_save(flags);
                rstat = info->port[REG_STATUS];
                DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
                e100_disable_serial_tx_ready_irq(info);
@@ -2959,7 +2561,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
                        nop();
 
                *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue);
-               restore_flags(flags);
+               local_irq_restore(flags);
                return;
        }
        /* Normal char-by-char interrupt */
@@ -2973,7 +2575,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
        }
        DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
        /* Send a byte, rs485 timing is critical so turn of ints */
-       save_flags(flags); cli();
+       local_irq_save(flags);
        info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
        info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
        info->icount.tx++;
@@ -2997,7 +2599,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
                /* We must enable since it is disabled in ser_interrupt */
                e100_enable_serial_tx_ready_irq(info);
        }
-       restore_flags(flags);
+       local_irq_restore(flags);
 
        if (CIRC_CNT(info->xmit.head,
                     info->xmit.tail,
@@ -3022,7 +2624,7 @@ ser_interrupt(int irq, void *dev_id)
        int handled = 0;
        static volatile unsigned long reentered_ready_mask = 0;
 
-       save_flags(flags); cli();
+       local_irq_save(flags);
        irq_mask1_rd = *R_IRQ_MASK1_RD;
        /* First handle all rx interrupts with ints disabled */
        info = rs_table;
@@ -3067,7 +2669,7 @@ ser_interrupt(int irq, void *dev_id)
                        /* Unblock the serial interrupt */
                        *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
 
-                       sti();
+                       local_irq_enable();
                        ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */
                        info = rs_table;
                        for (i = 0; i < NR_PORTS; i++) {
@@ -3080,11 +2682,11 @@ ser_interrupt(int irq, void *dev_id)
                                ready_mask <<= 2;
                        }
                        /* handle_ser_tx_interrupt enables tr_ready interrupts */
-                       cli();
+                       local_irq_disable();
                        /* Handle reentered TX interrupt */
                        irq_mask1_rd = reentered_ready_mask;
                }
-               cli();
+               local_irq_disable();
                tx_started = 0;
        } else {
                unsigned long ready_mask;
@@ -3100,7 +2702,7 @@ ser_interrupt(int irq, void *dev_id)
                }
        }
 
-       restore_flags(flags);
+       local_irq_restore(flags);
        return IRQ_RETVAL(handled);
 } /* ser_interrupt */
 #endif
@@ -3121,11 +2723,13 @@ ser_interrupt(int irq, void *dev_id)
  * them using rs_sched_event(), and they get done here.
  */
 static void
-do_softint(void *private_)
+do_softint(struct work_struct *work)
 {
-       struct e100_serial      *info = (struct e100_serial *) private_;
+       struct e100_serial      *info;
        struct tty_struct       *tty;
 
+       info = container_of(work, struct e100_serial, work);
+
        tty = info->tty;
        if (!tty)
                return;
@@ -3145,13 +2749,12 @@ startup(struct e100_serial * info)
        if (!xmit_page)
                return -ENOMEM;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
 
        /* if it was already initialized, skip this */
 
        if (info->flags & ASYNC_INITIALIZED) {
-               restore_flags(flags);
+               local_irq_restore(flags);
                free_page(xmit_page);
                return 0;
        }
@@ -3277,7 +2880,7 @@ startup(struct e100_serial * info)
 
        info->flags |= ASYNC_INITIALIZED;
 
-       restore_flags(flags);
+       local_irq_restore(flags);
        return 0;
 }
 
@@ -3328,8 +2931,7 @@ shutdown(struct e100_serial * info)
               info->irq);
 #endif
 
-       save_flags(flags);
-       cli(); /* Disable interrupts */
+       local_irq_save(flags);
 
        if (info->xmit.buf) {
                free_page((unsigned long)info->xmit.buf);
@@ -3353,7 +2955,7 @@ shutdown(struct e100_serial * info)
                set_bit(TTY_IO_ERROR, &info->tty->flags);
 
        info->flags &= ~ASYNC_INITIALIZED;
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 
@@ -3411,7 +3013,6 @@ change_speed(struct e100_serial *info)
                                DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8));
                                info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8;
                        }
-               }
 #endif
                else
                {
@@ -3445,8 +3046,7 @@ change_speed(struct e100_serial *info)
 
 #ifndef CONFIG_SVINTO_SIM
        /* start with default settings and then fill in changes */
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        /* 8 bit, no/even parity */
        info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) |
                           IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) |
@@ -3510,7 +3110,7 @@ change_speed(struct e100_serial *info)
        }
 
        *((unsigned long *)&info->port[REG_XOFF]) = xoff;
-       restore_flags(flags);
+       local_irq_restore(flags);
 #endif /* !CONFIG_SVINTO_SIM */
 
        update_char_time(info);
@@ -3538,13 +3138,12 @@ rs_flush_chars(struct tty_struct *tty)
 
        /* this protection might not exactly be necessary here */
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        start_transmit(info);
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
-static int rs_raw_write(struct tty_struct * tty, int from_user,
+static int rs_raw_write(struct tty_struct *tty,
                        const unsigned char *buf, int count)
 {
        int     c, ret = 0;
@@ -3567,53 +3166,19 @@ static int rs_raw_write(struct tty_struct * tty, int from_user,
        SIMCOUT(buf, count);
        return count;
 #endif
-       save_flags(flags);
+       local_save_flags(flags);
        DFLOW(DEBUG_LOG(info->line, "write count %i ", count));
        DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty)));
 
 
-       /* the cli/restore_flags pairs below are needed because the
-        * DMA interrupt handler moves the info->xmit values. the memcpy
-        * needs to be in the critical region unfortunately, because we
-        * need to read xmit values, memcpy, write xmit values in one
-        * atomic operation... this could perhaps be avoided by more clever
-        * design.
+       /* The local_irq_disable/restore_flags pairs below are needed
+        * because the DMA interrupt handler moves the info->xmit values.
+        * the memcpy needs to be in the critical region unfortunately,
+        * because we need to read xmit values, memcpy, write xmit values
+        * in one atomic operation... this could perhaps be avoided by
+        * more clever design.
         */
-       if (from_user) {
-               mutex_lock(&tmp_buf_mutex);
-               while (1) {
-                       int c1;
-                       c = CIRC_SPACE_TO_END(info->xmit.head,
-                                             info->xmit.tail,
-                                             SERIAL_XMIT_SIZE);
-                       if (count < c)
-                               c = count;
-                       if (c <= 0)
-                               break;
-
-                       c -= copy_from_user(tmp_buf, buf, c);
-                       if (!c) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
-                       cli();
-                       c1 = CIRC_SPACE_TO_END(info->xmit.head,
-                                              info->xmit.tail,
-                                              SERIAL_XMIT_SIZE);
-                       if (c1 < c)
-                               c = c1;
-                       memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
-                       info->xmit.head = ((info->xmit.head + c) &
-                                          (SERIAL_XMIT_SIZE-1));
-                       restore_flags(flags);
-                       buf += c;
-                       count -= c;
-                       ret += c;
-               }
-               mutex_unlock(&tmp_buf_mutex);
-       } else {
-               cli();
+       local_irq_disable();
                while (count) {
                        c = CIRC_SPACE_TO_END(info->xmit.head,
                                              info->xmit.tail,
@@ -3631,8 +3196,7 @@ static int rs_raw_write(struct tty_struct * tty, int from_user,
                        count -= c;
                        ret += c;
                }
-               restore_flags(flags);
-       }
+       local_irq_restore(flags);
 
        /* enable transmitter if not running, unless the tty is stopped
         * this does not need IRQ protection since if tr_running == 0
@@ -3651,7 +3215,7 @@ static int rs_raw_write(struct tty_struct * tty, int from_user,
 } /* raw_raw_write() */
 
 static int
-rs_write(struct tty_struct * tty, int from_user,
+rs_write(struct tty_struct *tty,
         const unsigned char *buf, int count)
 {
 #if defined(CONFIG_ETRAX_RS485)
@@ -3678,7 +3242,7 @@ rs_write(struct tty_struct * tty, int from_user,
        }
 #endif /* CONFIG_ETRAX_RS485 */
 
-       count = rs_raw_write(tty, from_user, buf, count);
+       count = rs_raw_write(tty, buf, count);
 
 #if defined(CONFIG_ETRAX_RS485)
        if (info->rs485.enabled)
@@ -3746,10 +3310,9 @@ rs_flush_buffer(struct tty_struct *tty)
        struct e100_serial *info = (struct e100_serial *)tty->driver_data;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        info->xmit.head = info->xmit.tail = 0;
-       restore_flags(flags);
+       local_irq_restore(flags);
 
        tty_wakeup(tty);
 }
@@ -3767,7 +3330,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
 {
        struct e100_serial *info = (struct e100_serial *)tty->driver_data;
        unsigned long flags;
-       save_flags(flags); cli();
+       local_irq_save(flags);
        if (info->uses_dma_out) {
                /* Put the DMA on hold and disable the channel */
                *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold);
@@ -3784,7 +3347,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
        DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch));
        info->x_char = ch;
        e100_enable_serial_tx_ready_irq(info);
-       restore_flags(flags);
+       local_irq_restore(flags);
 }
 
 /*
@@ -3996,21 +3559,61 @@ char *get_control_state_str(int MLines, char *s)
 }
 #endif
 
+static void
+rs_break(struct tty_struct *tty, int break_state)
+{
+       struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+       unsigned long flags;
+
+       if (!info->port)
+               return;
+
+       local_irq_save(flags);
+       if (break_state == -1) {
+               /* Go to manual mode and set the txd pin to 0 */
+               /* Clear bit 7 (txd) and 6 (tr_enable) */
+               info->tx_ctrl &= 0x3F;
+       } else {
+               /* Set bit 7 (txd) and 6 (tr_enable) */
+               info->tx_ctrl |= (0x80 | 0x40);
+       }
+       info->port[REG_TR_CTRL] = info->tx_ctrl;
+       local_irq_restore(flags);
+}
+
 static int
-get_modem_info(struct e100_serial * info, unsigned int *value)
+rs_tiocmset(struct tty_struct *tty, struct file *file,
+               unsigned int set, unsigned int clear)
 {
-       unsigned int result;
-       /* Polarity isn't verified */
-#if 0 /*def SERIAL_DEBUG_IO  */
+       struct e100_serial *info = (struct e100_serial *)tty->driver_data;
 
-       printk("get_modem_info: RTS: %i DTR: %i CD: %i RI: %i DSR: %i CTS: %i\n",
-              E100_RTS_GET(info),
-              E100_DTR_GET(info),
-              E100_CD_GET(info),
-              E100_RI_GET(info),
-              E100_DSR_GET(info),
-              E100_CTS_GET(info));
-#endif
+       if (clear & TIOCM_RTS)
+               e100_rts(info, 0);
+       if (clear & TIOCM_DTR)
+               e100_dtr(info, 0);
+       /* Handle FEMALE behaviour */
+       if (clear & TIOCM_RI)
+               e100_ri_out(info, 0);
+       if (clear & TIOCM_CD)
+               e100_cd_out(info, 0);
+
+       if (set & TIOCM_RTS)
+               e100_rts(info, 1);
+       if (set & TIOCM_DTR)
+               e100_dtr(info, 1);
+       /* Handle FEMALE behaviour */
+       if (set & TIOCM_RI)
+               e100_ri_out(info, 1);
+       if (set & TIOCM_CD)
+               e100_cd_out(info, 1);
+       return 0;
+}
+
+static int
+rs_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+       unsigned int result;
 
        result =
                (!E100_RTS_GET(info) ? TIOCM_RTS : 0)
@@ -4021,95 +3624,20 @@ get_modem_info(struct e100_serial * info, unsigned int *value)
                | (!E100_CTS_GET(info) ? TIOCM_CTS : 0);
 
 #ifdef SERIAL_DEBUG_IO
-       printk("e100ser: modem state: %i 0x%08X\n", result, result);
+       printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n",
+               info->line, result, result);
        {
                char s[100];
 
                get_control_state_str(result, s);
-               printk("state: %s\n", s);
+               printk(KERN_DEBUG "state: %s\n", s);
        }
 #endif
-       if (copy_to_user(value, &result, sizeof(int)))
-               return -EFAULT;
-       return 0;
-}
+       return result;
 
-
-static int
-set_modem_info(struct e100_serial * info, unsigned int cmd,
-              unsigned int *value)
-{
-       unsigned int arg;
-
-       if (copy_from_user(&arg, value, sizeof(int)))
-               return -EFAULT;
-
-       switch (cmd) {
-       case TIOCMBIS:
-               if (arg & TIOCM_RTS) {
-                       e100_rts(info, 1);
-               }
-               if (arg & TIOCM_DTR) {
-                       e100_dtr(info, 1);
-               }
-               /* Handle FEMALE behaviour */
-               if (arg & TIOCM_RI) {
-                       e100_ri_out(info, 1);
-               }
-               if (arg & TIOCM_CD) {
-                       e100_cd_out(info, 1);
-               }
-               break;
-       case TIOCMBIC:
-               if (arg & TIOCM_RTS) {
-                       e100_rts(info, 0);
-               }
-               if (arg & TIOCM_DTR) {
-                       e100_dtr(info, 0);
-               }
-               /* Handle FEMALE behaviour */
-               if (arg & TIOCM_RI) {
-                       e100_ri_out(info, 0);
-               }
-               if (arg & TIOCM_CD) {
-                       e100_cd_out(info, 0);
-               }
-               break;
-       case TIOCMSET:
-               e100_rts(info, arg & TIOCM_RTS);
-               e100_dtr(info, arg & TIOCM_DTR);
-               /* Handle FEMALE behaviour */
-               e100_ri_out(info, arg & TIOCM_RI);
-               e100_cd_out(info, arg & TIOCM_CD);
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
 }
 
 
-static void
-rs_break(struct tty_struct *tty, int break_state)
-{
-       struct e100_serial * info = (struct e100_serial *)tty->driver_data;
-       unsigned long flags;
-
-       if (!info->port)
-               return;
-
-       save_flags(flags);
-       cli();
-       if (break_state == -1) {
-               /* Go to manual mode and set the txd pin to 0 */
-               info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */
-       } else {
-               info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */
-       }
-       info->port[REG_TR_CTRL] = info->tx_ctrl;
-       restore_flags(flags);
-}
-
 static int
 rs_ioctl(struct tty_struct *tty, struct file * file,
         unsigned int cmd, unsigned long arg)
@@ -4124,49 +3652,45 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
        }
 
        switch (cmd) {
-               case TIOCMGET:
-                       return get_modem_info(info, (unsigned int *) arg);
-               case TIOCMBIS:
-               case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
-               case TIOCGSERIAL:
-                       return get_serial_info(info,
-                                              (struct serial_struct *) arg);
-               case TIOCSSERIAL:
-                       return set_serial_info(info,
-                                              (struct serial_struct *) arg);
-               case TIOCSERGETLSR: /* Get line status register */
-                       return get_lsr_info(info, (unsigned int *) arg);
-
-               case TIOCSERGSTRUCT:
-                       if (copy_to_user((struct e100_serial *) arg,
-                                        info, sizeof(struct e100_serial)))
-                               return -EFAULT;
-                       return 0;
+       case TIOCGSERIAL:
+               return get_serial_info(info,
+                                      (struct serial_struct *) arg);
+       case TIOCSSERIAL:
+               return set_serial_info(info,
+                                      (struct serial_struct *) arg);
+       case TIOCSERGETLSR: /* Get line status register */
+               return get_lsr_info(info, (unsigned int *) arg);
+
+       case TIOCSERGSTRUCT:
+               if (copy_to_user((struct e100_serial *) arg,
+                                info, sizeof(struct e100_serial)))
+                       return -EFAULT;
+               return 0;
 
 #if defined(CONFIG_ETRAX_RS485)
-               case TIOCSERSETRS485:
-               {
-                       struct rs485_control rs485ctrl;
-                       if (copy_from_user(&rs485ctrl, (struct rs485_control*)arg, sizeof(rs485ctrl)))
-                               return -EFAULT;
+       case TIOCSERSETRS485:
+       {
+               struct rs485_control rs485ctrl;
+               if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg,
+                               sizeof(rs485ctrl)))
+                       return -EFAULT;
 
-                       return e100_enable_rs485(tty, &rs485ctrl);
-               }
+               return e100_enable_rs485(tty, &rs485ctrl);
+       }
 
-               case TIOCSERWRRS485:
-               {
-                       struct rs485_write rs485wr;
-                       if (copy_from_user(&rs485wr, (struct rs485_write*)arg, sizeof(rs485wr)))
-                               return -EFAULT;
+       case TIOCSERWRRS485:
+       {
+               struct rs485_write rs485wr;
+               if (copy_from_user(&rs485wr, (struct rs485_write *)arg,
+                               sizeof(rs485wr)))
+                       return -EFAULT;
 
-                       return e100_write_rs485(tty, 1, rs485wr.outc, rs485wr.outc_size);
-               }
+               return e100_write_rs485(tty, rs485wr.outc, rs485wr.outc_size);
+       }
 #endif
 
-               default:
-                       return -ENOIOCTLCMD;
+       default:
+               return -ENOIOCTLCMD;
        }
        return 0;
 }
@@ -4191,46 +3715,6 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
 }
 
-/* In debugport.c - register a console write function that uses the normal
- * serial driver
- */
-typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len);
-
-extern debugport_write_function debug_write_function;
-
-static int rs_debug_write_function(int i, const char *buf, unsigned int len)
-{
-       int cnt;
-       int written = 0;
-        struct tty_struct *tty;
-        static int recurse_cnt = 0;
-
-        tty = rs_table[i].tty;
-        if (tty)  {
-               unsigned long flags;
-               if (recurse_cnt > 5) /* We skip this debug output */
-                       return 1;
-
-               local_irq_save(flags);
-               recurse_cnt++;
-               local_irq_restore(flags);
-                do {
-                        cnt = rs_write(tty, 0, buf + written, len);
-                        if (cnt >= 0) {
-                               written += cnt;
-                                buf += cnt;
-                                len -= cnt;
-                        } else
-                                len = cnt;
-                } while(len > 0);
-               local_irq_save(flags);
-               recurse_cnt--;
-               local_irq_restore(flags);
-                return 1;
-        }
-        return 0;
-}
-
 /*
  * ------------------------------------------------------------
  * rs_close()
@@ -4252,11 +3736,10 @@ rs_close(struct tty_struct *tty, struct file * filp)
 
        /* interrupts are disabled for this entire function */
 
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
 
        if (tty_hung_up_p(filp)) {
-               restore_flags(flags);
+               local_irq_restore(flags);
                return;
        }
 
@@ -4283,7 +3766,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
                info->count = 0;
        }
        if (info->count) {
-               restore_flags(flags);
+               local_irq_restore(flags);
                return;
        }
        info->flags |= ASYNC_CLOSING;
@@ -4337,7 +3820,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
        }
        info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
        wake_up_interruptible(&info->close_wait);
-       restore_flags(flags);
+       local_irq_restore(flags);
 
        /* port closed */
 
@@ -4359,6 +3842,28 @@ rs_close(struct tty_struct *tty, struct file * filp)
 #endif
        }
 #endif
+
+       /*
+        * Release any allocated DMA irq's.
+        */
+       if (info->dma_in_enabled) {
+               free_irq(info->dma_in_irq_nbr, info);
+               cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description);
+               info->uses_dma_in = 0;
+#ifdef SERIAL_DEBUG_OPEN
+               printk(KERN_DEBUG "DMA irq '%s' freed\n",
+                       info->dma_in_irq_description);
+#endif
+       }
+       if (info->dma_out_enabled) {
+               free_irq(info->dma_out_irq_nbr, info);
+               cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description);
+               info->uses_dma_out = 0;
+#ifdef SERIAL_DEBUG_OPEN
+               printk(KERN_DEBUG "DMA irq '%s' freed\n",
+                       info->dma_out_irq_description);
+#endif
+       }
 }
 
 /*
@@ -4433,8 +3938,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
         */
        if (tty_hung_up_p(filp) ||
            (info->flags & ASYNC_CLOSING)) {
-               if (info->flags & ASYNC_CLOSING)
-                       interruptible_sleep_on(&info->close_wait);
+               wait_event_interruptible(info->close_wait,
+                       !(info->flags & ASYNC_CLOSING));
 #ifdef SERIAL_DO_RESTART
                if (info->flags & ASYNC_HUP_NOTIFY)
                        return -EAGAIN;
@@ -4472,21 +3977,19 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
        printk("block_til_ready before block: ttyS%d, count = %d\n",
               info->line, info->count);
 #endif
-       save_flags(flags);
-       cli();
+       local_irq_save(flags);
        if (!tty_hung_up_p(filp)) {
                extra_count++;
                info->count--;
        }
-       restore_flags(flags);
+       local_irq_restore(flags);
        info->blocked_open++;
        while (1) {
-               save_flags(flags);
-               cli();
+               local_irq_save(flags);
                /* assert RTS and DTR */
                e100_rts(info, 1);
                e100_dtr(info, 1);
-               restore_flags(flags);
+               local_irq_restore(flags);
                set_current_state(TASK_INTERRUPTIBLE);
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
@@ -4528,6 +4031,19 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
        return 0;
 }
 
+static void
+deinit_port(struct e100_serial *info)
+{
+       if (info->dma_out_enabled) {
+               cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description);
+               free_irq(info->dma_out_irq_nbr, info);
+       }
+       if (info->dma_in_enabled) {
+               cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description);
+               free_irq(info->dma_in_irq_nbr, info);
+       }
+}
+
 /*
  * This routine is called whenever a serial port is opened.
  * It performs the serial-specific initialization for the tty structure.
@@ -4538,9 +4054,9 @@ rs_open(struct tty_struct *tty, struct file * filp)
        struct e100_serial      *info;
        int                     retval, line;
        unsigned long           page;
+       int                     allocated_resources = 0;
 
        /* find which port we want to open */
-
        line = tty->index;
 
        if (line < 0 || line >= NR_PORTS)
@@ -4580,8 +4096,8 @@ rs_open(struct tty_struct *tty, struct file * filp)
         */
        if (tty_hung_up_p(filp) ||
            (info->flags & ASYNC_CLOSING)) {
-               if (info->flags & ASYNC_CLOSING)
-                       interruptible_sleep_on(&info->close_wait);
+               wait_event_interruptible(info->close_wait,
+                       !(info->flags & ASYNC_CLOSING));
 #ifdef SERIAL_DO_RESTART
                return ((info->flags & ASYNC_HUP_NOTIFY) ?
                        -EAGAIN : -ERESTARTSYS);
@@ -4590,13 +4106,86 @@ rs_open(struct tty_struct *tty, struct file * filp)
 #endif
        }
 
+       /*
+        * If DMA is enabled try to allocate the irq's.
+        */
+       if (info->count == 1) {
+               allocated_resources = 1;
+               if (info->dma_in_enabled) {
+                       if (request_irq(info->dma_in_irq_nbr,
+                                       rec_interrupt,
+                                       info->dma_in_irq_flags,
+                                       info->dma_in_irq_description,
+                                       info)) {
+                               printk(KERN_WARNING "DMA irq '%s' busy; "
+                                       "falling back to non-DMA mode\n",
+                                       info->dma_in_irq_description);
+                               /* Make sure we never try to use DMA in */
+                               /* for the port again. */
+                               info->dma_in_enabled = 0;
+                       } else if (cris_request_dma(info->dma_in_nbr,
+                                       info->dma_in_irq_description,
+                                       DMA_VERBOSE_ON_ERROR,
+                                       info->dma_owner)) {
+                               free_irq(info->dma_in_irq_nbr, info);
+                               printk(KERN_WARNING "DMA '%s' busy; "
+                                       "falling back to non-DMA mode\n",
+                                       info->dma_in_irq_description);
+                               /* Make sure we never try to use DMA in */
+                               /* for the port again. */
+                               info->dma_in_enabled = 0;
+                       }
+#ifdef SERIAL_DEBUG_OPEN
+                       else
+                               printk(KERN_DEBUG "DMA irq '%s' allocated\n",
+                                       info->dma_in_irq_description);
+#endif
+               }
+               if (info->dma_out_enabled) {
+                       if (request_irq(info->dma_out_irq_nbr,
+                                              tr_interrupt,
+                                              info->dma_out_irq_flags,
+                                              info->dma_out_irq_description,
+                                              info)) {
+                               printk(KERN_WARNING "DMA irq '%s' busy; "
+                                       "falling back to non-DMA mode\n",
+                                       info->dma_out_irq_description);
+                               /* Make sure we never try to use DMA out */
+                               /* for the port again. */
+                               info->dma_out_enabled = 0;
+                       } else if (cris_request_dma(info->dma_out_nbr,
+                                            info->dma_out_irq_description,
+                                            DMA_VERBOSE_ON_ERROR,
+                                            info->dma_owner)) {
+                               free_irq(info->dma_out_irq_nbr, info);
+                               printk(KERN_WARNING "DMA '%s' busy; "
+                                       "falling back to non-DMA mode\n",
+                                       info->dma_out_irq_description);
+                               /* Make sure we never try to use DMA out */
+                               /* for the port again. */
+                               info->dma_out_enabled = 0;
+                       }
+#ifdef SERIAL_DEBUG_OPEN
+                       else
+                               printk(KERN_DEBUG "DMA irq '%s' allocated\n",
+                                       info->dma_out_irq_description);
+#endif
+               }
+       }
+
        /*
         * Start up the serial port
         */
 
        retval = startup(info);
-       if (retval)
+       if (retval) {
+               if (allocated_resources)
+                       deinit_port(info);
+
+               /* FIXME Decrease count info->count here too? */
                return retval;
+       }
+
 
        retval = block_til_ready(tty, filp, info);
        if (retval) {
@@ -4604,6 +4193,9 @@ rs_open(struct tty_struct *tty, struct file * filp)
                printk("rs_open returning after block_til_ready with %d\n",
                       retval);
 #endif
+               if (allocated_resources)
+                       deinit_port(info);
+
                return retval;
        }
 
@@ -4793,6 +4385,8 @@ static const struct tty_operations rs_ops = {
        .send_xchar = rs_send_xchar,
        .wait_until_sent = rs_wait_until_sent,
        .read_proc = rs_read_proc,
+       .tiocmget = rs_tiocmget,
+       .tiocmset = rs_tiocmset
 };
 
 static int __init
@@ -4810,9 +4404,27 @@ rs_init(void)
        /* Setup the timed flush handler system */
 
 #if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER)
-       init_timer(&flush_timer);
-       flush_timer.function = timed_flush_handler;
-       mod_timer(&flush_timer, jiffies + CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS);
+       setup_timer(&flush_timer, timed_flush_handler, 0);
+       mod_timer(&flush_timer, jiffies + 5);
+#endif
+
+#if defined(CONFIG_ETRAX_RS485)
+#if defined(CONFIG_ETRAX_RS485_ON_PA)
+       if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit,
+                       rs485_pa_bit)) {
+               printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
+                       "RS485 pin\n");
+               return -EBUSY;
+       }
+#endif
+#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
+       if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit,
+                       rs485_port_g_bit)) {
+               printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
+                       "RS485 pin\n");
+               return -EBUSY;
+       }
+#endif
 #endif
 
        /* Initialize the tty_driver structure */
@@ -4839,6 +4451,16 @@ rs_init(void)
        /* do some initializing for the separate ports */
 
        for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
+               if (info->enabled) {
+                       if (cris_request_io_interface(info->io_if,
+                                       info->io_if_description)) {
+                               printk(KERN_CRIT "ETRAX100LX async serial: "
+                                       "Could not allocate IO pins for "
+                                       "%s, port %d\n",
+                                       info->io_if_description, i);
+                               info->enabled = 0;
+                       }
+               }
                info->uses_dma_in = 0;
                info->uses_dma_out = 0;
                info->line = i;
@@ -4872,7 +4494,7 @@ rs_init(void)
                info->rs485.delay_rts_before_send = 0;
                info->rs485.enabled = 0;
 #endif
-               INIT_WORK(&info->work, do_softint, info);
+               INIT_WORK(&info->work, do_softint);
 
                if (info->enabled) {
                        printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
@@ -4890,64 +4512,17 @@ rs_init(void)
 #endif
 
 #ifndef CONFIG_SVINTO_SIM
+#ifndef CONFIG_ETRAX_KGDB
        /* Not needed in simulator.  May only complicate stuff. */
        /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
 
-       if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial ", NULL))
-               panic("irq8");
-
-#ifdef CONFIG_ETRAX_SERIAL_PORT0
-#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
-       if (request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_DISABLED, "serial 0 dma tr", NULL))
-               panic("irq22");
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
-       if (request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_DISABLED, "serial 0 dma rec", NULL))
-               panic("irq23");
-#endif
-#endif
-
-#ifdef CONFIG_ETRAX_SERIAL_PORT1
-#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
-       if (request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_DISABLED, "serial 1 dma tr", NULL))
-               panic("irq24");
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
-       if (request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_DISABLED, "serial 1 dma rec", NULL))
-               panic("irq25");
-#endif
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT2
-       /* DMA Shared with par0 (and SCSI0 and ATA) */
-#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
-       if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 2 dma tr", NULL))
-               panic("irq18");
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
-       if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 2 dma rec", NULL))
-               panic("irq19");
-#endif
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT3
-       /* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
-#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
-       if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 3 dma tr", NULL))
-               panic("irq20");
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
-       if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 3 dma rec", NULL))
-               panic("irq21");
-#endif
-#endif
+       if (request_irq(SERIAL_IRQ_NBR, ser_interrupt,
+                       IRQF_SHARED | IRQF_DISABLED, "serial ", driver))
+               panic("%s: Failed to request irq8", __FUNCTION__);
 
-#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
-       if (request_irq(TIMER1_IRQ_NBR, timeout_interrupt, IRQF_SHARED | IRQF_DISABLED,
-                      "fast serial dma timeout", NULL)) {
-               printk(KERN_CRIT "err: timer1 irq\n");
-       }
 #endif
 #endif /* CONFIG_SVINTO_SIM */
-       debug_write_function = rs_debug_write_function;
+
        return 0;
 }
 
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
new file mode 100644 (file)
index 0000000..ccd0f32
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * serial.h: Arch-dep definitions for the Etrax100 serial driver.
+ *
+ * Copyright (C) 1998-2007 Axis Communications AB
+ */
+
+#ifndef _ETRAX_SERIAL_H
+#define _ETRAX_SERIAL_H
+
+#include <linux/circ_buf.h>
+#include <asm/termios.h>
+#include <asm/dma.h>
+#include <asm/arch/io_interface_mux.h>
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+/*
+ * This is our internal structure for each serial port's state.
+ *
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+#define SERIAL_RECV_DESCRIPTORS 8
+
+struct etrax_recv_buffer {
+       struct etrax_recv_buffer *next;
+       unsigned short length;
+       unsigned char error;
+       unsigned char pad;
+
+       unsigned char buffer[0];
+};
+
+struct e100_serial {
+       int baud;
+       volatile u8     *port;  /* R_SERIALx_CTRL */
+       u32             irq;    /* bitnr in R_IRQ_MASK2 for dmaX_descr */
+
+       /* Output registers */
+       volatile u8 *oclrintradr;       /* adr to R_DMA_CHx_CLR_INTR */
+       volatile u32 *ofirstadr;        /* adr to R_DMA_CHx_FIRST */
+       volatile u8 *ocmdadr;           /* adr to R_DMA_CHx_CMD */
+       const volatile u8 *ostatusadr;  /* adr to R_DMA_CHx_STATUS */
+
+       /* Input registers */
+       volatile u8 *iclrintradr;       /* adr to R_DMA_CHx_CLR_INTR */
+       volatile u32 *ifirstadr;        /* adr to R_DMA_CHx_FIRST */
+       volatile u8 *icmdadr;           /* adr to R_DMA_CHx_CMD */
+       volatile u32 *idescradr;        /* adr to R_DMA_CHx_DESCR */
+
+       int flags;      /* defined in tty.h */
+
+       u8 rx_ctrl;     /* shadow for R_SERIALx_REC_CTRL */
+       u8 tx_ctrl;     /* shadow for R_SERIALx_TR_CTRL */
+       u8 iseteop;     /* bit number for R_SET_EOP for the input dma */
+       int enabled;    /* Set to 1 if the port is enabled in HW config */
+
+       u8 dma_out_enabled;     /* Set to 1 if DMA should be used */
+       u8 dma_in_enabled;      /* Set to 1 if DMA should be used */
+
+       /* end of fields defined in rs_table[] in .c-file */
+       int             dma_owner;
+       unsigned int    dma_in_nbr;
+       unsigned int    dma_out_nbr;
+       unsigned int    dma_in_irq_nbr;
+       unsigned int    dma_out_irq_nbr;
+       unsigned long   dma_in_irq_flags;
+       unsigned long   dma_out_irq_flags;
+       char            *dma_in_irq_description;
+       char            *dma_out_irq_description;
+
+       enum cris_io_interface io_if;
+       char            *io_if_description;
+
+       u8              uses_dma_in;  /* Set to 1 if DMA is used */
+       u8              uses_dma_out; /* Set to 1 if DMA is used */
+       u8              forced_eop;   /* a fifo eop has been forced */
+       int                     baud_base;     /* For special baudrates */
+       int                     custom_divisor; /* For special baudrates */
+       struct etrax_dma_descr  tr_descr;
+       struct etrax_dma_descr  rec_descr[SERIAL_RECV_DESCRIPTORS];
+       int                     cur_rec_descr;
+
+       volatile int            tr_running; /* 1 if output is running */
+
+       struct tty_struct       *tty;
+       int                     read_status_mask;
+       int                     ignore_status_mask;
+       int                     x_char; /* xon/xoff character */
+       int                     close_delay;
+       unsigned short          closing_wait;
+       unsigned short          closing_wait2;
+       unsigned long           event;
+       unsigned long           last_active;
+       int                     line;
+       int                     type;  /* PORT_ETRAX */
+       int                     count;      /* # of fd on device */
+       int                     blocked_open; /* # of blocked opens */
+       struct circ_buf         xmit;
+       struct etrax_recv_buffer *first_recv_buffer;
+       struct etrax_recv_buffer *last_recv_buffer;
+       unsigned int            recv_cnt;
+       unsigned int            max_recv_cnt;
+
+       struct work_struct      work;
+       struct async_icount     icount;   /* error-statistics etc.*/
+       struct ktermios         normal_termios;
+       struct ktermios         callout_termios;
+       wait_queue_head_t       open_wait;
+       wait_queue_head_t       close_wait;
+
+       unsigned long char_time_usec;       /* The time for 1 char, in usecs */
+       unsigned long flush_time_usec;      /* How often we should flush */
+       unsigned long last_tx_active_usec;  /* Last tx usec in the jiffies */
+       unsigned long last_tx_active;       /* Last tx time in jiffies */
+       unsigned long last_rx_active_usec;  /* Last rx usec in the jiffies */
+       unsigned long last_rx_active;       /* Last rx time in jiffies */
+
+       int break_detected_cnt;
+       int errorcode;
+
+#ifdef CONFIG_ETRAX_RS485
+       struct rs485_control    rs485;  /* RS-485 support */
+#endif
+};
+
+/* this PORT is not in the standard serial.h. it's not actually used for
+ * anything since we only have one type of async serial-port anyway in this
+ * system.
+ */
+
+#define PORT_ETRAX 1
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP  0
+
+#endif /* __KERNEL__ */
+
+#endif /* !_ETRAX_SERIAL_H */
index e89ae29645d61d554b5ff67b698a7ece50659129..d24621ce799ab30f3e3b5370db6bf70a5e305fbb 100644 (file)
@@ -77,7 +77,6 @@
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
 # define SCSPTR0 0xA4400000      /* 16 bit SCIF */
-# define SCI_NPORTS 2
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define PACR 0xa4050100
 # define PBCR 0xa4050102
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-# define SCSPTR1 0xffe00020 /* 16 bit SCIF */
-# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
-# define SCIF_ORER 0x0001   /* overrun error bit */
-# define SCSCR_INIT(port)          0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
-# define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
 # include <asm/hardware.h>
 # define SCIF_BASE_ADDR    0x01030000
 # define SCIF_LSR2_OFFS    0x0000024
 # define SCSPTR2           ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */
 # define SCLSR2            ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */
-# define SCSCR_INIT(port)  0x38                           /* TIE=0,RIE=0,
-                                                            TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port)  0x38                /* TIE=0,RIE=0, TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
@@ -577,15 +569,6 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
        return 1;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-       if (port->mapbase == 0xffe00000)
-               return ctrl_inw(SCSPTR1)&0x0001 ? 1 : 0; /* SCIF */
-       else
-               return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
-
-}
 #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
 static inline int sci_rxd_in(struct uart_port *port)
 {
index dfef83f14960d58de1c9ac7eb793f4aa105dcc72..a85f2d31a686c69f4f0a076358554bb54016325b 100644 (file)
@@ -329,12 +329,14 @@ static struct uart_ops ulite_ops = {
 static void ulite_console_wait_tx(struct uart_port *port)
 {
        int i;
+       u8 val;
 
-       /* wait up to 10ms for the character(s) to be sent */
-       for (i = 0; i < 10000; i++) {
-               if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
+       /* Spin waiting for TX fifo to have space available */
+       for (i = 0; i < 100000; i++) {
+               val = readb(port->membase + ULITE_STATUS);
+               if ((val & ULITE_STATUS_TXFULL) == 0)
                        break;
-               udelay(1);
+               cpu_relax();
        }
 }
 
index 7d873b3b0513c03fb8fcfaa3e52b622e4cc4760f..4d0282b821b519b3bd750cd5266ea9a02b78cd26 100644 (file)
@@ -107,16 +107,17 @@ int superhyway_add_devices(struct superhyway_bus *bus,
 static int __init superhyway_init(void)
 {
        struct superhyway_bus *bus;
-       int ret = 0;
+       int ret;
 
-       device_register(&superhyway_bus_device);
+       ret = device_register(&superhyway_bus_device);
+       if (unlikely(ret))
+               return ret;
 
        for (bus = superhyway_channels; bus->ops; bus++)
                ret |= superhyway_scan_bus(bus);
 
        return ret;
 }
-
 postcore_initcall(superhyway_init);
 
 static const struct superhyway_device_id *
index 89769ce16f882058934698ce566b804aa3a13e2d..b31f4431849b25e771d301f956b3afd31b00d2bf 100644 (file)
@@ -457,10 +457,11 @@ done:
 EXPORT_SYMBOL_GPL(spi_register_master);
 
 
-static int __unregister(struct device *dev, void *unused)
+static int __unregister(struct device *dev, void *master_dev)
 {
        /* note: before about 2.6.14-rc1 this would corrupt memory: */
-       spi_unregister_device(to_spi_device(dev));
+       if (dev != master_dev)
+               spi_unregister_device(to_spi_device(dev));
        return 0;
 }
 
@@ -478,7 +479,8 @@ void spi_unregister_master(struct spi_master *master)
 {
        int dummy;
 
-       dummy = device_for_each_child(master->dev.parent, NULL, __unregister);
+       dummy = device_for_each_child(master->dev.parent, &master->dev,
+                                       __unregister);
        device_unregister(&master->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_master);
index cc5094f37dd3d71a791df96efa58c374d8d68137..363ac8e6882106074478ae74b48cb8383440b770 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 #include <asm/gpio.h>
 
 
@@ -74,7 +75,6 @@ struct txx9spi {
        struct list_head queue;
        wait_queue_head_t waitq;
        void __iomem *membase;
-       int irq;
        int baseclk;
        struct clk *clk;
        u32 max_speed_hz, min_speed_hz;
@@ -350,12 +350,12 @@ static int __init txx9spi_probe(struct platform_device *dev)
        struct resource *res;
        int ret = -ENODEV;
        u32 mcr;
+       int irq;
 
        master = spi_alloc_master(&dev->dev, sizeof(*c));
        if (!master)
                return ret;
        c = spi_master_get_devdata(master);
-       c->irq = -1;
        platform_set_drvdata(dev, master);
 
        INIT_WORK(&c->work, txx9spi_work);
@@ -381,32 +381,36 @@ static int __init txx9spi_probe(struct platform_device *dev)
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res)
-               goto exit;
-       c->membase = ioremap(res->start, res->end - res->start + 1);
+               goto exit_busy;
+       if (!devm_request_mem_region(&dev->dev,
+                                    res->start, res->end - res->start + 1,
+                                    "spi_txx9"))
+               goto exit_busy;
+       c->membase = devm_ioremap(&dev->dev,
+                                 res->start, res->end - res->start + 1);
        if (!c->membase)
-               goto exit;
+               goto exit_busy;
 
        /* enter config mode */
        mcr = txx9spi_rd(c, TXx9_SPMCR);
        mcr &= ~(TXx9_SPMCR_OPMODE | TXx9_SPMCR_SPSTP | TXx9_SPMCR_BCLR);
        txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR, TXx9_SPMCR);
 
-       c->irq = platform_get_irq(dev, 0);
-       if (c->irq < 0)
-               goto exit;
-       ret = request_irq(c->irq, txx9spi_interrupt, 0, dev->name, c);
-       if (ret) {
-               c->irq = -1;
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0)
+               goto exit_busy;
+       ret = devm_request_irq(&dev->dev, irq, txx9spi_interrupt, 0,
+                              "spi_txx9", c);
+       if (ret)
                goto exit;
-       }
 
        c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
        if (!c->workqueue)
-               goto exit;
+               goto exit_busy;
        c->last_chipselect = -1;
 
        dev_info(&dev->dev, "at %#llx, irq %d, %dMHz\n",
-                (unsigned long long)res->start, c->irq,
+                (unsigned long long)res->start, irq,
                 (c->baseclk + 500000) / 1000000);
 
        master->bus_num = dev->id;
@@ -418,13 +422,11 @@ static int __init txx9spi_probe(struct platform_device *dev)
        if (ret)
                goto exit;
        return 0;
+exit_busy:
+       ret = -EBUSY;
 exit:
        if (c->workqueue)
                destroy_workqueue(c->workqueue);
-       if (c->irq >= 0)
-               free_irq(c->irq, c);
-       if (c->membase)
-               iounmap(c->membase);
        if (c->clk) {
                clk_disable(c->clk);
                clk_put(c->clk);
@@ -442,8 +444,6 @@ static int __exit txx9spi_remove(struct platform_device *dev)
        spi_unregister_master(master);
        platform_set_drvdata(dev, NULL);
        destroy_workqueue(c->workqueue);
-       free_irq(c->irq, c);
-       iounmap(c->membase);
        clk_disable(c->clk);
        clk_put(c->clk);
        spi_master_put(master);
index 6da58ca48b333b60cd4d6c1cf8a7a493b7908e9c..455991fbe28f0cb300ff354d0b5106d12cd7125a 100644 (file)
@@ -107,8 +107,11 @@ static ssize_t tle62x0_status_show(struct device *dev,
 
        mutex_lock(&st->lock);
        ret = tle62x0_read(st);
-
        dev_dbg(dev, "tle62x0_read() returned %d\n", ret);
+       if (ret < 0) {
+               mutex_unlock(&st->lock);
+               return ret;
+       }
 
        for (ptr = 0; ptr < (st->nr_gpio * 2)/8; ptr += 1) {
                fault <<= 8;
index c12a741b5574d21681d5ff5f2c89014675dff010..85a20546e82777c169cecafa1d65f7a52dd921f5 100644 (file)
@@ -440,6 +440,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
                        break;
                case SSB_BUSTYPE_PCMCIA:
 #ifdef CONFIG_SSB_PCMCIAHOST
+                       sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
                        dev->parent = &bus->host_pcmcia->dev;
 #endif
                        break;
@@ -1147,7 +1148,10 @@ static int __init ssb_modinit(void)
 
        return err;
 }
-subsys_initcall(ssb_modinit);
+/* ssb must be initialized after PCI but before the ssb drivers.
+ * That means we must use some initcall between subsys_initcall
+ * and device_initcall. */
+fs_initcall(ssb_modinit);
 
 static void __exit ssb_modexit(void)
 {
index b6abee846f023a81af3a4ecf3fb015ac642a5e53..bb44a76b3eb5508d605869936e34857afbfc2e18 100644 (file)
@@ -63,17 +63,17 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
                err = pcmcia_access_configuration_register(pdev, &reg);
                if (err != CS_SUCCESS)
                        goto error;
-               read_addr |= (reg.Value & 0xF) << 12;
+               read_addr |= ((u32)(reg.Value & 0x0F)) << 12;
                reg.Offset = 0x30;
                err = pcmcia_access_configuration_register(pdev, &reg);
                if (err != CS_SUCCESS)
                        goto error;
-               read_addr |= reg.Value << 16;
+               read_addr |= ((u32)reg.Value) << 16;
                reg.Offset = 0x32;
                err = pcmcia_access_configuration_register(pdev, &reg);
                if (err != CS_SUCCESS)
                        goto error;
-               read_addr |= reg.Value << 24;
+               read_addr |= ((u32)reg.Value) << 24;
 
                cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
                if (cur_core == coreidx)
@@ -152,28 +152,29 @@ error:
        goto out_unlock;
 }
 
-/* These are the main device register access functions.
- * do_select_core is inline to have the likely hotpath inline.
- * All unlikely codepaths are out-of-line. */
-static inline int do_select_core(struct ssb_bus *bus,
-                                struct ssb_device *dev,
-                                u16 *offset)
+static int select_core_and_segment(struct ssb_device *dev,
+                                  u16 *offset)
 {
+       struct ssb_bus *bus = dev->bus;
        int err;
-       u8 need_seg = (*offset >= 0x800) ? 1 : 0;
+       u8 need_segment;
+
+       if (*offset >= 0x800) {
+               *offset -= 0x800;
+               need_segment = 1;
+       } else
+               need_segment = 0;
 
        if (unlikely(dev != bus->mapped_device)) {
                err = ssb_pcmcia_switch_core(bus, dev);
                if (unlikely(err))
                        return err;
        }
-       if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
-               err = ssb_pcmcia_switch_segment(bus, need_seg);
+       if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
+               err = ssb_pcmcia_switch_segment(bus, need_segment);
                if (unlikely(err))
                        return err;
        }
-       if (need_seg == 1)
-               *offset -= 0x800;
 
        return 0;
 }
@@ -181,32 +182,31 @@ static inline int do_select_core(struct ssb_bus *bus,
 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
-       u16 x;
 
-       if (unlikely(do_select_core(bus, dev, &offset)))
+       if (unlikely(select_core_and_segment(dev, &offset)))
                return 0xFFFF;
-       x = readw(bus->mmio + offset);
 
-       return x;
+       return readw(bus->mmio + offset);
 }
 
 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
-       u32 x;
+       u32 lo, hi;
 
-       if (unlikely(do_select_core(bus, dev, &offset)))
+       if (unlikely(select_core_and_segment(dev, &offset)))
                return 0xFFFFFFFF;
-       x = readl(bus->mmio + offset);
+       lo = readw(bus->mmio + offset);
+       hi = readw(bus->mmio + offset + 2);
 
-       return x;
+       return (lo | (hi << 16));
 }
 
 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
 {
        struct ssb_bus *bus = dev->bus;
 
-       if (unlikely(do_select_core(bus, dev, &offset)))
+       if (unlikely(select_core_and_segment(dev, &offset)))
                return;
        writew(value, bus->mmio + offset);
 }
@@ -215,12 +215,12 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
 {
        struct ssb_bus *bus = dev->bus;
 
-       if (unlikely(do_select_core(bus, dev, &offset)))
+       if (unlikely(select_core_and_segment(dev, &offset)))
                return;
-       readw(bus->mmio + offset);
-       writew(value >> 16, bus->mmio + offset + 2);
-       readw(bus->mmio + offset);
-       writew(value, bus->mmio + offset);
+       writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3);
+       writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2);
+       writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1);
+       writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0);
 }
 
 /* Not "static", as it's used in main.c */
index 4d8c2a5b3297fdb2447f764ac8f5974277d936fd..bcea8d9b718ce782da7f1e3fdb20d4d278d9d00e 100644 (file)
@@ -120,9 +120,8 @@ int phone_register_device(struct phone_device *p, int unit)
 void phone_unregister_device(struct phone_device *pfd)
 {
        mutex_lock(&phone_lock);
-       if (phone_device[pfd->minor] != pfd)
-               panic("phone: bad unregister");
-       phone_device[pfd->minor] = NULL;
+       if (likely(phone_device[pfd->minor] == pfd))
+               phone_device[pfd->minor] = NULL;
        mutex_unlock(&phone_lock);
 }
 
index 6bfdba6a213fc48699612933dea3c70d49ffe2bf..1f7ab15df36dead8dc571ecfc7495560fcdf2259 100644 (file)
@@ -1215,20 +1215,18 @@ static int keyspan_chars_in_buffer (struct usb_serial_port *port)
 
 static int keyspan_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct keyspan_port_private     *p_priv;
-       struct keyspan_serial_private   *s_priv;
-       struct usb_serial               *serial = port->serial;
+       struct keyspan_port_private     *p_priv;
+       struct keyspan_serial_private   *s_priv;
+       struct usb_serial               *serial = port->serial;
        const struct keyspan_device_details     *d_details;
        int                             i, err;
-       int                             baud_rate, device_port;
        struct urb                      *urb;
-       unsigned int                    cflag;
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
        d_details = p_priv->device_details;
-       
-       dbg("%s - port%d.", __FUNCTION__, port->number); 
+
+       dbg("%s - port%d.", __FUNCTION__, port->number);
 
        /* Set some sane defaults */
        p_priv->rts_state = 1;
@@ -1249,7 +1247,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
                urb->dev = serial->dev;
 
                /* make sure endpoint data toggle is synchronized with the device */
-               
+
                usb_clear_halt(urb->dev, urb->pipe);
 
                if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
@@ -1265,30 +1263,6 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
                /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
        }
 
-       /* get the terminal config for the setup message now so we don't 
-        * need to send 2 of them */
-
-       cflag = port->tty->termios->c_cflag;
-       device_port = port->number - port->serial->minor;
-
-       /* Baud rate calculation takes baud rate as an integer
-          so other rates can be generated if desired. */
-       baud_rate = tty_get_baud_rate(port->tty);
-       /* If no match or invalid, leave as default */          
-       if (baud_rate >= 0
-           && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
-                               NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
-               p_priv->baud = baud_rate;
-       }
-
-       /* set CTS/RTS handshake etc. */
-       p_priv->cflag = cflag;
-       p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
-
-       keyspan_send_setup(port, 1);
-       //mdelay(100);
-       //keyspan_set_termios(port, NULL);
-
        return (0);
 }
 
index cc4b60f899ca7209eff8e352a5e3f4dbeda62f2e..7d86e9eae915a55a05757e8f2cc1cf2839140684 100644 (file)
@@ -503,7 +503,7 @@ config FB_VALKYRIE
 
 config FB_CT65550
        bool "Chips 65550 display support"
-       depends on (FB = y) && PPC32
+       depends on (FB = y) && PPC32 && PCI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index 5fb8675e0d6b9278a3c31b9ec732cd3c918578db..d0e4cb618269b7c44c5c920def6e3bbc49e807f6 100644 (file)
@@ -874,6 +874,8 @@ static int cyber2000fb_set_par(struct fb_info *info)
                default:
                        BUG();
                }
+               break;
+
        case 24:/* TRUECOLOUR, 16m */
                hw.co_pixfmt            = CO_PIXFMT_24BPP;
                hw.width                *= 3;
index b9b572b293d4ffd494782298fd4de7444edc1027..2e552d5bbb5d8bf4888fba36d4bc6bdace9f59f9 100644 (file)
@@ -183,8 +183,8 @@ static struct fb_videomode default_mode_LCD __initdata = {
        .vmode          = FB_VMODE_NONINTERLACED,
 };
 
-struct fb_videomode *default_mode = &default_mode_CRT;
-struct fb_var_screeninfo *default_var = &default_var_CRT;
+struct fb_videomode *default_mode __initdata = &default_mode_CRT;
+struct fb_var_screeninfo *default_var __initdata = &default_var_CRT;
 
 static int flat_panel_enabled = 0;
 
index 6c227f9592a5c4c6aeddfcb7af10dec334307bd6..ca13c48d19b068a58d2b5b9f24519df840725093 100644 (file)
@@ -33,7 +33,7 @@ void lx_set_palette_reg(struct fb_info *, unsigned int, unsigned int,
 
 #define MSR_LX_GLD_CONFIG    0x48002001
 #define MSR_LX_GLCP_DOTPLL   0x4c000015
-#define MSR_LX_DF_PADSEL     0x48000011
+#define MSR_LX_DF_PADSEL     0x48002011
 #define MSR_LX_DC_SPARE      0x80000011
 #define MSR_LX_DF_GLCONFIG   0x48002001
 
index b3463ddcfd608df0a7b2ada2990f1ee1d974f4b0..75836aa8319196345d5a24123af97e509a643543 100644 (file)
@@ -727,7 +727,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
 
 static int ps3fb_get_vblank(struct fb_vblank *vblank)
 {
-       memset(vblank, 0, sizeof(&vblank));
+       memset(vblank, 0, sizeof(*vblank));
        vblank->flags = FB_VBLANK_HAVE_VSYNC;
        return 0;
 }
index a5333c1907898ef71a301eecd75d8e3e56cbb5fd..b829dc7c5edfeb4d9621599aa05d1c0dd296dfa7 100644 (file)
@@ -540,7 +540,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
        int ret = 0;
        u8 revision;
 
-       dbg("probe called: device is %p\n", dev);
+       dbg("probe called: device is %p\n", pdev);
 
        printk(KERN_INFO "Epson S1D13XXX FB Driver\n");
 
@@ -753,8 +753,11 @@ static struct platform_driver s1d13xxxfb_driver = {
 static int __init
 s1d13xxxfb_init(void)
 {
+
+#ifndef MODULE
        if (fb_get_options("s1d13xxxfb", NULL))
                return -ENODEV;
+#endif
 
        return platform_driver_register(&s1d13xxxfb_driver);
 }
index bc7d23683735732134970abe4d1aaf58141102ad..37bd24b8d83b2568d516a16cd58e196e4e2e59f7 100644 (file)
@@ -1248,7 +1248,6 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
        if(found_mode) {
                ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
                                ivideo->sisfb_mode_idx, ivideo->currentvbflags);
-               ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
        } else {
                ivideo->sisfb_mode_idx = -1;
        }
@@ -1260,6 +1259,8 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
                return -EINVAL;
        }
 
+       ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
+
        if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {
                ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
                ivideo->refresh_rate = 60;
index b983d262ab7827f7520a3164092bfddf8195e6cc..d1d6c0facd549737ef290d6325a4f4c29b7901d4 100644 (file)
@@ -926,8 +926,10 @@ static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
                int start, struct fb_info *info)
 {
        struct uvesafb_ktask *task;
+#ifdef CONFIG_X86
        struct uvesafb_par *par = info->par;
        int i = par->mode_idx;
+#endif
        int err = 0;
 
        /*
@@ -1103,11 +1105,11 @@ static int uvesafb_pan_display(struct fb_var_screeninfo *var,
 
 static int uvesafb_blank(int blank, struct fb_info *info)
 {
-       struct uvesafb_par *par = info->par;
        struct uvesafb_ktask *task;
        int err = 1;
-
 #ifdef CONFIG_X86
+       struct uvesafb_par *par = info->par;
+
        if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
                int loop = 10000;
                u8 seq = 0, crtc17 = 0;
index 0e4baca21b8f46e02f716a07aab4605e6663f20d..1dc04b6684e6a3ce03451923d09164480932eebd 100644 (file)
@@ -53,7 +53,7 @@ struct vring_virtqueue
        unsigned int num_added;
 
        /* Last used index we've seen. */
-       unsigned int last_used_idx;
+       u16 last_used_idx;
 
        /* How to notify other side. FIXME: commonalize hcalls! */
        void (*notify)(struct virtqueue *vq);
@@ -277,11 +277,17 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
        struct vring_virtqueue *vq;
        unsigned int i;
 
+       /* We assume num is a power of 2. */
+       if (num & (num - 1)) {
+               dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+               return NULL;
+       }
+
        vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
        if (!vq)
                return NULL;
 
-       vring_init(&vq->vring, num, pages);
+       vring_init(&vq->vring, num, pages, PAGE_SIZE);
        vq->vq.callback = callback;
        vq->vq.vdev = vdev;
        vq->vq.vq_ops = &vring_vq_ops;
index 299e274d241ae298748151c9f63cf30fbdd91d9d..b63b5e044a4cc7aa641c26ea1de8906f7a4656c4 100644 (file)
@@ -233,7 +233,7 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
 {
        int count, err;
 
-       memset(st, 0, sizeof(st));
+       memset(st, 0, sizeof(*st));
 
        count = 0;
        err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);
index 756f7e9beb2e0a12cc1ad527992ca9fe6537c966..fbb12dadba8389a77f7cfece24fc452d86732640 100644 (file)
@@ -82,7 +82,7 @@ static match_table_t tokens = {
 
 static void v9fs_parse_options(struct v9fs_session_info *v9ses)
 {
-       char *options = v9ses->options;
+       char *options;
        substring_t args[MAX_OPT_ARGS];
        char *p;
        int option;
@@ -96,9 +96,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
        v9ses->cache = 0;
        v9ses->trans = v9fs_default_trans();
 
-       if (!options)
+       if (!v9ses->options)
                return;
 
+       options = kstrdup(v9ses->options, GFP_KERNEL);
        while ((p = strsep(&options, ",")) != NULL) {
                int token;
                if (!*p)
@@ -169,6 +170,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
                        continue;
                }
        }
+       kfree(options);
 }
 
 /**
index bb0cef9a6b8aced66b67d583d7a907c3742045b6..678c02f1ae231306b8f2062ef6925bb69a4a6b71 100644 (file)
@@ -119,6 +119,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
 
        P9_DPRINTK(P9_DEBUG_VFS, " \n");
 
+       st = NULL;
        v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
        if (!v9ses)
                return -ENOMEM;
@@ -164,10 +165,12 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
        root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
        v9fs_stat2inode(st, root->d_inode, sb);
        v9fs_fid_add(root, fid);
+       kfree(st);
 
        return simple_set_mnt(mnt, sb);
 
 error:
+       kfree(st);
        if (fid)
                p9_client_clunk(fid);
 
index c75c95406497f5173e449f3571fda8db8daef360..429a002285075c7556b30f1364a3d091a3052c57 100644 (file)
@@ -2007,7 +2007,7 @@ config CIFS_EXPERIMENTAL
 config CIFS_UPCALL
          bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
          depends on CIFS_EXPERIMENTAL
-         depends on CONNECTOR
+         depends on KEYS
          help
            Enables an upcall mechanism for CIFS which will be used to contact
            userspace helper utilities to provide SPNEGO packaged Kerberos
index 7b4bbe48112d547555433666ccccf5926ce79e2c..849fc3160cb5b372c2626545f926ce185c22762b 100644 (file)
@@ -382,7 +382,7 @@ struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,
               cell->name, key_serial(key),
               (int) namesz, (int) namesz, name, namesz);
 
-       if (namesz > sizeof(vl->vldb.name)) {
+       if (namesz >= sizeof(vl->vldb.name)) {
                _leave(" = -ENAMETOOLONG");
                return ERR_PTR(-ENAMETOOLONG);
        }
index 130f6c66c5ba09dab89de3b7865ac09a6c96ae25..ac7a8b1d6c3ab5f749305c4c38fec63289791b19 100644 (file)
@@ -14,8 +14,6 @@ struct bfs_sb_info {
        unsigned long si_blocks;
        unsigned long si_freeb;
        unsigned long si_freei;
-       unsigned long si_lf_ioff;
-       unsigned long si_lf_sblk;
        unsigned long si_lf_eblk;
        unsigned long si_lasti;
        unsigned long * si_imap;
@@ -39,7 +37,7 @@ static inline struct bfs_sb_info *BFS_SB(struct super_block *sb)
 
 static inline struct bfs_inode_info *BFS_I(struct inode *inode)
 {
-       return list_entry(inode, struct bfs_inode_info, vfs_inode);
+       return container_of(inode, struct bfs_inode_info, vfs_inode);
 }
 
 
index 097f1497f743a2063e66c9511d947e6917251996..1fd056d0fc3dc3029f36bb5a23b38ff71a320750 100644 (file)
 #define dprintf(x...)
 #endif
 
-static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino);
-static struct buffer_head * bfs_find_entry(struct inode * dir, 
-       const unsigned char * name, int namelen, struct bfs_dirent ** res_dir);
+static int bfs_add_entry(struct inode *dir, const unsigned char *name,
+                                               int namelen, int ino);
+static struct buffer_head *bfs_find_entry(struct inode *dir,
+                               const unsigned char *name, int namelen,
+                               struct bfs_dirent **res_dir);
 
-static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
+static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
 {
-       struct inode * dir = f->f_path.dentry->d_inode;
-       struct buffer_head * bh;
-       struct bfs_dirent * de;
+       struct inode *dir = f->f_path.dentry->d_inode;
+       struct buffer_head *bh;
+       struct bfs_dirent *de;
        unsigned int offset;
        int block;
 
        lock_kernel();
 
-       if (f->f_pos & (BFS_DIRENT_SIZE-1)) {
-               printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, 
-                       dir->i_sb->s_id, dir->i_ino);
+       if (f->f_pos & (BFS_DIRENT_SIZE - 1)) {
+               printf("Bad f_pos=%08lx for %s:%08lx\n",
+                                       (unsigned long)f->f_pos,
+                                       dir->i_sb->s_id, dir->i_ino);
                unlock_kernel();
                return -EBADF;
        }
 
        while (f->f_pos < dir->i_size) {
-               offset = f->f_pos & (BFS_BSIZE-1);
+               offset = f->f_pos & (BFS_BSIZE - 1);
                block = BFS_I(dir)->i_sblock + (f->f_pos >> BFS_BSIZE_BITS);
                bh = sb_bread(dir->i_sb, block);
                if (!bh) {
@@ -54,7 +57,9 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
                        de = (struct bfs_dirent *)(bh->b_data + offset);
                        if (de->ino) {
                                int size = strnlen(de->name, BFS_NAMELEN);
-                               if (filldir(dirent, de->name, size, f->f_pos, le16_to_cpu(de->ino), DT_UNKNOWN) < 0) {
+                               if (filldir(dirent, de->name, size, f->f_pos,
+                                               le16_to_cpu(de->ino),
+                                               DT_UNKNOWN) < 0) {
                                        brelse(bh);
                                        unlock_kernel();
                                        return 0;
@@ -62,7 +67,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
                        }
                        offset += BFS_DIRENT_SIZE;
                        f->f_pos += BFS_DIRENT_SIZE;
-               } while (offset < BFS_BSIZE && f->f_pos < dir->i_size);
+               } while ((offset < BFS_BSIZE) && (f->f_pos < dir->i_size));
                brelse(bh);
        }
 
@@ -78,13 +83,13 @@ const struct file_operations bfs_dir_operations = {
 
 extern void dump_imap(const char *, struct super_block *);
 
-static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
-               struct nameidata *nd)
+static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
+                                               struct nameidata *nd)
 {
        int err;
-       struct inode * inode;
-       struct super_block * s = dir->i_sb;
-       struct bfs_sb_info * info = BFS_SB(s);
+       struct inode *inode;
+       struct super_block *s = dir->i_sb;
+       struct bfs_sb_info *info = BFS_SB(s);
        unsigned long ino;
 
        inode = new_inode(s);
@@ -97,7 +102,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
                iput(inode);
                return -ENOSPC;
        }
-       set_bit(ino, info->si_imap);    
+       set_bit(ino, info->si_imap);
        info->si_freei--;
        inode->i_uid = current->fsuid;
        inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
@@ -113,9 +118,10 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
        BFS_I(inode)->i_eblock = 0;
        insert_inode_hash(inode);
         mark_inode_dirty(inode);
-       dump_imap("create",s);
+       dump_imap("create", s);
 
-       err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino);
+       err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len,
+                                                       inode->i_ino);
        if (err) {
                inode_dec_link_count(inode);
                iput(inode);
@@ -127,11 +133,12 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
        return 0;
 }
 
-static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
+                                               struct nameidata *nd)
 {
-       struct inode * inode = NULL;
-       struct buffer_head * bh;
-       struct bfs_dirent * de;
+       struct inode *inode = NULL;
+       struct buffer_head *bh;
+       struct bfs_dirent *de;
 
        if (dentry->d_name.len > BFS_NAMELEN)
                return ERR_PTR(-ENAMETOOLONG);
@@ -152,13 +159,15 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, st
        return NULL;
 }
 
-static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new)
+static int bfs_link(struct dentry *old, struct inode *dir,
+                                               struct dentry *new)
 {
-       struct inode * inode = old->d_inode;
+       struct inode *inode = old->d_inode;
        int err;
 
        lock_kernel();
-       err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, inode->i_ino);
+       err = bfs_add_entry(dir, new->d_name.name, new->d_name.len,
+                                                       inode->i_ino);
        if (err) {
                unlock_kernel();
                return err;
@@ -172,23 +181,23 @@ static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new
        return 0;
 }
 
-
-static int bfs_unlink(struct inode * dir, struct dentry * dentry)
+static int bfs_unlink(struct inode *dir, struct dentry *dentry)
 {
        int error = -ENOENT;
-       struct inode * inode;
-       struct buffer_head * bh;
-       struct bfs_dirent * de;
+       struct inode *inode;
+       struct buffer_head *bh;
+       struct bfs_dirent *de;
 
        inode = dentry->d_inode;
        lock_kernel();
        bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
-       if (!bh || le16_to_cpu(de->ino) != inode->i_ino)
+       if (!bh || (le16_to_cpu(de->ino) != inode->i_ino))
                goto out_brelse;
 
        if (!inode->i_nlink) {
-               printf("unlinking non-existent file %s:%lu (nlink=%d)\n", inode->i_sb->s_id, 
-                               inode->i_ino, inode->i_nlink);
+               printf("unlinking non-existent file %s:%lu (nlink=%d)\n",
+                                       inode->i_sb->s_id, inode->i_ino,
+                                       inode->i_nlink);
                inode->i_nlink = 1;
        }
        de->ino = 0;
@@ -205,12 +214,12 @@ out_brelse:
        return error;
 }
 
-static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, 
-                       struct inode * new_dir, struct dentry * new_dentry)
+static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+                       struct inode *new_dir, struct dentry *new_dentry)
 {
-       struct inode * old_inode, * new_inode;
-       struct buffer_head * old_bh, * new_bh;
-       struct bfs_dirent * old_de, * new_de;           
+       struct inode *old_inode, *new_inode;
+       struct buffer_head *old_bh, *new_bh;
+       struct bfs_dirent *old_de, *new_de;
        int error = -ENOENT;
 
        old_bh = new_bh = NULL;
@@ -223,7 +232,7 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
                                old_dentry->d_name.name, 
                                old_dentry->d_name.len, &old_de);
 
-       if (!old_bh || le16_to_cpu(old_de->ino) != old_inode->i_ino)
+       if (!old_bh || (le16_to_cpu(old_de->ino) != old_inode->i_ino))
                goto end_rename;
 
        error = -EPERM;
@@ -239,7 +248,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
        if (!new_bh) {
                error = bfs_add_entry(new_dir, 
                                        new_dentry->d_name.name,
-                                       new_dentry->d_name.len, old_inode->i_ino);
+                                       new_dentry->d_name.len,
+                                       old_inode->i_ino);
                if (error)
                        goto end_rename;
        }
@@ -268,11 +278,12 @@ const struct inode_operations bfs_dir_inops = {
        .rename                 = bfs_rename,
 };
 
-static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino)
+static int bfs_add_entry(struct inode *dir, const unsigned char *name,
+                                                       int namelen, int ino)
 {
-       struct buffer_head * bh;
-       struct bfs_dirent * de;
-       int block, sblock, eblock, off, eoff;
+       struct buffer_head *bh;
+       struct bfs_dirent *de;
+       int block, sblock, eblock, off, pos;
        int i;
 
        dprintf("name=%s, namelen=%d\n", name, namelen);
@@ -284,27 +295,24 @@ static int bfs_add_entry(struct inode * dir, const unsigned char * name, int nam
 
        sblock = BFS_I(dir)->i_sblock;
        eblock = BFS_I(dir)->i_eblock;
-       eoff = dir->i_size % BFS_BSIZE;
-       for (block=sblock; block<=eblock; block++) {
+       for (block = sblock; block <= eblock; block++) {
                bh = sb_bread(dir->i_sb, block);
-               if(!bh) 
+               if (!bh)
                        return -ENOSPC;
-               for (off=0; off<BFS_BSIZE; off+=BFS_DIRENT_SIZE) {
+               for (off = 0; off < BFS_BSIZE; off += BFS_DIRENT_SIZE) {
                        de = (struct bfs_dirent *)(bh->b_data + off);
-                       if (block==eblock && off>=eoff) {
-                               /* Do not read/interpret the garbage in the end of eblock. */
-                               de->ino = 0;
-                       }
                        if (!de->ino) {
-                               if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) {
+                               pos = (block - sblock) * BFS_BSIZE + off;
+                               if (pos >= dir->i_size) {
                                        dir->i_size += BFS_DIRENT_SIZE;
                                        dir->i_ctime = CURRENT_TIME_SEC;
                                }
                                dir->i_mtime = CURRENT_TIME_SEC;
                                mark_inode_dirty(dir);
                                de->ino = cpu_to_le16((u16)ino);
-                               for (i=0; i<BFS_NAMELEN; i++)
-                                       de->name[i] = (i < namelen) ? name[i] : 0;
+                               for (i = 0; i < BFS_NAMELEN; i++)
+                                       de->name[i] =
+                                               (i < namelen) ? name[i] : 0;
                                mark_buffer_dirty(bh);
                                brelse(bh);
                                return 0;
@@ -315,25 +323,26 @@ static int bfs_add_entry(struct inode * dir, const unsigned char * name, int nam
        return -ENOSPC;
 }
 
-static inline int bfs_namecmp(int len, const unsigned char * name, const char * buffer)
+static inline int bfs_namecmp(int len, const unsigned char *name,
+                                                       const char *buffer)
 {
-       if (len < BFS_NAMELEN && buffer[len])
+       if ((len < BFS_NAMELEN) && buffer[len])
                return 0;
        return !memcmp(name, buffer, len);
 }
 
-static struct buffer_head * bfs_find_entry(struct inode * dir, 
-       const unsigned char * name, int namelen, struct bfs_dirent ** res_dir)
+static struct buffer_head *bfs_find_entry(struct inode *dir,
+                       const unsigned char *name, int namelen,
+                       struct bfs_dirent **res_dir)
 {
-       unsigned long block, offset;
-       struct buffer_head * bh;
-       struct bfs_dirent * de;
+       unsigned long block = 0, offset = 0;
+       struct buffer_head *bh = NULL;
+       struct bfs_dirent *de;
 
        *res_dir = NULL;
        if (namelen > BFS_NAMELEN)
                return NULL;
-       bh = NULL;
-       block = offset = 0;
+
        while (block * BFS_BSIZE + offset < dir->i_size) {
                if (!bh) {
                        bh = sb_bread(dir->i_sb, BFS_I(dir)->i_sblock + block);
@@ -344,7 +353,8 @@ static struct buffer_head * bfs_find_entry(struct inode * dir,
                }
                de = (struct bfs_dirent *)(bh->b_data + offset);
                offset += BFS_DIRENT_SIZE;
-               if (le16_to_cpu(de->ino) && bfs_namecmp(namelen, name, de->name)) {
+               if (le16_to_cpu(de->ino) &&
+                               bfs_namecmp(namelen, name, de->name)) {
                        *res_dir = de;
                        return bh;
                }
index 911b4ccf470f4d4d0bd4bb77199f67a7f0cd3ca0..b11e63e8fbcd88389e4fb2e2a62b41465595dc04 100644 (file)
@@ -2,6 +2,11 @@
  *     fs/bfs/file.c
  *     BFS file operations.
  *     Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
+ *
+ *     Make the file block allocation algorithm understand the size
+ *     of the underlying block device.
+ *     Copyright (C) 2007 Dmitri Vorobiev <dmitri.vorobiev@gmail.com>
+ *
  */
 
 #include <linux/fs.h>
@@ -27,7 +32,8 @@ const struct file_operations bfs_file_operations = {
        .splice_read    = generic_file_splice_read,
 };
 
-static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb)
+static int bfs_move_block(unsigned long from, unsigned long to,
+                                       struct super_block *sb)
 {
        struct buffer_head *bh, *new;
 
@@ -43,21 +49,22 @@ static int bfs_move_block(unsigned long from, unsigned long to, struct super_blo
 }
 
 static int bfs_move_blocks(struct super_block *sb, unsigned long start,
-                           unsigned long end, unsigned long where)
+                               unsigned long end, unsigned long where)
 {
        unsigned long i;
 
        dprintf("%08lx-%08lx->%08lx\n", start, end, where);
        for (i = start; i <= end; i++)
                if(bfs_move_block(i, where + i, sb)) {
-                       dprintf("failed to move block %08lx -> %08lx\n", i, where + i);
+                       dprintf("failed to move block %08lx -> %08lx\n", i,
+                                                               where + i);
                        return -EIO;
                }
        return 0;
 }
 
-static int bfs_get_block(struct inode * inode, sector_t block, 
-       struct buffer_head * bh_result, int create)
+static int bfs_get_block(struct inode *inode, sector_t block,
+                       struct buffer_head *bh_result, int create)
 {
        unsigned long phys;
        int err;
@@ -66,9 +73,6 @@ static int bfs_get_block(struct inode * inode, sector_t block,
        struct bfs_inode_info *bi = BFS_I(inode);
        struct buffer_head *sbh = info->si_sbh;
 
-       if (block > info->si_blocks)
-               return -EIO;
-
        phys = bi->i_sblock + block;
        if (!create) {
                if (phys <= bi->i_eblock) {
@@ -79,21 +83,29 @@ static int bfs_get_block(struct inode * inode, sector_t block,
                return 0;
        }
 
-       /* if the file is not empty and the requested block is within the range
-          of blocks allocated for this file, we can grant it */
-       if (inode->i_size && phys <= bi->i_eblock) {
+       /*
+        * If the file is not empty and the requested block is within the
+        * range of blocks allocated for this file, we can grant it.
+        */
+       if (bi->i_sblock && (phys <= bi->i_eblock)) {
                dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n", 
                                create, (unsigned long)block, phys);
                map_bh(bh_result, sb, phys);
                return 0;
        }
 
-       /* the rest has to be protected against itself */
+       /* The file will be extended, so let's see if there is enough space. */
+       if (phys >= info->si_blocks)
+               return -ENOSPC;
+
+       /* The rest has to be protected against itself. */
        lock_kernel();
 
-       /* if the last data block for this file is the last allocated
-          block, we can extend the file trivially, without moving it
-          anywhere */
+       /*
+        * If the last data block for this file is the last allocated
+        * block, we can extend the file trivially, without moving it
+        * anywhere.
+        */
        if (bi->i_eblock == info->si_lf_eblk) {
                dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", 
                                create, (unsigned long)block, phys);
@@ -106,13 +118,19 @@ static int bfs_get_block(struct inode * inode, sector_t block,
                goto out;
        }
 
-       /* Ok, we have to move this entire file to the next free block */
+       /* Ok, we have to move this entire file to the next free block. */
        phys = info->si_lf_eblk + 1;
-       if (bi->i_sblock) { /* if data starts on block 0 then there is no data */
+       if (phys + block >= info->si_blocks) {
+               err = -ENOSPC;
+               goto out;
+       }
+
+       if (bi->i_sblock) {
                err = bfs_move_blocks(inode->i_sb, bi->i_sblock, 
-                               bi->i_eblock, phys);
+                                               bi->i_eblock, phys);
                if (err) {
-                       dprintf("failed to move ino=%08lx -> fs corruption\n", inode->i_ino);
+                       dprintf("failed to move ino=%08lx -> fs corruption\n",
+                                                               inode->i_ino);
                        goto out;
                }
        } else
@@ -124,8 +142,10 @@ static int bfs_get_block(struct inode * inode, sector_t block,
        phys += block;
        info->si_lf_eblk = bi->i_eblock = phys;
 
-       /* this assumes nothing can write the inode back while we are here
-        * and thus update inode->i_blocks! (XXX)*/
+       /*
+        * This assumes nothing can write the inode back while we are here
+        * and thus update inode->i_blocks! (XXX)
+        */
        info->si_freeb -= bi->i_eblock - bi->i_sblock + 1 - inode->i_blocks;
        mark_inode_dirty(inode);
        mark_buffer_dirty(sbh);
index 7bd9c2bbe6ee61e5d48485d80b9b0b3096512370..294c41baef6ed35cb65118867f965ebf522b36ec 100644 (file)
@@ -30,25 +30,26 @@ MODULE_LICENSE("GPL");
 #define dprintf(x...)
 #endif
 
-void dump_imap(const char *prefix, struct super_block * s);
+void dump_imap(const char *prefix, struct super_block *s);
 
-static void bfs_read_inode(struct inode * inode)
+static void bfs_read_inode(struct inode *inode)
 {
        unsigned long ino = inode->i_ino;
-       struct bfs_inode * di;
-       struct buffer_head * bh;
+       struct bfs_inode *di;
+       struct buffer_head *bh;
        int block, off;
 
-       if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
+       if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
                printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
                make_bad_inode(inode);
                return;
        }
 
-       block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+       block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
        bh = sb_bread(inode->i_sb, block);
        if (!bh) {
-               printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino);
+               printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id,
+                                                                       ino);
                make_bad_inode(inode);
                return;
        }
@@ -56,7 +57,7 @@ static void bfs_read_inode(struct inode * inode)
        off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
        di = (struct bfs_inode *)bh->b_data + off;
 
-       inode->i_mode = 0x0000FFFF &  le32_to_cpu(di->i_mode);
+       inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
        if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
                inode->i_mode |= S_IFDIR;
                inode->i_op = &bfs_dir_inops;
@@ -70,48 +71,48 @@ static void bfs_read_inode(struct inode * inode)
 
        BFS_I(inode)->i_sblock =  le32_to_cpu(di->i_sblock);
        BFS_I(inode)->i_eblock =  le32_to_cpu(di->i_eblock);
+       BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino);
        inode->i_uid =  le32_to_cpu(di->i_uid);
        inode->i_gid =  le32_to_cpu(di->i_gid);
        inode->i_nlink =  le32_to_cpu(di->i_nlink);
        inode->i_size = BFS_FILESIZE(di);
        inode->i_blocks = BFS_FILEBLOCKS(di);
-        if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks\n", inode->i_size, inode->i_blocks);
        inode->i_atime.tv_sec =  le32_to_cpu(di->i_atime);
        inode->i_mtime.tv_sec =  le32_to_cpu(di->i_mtime);
        inode->i_ctime.tv_sec =  le32_to_cpu(di->i_ctime);
        inode->i_atime.tv_nsec = 0;
        inode->i_mtime.tv_nsec = 0;
        inode->i_ctime.tv_nsec = 0;
-       BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */
 
        brelse(bh);
 }
 
-static int bfs_write_inode(struct inode * inode, int unused)
+static int bfs_write_inode(struct inode *inode, int unused)
 {
        unsigned int ino = (u16)inode->i_ino;
         unsigned long i_sblock;
-       struct bfs_inode * di;
-       struct buffer_head * bh;
+       struct bfs_inode *di;
+       struct buffer_head *bh;
        int block, off;
 
         dprintf("ino=%08x\n", ino);
 
-       if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
+       if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
                printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
                return -EIO;
        }
 
        lock_kernel();
-       block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+       block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
        bh = sb_bread(inode->i_sb, block);
        if (!bh) {
-               printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino);
+               printf("Unable to read inode %s:%08x\n",
+                               inode->i_sb->s_id, ino);
                unlock_kernel();
                return -EIO;
        }
 
-       off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
+       off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
        di = (struct bfs_inode *)bh->b_data + off;
 
        if (ino == BFS_ROOT_INO)
@@ -133,27 +134,26 @@ static int bfs_write_inode(struct inode * inode, int unused)
        di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
 
        mark_buffer_dirty(bh);
-        dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di->i_ino),block,off);
        brelse(bh);
        unlock_kernel();
        return 0;
 }
 
-static void bfs_delete_inode(struct inode * inode)
+static void bfs_delete_inode(struct inode *inode)
 {
        unsigned long ino = inode->i_ino;
-       struct bfs_inode * di;
-       struct buffer_head * bh;
+       struct bfs_inode *di;
+       struct buffer_head *bh;
        int block, off;
-       struct super_block * s = inode->i_sb;
-       struct bfs_sb_info * info = BFS_SB(s);
-       struct bfs_inode_info * bi = BFS_I(inode);
+       struct super_block *s = inode->i_sb;
+       struct bfs_sb_info *info = BFS_SB(s);
+       struct bfs_inode_info *bi = BFS_I(inode);
 
        dprintf("ino=%08lx\n", ino);
 
        truncate_inode_pages(&inode->i_data, 0);
 
-       if (ino < BFS_ROOT_INO || ino > info->si_lasti) {
+       if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) {
                printf("invalid ino=%08lx\n", ino);
                return;
        }
@@ -162,31 +162,35 @@ static void bfs_delete_inode(struct inode * inode)
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
        lock_kernel();
        mark_inode_dirty(inode);
-       block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+
+       block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
        bh = sb_bread(s, block);
        if (!bh) {
-               printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino);
+               printf("Unable to read inode %s:%08lx\n",
+                                       inode->i_sb->s_id, ino);
                unlock_kernel();
                return;
        }
-       off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
-       di = (struct bfs_inode *) bh->b_data + off;
+       off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
+       di = (struct bfs_inode *)bh->b_data + off;
+       memset((void *)di, 0, sizeof(struct bfs_inode));
+       mark_buffer_dirty(bh);
+       brelse(bh);
+
         if (bi->i_dsk_ino) {
-               info->si_freeb += 1 + bi->i_eblock - bi->i_sblock;
+               info->si_freeb += BFS_FILEBLOCKS(bi);
                info->si_freei++;
                clear_bit(ino, info->si_imap);
                dump_imap("delete_inode", s);
         }
-       di->i_ino = 0;
-       di->i_sblock = 0;
-       mark_buffer_dirty(bh);
-       brelse(bh);
 
-       /* if this was the last file, make the previous 
-          block "last files last block" even if there is no real file there,
-          saves us 1 gap */
-       if (info->si_lf_eblk == BFS_I(inode)->i_eblock) {
-               info->si_lf_eblk = BFS_I(inode)->i_sblock - 1;
+       /*
+        * If this was the last file, make the previous block
+        * "last block of the last file" even if there is no
+        * real file there, saves us 1 gap.
+        */
+       if (info->si_lf_eblk == bi->i_eblock) {
+               info->si_lf_eblk = bi->i_sblock - 1;
                mark_buffer_dirty(info->si_sbh);
        }
        unlock_kernel();
@@ -228,7 +232,7 @@ static void bfs_write_super(struct super_block *s)
        unlock_kernel();
 }
 
-static struct kmem_cache * bfs_inode_cachep;
+static struct kmem_cache *bfs_inode_cachep;
 
 static struct inode *bfs_alloc_inode(struct super_block *sb)
 {
@@ -279,7 +283,7 @@ static const struct super_operations bfs_sops = {
        .statfs         = bfs_statfs,
 };
 
-void dump_imap(const char *prefix, struct super_block * s)
+void dump_imap(const char *prefix, struct super_block *s)
 {
 #ifdef DEBUG
        int i;
@@ -287,25 +291,26 @@ void dump_imap(const char *prefix, struct super_block * s)
 
        if (!tmpbuf)
                return;
-       for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
-               if (i > PAGE_SIZE-100) break;
+       for (i = BFS_SB(s)->si_lasti; i >= 0; i--) {
+               if (i > PAGE_SIZE - 100) break;
                if (test_bit(i, BFS_SB(s)->si_imap))
                        strcat(tmpbuf, "1");
                else
                        strcat(tmpbuf, "0");
        }
-       printk(KERN_ERR "BFS-fs: %s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf);
+       printf("BFS-fs: %s: lasti=%08lx <%s>\n",
+                               prefix, BFS_SB(s)->si_lasti, tmpbuf);
        free_page((unsigned long)tmpbuf);
 #endif
 }
 
 static int bfs_fill_super(struct super_block *s, void *data, int silent)
 {
-       struct buffer_head * bh;
-       struct bfs_super_block * bfs_sb;
-       struct inode * inode;
+       struct buffer_head *bh;
+       struct bfs_super_block *bfs_sb;
+       struct inode *inode;
        unsigned i, imap_len;
-       struct bfs_sb_info * info;
+       struct bfs_sb_info *info;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
@@ -329,14 +334,14 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
 
        s->s_magic = BFS_MAGIC;
        info->si_sbh = bh;
-       info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode)
-                       + BFS_ROOT_INO - 1;
-
-       imap_len = info->si_lasti/8 + 1;
+       info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
+                                       sizeof(struct bfs_inode)
+                                       + BFS_ROOT_INO - 1;
+       imap_len = (info->si_lasti / 8) + 1;
        info->si_imap = kzalloc(imap_len, GFP_KERNEL);
        if (!info->si_imap)
                goto out;
-       for (i=0; i<BFS_ROOT_INO; i++) 
+       for (i = 0; i < BFS_ROOT_INO; i++)
                set_bit(i, info->si_imap);
 
        s->s_op = &bfs_sops;
@@ -352,16 +357,15 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
                goto out;
        }
 
-       info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
-       info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 -  le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS;
+       info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
+       info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1
+                       - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
        info->si_freei = 0;
        info->si_lf_eblk = 0;
-       info->si_lf_sblk = 0;
-       info->si_lf_ioff = 0;
        bh = NULL;
-       for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
+       for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) {
                struct bfs_inode *di;
-               int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
+               int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
                int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
                unsigned long sblock, eblock;
 
@@ -384,11 +388,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
 
                sblock =  le32_to_cpu(di->i_sblock);
                eblock =  le32_to_cpu(di->i_eblock);
-               if (eblock > info->si_lf_eblk) {
+               if (eblock > info->si_lf_eblk)
                        info->si_lf_eblk = eblock;
-                       info->si_lf_sblk = sblock;
-                       info->si_lf_ioff = BFS_INO2OFF(i);
-               }
        }
        brelse(bh);
        if (!(s->s_flags & MS_RDONLY)) {
index 3d419163c3d3a345f0a3bd06b230f0186038d60b..64dd22239b21b4a7181b6c719ae091b76fc7b30d 100644 (file)
@@ -1,3 +1,7 @@
+Version 1.52
+------------
+Fix oops on second mount to server when null auth is used.
+
 Version 1.51
 ------------
 Fix memory leak in statfs when mounted to very old servers (e.g.
@@ -12,7 +16,12 @@ leak that causes cifsd not to stop and rmmod to fail to cleanup
 cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
 bigendian architectures. Fix possible memory corruption when
 EAGAIN returned on kern_recvmsg. Return better error if server
-requires packet signing but client has disabled it.
+requires packet signing but client has disabled it. When mounted
+with cifsacl mount option - mode bits are approximated based
+on the contents of the ACL of the file or directory. When cifs
+mount helper is missing convert make sure that UNC name 
+has backslash (not forward slash) between ip address of server
+and the share name.
 
 Version 1.50
 ------------
index ff6ba8d823f03a91b3ffad88202c75708d1c9eba..45e42fb97c19e9df3750ac0adc8817b2f251a425 100644 (file)
@@ -3,4 +3,9 @@
 #
 obj-$(CONFIG_CIFS) += cifs.o
 
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o
+cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
+         link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
+         md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o \
+         readdir.o ioctl.o sess.o export.o cifsacl.o
+
+cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
index 2a01f3ef96a0503332da509b81e4c788f07113c2..bcda2c6b6a048db68697246a61040e41f6b35da6 100644 (file)
 
 #define SPNEGO_OID_LEN 7
 #define NTLMSSP_OID_LEN  10
+#define KRB5_OID_LEN  7
+#define MSKRB5_OID_LEN  7
 static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
 static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
+static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
+static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
 
 /*
  * ASN.1 context.
@@ -457,6 +461,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
        unsigned long *oid = NULL;
        unsigned int cls, con, tag, oidlen, rc;
        int use_ntlmssp = FALSE;
+       int use_kerberos = FALSE;
 
        *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
 
@@ -545,18 +550,28 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                                return 0;
                        }
                        if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
-                               rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
-                               if (rc) {
+                               if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
+
                                        cFYI(1,
                                          ("OID len = %d oid = 0x%lx 0x%lx "
                                           "0x%lx 0x%lx",
                                           oidlen, *oid, *(oid + 1),
                                           *(oid + 2), *(oid + 3)));
-                                       rc = compare_oid(oid, oidlen,
-                                                NTLMSSP_OID, NTLMSSP_OID_LEN);
-                                       kfree(oid);
-                                       if (rc)
+
+                                       if (compare_oid(oid, oidlen,
+                                                       MSKRB5_OID,
+                                                       MSKRB5_OID_LEN))
+                                               use_kerberos = TRUE;
+                                       else if (compare_oid(oid, oidlen,
+                                                            KRB5_OID,
+                                                            KRB5_OID_LEN))
+                                               use_kerberos = TRUE;
+                                       else if (compare_oid(oid, oidlen,
+                                                            NTLMSSP_OID,
+                                                            NTLMSSP_OID_LEN))
                                                use_ntlmssp = TRUE;
+
+                                       kfree(oid);
                                }
                        } else {
                                cFYI(1, ("Should be an oid what is going on?"));
@@ -609,12 +624,10 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                         ctx.pointer)); /* is this UTF-8 or ASCII? */
        }
 
-       /* if (use_kerberos)
-          *secType = Kerberos
-          else */
-       if (use_ntlmssp) {
+       if (use_kerberos)
+               *secType = Kerberos;
+       else if (use_ntlmssp)
                *secType = NTLMSSP;
-       }
 
        return 1;
 }
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
new file mode 100644 (file)
index 0000000..ad54a3a
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *   fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS
+ *
+ *   Copyright (c) 2007 Red Hat, Inc.
+ *   Author(s): Jeff Layton (jlayton@redhat.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/list.h>
+#include <linux/string.h>
+#include <keys/user-type.h>
+#include <linux/key-type.h>
+#include "cifsglob.h"
+#include "cifs_spnego.h"
+#include "cifs_debug.h"
+
+/* create a new cifs key */
+static int
+cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen)
+{
+       char *payload;
+       int ret;
+
+       ret = -ENOMEM;
+       payload = kmalloc(datalen, GFP_KERNEL);
+       if (!payload)
+               goto error;
+
+       /* attach the data */
+       memcpy(payload, data, datalen);
+       rcu_assign_pointer(key->payload.data, payload);
+       ret = 0;
+
+error:
+       return ret;
+}
+
+static void
+cifs_spnego_key_destroy(struct key *key)
+{
+       kfree(key->payload.data);
+}
+
+
+/*
+ * keytype for CIFS spnego keys
+ */
+struct key_type cifs_spnego_key_type = {
+       .name           = "cifs.spnego",
+       .instantiate    = cifs_spnego_key_instantiate,
+       .match          = user_match,
+       .destroy        = cifs_spnego_key_destroy,
+       .describe       = user_describe,
+};
+
+/* get a key struct with a SPNEGO security blob, suitable for session setup */
+struct key *
+cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname)
+{
+       struct TCP_Server_Info *server = sesInfo->server;
+       char *description, *dp;
+       size_t desc_len;
+       struct key *spnego_key;
+
+
+       /* version + ;ip{4|6}= + address + ;host=hostname +
+               ;sec= + ;uid= + NULL */
+       desc_len = 4 + 5 + 32 + 1 + 5 + strlen(hostname) +
+                  strlen(";sec=krb5") + 7 + sizeof(uid_t)*2 + 1;
+       spnego_key = ERR_PTR(-ENOMEM);
+       description = kzalloc(desc_len, GFP_KERNEL);
+       if (description == NULL)
+               goto out;
+
+       dp = description;
+       /* start with version and hostname portion of UNC string */
+       spnego_key = ERR_PTR(-EINVAL);
+       sprintf(dp, "0x%2.2x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION,
+               hostname);
+       dp = description + strlen(description);
+
+       /* add the server address */
+       if (server->addr.sockAddr.sin_family == AF_INET)
+               sprintf(dp, "ip4=" NIPQUAD_FMT,
+                       NIPQUAD(server->addr.sockAddr.sin_addr));
+       else if (server->addr.sockAddr.sin_family == AF_INET6)
+               sprintf(dp, "ip6=" NIP6_SEQFMT,
+                       NIP6(server->addr.sockAddr6.sin6_addr));
+       else
+               goto out;
+
+       dp = description + strlen(description);
+
+       /* for now, only sec=krb5 is valid */
+       if (server->secType == Kerberos)
+               sprintf(dp, ";sec=krb5");
+       else
+               goto out;
+
+       dp = description + strlen(description);
+       sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
+
+       cFYI(1, ("key description = %s", description));
+       spnego_key = request_key(&cifs_spnego_key_type, description, "");
+
+       if (cifsFYI && !IS_ERR(spnego_key)) {
+               struct cifs_spnego_msg *msg = spnego_key->payload.data;
+               cifs_dump_mem("SPNEGO reply blob:", msg->data,
+                               msg->secblob_len + msg->sesskey_len);
+       }
+
+out:
+       kfree(description);
+       return spnego_key;
+}
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h
new file mode 100644 (file)
index 0000000..f443f3b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *   fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS
+ *
+ *   Copyright (c) 2007 Red Hat, Inc.
+ *   Author(s): Jeff Layton (jlayton@redhat.com)
+ *              Steve French (sfrench@us.ibm.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CIFS_SPNEGO_H
+#define _CIFS_SPNEGO_H
+
+#define CIFS_SPNEGO_UPCALL_VERSION 1
+
+/*
+ * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
+ * The flags field is for future use. The request-key callout should set
+ * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob
+ * and stuff it in the data field.
+ */
+struct cifs_spnego_msg {
+       uint32_t        version;
+       uint32_t        flags;
+       uint32_t        sesskey_len;
+       uint32_t        secblob_len;
+       uint8_t         data[1];
+};
+
+#ifdef __KERNEL__
+extern struct key_type cifs_spnego_key_type;
+#endif /* KERNEL */
+
+#endif /* _CIFS_SPNEGO_H */
index e8e56353f5a1c423b5e6e70f986bbb8b6a3f7a19..dabbce00712b0f23e02e5bfe46e5696850791e1f 100644 (file)
@@ -38,13 +38,13 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
        {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
        {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
        {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
-       {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"}
-};
+       {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} }
+;
 
 
 /* security id for everyone */
-static const struct cifs_sid sid_everyone =
-               {1, 1, {0, 0, 0, 0, 0, 0}, {} };
+static const struct cifs_sid sid_everyone = {
+       1, 1, {0, 0, 0, 0, 0, 1}, {0} };
 /* group users */
 static const struct cifs_sid sid_user =
                {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
@@ -97,7 +97,7 @@ int match_sid(struct cifs_sid *ctsid)
 
 /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
    the same returns 1, if they do not match returns 0 */
-int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
+int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
 {
        int i;
        int num_subauth, num_sat, num_saw;
@@ -129,66 +129,142 @@ int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
        return (1); /* sids compare/match */
 }
 
+/*
+   change posix mode to reflect permissions
+   pmode is the existing mode (we only want to overwrite part of this
+   bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
+*/
+static void access_flags_to_mode(__u32 ace_flags, int type, umode_t *pmode,
+                                umode_t *pbits_to_set)
+{
+       /* the order of ACEs is important.  The canonical order is to begin with
+          DENY entries followed by ALLOW, otherwise an allow entry could be
+          encountered first, making the subsequent deny entry like "dead code"
+          which would be superflous since Windows stops when a match is made
+          for the operation you are trying to perform for your user */
+
+       /* For deny ACEs we change the mask so that subsequent allow access
+          control entries do not turn on the bits we are denying */
+       if (type == ACCESS_DENIED) {
+               if (ace_flags & GENERIC_ALL) {
+                       *pbits_to_set &= ~S_IRWXUGO;
+               }
+               if ((ace_flags & GENERIC_WRITE) ||
+                       ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+                       *pbits_to_set &= ~S_IWUGO;
+               if ((ace_flags & GENERIC_READ) ||
+                       ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+                       *pbits_to_set &= ~S_IRUGO;
+               if ((ace_flags & GENERIC_EXECUTE) ||
+                       ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+                       *pbits_to_set &= ~S_IXUGO;
+               return;
+       } else if (type != ACCESS_ALLOWED) {
+               cERROR(1, ("unknown access control type %d", type));
+               return;
+       }
+       /* else ACCESS_ALLOWED type */
+
+       if (ace_flags & GENERIC_ALL) {
+               *pmode |= (S_IRWXUGO & (*pbits_to_set));
+#ifdef CONFIG_CIFS_DEBUG2
+               cFYI(1, ("all perms"));
+#endif
+               return;
+       }
+       if ((ace_flags & GENERIC_WRITE) ||
+                       ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+               *pmode |= (S_IWUGO & (*pbits_to_set));
+       if ((ace_flags & GENERIC_READ) ||
+                       ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+               *pmode |= (S_IRUGO & (*pbits_to_set));
+       if ((ace_flags & GENERIC_EXECUTE) ||
+                       ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+               *pmode |= (S_IXUGO & (*pbits_to_set));
+
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode));
+#endif
+       return;
+}
+
+/*
+   Generate access flags to reflect permissions mode is the existing mode.
+   This function is called for every ACE in the DACL whose SID matches
+   with either owner or group or everyone.
+*/
+
+static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
+                               __u32 *pace_flags)
+{
+       /* reset access mask */
+       *pace_flags = 0x0;
+
+       /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
+       mode &= bits_to_use;
+
+       /* check for R/W/X UGO since we do not know whose flags
+          is this but we have cleared all the bits sans RWX for
+          either user or group or other as per bits_to_use */
+       if (mode & S_IRUGO)
+               *pace_flags |= SET_FILE_READ_RIGHTS;
+       if (mode & S_IWUGO)
+               *pace_flags |= SET_FILE_WRITE_RIGHTS;
+       if (mode & S_IXUGO)
+               *pace_flags |= SET_FILE_EXEC_RIGHTS;
+
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
+#endif
+       return;
+}
+
 
-static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+#ifdef CONFIG_CIFS_DEBUG2
+static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
 {
        int num_subauth;
 
        /* validate that we do not go past end of acl */
 
-       /* XXX this if statement can be removed
-       if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
+       if (le16_to_cpu(pace->size) < 16) {
+               cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
+               return;
+       }
+
+       if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
                cERROR(1, ("ACL too small to parse ACE"));
                return;
-       } */
+       }
 
-       num_subauth = pace->num_subauth;
+       num_subauth = pace->sid.num_subauth;
        if (num_subauth) {
-#ifdef CONFIG_CIFS_DEBUG2
                int i;
-               cFYI(1, ("ACE revision %d num_subauth %d",
-                       pace->revision, pace->num_subauth));
+               cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
+                       pace->sid.revision, pace->sid.num_subauth, pace->type,
+                       pace->flags, pace->size));
                for (i = 0; i < num_subauth; ++i) {
                        cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
-                               le32_to_cpu(pace->sub_auth[i])));
+                               le32_to_cpu(pace->sid.sub_auth[i])));
                }
 
                /* BB add length check to make sure that we do not have huge
                        num auths and therefore go off the end */
-
-               cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
-#endif
        }
 
        return;
 }
-
-static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
-{
-       /* validate that we do not go past end of acl */
-       if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
-               cERROR(1, ("ACL too small to parse NT ACE"));
-               return;
-       }
-
-#ifdef CONFIG_CIFS_DEBUG2
-       cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
-               pntace->type, pntace->flags, pntace->size,
-               pntace->access_req));
 #endif
-       return;
-}
-
 
 
 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
-                      struct cifs_sid *pownersid, struct cifs_sid *pgrpsid)
+                      struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
+                      struct inode *inode)
 {
        int i;
        int num_aces = 0;
        int acl_size;
        char *acl_base;
-       struct cifs_ntace **ppntace;
        struct cifs_ace **ppace;
 
        /* BB need to add parm so we can store the SID BB */
@@ -205,50 +281,63 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
                le32_to_cpu(pdacl->num_aces)));
 #endif
 
+       /* reset rwx permissions for user/group/other.
+          Also, if num_aces is 0 i.e. DACL has no ACEs,
+          user/group/other have no permissions */
+       inode->i_mode &= ~(S_IRWXUGO);
+
+       if (!pdacl) {
+               /* no DACL in the security descriptor, set
+                  all the permissions for user/group/other */
+               inode->i_mode |= S_IRWXUGO;
+               return;
+       }
        acl_base = (char *)pdacl;
        acl_size = sizeof(struct cifs_acl);
 
        num_aces = le32_to_cpu(pdacl->num_aces);
        if (num_aces  > 0) {
-               ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
-                               GFP_KERNEL);
+               umode_t user_mask = S_IRWXU;
+               umode_t group_mask = S_IRWXG;
+               umode_t other_mask = S_IRWXO;
+
                ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
                                GFP_KERNEL);
 
 /*             cifscred->cecount = pdacl->num_aces;
-               cifscred->ntaces = kmalloc(num_aces *
-                       sizeof(struct cifs_ntace *), GFP_KERNEL);
                cifscred->aces = kmalloc(num_aces *
                        sizeof(struct cifs_ace *), GFP_KERNEL);*/
 
                for (i = 0; i < num_aces; ++i) {
-                       ppntace[i] = (struct cifs_ntace *)
-                                       (acl_base + acl_size);
-                       ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
-                                       sizeof(struct cifs_ntace));
-
-                       parse_ntace(ppntace[i], end_of_acl);
-                       if (end_of_acl < ((char *)ppace[i] +
-                                       (le16_to_cpu(ppntace[i]->size) -
-                                       sizeof(struct cifs_ntace)))) {
-                               cERROR(1, ("ACL too small to parse ACE"));
-                               break;
-                       } else
-                               parse_ace(ppace[i], end_of_acl);
-
-/*                     memcpy((void *)(&(cifscred->ntaces[i])),
-                               (void *)ppntace[i],
-                               sizeof(struct cifs_ntace));
-                       memcpy((void *)(&(cifscred->aces[i])),
+                       ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
+#ifdef CONFIG_CIFS_DEBUG2
+                       dump_ace(ppace[i], end_of_acl);
+#endif
+                       if (compare_sids(&(ppace[i]->sid), pownersid))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                                    ppace[i]->type,
+                                                    &(inode->i_mode),
+                                                    &user_mask);
+                       if (compare_sids(&(ppace[i]->sid), pgrpsid))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                                    ppace[i]->type,
+                                                    &(inode->i_mode),
+                                                    &group_mask);
+                       if (compare_sids(&(ppace[i]->sid), &sid_everyone))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                                    ppace[i]->type,
+                                                    &(inode->i_mode),
+                                                    &other_mask);
+
+/*                     memcpy((void *)(&(cifscred->aces[i])),
                                (void *)ppace[i],
                                sizeof(struct cifs_ace)); */
 
-                       acl_base = (char *)ppntace[i];
-                       acl_size = le16_to_cpu(ppntace[i]->size);
+                       acl_base = (char *)ppace[i];
+                       acl_size = le16_to_cpu(ppace[i]->size);
                }
 
                kfree(ppace);
-               kfree(ppntace);
        }
 
        return;
@@ -257,20 +346,20 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 
 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
 {
-
        /* BB need to add parm so we can store the SID BB */
 
-       /* validate that we do not go past end of acl */
-       if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
-               cERROR(1, ("ACL too small to parse SID"));
+       /* validate that we do not go past end of ACL - sid must be at least 8
+          bytes long (assuming no sub-auths - e.g. the null SID */
+       if (end_of_acl < (char *)psid + 8) {
+               cERROR(1, ("ACL too small to parse SID %p", psid));
                return -EINVAL;
        }
 
        if (psid->num_subauth) {
 #ifdef CONFIG_CIFS_DEBUG2
                int i;
-               cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
-                       psid->revision, psid->num_subauth, psid->sub_auth[0]));
+               cFYI(1, ("SID revision %d num_auth %d",
+                       psid->revision, psid->num_subauth));
 
                for (i = 0; i < psid->num_subauth; i++) {
                        cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
@@ -289,27 +378,32 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
 
 
 /* Convert CIFS ACL to POSIX form */
-int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
+static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
+                         struct inode *inode)
 {
        int rc;
        struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
        struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
        char *end_of_acl = ((char *)pntsd) + acl_len;
+       __u32 dacloffset;
+
+       if ((inode == NULL) || (pntsd == NULL))
+               return -EIO;
 
        owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
                                le32_to_cpu(pntsd->osidoffset));
        group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
                                le32_to_cpu(pntsd->gsidoffset));
-       dacl_ptr = (struct cifs_acl *)((char *)pntsd +
-                               le32_to_cpu(pntsd->dacloffset));
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+       dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
 #ifdef CONFIG_CIFS_DEBUG2
        cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
                 "sacloffset 0x%x dacloffset 0x%x",
                 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
                 le32_to_cpu(pntsd->gsidoffset),
-                le32_to_cpu(pntsd->sacloffset),
-                le32_to_cpu(pntsd->dacloffset)));
+                le32_to_cpu(pntsd->sacloffset), dacloffset));
 #endif
+/*     cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
        rc = parse_sid(owner_sid_ptr, end_of_acl);
        if (rc)
                return rc;
@@ -318,16 +412,120 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
        if (rc)
                return rc;
 
-       parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr);
+       if (dacloffset)
+               parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
+                          group_sid_ptr, inode);
+       else
+               cFYI(1, ("no ACL")); /* BB grant all or default perms? */
 
 /*     cifscred->uid = owner_sid_ptr->rid;
        cifscred->gid = group_sid_ptr->rid;
        memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
-                       sizeof (struct cifs_sid));
+                       sizeof(struct cifs_sid));
        memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
-                       sizeof (struct cifs_sid)); */
+                       sizeof(struct cifs_sid)); */
 
 
        return (0);
 }
+
+
+/* Retrieve an ACL from the server */
+static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
+                                      const char *path)
+{
+       struct cifsFileInfo *open_file;
+       int unlock_file = FALSE;
+       int xid;
+       int rc = -EIO;
+       __u16 fid;
+       struct super_block *sb;
+       struct cifs_sb_info *cifs_sb;
+       struct cifs_ntsd *pntsd = NULL;
+
+       cFYI(1, ("get mode from ACL for %s", path));
+
+       if (inode == NULL)
+               return NULL;
+
+       xid = GetXid();
+       open_file = find_readable_file(CIFS_I(inode));
+       sb = inode->i_sb;
+       if (sb == NULL) {
+               FreeXid(xid);
+               return NULL;
+       }
+       cifs_sb = CIFS_SB(sb);
+
+       if (open_file) {
+               unlock_file = TRUE;
+               fid = open_file->netfid;
+       } else {
+               int oplock = FALSE;
+               /* open file */
+               rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
+                               READ_CONTROL, 0, &fid, &oplock, NULL,
+                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+               if (rc != 0) {
+                       cERROR(1, ("Unable to open file to get ACL"));
+                       FreeXid(xid);
+                       return NULL;
+               }
+       }
+
+       rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
+       cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+       if (unlock_file == TRUE)
+               atomic_dec(&open_file->wrtPending);
+       else
+               CIFSSMBClose(xid, cifs_sb->tcon, fid);
+
+       FreeXid(xid);
+       return pntsd;
+}
+
+/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
+void acl_to_uid_mode(struct inode *inode, const char *path)
+{
+       struct cifs_ntsd *pntsd = NULL;
+       u32 acllen = 0;
+       int rc = 0;
+
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("converting ACL to mode for %s", path));
+#endif
+       pntsd = get_cifs_acl(&acllen, inode, path);
+
+       /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
+       if (pntsd)
+               rc = parse_sec_desc(pntsd, acllen, inode);
+       if (rc)
+               cFYI(1, ("parse sec desc failed rc = %d", rc));
+
+       kfree(pntsd);
+       return;
+}
+
+/* Convert mode bits to an ACL so we can update the ACL on the server */
+int mode_to_acl(struct inode *inode, const char *path)
+{
+       int rc = 0;
+       __u32 acllen = 0;
+       struct cifs_ntsd *pntsd = NULL;
+
+       cFYI(1, ("set ACL from mode for %s", path));
+
+       /* Get the security descriptor */
+       pntsd = get_cifs_acl(&acllen, inode, path);
+
+       /* Add/Modify the three ACEs for owner, group, everyone
+          while retaining the other ACEs */
+
+       /* Set the security descriptor */
+
+
+       kfree(pntsd);
+       return rc;
+}
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
index 420f87813647b9b9307ce484b3813f59180247a4..93a7c3462ea27c7c3080bbc963f545ba51fe1286 100644 (file)
@@ -35,6 +35,9 @@
 #define UBITSHIFT      6
 #define GBITSHIFT      3
 
+#define ACCESS_ALLOWED 0
+#define ACCESS_DENIED  1
+
 struct cifs_ntsd {
        __le16 revision; /* revision level */
        __le16 type;
@@ -48,7 +51,7 @@ struct cifs_sid {
        __u8 revision; /* revision level */
        __u8 num_subauth;
        __u8 authority[6];
-       __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */
+       __le32 sub_auth[5]; /* sub_auth[num_subauth] */
 } __attribute__((packed));
 
 struct cifs_acl {
@@ -57,18 +60,12 @@ struct cifs_acl {
        __le32 num_aces;
 } __attribute__((packed));
 
-struct cifs_ntace { /* first part of ACE which contains perms */
+struct cifs_ace {
        __u8 type;
        __u8 flags;
        __le16 size;
        __le32 access_req;
-} __attribute__((packed));
-
-struct cifs_ace { /* last part of ACE which includes user info */
-       __u8 revision; /* revision level */
-       __u8 num_subauth;
-       __u8 authority[6];
-       __le32 sub_auth[5];
+       struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
 } __attribute__((packed));
 
 struct cifs_wksid {
@@ -79,7 +76,7 @@ struct cifs_wksid {
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 
 extern int match_sid(struct cifs_sid *);
-extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
+extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
 
 #endif /*  CONFIG_CIFS_EXPERIMENTAL */
 
index 632070b4275d91ba46baa1d735b578aeca555462..4ff8939c6cc7b51543170ab8c28d4a54d450f483 100644 (file)
@@ -99,15 +99,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
        MD5Init(&context);
        MD5Update(&context, (char *)&key->data, key->len);
        for (i = 0; i < n_vec; i++) {
+               if (iov[i].iov_len == 0)
+                       continue;
                if (iov[i].iov_base == NULL) {
                        cERROR(1, ("null iovec entry"));
                        return -EIO;
-               } else if (iov[i].iov_len == 0)
-                       break; /* bail out if we are sent nothing to sign */
+               }
                /* The first entry includes a length field (which does not get
                   signed that occupies the first 4 bytes before the header */
                if (i == 0) {
-                       if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
+                       if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
                                break; /* nothing to sign or corrupt header */
                        MD5Update(&context, iov[0].iov_base+4,
                                  iov[0].iov_len-4);
@@ -122,7 +123,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
 
 
 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
-                  __u32 * pexpected_response_sequence_number)
+                  __u32 *pexpected_response_sequence_number)
 {
        int rc = 0;
        char smb_signature[20];
index a6fbea57c4b1e6d895375ed10e8ef636995d763e..416dc9fe8961ac4e2e0c4eaebbaec7d1e186a739 100644 (file)
@@ -43,6 +43,8 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 #include <linux/mm.h>
+#include <linux/key-type.h>
+#include "cifs_spnego.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDUs */
 
 #ifdef CONFIG_CIFS_QUOTA
@@ -1005,12 +1007,16 @@ init_cifs(void)
        rc = register_filesystem(&cifs_fs_type);
        if (rc)
                goto out_destroy_request_bufs;
-
+#ifdef CONFIG_CIFS_UPCALL
+       rc = register_key_type(&cifs_spnego_key_type);
+       if (rc)
+               goto out_unregister_filesystem;
+#endif
        oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
        if (IS_ERR(oplockThread)) {
                rc = PTR_ERR(oplockThread);
                cERROR(1, ("error %d create oplock thread", rc));
-               goto out_unregister_filesystem;
+               goto out_unregister_key_type;
        }
 
        dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
@@ -1024,7 +1030,11 @@ init_cifs(void)
 
  out_stop_oplock_thread:
        kthread_stop(oplockThread);
+ out_unregister_key_type:
+#ifdef CONFIG_CIFS_UPCALL
+       unregister_key_type(&cifs_spnego_key_type);
  out_unregister_filesystem:
+#endif
        unregister_filesystem(&cifs_fs_type);
  out_destroy_request_bufs:
        cifs_destroy_request_bufs();
@@ -1045,6 +1055,9 @@ exit_cifs(void)
        cFYI(0, ("exit_cifs"));
 #ifdef CONFIG_PROC_FS
        cifs_proc_clean();
+#endif
+#ifdef CONFIG_CIFS_UPCALL
+       unregister_key_type(&cifs_spnego_key_type);
 #endif
        unregister_filesystem(&cifs_fs_type);
        cifs_destroy_inodecache();
index 5574ba3ab1f9c3c669b5f3e606bff729bcc2ebd6..2a21dc66f0de20be9544887d6312aa9b3394bac1 100644 (file)
@@ -106,5 +106,5 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep,
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.51"
+#define CIFS_VERSION   "1.52"
 #endif                         /* _CIFSFS_H */
index c41ff74e9128b91af914930334b241fd3c0d313f..dbe6b846f37f0f476d83d59804aefde6e4d75881 100644 (file)
                                | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
 #define FILE_EXEC_RIGHTS (FILE_EXECUTE)
 
+#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
+                               | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+                               | FILE_READ_EA | FILE_WRITE_EA \
+                               | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
+                               | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+
 
 /*
  * Invalid readdir handle
@@ -1211,6 +1228,29 @@ typedef struct smb_com_transaction_qsec_req {
        __le32 AclFlags;
 } __attribute__((packed)) QUERY_SEC_DESC_REQ;
 
+
+typedef struct smb_com_transaction_ssec_req {
+       struct smb_hdr hdr;     /* wct = 19 */
+       __u8 MaxSetupCount;
+       __u16 Reserved;
+       __le32 TotalParameterCount;
+       __le32 TotalDataCount;
+       __le32 MaxParameterCount;
+       __le32 MaxDataCount;
+       __le32 ParameterCount;
+       __le32 ParameterOffset;
+       __le32 DataCount;
+       __le32 DataOffset;
+       __u8 SetupCount; /* no setup words follow subcommand */
+       /* SNIA spec incorrectly included spurious pad here */
+       __le16 SubCommand; /* 3 = SET_SECURITY_DESC */
+       __le16 ByteCount; /* bcc = 3 + 8 */
+       __u8 Pad[3];
+       __u16 Fid;
+       __u16 Reserved2;
+       __le32 AclFlags;
+} __attribute__((packed)) SET_SEC_DESC_REQ;
+
 typedef struct smb_com_transaction_change_notify_req {
        struct smb_hdr hdr;     /* wct = 23 */
        __u8 MaxSetupCount;
index 1a883663b22dfcc51eac71da6fc8930bf5b7d3e6..dd1d7c200ee63a30e6496d1bbe0f5e153391346e 100644 (file)
@@ -61,6 +61,9 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
 extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
+#endif
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -73,6 +76,8 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
 extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
                                struct cifsSesInfo *ses,
                                void **request_buf);
+extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo,
+                                       const char *hostname);
 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
                             const int stage,
                             const struct nls_table *nls_cp);
@@ -92,6 +97,8 @@ extern int cifs_get_inode_info(struct inode **pinode,
 extern int cifs_get_inode_info_unix(struct inode **pinode,
                        const unsigned char *search_path,
                        struct super_block *sb, int xid);
+extern void acl_to_uid_mode(struct inode *inode, const char *search_path);
+extern int mode_to_acl(struct inode *inode, const char *path);
 
 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
                        const char *);
@@ -311,7 +318,6 @@ extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
 #endif /* CIFS_WEAK_PW_HASH */
-extern int parse_sec_desc(struct cifs_ntsd *, int);
 extern int CIFSSMBCopy(int xid,
                        struct cifsTconInfo *source_tcon,
                        const char *fromName,
@@ -336,8 +342,7 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
                const void *ea_value, const __u16 ea_value_len,
                const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
-                       __u16 fid, char *acl_inf, const int buflen,
-                       const int acl_type /* ACCESS vs. DEFAULT */);
+                       __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
                const unsigned char *searchName,
                char *acl_inf, const int buflen, const int acl_type,
index f0d9a485d0951f29c3f140ebda33391d7471a53d..59d7b7c037adafa4eac1357c62cc87eff1c1bcc7 100644 (file)
@@ -647,8 +647,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                                                 count - 16,
                                                 &server->secType);
                        if (rc == 1) {
-                       /* BB Need to fill struct for sessetup here */
-                               rc = -EOPNOTSUPP;
+                               rc = 0;
                        } else {
                                rc = -EINVAL;
                        }
@@ -2486,6 +2485,7 @@ querySymLinkRetry:
        return rc;
 }
 
+#ifdef CONFIG_CIFS_EXPERIMENTAL
 /* Initialize NT TRANSACT SMB into small smb request buffer.
    This assumes that all NT TRANSACTS that we init here have
    total parm and data under about 400 bytes (to fit in small cifs
@@ -2494,7 +2494,7 @@ querySymLinkRetry:
        MaxSetupCount (size of returned setup area) and
        MaxParameterCount (returned parms size) must be set by caller */
 static int
-smb_init_ntransact(const __u16 sub_command, const int setup_count,
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
                   const int parm_len, struct cifsTconInfo *tcon,
                   void **ret_buf)
 {
@@ -2525,12 +2525,15 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count,
 
 static int
 validate_ntransact(char *buf, char **ppparm, char **ppdata,
-                  int *pdatalen, int *pparmlen)
+                  __u32 *pparmlen, __u32 *pdatalen)
 {
        char *end_of_smb;
        __u32 data_count, data_offset, parm_count, parm_offset;
        struct smb_com_ntransact_rsp *pSMBr;
 
+       *pdatalen = 0;
+       *pparmlen = 0;
+
        if (buf == NULL)
                return -EINVAL;
 
@@ -2567,8 +2570,11 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
                cFYI(1, ("parm count and data count larger than SMB"));
                return -EINVAL;
        }
+       *pdatalen = data_count;
+       *pparmlen = parm_count;
        return 0;
 }
+#endif /* CIFS_EXPERIMENTAL */
 
 int
 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3067,8 +3073,7 @@ GetExtAttrOut:
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
-               /* BB fix up return info */ char *acl_inf, const int buflen,
-                 const int acl_type)
+                 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
 {
        int rc = 0;
        int buf_type = 0;
@@ -3077,7 +3082,10 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
        cFYI(1, ("GetCifsACL"));
 
-       rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
+       *pbuflen = 0;
+       *acl_inf = NULL;
+
+       rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
                        8 /* parm len */, tcon, (void **) &pSMB);
        if (rc)
                return rc;
@@ -3099,34 +3107,52 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
        if (rc) {
                cFYI(1, ("Send error in QuerySecDesc = %d", rc));
        } else {                /* decode response */
-               struct cifs_ntsd *psec_desc;
                __le32 * parm;
-               int parm_len;
-               int data_len;
-               int acl_len;
+               __u32 parm_len;
+               __u32 acl_len;
                struct smb_com_ntransact_rsp *pSMBr;
+               char *pdata;
 
 /* validate_nttransact */
                rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
-                                       (char **)&psec_desc,
-                                       &parm_len, &data_len);
+                                       &pdata, &parm_len, pbuflen);
                if (rc)
                        goto qsec_out;
                pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
+               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf));
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
                        rc = -EIO;      /* bad smb */
+                       *pbuflen = 0;
                        goto qsec_out;
                }
 
 /* BB check that data area is minimum length and as big as acl_len */
 
                acl_len = le32_to_cpu(*parm);
-               /* BB check if (acl_len > bufsize) */
+               if (acl_len != *pbuflen) {
+                       cERROR(1, ("acl length %d does not match %d",
+                                  acl_len, *pbuflen));
+                       if (*pbuflen > acl_len)
+                               *pbuflen = acl_len;
+               }
 
-               parse_sec_desc(psec_desc, acl_len);
+               /* check if buffer is big enough for the acl
+                  header followed by the smallest SID */
+               if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
+                   (*pbuflen >= 64 * 1024)) {
+                       cERROR(1, ("bad acl length %d", *pbuflen));
+                       rc = -EINVAL;
+                       *pbuflen = 0;
+               } else {
+                       *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
+                       if (*acl_inf == NULL) {
+                               *pbuflen = 0;
+                               rc = -ENOMEM;
+                       }
+                       memcpy(*acl_inf, pdata, *pbuflen);
+               }
        }
 qsec_out:
        if (buf_type == CIFS_SMALL_BUFFER)
@@ -3381,7 +3407,7 @@ UnixQPathInfoRetry:
                        memcpy((char *) pFindData,
                               (char *) &pSMBr->hdr.Protocol +
                               data_offset,
-                              sizeof (FILE_UNIX_BASIC_INFO));
+                              sizeof(FILE_UNIX_BASIC_INFO));
                }
        }
        cifs_buf_release(pSMB);
@@ -3649,7 +3675,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
        pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
        pSMB->SearchHandle = searchHandle;      /* always kept as le */
        pSMB->SearchCount =
-               cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
+               cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
        pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
        pSMB->ResumeKey = psrch_inf->resume_key;
        pSMB->SearchFlags =
@@ -4331,7 +4357,7 @@ QFSDeviceRetry:
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
-               if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO)))
+               if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO)))
                        rc = -EIO;      /* bad smb */
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
index 19ee11f7f35ad6188207d25edccb0af3b8cdad11..c52a76ff4bb9db8c2625ed6213dc0a8b026664d6 100644 (file)
@@ -160,7 +160,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        if (server->ssocket) {
                cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
                        server->ssocket->flags));
-               server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
+               kernel_sock_shutdown(server->ssocket, SHUT_WR);
                cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
                        server->ssocket->state,
                        server->ssocket->flags));
@@ -793,7 +793,7 @@ cifs_parse_mount_options(char *options, const char *devname,
        vol->linux_gid = current->gid;
        vol->dir_mode = S_IRWXUGO;
        /* 2767 perms indicate mandatory locking support */
-       vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
+       vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
 
        /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
        vol->rw = TRUE;
@@ -1790,7 +1790,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
        if (volume_info.nullauth) {
                cFYI(1, ("null user"));
-               volume_info.username = NULL;
+               volume_info.username = "";
        } else if (volume_info.username) {
                /* BB fixme parse for domain name here */
                cFYI(1, ("Username: %s", volume_info.username));
index 793404b109252b7f589a1d5f11da8667e76379c2..37dc97af1487d2eed97fdfffa19f8f90c056830b 100644 (file)
@@ -593,7 +593,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
                 * case take precedence.  If a is not a negative dentry, this
                 * should have no side effects
                 */
-               memcpy((unsigned char *)a->name, b->name, a->len);
+               memcpy(a->name, b->name, a->len);
                return 0;
        }
        return 1;
index 1e7e4c06d9e3f8771f813064fcdc2bcce29596cc..68ad4ca0cfa3109fa155b1c7ef9527ba3bb0aed3 100644 (file)
@@ -1026,6 +1026,37 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
        return total_written;
 }
 
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
+{
+       struct cifsFileInfo *open_file = NULL;
+
+       read_lock(&GlobalSMBSeslock);
+       /* we could simply get the first_list_entry since write-only entries
+          are always at the end of the list but since the first entry might
+          have a close pending, we go through the whole list */
+       list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+               if (open_file->closePend)
+                       continue;
+               if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) ||
+                   (open_file->pfile->f_flags & O_RDONLY))) {
+                       if (!open_file->invalidHandle) {
+                               /* found a good file */
+                               /* lock it so it will not be closed on us */
+                               atomic_inc(&open_file->wrtPending);
+                               read_unlock(&GlobalSMBSeslock);
+                               return open_file;
+                       } /* else might as well continue, and look for
+                            another, or simply have the caller reopen it
+                            again rather than trying to fix this handle */
+               } else /* write only file */
+                       break; /* write only files are last so must be done */
+       }
+       read_unlock(&GlobalSMBSeslock);
+       return NULL;
+}
+#endif
+
 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
 {
        struct cifsFileInfo *open_file;
index 5e8b388be3b672a7130e9e26f8bb954ed8321534..7d907e84e0327d01d531ef9fa142670de04b1ccb 100644 (file)
@@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
 
 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
 
-static int get_sfu_uid_mode(struct inode *inode,
+static int get_sfu_mode(struct inode *inode,
                        const unsigned char *path,
                        struct cifs_sb_info *cifs_sb, int xid)
 {
@@ -527,11 +527,16 @@ int cifs_get_inode_info(struct inode **pinode,
 
                /* BB fill in uid and gid here? with help from winbind?
                   or retrieve from NTFS stream extended attribute */
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+               /* fill in 0777 bits from ACL */
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+                       cFYI(1, ("Getting mode bits from ACL"));
+                       acl_to_uid_mode(inode, search_path);
+               }
+#endif
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
-                       /* fill in uid, gid, mode from server ACL */
-                       /* BB FIXME this should also take into account the
-                        * default uid specified on mount if present */
-                       get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
+                       /* fill in remaining high mode bits e.g. SUID, VTX */
+                       get_sfu_mode(inode, search_path, cifs_sb, xid);
                } else if (atomic_read(&cifsInfo->inUse) == 0) {
                        inode->i_uid = cifs_sb->mnt_uid;
                        inode->i_gid = cifs_sb->mnt_gid;
index e5c3e1212697a2253f4474b17b90371f462588ae..f13f96d42fcf63ebdfe4c76a1914a3d0afd03738 100644 (file)
@@ -276,8 +276,8 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
        }
 
        /* start out by storing key in pads */
-       memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
-       memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
+       memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
+       memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
        memcpy(ctx->k_ipad, key, key_len);
        memcpy(ctx->k_opad, key, key_len);
 
@@ -307,8 +307,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
        }
 
        /* start out by storing key in pads */
-       memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
-       memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
+       memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
+       memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
        memcpy(ctx->k_ipad, key, key_len);
        memcpy(ctx->k_opad, key, key_len);
 
index 51ec681fe74a2e32c19d90e2f45de591bb3ab048..15546c2354c5800b7930860304a0d043273db7fb 100644 (file)
@@ -73,7 +73,7 @@ sesInfoAlloc(void)
 {
        struct cifsSesInfo *ret_buf;
 
-       ret_buf = kzalloc(sizeof (struct cifsSesInfo), GFP_KERNEL);
+       ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
        if (ret_buf) {
                write_lock(&GlobalSMBSeslock);
                atomic_inc(&sesInfoAllocCount);
@@ -109,7 +109,7 @@ struct cifsTconInfo *
 tconInfoAlloc(void)
 {
        struct cifsTconInfo *ret_buf;
-       ret_buf = kzalloc(sizeof (struct cifsTconInfo), GFP_KERNEL);
+       ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
        if (ret_buf) {
                write_lock(&GlobalSMBSeslock);
                atomic_inc(&tconInfoAllocCount);
@@ -298,7 +298,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
        memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
 
        buffer->smb_buf_length =
-           (2 * word_count) + sizeof (struct smb_hdr) -
+           (2 * word_count) + sizeof(struct smb_hdr) -
            4 /*  RFC 1001 length field does not count */  +
            2 /* for bcc field itself */ ;
        /* Note that this is the only network field that has to be converted
@@ -422,8 +422,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
        __u32 clc_len;  /* calculated length */
        cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
 
-       if (length < 2 + sizeof (struct smb_hdr)) {
-               if ((length >= sizeof (struct smb_hdr) - 1)
+       if (length < 2 + sizeof(struct smb_hdr)) {
+               if ((length >= sizeof(struct smb_hdr) - 1)
                            && (smb->Status.CifsError != 0)) {
                        smb->WordCount = 0;
                        /* some error cases do not return wct and bcc */
index f06359cb22ee96645e7dfd7b0aa62cc0de216b2b..646e1f06941b5c8062e9c8e590c2e2790736ab7f 100644 (file)
@@ -132,6 +132,34 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
        {0, 0}
 };
 
+
+/* if the mount helper is missing we need to reverse the 1st slash
+   from '/' to backslash in order to format the UNC properly for
+   ip address parsing and for tree connect (unless the user
+   remembered to put the UNC name in properly). Fortunately we do
+   not have to call this twice (we check for IPv4 addresses
+   first, so it is already converted by the time we
+   try IPv6 addresses */
+static int canonicalize_unc(char *cp)
+{
+       int i;
+
+       for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) {
+               if (cp[i] == 0)
+                       break;
+               if (cp[i] == '\\')
+                       break;
+               if (cp[i] == '/') {
+#ifdef CONFIG_CIFS_DEBUG2
+                       cFYI(1, ("change slash to backslash in malformed UNC"));
+#endif
+                       cp[i] = '\\';
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 /* Convert string containing dotted ip address to binary form */
 /* returns 0 if invalid address */
 
@@ -141,11 +169,13 @@ cifs_inet_pton(int address_family, char *cp, void *dst)
        int ret = 0;
 
        /* calculate length by finding first slash or NULL */
-       /* BB Should we convert '/' slash to '\' here since it seems already
-        * done before this */
-       if ( address_family == AF_INET ) {
-               ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
-       } else if ( address_family == AF_INET6 ) {
+       if (address_family == AF_INET) {
+               ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
+               if (ret == 0) {
+                       if (canonicalize_unc(cp))
+                               ret = in4_pton(cp, -1, dst, '\\', NULL);
+               }
+       } else if (address_family == AF_INET6) {
                ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
        }
 #ifdef CONFIG_CIFS_DEBUG2
@@ -740,7 +770,7 @@ cifs_print_status(__u32 status_code)
 
 
 static void
-ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
+ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
 {
        int i;
        if (ntstatus == 0) {
@@ -793,8 +823,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
        if (smberrclass == ERRDOS) {  /* 1 byte field no need to byte reverse */
                for (i = 0;
                     i <
-                    sizeof (mapping_table_ERRDOS) /
-                    sizeof (struct smb_to_posix_error); i++) {
+                    sizeof(mapping_table_ERRDOS) /
+                    sizeof(struct smb_to_posix_error); i++) {
                        if (mapping_table_ERRDOS[i].smb_err == 0)
                                break;
                        else if (mapping_table_ERRDOS[i].smb_err ==
@@ -807,8 +837,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
        } else if (smberrclass == ERRSRV) {   /* server class of error codes */
                for (i = 0;
                     i <
-                    sizeof (mapping_table_ERRSRV) /
-                    sizeof (struct smb_to_posix_error); i++) {
+                    sizeof(mapping_table_ERRSRV) /
+                    sizeof(struct smb_to_posix_error); i++) {
                        if (mapping_table_ERRSRV[i].smb_err == 0)
                                break;
                        else if (mapping_table_ERRSRV[i].smb_err ==
@@ -837,14 +867,14 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
 unsigned int
 smbCalcSize(struct smb_hdr *ptr)
 {
-       return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+       return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
                2 /* size of the bcc field */ + BCC(ptr));
 }
 
 unsigned int
 smbCalcSize_LE(struct smb_hdr *ptr)
 {
-       return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+       return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
                2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
 }
 
index 3746580e97016f390a491684ecfae3a14cbd5796..0f22def4bdff47e30300dec9bcad5be12cd193d6 100644 (file)
@@ -171,7 +171,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
        /* Linux can not store file creation time unfortunately so ignore it */
 
        cifsInfo->cifsAttrs = attr;
-       cifsInfo->time = jiffies;
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+               /* get more accurate mode via ACL - so force inode refresh */
+               cifsInfo->time = 0;
+       } else
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
+               cifsInfo->time = jiffies;
 
        /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
        /* 2767 perms - indicate mandatory locking */
@@ -495,7 +501,7 @@ ffirst_retry:
 static int cifs_unicode_bytelen(char *str)
 {
        int len;
-       __le16 * ustr = (__le16 *)str;
+       __le16 *ustr = (__le16 *)str;
 
        for (len = 0; len <= PATH_MAX; len++) {
                if (ustr[len] == 0)
index 90542a39be1750197345b404bf23806c400c8460..58bbfd992cc0f4afe26f057752aeddfbd3da53ba 100644 (file)
@@ -80,7 +80,7 @@ SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
 
 /* Routines for Windows NT MD4 Hash functions. */
 static int
-_my_wcslen(__u16 * str)
+_my_wcslen(__u16 *str)
 {
        int len = 0;
        while (*str++ != 0)
@@ -96,7 +96,7 @@ _my_wcslen(__u16 * str)
  */
 
 static int
-_my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
+_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
 {      /* BB not a very good conversion routine - change/fix */
        int i;
        __u16 val;
@@ -125,9 +125,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
        /* Password cannot be longer than 128 characters */
        if (passwd) {
                len = strlen((char *) passwd);
-               if (len > 128) {
+               if (len > 128)
                        len = 128;
-               }
+
                /* Password must be converted to NT unicode */
                _my_mbstowcs(wpwd, passwd, len);
        } else
@@ -135,7 +135,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
 
        wpwd[len] = 0;  /* Ensure string is null terminated */
        /* Calculate length in bytes */
-       len = _my_wcslen(wpwd) * sizeof (__u16);
+       len = _my_wcslen(wpwd) * sizeof(__u16);
 
        mdfour(p16, (unsigned char *) wpwd, len);
        memset(wpwd, 0, 129 * 2);
@@ -167,7 +167,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
        E_P16((unsigned char *) passwd, (unsigned char *) p16);
 
        /* clear out local copy of user's password (just being paranoid). */
-       memset(passwd, '\0', sizeof (passwd));
+       memset(passwd, '\0', sizeof(passwd));
 }
 #endif
 
@@ -189,8 +189,10 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
                return;
        dom_u = user_u + 1024;
 
-       /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
-          push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
+       /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
+                       STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
+          push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
+                       STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
 
        /* BB user and domain may need to be uppercased */
        user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
index 369e838bebd3142554b72d58e7333547079b3e41..54e8ef96cb7930c07734aa9f0b808eaa2e215953 100644 (file)
@@ -265,7 +265,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                        __u16 fid;
                        int oplock = FALSE;
-                       if (experimEnabled) 
+                       struct cifs_ntsd *pacl = NULL;
+                       __u32 buflen = 0;
+                       if (experimEnabled)
                                rc = CIFSSMBOpen(xid, pTcon, full_path,
                                        FILE_OPEN, GENERIC_READ, 0, &fid,
                                        &oplock, NULL, cifs_sb->local_nls,
@@ -273,10 +275,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
                        /* else rc is EOPNOTSUPP from above */
 
-                       if(rc == 0) {
-                               rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
-                                       ea_value, buf_size,
-                                       ACL_TYPE_ACCESS);
+                       if (rc == 0) {
+                               rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
+                                                     &buflen);
                                CIFSSMBClose(xid, pTcon, fid);
                        }
                }
index 58bf3f5cdbe25ac6cbd2c527be2df7c286d01ede..e9923ca9c2d9ee4c700eb6f18ea1bfb150fee52f 100644 (file)
@@ -1062,7 +1062,7 @@ static int sctp_listen_for_all(void)
        subscribe.sctp_shutdown_event = 1;
        subscribe.sctp_partial_delivery_event = 1;
 
-       result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+       result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE,
                                 (char *)&bufsize, sizeof(bufsize));
        if (result)
                log_print("Error increasing buffer space on socket %d", result);
@@ -1454,10 +1454,6 @@ int dlm_lowcomms_start(void)
        if (!con_cache)
                goto out;
 
-       /* Set some sysctl minima */
-       if (sysctl_rmem_max < NEEDED_RMEM)
-               sysctl_rmem_max = NEEDED_RMEM;
-
        /* Start listening */
        if (dlm_config.ci_protocol == 0)
                error = tcp_listen_for_all();
index 9d70289f7df328022e050bbcb3723923524c562f..bbed2fd40fdcd59d125e269afde868880c495724 100644 (file)
@@ -115,11 +115,29 @@ static int ecryptfs_calculate_md5(char *dst,
                }
                crypt_stat->hash_tfm = desc.tfm;
        }
-       crypto_hash_init(&desc);
-       crypto_hash_update(&desc, &sg, len);
-       crypto_hash_final(&desc, dst);
-       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
+       rc = crypto_hash_init(&desc);
+       if (rc) {
+               printk(KERN_ERR
+                      "%s: Error initializing crypto hash; rc = [%d]\n",
+                      __FUNCTION__, rc);
+               goto out;
+       }
+       rc = crypto_hash_update(&desc, &sg, len);
+       if (rc) {
+               printk(KERN_ERR
+                      "%s: Error updating crypto hash; rc = [%d]\n",
+                      __FUNCTION__, rc);
+               goto out;
+       }
+       rc = crypto_hash_final(&desc, dst);
+       if (rc) {
+               printk(KERN_ERR
+                      "%s: Error finalizing crypto hash; rc = [%d]\n",
+                      __FUNCTION__, rc);
+               goto out;
+       }
 out:
+       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
        return rc;
 }
 
@@ -504,7 +522,6 @@ int ecryptfs_encrypt_page(struct page *page)
                                        "\n", rc);
                        goto out;
                }
-               extent_offset++;
        }
 out:
        kfree(enc_extent_virt);
@@ -640,7 +657,6 @@ int ecryptfs_decrypt_page(struct page *page)
                               "rc = [%d]\n", __FUNCTION__, rc);
                        goto out;
                }
-               extent_offset++;
        }
 out:
        kfree(enc_extent_virt);
index 2150edf9a58e6db662adcb12bb9ae279ad306c2d..6b7474a4336a5844cd004d3b8af923f19d6fc536 100644 (file)
@@ -87,7 +87,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
        loff_t offset;
        int rc;
 
-       offset = ((((off_t)page_for_lower->index) << PAGE_CACHE_SHIFT)
+       offset = ((((loff_t)page_for_lower->index) << PAGE_CACHE_SHIFT)
                  + offset_in_page);
        virt = kmap(page_for_lower);
        rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
index 2c942e2d14ea2b3ebf2fb51bcf692e3a37565ae5..4ccaaa4b13b229ec17456789ead9aad76c8078bf 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1692,7 +1692,10 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
        if (!binfmt || !binfmt->core_dump)
                goto fail;
        down_write(&mm->mmap_sem);
-       if (!get_dumpable(mm)) {
+       /*
+        * If another thread got here first, or we are not dumpable, bail out.
+        */
+       if (mm->core_waiters || !get_dumpable(mm)) {
                up_write(&mm->mmap_sem);
                goto fail;
        }
@@ -1706,7 +1709,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                flag = O_EXCL;          /* Stop rewrite attacks */
                current->fsuid = 0;     /* Dump root private */
        }
-       set_dumpable(mm, 0);
 
        retval = coredump_wait(exit_code);
        if (retval < 0)
index 18a42de25b556dd2b311f06619678c4bc06c66e7..377ad172d74b1c5e8110393d875d5499f9bfe199 100644 (file)
@@ -69,14 +69,6 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
        return desc + offset;
 }
 
-static inline int
-block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
-{
-       return ext2_test_bit ((block -
-               le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
-                        EXT2_BLOCKS_PER_GROUP(sb), map);
-}
-
 /*
  * Read the bitmap for a given block_group, reading into the specified 
  * slot in the superblock's bitmap cache.
@@ -86,51 +78,20 @@ block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
-       int i;
        struct ext2_group_desc * desc;
        struct buffer_head * bh = NULL;
-       unsigned int bitmap_blk;
-
+       
        desc = ext2_get_group_desc (sb, block_group, NULL);
        if (!desc)
-               return NULL;
-       bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
-       bh = sb_bread(sb, bitmap_blk);
+               goto error_out;
+       bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
        if (!bh)
-               ext2_error (sb, __FUNCTION__,
+               ext2_error (sb, "read_block_bitmap",
                            "Cannot read block bitmap - "
                            "block_group = %d, block_bitmap = %u",
                            block_group, le32_to_cpu(desc->bg_block_bitmap));
-
-       /* check whether block bitmap block number is set */
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-       /* check whether the inode bitmap block number is set */
-       bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-       /* check whether the inode table block number is set */
-       bitmap_blk = le32_to_cpu(desc->bg_inode_table);
-       for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
-               if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-                       /* bad block bitmap */
-                       goto error_out;
-               }
-       }
-
-       return bh;
-
 error_out:
-       brelse(bh);
-       ext2_error(sb, __FUNCTION__,
-                       "Invalid block bitmap - "
-                       "block_group = %d, block = %u",
-                       block_group, bitmap_blk);
-       return NULL;
+       return bh;
 }
 
 static void release_blocks(struct super_block *sb, int count)
@@ -1461,7 +1422,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
 #endif
 }
 
-
 static inline int test_root(int a, int b)
 {
        int num = b;
index c2324d5fe4ac149a5672bad13134d4775c815100..320b2cb3d4d22eddf610d7a27d043eeef0437d5e 100644 (file)
@@ -47,6 +47,11 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                        flags &= ~EXT2_DIRSYNC_FL;
 
                mutex_lock(&inode->i_mutex);
+               /* Is it quota file? Do not allow user to mess with it */
+               if (IS_NOQUOTA(inode)) {
+                       mutex_unlock(&inode->i_mutex);
+                       return -EPERM;
+               }
                oldflags = ei->i_flags;
 
                /*
index 7a87d15523be62f1d33c72c4d8a2eba359d45237..a8ba7e831278a0f53518edc101cd5517734af33e 100644 (file)
@@ -80,14 +80,6 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
        return desc + offset;
 }
 
-static inline int
-block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-       return ext3_test_bit ((block -
-               le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
-                        EXT3_BLOCKS_PER_GROUP(sb), map);
-}
-
 /**
  * read_block_bitmap()
  * @sb:                        super block
@@ -101,51 +93,20 @@ block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
-       int i;
        struct ext3_group_desc * desc;
        struct buffer_head * bh = NULL;
-       ext3_fsblk_t bitmap_blk;
 
        desc = ext3_get_group_desc (sb, block_group, NULL);
        if (!desc)
-               return NULL;
-       bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
-       bh = sb_bread(sb, bitmap_blk);
+               goto error_out;
+       bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
        if (!bh)
-               ext3_error (sb, __FUNCTION__,
+               ext3_error (sb, "read_block_bitmap",
                            "Cannot read block bitmap - "
                            "block_group = %d, block_bitmap = %u",
                            block_group, le32_to_cpu(desc->bg_block_bitmap));
-
-       /* check whether block bitmap block number is set */
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-       /* check whether the inode bitmap block number is set */
-       bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-       /* check whether the inode table block number is set */
-       bitmap_blk = le32_to_cpu(desc->bg_inode_table);
-       for (i = 0; i < EXT3_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
-               if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-                       /* bad block bitmap */
-                       goto error_out;
-               }
-       }
-
-       return bh;
-
 error_out:
-       brelse(bh);
-       ext3_error(sb, __FUNCTION__,
-                       "Invalid block bitmap - "
-                       "block_group = %d, block = %lu",
-                       block_group, bitmap_blk);
-       return NULL;
+       return bh;
 }
 /*
  * The reservation window structure operations
@@ -1772,7 +1733,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-
 static inline int test_root(int a, int b)
 {
        int num = b;
index c8e4ee3af1d0a7ead446bb5dcf34040db7690138..8ca3bfd7242743dba5d05f5afd06e3cdb549718d 100644 (file)
@@ -67,7 +67,7 @@ int ext3_check_dir_entry (const char * function, struct inode * dir,
                          unsigned long offset)
 {
        const char * error_msg = NULL;
-       const int rlen = le16_to_cpu(de->rec_len);
+       const int rlen = ext3_rec_len_from_disk(de->rec_len);
 
        if (rlen < EXT3_DIR_REC_LEN(1))
                error_msg = "rec_len is smaller than minimal";
@@ -173,10 +173,10 @@ revalidate:
                                 * least that it is non-zero.  A
                                 * failure will be detected in the
                                 * dirent test below. */
-                               if (le16_to_cpu(de->rec_len) <
+                               if (ext3_rec_len_from_disk(de->rec_len) <
                                                EXT3_DIR_REC_LEN(1))
                                        break;
-                               i += le16_to_cpu(de->rec_len);
+                               i += ext3_rec_len_from_disk(de->rec_len);
                        }
                        offset = i;
                        filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
@@ -197,7 +197,7 @@ revalidate:
                                ret = stored;
                                goto out;
                        }
-                       offset += le16_to_cpu(de->rec_len);
+                       offset += ext3_rec_len_from_disk(de->rec_len);
                        if (le32_to_cpu(de->inode)) {
                                /* We might block in the next section
                                 * if the data destination is
@@ -219,7 +219,7 @@ revalidate:
                                        goto revalidate;
                                stored ++;
                        }
-                       filp->f_pos += le16_to_cpu(de->rec_len);
+                       filp->f_pos += ext3_rec_len_from_disk(de->rec_len);
                }
                offset = 0;
                brelse (bh);
index 4a2a02c95bf94b98fc4534d870f3546a45442c8e..023a070f55f18fac29cfddafa08557085ad6b2fa 100644 (file)
@@ -51,6 +51,11 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                        flags &= ~EXT3_DIRSYNC_FL;
 
                mutex_lock(&inode->i_mutex);
+               /* Is it quota file? Do not allow user to mess with it */
+               if (IS_NOQUOTA(inode)) {
+                       mutex_unlock(&inode->i_mutex);
+                       return -EPERM;
+               }
                oldflags = ei->i_flags;
 
                /* The JOURNAL_DATA flag is modifiable only by root */
index ec8170adac5397de65b862fa549e27acdc9ab294..4ab6f76e63d0cda8e125672153571038f48b16c6 100644 (file)
@@ -176,6 +176,16 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
 static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
                             struct inode *inode);
 
+/*
+ * p is at least 6 bytes before the end of page
+ */
+static inline struct ext3_dir_entry_2 *
+ext3_next_entry(struct ext3_dir_entry_2 *p)
+{
+       return (struct ext3_dir_entry_2 *)((char *)p +
+               ext3_rec_len_from_disk(p->rec_len));
+}
+
 /*
  * Future: use high four bits of block for coalesce-on-delete flags
  * Mask them off for now.
@@ -280,7 +290,7 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_ent
                        space += EXT3_DIR_REC_LEN(de->name_len);
                        names++;
                }
-               de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+               de = ext3_next_entry(de);
        }
        printk("(%i)\n", names);
        return (struct stats) { names, space, 1 };
@@ -546,14 +556,6 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash,
 }
 
 
-/*
- * p is at least 6 bytes before the end of page
- */
-static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
-{
-       return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
-}
-
 /*
  * This function fills a red-black tree with information from a
  * directory block.  It returns the number directory entries loaded
@@ -720,7 +722,7 @@ static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
                        cond_resched();
                }
                /* XXX: do we need to check rec_len == 0 case? -Chris */
-               de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+               de = ext3_next_entry(de);
        }
        return count;
 }
@@ -822,7 +824,7 @@ static inline int search_dirblock(struct buffer_head * bh,
                        return 1;
                }
                /* prevent looping on a bad block */
-               de_len = le16_to_cpu(de->rec_len);
+               de_len = ext3_rec_len_from_disk(de->rec_len);
                if (de_len <= 0)
                        return -1;
                offset += de_len;
@@ -1130,7 +1132,7 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
                rec_len = EXT3_DIR_REC_LEN(de->name_len);
                memcpy (to, de, rec_len);
                ((struct ext3_dir_entry_2 *) to)->rec_len =
-                               cpu_to_le16(rec_len);
+                               ext3_rec_len_to_disk(rec_len);
                de->inode = 0;
                map++;
                to += rec_len;
@@ -1149,13 +1151,12 @@ static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
 
        prev = to = de;
        while ((char*)de < base + size) {
-               next = (struct ext3_dir_entry_2 *) ((char *) de +
-                                                   le16_to_cpu(de->rec_len));
+               next = ext3_next_entry(de);
                if (de->inode && de->name_len) {
                        rec_len = EXT3_DIR_REC_LEN(de->name_len);
                        if (de > to)
                                memmove(to, de, rec_len);
-                       to->rec_len = cpu_to_le16(rec_len);
+                       to->rec_len = ext3_rec_len_to_disk(rec_len);
                        prev = to;
                        to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
                }
@@ -1229,8 +1230,8 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
        /* Fancy dance to stay within two buffers */
        de2 = dx_move_dirents(data1, data2, map + split, count - split);
        de = dx_pack_dirents(data1,blocksize);
-       de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-       de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
+       de->rec_len = ext3_rec_len_to_disk(data1 + blocksize - (char *) de);
+       de2->rec_len = ext3_rec_len_to_disk(data2 + blocksize - (char *) de2);
        dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
        dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
 
@@ -1300,7 +1301,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
                                return -EEXIST;
                        }
                        nlen = EXT3_DIR_REC_LEN(de->name_len);
-                       rlen = le16_to_cpu(de->rec_len);
+                       rlen = ext3_rec_len_from_disk(de->rec_len);
                        if ((de->inode? rlen - nlen: rlen) >= reclen)
                                break;
                        de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
@@ -1319,11 +1320,11 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
 
        /* By now the buffer is marked for journaling */
        nlen = EXT3_DIR_REC_LEN(de->name_len);
-       rlen = le16_to_cpu(de->rec_len);
+       rlen = ext3_rec_len_from_disk(de->rec_len);
        if (de->inode) {
                struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
-               de1->rec_len = cpu_to_le16(rlen - nlen);
-               de->rec_len = cpu_to_le16(nlen);
+               de1->rec_len = ext3_rec_len_to_disk(rlen - nlen);
+               de->rec_len = ext3_rec_len_to_disk(nlen);
                de = de1;
        }
        de->file_type = EXT3_FT_UNKNOWN;
@@ -1400,17 +1401,18 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
 
        /* The 0th block becomes the root, move the dirents out */
        fde = &root->dotdot;
-       de = (struct ext3_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len));
+       de = (struct ext3_dir_entry_2 *)((char *)fde +
+                       ext3_rec_len_from_disk(fde->rec_len));
        len = ((char *) root) + blocksize - (char *) de;
        memcpy (data1, de, len);
        de = (struct ext3_dir_entry_2 *) data1;
        top = data1 + len;
-       while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top)
+       while ((char *)(de2 = ext3_next_entry(de)) < top)
                de = de2;
-       de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
+       de->rec_len = ext3_rec_len_to_disk(data1 + blocksize - (char *) de);
        /* Initialize the root; the dot dirents already exist */
        de = (struct ext3_dir_entry_2 *) (&root->dotdot);
-       de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
+       de->rec_len = ext3_rec_len_to_disk(blocksize - EXT3_DIR_REC_LEN(2));
        memset (&root->info, 0, sizeof(root->info));
        root->info.info_length = sizeof(root->info);
        root->info.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
@@ -1490,7 +1492,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
                return retval;
        de = (struct ext3_dir_entry_2 *) bh->b_data;
        de->inode = 0;
-       de->rec_len = cpu_to_le16(blocksize);
+       de->rec_len = ext3_rec_len_to_disk(blocksize);
        return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
 
@@ -1553,7 +1555,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
                        goto cleanup;
                node2 = (struct dx_node *)(bh2->b_data);
                entries2 = node2->entries;
-               node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
+               node2->fake.rec_len = ext3_rec_len_to_disk(sb->s_blocksize);
                node2->fake.inode = 0;
                BUFFER_TRACE(frame->bh, "get_write_access");
                err = ext3_journal_get_write_access(handle, frame->bh);
@@ -1651,9 +1653,9 @@ static int ext3_delete_entry (handle_t *handle,
                        BUFFER_TRACE(bh, "get_write_access");
                        ext3_journal_get_write_access(handle, bh);
                        if (pde)
-                               pde->rec_len =
-                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
-                                                   le16_to_cpu(de->rec_len));
+                               pde->rec_len = ext3_rec_len_to_disk(
+                                       ext3_rec_len_from_disk(pde->rec_len) +
+                                       ext3_rec_len_from_disk(de->rec_len));
                        else
                                de->inode = 0;
                        dir->i_version++;
@@ -1661,10 +1663,9 @@ static int ext3_delete_entry (handle_t *handle,
                        ext3_journal_dirty_metadata(handle, bh);
                        return 0;
                }
-               i += le16_to_cpu(de->rec_len);
+               i += ext3_rec_len_from_disk(de->rec_len);
                pde = de;
-               de = (struct ext3_dir_entry_2 *)
-                       ((char *) de + le16_to_cpu(de->rec_len));
+               de = ext3_next_entry(de);
        }
        return -ENOENT;
 }
@@ -1798,13 +1799,13 @@ retry:
        de = (struct ext3_dir_entry_2 *) dir_block->b_data;
        de->inode = cpu_to_le32(inode->i_ino);
        de->name_len = 1;
-       de->rec_len = cpu_to_le16(EXT3_DIR_REC_LEN(de->name_len));
+       de->rec_len = ext3_rec_len_to_disk(EXT3_DIR_REC_LEN(de->name_len));
        strcpy (de->name, ".");
        ext3_set_de_type(dir->i_sb, de, S_IFDIR);
-       de = (struct ext3_dir_entry_2 *)
-                       ((char *) de + le16_to_cpu(de->rec_len));
+       de = ext3_next_entry(de);
        de->inode = cpu_to_le32(dir->i_ino);
-       de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT3_DIR_REC_LEN(1));
+       de->rec_len = ext3_rec_len_to_disk(inode->i_sb->s_blocksize -
+                                       EXT3_DIR_REC_LEN(1));
        de->name_len = 2;
        strcpy (de->name, "..");
        ext3_set_de_type(dir->i_sb, de, S_IFDIR);
@@ -1856,8 +1857,7 @@ static int empty_dir (struct inode * inode)
                return 1;
        }
        de = (struct ext3_dir_entry_2 *) bh->b_data;
-       de1 = (struct ext3_dir_entry_2 *)
-                       ((char *) de + le16_to_cpu(de->rec_len));
+       de1 = ext3_next_entry(de);
        if (le32_to_cpu(de->inode) != inode->i_ino ||
                        !le32_to_cpu(de1->inode) ||
                        strcmp (".", de->name) ||
@@ -1868,9 +1868,9 @@ static int empty_dir (struct inode * inode)
                brelse (bh);
                return 1;
        }
-       offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
-       de = (struct ext3_dir_entry_2 *)
-                       ((char *) de1 + le16_to_cpu(de1->rec_len));
+       offset = ext3_rec_len_from_disk(de->rec_len) +
+                       ext3_rec_len_from_disk(de1->rec_len);
+       de = ext3_next_entry(de1);
        while (offset < inode->i_size ) {
                if (!bh ||
                        (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
@@ -1899,9 +1899,8 @@ static int empty_dir (struct inode * inode)
                        brelse (bh);
                        return 0;
                }
-               offset += le16_to_cpu(de->rec_len);
-               de = (struct ext3_dir_entry_2 *)
-                               ((char *) de + le16_to_cpu(de->rec_len));
+               offset += ext3_rec_len_from_disk(de->rec_len);
+               de = ext3_next_entry(de);
        }
        brelse (bh);
        return 1;
@@ -2255,8 +2254,7 @@ retry:
 }
 
 #define PARENT_INO(buffer) \
-       ((struct ext3_dir_entry_2 *) ((char *) buffer + \
-       le16_to_cpu(((struct ext3_dir_entry_2 *) buffer)->rec_len)))->inode
+       (ext3_next_entry((struct ext3_dir_entry_2 *)(buffer))->inode)
 
 /*
  * Anybody can rename anything with this: the permission checks are left to the
index e906b65448e2ed9da721f68056333eacf4386e98..71ee95e534fdcb6c7128aa843accea7b9a082eec 100644 (file)
@@ -189,15 +189,6 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
        return desc;
 }
 
-static inline int
-block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-       ext4_grpblk_t offset;
-
-       ext4_get_group_no_and_offset(sb, block, NULL, &offset);
-       return ext4_test_bit (offset, map);
-}
-
 /**
  * read_block_bitmap()
  * @sb:                        super block
@@ -211,7 +202,6 @@ block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
 struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
-       int i;
        struct ext4_group_desc * desc;
        struct buffer_head * bh = NULL;
        ext4_fsblk_t bitmap_blk;
@@ -239,38 +229,7 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
                            "Cannot read block bitmap - "
                            "block_group = %d, block_bitmap = %llu",
                            block_group, bitmap_blk);
-
-       /* check whether block bitmap block number is set */
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-
-       /* check whether the inode bitmap block number is set */
-       bitmap_blk = ext4_inode_bitmap(sb, desc);
-       if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-               /* bad block bitmap */
-               goto error_out;
-       }
-       /* check whether the inode table block number is set */
-       bitmap_blk = ext4_inode_table(sb, desc);
-       for (i = 0; i < EXT4_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
-               if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
-                       /* bad block bitmap */
-                       goto error_out;
-               }
-       }
-
        return bh;
-
-error_out:
-       brelse(bh);
-       ext4_error(sb, __FUNCTION__,
-                       "Invalid block bitmap - "
-                       "block_group = %d, block = %llu",
-                       block_group, bitmap_blk);
-       return NULL;
-
 }
 /*
  * The reservation window structure operations
index c04c7ccba9e3f140ed5243a6ccdcc58d6afcaa15..e7f894bdb4202359974088ba5c1f14585a43fc03 100644 (file)
@@ -51,6 +51,11 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                        flags &= ~EXT4_DIRSYNC_FL;
 
                mutex_lock(&inode->i_mutex);
+               /* Is it quota file? Do not allow user to mess with it */
+               if (IS_NOQUOTA(inode)) {
+                       mutex_unlock(&inode->i_mutex);
+                       return -EPERM;
+               }
                oldflags = ei->i_flags;
 
                /* The JOURNAL_DATA flag is modifiable only by root */
index 0fcdba9d47c090ba5b6dae59abfdc41897d5b7f1..535b37399009128df2413d3b7632160390113b9c 100644 (file)
@@ -55,9 +55,10 @@ struct fuse_file *fuse_file_alloc(void)
                if (!ff->reserved_req) {
                        kfree(ff);
                        ff = NULL;
+               } else {
+                       INIT_LIST_HEAD(&ff->write_entry);
+                       atomic_set(&ff->count, 0);
                }
-               INIT_LIST_HEAD(&ff->write_entry);
-               atomic_set(&ff->count, 0);
        }
        return ff;
 }
index 12aca8ed605f1616b1f1deda3867464780fcf66d..09ee07f026630501869eb0bd53131e46b7f8d82d 100644 (file)
@@ -364,7 +364,6 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
                        ++next;
                        truncate_huge_page(page);
                        unlock_page(page);
-                       hugetlb_put_quota(mapping);
                        freed++;
                }
                huge_pagevec_release(&pvec);
@@ -859,15 +858,15 @@ out_free:
        return -ENOMEM;
 }
 
-int hugetlb_get_quota(struct address_space *mapping)
+int hugetlb_get_quota(struct address_space *mapping, long delta)
 {
        int ret = 0;
        struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
 
        if (sbinfo->free_blocks > -1) {
                spin_lock(&sbinfo->stat_lock);
-               if (sbinfo->free_blocks > 0)
-                       sbinfo->free_blocks--;
+               if (sbinfo->free_blocks - delta >= 0)
+                       sbinfo->free_blocks -= delta;
                else
                        ret = -ENOMEM;
                spin_unlock(&sbinfo->stat_lock);
@@ -876,13 +875,13 @@ int hugetlb_get_quota(struct address_space *mapping)
        return ret;
 }
 
-void hugetlb_put_quota(struct address_space *mapping)
+void hugetlb_put_quota(struct address_space *mapping, long delta)
 {
        struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
 
        if (sbinfo->free_blocks > -1) {
                spin_lock(&sbinfo->stat_lock);
-               sbinfo->free_blocks++;
+               sbinfo->free_blocks += delta;
                spin_unlock(&sbinfo->stat_lock);
        }
 }
index d6ff77e8e7ec563b273bd94d2458ba89b1355cee..e4e01bc7f3387daf2b9282a4ec614a50b5955190 100644 (file)
@@ -78,6 +78,10 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                        if (!capable(CAP_SYS_ADMIN))
                                return -EPERM;
                        break;
+               case IOPRIO_CLASS_NONE:
+                       if (data)
+                               return -EINVAL;
+                       break;
                default:
                        return -EINVAL;
        }
index 3c8663bea98ca3bf373f3ea83260b33d67548f3a..dfda12a073e1985fb28b798df2e9088a9a996be4 100644 (file)
@@ -79,6 +79,9 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
                if (!S_ISDIR(inode->i_mode))
                        flags &= ~JFS_DIRSYNC_FL;
 
+               /* Is it quota file? Do not allow user to mess with it */
+               if (IS_NOQUOTA(inode))
+                       return -EPERM;
                jfs_get_inode_flags(jfs_inode);
                oldflags = jfs_inode->mode2;
 
index b6174288501112f4cef17b0d4349e88832da551a..0e5fa11e6b44c4fa114e5e48ef0408a4227a5c07 100644 (file)
@@ -41,7 +41,7 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
 
        fh = fh_copy(&resp->fh, &argp->fh);
        if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
-               RETURN_STATUS(nfserr_inval);
+               RETURN_STATUS(nfserr);
 
        if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
                RETURN_STATUS(nfserr_inval);
index 3e3f2de82c36bc4586789c79ca1a30aeb5272626..b647f2f872dcf60685bd03a1c5d3022b47bfb314 100644 (file)
@@ -37,7 +37,7 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
 
        fh = fh_copy(&resp->fh, &argp->fh);
        if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
-               RETURN_STATUS(nfserr_inval);
+               RETURN_STATUS(nfserr);
 
        if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
                RETURN_STATUS(nfserr_inval);
index 4f712e970584939847ed8287ffa0e379cea177e4..468f17a784416e96e11081d90230a8e6df4eec90 100644 (file)
@@ -95,6 +95,22 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
        return 0;
 }
 
+static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
+                                         struct svc_export *exp)
+{
+       /* Check if the request originated from a secure port. */
+       if (!rqstp->rq_secure && EX_SECURE(exp)) {
+               char buf[RPC_MAX_ADDRBUFLEN];
+               dprintk(KERN_WARNING
+                      "nfsd: request from insecure port %s!\n",
+                      svc_print_addr(rqstp, buf, sizeof(buf)));
+               return nfserr_perm;
+       }
+
+       /* Set user creds for this exportpoint */
+       return nfserrno(nfsd_setuser(rqstp, exp));
+}
+
 /*
  * Perform sanity checks on the dentry in a client's file handle.
  *
@@ -167,18 +183,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                        goto out;
                }
 
-               /* Check if the request originated from a secure port. */
-               error = nfserr_perm;
-               if (!rqstp->rq_secure && EX_SECURE(exp)) {
-                       char buf[RPC_MAX_ADDRBUFLEN];
-                       printk(KERN_WARNING
-                              "nfsd: request from insecure port %s!\n",
-                              svc_print_addr(rqstp, buf, sizeof(buf)));
-                       goto out;
-               }
-
-               /* Set user creds for this exportpoint */
-               error = nfserrno(nfsd_setuser(rqstp, exp));
+               error = nfsd_setuser_and_check_port(rqstp, exp);
                if (error)
                        goto out;
 
@@ -227,18 +232,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                fhp->fh_export = exp;
                nfsd_nr_verified++;
        } else {
-               /* just rechecking permissions
-                * (e.g. nfsproc_create calls fh_verify, then nfsd_create does as well)
+               /*
+                * just rechecking permissions
+                * (e.g. nfsproc_create calls fh_verify, then nfsd_create
+                * does as well)
                 */
                dprintk("nfsd: fh_verify - just checking\n");
                dentry = fhp->fh_dentry;
                exp = fhp->fh_export;
-               /* Set user creds for this exportpoint; necessary even
+               /*
+                * Set user creds for this exportpoint; necessary even
                 * in the "just checking" case because this may be a
                 * filehandle that was created by fh_compose, and that
                 * is about to be used in another nfsv4 compound
-                * operation */
-               error = nfserrno(nfsd_setuser(rqstp, exp));
+                * operation.
+                */
+               error = nfsd_setuser_and_check_port(rqstp, exp);
                if (error)
                        goto out;
        }
index 4ba7f0bdc248e0ff4656b3a5a9bd56851233636f..ce62c152823dd2df71b1d504cc598a1983409d5d 100644 (file)
@@ -3946,7 +3946,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
        struct ocfs2_merge_ctxt ctxt;
        struct ocfs2_extent_list *rightmost_el;
 
-       if (!rec->e_flags & OCFS2_EXT_UNWRITTEN) {
+       if (!(rec->e_flags & OCFS2_EXT_UNWRITTEN)) {
                ret = -EIO;
                mlog_errno(ret);
                goto out;
index c69c1b300155d31aecce94278f52ac8e84b2b537..556e34ccb005f06fb52b611066a0c4db6e10a071 100644 (file)
@@ -728,6 +728,27 @@ static void ocfs2_clear_page_regions(struct page *page,
        kunmap_atomic(kaddr, KM_USER0);
 }
 
+/*
+ * Nonsparse file systems fully allocate before we get to the write
+ * code. This prevents ocfs2_write() from tagging the write as an
+ * allocating one, which means ocfs2_map_page_blocks() might try to
+ * read-in the blocks at the tail of our file. Avoid reading them by
+ * testing i_size against each block offset.
+ */
+static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
+                                unsigned int block_start)
+{
+       u64 offset = page_offset(page) + block_start;
+
+       if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+               return 1;
+
+       if (i_size_read(inode) > offset)
+               return 1;
+
+       return 0;
+}
+
 /*
  * Some of this taken from block_prepare_write(). We already have our
  * mapping by now though, and the entire write will be allocating or
@@ -781,6 +802,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
                                set_buffer_uptodate(bh);
                } else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
                           !buffer_new(bh) &&
+                          ocfs2_should_read_blk(inode, page, block_start) &&
                           (block_start < from || block_end > to)) {
                        ll_rw_block(READ, 1, &bh);
                        *wait_bh++=bh;
index 9cc7c0418b70eb53b04d1904a197feb82b196b24..f02ccb34604d5f855851eee98dc274f09787480e 100644 (file)
@@ -267,7 +267,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
                current_page = cs / spp;
                page = reg->hr_slot_data[current_page];
 
-               vec_len = min(PAGE_CACHE_SIZE,
+               vec_len = min(PAGE_CACHE_SIZE - vec_start,
                              (max_slots-cs) * (PAGE_CACHE_SIZE/spp) );
 
                mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n",
index 685c18065c82ed3b844fca3226d61b850cb01d66..d84bd155997ba2e3546f0811658c4cfe8956dd75 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/slab.h>
 #include <linux/idr.h>
 #include <linux/kref.h>
+#include <linux/net.h>
 #include <net/tcp.h>
 
 #include <asm/uaccess.h>
@@ -616,8 +617,7 @@ static void o2net_shutdown_sc(struct work_struct *work)
                del_timer_sync(&sc->sc_idle_timeout);
                o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
                sc_put(sc);
-               sc->sc_sock->ops->shutdown(sc->sc_sock,
-                                          RCV_SHUTDOWN|SEND_SHUTDOWN);
+               kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR);
        }
 
        /* not fatal so failed connects before the other guy has our
index 3094ddb7a25491b1d2db567707ce7f6a01592c27..1957a5ed219e5845e88c3ec47e1b02e0b34d6a3f 100644 (file)
@@ -318,9 +318,9 @@ out_attach:
 static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
                                   struct ocfs2_dentry_lock *dl)
 {
+       iput(dl->dl_inode);
        ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
        ocfs2_lock_res_free(&dl->dl_lockres);
-       iput(dl->dl_inode);
        kfree(dl);
 }
 
index 6a2f143e269c338b09989595264722dcf742e4e4..63b28fdceb4a3c7b425e87290d08237b5182a790 100644 (file)
@@ -208,9 +208,9 @@ out:
        return NULL;
 }
 
-struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
-                                       struct inode *dir,
-                                       struct ocfs2_dir_entry **res_dir)
+static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
+                                              struct inode *dir,
+                                              struct ocfs2_dir_entry **res_dir)
 {
        struct super_block *sb;
        struct buffer_head *bh_use[NAMEI_RA_SIZE];
index 41c76ff2fcfbc4d725be65a4498b5fd603aa6f2c..4e97dcceaf8f5354fab2b4e78563f56b5853bf35 100644 (file)
@@ -670,7 +670,7 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc
 {
        mlog_entry_void();
 
-       BUG_ON((!lockres->l_flags & OCFS2_LOCK_BUSY));
+       BUG_ON((!(lockres->l_flags & OCFS2_LOCK_BUSY)));
        BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
 
        if (lockres->l_requested > LKM_NLMODE &&
@@ -980,18 +980,6 @@ again:
                goto unlock;
        }
 
-       if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
-               /* lock has not been created yet. */
-               spin_unlock_irqrestore(&lockres->l_lock, flags);
-
-               ret = ocfs2_lock_create(osb, lockres, LKM_NLMODE, 0);
-               if (ret < 0) {
-                       mlog_errno(ret);
-                       goto out;
-               }
-               goto again;
-       }
-
        if (lockres->l_flags & OCFS2_LOCK_BLOCKED &&
            !ocfs2_may_continue_on_blocked_lock(lockres, level)) {
                /* is the lock is currently blocked on behalf of
@@ -1006,7 +994,14 @@ again:
                        mlog(ML_ERROR, "lockres %s has action %u pending\n",
                             lockres->l_name, lockres->l_action);
 
-               lockres->l_action = OCFS2_AST_CONVERT;
+               if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
+                       lockres->l_action = OCFS2_AST_ATTACH;
+                       lkm_flags &= ~LKM_CONVERT;
+               } else {
+                       lockres->l_action = OCFS2_AST_CONVERT;
+                       lkm_flags |= LKM_CONVERT;
+               }
+
                lockres->l_requested = level;
                lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
                spin_unlock_irqrestore(&lockres->l_lock, flags);
@@ -1021,7 +1016,7 @@ again:
                status = dlmlock(osb->dlm,
                                 level,
                                 &lockres->l_lksb,
-                                lkm_flags|LKM_CONVERT,
+                                lkm_flags,
                                 lockres->l_name,
                                 OCFS2_LOCK_ID_MAX_LEN - 1,
                                 ocfs2_locking_ast,
index f92fe91ff260bb8439a44f35240c0b36d803ca87..bbac7cd33e0b453f9db0bcfe668eaa344a10f851 100644 (file)
@@ -1891,9 +1891,11 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        ssize_t written = 0;
        size_t ocount;          /* original count */
        size_t count;           /* after file limit checks */
-       loff_t *ppos = &iocb->ki_pos;
+       loff_t old_size, *ppos = &iocb->ki_pos;
+       u32 old_clusters;
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_path.dentry->d_inode;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry("(0x%p, %u, '%.*s')\n", file,
                   (unsigned int)nr_segs,
@@ -1949,6 +1951,13 @@ relock:
                goto relock;
        }
 
+       /*
+        * To later detect whether a journal commit for sync writes is
+        * necessary, we sample i_size, and cluster count here.
+        */
+       old_size = i_size_read(inode);
+       old_clusters = OCFS2_I(inode)->ip_clusters;
+
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
@@ -1978,6 +1987,21 @@ out_dio:
        /* buffered aio wouldn't have proper lock coverage today */
        BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
 
+       if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) {
+               /*
+                * The generic write paths have handled getting data
+                * to disk, but since we don't make use of the dirty
+                * inode list, a manual journal commit is necessary
+                * here.
+                */
+               if (old_size != i_size_read(inode) ||
+                   old_clusters != OCFS2_I(inode)->ip_clusters) {
+                       ret = journal_force_commit(osb->journal->j_journal);
+                       if (ret < 0)
+                               written = ret;
+               }
+       }
+
        /* 
         * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
         * function pointer which is called when o_direct io completes so that
index 729259016c182f5a9f1e9e15da136419198dc2fd..989ac271858758065c83d6eb7681f9555ba54fd2 100644 (file)
@@ -1105,9 +1105,16 @@ static int ocfs2_rename(struct inode *old_dir,
                goto bail;
        }
 
-       if (!new_de && new_inode)
-               mlog(ML_ERROR, "inode %lu does not exist in it's parent "
-                    "directory!", new_inode->i_ino);
+       if (!new_de && new_inode) {
+               /*
+                * Target was unlinked by another node while we were
+                * waiting to get to ocfs2_rename(). There isn't
+                * anything we can do here to help the situation, so
+                * bubble up the appropriate error.
+                */
+               status = -ENOENT;
+               goto bail;
+       }
 
        /* In case we need to overwrite an existing file, we blow it
         * away first */
index 3b69c53e18379801e9bad4111e689be2cdaf1952..4932b4d1da05f72037b22ec04378edcf83fbc14f 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1061,7 +1061,7 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode)
        prevent_tail_call(ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(sys_open);
+EXPORT_UNUSED_SYMBOL_GPL(sys_open); /* To be deleted for 2.6.25 */
 
 asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
                           int mode)
index aeaf0d0f2f51813bdc2f63115d855e66efe9e93c..a17c26859074e80f47088e4e5a44d900190ed66f 100644 (file)
@@ -2328,21 +2328,18 @@ out:
 
 void proc_flush_task(struct task_struct *task)
 {
-       int i, leader;
-       struct pid *pid, *tgid;
+       int i;
+       struct pid *pid, *tgid = NULL;
        struct upid *upid;
 
-       leader = thread_group_leader(task);
-       proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0);
        pid = task_pid(task);
-       if (pid->level == 0)
-               return;
+       if (thread_group_leader(task))
+               tgid = task_tgid(task);
 
-       tgid = task_tgid(task);
-       for (i = 1; i <= pid->level; i++) {
+       for (i = 0; i <= pid->level; i++) {
                upid = &pid->numbers[i];
                proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
-                               leader ? 0 : tgid->numbers[i].nr);
+                       tgid ? tgid->numbers[i].nr : 0);
        }
 
        upid = &pid->numbers[pid->level];
index 1bdb624357587ae23f31ec3b6f84ef42827cc6f4..a9806bc21ec3d5480b8b6695c6d3f6fb82a203ad 100644 (file)
@@ -561,28 +561,33 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
 static void proc_kill_inodes(struct proc_dir_entry *de)
 {
        struct list_head *p;
-       struct super_block *sb = proc_mnt->mnt_sb;
+       struct super_block *sb;
 
        /*
         * Actually it's a partial revoke().
         */
-       file_list_lock();
-       list_for_each(p, &sb->s_files) {
-               struct file * filp = list_entry(p, struct file, f_u.fu_list);
-               struct dentry * dentry = filp->f_path.dentry;
-               struct inode * inode;
-               const struct file_operations *fops;
-
-               if (dentry->d_op != &proc_dentry_operations)
-                       continue;
-               inode = dentry->d_inode;
-               if (PDE(inode) != de)
-                       continue;
-               fops = filp->f_op;
-               filp->f_op = NULL;
-               fops_put(fops);
+       spin_lock(&sb_lock);
+       list_for_each_entry(sb, &proc_fs_type.fs_supers, s_instances) {
+               file_list_lock();
+               list_for_each(p, &sb->s_files) {
+                       struct file *filp = list_entry(p, struct file,
+                                                       f_u.fu_list);
+                       struct dentry *dentry = filp->f_path.dentry;
+                       struct inode *inode;
+                       const struct file_operations *fops;
+
+                       if (dentry->d_op != &proc_dentry_operations)
+                               continue;
+                       inode = dentry->d_inode;
+                       if (PDE(inode) != de)
+                               continue;
+                       fops = filp->f_op;
+                       filp->f_op = NULL;
+                       fops_put(fops);
+               }
+               file_list_unlock();
        }
-       file_list_unlock();
+       spin_unlock(&sb_lock);
 }
 
 static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
index 1820eb2ef7623a2c222e9be9b61d0e749f259187..1b2b6c6bb47557c2553736b063c79dc48a7a2721 100644 (file)
@@ -78,3 +78,5 @@ static inline int proc_fd(struct inode *inode)
 {
        return PROC_I(inode)->fd;
 }
+
+extern struct file_system_type proc_fs_type;
index 749def054a341b62ff8f542a4bfa21bf5e93821a..131f9c68be5f1d3b2fa036189f7864ca371c63ae 100644 (file)
 #include "internal.h"
 
 
-struct proc_dir_entry *proc_net_create(struct net *net,
-       const char *name, mode_t mode, get_info_t *get_info)
-{
-       return create_proc_info_entry(name,mode, net->proc_net, get_info);
-}
-EXPORT_SYMBOL_GPL(proc_net_create);
-
 struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops)
 {
@@ -185,7 +178,7 @@ static __net_exit void proc_net_ns_exit(struct net *net)
        kfree(net->proc_net_root);
 }
 
-static struct pernet_operations proc_net_ns_ops = {
+static struct pernet_operations __net_initdata proc_net_ns_ops = {
        .init = proc_net_ns_init,
        .exit = proc_net_ns_exit,
 };
index ec9cb3b6c93bf777e8c6cb8ed4a6f8405898fa87..1f86bb860e049888f96d438acf68d3ea53a25188 100644 (file)
@@ -98,7 +98,7 @@ static void proc_kill_sb(struct super_block *sb)
        put_pid_ns(ns);
 }
 
-static struct file_system_type proc_fs_type = {
+struct file_system_type proc_fs_type = {
        .name           = "proc",
        .get_sb         = proc_get_sb,
        .kill_sb        = proc_kill_sb,
index 124693e8d3fa068d60e7f6ad82670a3577ae80fb..ea1f94cc722e0c942111b9849cedf8b1aef1d86a 100644 (file)
@@ -370,7 +370,7 @@ asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(sys_read);
+EXPORT_UNUSED_SYMBOL_GPL(sys_read); /* to be deleted for 2.6.25 */
 
 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)
 {
index c438a8f83f26f7ad3412f5fd2f3af69e582ad02d..e0f0f098a523a8d1c3a41099ab76b411989a23a0 100644 (file)
@@ -57,6 +57,9 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                        if (get_user(flags, (int __user *)arg))
                                return -EFAULT;
 
+                       /* Is it quota file? Do not allow user to mess with it. */
+                       if (IS_NOQUOTA(inode))
+                               return -EPERM;
                        if (((flags ^ REISERFS_I(inode)->
                              i_attrs) & (REISERFS_IMMUTABLE_FL |
                                          REISERFS_APPEND_FL))
index ca41567d7890b8fecbec571d59f357e66eeb171e..d2db2417b2bd68a96ad57ff4e8bf429d5aeee0d1 100644 (file)
@@ -1458,9 +1458,6 @@ static void unmap_buffers(struct page *page, loff_t pos)
                                }
                                bh = next;
                        } while (bh != head);
-                       if (PAGE_SIZE == bh->b_size) {
-                               cancel_dirty_page(page, PAGE_CACHE_SIZE);
-                       }
                }
        }
 }
index f5d14cebc75a5141a3eaf8f85a918fae9f82e913..efbe29af3d7a030bbd531786edbeb15a107eaf48 100644 (file)
@@ -234,7 +234,7 @@ smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
 
        VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n",
                (long)dentry->d_inode->i_size,
-               dentry->d_inode->i_flags, dentry->d_inode->i_atime);
+               dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec);
 
        status = generic_file_aio_read(iocb, iov, nr_segs, pos);
 out:
@@ -269,7 +269,7 @@ smb_file_splice_read(struct file *file, loff_t *ppos,
        struct dentry *dentry = file->f_path.dentry;
        ssize_t status;
 
-       VERBOSE("file %s/%s, pos=%Ld, count=%d\n",
+       VERBOSE("file %s/%s, pos=%Ld, count=%lu\n",
                DENTRY_PATH(dentry), *ppos, count);
 
        status = smb_revalidate_inode(dentry);
@@ -363,7 +363,8 @@ smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                result = generic_file_aio_write(iocb, iov, nr_segs, pos);
                VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
                        (long) file->f_pos, (long) dentry->d_inode->i_size,
-                       dentry->d_inode->i_mtime, dentry->d_inode->i_atime);
+                       dentry->d_inode->i_mtime.tv_sec,
+                       dentry->d_inode->i_atime.tv_sec);
        }
 out:
        return result;
index ab517755ece0aed5a07d46fcd16ad447e68f8d85..9416ead0c7aae67ef1c2bd8b9d3ce12e79cdd9c8 100644 (file)
@@ -536,7 +536,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
 
        /* Allocate the global temp buffer and some superblock helper structs */
        /* FIXME: move these to the smb_sb_info struct */
-       VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
+       VERBOSE("alloc chunk = %lu\n", sizeof(struct smb_ops) +
                sizeof(struct smb_mount_data_kernel));
        mem = kmalloc(sizeof(struct smb_ops) +
                      sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
index feac46050619075aa90a88f71e4a8e4a31b5cda5..d517a27b7f4b7baeefb6048aef46a20d03293b21 100644 (file)
@@ -2593,7 +2593,7 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
        fattr->f_mtime.tv_sec = date_dos2unix(server, date, time);
        fattr->f_mtime.tv_nsec = 0;
        VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
-               mask, date, time, fattr->f_mtime);
+               mask, date, time, fattr->f_mtime.tv_sec);
        fattr->f_size = DVAL(req->rq_data, 12);
        /* ULONG allocation size */
        fattr->attr = WVAL(req->rq_data, 20);
index 283c5720c9de1801e6484173f86df376a49894b9..fae8e85af0ed59ae850ca66f250d3a71c36c1ff8 100644 (file)
@@ -227,7 +227,7 @@ int smbiod_retry(struct smb_sb_info *server)
                printk(KERN_ERR "smb_retry: signal failed [%d]\n", result);
                goto out;
        }
-       VERBOSE("signalled pid %d\n", pid);
+       VERBOSE("signalled pid %d\n", pid_nr(pid));
 
        /* FIXME: The retried requests should perhaps get a "time boost". */
 
index 26d79f6db8a044490c95c8752a40a9fa4c68eff5..76411b1fc4fd4778e2e35cda00da46ead7b7dd5e 100644 (file)
@@ -78,7 +78,6 @@ struct acpi_processor_cx {
 struct acpi_processor_power {
        struct cpuidle_device dev;
        struct acpi_processor_cx *state;
-       struct acpi_processor_cx *bm_state;
        unsigned long bm_check_timestamp;
        u32 default_state;
        u32 bm_activity;
index fb90b421f31c94d5c771255bdc429abd5aca0409..ede377ec91470e11472c1059b7dc55c790b28074 100644 (file)
@@ -231,7 +231,7 @@ extern int init_atu;
                                        IOP3XX_PCI_IO_WINDOW_SIZE - 1)
 #define IOP3XX_PCI_UPPER_IO_VA         (IOP3XX_PCI_LOWER_IO_VA +\
                                        IOP3XX_PCI_IO_WINDOW_SIZE - 1)
-#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) addr -\
+#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\
                                        IOP3XX_PCI_LOWER_IO_PA) +\
                                        IOP3XX_PCI_LOWER_IO_VA)
 
index d2e8171d1d4e9eb93f5f107c0cca421593aa7bca..5e0182485d8c0978872cceff729145291a328596 100644 (file)
@@ -249,7 +249,7 @@ extern struct page *empty_zero_page;
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
 
 #define set_pte_at(mm,addr,ptep,pteval) do { \
-       set_pte_ext(ptep, pteval, (addr) >= PAGE_OFFSET ? 0 : PTE_EXT_NG); \
+       set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
  } while (0)
 
 /*
diff --git a/include/asm-arm26/irq_regs.h b/include/asm-arm26/irq_regs.h
deleted file mode 100644 (file)
index 3dd9c0b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/irq_regs.h>
index c02bc8304b137cd407d88498729bd4fb53acf69e..dd21182b60e0fd11fd6c873a67e3e694229fb340 100644 (file)
 #define SYSREG_IRP_SIZE                                6
 
 /* Bitfields in PCCR */
+#define SYSREG_PCCR_E_OFFSET                   0
+#define SYSREG_PCCR_E_SIZE                     1
 #define SYSREG_PCCR_R_OFFSET                   1
 #define SYSREG_PCCR_R_SIZE                     1
 #define SYSREG_PCCR_C_OFFSET                   2
index 0b51a87e5532e9025111b6c5177bf8c964d58f22..2949a945876a5c4685197927426809a61ee03999 100644 (file)
@@ -3,6 +3,8 @@
 #ifndef __ASM_CRIS_ATOMIC__
 #define __ASM_CRIS_ATOMIC__
 
+#include <linux/compiler.h>
+
 #include <asm/system.h>
 #include <asm/arch/atomic.h>
 
index 180dbf2757b0a87c8ec0ec2ad7a1481ee3f5a5ea..c6c5be62c6981aadf552a1d8dadf54b4a3012d1c 100644 (file)
@@ -62,7 +62,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
  * returns a 16-bit checksum, already complemented
  */
 
-static inline __sum16 int csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
                                                   unsigned short len,
                                                   unsigned short proto,
                                                   __wsum sum)
index 30da58a7d00d26c8a3ffca11c498b342b7b4b28b..4d58652c3a49b1f75b2b2581cabd1a7597398806 100644 (file)
@@ -15,4 +15,7 @@
 #define SET_ETH_DUPLEX_AUTO     SIOCDEVPRIVATE+3        /* Auto neg duplex */
 #define SET_ETH_DUPLEX_HALF     SIOCDEVPRIVATE+4        /* Full duplex */
 #define SET_ETH_DUPLEX_FULL     SIOCDEVPRIVATE+5        /* Half duplex */
+#define SET_ETH_ENABLE_LEDS     SIOCDEVPRIVATE+6        /* Enable net LEDs */
+#define SET_ETH_DISABLE_LEDS    SIOCDEVPRIVATE+7        /* Disable net LEDs */
+#define SET_ETH_AUTONEG         SIOCDEVPRIVATE+8
 #endif /* _CRIS_ETHERNET_H */
index a3a77132ce326023a525f743dfe07962fccc1381..8f8a8d6c9653077ea956a60cd25502190e83c2ed 100644 (file)
@@ -1,9 +1,8 @@
-/* $Id: fasttimer.h,v 1.3 2004/05/14 10:19:19 starvik Exp $
+/*
  * linux/include/asm-cris/fasttimer.h
  *
  * Fast timers for ETRAX100LX
- * This may be useful in other OS than Linux so use 2 space indentation...
- * Copyright (C) 2000, 2002 Axis Communications AB
+ * Copyright (C) 2000-2007 Axis Communications AB
  */
 #include <linux/time.h> /* struct timeval */
 #include <linux/timex.h>
 
 typedef void fast_timer_function_type(unsigned long);
 
+struct fasttime_t {
+       unsigned long tv_jiff;  /* jiffies */
+       unsigned long tv_usec;  /* microseconds */
+};
+
 struct fast_timer{ /* Close to timer_list */
   struct fast_timer *next;
   struct fast_timer *prev;
-  struct timeval tv_set;
-  struct timeval tv_expires;
+       struct fasttime_t tv_set;
+       struct fasttime_t tv_expires;
   unsigned long delay_us;
   fast_timer_function_type *function;
   unsigned long data;
@@ -38,6 +42,6 @@ int del_fast_timer(struct fast_timer * t);
 void schedule_usleep(unsigned long us);
 
 
-void fast_timer_init(void);
+int fast_timer_init(void);
 
 #endif
index 1c13dd3faac3df57e186590f538ac4195bf5a9ea..74178adeb1cd30f3a07eed6366ee36b8613ffe47 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_HARDIRQ_H
 #define __ASM_HARDIRQ_H
 
+#include <asm/irq.h>
 #include <linux/threads.h>
 #include <linux/cache.h>
 
index 92000d0c3f9753a645fdf14dbfd875cd22e9b91b..3a5e4c43eae730c6acce90361cb83a9d7adc266d 100644 (file)
@@ -52,7 +52,6 @@ typedef struct {
 } __kernel_fsid_t;
 
 #ifdef __KERNEL__
-#include <linux/bitops.h>
 
 #undef __FD_SET
 #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
index 71c1b36269b8b490915e8550183fc79aeff98ba4..66e1a7492a0c7aeeac549aaedaefb48e884e68a7 100644 (file)
@@ -171,6 +171,19 @@ struct ktermios {
 #define  B115200 0010002
 #define  B230400 0010003
 #define  B460800 0010004
+
+/* Unsupported rates, but needed to avoid compile error. */
+#define   B500000 0010005
+#define   B576000 0010006
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+
 /* etrax supports these additional three baud rates */
 #define  B921600   0010005
 #define  B1843200  0010006
index fde39f6c49c7780ab96beb0b0fa4e90fe6dae40c..784668ab0fa29dfdb251302f623993c9ceb19d65 100644 (file)
@@ -32,6 +32,7 @@ struct thread_info {
        unsigned long           flags;          /* low level flags */
        __u32                   cpu;            /* current CPU */
        int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
+       __u32                   tls;            /* TLS for this thread */
 
        mm_segment_t            addr_limit;     /* thread address space:
                                                   0-0xBFFFFFFF for user-thead
@@ -79,14 +80,18 @@ struct thread_info {
  * - other flags in MSW
  */
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
-#define TIF_SIGPENDING         1       /* signal pending */
-#define TIF_NEED_RESCHED       2       /* rescheduling necessary */
+#define TIF_NOTIFY_RESUME      1       /* resumption notification requested */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
index 6cc26debe40f9176698b6109b7eff83efa1c58e4..7724246a2601495d0b16b76eba516f1c8f9b8be8 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _CRIS_TLB_H
 #define _CRIS_TLB_H
 
+#include <linux/pagemap.h>
+
 #include <asm/arch/tlb.h>
 
 /*
index 7c90fa970c3842f468b88b163943770425db6dbe..6f2d924f4fd6d0f1421a46666ae81ad9c418b52f 100644 (file)
 #define __NR_io_submit         248
 #define __NR_io_cancel         249
 #define __NR_fadvise64         250
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
 #define __NR_exit_group                252
 #define __NR_lookup_dcookie    253
 #define __NR_epoll_create      254
 #define __NR_add_key           286
 #define __NR_request_key       287
 #define __NR_keyctl            288
+#define __NR_ioprio_set                289
+#define __NR_ioprio_get                290
+#define __NR_inotify_init      291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch  293
+#define __NR_migrate_pages     294
+#define __NR_openat            295
+#define __NR_mkdirat           296
+#define __NR_mknodat           297
+#define __NR_fchownat          298
+#define __NR_futimesat         299
+#define __NR_fstatat64         300
+#define __NR_unlinkat          301
+#define __NR_renameat          302
+#define __NR_linkat            303
+#define __NR_symlinkat         304
+#define __NR_readlinkat                305
+#define __NR_fchmodat          306
+#define __NR_faccessat         307
+#define __NR_pselect6          308
+#define __NR_ppoll             309
+#define __NR_unshare           310
+#define __NR_set_robust_list   311
+#define __NR_get_robust_list   312
+#define __NR_splice            313
+#define __NR_sync_file_range   314
+#define __NR_tee               315
+#define __NR_vmsplice          316
+#define __NR_move_pages                317
+#define __NR_getcpu            318
+#define __NR_epoll_pwait       319
+#define __NR_utimensat         320
+#define __NR_signalfd          321
+#define __NR_timerfd           322
+#define __NR_eventfd           323
+#define __NR_fallocate         324
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 289
+#define NR_syscalls 325
 
 #include <asm/arch/unistd.h>
 
index 8fefd6b827aab3dea697294d99cec7e4934a4429..3a66ebd754bd03604eca6efd4ed8b0efed7093cd 100644 (file)
@@ -12,9 +12,6 @@
 #ifndef _ASM_IRQ_H_
 #define _ASM_IRQ_H_
 
-/* this number is used when no interrupt has been assigned */
-#define NO_IRQ                         (-1)
-
 #define NR_IRQS                                48
 #define IRQ_BASE_CPU                   (0 * 16)
 #define IRQ_BASE_FPGA                  (1 * 16)
index abfcb3a2588fb7de4e98190fd95723d2de526e55..8a695d3407d2576a8d51a4c99d2c2201202b2a87 100644 (file)
@@ -1379,10 +1379,11 @@ struct pal_features_s;
 static inline s64
 ia64_pal_proc_get_features (u64 *features_avail,
                            u64 *features_status,
-                           u64 *features_control)
+                           u64 *features_control,
+                           u64 features_set)
 {
        struct ia64_pal_retval iprv;
-       PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, 0, 0);
+       PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, features_set, 0);
        if (iprv.status == 0) {
                *features_avail   = iprv.v0;
                *features_status  = iprv.v1;
index eb1b566793fe140fd66b2cbae666a402c4727360..27c2f9bb4dbdd7a6528203ccd3a98e95b17486ab 100644 (file)
 #define __NR_rt_sigtimedwait   177
 #define __NR_rt_sigqueueinfo   178
 #define __NR_rt_sigsuspend     179
-#define __NR_pread             180
-#define __NR_pwrite            181
+#define __NR_pread64           180
+#define __NR_pwrite64          181
 #define __NR_lchown            182
 #define __NR_getcwd            183
 #define __NR_capget            184
index 94f1c8172360bb5712e9c5b4607ae7d1e1152d66..ed5c02c6afbbafa98420565c8f7a88c74bbe2e27 100644 (file)
@@ -54,6 +54,7 @@ struct cpuinfo_mips {
        struct cache_desc       dcache; /* Primary D or combined I/D cache */
        struct cache_desc       scache; /* Secondary cache */
        struct cache_desc       tcache; /* Tertiary/split secondary cache */
+       int                     srsets; /* Shadow register sets */
 #if defined(CONFIG_MIPS_MT_SMTC)
        /*
         * In the MIPS MT "SMTC" model, each TC is considered
index 581dc45685a23a05b5129ec9c6630d89e36e42ad..e0d2458b43d06f4be912d70088dfc76105ca9442 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_LASAT_LASATINT_H
 #define __ASM_LASAT_LASATINT_H
 
-#include <linux/irq.h>
-
-#define LASATINT_BASE  MIPS_CPU_IRQ_BASE
-#define LASATINT_END   (LASATINT_BASE + 16)
-
 /* lasat 100 */
 #define LASAT_INT_STATUS_REG_100       (KSEG1ADDR(0x1c880000))
 #define LASAT_INT_MASK_REG_100         (KSEG1ADDR(0x1c890000))
diff --git a/include/asm-mips/mach-lasat/irq.h b/include/asm-mips/mach-lasat/irq.h
new file mode 100644 (file)
index 0000000..da75f89
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _ASM_MACH_LASAT_IRQ_H
+#define _ASM_MACH_LASAT_IRQ_H
+
+#define LASAT_CASCADE_IRQ      (MIPS_CPU_IRQ_BASE + 0)
+
+#define LASAT_IRQ_BASE         8
+#define LASAT_IRQ_END          23
+
+#define NR_IRQS                        24
+
+#include_next <irq.h>
+
+#endif /* _ASM_MACH_LASAT_IRQ_H */
index 5816ad1569d66762413fe7cf1748a5ff001ab391..6529704aa73ae0c3cee7789648fb5328b3948168 100644 (file)
@@ -35,7 +35,7 @@ typedef unsigned int cycles_t;
 
 static inline cycles_t get_cycles(void)
 {
-       return read_c0_count();
+       return 0;
 }
 
 #endif /* __KERNEL__ */
index 0307c84a5c1d70d4cb64876d44ab81a54ca648d4..a2328b8addd83b927fb0d0642f623fc4112d7ba6 100644 (file)
@@ -91,7 +91,7 @@ extern uint m8xx_cpm_hostalloc(uint size);
 extern int  m8xx_cpm_hostfree(uint start);
 extern void m8xx_cpm_hostdump(void);
 
-extern void cpm_load_patch(volatile immap_t *immr);
+extern void cpm_load_patch(cpm8xx_t *cp);
 
 /* Buffer descriptors used by many of the CPM protocols.
 */
index 9d74338e3dec05bcd4ce93090fe365ba8279f1e1..4525c784dfd08d31ad7734a3b50fe4d42151683c 100644 (file)
@@ -138,6 +138,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
 #define CPU_FTR_FPU_UNAVAILABLE                ASM_CONST(0x0000000000800000)
 #define CPU_FTR_UNIFIED_ID_CACHE       ASM_CONST(0x0000000001000000)
 #define CPU_FTR_SPE                    ASM_CONST(0x0000000002000000)
+#define CPU_FTR_NEED_PAIRED_STWCX      ASM_CONST(0x0000000004000000)
 
 /*
  * Add the 64-bit processor unique features in the top half of the word;
@@ -261,25 +262,25 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
 #define CPU_FTRS_7450_20       (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7450_21       (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7450_23       (CPU_FTR_COMMON | \
-           CPU_FTR_USE_TB | \
+           CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7455_1        (CPU_FTR_COMMON | \
-           CPU_FTR_USE_TB | \
+           CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
            CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | \
            CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7455_20       (CPU_FTR_COMMON | \
-           CPU_FTR_USE_TB | \
+           CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
@@ -289,31 +290,32 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7447_10       (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC | CPU_FTR_PPC_LE | \
+           CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7447  (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7447A (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_7448  (CPU_FTR_COMMON | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_PPC_LE)
+           CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
 #define CPU_FTRS_82XX  (CPU_FTR_COMMON | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB)
 #define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
index 86a54a4a8a2a621beca0bdd096d5291ff0c6255e..fea2d8ff1e7330066837038fec03127c70495058 100644 (file)
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
 extern unsigned long ioremap_bot, ioremap_base;
+
+#ifdef CONFIG_44x
+extern int icache_44x_need_flush;
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
        : "=&r" (old), "=&r" (tmp), "=m" (*p)
        : "r" (p), "r" (clr), "r" (set), "m" (*p)
        : "cc" );
+#ifdef CONFIG_44x
+       if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+               icache_44x_need_flush = 1;
+#endif
        return old;
 }
 #else
@@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
        : "=&r" (old), "=&r" (tmp), "=m" (*p)
        : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
        : "cc" );
+#ifdef CONFIG_44x
+       if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+               icache_44x_need_flush = 1;
+#endif
        return old;
 }
 #endif
index cc6d8722825882f33ed2cb9d85805bdcd6a7fed7..11d5383b2f09b470d6b374cfa808ef83811970fc 100644 (file)
@@ -308,8 +308,8 @@ COMPAT_SYS_SPU(move_pages)
 SYSCALL_SPU(getcpu)
 COMPAT_SYS(epoll_pwait)
 COMPAT_SYS_SPU(utimensat)
-COMPAT_SYS(fallocate)
 COMPAT_SYS_SPU(signalfd)
 COMPAT_SYS_SPU(timerfd)
 SYSCALL_SPU(eventfd)
 COMPAT_SYS_SPU(sync_file_range2)
+COMPAT_SYS(fallocate)
index f05895522f7f796e8136ea7bc231007c721a39c9..780f82642756cd4dc3e319687f944432cf297f15 100644 (file)
@@ -176,25 +176,31 @@ static inline unsigned int get_dec(void)
 #endif
 }
 
+/*
+ * Note: Book E and 4xx processors differ from other PowerPC processors
+ * in when the decrementer generates its interrupt: on the 1 to 0
+ * transition for Book E/4xx, but on the 0 to -1 transition for others.
+ */
 static inline void set_dec(int val)
 {
 #if defined(CONFIG_40x)
        mtspr(SPRN_PIT, val);
 #elif defined(CONFIG_8xx_CPU6)
-       set_dec_cpu6(val);
+       set_dec_cpu6(val - 1);
 #else
+#ifndef CONFIG_BOOKE
+       --val;
+#endif
 #ifdef CONFIG_PPC_ISERIES
-       int cur_dec;
-
        if (firmware_has_feature(FW_FEATURE_ISERIES) &&
                        get_lppaca()->shared_proc) {
                get_lppaca()->virtual_decr = val;
-               cur_dec = get_dec();
-               if (cur_dec > val)
+               if (get_dec() > val)
                        HvCall_setVirtualDecr();
-       } else
+               return;
+       }
 #endif
-               mtspr(SPRN_DEC, val);
+       mtspr(SPRN_DEC, val);
 #endif /* not 40x or 8xx_CPU6 */
 }
 
index b6b036ccee34f5fd5abbea69c712e4f273219d5a..5c91081476441277c968d0f55067442d4cd20640 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef _ASM_POWERPC_TLBFLUSH_H
 #define _ASM_POWERPC_TLBFLUSH_H
+
 /*
  * TLB flushing:
  *
@@ -16,9 +17,6 @@
  */
 #ifdef __KERNEL__
 
-struct mm_struct;
-struct vm_area_struct;
-
 #if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
 /*
  * TLB flushing for software loaded TLB chips
@@ -28,7 +26,9 @@ struct vm_area_struct;
  * specific tlbie's
  */
 
-extern void _tlbie(unsigned long address);
+#include <linux/mm.h>
+
+extern void _tlbie(unsigned long address, unsigned int pid);
 
 #if defined(CONFIG_40x) || defined(CONFIG_8xx)
 #define _tlbia()       asm volatile ("tlbia; sync" : : : "memory")
@@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 static inline void flush_tlb_page(struct vm_area_struct *vma,
                                  unsigned long vmaddr)
 {
-       _tlbie(vmaddr);
+       _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
 }
 
 static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
                                         unsigned long vmaddr)
 {
-       _tlbie(vmaddr);
+       _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
 }
 
 static inline void flush_tlb_range(struct vm_area_struct *vma,
index aa558da084715874d5169f5b3a58863db83849ee..b91246153b7ef4b90372b8e1982f7114bd8cd97d 100644 (file)
@@ -43,21 +43,31 @@ extern void __flush_purge_region(void *start, int size);
 extern void __flush_invalidate_region(void *start, int size);
 #endif
 
-#define flush_cache_vmap(start, end)           flush_cache_all()
-#define flush_cache_vunmap(start, end)         flush_cache_all()
+#ifdef CONFIG_CPU_SH4
+extern void copy_to_user_page(struct vm_area_struct *vma,
+       struct page *page, unsigned long vaddr, void *dst, const void *src,
+       unsigned long len);
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+extern void copy_from_user_page(struct vm_area_struct *vma,
+       struct page *page, unsigned long vaddr, void *dst, const void *src,
+       unsigned long len);
+#else
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)     \
        do {                                                    \
                flush_cache_page(vma, vaddr, page_to_pfn(page));\
                memcpy(dst, src, len);                          \
                flush_icache_user_range(vma, page, vaddr, len); \
        } while (0)
 
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)   \
        do {                                                    \
                flush_cache_page(vma, vaddr, page_to_pfn(page));\
                memcpy(dst, src, len);                          \
        } while (0)
+#endif
+
+#define flush_cache_vmap(start, end)           flush_cache_all()
+#define flush_cache_vunmap(start, end)         flush_cache_all()
 
 #define HAVE_ARCH_UNMAPPED_AREA
 
index 3880ce047fe0c1b02af1dba8cc1c049c6a99db1b..7b795ac5477cb215fd5958be2bab51f43ad49b7f 100644 (file)
@@ -23,8 +23,7 @@
  * ---------------------------------------------------------------------------
  */
 
-#if  !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
-     !defined(CONFIG_CPU_SUBTYPE_SH7727)
+#if  !defined(CONFIG_CPU_SUBTYPE_SH7720)
 #define TMU_TOCR       0xfffffe90      /* Byte access */
 #endif
 
@@ -58,8 +57,7 @@
 #define TMU2_TCOR      0xfffffeac      /* Long access */
 #define TMU2_TCNT      0xfffffeb0      /* Long access */
 #define TMU2_TCR       0xfffffeb4      /* Word access */
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
-    !defined(CONFIG_CPU_SUBTYPE_SH7727)
+#if !defined(CONFIG_CPU_SUBTYPE_SH7720)
 #define TMU2_TCPR2     0xfffffeb8      /* Long access */
 #endif
 #endif
index 3aa8b07da47d043b759246252e97dfda3f3c2434..d00a8fde7c7f82b965552342cbcef6d05b66bbae 100644 (file)
@@ -73,10 +73,13 @@ extern void copy_page_nommu(void *to, void *from);
 #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
        (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
 struct page;
-extern void clear_user_page(void *to, unsigned long address, struct page *pg);
-extern void copy_user_page(void *to, void *from, unsigned long address, struct page *pg);
-extern void __clear_user_page(void *to, void *orig_to);
-extern void __copy_user_page(void *to, void *from, void *orig_to);
+struct vm_area_struct;
+extern void clear_user_page(void *to, unsigned long address, struct page *page);
+#ifdef CONFIG_CPU_SH4
+extern void copy_user_highpage(struct page *to, struct page *from,
+                              unsigned long vaddr, struct vm_area_struct *vma);
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
+#endif
 #else
 #define clear_user_page(page, vaddr, pg)       clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)    copy_page(to, from)
index 0b1d7c665659f8f1b2c424c5dbd3d7b38046416e..8f1e8be8d15ddf7fc57f1774f6c7454fa5cc1a10 100644 (file)
@@ -322,7 +322,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 #define PAGE_KERNEL            __pgprot(0)
 #define PAGE_KERNEL_NOCACHE    __pgprot(0)
 #define PAGE_KERNEL_RO         __pgprot(0)
-#define PAGE_KERNEL_PCC                __pgprot(0)
+
+#define PAGE_KERNEL_PCC(slot, type) \
+                               __pgprot(0)
 #endif
 
 #endif /* __ASSEMBLY__ */
index ab0028db645a49d0ed24a4c1a25363ef51f81f60..fda68480f3774973cdc859341be123f4a2ed0260 100644 (file)
@@ -49,7 +49,7 @@ enum cpu_type {
 
        /* SH-4 types */
        CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R,
-       CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501,
+       CPU_SH7760, CPU_SH4_202, CPU_SH4_501,
 
        /* SH-4A types */
        CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3,
index ed358a376e6ea19ab31ef4fc14370dfe0a2003f8..b9789c8b4d15aa817d39913bfd075c265ab7efd1 100644 (file)
@@ -42,9 +42,6 @@
 #define REG_FPSCR      55
 #define REG_FPUL       56
 
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
-
 /*
  * This struct defines the way the registers are stored on the
  * kernel stack during a system call or other kernel entry.
diff --git a/include/asm-sh/vga.h b/include/asm-sh/vga.h
new file mode 100644 (file)
index 0000000..06a5de8
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_VGA_H
+#define __ASM_SH_VGA_H
+
+/* Stupid drivers. */
+
+#endif /* __ASM_SH_VGA_H */
index a6d4da519db6238ff250a570ed5eb6285be4b2cc..c424f80e3ae05ad4b3ecc5e2f7dabeafae2acfe7 100644 (file)
@@ -32,6 +32,4 @@ struct pt_regs {
 extern void show_regs(struct pt_regs *);
 #endif
 
-#define PTRACE_O_TRACESYSGOOD     0x00000001
-
 #endif /* __ASM_SH64_PTRACE_H */
index f7417e91b1706bb79c438446b8b941e5ddb7c9ef..d4de32f0f8afdb849495f29aff26f3c0f004f7d3 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/list.h>
+#include <linux/log2.h>
 
 #include <asm/ldc.h>
 #include <asm/mdesc.h>
@@ -257,8 +258,7 @@ static inline void *vio_dring_entry(struct vio_dring_state *dr,
 static inline u32 vio_dring_avail(struct vio_dring_state *dr,
                                  unsigned int ring_size)
 {
-       /* Ensure build-time power-of-2.  */
-       BUILD_BUG_ON(ring_size & (ring_size - 1));
+       BUILD_BUG_ON(!is_power_of_2(ring_size));
 
        return (dr->pending -
                ((dr->prod - dr->cons) & (ring_size - 1)));
index aa82b88db805bafd93224590924a3883084e05ef..3ebafbaacb24196d82eb5521f4c17292c0a850e7 100644 (file)
@@ -71,7 +71,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 
 static inline void pud_clear (pud_t *pud)
 {
-        set_pud(pud, __pud(0));
+       set_pud(pud, __pud(_PAGE_NEWPAGE));
 }
 
 #define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
index 0217b74cc9fc0cd30456d40929e6196229680178..3a4ffba3d6bcf2c30bbad9e6cd7f87cce8a165ba 100644 (file)
@@ -203,6 +203,11 @@ static inline void save_init_fpu(struct task_struct *tsk)
  */
 static inline int restore_i387(struct _fpstate __user *buf)
 {
+       set_used_math();
+       if (!(task_thread_info(current)->status & TS_USEDFPU)) {
+               clts();
+               task_thread_info(current)->status |= TS_USEDFPU;
+       }
        return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
 }
 
index 9c5092b6aa9f294028cfe0e18189f91764e061e7..2091779e91fbe4f06b659235dc9e8abe2c09922c 100644 (file)
@@ -54,9 +54,6 @@ hcall(unsigned long call,
 }
 /*:*/
 
-void async_hcall(unsigned long call,
-                unsigned long arg1, unsigned long arg2, unsigned long arg3);
-
 /* Can't use our min() macro here: needs to be a constant */
 #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
 
index e23fd9fbebb3a5b024a9c8c2e155ea02ae51c8a9..6adee6a97dec4f462776a59c2259842a4cfc7c71 100644 (file)
@@ -49,7 +49,7 @@ static inline void mach_reboot(void)
                udelay(50);
                kb_wait();
                udelay(50);
-               outb(cmd | 0x04, 0x60); /* set "System flag" */
+               outb(cmd | 0x14, 0x60); /* set "System flag" and "Keyboard Disabled" */
                udelay(50);
                kb_wait();
                udelay(50);
index 8aa10547b4b1e9aed60bc91223fc86ccf035a9aa..52ee75cd0fe175067d5bbe35af64d3f1801296c2 100644 (file)
@@ -29,9 +29,9 @@ extern int mps_oem_check(struct mp_config_table *mpc, char *oem,
 static inline int es7000_check_dsdt(void)
 {
        struct acpi_table_header header;
-       memcpy(&header, 0, sizeof(struct acpi_table_header));
-       acpi_get_table_header(ACPI_SIG_DSDT, 0, &header);
-       if (!strncmp(header.oem_id, "UNISYS", 6))
+
+       if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
+           !strncmp(header.oem_id, "UNISYS", 6))
                return 1;
        return 0;
 }
index 84d01ad334593a99083ec0dcc96873b10e3c611e..71729ca05cd738308eabc7f61ba6cb94dff94554 100644 (file)
@@ -1,5 +1,7 @@
 #include <asm/voyager.h>
-#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *)(PARAM+0x40))
+#include <asm/setup.h>
+#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *) \
+                       (&boot_params.apm_bios_info))
 
 /* Hook to call BIOS initialisation function */
 
index 213c97300cb3fd90842da2e61de07ba9a22227cc..51ddb2590870f96d0e6f0b373cd7a91e22b61d49 100644 (file)
@@ -60,7 +60,7 @@ static inline int v8086_mode(struct pt_regs *regs)
 
 #define instruction_pointer(regs) ((regs)->eip)
 #define frame_pointer(regs) ((regs)->ebp)
-#define stack_pointer(regs) ((regs)->esp)
+#define stack_pointer(regs) ((unsigned long)(regs))
 #define regs_return_value(regs) ((regs)->eax)
 
 extern unsigned long profile_pc(struct pt_regs *regs);
index 8ccedf7a0a5af4ce4679294bfacb44f597eebb73..e3c16c981e4627beca2b3bd2240d51e67b64918a 100644 (file)
@@ -132,6 +132,11 @@ extern unsigned long acpi_realmode_flags;
 int acpi_register_gsi (u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
+#ifdef CONFIG_X86_IO_APIC
+extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+#else
+#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().
  * If this matches the last registration, any IRQ resources for gsi
index 61535e72834dcf79403a222c6875d95cafea619a..5c4e54a2a8d65361aaf7ff9ee691baab67cb642e 100644 (file)
@@ -425,6 +425,8 @@ static inline int ata_id_has_lba48(const u16 *id)
 {
        if ((id[83] & 0xC000) != 0x4000)
                return 0;
+       if (!ata_id_u64(id, 100))
+               return 0;
        return id[83] & (1 << 10);
 }
 
@@ -535,6 +537,15 @@ static inline int ata_drive_40wire(const u16 *dev_id)
        return 1;
 }
 
+static inline int ata_drive_40wire_relaxed(const u16 *dev_id)
+{
+       if (ata_id_is_sata(dev_id))
+               return 0;       /* SATA */
+       if ((dev_id[93] & 0x2000) == 0x2000)
+               return 0;       /* 80 wire */
+       return 1;
+}
+
 static inline int atapi_cdb_len(const u16 *dev_id)
 {
        u16 tmp = dev_id[0] & 0x3;
index 8396db24d01902d9502016776bc9685c3ccea9f1..d18ee67b40f8198118e93336aee272324d9c30db 100644 (file)
@@ -697,6 +697,7 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *,
 extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
                                  struct request *, int, rq_end_io_fn *);
 extern int blk_verify_command(unsigned char *, int);
+extern void blk_unplug(struct request_queue *q);
 
 static inline struct request_queue *bdev_get_queue(struct block_device *bdev)
 {
index 0b9bfbde81686cc1ef6854ce429672ef5b85855c..d62fcee9a08aa8b620436047fadb679f84095b04 100644 (file)
@@ -13,12 +13,6 @@ SUBSYS(cpuset)
 
 /* */
 
-#ifdef CONFIG_CGROUP_CPUACCT
-SUBSYS(cpuacct)
-#endif
-
-/* */
-
 #ifdef CONFIG_CGROUP_DEBUG
 SUBSYS(debug)
 #endif
diff --git a/include/linux/cpu_acct.h b/include/linux/cpu_acct.h
deleted file mode 100644 (file)
index 6b5fd8a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#ifndef _LINUX_CPU_ACCT_H
-#define _LINUX_CPU_ACCT_H
-
-#include <linux/cgroup.h>
-#include <asm/cputime.h>
-
-#ifdef CONFIG_CGROUP_CPUACCT
-extern void cpuacct_charge(struct task_struct *, cputime_t cputime);
-#else
-static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {}
-#endif
-
-#endif
index 16a51546db444f9cbbbc0d845b312621eec0ae44..c4e00161a247975aca754484ecb5f232d1ff4f08 100644 (file)
@@ -92,6 +92,7 @@ struct cpuidle_device {
        struct kobject          kobj;
        struct completion       kobj_unregister;
        void                    *governor_data;
+       struct cpuidle_state    *safe_state;
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
index 64134456ed8cf33782e3d4a83757f4c46515f644..241c01cb92b24e64027c11341475c030a2a825d3 100644 (file)
@@ -656,6 +656,26 @@ struct ext3_dir_entry_2 {
 #define EXT3_DIR_ROUND                 (EXT3_DIR_PAD - 1)
 #define EXT3_DIR_REC_LEN(name_len)     (((name_len) + 8 + EXT3_DIR_ROUND) & \
                                         ~EXT3_DIR_ROUND)
+#define EXT3_MAX_REC_LEN               ((1<<16)-1)
+
+static inline unsigned ext3_rec_len_from_disk(__le16 dlen)
+{
+       unsigned len = le16_to_cpu(dlen);
+
+       if (len == EXT3_MAX_REC_LEN)
+               return 1 << 16;
+       return len;
+}
+
+static inline __le16 ext3_rec_len_to_disk(unsigned len)
+{
+       if (len == (1 << 16))
+               return cpu_to_le16(EXT3_MAX_REC_LEN);
+       else if (len > (1 << 16))
+               BUG();
+       return cpu_to_le16(len);
+}
+
 /*
  * Hash Tree Directory indexing
  * (c) Daniel Phillips, 2001
diff --git a/include/linux/f75375s.h b/include/linux/f75375s.h
new file mode 100644 (file)
index 0000000..e99e225
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * f75375s.h - platform data structure for f75375s sensor
+ *
+ * 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) 2007, Riku Voipio <riku.voipio@iki.fi>
+ */
+
+#ifndef __LINUX_F75375S_H
+#define __LINUX_F75375S_H
+
+/* We want to set fans spinning on systems where there is no
+ * BIOS to do that for us */
+struct f75375s_platform_data {
+       u8 pwm[2];
+       u8 pwm_enable[2];
+};
+
+#endif /* __LINUX_F75375S_H */
index 99650353adfaeb5f1d0b195770faaa5469548cf9..92d420fe03f8173d072b1d8d03a7c51fdcef2125 100644 (file)
@@ -149,10 +149,6 @@ union futex_key {
                int offset;
        } both;
 };
-int get_futex_key(u32 __user *uaddr, struct rw_semaphore *shared,
-                 union futex_key *key);
-void get_futex_key_refs(union futex_key *key);
-void drop_futex_key_refs(union futex_key *key);
 
 #ifdef CONFIG_FUTEX
 extern void exit_robust_list(struct task_struct *curr);
index ea0f50bfbe030dda0ff6d5b1ea22b5f346302279..24968790bc3e3c451f178a1605e9eecb01acf918 100644 (file)
@@ -19,7 +19,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
 int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
 int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
-int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
+int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int);
 void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
 void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
 int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
@@ -106,7 +106,7 @@ static inline unsigned long hugetlb_total_pages(void)
        return 0;
 }
 
-#define follow_hugetlb_page(m,v,p,vs,a,b,i)    ({ BUG(); 0; })
+#define follow_hugetlb_page(m,v,p,vs,a,b,i,w)  ({ BUG(); 0; })
 #define follow_huge_addr(mm, addr, write)      ERR_PTR(-EINVAL)
 #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
 #define hugetlb_prefault(mapping, vma)         ({ BUG(); 0; })
@@ -165,8 +165,10 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
 extern const struct file_operations hugetlbfs_file_operations;
 extern struct vm_operations_struct hugetlb_vm_ops;
 struct file *hugetlb_file_setup(const char *name, size_t);
-int hugetlb_get_quota(struct address_space *mapping);
-void hugetlb_put_quota(struct address_space *mapping);
+int hugetlb_get_quota(struct address_space *mapping, long delta);
+void hugetlb_put_quota(struct address_space *mapping, long delta);
+
+#define BLOCKS_PER_HUGEPAGE    (HPAGE_SIZE / 512)
 
 static inline int is_file_hugepages(struct file *file)
 {
index 8033e6b33271d0fdc07088d1c10d3bf27df1d4ae..a100c9f8eb7c7645eaf7eb5cb3681e69567d2431 100644 (file)
@@ -400,11 +400,6 @@ extern int i2c_release_client(struct i2c_client *);
 extern void i2c_clients_command(struct i2c_adapter *adap,
                                unsigned int cmd, void *arg);
 
-/* returns -EBUSY if address has been taken, 0 if not. Note that the only
-   other place at which this is called is within i2c_attach_client; so
-   you can cheat by simply not registering. Not recommended, of course! */
-extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
-
 /* Detect function. It iterates over all possible addresses itself.
  * It will only call found_proc if some client is connected at the
  * specific address (unless a 'force' matched);
index 4ed4777bba67abcd5ecba17bb3c8c2ca19e999f9..dc75ccbcf9912684094e88afa733b63eb7255259 100644 (file)
@@ -1031,14 +1031,7 @@ ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
 extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
 
 extern void ide_fix_driveid(struct hd_driveid *);
-/*
- * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
- * removing leading/trailing blanks and compressing internal blanks.
- * It is primarily used to tidy up the model name/number fields as
- * returned by the WIN_[P]IDENTIFY commands.
- *
- * (s, bytecount, byteswap)
- */
+
 extern void ide_fixstring(u8 *, const int, const int);
 
 int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
index f73de6fb5c682a7b2f97a599b50792dbfb6c608a..82de2fb62cb71677cfbd876e34189b2b7b002779 100644 (file)
@@ -6,6 +6,7 @@
 #define _LINUX_KALLSYMS_H
 
 #include <linux/errno.h>
+#include <linux/stddef.h>
 
 #define KSYM_NAME_LEN 128
 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
index 1e277852ba42077099f638d09d43bfb8078a7238..56a5673aebad3ecd0384d861f88ae61d65c166f3 100644 (file)
@@ -339,6 +339,7 @@ enum {
        ATA_HORKAGE_SKIP_PM     = (1 << 5),     /* Skip PM operations */
        ATA_HORKAGE_HPA_SIZE    = (1 << 6),     /* native size off by one */
        ATA_HORKAGE_IPM         = (1 << 7),     /* Link PM problems */
+       ATA_HORKAGE_IVB         = (1 << 8),     /* cbl det validity bit bugs */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */
index 580b3f4956ee260b551850d157f1f1b3992a5429..2f4e957af6568990944e0656546fcdba9a8faf3a 100644 (file)
@@ -109,8 +109,11 @@ struct cmos_rtc_board_info {
 #ifndef ARCH_RTC_LOCATION      /* Override by <asm/mc146818rtc.h>? */
 
 #define RTC_IO_EXTENT  0x8
+#define RTC_IO_EXTENT_USED     0x2
 #define RTC_IOMAPPED   1       /* Default to I/O mapping. */
 
+#else
+#define RTC_IO_EXTENT_USED      RTC_IO_EXTENT
 #endif /* ARCH_RTC_LOCATION */
 
 #endif /* _MC146818RTC_H */
index 7da2cee8e1328731ef3fccbcb011f2d9524be3b6..35a8277ec1bd62890966c816714913c53965c937 100644 (file)
@@ -128,6 +128,18 @@ struct igmpmsg
 #ifdef __KERNEL__
 #include <net/sock.h>
 
+#ifdef CONFIG_IP_MROUTE
+static inline int ip_mroute_opt(int opt)
+{
+       return (opt >= MRT_BASE) && (opt <= MRT_BASE + 10);
+}
+#else
+static inline int ip_mroute_opt(int opt)
+{
+       return 0;
+}
+#endif
+
 extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
 extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
 extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
index dd79cdb8c4cf76fb7a7fe794ca32083fc9fe0be3..596131ea46f40259004d1ff4c8fd38b47ee58bea 100644 (file)
@@ -95,6 +95,12 @@ enum sock_type {
 
 #endif /* ARCH_HAS_SOCKET_TYPES */
 
+enum sock_shutdown_cmd {
+       SHUT_RD         = 0,
+       SHUT_WR         = 1,
+       SHUT_RDWR       = 2,
+};
+
 /**
  *  struct socket - general BSD socket
  *  @state: socket state (%SS_CONNECTED, etc)
@@ -223,6 +229,8 @@ extern int kernel_setsockopt(struct socket *sock, int level, int optname,
 extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
                           size_t size, int flags);
 extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
+extern int kernel_sock_shutdown(struct socket *sock,
+                               enum sock_shutdown_cmd how);
 
 #ifndef CONFIG_SMP
 #define SOCKOPS_WRAPPED(name) name
index f2eaea2234ec3a16702fd0d881f4285d48300f73..b87e83a5e0707e5f9e06c18f09a25fbc42e31c62 100644 (file)
@@ -4,25 +4,28 @@ header-y += nfnetlink_conntrack.h
 header-y += nfnetlink_log.h
 header-y += nfnetlink_queue.h
 header-y += xt_CLASSIFY.h
+header-y += xt_CONNMARK.h
+header-y += xt_CONNSECMARK.h
+header-y += xt_DSCP.h
+header-y += xt_MARK.h
+header-y += xt_NFLOG.h
+header-y += xt_NFQUEUE.h
+header-y += xt_SECMARK.h
+header-y += xt_TCPMSS.h
 header-y += xt_comment.h
 header-y += xt_connbytes.h
 header-y += xt_connmark.h
-header-y += xt_CONNMARK.h
 header-y += xt_conntrack.h
 header-y += xt_dccp.h
 header-y += xt_dscp.h
-header-y += xt_DSCP.h
 header-y += xt_esp.h
-header-y += xt_helper.h
 header-y += xt_hashlimit.h
+header-y += xt_helper.h
 header-y += xt_length.h
 header-y += xt_limit.h
 header-y += xt_mac.h
 header-y += xt_mark.h
-header-y += xt_MARK.h
 header-y += xt_multiport.h
-header-y += xt_NFQUEUE.h
-header-y += xt_NFLOG.h
 header-y += xt_pkttype.h
 header-y += xt_policy.h
 header-y += xt_realm.h
@@ -32,9 +35,6 @@ header-y += xt_statistic.h
 header-y += xt_string.h
 header-y += xt_tcpmss.h
 header-y += xt_tcpudp.h
-header-y += xt_SECMARK.h
-header-y += xt_CONNSECMARK.h
-header-y += xt_TCPMSS.h
 
 unifdef-y += nf_conntrack_common.h
 unifdef-y += nf_conntrack_ftp.h
index 7185792b900fe479ff4c6d6a631001c70c789d7d..3a7105bb8f33eac65084e2cd62323f5491a02f18 100644 (file)
@@ -1,47 +1,47 @@
-header-y += ipt_addrtype.h
-header-y += ipt_ah.h
 header-y += ipt_CLASSIFY.h
 header-y += ipt_CLUSTERIP.h
+header-y += ipt_CONNMARK.h
+header-y += ipt_DSCP.h
+header-y += ipt_ECN.h
+header-y += ipt_LOG.h
+header-y += ipt_MARK.h
+header-y += ipt_NFQUEUE.h
+header-y += ipt_REJECT.h
+header-y += ipt_SAME.h
+header-y += ipt_TCPMSS.h
+header-y += ipt_TOS.h
+header-y += ipt_TTL.h
+header-y += ipt_ULOG.h
+header-y += ipt_addrtype.h
+header-y += ipt_ah.h
 header-y += ipt_comment.h
 header-y += ipt_connbytes.h
 header-y += ipt_connmark.h
-header-y += ipt_CONNMARK.h
 header-y += ipt_conntrack.h
 header-y += ipt_dccp.h
 header-y += ipt_dscp.h
-header-y += ipt_DSCP.h
 header-y += ipt_ecn.h
-header-y += ipt_ECN.h
 header-y += ipt_esp.h
 header-y += ipt_hashlimit.h
 header-y += ipt_helper.h
 header-y += ipt_iprange.h
 header-y += ipt_length.h
 header-y += ipt_limit.h
-header-y += ipt_LOG.h
 header-y += ipt_mac.h
 header-y += ipt_mark.h
-header-y += ipt_MARK.h
 header-y += ipt_multiport.h
-header-y += ipt_NFQUEUE.h
 header-y += ipt_owner.h
 header-y += ipt_physdev.h
 header-y += ipt_pkttype.h
 header-y += ipt_policy.h
 header-y += ipt_realm.h
 header-y += ipt_recent.h
-header-y += ipt_REJECT.h
-header-y += ipt_SAME.h
 header-y += ipt_sctp.h
 header-y += ipt_state.h
 header-y += ipt_string.h
 header-y += ipt_tcpmss.h
-header-y += ipt_TCPMSS.h
 header-y += ipt_tos.h
-header-y += ipt_TOS.h
 header-y += ipt_ttl.h
-header-y += ipt_TTL.h
-header-y += ipt_ULOG.h
 
 unifdef-y += ip_queue.h
 unifdef-y += ip_tables.h
index 9dd978d149ff8927e4754fb6697540d638fdc137..8887a5fcd1d0c5952dd54156352a6fac3d73d9f5 100644 (file)
@@ -14,8 +14,8 @@ header-y += ip6t_mark.h
 header-y += ip6t_multiport.h
 header-y += ip6t_opts.h
 header-y += ip6t_owner.h
-header-y += ip6t_policy.h
 header-y += ip6t_physdev.h
+header-y += ip6t_policy.h
 header-y += ip6t_rt.h
 
 unifdef-y += ip6_tables.h
index 7c1f3b1d2ee5a3e3b6c6cda0794a4847e6e044ae..d5bfaba595c79e796be9d105b0359d02ac5a88a8 100644 (file)
@@ -192,7 +192,7 @@ extern int netlink_unregister_notifier(struct notifier_block *nb);
 /* finegrained unicast helpers: */
 struct sock *netlink_getsockbyfilp(struct file *filp);
 int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
-               long timeo, struct sock *ssk);
+                     long *timeo, struct sock *ssk);
 void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
 int netlink_sendskb(struct sock *sk, struct sk_buff *skb);
 
index 5d2281f661f77e70a13090d7508f8adcdbba9584..0dd93bb62fbe9f4af33c458f24db96ca79d8c0c2 100644 (file)
@@ -109,6 +109,14 @@ enum pcie_reset_state {
        pcie_hot_reset = (__force pcie_reset_state_t) 3
 };
 
+typedef unsigned short __bitwise pci_dev_flags_t;
+enum pci_dev_flags {
+       /* INTX_DISABLE in PCI_COMMAND register disables MSI
+        * generation too.
+        */
+       PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
+};
+
 typedef unsigned short __bitwise pci_bus_flags_t;
 enum pci_bus_flags {
        PCI_BUS_FLAGS_NO_MSI   = (__force pci_bus_flags_t) 1,
@@ -185,6 +193,7 @@ struct pci_dev {
        unsigned int    msix_enabled:1;
        unsigned int    is_managed:1;
        unsigned int    is_pcie:1;
+       pci_dev_flags_t dev_flags;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */
 
        u32             saved_config_space[16]; /* config space saved at suspend time */
@@ -479,8 +488,11 @@ extern void pci_sort_breadthfirst(void);
 
 /* Generic PCI functions exported to card drivers */
 
+#ifdef CONFIG_PCI_LEGACY
 struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
 struct pci_dev __deprecated *pci_find_slot (unsigned int bus, unsigned int devfn);
+#endif /* CONFIG_PCI_LEGACY */
+
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
@@ -622,7 +634,6 @@ static inline int __must_check pci_register_driver(struct pci_driver *driver)
 void pci_unregister_driver(struct pci_driver *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
-const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev);
 const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
@@ -751,7 +762,6 @@ static inline void pci_unregister_driver(struct pci_driver *drv) { }
 static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
 static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; }
 static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
-static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
 
 /* Power management related routines */
 static inline int pci_save_state(struct pci_dev *dev) { return 0; }
index e44aac8cf5ffb077d218d80fa5650944f6cec772..1ee009e8fec8c6a670c7a33ac7da40b0844d3b80 100644 (file)
 #define PCI_DEVICE_ID_ATI_RS400_166     0x5a32
 #define PCI_DEVICE_ID_ATI_RS400_200     0x5a33
 #define PCI_DEVICE_ID_ATI_RS480         0x5950
-#define PCI_DEVICE_ID_ATI_RD580                0x5952
-#define PCI_DEVICE_ID_ATI_RX790                0x5957
-#define PCI_DEVICE_ID_ATI_RS690                0x7910
 /* ATI IXP Chipset */
 #define PCI_DEVICE_ID_ATI_IXP200_IDE   0x4349
 #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353
 #define PCI_DEVICE_ID_SERVERWORKS_HE     0x0008
 #define PCI_DEVICE_ID_SERVERWORKS_LE     0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
+#define PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB   0x0036
 #define PCI_DEVICE_ID_SERVERWORKS_EPB    0x0103
-#define PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX  0x0104
 #define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE  0x0132
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4   0x0200
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5   0x0201
 #define PCI_DEVICE_ID_INTEL_82915G_IG  0x2582
 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590
 #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592
+#define PCI_DEVICE_ID_INTEL_5000_ERR   0x25F0
+#define PCI_DEVICE_ID_INTEL_5000_FBD0  0x25F5
+#define PCI_DEVICE_ID_INTEL_5000_FBD1  0x25F6
 #define PCI_DEVICE_ID_INTEL_82945G_HB  0x2770
 #define PCI_DEVICE_ID_INTEL_82945G_IG  0x2772
 #define PCI_DEVICE_ID_INTEL_3000_HB    0x2778
 #define PCI_DEVICE_ID_INTEL_MCH_PC1    0x359a
 #define PCI_DEVICE_ID_INTEL_E7525_MCH  0x359e
 #define PCI_DEVICE_ID_INTEL_IOAT_CNB   0x360b
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB   0x402f
 #define PCI_DEVICE_ID_INTEL_IOAT_SCNB  0x65ff
 #define PCI_DEVICE_ID_INTEL_TOLAPAI_0  0x5031
 #define PCI_DEVICE_ID_INTEL_TOLAPAI_1  0x5032
index 0135c76c76c6dc8005d4cb2d42353fd3320624b1..1689e28483e49d2c2f043a55531280e783fb48d5 100644 (file)
@@ -29,6 +29,7 @@ struct pid_namespace {
 
 extern struct pid_namespace init_pid_ns;
 
+#ifdef CONFIG_PID_NS
 static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 {
        if (ns != &init_pid_ns)
@@ -45,6 +46,28 @@ static inline void put_pid_ns(struct pid_namespace *ns)
                kref_put(&ns->kref, free_pid_ns);
 }
 
+#else /* !CONFIG_PID_NS */
+#include <linux/err.h>
+
+static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
+{
+       return ns;
+}
+
+static inline struct pid_namespace *
+copy_pid_ns(unsigned long flags, struct pid_namespace *ns)
+{
+       if (flags & CLONE_NEWPID)
+               ns = ERR_PTR(-EINVAL);
+       return ns;
+}
+
+static inline void put_pid_ns(struct pid_namespace *ns)
+{
+}
+
+#endif /* CONFIG_PID_NS */
+
 static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
 {
        return tsk->nsproxy->pid_ns;
index 1ff461672060ebc52d882156e0659250944d4110..1273c6ec535c96c1f5151ca47bcc0e9d1ad8db66 100644 (file)
@@ -196,8 +196,6 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
        return res;
 }
 
-extern struct proc_dir_entry *proc_net_create(struct net *net,
-       const char *name, mode_t mode, get_info_t *get_info);
 extern struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops);
 extern void proc_net_remove(struct net *net, const char *name);
@@ -208,7 +206,6 @@ extern void proc_net_remove(struct net *net, const char *name);
 #define proc_bus NULL
 
 #define proc_net_fops_create(net, name, mode, fops)  ({ (void)(mode), NULL; })
-#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
 static inline void proc_net_remove(struct net *net, const char *name) {}
 
 static inline void proc_flush_task(struct task_struct *task)
index 5bf618241ab910eaf1c92a53026ccc672bf6165a..4e81836191df82ebaa5d8bf19e658ad29e92c16e 100644 (file)
@@ -491,9 +491,11 @@ struct nduseroptmsg
        unsigned char   nduseropt_family;
        unsigned char   nduseropt_pad1;
        unsigned short  nduseropt_opts_len;     /* Total length of options */
+       int             nduseropt_ifindex;
        __u8            nduseropt_icmp_type;
        __u8            nduseropt_icmp_code;
        unsigned short  nduseropt_pad2;
+       unsigned int    nduseropt_pad3;
        /* Followed by one or more ND options */
 };
 
index 155d7438f7ad8b46cdb95939efe42ce8d7a07211..ee800e7a70de427ae9ce46e34c27ac659d04336b 100644 (file)
@@ -254,6 +254,7 @@ long io_schedule_timeout(long timeout);
 
 extern void cpu_init (void);
 extern void trap_init(void);
+extern void account_process_tick(struct task_struct *task, int user);
 extern void update_process_times(int user);
 extern void scheduler_tick(void);
 
@@ -862,7 +863,6 @@ struct sched_entity {
        struct load_weight      load;           /* for load-balancing */
        struct rb_node          run_node;
        unsigned int            on_rq;
-       int                     peer_preempt;
 
        u64                     exec_start;
        u64                     sum_exec_runtime;
@@ -1460,12 +1460,17 @@ extern void sched_idle_next(void);
 
 #ifdef CONFIG_SCHED_DEBUG
 extern unsigned int sysctl_sched_latency;
-extern unsigned int sysctl_sched_nr_latency;
+extern unsigned int sysctl_sched_min_granularity;
 extern unsigned int sysctl_sched_wakeup_granularity;
 extern unsigned int sysctl_sched_batch_wakeup_granularity;
 extern unsigned int sysctl_sched_child_runs_first;
 extern unsigned int sysctl_sched_features;
 extern unsigned int sysctl_sched_migration_cost;
+extern unsigned int sysctl_sched_nr_migrate;
+
+int sched_nr_latency_handler(struct ctl_table *table, int write,
+               struct file *file, void __user *buffer, size_t *length,
+               loff_t *ppos);
 #endif
 
 extern unsigned int sysctl_sched_compat_yield;
@@ -1983,6 +1988,14 @@ static inline void inc_syscw(struct task_struct *tsk)
 }
 #endif
 
+#ifdef CONFIG_SMP
+void migration_init(void);
+#else
+static inline void migration_init(void)
+{
+}
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif
index d1b7ca6c1c57af517e0b1f00b7e97f4c78c0c1d9..6080f73fc85f0b5555f973b606984ecc77ddefe2 100644 (file)
@@ -136,7 +136,7 @@ static inline int selinux_audit_rule_init(u32 field, u32 op,
                                           char *rulestr,
                                           struct selinux_audit_rule **rule)
 {
-       return -ENOTSUPP;
+       return -EOPNOTSUPP;
 }
 
 static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule)
index 94e49915a8c0e1113091bd12261f349f852ef6ad..91140fe8c119a317b28d62ce1255f00d8719dba8 100644 (file)
@@ -387,7 +387,9 @@ extern void       skb_truesize_bug(struct sk_buff *skb);
 
 static inline void skb_truesize_check(struct sk_buff *skb)
 {
-       if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
+       int len = sizeof(struct sk_buff) + skb->len;
+
+       if (unlikely((int)skb->truesize < len))
                skb_truesize_bug(skb);
 }
 
index 259a13c3bd98eda779379be1c5df5e37aae6c73e..c25e66bcecf335cfead012f4fd8feeff8834e5aa 100644 (file)
@@ -84,11 +84,12 @@ void smp_prepare_boot_cpu(void);
  *     These macros fold the SMP functionality into a single CPU system
  */
 #define raw_smp_processor_id()                 0
-static inline int up_smp_call_function(void)
+static inline int up_smp_call_function(void (*func)(void *), void *info)
 {
        return 0;
 }
-#define smp_call_function(func,info,retry,wait)        (up_smp_call_function())
+#define smp_call_function(func, info, retry, wait) \
+                       (up_smp_call_function(func, info))
 #define on_each_cpu(func,info,retry,wait)      \
        ({                                      \
                local_irq_disable();            \
@@ -107,6 +108,8 @@ static inline void smp_send_reschedule(int cpu) { }
        local_irq_enable();     \
        0;                      \
 })
+#define smp_call_function_mask(mask, func, info, wait) \
+                       (up_smp_call_function(func, info))
 
 #endif /* !SMP */
 
index 56164d7ba0add0efa325214715706c611b091486..c555f5442bd7c2c99cad45fb49370bb2280a8629 100644 (file)
@@ -332,7 +332,9 @@ extern void tty_ldisc_flush(struct tty_struct *tty);
 
 extern int tty_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                     unsigned long arg);
-
+extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
 extern dev_t tty_devnum(struct tty_struct *tty);
 extern void proc_clear_tty(struct task_struct *p);
 extern struct tty_struct *get_current_tty(void);
index ac69e7bb5a14f5465df654a5d7668cb45a7669f5..1a4ed49f64780cc553a1ac3f6dcca0f2065972ff 100644 (file)
@@ -67,7 +67,7 @@ struct vring {
 };
 
 /* The standard layout for the ring is a continuous chunk of memory which looks
- * like this.  The used fields will be aligned to a "num+1" boundary.
+ * like this.  We assume num is a power of 2.
  *
  * struct vring
  * {
@@ -79,8 +79,8 @@ struct vring {
  *     __u16 avail_idx;
  *     __u16 available[num];
  *
- *     // Padding so a correctly-chosen num value will cache-align used_idx.
- *     char pad[sizeof(struct vring_desc) - sizeof(avail_flags)];
+ *     // Padding to the next page boundary.
+ *     char pad[];
  *
  *     // A ring of used descriptor heads with free-running index.
  *     __u16 used_flags;
@@ -88,18 +88,21 @@ struct vring {
  *     struct vring_used_elem used[num];
  * };
  */
-static inline void vring_init(struct vring *vr, unsigned int num, void *p)
+static inline void vring_init(struct vring *vr, unsigned int num, void *p,
+                             unsigned int pagesize)
 {
        vr->num = num;
        vr->desc = p;
-       vr->avail = p + num*sizeof(struct vring);
-       vr->used = p + (num+1)*(sizeof(struct vring) + sizeof(__u16));
+       vr->avail = p + num*sizeof(struct vring_desc);
+       vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + pagesize-1)
+                           & ~(pagesize - 1));
 }
 
-static inline unsigned vring_size(unsigned int num)
+static inline unsigned vring_size(unsigned int num, unsigned int pagesize)
 {
-       return (num + 1) * (sizeof(struct vring_desc) + sizeof(__u16))
-               + sizeof(__u32) + num * sizeof(struct vring_used_elem);
+       return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
+                + pagesize - 1) & ~(pagesize - 1))
+               + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num;
 }
 
 #ifdef __KERNEL__
index 0864a775de24462fb962545da1c91b7b56a860ae..a1c805d7f488b7295a335c33de66f495cd5d0e37 100644 (file)
@@ -12,7 +12,7 @@ extern void unix_gc(void);
 
 #define UNIX_HASH_SIZE 256
 
-extern atomic_t unix_tot_inflight;
+extern unsigned int unix_tot_inflight;
 
 struct unix_address {
        atomic_t        refcnt;
index e9ff4a4caef992806909de300cb92421b5be90ae..2f65e894b8295f310ad20d331e56d981c94b67d0 100644 (file)
@@ -143,6 +143,13 @@ static inline void dst_hold(struct dst_entry * dst)
        atomic_inc(&dst->__refcnt);
 }
 
+static inline void dst_use(struct dst_entry *dst, unsigned long time)
+{
+       dst_hold(dst);
+       dst->__use++;
+       dst->lastuse = time;
+}
+
 static inline
 struct dst_entry * dst_clone(struct dst_entry * dst)
 {
index 017aebd9068317f387df8f62de160cc7bad36a08..41a301e386433006e659ae14409e1373f905d36b 100644 (file)
@@ -107,4 +107,7 @@ extern int                  fib_rules_unregister(struct fib_rules_ops *);
 extern int                     fib_rules_lookup(struct fib_rules_ops *,
                                                 struct flowi *, int flags,
                                                 struct fib_lookup_arg *);
+extern int                     fib_default_rule_add(struct fib_rules_ops *,
+                                                    u32 pref, u32 table,
+                                                    u32 flags);
 #endif
index 227adcbdfec801e313f9e4c49a029a8f4347be90..38d5a1e9980da3a09f6e6f2c96122bbedf7cc21f 100644 (file)
@@ -13,9 +13,6 @@ struct sock;
 struct sockaddr;
 struct socket;
 
-extern void                    inet_remove_sock(struct sock *sk1);
-extern void                    inet_put_sock(unsigned short num, 
-                                             struct sock *sk);
 extern int                     inet_release(struct socket *sock);
 extern int                     inet_stream_connect(struct socket *sock,
                                                    struct sockaddr * uaddr,
@@ -30,7 +27,6 @@ extern int                    inet_sendmsg(struct kiocb *iocb,
                                             struct msghdr *msg, 
                                             size_t size);
 extern int                     inet_shutdown(struct socket *sock, int how);
-extern unsigned int            inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
 extern int                     inet_listen(struct socket *sock, int backlog);
 
 extern void                    inet_sock_destruct(struct sock *sk);
index 4427dcd1e53a7bf2dc49d2a9f99b913978e4b57a..469216d936631d3e76a4d92544b7e9f32e5c0706 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/wait.h>
+#include <linux/vmalloc.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_sock.h>
@@ -37,7 +38,6 @@
  * I'll experiment with dynamic table growth later.
  */
 struct inet_ehash_bucket {
-       rwlock_t          lock;
        struct hlist_head chain;
        struct hlist_head twchain;
 };
@@ -100,6 +100,9 @@ struct inet_hashinfo {
         * TIME_WAIT sockets use a separate chain (twchain).
         */
        struct inet_ehash_bucket        *ehash;
+       rwlock_t                        *ehash_locks;
+       unsigned int                    ehash_size;
+       unsigned int                    ehash_locks_mask;
 
        /* Ok, let's try this, I give up, we do need a local binding
         * TCP hash as well as the others for fast bind/connect.
@@ -107,7 +110,7 @@ struct inet_hashinfo {
        struct inet_bind_hashbucket     *bhash;
 
        unsigned int                    bhash_size;
-       unsigned int                    ehash_size;
+       /* Note : 4 bytes padding on 64 bit arches */
 
        /* All sockets in TCP_LISTEN state will be in here.  This is the only
         * table where wildcard'd TCP sockets can exist.  Hash function here
@@ -134,6 +137,62 @@ static inline struct inet_ehash_bucket *inet_ehash_bucket(
        return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
 }
 
+static inline rwlock_t *inet_ehash_lockp(
+       struct inet_hashinfo *hashinfo,
+       unsigned int hash)
+{
+       return &hashinfo->ehash_locks[hash & hashinfo->ehash_locks_mask];
+}
+
+static inline int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)
+{
+       unsigned int i, size = 256;
+#if defined(CONFIG_PROVE_LOCKING)
+       unsigned int nr_pcpus = 2;
+#else
+       unsigned int nr_pcpus = num_possible_cpus();
+#endif
+       if (nr_pcpus >= 4)
+               size = 512;
+       if (nr_pcpus >= 8)
+               size = 1024;
+       if (nr_pcpus >= 16)
+               size = 2048;
+       if (nr_pcpus >= 32)
+               size = 4096;
+       if (sizeof(rwlock_t) != 0) {
+#ifdef CONFIG_NUMA
+               if (size * sizeof(rwlock_t) > PAGE_SIZE)
+                       hashinfo->ehash_locks = vmalloc(size * sizeof(rwlock_t));
+               else
+#endif
+               hashinfo->ehash_locks = kmalloc(size * sizeof(rwlock_t),
+                                               GFP_KERNEL);
+               if (!hashinfo->ehash_locks)
+                       return ENOMEM;
+               for (i = 0; i < size; i++)
+                       rwlock_init(&hashinfo->ehash_locks[i]);
+       }
+       hashinfo->ehash_locks_mask = size - 1;
+       return 0;
+}
+
+static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
+{
+       if (hashinfo->ehash_locks) {
+#ifdef CONFIG_NUMA
+               unsigned int size = (hashinfo->ehash_locks_mask + 1) *
+                                                       sizeof(rwlock_t);
+               if (size > PAGE_SIZE)
+                       vfree(hashinfo->ehash_locks);
+               else
+#else
+               kfree(hashinfo->ehash_locks);
+#endif
+               hashinfo->ehash_locks = NULL;
+       }
+}
+
 extern struct inet_bind_bucket *
                    inet_bind_bucket_create(struct kmem_cache *cachep,
                                            struct inet_bind_hashbucket *head,
@@ -222,7 +281,7 @@ static inline void __inet_hash(struct inet_hashinfo *hashinfo,
                sk->sk_hash = inet_sk_ehashfn(sk);
                head = inet_ehash_bucket(hashinfo, sk->sk_hash);
                list = &head->chain;
-               lock = &head->lock;
+               lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
                write_lock(lock);
        }
        __sk_add_node(sk, list);
@@ -253,7 +312,7 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
                inet_listen_wlock(hashinfo);
                lock = &hashinfo->lhash_lock;
        } else {
-               lock = &inet_ehash_bucket(hashinfo, sk->sk_hash)->lock;
+               lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
                write_lock_bh(lock);
        }
 
@@ -354,9 +413,10 @@ static inline struct sock *
         */
        unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
 
        prefetch(head->chain.first);
-       read_lock(&head->lock);
+       read_lock(lock);
        sk_for_each(sk, node, &head->chain) {
                if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
                        goto hit; /* You sunk my battleship! */
@@ -369,7 +429,7 @@ static inline struct sock *
        }
        sk = NULL;
 out:
-       read_unlock(&head->lock);
+       read_unlock(lock);
        return sk;
 hit:
        sock_hold(sk);
index aa10a8178e7011532d63e66ef0d0d08dfc583634..ad8404b5611372bbecc7b1759463bb817e8051df 100644 (file)
@@ -22,7 +22,7 @@ struct inet_peer
        __be32                  v4daddr;        /* peer's address */
        __u16                   avl_height;
        __u16                   ip_id_count;    /* IP ID for the next packet */
-       struct inet_peer        *unused_next, **unused_prevp;
+       struct list_head        unused;
        __u32                   dtime;          /* the time of last use of not
                                                 * referenced entries */
        atomic_t                refcnt;
index 8cadc77c7df4bfbd58d02c3b03ecddc01d9e85af..ed514bfb61ba066edc9c560eccdd7d468ac694c5 100644 (file)
@@ -185,6 +185,12 @@ static inline void fib_select_default(const struct flowi *flp, struct fib_result
 }
 
 #else /* CONFIG_IP_MULTIPLE_TABLES */
+extern void __init fib4_rules_init(void);
+
+#ifdef CONFIG_NET_CLS_ROUTE
+extern u32 fib_rules_tclass(struct fib_result *res);
+#endif
+
 #define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
 #define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
 
@@ -214,15 +220,6 @@ extern __be32  __fib_res_prefsrc(struct fib_result *res);
 /* Exported by fib_hash.c */
 extern struct fib_table *fib_hash_init(u32 id);
 
-#ifdef CONFIG_IP_MULTIPLE_TABLES
-extern void __init fib4_rules_init(void);
-
-#ifdef CONFIG_NET_CLS_ROUTE
-extern u32 fib_rules_tclass(struct fib_result *res);
-#endif
-
-#endif
-
 static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
 {
 #ifdef CONFIG_NET_CLS_ROUTE
index 41870564df8eb163d6eef78876c01dad8a06788b..67ea2c0c0ab75a1fb1a40dd31c734c6326f73cca 100644 (file)
@@ -520,6 +520,10 @@ struct ip_vs_conn {
        spinlock_t              lock;           /* lock for state transition */
        volatile __u16          flags;          /* status flags */
        volatile __u16          state;          /* state info */
+       volatile __u16          old_state;      /* old state, to be used for
+                                                * state transition triggerd
+                                                * synchronization
+                                                */
 
        /* Control members */
        struct ip_vs_conn       *control;       /* Master control connection */
@@ -901,6 +905,10 @@ extern int ip_vs_use_count_inc(void);
 extern void ip_vs_use_count_dec(void);
 extern int ip_vs_control_init(void);
 extern void ip_vs_control_cleanup(void);
+extern struct ip_vs_dest *
+ip_vs_find_dest(__be32 daddr, __be16 dport,
+                __be32 vaddr, __be16 vport, __u16 protocol);
+extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
 
 
 /*
index 5fcc4c1043401cac93ab97a96a5fcb97da0ca031..17b60391fcd66c7ba94ff14b44c0139881412b8b 100644 (file)
@@ -706,11 +706,16 @@ enum ieee80211_hw_flags {
  *
  * @queues: number of available hardware transmit queues for
  *     data packets. WMM/QoS requires at least four.
+ *
+ * @rate_control_algorithm: rate control algorithm for this hardware.
+ *     If unset (NULL), the default algorithm will be used. Must be
+ *     set before calling ieee80211_register_hw().
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
        struct wiphy *wiphy;
        struct workqueue_struct *workqueue;
+       const char *rate_control_algorithm;
        void *priv;
        u32 flags;
        unsigned int extra_tx_headroom;
@@ -936,27 +941,11 @@ enum ieee80211_erp_change_flags {
  *     and remove_interface calls, i.e. while the interface with the
  *     given local_address is enabled.
  *
- * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card
- *     to pass unencrypted EAPOL-Key frames even when encryption is
- *     configured. If the wlan card does not require such a configuration,
- *     this function pointer can be set to NULL.
- *
- * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be
- *     authorized (@authorized=1) or unauthorized (=0). This function can be
- *     used if the wlan hardware or low-level driver implements PAE.
- *     mac80211 will filter frames based on authorization state in any case,
- *     so this function pointer can be NULL if low-level driver does not
- *     require event notification about port state changes.
- *
  * @hw_scan: Ask the hardware to service the scan request, no need to start
  *     the scan state machine in stack.
  *
  * @get_stats: return low-level statistics
  *
- * @set_privacy_invoked: For devices that generate their own beacons and probe
- *     response or association responses this updates the state of privacy_invoked
- *     returns 0 for success or an error number.
- *
  * @get_sequence_counter: For devices that have internal sequence counters this
  *     callback allows mac80211 to access the current value of a counter.
  *     This callback seems not well-defined, tell us if you need it.
@@ -1029,14 +1018,9 @@ struct ieee80211_ops {
        int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                       const u8 *local_address, const u8 *address,
                       struct ieee80211_key_conf *key);
-       int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x);
-       int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr,
-                            int authorized);
        int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
        int (*get_stats)(struct ieee80211_hw *hw,
                         struct ieee80211_low_level_stats *stats);
-       int (*set_privacy_invoked)(struct ieee80211_hw *hw,
-                                  int privacy_invoked);
        int (*get_sequence_counter)(struct ieee80211_hw *hw,
                                    u8* addr, u8 keyidx, u8 txrx,
                                    u32* iv32, u16* iv16);
index 1fd449a6530b293f040eaa6c21ea40887994ea62..5dd6d90b37eb778dfffde65e4998b0bdb8c8d13b 100644 (file)
@@ -119,9 +119,11 @@ static inline struct net *maybe_get_net(struct net *net)
 #ifdef CONFIG_NET_NS
 #define __net_init
 #define __net_exit
+#define __net_initdata
 #else
 #define __net_init     __init
 #define __net_exit     __exit_refok
+#define __net_initdata __initdata
 #endif
 
 struct pernet_operations {
index 7aed02ce2b65b502dd97f72f91417ed5c78e5ca8..cff4608179c12c2f4f19be4ee04d787af0aa9d71 100644 (file)
@@ -124,23 +124,7 @@ struct request_sock_queue {
 extern int reqsk_queue_alloc(struct request_sock_queue *queue,
                             unsigned int nr_table_entries);
 
-static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
-{
-       struct listen_sock *lopt;
-
-       write_lock_bh(&queue->syn_wait_lock);
-       lopt = queue->listen_opt;
-       queue->listen_opt = NULL;
-       write_unlock_bh(&queue->syn_wait_lock);
-
-       return lopt;
-}
-
-static inline void __reqsk_queue_destroy(struct request_sock_queue *queue)
-{
-       kfree(reqsk_queue_yank_listen_sk(queue));
-}
-
+extern void __reqsk_queue_destroy(struct request_sock_queue *queue);
 extern void reqsk_queue_destroy(struct request_sock_queue *queue);
 
 static inline struct request_sock *
index b8733364557ff6d78403584c383a2a2e4334044c..c1f79767357196aecd1aff0235a0445605fe1edd 100644 (file)
@@ -103,6 +103,7 @@ typedef enum {
        SCTP_CMD_ASSOC_CHANGE,   /* generate and send assoc_change event */
        SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
        SCTP_CMD_ASSOC_SHKEY,    /* generate the association shared keys */
+       SCTP_CMD_T1_RETRAN,      /* Mark for retransmission after T1 timeout  */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index da8354e8e33c5269fa92ab4a1dd4a8f4d4971ad8..f30b537d69525168e078a2eb8a0c39a51ef6bdc1 100644 (file)
@@ -186,6 +186,8 @@ typedef enum {
        SCTP_IERROR_AUTH_BAD_HMAC,
        SCTP_IERROR_AUTH_BAD_KEYID,
        SCTP_IERROR_PROTO_VIOLATION,
+       SCTP_IERROR_ERROR,
+       SCTP_IERROR_ABORT,
 } sctp_ierror_t;
 
 
@@ -407,6 +409,7 @@ typedef enum {
        SCTP_RTXR_T3_RTX,
        SCTP_RTXR_FAST_RTX,
        SCTP_RTXR_PMTUD,
+       SCTP_RTXR_T1_RTX,
 } sctp_retransmit_reason_t;
 
 /* Reasons to lower cwnd. */
index 93eb708609e7ef588c3ee517ba80d106c481c140..34318a33a94c0471126a763439fe62ce695aa008 100644 (file)
@@ -65,7 +65,6 @@
 
 
 #ifdef TEST_FRAME
-#undef CONFIG_PROC_FS
 #undef CONFIG_SCTP_DBG_OBJCNT
 #undef CONFIG_SYSCTL
 #endif /* TEST_FRAME */
@@ -267,6 +266,7 @@ enum
        SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS,
        SCTP_MIB_DELAY_SACK_EXPIREDS,
        SCTP_MIB_AUTOCLOSE_EXPIREDS,
+       SCTP_MIB_T1_RETRANSMITS,
        SCTP_MIB_T3_RETRANSMITS,
        SCTP_MIB_PMTUD_RETRANSMITS,
        SCTP_MIB_FAST_RETRANSMITS,
@@ -664,6 +664,9 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
        return (h & (sctp_assoc_hashsize-1));
 }
 
+#define sctp_for_each_hentry(epb, node, head) \
+       hlist_for_each_entry(epb, node, head, node)
+
 /* Is a socket of this style? */
 #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
 static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
index ef892e00c83365acdccb3810158277364b5ddae9..eb3113c38a943469c74b76163f6ee448b528d66f 100644 (file)
@@ -100,20 +100,19 @@ struct crypto_hash;
 struct sctp_bind_bucket {
        unsigned short  port;
        unsigned short  fastreuse;
-       struct sctp_bind_bucket *next;
-       struct sctp_bind_bucket **pprev;
+       struct hlist_node       node;
        struct hlist_head       owner;
 };
 
 struct sctp_bind_hashbucket {
        spinlock_t      lock;
-       struct sctp_bind_bucket *chain;
+       struct hlist_head       chain;
 };
 
 /* Used for hashing all associations.  */
 struct sctp_hashbucket {
        rwlock_t        lock;
-       struct sctp_ep_common  *chain;
+       struct hlist_head       chain;
 } __attribute__((__aligned__(8)));
 
 
@@ -212,6 +211,7 @@ extern struct sctp_globals {
        
        /* Flag to indicate if addip is enabled. */
        int addip_enable;
+       int addip_noauth_enable;
 
        /* Flag to indicate if PR-SCTP is enabled. */
        int prsctp_enable;
@@ -249,6 +249,7 @@ extern struct sctp_globals {
 #define sctp_local_addr_list           (sctp_globals.local_addr_list)
 #define sctp_local_addr_lock           (sctp_globals.addr_list_lock)
 #define sctp_addip_enable              (sctp_globals.addip_enable)
+#define sctp_addip_noauth              (sctp_globals.addip_noauth_enable)
 #define sctp_prsctp_enable             (sctp_globals.prsctp_enable)
 #define sctp_auth_enable               (sctp_globals.auth_enable)
 
@@ -873,10 +874,11 @@ struct sctp_transport {
         * address list derived from the INIT or INIT ACK chunk, a
         * number of data elements needs to be maintained including:
         */
-       __u32 rtt;              /* This is the most recent RTT.  */
-
        /* RTO         : The current retransmission timeout value.  */
        unsigned long rto;
+       unsigned long last_rto;
+
+       __u32 rtt;              /* This is the most recent RTT.  */
 
        /* RTTVAR      : The current RTT variation.  */
        __u32 rttvar;
@@ -1184,9 +1186,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        int flags);
 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
                       __u8 use_as_src, gfp_t gfp);
-int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-                       void fastcall (*rcu_call)(struct rcu_head *,
-                                         void (*func)(struct rcu_head *)));
+int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
                         struct sctp_sock *);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr  *bp,
@@ -1229,8 +1229,7 @@ typedef enum {
 
 struct sctp_ep_common {
        /* Fields to help us manage our entries in the hash tables. */
-       struct sctp_ep_common *next;
-       struct sctp_ep_common **pprev;
+       struct hlist_node node;
        int hashent;
 
        /* Runtime type information.  What kind of endpoint is this? */
@@ -1541,7 +1540,6 @@ struct sctp_association {
                __u8    asconf_capable;  /* Does peer support ADDIP? */
                __u8    prsctp_capable;  /* Can peer do PR-SCTP? */
                __u8    auth_capable;    /* Is peer doing SCTP-AUTH? */
-               __u8    addip_capable;   /* Can peer do ADD-IP */
 
                __u32   adaptation_ind;  /* Adaptation Code point. */
 
index 20de3fa7ae40001bbe7771bb32915b8604f686f7..567e468d74929c993f6c8fd14271068dc6bc0eb3 100644 (file)
@@ -560,6 +560,14 @@ struct proto {
        void                    (*unhash)(struct sock *sk);
        int                     (*get_port)(struct sock *sk, unsigned short snum);
 
+#ifdef CONFIG_SMP
+       /* Keeping track of sockets in use */
+       void                    (*inuse_add)(struct proto *prot, int inc);
+       int                     (*inuse_getval)(const struct proto *prot);
+       int                     *inuse_ptr;
+#else
+       int                     inuse;
+#endif
        /* Memory pressure */
        void                    (*enter_memory_pressure)(void);
        atomic_t                *memory_allocated;      /* Current allocated memory. */
@@ -592,12 +600,38 @@ struct proto {
 #ifdef SOCK_REFCNT_DEBUG
        atomic_t                socks;
 #endif
-       struct {
-               int inuse;
-               u8  __pad[SMP_CACHE_BYTES - sizeof(int)];
-       } stats[NR_CPUS];
 };
 
+/*
+ * Special macros to let protos use a fast version of inuse{get|add}
+ * using a static percpu variable per proto instead of an allocated one,
+ * saving one dereference.
+ * This might be changed if/when dynamic percpu vars become fast.
+ */
+#ifdef CONFIG_SMP
+# define DEFINE_PROTO_INUSE(NAME)                      \
+static DEFINE_PER_CPU(int, NAME##_inuse);              \
+static void NAME##_inuse_add(struct proto *prot, int inc)      \
+{                                                      \
+       __get_cpu_var(NAME##_inuse) += inc;             \
+}                                                      \
+                                                       \
+static int NAME##_inuse_getval(const struct proto *prot)\
+{                                                      \
+       int res = 0, cpu;                               \
+                                                       \
+       for_each_possible_cpu(cpu)                      \
+               res += per_cpu(NAME##_inuse, cpu);      \
+       return res;                                     \
+}
+# define REF_PROTO_INUSE(NAME)                         \
+       .inuse_add = NAME##_inuse_add,                  \
+       .inuse_getval = NAME##_inuse_getval,
+#else
+# define DEFINE_PROTO_INUSE(NAME)
+# define REF_PROTO_INUSE(NAME)
+#endif
+
 extern int proto_register(struct proto *prot, int alloc_slab);
 extern void proto_unregister(struct proto *prot);
 
@@ -629,12 +663,29 @@ static inline void sk_refcnt_debug_release(const struct sock *sk)
 /* Called with local bh disabled */
 static __inline__ void sock_prot_inc_use(struct proto *prot)
 {
-       prot->stats[smp_processor_id()].inuse++;
+#ifdef CONFIG_SMP
+       prot->inuse_add(prot, 1);
+#else
+       prot->inuse++;
+#endif
 }
 
 static __inline__ void sock_prot_dec_use(struct proto *prot)
 {
-       prot->stats[smp_processor_id()].inuse--;
+#ifdef CONFIG_SMP
+       prot->inuse_add(prot, -1);
+#else
+       prot->inuse--;
+#endif
+}
+
+static __inline__ int sock_prot_inuse(struct proto *proto)
+{
+#ifdef CONFIG_SMP
+       return proto->inuse_getval(proto);
+#else
+       return proto->inuse;
+#endif
 }
 
 /* With per-bucket locks this operation is not-atomic, so that
@@ -1184,14 +1235,16 @@ static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
                                                   gfp_t gfp)
 {
        struct sk_buff *skb;
-       int hdr_len;
 
-       hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header);
-       skb = alloc_skb_fclone(size + hdr_len, gfp);
+       skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
        if (skb) {
                skb->truesize += mem;
                if (sk_stream_wmem_schedule(sk, skb->truesize)) {
-                       skb_reserve(skb, hdr_len);
+                       /*
+                        * Make sure that we have exactly size bytes
+                        * available to the caller, no more, no less.
+                        */
+                       skb_reserve(skb, skb_tailroom(skb) - size);
                        return skb;
                }
                __kfree_skb(skb);
index c1d1629fcd272a038bc359f81d9fa700eb4d8524..5f388035687de5004d11d42fbb436abb08fb325b 100644 (file)
@@ -21,7 +21,7 @@
 #include <sys/types.h>
 #endif
 
-#if defined(__arm__) || defined(__mips__)
+#if defined(__arm__) || defined(__mips__) || defined(__avr32__)
 /* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
 typedef u_int   ioaddr_t;
 #else
index 8b88d0bedcbdeeb7bc08f3592bb3efdb0291c6bd..c5b354b1409e13e80d32e366b5a9844d9481e0d6 100644 (file)
@@ -215,6 +215,18 @@ config USER_NS
          vservers, to use user namespaces to provide different
          user info for different servers.  If unsure, say N.
 
+config PID_NS
+       bool "PID Namespaces (EXPERIMENTAL)"
+       default n
+       depends on EXPERIMENTAL
+       help
+         Suport process id namespaces.  This allows having multiple
+         process with the same pid as long as they are in different
+         pid namespaces.  This is a building block of containers.
+
+         Unless you want to work with an experimental feature
+         say N here.
+
 config AUDIT
        bool "Auditing support"
        depends on NET
@@ -301,13 +313,6 @@ config CGROUP_NS
           for instance virtual servers and checkpoint/restart
           jobs.
 
-config CGROUP_CPUACCT
-       bool "Simple CPU accounting cgroup subsystem"
-       depends on CGROUPS
-       help
-         Provides a simple Resource Controller for monitoring the
-         total CPU consumed by the tasks in a cgroup
-
 config CPUSETS
        bool "Cpuset support"
        depends on SMP && CGROUPS
index f605a969ea6141281891bb007edc41938c63e3f1..80b04b6c5157c85151669fdfe2864c16f876680e 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/device.h>
 #include <linux/kthread.h>
+#include <linux/sched.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -747,11 +748,8 @@ __setup("nosoftlockup", nosoftlockup_setup);
 static void __init do_pre_smp_initcalls(void)
 {
        extern int spawn_ksoftirqd(void);
-#ifdef CONFIG_SMP
-       extern int migration_init(void);
 
        migration_init();
-#endif
        spawn_ksoftirqd();
        if (!nosoftlockup)
                spawn_softlockup_task();
index bfa274ba9ed40267201bee1f6fc45c4d5a5f213b..1e04cd464af9b5ad961684dd358a97870bc36323 100644 (file)
@@ -1010,6 +1010,8 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
                        return -EINVAL;
                }
                if (notification.sigev_notify == SIGEV_THREAD) {
+                       long timeo;
+
                        /* create the notify skb */
                        nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
                        ret = -ENOMEM;
@@ -1038,8 +1040,8 @@ retry:
                                goto out;
                        }
 
-                       ret = netlink_attachskb(sock, nc, 0,
-                                       MAX_SCHEDULE_TIMEOUT, NULL);
+                       timeo = MAX_SCHEDULE_TIMEOUT;
+                       ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
                        if (ret == 1)
                                goto retry;
                        if (ret) {
index f60afe74259912d0f5c57d41736a812bd44eef2f..dfa96956dae0869c93f287b4c7348428eacaf8f3 100644 (file)
@@ -40,7 +40,6 @@ obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CGROUPS) += cgroup.o
 obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
-obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o
 obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
index 3fe21e19c96e3a51adfa6c462f188bdf6ca407b7..1a3c23936d43d99ec3d429123c95182a94de0c02 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  kernel/cgroup.c
- *
  *  Generic process-grouping system.
  *
  *  Based originally on the cpuset system, extracted by Paul Menage
@@ -2200,7 +2198,8 @@ static void cgroup_init_subsys(struct cgroup_subsys *ss)
 {
        struct cgroup_subsys_state *css;
        struct list_head *l;
-       printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name);
+
+       printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name);
 
        /* Create the top cgroup state for this subsystem */
        ss->root = &rootnode;
@@ -2273,7 +2272,7 @@ int __init cgroup_init_early(void)
                BUG_ON(!ss->create);
                BUG_ON(!ss->destroy);
                if (ss->subsys_id != i) {
-                       printk(KERN_ERR "Subsys %s id == %d\n",
+                       printk(KERN_ERR "cgroup: Subsys %s id == %d\n",
                               ss->name, ss->subsys_id);
                        BUG();
                }
@@ -2605,7 +2604,7 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
        dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename));
        if (IS_ERR(dentry)) {
                printk(KERN_INFO
-                      "Couldn't allocate dentry for %s: %ld\n", nodename,
+                      "cgroup: Couldn't allocate dentry for %s: %ld\n", nodename,
                       PTR_ERR(dentry));
                ret = PTR_ERR(dentry);
                goto out_release;
diff --git a/kernel/cpu_acct.c b/kernel/cpu_acct.c
deleted file mode 100644 (file)
index 731e47e..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * kernel/cpu_acct.c - CPU accounting cgroup subsystem
- *
- * Copyright (C) Google Inc, 2006
- *
- * Developed by Paul Menage (menage@google.com) and Balbir Singh
- * (balbir@in.ibm.com)
- *
- */
-
-/*
- * Example cgroup subsystem for reporting total CPU usage of tasks in a
- * cgroup, along with percentage load over a time interval
- */
-
-#include <linux/module.h>
-#include <linux/cgroup.h>
-#include <linux/fs.h>
-#include <linux/rcupdate.h>
-
-#include <asm/div64.h>
-
-struct cpuacct {
-       struct cgroup_subsys_state css;
-       spinlock_t lock;
-       /* total time used by this class */
-       cputime64_t time;
-
-       /* time when next load calculation occurs */
-       u64 next_interval_check;
-
-       /* time used in current period */
-       cputime64_t current_interval_time;
-
-       /* time used in last period */
-       cputime64_t last_interval_time;
-};
-
-struct cgroup_subsys cpuacct_subsys;
-
-static inline struct cpuacct *cgroup_ca(struct cgroup *cont)
-{
-       return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id),
-                           struct cpuacct, css);
-}
-
-static inline struct cpuacct *task_ca(struct task_struct *task)
-{
-       return container_of(task_subsys_state(task, cpuacct_subsys_id),
-                           struct cpuacct, css);
-}
-
-#define INTERVAL (HZ * 10)
-
-static inline u64 next_interval_boundary(u64 now)
-{
-       /* calculate the next interval boundary beyond the
-        * current time */
-       do_div(now, INTERVAL);
-       return (now + 1) * INTERVAL;
-}
-
-static struct cgroup_subsys_state *cpuacct_create(
-       struct cgroup_subsys *ss, struct cgroup *cont)
-{
-       struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
-
-       if (!ca)
-               return ERR_PTR(-ENOMEM);
-       spin_lock_init(&ca->lock);
-       ca->next_interval_check = next_interval_boundary(get_jiffies_64());
-       return &ca->css;
-}
-
-static void cpuacct_destroy(struct cgroup_subsys *ss,
-                           struct cgroup *cont)
-{
-       kfree(cgroup_ca(cont));
-}
-
-/* Lazily update the load calculation if necessary. Called with ca locked */
-static void cpuusage_update(struct cpuacct *ca)
-{
-       u64 now = get_jiffies_64();
-
-       /* If we're not due for an update, return */
-       if (ca->next_interval_check > now)
-               return;
-
-       if (ca->next_interval_check <= (now - INTERVAL)) {
-               /* If it's been more than an interval since the last
-                * check, then catch up - the last interval must have
-                * been zero load */
-               ca->last_interval_time = 0;
-               ca->next_interval_check = next_interval_boundary(now);
-       } else {
-               /* If a steal takes the last interval time negative,
-                * then we just ignore it */
-               if ((s64)ca->current_interval_time > 0)
-                       ca->last_interval_time = ca->current_interval_time;
-               else
-                       ca->last_interval_time = 0;
-               ca->next_interval_check += INTERVAL;
-       }
-       ca->current_interval_time = 0;
-}
-
-static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
-{
-       struct cpuacct *ca = cgroup_ca(cont);
-       u64 time;
-
-       spin_lock_irq(&ca->lock);
-       cpuusage_update(ca);
-       time = cputime64_to_jiffies64(ca->time);
-       spin_unlock_irq(&ca->lock);
-
-       /* Convert 64-bit jiffies to seconds */
-       time *= 1000;
-       do_div(time, HZ);
-       return time;
-}
-
-static u64 load_read(struct cgroup *cont, struct cftype *cft)
-{
-       struct cpuacct *ca = cgroup_ca(cont);
-       u64 time;
-
-       /* Find the time used in the previous interval */
-       spin_lock_irq(&ca->lock);
-       cpuusage_update(ca);
-       time = cputime64_to_jiffies64(ca->last_interval_time);
-       spin_unlock_irq(&ca->lock);
-
-       /* Convert time to a percentage, to give the load in the
-        * previous period */
-       time *= 100;
-       do_div(time, INTERVAL);
-
-       return time;
-}
-
-static struct cftype files[] = {
-       {
-               .name = "usage",
-               .read_uint = cpuusage_read,
-       },
-       {
-               .name = "load",
-               .read_uint = load_read,
-       }
-};
-
-static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont)
-{
-       return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
-}
-
-void cpuacct_charge(struct task_struct *task, cputime_t cputime)
-{
-
-       struct cpuacct *ca;
-       unsigned long flags;
-
-       if (!cpuacct_subsys.active)
-               return;
-       rcu_read_lock();
-       ca = task_ca(task);
-       if (ca) {
-               spin_lock_irqsave(&ca->lock, flags);
-               cpuusage_update(ca);
-               ca->time = cputime64_add(ca->time, cputime);
-               ca->current_interval_time =
-                       cputime64_add(ca->current_interval_time, cputime);
-               spin_unlock_irqrestore(&ca->lock, flags);
-       }
-       rcu_read_unlock();
-}
-
-struct cgroup_subsys cpuacct_subsys = {
-       .name = "cpuacct",
-       .create = cpuacct_create,
-       .destroy = cpuacct_destroy,
-       .populate = cpuacct_populate,
-       .subsys_id = cpuacct_subsys_id,
-};
index f1aec27f1df00eaae4cbb9c3f99dde1b4e1c8520..cd0f1d4137a734abb393a5ebc5a8534b2b8f882a 100644 (file)
@@ -1386,8 +1386,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
                int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
 
                exit_code = p->exit_code;
-               if (unlikely(!exit_code) ||
-                   unlikely(p->state & TASK_TRACED))
+               if (unlikely(!exit_code) || unlikely(p->exit_state))
                        goto bail_ref;
                return wait_noreap_copyout(p, pid, uid,
                                           why, (exit_code << 8) | 0x7f,
index 28a74015198899c3511f3daedbb2412c750c4fe4..8ca1a14cdc8c12ee8e592f7913f07f22dcec3d9b 100644 (file)
@@ -1123,6 +1123,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->blocked_on = NULL; /* not blocked yet */
 #endif
 
+       /* Perform scheduler related setup. Assign this task to a CPU. */
+       sched_fork(p, clone_flags);
+
        if ((retval = security_task_alloc(p)))
                goto bad_fork_cleanup_policy;
        if ((retval = audit_alloc(p)))
@@ -1212,9 +1215,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        INIT_LIST_HEAD(&p->ptrace_children);
        INIT_LIST_HEAD(&p->ptrace_list);
 
-       /* Perform scheduler related setup. Assign this task to a CPU. */
-       sched_fork(p, clone_flags);
-
        /* Now that the task is set up, run cgroup callbacks if
         * necessary. We need to run them before the task is visible
         * on the tasklist. */
index 32710451dc20ea7763cc22d02f0363c9155a772f..9dc591ab681a92c87209463e922f1a06e8d9bfa7 100644 (file)
@@ -181,8 +181,8 @@ static inline int match_futex(union futex_key *key1, union futex_key *key2)
  * For other futexes, it points to &current->mm->mmap_sem and
  * caller must have taken the reader lock. but NOT any spinlocks.
  */
-int get_futex_key(u32 __user *uaddr, struct rw_semaphore *fshared,
-                 union futex_key *key)
+static int get_futex_key(u32 __user *uaddr, struct rw_semaphore *fshared,
+                        union futex_key *key)
 {
        unsigned long address = (unsigned long)uaddr;
        struct mm_struct *mm = current->mm;
@@ -268,14 +268,13 @@ int get_futex_key(u32 __user *uaddr, struct rw_semaphore *fshared,
        }
        return err;
 }
-EXPORT_SYMBOL_GPL(get_futex_key);
 
 /*
  * Take a reference to the resource addressed by a key.
  * Can be called while holding spinlocks.
  *
  */
-inline void get_futex_key_refs(union futex_key *key)
+static void get_futex_key_refs(union futex_key *key)
 {
        if (key->both.ptr == 0)
                return;
@@ -288,13 +287,12 @@ inline void get_futex_key_refs(union futex_key *key)
                        break;
        }
 }
-EXPORT_SYMBOL_GPL(get_futex_key_refs);
 
 /*
  * Drop a reference to the resource addressed by a key.
  * The hash bucket spinlock must not be held.
  */
-void drop_futex_key_refs(union futex_key *key)
+static void drop_futex_key_refs(union futex_key *key)
 {
        if (!key->both.ptr)
                return;
@@ -307,7 +305,6 @@ void drop_futex_key_refs(union futex_key *key)
                        break;
        }
 }
-EXPORT_SYMBOL_GPL(drop_futex_key_refs);
 
 static u32 cmpxchg_futex_value_locked(u32 __user *uaddr, u32 uval, u32 newval)
 {
index 00b572666cc76178d81979f512dc9e3078b08fda..0a43def6fee7de877f43bdd0d7276efc05b8a48e 100644 (file)
@@ -30,6 +30,15 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
        return 0;
 }
 
+static void __user *futex_uaddr(struct robust_list *entry,
+                               compat_long_t futex_offset)
+{
+       compat_uptr_t base = ptr_to_compat(entry);
+       void __user *uaddr = compat_ptr(base + futex_offset);
+
+       return uaddr;
+}
+
 /*
  * Walk curr->robust_list (very carefully, it's a userspace list!)
  * and mark any locks found there dead, and notify any waiters.
@@ -76,11 +85,12 @@ void compat_exit_robust_list(struct task_struct *curr)
                 * A pending lock might already be on the list, so
                 * dont process it twice:
                 */
-               if (entry != pending)
-                       if (handle_futex_death((void __user *)entry + futex_offset,
-                                               curr, pi))
-                               return;
+               if (entry != pending) {
+                       void __user *uaddr = futex_uaddr(entry, futex_offset);
 
+                       if (handle_futex_death(uaddr, curr, pi))
+                               return;
+               }
                if (rc)
                        return;
                uentry = next_uentry;
@@ -94,9 +104,11 @@ void compat_exit_robust_list(struct task_struct *curr)
 
                cond_resched();
        }
-       if (pending)
-               handle_futex_death((void __user *)pending + futex_offset,
-                                  curr, pip);
+       if (pending) {
+               void __user *uaddr = futex_uaddr(pending, futex_offset);
+
+               handle_futex_death(uaddr, curr, pip);
+       }
 }
 
 asmlinkage long
index e391cbb1f56665e4f751706403d69bd3bd86c471..dc335ad27525f0019d475124322779d6c6ed5f09 100644 (file)
@@ -178,9 +178,11 @@ fastcall unsigned int __do_IRQ(unsigned int irq)
                 */
                if (desc->chip->ack)
                        desc->chip->ack(irq);
-               action_ret = handle_IRQ_event(irq, desc->action);
-               if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret);
+               if (likely(!(desc->status & IRQ_DISABLED))) {
+                       action_ret = handle_IRQ_event(irq, desc->action);
+                       if (!noirqdebug)
+                               note_interrupt(irq, desc, action_ret);
+               }
                desc->chip->end(irq);
                return 1;
        }
index ccb48d9a365718128c380018d4c936fc32fb2ef5..5323cfaedbce52f4cfbdb7bf6338ca368a64ac0b 100644 (file)
@@ -28,7 +28,7 @@ extern struct marker __start___markers[];
 extern struct marker __stop___markers[];
 
 /*
- * module_mutex nests inside markers_mutex. Markers mutex protects the builtin
+ * markers_mutex nests inside module_mutex. Markers mutex protects the builtin
  * and module markers, the hash table and deferred_sync.
  */
 static DEFINE_MUTEX(markers_mutex);
@@ -257,7 +257,6 @@ static void disable_marker(struct marker *elem)
  * @refcount: number of references left to the given probe_module (out)
  *
  * Updates the probe callback corresponding to a range of markers.
- * Must be called with markers_mutex held.
  */
 void marker_update_probe_range(struct marker *begin,
        struct marker *end, struct module *probe_module,
@@ -266,6 +265,7 @@ void marker_update_probe_range(struct marker *begin,
        struct marker *iter;
        struct marker_entry *mark_entry;
 
+       mutex_lock(&markers_mutex);
        for (iter = begin; iter < end; iter++) {
                mark_entry = get_marker(iter->name);
                if (mark_entry && mark_entry->refcount) {
@@ -281,6 +281,7 @@ void marker_update_probe_range(struct marker *begin,
                        disable_marker(iter);
                }
        }
+       mutex_unlock(&markers_mutex);
 }
 
 /*
@@ -293,7 +294,6 @@ static void marker_update_probes(struct module *probe_module)
 {
        int refcount = 0;
 
-       mutex_lock(&markers_mutex);
        /* Core kernel markers */
        marker_update_probe_range(__start___markers,
                        __stop___markers, probe_module, &refcount);
@@ -303,7 +303,6 @@ static void marker_update_probes(struct module *probe_module)
                synchronize_sched();
                deferred_sync = 0;
        }
-       mutex_unlock(&markers_mutex);
 }
 
 /**
@@ -320,7 +319,7 @@ int marker_probe_register(const char *name, const char *format,
                        marker_probe_func *probe, void *private)
 {
        struct marker_entry *entry;
-       int ret = 0, need_update = 0;
+       int ret = 0;
 
        mutex_lock(&markers_mutex);
        entry = get_marker(name);
@@ -335,11 +334,11 @@ int marker_probe_register(const char *name, const char *format,
        ret = add_marker(name, format, probe, private);
        if (ret)
                goto end;
-       need_update = 1;
+       mutex_unlock(&markers_mutex);
+       marker_update_probes(NULL);
+       return ret;
 end:
        mutex_unlock(&markers_mutex);
-       if (need_update)
-               marker_update_probes(NULL);
        return ret;
 }
 EXPORT_SYMBOL_GPL(marker_probe_register);
@@ -355,7 +354,6 @@ void *marker_probe_unregister(const char *name)
        struct module *probe_module;
        struct marker_entry *entry;
        void *private;
-       int need_update = 0;
 
        mutex_lock(&markers_mutex);
        entry = get_marker(name);
@@ -368,11 +366,11 @@ void *marker_probe_unregister(const char *name)
        probe_module = __module_text_address((unsigned long)entry->probe);
        private = remove_marker(name);
        deferred_sync = 1;
-       need_update = 1;
+       mutex_unlock(&markers_mutex);
+       marker_update_probes(probe_module);
+       return private;
 end:
        mutex_unlock(&markers_mutex);
-       if (need_update)
-               marker_update_probes(probe_module);
        return private;
 }
 EXPORT_SYMBOL_GPL(marker_probe_unregister);
@@ -392,7 +390,6 @@ void *marker_probe_unregister_private_data(void *private)
        struct marker_entry *entry;
        int found = 0;
        unsigned int i;
-       int need_update = 0;
 
        mutex_lock(&markers_mutex);
        for (i = 0; i < MARKER_TABLE_SIZE; i++) {
@@ -414,11 +411,11 @@ iter_end:
        probe_module = __module_text_address((unsigned long)entry->probe);
        private = remove_marker(entry->name);
        deferred_sync = 1;
-       need_update = 1;
+       mutex_unlock(&markers_mutex);
+       marker_update_probes(probe_module);
+       return private;
 end:
        mutex_unlock(&markers_mutex);
-       if (need_update)
-               marker_update_probes(probe_module);
        return private;
 }
 EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
@@ -434,7 +431,7 @@ EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
 int marker_arm(const char *name)
 {
        struct marker_entry *entry;
-       int ret = 0, need_update = 0;
+       int ret = 0;
 
        mutex_lock(&markers_mutex);
        entry = get_marker(name);
@@ -447,11 +444,9 @@ int marker_arm(const char *name)
         */
        if (entry->refcount++)
                goto end;
-       need_update = 1;
 end:
        mutex_unlock(&markers_mutex);
-       if (need_update)
-               marker_update_probes(NULL);
+       marker_update_probes(NULL);
        return ret;
 }
 EXPORT_SYMBOL_GPL(marker_arm);
@@ -467,7 +462,7 @@ EXPORT_SYMBOL_GPL(marker_arm);
 int marker_disarm(const char *name)
 {
        struct marker_entry *entry;
-       int ret = 0, need_update = 0;
+       int ret = 0;
 
        mutex_lock(&markers_mutex);
        entry = get_marker(name);
@@ -486,11 +481,9 @@ int marker_disarm(const char *name)
                ret = -EPERM;
                goto end;
        }
-       need_update = 1;
 end:
        mutex_unlock(&markers_mutex);
-       if (need_update)
-               marker_update_probes(NULL);
+       marker_update_probes(NULL);
        return ret;
 }
 EXPORT_SYMBOL_GPL(marker_disarm);
index 16f269e9ddc9b7d4ed129f98f0deac4965b87507..2a4c51487e7257e1865ae33d805a22e3dbb7f9ae 100644 (file)
@@ -592,19 +592,16 @@ static void __init param_sysfs_builtin(void)
 
        for (i=0; i < __stop___param - __start___param; i++) {
                char *dot;
-               size_t kplen;
+               size_t max_name_len;
 
                kp = &__start___param[i];
-               kplen = strlen(kp->name);
+               max_name_len =
+                       min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name));
 
-               /* We do not handle args without periods. */
-               if (kplen > MAX_KBUILD_MODNAME) {
-                       DEBUGP("kernel parameter name is too long: %s\n", kp->name);
-                       continue;
-               }
-               dot = memchr(kp->name, '.', kplen);
+               dot = memchr(kp->name, '.', max_name_len);
                if (!dot) {
-                       DEBUGP("couldn't find period in %s\n", kp->name);
+                       DEBUGP("couldn't find period in first %d characters "
+                              "of %s\n", MAX_KBUILD_MODNAME, kp->name);
                        continue;
                }
                name_len = dot - kp->name;
index d1db36b94674dbdc318845233b1804c659515740..f815455431bff3c95855a674086e6c1d8322a7c4 100644 (file)
@@ -537,6 +537,7 @@ err_alloc:
        return NULL;
 }
 
+#ifdef CONFIG_PID_NS
 static struct pid_namespace *create_pid_namespace(int level)
 {
        struct pid_namespace *ns;
@@ -621,6 +622,7 @@ void free_pid_ns(struct kref *kref)
        if (parent != NULL)
                put_pid_ns(parent);
 }
+#endif /* CONFIG_PID_NS */
 
 void zap_pid_ns_processes(struct pid_namespace *pid_ns)
 {
index 8b15f777010a9daefe2361adfbf5c1c0851dfb75..05b64790fe8391ed5189eee02144e5cf63f3fa2b 100644 (file)
@@ -456,7 +456,17 @@ static int software_resume(void)
        int error;
        unsigned int flags;
 
-       mutex_lock(&pm_mutex);
+       /*
+        * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
+        * is configured into the kernel. Since the regular hibernate
+        * trigger path is via sysfs which takes a buffer mutex before
+        * calling hibernate functions (which take pm_mutex) this can
+        * cause lockdep to complain about a possible ABBA deadlock
+        * which cannot happen since we're in the boot code here and
+        * sysfs can't be invoked yet. Therefore, we use a subclass
+        * here to avoid lockdep complaining.
+        */
+       mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING);
        if (!swsusp_resume_device) {
                if (!strlen(resume_file)) {
                        mutex_unlock(&pm_mutex);
index a358142ff48f34ca2dd0653f8bb1fc7c6f2c3fe0..2eb553d9b517153d8d938b34d60718b948b6bac0 100644 (file)
@@ -277,7 +277,7 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
        int ret = -1;
        res.start = (u64) start_pfn << PAGE_SHIFT;
        res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
-       res.flags = IORESOURCE_MEM;
+       res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        orig_end = res.end;
        while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
                pfn = (unsigned long)(res.start >> PAGE_SHIFT);
index 3f6bd1112900c9bcf5151d25a22b1d3d8dfda29c..38933cafea8abdf3042dde657798fbce7dc84c6e 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
-#include <linux/cpu_acct.h>
 #include <linux/kthread.h>
 #include <linux/seq_file.h>
 #include <linux/sysctl.h>
@@ -75,7 +74,7 @@
  */
 unsigned long long __attribute__((weak)) sched_clock(void)
 {
-       return (unsigned long long)jiffies * (1000000000 / HZ);
+       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
 }
 
 /*
@@ -99,8 +98,8 @@ unsigned long long __attribute__((weak)) sched_clock(void)
 /*
  * Some helpers for converting nanosecond timing to jiffy resolution
  */
-#define NS_TO_JIFFIES(TIME)    ((unsigned long)(TIME) / (1000000000 / HZ))
-#define JIFFIES_TO_NS(TIME)    ((TIME) * (1000000000 / HZ))
+#define NS_TO_JIFFIES(TIME)    ((unsigned long)(TIME) / (NSEC_PER_SEC / HZ))
+#define JIFFIES_TO_NS(TIME)    ((TIME) * (NSEC_PER_SEC / HZ))
 
 #define NICE_0_LOAD            SCHED_LOAD_SCALE
 #define NICE_0_SHIFT           SCHED_LOAD_SHIFT
@@ -217,15 +216,15 @@ static inline struct task_group *task_group(struct task_struct *p)
 }
 
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
-static inline void set_task_cfs_rq(struct task_struct *p)
+static inline void set_task_cfs_rq(struct task_struct *p, unsigned int cpu)
 {
-       p->se.cfs_rq = task_group(p)->cfs_rq[task_cpu(p)];
-       p->se.parent = task_group(p)->se[task_cpu(p)];
+       p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
+       p->se.parent = task_group(p)->se[cpu];
 }
 
 #else
 
-static inline void set_task_cfs_rq(struct task_struct *p) { }
+static inline void set_task_cfs_rq(struct task_struct *p, unsigned int cpu) { }
 
 #endif /* CONFIG_FAIR_GROUP_SCHED */
 
@@ -456,23 +455,27 @@ static void update_rq_clock(struct rq *rq)
  */
 enum {
        SCHED_FEAT_NEW_FAIR_SLEEPERS    = 1,
-       SCHED_FEAT_START_DEBIT          = 2,
-       SCHED_FEAT_TREE_AVG             = 4,
-       SCHED_FEAT_APPROX_AVG           = 8,
-       SCHED_FEAT_WAKEUP_PREEMPT       = 16,
-       SCHED_FEAT_PREEMPT_RESTRICT     = 32,
+       SCHED_FEAT_WAKEUP_PREEMPT       = 2,
+       SCHED_FEAT_START_DEBIT          = 4,
+       SCHED_FEAT_TREE_AVG             = 8,
+       SCHED_FEAT_APPROX_AVG           = 16,
 };
 
 const_debug unsigned int sysctl_sched_features =
                SCHED_FEAT_NEW_FAIR_SLEEPERS    * 1 |
+               SCHED_FEAT_WAKEUP_PREEMPT       * 1 |
                SCHED_FEAT_START_DEBIT          * 1 |
                SCHED_FEAT_TREE_AVG             * 0 |
-               SCHED_FEAT_APPROX_AVG           * 0 |
-               SCHED_FEAT_WAKEUP_PREEMPT       * 1 |
-               SCHED_FEAT_PREEMPT_RESTRICT     * 1;
+               SCHED_FEAT_APPROX_AVG           * 0;
 
 #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
 
+/*
+ * Number of tasks to iterate in a single balance run.
+ * Limited because this is done with IRQs disabled.
+ */
+const_debug unsigned int sysctl_sched_nr_migrate = 32;
+
 /*
  * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
  * clock constructed from sched_clock():
@@ -1019,10 +1022,16 @@ unsigned long weighted_cpuload(const int cpu)
 
 static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
 {
+       set_task_cfs_rq(p, cpu);
 #ifdef CONFIG_SMP
+       /*
+        * After ->cpu is set up to a new value, task_rq_lock(p, ...) can be
+        * successfuly executed on another CPU. We must ensure that updates of
+        * per-task data have been completed by this moment.
+        */
+       smp_wmb();
        task_thread_info(p)->cpu = cpu;
 #endif
-       set_task_cfs_rq(p);
 }
 
 #ifdef CONFIG_SMP
@@ -2237,7 +2246,7 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
              enum cpu_idle_type idle, int *all_pinned,
              int *this_best_prio, struct rq_iterator *iterator)
 {
-       int pulled = 0, pinned = 0, skip_for_load;
+       int loops = 0, pulled = 0, pinned = 0, skip_for_load;
        struct task_struct *p;
        long rem_load_move = max_load_move;
 
@@ -2251,10 +2260,10 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
         */
        p = iterator->start(iterator->arg);
 next:
-       if (!p)
+       if (!p || loops++ > sysctl_sched_nr_migrate)
                goto out;
        /*
-        * To help distribute high priority tasks accross CPUs we don't
+        * To help distribute high priority tasks across CPUs we don't
         * skip a task if it will be the highest priority task (i.e. smallest
         * prio value) on its new queue regardless of its load weight
         */
@@ -2271,8 +2280,7 @@ next:
        rem_load_move -= p->se.load.weight;
 
        /*
-        * We only want to steal up to the prescribed number of tasks
-        * and the prescribed amount of weighted load.
+        * We only want to steal up to the prescribed amount of weighted load.
         */
        if (rem_load_move > 0) {
                if (p->prio < *this_best_prio)
@@ -3335,13 +3343,9 @@ void account_user_time(struct task_struct *p, cputime_t cputime)
 {
        struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
        cputime64_t tmp;
-       struct rq *rq = this_rq();
 
        p->utime = cputime_add(p->utime, cputime);
 
-       if (p != rq->idle)
-               cpuacct_charge(p, cputime);
-
        /* Add user time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
        if (TASK_NICE(p) > 0)
@@ -3392,10 +3396,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
        struct rq *rq = this_rq();
        cputime64_t tmp;
 
-       if (p->flags & PF_VCPU) {
-               account_guest_time(p, cputime);
-               return;
-       }
+       if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0))
+               return account_guest_time(p, cputime);
 
        p->stime = cputime_add(p->stime, cputime);
 
@@ -3405,10 +3407,9 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
                cpustat->irq = cputime64_add(cpustat->irq, tmp);
        else if (softirq_count())
                cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
-       else if (p != rq->idle) {
+       else if (p != rq->idle)
                cpustat->system = cputime64_add(cpustat->system, tmp);
-               cpuacct_charge(p, cputime);
-       } else if (atomic_read(&rq->nr_iowait) > 0)
+       else if (atomic_read(&rq->nr_iowait) > 0)
                cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
        else
                cpustat->idle = cputime64_add(cpustat->idle, tmp);
@@ -3444,10 +3445,8 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
                        cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
                else
                        cpustat->idle = cputime64_add(cpustat->idle, tmp);
-       } else {
+       } else
                cpustat->steal = cputime64_add(cpustat->steal, tmp);
-               cpuacct_charge(p, -tmp);
-       }
 }
 
 /*
@@ -4992,6 +4991,32 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
  */
 cpumask_t nohz_cpu_mask = CPU_MASK_NONE;
 
+/*
+ * Increase the granularity value when there are more CPUs,
+ * because with more CPUs the 'effective latency' as visible
+ * to users decreases. But the relationship is not linear,
+ * so pick a second-best guess by going with the log2 of the
+ * number of CPUs.
+ *
+ * This idea comes from the SD scheduler of Con Kolivas:
+ */
+static inline void sched_init_granularity(void)
+{
+       unsigned int factor = 1 + ilog2(num_online_cpus());
+       const unsigned long limit = 200000000;
+
+       sysctl_sched_min_granularity *= factor;
+       if (sysctl_sched_min_granularity > limit)
+               sysctl_sched_min_granularity = limit;
+
+       sysctl_sched_latency *= factor;
+       if (sysctl_sched_latency > limit)
+               sysctl_sched_latency = limit;
+
+       sysctl_sched_wakeup_granularity *= factor;
+       sysctl_sched_batch_wakeup_granularity *= factor;
+}
+
 #ifdef CONFIG_SMP
 /*
  * This is how migration works:
@@ -5256,24 +5281,10 @@ static void migrate_live_tasks(int src_cpu)
        read_unlock(&tasklist_lock);
 }
 
-/*
- * activate_idle_task - move idle task to the _front_ of runqueue.
- */
-static void activate_idle_task(struct task_struct *p, struct rq *rq)
-{
-       update_rq_clock(rq);
-
-       if (p->state == TASK_UNINTERRUPTIBLE)
-               rq->nr_uninterruptible--;
-
-       enqueue_task(rq, p, 0);
-       inc_nr_running(p, rq);
-}
-
 /*
  * Schedules idle task to be the next runnable task on current CPU.
- * It does so by boosting its priority to highest possible and adding it to
- * the _front_ of the runqueue. Used by CPU offline code.
+ * It does so by boosting its priority to highest possible.
+ * Used by CPU offline code.
  */
 void sched_idle_next(void)
 {
@@ -5293,8 +5304,8 @@ void sched_idle_next(void)
 
        __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
 
-       /* Add idle task to the _front_ of its priority queue: */
-       activate_idle_task(p, rq);
+       update_rq_clock(rq);
+       activate_task(rq, p, 0);
 
        spin_unlock_irqrestore(&rq->lock, flags);
 }
@@ -5621,7 +5632,7 @@ static struct notifier_block __cpuinitdata migration_notifier = {
        .priority = 10
 };
 
-int __init migration_init(void)
+void __init migration_init(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
        int err;
@@ -5631,8 +5642,6 @@ int __init migration_init(void)
        BUG_ON(err == NOTIFY_BAD);
        migration_call(&migration_notifier, CPU_ONLINE, cpu);
        register_cpu_notifier(&migration_notifier);
-
-       return 0;
 }
 #endif
 
@@ -6688,10 +6697,12 @@ void __init sched_init_smp(void)
        /* Move init over to a non-isolated CPU */
        if (set_cpus_allowed(current, non_isolated_cpus) < 0)
                BUG();
+       sched_init_granularity();
 }
 #else
 void __init sched_init_smp(void)
 {
+       sched_init_granularity();
 }
 #endif /* CONFIG_SMP */
 
@@ -7068,8 +7079,10 @@ void sched_move_task(struct task_struct *tsk)
 
        rq = task_rq_lock(tsk, &flags);
 
-       if (tsk->sched_class != &fair_sched_class)
+       if (tsk->sched_class != &fair_sched_class) {
+               set_task_cfs_rq(tsk, task_cpu(tsk));
                goto done;
+       }
 
        update_rq_clock(rq);
 
@@ -7082,7 +7095,7 @@ void sched_move_task(struct task_struct *tsk)
                        tsk->sched_class->put_prev_task(rq, tsk);
        }
 
-       set_task_cfs_rq(tsk);
+       set_task_cfs_rq(tsk, task_cpu(tsk));
 
        if (on_rq) {
                if (unlikely(running))
@@ -7228,7 +7241,7 @@ static u64 cpu_usage_read(struct cgroup *cgrp, struct cftype *cft)
                spin_unlock_irqrestore(&cpu_rq(i)->lock, flags);
        }
        /* Convert from ns to ms */
-       do_div(res, 1000000);
+       do_div(res, NSEC_PER_MSEC);
 
        return res;
 }
index 415e5c38554217ed348f91d80f7f20eaebd01560..ca198a797bfab87691616f05da95c16912bd105b 100644 (file)
@@ -211,7 +211,7 @@ static int sched_debug_show(struct seq_file *m, void *v)
 #define PN(x) \
        SEQ_printf(m, "  .%-40s: %Ld.%06ld\n", #x, SPLIT_NS(x))
        PN(sysctl_sched_latency);
-       PN(sysctl_sched_nr_latency);
+       PN(sysctl_sched_min_granularity);
        PN(sysctl_sched_wakeup_granularity);
        PN(sysctl_sched_batch_wakeup_granularity);
        PN(sysctl_sched_child_runs_first);
index 01859f662ab7c834826f9197e93ebe9d44ad548a..ee00da284b1230233f0fb0c0d2028cb2579c441f 100644 (file)
@@ -22,7 +22,7 @@
 
 /*
  * Targeted preemption latency for CPU-bound tasks:
- * (default: 20ms, units: nanoseconds)
+ * (default: 20ms * ilog(ncpus), units: nanoseconds)
  *
  * NOTE: this latency value is not the same as the concept of
  * 'timeslice length' - timeslices in CFS are of variable length
  * (to see the precise effective timeslice length of your workload,
  *  run vmstat and monitor the context-switches (cs) field)
  */
-const_debug unsigned int sysctl_sched_latency = 20000000ULL;
+unsigned int sysctl_sched_latency = 20000000ULL;
 
 /*
- * After fork, child runs first. (default) If set to 0 then
- * parent will (try to) run first.
+ * Minimal preemption granularity for CPU-bound tasks:
+ * (default: 1 msec * ilog(ncpus), units: nanoseconds)
  */
-const_debug unsigned int sysctl_sched_child_runs_first = 1;
+unsigned int sysctl_sched_min_granularity = 1000000ULL;
 
 /*
- * Minimal preemption granularity for CPU-bound tasks:
- * (default: 2 msec, units: nanoseconds)
+ * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
+ */
+static unsigned int sched_nr_latency = 20;
+
+/*
+ * After fork, child runs first. (default) If set to 0 then
+ * parent will (try to) run first.
  */
-const_debug unsigned int sysctl_sched_nr_latency = 20;
+const_debug unsigned int sysctl_sched_child_runs_first = 1;
 
 /*
  * sys_sched_yield() compat mode
@@ -56,23 +61,23 @@ unsigned int __read_mostly sysctl_sched_compat_yield;
 
 /*
  * SCHED_BATCH wake-up granularity.
- * (default: 10 msec, units: nanoseconds)
+ * (default: 10 msec * ilog(ncpus), units: nanoseconds)
  *
  * This option delays the preemption effects of decoupled workloads
  * and reduces their over-scheduling. Synchronous workloads will still
  * have immediate wakeup/sleep latencies.
  */
-const_debug unsigned int sysctl_sched_batch_wakeup_granularity = 10000000UL;
+unsigned int sysctl_sched_batch_wakeup_granularity = 10000000UL;
 
 /*
  * SCHED_OTHER wake-up granularity.
- * (default: 10 msec, units: nanoseconds)
+ * (default: 10 msec * ilog(ncpus), units: nanoseconds)
  *
  * This option delays the preemption effects of decoupled workloads
  * and reduces their over-scheduling. Synchronous workloads will still
  * have immediate wakeup/sleep latencies.
  */
-const_debug unsigned int sysctl_sched_wakeup_granularity = 10000000UL;
+unsigned int sysctl_sched_wakeup_granularity = 10000000UL;
 
 const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
 
@@ -212,6 +217,22 @@ static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
  * Scheduling class statistics methods:
  */
 
+#ifdef CONFIG_SCHED_DEBUG
+int sched_nr_latency_handler(struct ctl_table *table, int write,
+               struct file *filp, void __user *buffer, size_t *lenp,
+               loff_t *ppos)
+{
+       int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+
+       if (ret || !write)
+               return ret;
+
+       sched_nr_latency = DIV_ROUND_UP(sysctl_sched_latency,
+                                       sysctl_sched_min_granularity);
+
+       return 0;
+}
+#endif
 
 /*
  * The idea is to set a period in which each task runs once.
@@ -224,7 +245,7 @@ static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
 static u64 __sched_period(unsigned long nr_running)
 {
        u64 period = sysctl_sched_latency;
-       unsigned long nr_latency = sysctl_sched_nr_latency;
+       unsigned long nr_latency = sched_nr_latency;
 
        if (unlikely(nr_running > nr_latency)) {
                period *= nr_running;
@@ -259,6 +280,7 @@ static u64 __sched_vslice(unsigned long rq_weight, unsigned long nr_running)
 {
        u64 vslice = __sched_period(nr_running);
 
+       vslice *= NICE_0_LOAD;
        do_div(vslice, rq_weight);
 
        return vslice;
@@ -472,19 +494,26 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
        } else if (sched_feat(APPROX_AVG) && cfs_rq->nr_running)
                vruntime += sched_vslice(cfs_rq)/2;
 
+       /*
+        * The 'current' period is already promised to the current tasks,
+        * however the extra weight of the new task will slow them down a
+        * little, place the new task so that it fits in the slot that
+        * stays open at the end.
+        */
        if (initial && sched_feat(START_DEBIT))
                vruntime += sched_vslice_add(cfs_rq, se);
 
        if (!initial) {
+               /* sleeps upto a single latency don't count. */
                if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se) &&
                                task_of(se)->policy != SCHED_BATCH)
                        vruntime -= sysctl_sched_latency;
 
-               vruntime = max_t(s64, vruntime, se->vruntime);
+               /* ensure we never gain time by being placed backwards. */
+               vruntime = max_vruntime(se->vruntime, vruntime);
        }
 
        se->vruntime = vruntime;
-
 }
 
 static void
@@ -517,7 +546,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
 
        update_stats_dequeue(cfs_rq, se);
        if (sleep) {
-               se->peer_preempt = 0;
 #ifdef CONFIG_SCHEDSTATS
                if (entity_is_task(se)) {
                        struct task_struct *tsk = task_of(se);
@@ -545,10 +573,8 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 
        ideal_runtime = sched_slice(cfs_rq, curr);
        delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
-       if (delta_exec > ideal_runtime ||
-                       (sched_feat(PREEMPT_RESTRICT) && curr->peer_preempt))
+       if (delta_exec > ideal_runtime)
                resched_task(rq_of(cfs_rq)->curr);
-       curr->peer_preempt = 0;
 }
 
 static void
@@ -811,7 +837,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
        struct task_struct *curr = rq->curr;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
        struct sched_entity *se = &curr->se, *pse = &p->se;
-       s64 delta, gran;
+       unsigned long gran;
 
        if (unlikely(rt_prio(p->prio))) {
                update_rq_clock(rq);
@@ -826,24 +852,20 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
        if (unlikely(p->policy == SCHED_BATCH))
                return;
 
-       if (sched_feat(WAKEUP_PREEMPT)) {
-               while (!is_same_group(se, pse)) {
-                       se = parent_entity(se);
-                       pse = parent_entity(pse);
-               }
+       if (!sched_feat(WAKEUP_PREEMPT))
+               return;
 
-               delta = se->vruntime - pse->vruntime;
-               gran = sysctl_sched_wakeup_granularity;
-               if (unlikely(se->load.weight != NICE_0_LOAD))
-                       gran = calc_delta_fair(gran, &se->load);
+       while (!is_same_group(se, pse)) {
+               se = parent_entity(se);
+               pse = parent_entity(pse);
+       }
 
-               if (delta > gran) {
-                       int now = !sched_feat(PREEMPT_RESTRICT);
+       gran = sysctl_sched_wakeup_granularity;
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               gran = calc_delta_fair(gran, &se->load);
 
-                       if (now || p->prio < curr->prio || !se->peer_preempt++)
-                               resched_task(curr);
-               }
-       }
+       if (pse->vruntime + gran < se->vruntime)
+               resched_task(curr);
 }
 
 static struct task_struct *pick_next_task_fair(struct rq *rq)
@@ -1045,8 +1067,9 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
        update_curr(cfs_rq);
        place_entity(cfs_rq, se, 1);
 
+       /* 'curr' will be NULL if the child belongs to a different group */
        if (sysctl_sched_child_runs_first && this_cpu == task_cpu(p) &&
-                       curr->vruntime < se->vruntime) {
+                       curr && curr->vruntime < se->vruntime) {
                /*
                 * Upon rescheduling, sched_class::put_prev_task() will place
                 * 'current' within the tree based on its new key value.
@@ -1054,7 +1077,6 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
                swap(curr->vruntime, se->vruntime);
        }
 
-       se->peer_preempt = 0;
        enqueue_task_fair(rq, p, 0);
        resched_task(rq->curr);
 }
index ef1a7df80ea21257ab141a3ef57142bad9ab47ae..630178e53bb6210d156ee94f9f9c4f3e96e473dd 100644 (file)
@@ -127,7 +127,7 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta)
 # define schedstat_set(var, val)       do { } while (0)
 #endif
 
-#ifdef CONFIG_SCHEDSTATS
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 /*
  * Called when a process is dequeued from the active array and given
  * the cpu.  We should note that with the exception of interactive
@@ -155,7 +155,7 @@ static inline void sched_info_dequeued(struct task_struct *t)
  */
 static void sched_info_arrive(struct task_struct *t)
 {
-       unsigned long long now = sched_clock(), delta = 0;
+       unsigned long long now = task_rq(t)->clock, delta = 0;
 
        if (t->sched_info.last_queued)
                delta = now - t->sched_info.last_queued;
@@ -186,7 +186,7 @@ static inline void sched_info_queued(struct task_struct *t)
 {
        if (unlikely(sched_info_on()))
                if (!t->sched_info.last_queued)
-                       t->sched_info.last_queued = sched_clock();
+                       t->sched_info.last_queued = task_rq(t)->clock;
 }
 
 /*
@@ -195,7 +195,8 @@ static inline void sched_info_queued(struct task_struct *t)
  */
 static inline void sched_info_depart(struct task_struct *t)
 {
-       unsigned long long delta = sched_clock() - t->sched_info.last_arrival;
+       unsigned long long delta = task_rq(t)->clock -
+                                       t->sched_info.last_arrival;
 
        t->sched_info.cpu_time += delta;
        rq_sched_info_depart(task_rq(t), delta);
@@ -231,5 +232,5 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
 #else
 #define sched_info_queued(t)           do { } while (0)
 #define sched_info_switch(t, next)     do { } while (0)
-#endif /* CONFIG_SCHEDSTATS */
+#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
 
index 909a0cc6bc70a3078f3e41a1e42b94a28cd9ae6e..afa4f781f924999086c3fe2f34530e1ee84b6496 100644 (file)
@@ -55,7 +55,7 @@ static int sig_ignored(struct task_struct *t, int sig)
         * signal handler may change by the time it is
         * unblocked.
         */
-       if (sigismember(&t->blocked, sig))
+       if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
                return 0;
 
        /* Is it explicitly or implicitly ignored? */
index 304b5410d746ec724afcb4e3ce50bfe65f1bf2ff..d1fe71eb45469bc99f23cfe9aee83a8cbecc81b1 100644 (file)
@@ -1750,7 +1750,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
 }
 
 asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
-                          struct getcpu_cache __user *cache)
+                          struct getcpu_cache __user *unused)
 {
        int err = 0;
        int cpu = raw_smp_processor_id();
@@ -1758,24 +1758,6 @@ asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
                err |= put_user(cpu, cpup);
        if (nodep)
                err |= put_user(cpu_to_node(cpu), nodep);
-       if (cache) {
-               /*
-                * The cache is not needed for this implementation,
-                * but make sure user programs pass something
-                * valid. vsyscall implementations can instead make
-                * good use of the cache. Only use t0 and t1 because
-                * these are available in both 32bit and 64bit ABI (no
-                * need for a compat_getcpu). 32bit has enough
-                * padding
-                */
-               unsigned long t0, t1;
-               get_user(t0, &cache->blob[0]);
-               get_user(t1, &cache->blob[1]);
-               t0++;
-               t1++;
-               put_user(t0, &cache->blob[0]);
-               put_user(t1, &cache->blob[1]);
-       }
        return err ? -EFAULT : 0;
 }
 
index 3b4efbe2644572a32576b1a591f003e9869699f0..0deed82a61568d6660a7f4ee625c490ffecffcc5 100644 (file)
@@ -226,20 +226,23 @@ static struct ctl_table root_table[] = {
 
 #ifdef CONFIG_SCHED_DEBUG
 static unsigned long min_sched_granularity_ns = 100000;                /* 100 usecs */
-static unsigned long max_sched_granularity_ns = 1000000000;    /* 1 second */
+static unsigned long max_sched_granularity_ns = NSEC_PER_SEC;  /* 1 second */
 static unsigned long min_wakeup_granularity_ns;                        /* 0 usecs */
-static unsigned long max_wakeup_granularity_ns = 1000000000;   /* 1 second */
+static unsigned long max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
 #endif
 
 static struct ctl_table kern_table[] = {
 #ifdef CONFIG_SCHED_DEBUG
        {
                .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "sched_nr_latency",
-               .data           = &sysctl_sched_nr_latency,
+               .procname       = "sched_min_granularity_ns",
+               .data           = &sysctl_sched_min_granularity,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &sched_nr_latency_handler,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_sched_granularity_ns,
+               .extra2         = &max_sched_granularity_ns,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -247,7 +250,7 @@ static struct ctl_table kern_table[] = {
                .data           = &sysctl_sched_latency,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
+               .proc_handler   = &sched_nr_latency_handler,
                .strategy       = &sysctl_intvec,
                .extra1         = &min_sched_granularity_ns,
                .extra2         = &max_sched_granularity_ns,
@@ -298,6 +301,14 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_nr_migrate",
+               .data           = &sysctl_sched_nr_migrate,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 644,
+               .proc_handler   = &proc_dointvec,
+       },
 #endif
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -2609,6 +2620,10 @@ static int deprecated_sysctl_warning(struct __sysctl_args *args)
        int name[CTL_MAXNAME];
        int i;
 
+       /* Check args->nlen. */
+       if (args->nlen < 0 || args->nlen > CTL_MAXNAME)
+               return -ENOTDIR;
+
        /* Read in the sysctl name for better debug message logging */
        for (i = 0; i < args->nlen; i++)
                if (get_user(name[i], args->name + i))
index ed6fe51df77ab53c5960df8b53024ae75120f3b2..4abc6d2306f451e8da9141e753b7b517045edda6 100644 (file)
@@ -738,7 +738,7 @@ static struct trans_ctl_table trans_net_table[] = {
        { NET_ROSE,             "rose",         trans_net_rose_table },
        { NET_IPV6,             "ipv6",         trans_net_ipv6_table },
        { NET_X25,              "x25",          trans_net_x25_table },
-       { NET_TR,               "tr",           trans_net_tr_table },
+       { NET_TR,               "token-ring",   trans_net_tr_table },
        { NET_DECNET,           "decnet",       trans_net_decnet_table },
        /*  NET_ECONET not used */
        { NET_SCTP,             "sctp",         trans_net_sctp_table },
@@ -1432,6 +1432,7 @@ static void set_fail(const char **fail, struct ctl_table *table, const char *str
                printk(KERN_ERR "sysctl table check failed: ");
                sysctl_print_path(table);
                printk(" %s\n", *fail);
+               dump_stack();
        }
        *fail = str;
 }
index 354e74bc17c186099b50edd9471b7f6163ce2c62..07e86a828073bc7ebffdcdb67c3ee726be9a5705 100644 (file)
@@ -398,31 +398,31 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
 
        fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
        file = fget_light(fd, &fput_needed);
-       if (file) {
-               size = nla_total_size(sizeof(struct cgroupstats));
+       if (!file)
+               return 0;
 
-               rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
-                                       size);
-               if (rc < 0)
-                       goto err;
+       size = nla_total_size(sizeof(struct cgroupstats));
 
-               na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
-                                       sizeof(struct cgroupstats));
-               stats = nla_data(na);
-               memset(stats, 0, sizeof(*stats));
+       rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
+                               size);
+       if (rc < 0)
+               goto err;
 
-               rc = cgroupstats_build(stats, file->f_dentry);
-               if (rc < 0)
-                       goto err;
+       na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
+                               sizeof(struct cgroupstats));
+       stats = nla_data(na);
+       memset(stats, 0, sizeof(*stats));
 
-               fput_light(file, fput_needed);
-               return send_reply(rep_skb, info->snd_pid);
+       rc = cgroupstats_build(stats, file->f_dentry);
+       if (rc < 0) {
+               nlmsg_free(rep_skb);
+               goto err;
        }
 
+       rc = send_reply(rep_skb, info->snd_pid);
+
 err:
-       if (file)
-               fput_light(file, fput_needed);
-       nlmsg_free(rep_skb);
+       fput_light(file, fput_needed);
        return rc;
 }
 
index de6a2d6b3ebb69ad65f1491e9f44a846e1b86f44..14a2ecf2b318f82bd87d22031da05738e3773fd4 100644 (file)
@@ -205,7 +205,7 @@ static void sync_cmos_clock(unsigned long dummy)
                return;
 
        getnstimeofday(&now);
-       if (abs(xtime.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
+       if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
                fail = update_persistent_clock(now);
 
        next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
index 8cfb8b2ce773ed4838b3bb4c699b22c4c34423c7..aa82d7bf478a7adc8eb34700b3a5b540e672b28d 100644 (file)
@@ -508,7 +508,7 @@ static void tick_broadcast_clear_oneshot(int cpu)
 }
 
 /**
- * tick_broadcast_setup_highres - setup the broadcast device for highres
+ * tick_broadcast_setup_oneshot - setup the broadcast device
  */
 void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
index 5997456ebbc913f30d922587feb0c0d9818e62f6..27a2338deb4ae32d12dd0789a63503666d8e66c1 100644 (file)
@@ -321,7 +321,7 @@ ktime_t tick_nohz_get_sleep_length(void)
 }
 
 /**
- * nohz_restart_sched_tick - restart the idle tick from the idle task
+ * tick_nohz_restart_sched_tick - restart the idle tick from the idle task
  *
  * Restart the idle tick when the CPU is woken up from idle
  */
index fb4e67d5dd6032eab811202526a194aa004523ad..a05817c021d62c1f93819ee666f2fc5bdb735f6a 100644 (file)
@@ -790,7 +790,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
 }
 
 /**
- * next_timer_interrupt - return the jiffy of the next pending timer
+ * get_next_timer_interrupt - return the jiffy of the next pending timer
  * @now: current time (in jiffies)
  */
 unsigned long get_next_timer_interrupt(unsigned long now)
@@ -817,6 +817,19 @@ unsigned long next_timer_interrupt(void)
 
 #endif
 
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+void account_process_tick(struct task_struct *p, int user_tick)
+{
+       if (user_tick) {
+               account_user_time(p, jiffies_to_cputime(1));
+               account_user_time_scaled(p, jiffies_to_cputime(1));
+       } else {
+               account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+               account_system_time_scaled(p, jiffies_to_cputime(1));
+       }
+}
+#endif
+
 /*
  * Called from the timer interrupt handler to charge one tick to the current
  * process.  user_tick is 1 if the tick is user time, 0 for system.
@@ -827,13 +840,7 @@ void update_process_times(int user_tick)
        int cpu = smp_processor_id();
 
        /* Note: this timer irq context must be accounted for as well. */
-       if (user_tick) {
-               account_user_time(p, jiffies_to_cputime(1));
-               account_user_time_scaled(p, jiffies_to_cputime(1));
-       } else {
-               account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
-               account_system_time_scaled(p, jiffies_to_cputime(1));
-       }
+       account_process_tick(p, user_tick);
        run_local_timers();
        if (rcu_pending(cpu))
                rcu_check_callbacks(cpu, user_tick);
index 3a0983b77412cdc6b0336bb0e3e1f539ddc2d0cd..b6793ed28d849031ac43f3c4ebc73df7e7b294dd 100644 (file)
@@ -4,7 +4,7 @@
 
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o \
-        idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
+        idr.o int_sqrt.o extable.o prio_tree.o \
         sha1.o irq_regs.o reciprocal_div.o argv_split.o \
         proportions.o prio_heap.o
 
@@ -14,7 +14,7 @@ lib-$(CONFIG_SMP) += cpumask.o
 lib-y  += kobject.o kref.o klist.o
 
 obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
-        bust_spinlocks.o hexdump.o kasprintf.o
+        bust_spinlocks.o hexdump.o kasprintf.o bitmap.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
index 26ebafa8c41d7e0ff602c0d2137a8ea284bb1ae5..2c9242e3fed01ca348b4171db2c0d89333fa357e 100644 (file)
@@ -469,6 +469,10 @@ int bitmap_scnlistprintf(char *buf, unsigned int buflen,
        /* current bit is 'cur', most recently seen range is [rbot, rtop] */
        int cur, rbot, rtop;
 
+       if (buflen == 0)
+               return 0;
+       buf[0] = 0;
+
        rbot = cur = find_first_bit(maskp, nmaskbits);
        while (cur < nmaskbits) {
                rtop = cur;
index 802f11f0bf5baebf99460c1e4d238921764fab93..b5c3287d8ea47567220cbafd2211dd12b5239356 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/crc32c.h>
 #include <linux/compiler.h>
 #include <linux/module.h>
-#include <asm/byteorder.h>
 
 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
@@ -161,15 +160,13 @@ static const u32 crc32c_table[256] = {
  */
 
 u32 __pure
-crc32c_le(u32 seed, unsigned char const *data, size_t length)
+crc32c_le(u32 crc, unsigned char const *data, size_t length)
 {
-       u32 crc = __cpu_to_le32(seed);
-       
        while (length--)
                crc =
                    crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
 
-       return __le32_to_cpu(crc);
+       return crc;
 }
 
 #endif /* CRC_LE_BITS == 8 */
index 8b809ecefa39e4b54f4bfbed8830009a9e260e96..6121b57bbe966735a6c44ae1f77854f2cec7c74b 100644 (file)
@@ -116,7 +116,9 @@ static void update_and_free_page(struct page *page)
 static void free_huge_page(struct page *page)
 {
        int nid = page_to_nid(page);
+       struct address_space *mapping;
 
+       mapping = (struct address_space *) page_private(page);
        BUG_ON(page_count(page));
        INIT_LIST_HEAD(&page->lru);
 
@@ -129,6 +131,9 @@ static void free_huge_page(struct page *page)
                enqueue_huge_page(page);
        }
        spin_unlock(&hugetlb_lock);
+       if (mapping)
+               hugetlb_put_quota(mapping, 1);
+       set_page_private(page, 0);
 }
 
 /*
@@ -323,7 +328,7 @@ free:
  * allocated to satisfy the reservation must be explicitly freed if they were
  * never used.
  */
-void return_unused_surplus_pages(unsigned long unused_resv_pages)
+static void return_unused_surplus_pages(unsigned long unused_resv_pages)
 {
        static int nid = -1;
        struct page *page;
@@ -353,35 +358,50 @@ void return_unused_surplus_pages(unsigned long unused_resv_pages)
        }
 }
 
-static struct page *alloc_huge_page(struct vm_area_struct *vma,
-                                   unsigned long addr)
+
+static struct page *alloc_huge_page_shared(struct vm_area_struct *vma,
+                                               unsigned long addr)
 {
-       struct page *page = NULL;
-       int use_reserved_page = vma->vm_flags & VM_MAYSHARE;
+       struct page *page;
 
        spin_lock(&hugetlb_lock);
-       if (!use_reserved_page && (free_huge_pages <= resv_huge_pages))
-               goto fail;
-
        page = dequeue_huge_page(vma, addr);
-       if (!page)
-               goto fail;
-
        spin_unlock(&hugetlb_lock);
-       set_page_refcounted(page);
-       return page;
+       return page ? page : ERR_PTR(-VM_FAULT_OOM);
+}
 
-fail:
-       spin_unlock(&hugetlb_lock);
+static struct page *alloc_huge_page_private(struct vm_area_struct *vma,
+                                               unsigned long addr)
+{
+       struct page *page = NULL;
 
-       /*
-        * Private mappings do not use reserved huge pages so the allocation
-        * may have failed due to an undersized hugetlb pool.  Try to grab a
-        * surplus huge page from the buddy allocator.
-        */
-       if (!use_reserved_page)
+       if (hugetlb_get_quota(vma->vm_file->f_mapping, 1))
+               return ERR_PTR(-VM_FAULT_SIGBUS);
+
+       spin_lock(&hugetlb_lock);
+       if (free_huge_pages > resv_huge_pages)
+               page = dequeue_huge_page(vma, addr);
+       spin_unlock(&hugetlb_lock);
+       if (!page)
                page = alloc_buddy_huge_page(vma, addr);
+       return page ? page : ERR_PTR(-VM_FAULT_OOM);
+}
+
+static struct page *alloc_huge_page(struct vm_area_struct *vma,
+                                   unsigned long addr)
+{
+       struct page *page;
+       struct address_space *mapping = vma->vm_file->f_mapping;
 
+       if (vma->vm_flags & VM_MAYSHARE)
+               page = alloc_huge_page_shared(vma, addr);
+       else
+               page = alloc_huge_page_private(vma, addr);
+
+       if (!IS_ERR(page)) {
+               set_page_refcounted(page);
+               set_page_private(page, (unsigned long) mapping);
+       }
        return page;
 }
 
@@ -726,9 +746,9 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
        page_cache_get(old_page);
        new_page = alloc_huge_page(vma, address);
 
-       if (!new_page) {
+       if (IS_ERR(new_page)) {
                page_cache_release(old_page);
-               return VM_FAULT_OOM;
+               return -PTR_ERR(new_page);
        }
 
        spin_unlock(&mm->page_table_lock);
@@ -772,27 +792,28 @@ retry:
                size = i_size_read(mapping->host) >> HPAGE_SHIFT;
                if (idx >= size)
                        goto out;
-               if (hugetlb_get_quota(mapping))
-                       goto out;
                page = alloc_huge_page(vma, address);
-               if (!page) {
-                       hugetlb_put_quota(mapping);
-                       ret = VM_FAULT_OOM;
+               if (IS_ERR(page)) {
+                       ret = -PTR_ERR(page);
                        goto out;
                }
                clear_huge_page(page, address);
 
                if (vma->vm_flags & VM_SHARED) {
                        int err;
+                       struct inode *inode = mapping->host;
 
                        err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
                        if (err) {
                                put_page(page);
-                               hugetlb_put_quota(mapping);
                                if (err == -EEXIST)
                                        goto retry;
                                goto out;
                        }
+
+                       spin_lock(&inode->i_lock);
+                       inode->i_blocks += BLOCKS_PER_HUGEPAGE;
+                       spin_unlock(&inode->i_lock);
                } else
                        lock_page(page);
        }
@@ -822,7 +843,6 @@ out:
 
 backout:
        spin_unlock(&mm->page_table_lock);
-       hugetlb_put_quota(mapping);
        unlock_page(page);
        put_page(page);
        goto out;
@@ -868,7 +888,8 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 
 int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                        struct page **pages, struct vm_area_struct **vmas,
-                       unsigned long *position, int *length, int i)
+                       unsigned long *position, int *length, int i,
+                       int write)
 {
        unsigned long pfn_offset;
        unsigned long vaddr = *position;
@@ -890,7 +911,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                        int ret;
 
                        spin_unlock(&mm->page_table_lock);
-                       ret = hugetlb_fault(mm, vma, vaddr, 0);
+                       ret = hugetlb_fault(mm, vma, vaddr, write);
                        spin_lock(&mm->page_table_lock);
                        if (!(ret & VM_FAULT_ERROR))
                                continue;
@@ -1132,6 +1153,8 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
        if (chg < 0)
                return chg;
 
+       if (hugetlb_get_quota(inode->i_mapping, chg))
+               return -ENOSPC;
        ret = hugetlb_acct_memory(chg);
        if (ret < 0)
                return ret;
@@ -1142,5 +1165,11 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
 void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed)
 {
        long chg = region_truncate(&inode->i_mapping->private_list, offset);
-       hugetlb_acct_memory(freed - chg);
+
+       spin_lock(&inode->i_lock);
+       inode->i_blocks -= BLOCKS_PER_HUGEPAGE * freed;
+       spin_unlock(&inode->i_lock);
+
+       hugetlb_put_quota(inode->i_mapping, (chg - freed));
+       hugetlb_acct_memory(-(chg - freed));
 }
index eefd5b68bc42d76768e773a43ae310806c9fa17c..4bf0b6d0eb2a675bbd1083099448d54979dff304 100644 (file)
@@ -1036,7 +1036,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
                if (is_vm_hugetlb_page(vma)) {
                        i = follow_hugetlb_page(mm, vma, pages, vmas,
-                                               &start, &len, i);
+                                               &start, &len, i, write);
                        continue;
                }
 
@@ -2084,9 +2084,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
                count_vm_event(PGMAJFAULT);
        }
 
-       delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
        mark_page_accessed(page);
        lock_page(page);
+       delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 
        /*
         * Back out if somebody else already faulted in this pte.
@@ -2748,4 +2748,3 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
 
        return buf - old_buf;
 }
-EXPORT_SYMBOL_GPL(access_process_vm);
index 3a47871a29d909c561a4371f6afca71f59689126..9512a544d0449ebcb789de665d9e8fc8ee0fdc8b 100644 (file)
@@ -39,7 +39,7 @@ static struct resource *register_memory_resource(u64 start, u64 size)
        res->name = "System RAM";
        res->start = start;
        res->end = start + size - 1;
-       res->flags = IORESOURCE_MEM;
+       res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        if (request_resource(&iomem_resource, res) < 0) {
                printk("System RAM resource %llx - %llx cannot be added\n",
                (unsigned long long)res->start, (unsigned long long)res->end);
@@ -574,8 +574,8 @@ repeat:
        /* Ok, all of our target is islaoted.
           We cannot do rollback at this point. */
        offline_isolated_pages(start_pfn, end_pfn);
-       /* reset pagetype flags */
-       start_isolate_page_range(start_pfn, end_pfn);
+       /* reset pagetype flags and makes migrate type to be MOVABLE */
+       undo_isolate_page_range(start_pfn, end_pfn);
        /* removal success */
        zone->present_pages -= offlined_pages;
        zone->zone_pgdat->node_present_pages -= offlined_pages;
index c1592a94582f8c2950a6a4cf34711f02a35066c6..83c69f8a64c29dd0878050b3912e5f0c2b1af3ac 100644 (file)
@@ -722,12 +722,29 @@ out:
 
 }
 
+/*
+ * Allocate a new page for page migration based on vma policy.
+ * Start assuming that page is mapped by vma pointed to by @private.
+ * Search forward from there, if not.  N.B., this assumes that the
+ * list of pages handed to migrate_pages()--which is how we get here--
+ * is in virtual address order.
+ */
 static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
 {
        struct vm_area_struct *vma = (struct vm_area_struct *)private;
+       unsigned long uninitialized_var(address);
 
-       return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
-                                       page_address_in_vma(page, vma));
+       while (vma) {
+               address = page_address_in_vma(page, vma);
+               if (address != -EFAULT)
+                       break;
+               vma = vma->vm_next;
+       }
+
+       /*
+        * if !vma, alloc_page_vma() will use task or system default policy
+        */
+       return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
 }
 #else
 
index 838a5e31394cbbbe0e9a34b66e1570cf03b5bb86..d55cfcae2ef1fea2082d28173dd2f94e1e6666ce 100644 (file)
@@ -297,20 +297,12 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
 {
        int background_ratio;           /* Percentages */
        int dirty_ratio;
-       int unmapped_ratio;
        long background;
        long dirty;
        unsigned long available_memory = determine_dirtyable_memory();
        struct task_struct *tsk;
 
-       unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
-                               global_page_state(NR_ANON_PAGES)) * 100) /
-                                       available_memory;
-
        dirty_ratio = vm_dirty_ratio;
-       if (dirty_ratio > unmapped_ratio / 2)
-               dirty_ratio = unmapped_ratio / 2;
-
        if (dirty_ratio < 5)
                dirty_ratio = 5;
 
@@ -355,8 +347,8 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
  */
 static void balance_dirty_pages(struct address_space *mapping)
 {
-       long bdi_nr_reclaimable;
-       long bdi_nr_writeback;
+       long nr_reclaimable, bdi_nr_reclaimable;
+       long nr_writeback, bdi_nr_writeback;
        long background_thresh;
        long dirty_thresh;
        long bdi_thresh;
@@ -376,11 +368,26 @@ static void balance_dirty_pages(struct address_space *mapping)
 
                get_dirty_limits(&background_thresh, &dirty_thresh,
                                &bdi_thresh, bdi);
+
+               nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
+                                       global_page_state(NR_UNSTABLE_NFS);
+               nr_writeback = global_page_state(NR_WRITEBACK);
+
                bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
                bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK);
+
                if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh)
                        break;
 
+               /*
+                * Throttle it only when the background writeback cannot
+                * catch-up. This avoids (excessively) small writeouts
+                * when the bdi limits are ramping up.
+                */
+               if (nr_reclaimable + nr_writeback <
+                               (background_thresh + dirty_thresh) / 2)
+                       break;
+
                if (!bdi->dirty_exceeded)
                        bdi->dirty_exceeded = 1;
 
index da69d833e0671fe6b8a04b019e47b63c7dcf0f4c..12376ae3f7334e124d488b1d7bc3d291d64e9be1 100644 (file)
@@ -749,23 +749,6 @@ int move_freepages_block(struct zone *zone, struct page *page, int migratetype)
        return move_freepages(zone, start_page, end_page, migratetype);
 }
 
-/* Return the page with the lowest PFN in the list */
-static struct page *min_page(struct list_head *list)
-{
-       unsigned long min_pfn = -1UL;
-       struct page *min_page = NULL, *page;;
-
-       list_for_each_entry(page, list, lru) {
-               unsigned long pfn = page_to_pfn(page);
-               if (pfn < min_pfn) {
-                       min_pfn = pfn;
-                       min_page = page;
-               }
-       }
-
-       return min_page;
-}
-
 /* Remove an element from the buddy allocator from the fallback list */
 static struct page *__rmqueue_fallback(struct zone *zone, int order,
                                                int start_migratetype)
@@ -789,11 +772,8 @@ static struct page *__rmqueue_fallback(struct zone *zone, int order,
                        if (list_empty(&area->free_list[migratetype]))
                                continue;
 
-                       /* Bias kernel allocations towards low pfns */
                        page = list_entry(area->free_list[migratetype].next,
                                        struct page, lru);
-                       if (unlikely(start_migratetype != MIGRATE_MOVABLE))
-                               page = min_page(&area->free_list[migratetype]);
                        area->nr_free--;
 
                        /*
index 8f92a29695cc93e82e19582c998b6702ff5e9a2f..3444b58033c87e4263c1d2f1db79f8f416580a29 100644 (file)
@@ -55,7 +55,7 @@ start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
        return 0;
 undo:
        for (pfn = start_pfn;
-            pfn <= undo_pfn;
+            pfn < undo_pfn;
             pfn += pageblock_nr_pages)
                unset_migratetype_isolate(pfn_to_page(pfn));
 
@@ -76,7 +76,7 @@ undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
             pfn < end_pfn;
             pfn += pageblock_nr_pages) {
                page = __first_valid_page(pfn, pageblock_nr_pages);
-               if (!page || get_pageblock_flags(page) != MIGRATE_ISOLATE)
+               if (!page || get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
                        continue;
                unset_migratetype_isolate(page);
        }
@@ -126,7 +126,7 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
         */
        for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
                page = __first_valid_page(pfn, pageblock_nr_pages);
-               if (page && get_pageblock_flags(page) != MIGRATE_ISOLATE)
+               if (page && get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
                        break;
        }
        if (pfn < end_pfn)
index 8990f909492f31d8a3f01df258907661db1bccf6..dc3be5f5b0dafd029860d7303d7e6e471a678597 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -183,7 +183,9 @@ static void page_unlock_anon_vma(struct anon_vma *anon_vma)
 }
 
 /*
- * At what user virtual address is page expected in vma?
+ * At what user virtual address is page expected in @vma?
+ * Returns virtual address or -EFAULT if page's index/offset is not
+ * within the range mapped the @vma.
  */
 static inline unsigned long
 vma_address(struct page *page, struct vm_area_struct *vma)
@@ -193,8 +195,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 
        address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
        if (unlikely(address < vma->vm_start || address >= vma->vm_end)) {
-               /* page should be within any vma from prio_tree_next */
-               BUG_ON(!PageAnon(page));
+               /* page should be within @vma mapping range */
                return -EFAULT;
        }
        return address;
index cfa6be4e378ea1c625081e3ace43c5b212f41968..c31cd3682a0b77ded3ac4e76cded3f427537a551 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1043,7 +1043,7 @@ static struct array_cache **alloc_alien_cache(int node, int limit)
                        }
                        ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d);
                        if (!ac_ptr[i]) {
-                               for (i--; i <= 0; i--)
+                               for (i--; i >= 0; i--)
                                        kfree(ac_ptr[i]);
                                kfree(ac_ptr);
                                return NULL;
index 5bc2ceb692ec94925340e0b65ce4cb8695e2cee1..08a9bd91a1aaf517f1b17ff688fa9f612273f873 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -321,7 +321,8 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
                /* Improve fragment distribution and reduce our average
                 * search time by starting our next search here. (see
                 * Knuth vol 1, sec 2.5, pg 449) */
-               if (free_slob_pages.next != prev->next)
+               if (prev != free_slob_pages.prev &&
+                               free_slob_pages.next != prev->next)
                        list_move_tail(&free_slob_pages, prev->next);
                break;
        }
index bcdb2c8941a5fcb428d4d3d256106f29e921debd..9acb413858ac532e9a668d4d2b351f4acdbd14c3 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1080,7 +1080,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
        struct page *page;
        struct kmem_cache_node *n;
        void *start;
-       void *end;
        void *last;
        void *p;
 
@@ -1101,7 +1100,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
                SetSlabDebug(page);
 
        start = page_address(page);
-       end = start + s->objects * s->size;
 
        if (unlikely(s->flags & SLAB_POISON))
                memset(start, POISON_INUSE, PAGE_SIZE << s->order);
@@ -1511,26 +1509,8 @@ new_slab:
 
        if (new) {
                c = get_cpu_slab(s, smp_processor_id());
-               if (c->page) {
-                       /*
-                        * Someone else populated the cpu_slab while we
-                        * enabled interrupts, or we have gotten scheduled
-                        * on another cpu. The page may not be on the
-                        * requested node even if __GFP_THISNODE was
-                        * specified. So we need to recheck.
-                        */
-                       if (node_match(c, node)) {
-                               /*
-                                * Current cpuslab is acceptable and we
-                                * want the current one since its cache hot
-                                */
-                               discard_slab(s, new);
-                               slab_lock(c->page);
-                               goto load_freelist;
-                       }
-                       /* New slab does not fit our expectations */
+               if (c->page)
                        flush_slab(s, c);
-               }
                slab_lock(new);
                SetSlabFrozen(new);
                c->page = new;
index 5f64026cbb4d0f6c053a539ffb0d723255da85f3..8f18683825bcd0e3b95b4fe1754befb3e0b0268c 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -95,8 +95,8 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)
                return (void *)p;
 
        ret = kmalloc_track_caller(new_size, flags);
-       if (ret) {
-               memcpy(ret, p, min(new_size, ks));
+       if (ret && p) {
+               memcpy(ret, p, ks);
                kfree(p);
        }
        return ret;
index 4651bf153f355998617b9657d0d02eb966d7c3e9..e8d846f57774ee631adc5836aeaa6498b39736a0 100644 (file)
@@ -803,7 +803,7 @@ static void vmstat_update(struct work_struct *w)
                sysctl_stat_interval);
 }
 
-static void __devinit start_cpu_timer(int cpu)
+static void __cpuinit start_cpu_timer(int cpu)
 {
        struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu);
 
index 3fe4fc86055faa4765701c3e36f88fed043cfaeb..6567213959cbac09f68a2a4973d4283361688196 100644 (file)
@@ -376,6 +376,7 @@ void vlan_setup(struct net_device *new_dev)
        new_dev->init = vlan_dev_init;
        new_dev->open = vlan_dev_open;
        new_dev->stop = vlan_dev_stop;
+       new_dev->set_mac_address = vlan_set_mac_address;
        new_dev->set_multicast_list = vlan_dev_set_multicast_list;
        new_dev->change_rx_flags = vlan_change_rx_flags;
        new_dev->destructor = free_netdev;
@@ -636,6 +637,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
                        if (!vlandev)
                                continue;
 
+                       flgs = vlandev->flags;
+                       if (!(flgs & IFF_UP))
+                               continue;
+
                        vlan_sync_address(dev, vlandev);
                }
                break;
@@ -747,6 +752,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
                vlan_dev_set_ingress_priority(dev,
                                              args.u.skb_priority,
                                              args.vlan_qos);
+               err = 0;
                break;
 
        case SET_VLAN_EGRESS_PRIORITY_CMD:
index cf4a80d06b3526f1ca2caf4e938561ec57c4dca9..2cd1393073ec8e4e845aac4d0f14672dabbf1f37 100644 (file)
@@ -60,6 +60,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev
 int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
 int vlan_dev_open(struct net_device* dev);
 int vlan_dev_stop(struct net_device* dev);
+int vlan_set_mac_address(struct net_device *dev, void *p);
 int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
 void vlan_dev_set_ingress_priority(const struct net_device *dev,
                                   u32 skb_prio, short vlan_prio);
index 1a1740aa9a8b52ced5b71c4b2443b2eea773c0a7..7a36878241dabf132f09fb861afca2b68f10ca77 100644 (file)
@@ -665,6 +665,32 @@ int vlan_dev_stop(struct net_device *dev)
        return 0;
 }
 
+int vlan_set_mac_address(struct net_device *dev, void *p)
+{
+       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+       struct sockaddr *addr = p;
+       int err;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (!(dev->flags & IFF_UP))
+               goto out;
+
+       if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) {
+               err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN);
+               if (err < 0)
+                       return err;
+       }
+
+       if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
+               dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN);
+
+out:
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       return 0;
+}
+
 int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
index 41d70f47375ddd5d825268b76ad7629bac368ef6..8f9763a9dc1296b54a2d889a6bae9402ccf6cd37 100644 (file)
@@ -76,9 +76,9 @@ struct p9_trans_module *v9fs_match_trans(const substring_t *name)
        list_for_each(p, &v9fs_trans_list) {
                t = list_entry(p, struct p9_trans_module, list);
                if (strncmp(t->name, name->from, name->to-name->from) == 0)
-                       break;
+                       return t;
        }
-       return t;
+       return NULL;
 }
 EXPORT_SYMBOL(v9fs_match_trans);
 
index 30269a4ff22a93e781be185df453c60f88837ba8..62332ed9da4afcd7e8b06577f0e4ec47d07ed171 100644 (file)
@@ -62,13 +62,14 @@ struct p9_trans_fd {
 
 enum {
        /* Options that take integer arguments */
-       Opt_port, Opt_rfdno, Opt_wfdno,
+       Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
 };
 
 static match_table_t tokens = {
        {Opt_port, "port=%u"},
        {Opt_rfdno, "rfdno=%u"},
        {Opt_wfdno, "wfdno=%u"},
+       {Opt_err, NULL},
 };
 
 /**
index da22f900e89dca6f54b9b46990e37d6f7feb8086..c1757c79dfbb3eaf7f857441f9a71966155b24a0 100644 (file)
@@ -766,6 +766,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
        if (!nf_bridge)
                return NF_ACCEPT;
 
+       if (!(nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT)))
+               return NF_ACCEPT;
+
        if (!realoutdev)
                return NF_DROP;
 
index 1a46952a56d9f197077e97e9cddf9814f24544b6..18141392a9b4eb87a45afc11902ae89249c7e7ac 100644 (file)
@@ -34,7 +34,7 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
           ah->ar_pro, EBT_ARP_PTYPE))
                return EBT_NOMATCH;
 
-       if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) {
+       if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
                __be32 saddr, daddr, *sap, *dap;
 
                if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
index be6cedab5aa83cc3d5551e89ef66d5597dfccbf0..86d62611f2fcc4583f2eaf9a40d600718944ad97 100644 (file)
@@ -1171,6 +1171,8 @@ rollback:
                        nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
                }
        }
+
+       raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
 }
 
@@ -2688,7 +2690,7 @@ static void __net_exit dev_proc_net_exit(struct net *net)
        proc_net_remove(net, "dev");
 }
 
-static struct pernet_operations dev_proc_ops = {
+static struct pernet_operations __net_initdata dev_proc_ops = {
        .init = dev_proc_net_init,
        .exit = dev_proc_net_exit,
 };
@@ -4330,7 +4332,6 @@ static struct hlist_head *netdev_create_hash(void)
 static int __net_init netdev_init(struct net *net)
 {
        INIT_LIST_HEAD(&net->dev_base_head);
-       rwlock_init(&dev_base_lock);
 
        net->dev_name_head = netdev_create_hash();
        if (net->dev_name_head == NULL)
@@ -4354,7 +4355,7 @@ static void __net_exit netdev_exit(struct net *net)
        kfree(net->dev_index_head);
 }
 
-static struct pernet_operations  netdev_net_ops = {
+static struct pernet_operations __net_initdata netdev_net_ops = {
        .init = netdev_init,
        .exit = netdev_exit,
 };
@@ -4385,7 +4386,7 @@ static void __net_exit default_device_exit(struct net *net)
        rtnl_unlock();
 }
 
-static struct pernet_operations  default_device_ops = {
+static struct pernet_operations __net_initdata default_device_ops = {
        .exit = default_device_exit,
 };
 
index ae354057d84cf5101b89126e343ce3903eed55d2..69fff16ece10c70c3c94d2624a2d1086a23e26a8 100644 (file)
@@ -168,13 +168,13 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from)
        da = from->mc_list;
        while (da != NULL) {
                next = da->next;
-               if (!da->da_synced)
-                       continue;
-               __dev_addr_delete(&to->mc_list, &to->mc_count,
-                                 da->da_addr, da->da_addrlen, 0);
-               da->da_synced = 0;
-               __dev_addr_delete(&from->mc_list, &from->mc_count,
-                                 da->da_addr, da->da_addrlen, 0);
+               if (da->da_synced) {
+                       __dev_addr_delete(&to->mc_list, &to->mc_count,
+                                         da->da_addr, da->da_addrlen, 0);
+                       da->da_synced = 0;
+                       __dev_addr_delete(&from->mc_list, &from->mc_count,
+                                         da->da_addr, da->da_addrlen, 0);
+               }
                da = next;
        }
        __dev_set_rx_mode(to);
@@ -285,7 +285,7 @@ static void __net_exit dev_mc_net_exit(struct net *net)
        proc_net_remove(net, "dev_mcast");
 }
 
-static struct pernet_operations dev_mc_net_ops = {
+static struct pernet_operations __net_initdata dev_mc_net_ops = {
        .init = dev_mc_net_init,
        .exit = dev_mc_net_exit,
 };
index 16958e64e577f8c12723f02129a5f1e9b1791fdb..03daead3592ad0ef60628e85eef11e18da28b610 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 #include <net/net_namespace.h>
 
-#include <net/net_namespace.h>
 #include <net/dst.h>
 
 /*
index 13de6f53f0981f19bb16e7aef2d542f2d5f8167a..848132b6cb733500663b64f4097516799d599f36 100644 (file)
 static LIST_HEAD(rules_ops);
 static DEFINE_SPINLOCK(rules_mod_lock);
 
+int fib_default_rule_add(struct fib_rules_ops *ops,
+                        u32 pref, u32 table, u32 flags)
+{
+       struct fib_rule *r;
+
+       r = kzalloc(ops->rule_size, GFP_KERNEL);
+       if (r == NULL)
+               return -ENOMEM;
+
+       atomic_set(&r->refcnt, 1);
+       r->action = FR_ACT_TO_TBL;
+       r->pref = pref;
+       r->table = table;
+       r->flags = flags;
+
+       /* The lock is not required here, the list in unreacheable
+        * at the moment this function is called */
+       list_add_tail(&r->list, &ops->rules_list);
+       return 0;
+}
+EXPORT_SYMBOL(fib_default_rule_add);
+
 static void notify_rule_change(int event, struct fib_rule *rule,
                               struct fib_rules_ops *ops, struct nlmsghdr *nlh,
                               u32 pid);
index 05979e35696320eeee0bbd5ae36d06ec50e496cc..29b8ee4e35d6dc53f32064c1c067c7287ce80924 100644 (file)
@@ -1435,6 +1435,8 @@ int neigh_table_clear(struct neigh_table *tbl)
        kfree(tbl->phash_buckets);
        tbl->phash_buckets = NULL;
 
+       remove_proc_entry(tbl->id, init_net.proc_net_stat);
+
        free_percpu(tbl->stats);
        tbl->stats = NULL;
 
index e9f0964ce70bf89eef873b23c2ad9c2f80a4cf57..383252b50411b89c5c18835bcbe4c9837ed16ad0 100644 (file)
@@ -64,6 +64,20 @@ static struct net *net_alloc(void)
        return kmem_cache_zalloc(net_cachep, GFP_KERNEL);
 }
 
+static void net_free(struct net *net)
+{
+       if (!net)
+               return;
+
+       if (unlikely(atomic_read(&net->use_count) != 0)) {
+               printk(KERN_EMERG "network namespace not free! Usage: %d\n",
+                       atomic_read(&net->use_count));
+               return;
+       }
+
+       kmem_cache_free(net_cachep, net);
+}
+
 struct net *copy_net_ns(unsigned long flags, struct net *old_net)
 {
        struct net *new_net = NULL;
@@ -100,20 +114,6 @@ out:
        return new_net;
 }
 
-static void net_free(struct net *net)
-{
-       if (!net)
-               return;
-
-       if (unlikely(atomic_read(&net->use_count) != 0)) {
-               printk(KERN_EMERG "network namespace not free! Usage: %d\n",
-                       atomic_read(&net->use_count));
-               return;
-       }
-
-       kmem_cache_free(net_cachep, net);
-}
-
 static void cleanup_net(struct work_struct *work)
 {
        struct pernet_operations *ops;
@@ -188,6 +188,7 @@ static int __init net_ns_init(void)
 
 pure_initcall(net_ns_init);
 
+#ifdef CONFIG_NET_NS
 static int register_pernet_operations(struct list_head *list,
                                      struct pernet_operations *ops)
 {
@@ -228,6 +229,23 @@ static void unregister_pernet_operations(struct pernet_operations *ops)
                        ops->exit(net);
 }
 
+#else
+
+static int register_pernet_operations(struct list_head *list,
+                                     struct pernet_operations *ops)
+{
+       if (ops->init == NULL)
+               return 0;
+       return ops->init(&init_net);
+}
+
+static void unregister_pernet_operations(struct pernet_operations *ops)
+{
+       if (ops->exit)
+               ops->exit(&init_net);
+}
+#endif
+
 /**
  *      register_pernet_subsys - register a network namespace subsystem
  *     @ops:  pernet operations structure for the subsystem
index 5f0818d815e6b700408f2dcea1986b87fdc09645..45aed75cb571220da14d2924ec9674ac06f4d99b 100644 (file)
@@ -71,6 +71,41 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
 
 EXPORT_SYMBOL(reqsk_queue_alloc);
 
+void __reqsk_queue_destroy(struct request_sock_queue *queue)
+{
+       struct listen_sock *lopt;
+       size_t lopt_size;
+
+       /*
+        * this is an error recovery path only
+        * no locking needed and the lopt is not NULL
+        */
+
+       lopt = queue->listen_opt;
+       lopt_size = sizeof(struct listen_sock) +
+               lopt->nr_table_entries * sizeof(struct request_sock *);
+
+       if (lopt_size > PAGE_SIZE)
+               vfree(lopt);
+       else
+               kfree(lopt);
+}
+
+EXPORT_SYMBOL(__reqsk_queue_destroy);
+
+static inline struct listen_sock *reqsk_queue_yank_listen_sk(
+               struct request_sock_queue *queue)
+{
+       struct listen_sock *lopt;
+
+       write_lock_bh(&queue->syn_wait_lock);
+       lopt = queue->listen_opt;
+       queue->listen_opt = NULL;
+       write_unlock_bh(&queue->syn_wait_lock);
+
+       return lopt;
+}
+
 void reqsk_queue_destroy(struct request_sock_queue *queue)
 {
        /* make all the listen_opt local to us */
index 12ad2067a988405b2768afa4eb421afd8440a1c8..c519b439b8b1927acf2e01209417747d5ebe7cb4 100644 (file)
@@ -1801,11 +1801,65 @@ EXPORT_SYMBOL(sk_common_release);
 static DEFINE_RWLOCK(proto_list_lock);
 static LIST_HEAD(proto_list);
 
+#ifdef CONFIG_SMP
+/*
+ * Define default functions to keep track of inuse sockets per protocol
+ * Note that often used protocols use dedicated functions to get a speed increase.
+ * (see DEFINE_PROTO_INUSE/REF_PROTO_INUSE)
+ */
+static void inuse_add(struct proto *prot, int inc)
+{
+       per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc;
+}
+
+static int inuse_get(const struct proto *prot)
+{
+       int res = 0, cpu;
+       for_each_possible_cpu(cpu)
+               res += per_cpu_ptr(prot->inuse_ptr, cpu)[0];
+       return res;
+}
+
+static int inuse_init(struct proto *prot)
+{
+       if (!prot->inuse_getval || !prot->inuse_add) {
+               prot->inuse_ptr = alloc_percpu(int);
+               if (prot->inuse_ptr == NULL)
+                       return -ENOBUFS;
+
+               prot->inuse_getval = inuse_get;
+               prot->inuse_add = inuse_add;
+       }
+       return 0;
+}
+
+static void inuse_fini(struct proto *prot)
+{
+       if (prot->inuse_ptr != NULL) {
+               free_percpu(prot->inuse_ptr);
+               prot->inuse_ptr = NULL;
+               prot->inuse_getval = NULL;
+               prot->inuse_add = NULL;
+       }
+}
+#else
+static inline int inuse_init(struct proto *prot)
+{
+       return 0;
+}
+
+static inline void inuse_fini(struct proto *prot)
+{
+}
+#endif
+
 int proto_register(struct proto *prot, int alloc_slab)
 {
        char *request_sock_slab_name = NULL;
        char *timewait_sock_slab_name;
-       int rc = -ENOBUFS;
+
+       if (inuse_init(prot))
+               goto out;
 
        if (alloc_slab) {
                prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,
@@ -1814,7 +1868,7 @@ int proto_register(struct proto *prot, int alloc_slab)
                if (prot->slab == NULL) {
                        printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
                               prot->name);
-                       goto out;
+                       goto out_free_inuse;
                }
 
                if (prot->rsk_prot != NULL) {
@@ -1858,9 +1912,8 @@ int proto_register(struct proto *prot, int alloc_slab)
        write_lock(&proto_list_lock);
        list_add(&prot->node, &proto_list);
        write_unlock(&proto_list_lock);
-       rc = 0;
-out:
-       return rc;
+       return 0;
+
 out_free_timewait_sock_slab_name:
        kfree(timewait_sock_slab_name);
 out_free_request_sock_slab:
@@ -1873,7 +1926,10 @@ out_free_request_sock_slab_name:
 out_free_sock_slab:
        kmem_cache_destroy(prot->slab);
        prot->slab = NULL;
-       goto out;
+out_free_inuse:
+       inuse_fini(prot);
+out:
+       return -ENOBUFS;
 }
 
 EXPORT_SYMBOL(proto_register);
@@ -1884,6 +1940,7 @@ void proto_unregister(struct proto *prot)
        list_del(&prot->node);
        write_unlock(&proto_list_lock);
 
+       inuse_fini(prot);
        if (prot->slab != NULL) {
                kmem_cache_destroy(prot->slab);
                prot->slab = NULL;
@@ -2040,7 +2097,3 @@ EXPORT_SYMBOL(sock_wmalloc);
 EXPORT_SYMBOL(sock_i_uid);
 EXPORT_SYMBOL(sock_i_ino);
 EXPORT_SYMBOL(sysctl_optmem_max);
-#ifdef CONFIG_SYSCTL
-EXPORT_SYMBOL(sysctl_rmem_max);
-EXPORT_SYMBOL(sysctl_wmem_max);
-#endif
index 01a6a808bdb7ba16687b44803cd4ffa3a42fbe3e..db17b83e8d3e85b267ed1bd352338ad64119f9df 100644 (file)
@@ -922,6 +922,8 @@ static struct timewait_sock_ops dccp_timewait_sock_ops = {
        .twsk_obj_size  = sizeof(struct inet_timewait_sock),
 };
 
+DEFINE_PROTO_INUSE(dccp_v4)
+
 static struct proto dccp_v4_prot = {
        .name                   = "DCCP",
        .owner                  = THIS_MODULE,
@@ -950,6 +952,7 @@ static struct proto dccp_v4_prot = {
        .compat_setsockopt      = compat_dccp_setsockopt,
        .compat_getsockopt      = compat_dccp_getsockopt,
 #endif
+       REF_PROTO_INUSE(dccp_v4)
 };
 
 static struct net_protocol dccp_v4_protocol = {
index 62428ff137ddb4f63120246da364c3f84c4a50d2..87c98fb86fa89311fb33863102875f5d853a94cf 100644 (file)
@@ -1107,6 +1107,8 @@ static struct timewait_sock_ops dccp6_timewait_sock_ops = {
        .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
 };
 
+DEFINE_PROTO_INUSE(dccp_v6)
+
 static struct proto dccp_v6_prot = {
        .name              = "DCCPv6",
        .owner             = THIS_MODULE,
@@ -1135,6 +1137,7 @@ static struct proto dccp_v6_prot = {
        .compat_setsockopt = compat_dccp_setsockopt,
        .compat_getsockopt = compat_dccp_getsockopt,
 #endif
+       REF_PROTO_INUSE(dccp_v6)
 };
 
 static struct inet6_protocol dccp_v6_protocol = {
index d84973928033bc47fd1dbd10384737758eec1a32..7a3bea9c28c172c8768414cf0fe8f616fb5e15b3 100644 (file)
@@ -1072,11 +1072,13 @@ static int __init dccp_init(void)
        }
 
        for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
-               rwlock_init(&dccp_hashinfo.ehash[i].lock);
                INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
                INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
        }
 
+       if (inet_ehash_locks_alloc(&dccp_hashinfo))
+                       goto out_free_dccp_ehash;
+
        bhash_order = ehash_order;
 
        do {
@@ -1091,7 +1093,7 @@ static int __init dccp_init(void)
 
        if (!dccp_hashinfo.bhash) {
                DCCP_CRIT("Failed to allocate DCCP bind hash table");
-               goto out_free_dccp_ehash;
+               goto out_free_dccp_locks;
        }
 
        for (i = 0; i < dccp_hashinfo.bhash_size; i++) {
@@ -1121,6 +1123,8 @@ out_free_dccp_mib:
 out_free_dccp_bhash:
        free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
        dccp_hashinfo.bhash = NULL;
+out_free_dccp_locks:
+       inet_ehash_locks_free(&dccp_hashinfo);
 out_free_dccp_ehash:
        free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
        dccp_hashinfo.ehash = NULL;
@@ -1139,6 +1143,7 @@ static void __exit dccp_fini(void)
        free_pages((unsigned long)dccp_hashinfo.ehash,
                   get_order(dccp_hashinfo.ehash_size *
                             sizeof(struct inet_ehash_bucket)));
+       inet_ehash_locks_free(&dccp_hashinfo);
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
        dccp_ackvec_exit();
        dccp_sysctl_exit();
index 26130afd80299a32692f74ab794af5d5e95f3b37..66e266fb5908b4976448da87ddc74d509c25b10f 100644 (file)
@@ -1439,7 +1439,7 @@ static const struct file_operations dn_dev_seq_fops = {
 
 #endif /* CONFIG_PROC_FS */
 
-static int __initdata addr[2];
+static int addr[2];
 module_param_array(addr, int, NULL, 0444);
 MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
 
index 97eee5e8fbbe35c1ec63ff45d8cb2dedd6aeba73..66663e5d7acdc8cb20349b62c86690fe82a1b770 100644 (file)
@@ -293,9 +293,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route *
                                           dn_rt_hash_table[hash].chain);
                        rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth);
 
-                       rth->u.dst.__use++;
-                       dst_hold(&rth->u.dst);
-                       rth->u.dst.lastuse = now;
+                       dst_use(&rth->u.dst, now);
                        spin_unlock_bh(&dn_rt_hash_table[hash].lock);
 
                        dnrt_drop(rt);
@@ -308,9 +306,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route *
        rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain);
        rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt);
 
-       dst_hold(&rt->u.dst);
-       rt->u.dst.__use++;
-       rt->u.dst.lastuse = now;
+       dst_use(&rt->u.dst, now);
        spin_unlock_bh(&dn_rt_hash_table[hash].lock);
        *rp = rt;
        return 0;
@@ -1182,9 +1178,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
                            (flp->mark == rt->fl.mark) &&
                            (rt->fl.iif == 0) &&
                            (rt->fl.oif == flp->oif)) {
-                               rt->u.dst.lastuse = jiffies;
-                               dst_hold(&rt->u.dst);
-                               rt->u.dst.__use++;
+                               dst_use(&rt->u.dst, jiffies);
                                rcu_read_unlock_bh();
                                *pprt = &rt->u.dst;
                                return 0;
@@ -1456,9 +1450,7 @@ int dn_route_input(struct sk_buff *skb)
                    (rt->fl.oif == 0) &&
                    (rt->fl.mark == skb->mark) &&
                    (rt->fl.iif == cb->iif)) {
-                       rt->u.dst.lastuse = jiffies;
-                       dst_hold(&rt->u.dst);
-                       rt->u.dst.__use++;
+                       dst_use(&rt->u.dst, jiffies);
                        rcu_read_unlock();
                        skb->dst = (struct dst_entry *)rt;
                        return 0;
index ddd3f04f0919ee880dba236ee1516df96d3a6bee..ffebea04cc99b9f6c5820734f057f9307ed5e333 100644 (file)
@@ -48,15 +48,6 @@ struct dn_fib_rule
        u8                      flags;
 };
 
-static struct dn_fib_rule default_rule = {
-       .common = {
-               .refcnt =               ATOMIC_INIT(2),
-               .pref =                 0x7fff,
-               .table =                RT_TABLE_MAIN,
-               .action =               FR_ACT_TO_TBL,
-       },
-};
-
 
 int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res)
 {
@@ -262,8 +253,8 @@ static struct fib_rules_ops dn_fib_rules_ops = {
 
 void __init dn_fib_rules_init(void)
 {
-       list_add_tail(&default_rule.common.list,
-                       &dn_fib_rules_ops.rules_list);
+       BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff,
+                                   RT_TABLE_MAIN, 0));
        fib_rules_register(&dn_fib_rules_ops);
 }
 
index 4cce3534e408c5e5d495eda666ccef80fd4348c3..58b22619ab15c160ad072cbd65edbc7931ba7b98 100644 (file)
@@ -25,7 +25,6 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
index 866fc04c44f9c989d64bd543e3a10224db78c11c..3fa30c40779f6b7c8242541a6a484440409a40d3 100644 (file)
@@ -22,7 +22,6 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
index ac36767b56e892c63d7eb0c0684b4d1b088f835e..e01b59aedc54612f49d4e225ff1459c37e57866d 100644 (file)
@@ -470,7 +470,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
-       u16 reason = cpu_to_le16(mlme->reason_code);
+       u16 reason = mlme->reason_code;
        struct ieee80211softmac_network *net;
        int err = -EINVAL;
 
index 60123905dbbf65d4e67a3c7adc86264091a52bfd..732d8f088b13298fdfef8eb1051477c7f6453080 100644 (file)
@@ -59,6 +59,13 @@ struct fib_table *ip_fib_main_table;
 #define FIB_TABLE_HASHSZ 1
 static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
 
+static void __init fib4_rules_init(void)
+{
+       ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
+       hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
+       ip_fib_main_table  = fib_hash_init(RT_TABLE_MAIN);
+       hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
+}
 #else
 
 #define FIB_TABLE_HASHSZ 256
@@ -905,14 +912,8 @@ void __init ip_fib_init(void)
 
        for (i = 0; i < FIB_TABLE_HASHSZ; i++)
                INIT_HLIST_HEAD(&fib_table_hash[i]);
-#ifndef CONFIG_IP_MULTIPLE_TABLES
-       ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
-       hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
-       ip_fib_main_table  = fib_hash_init(RT_TABLE_MAIN);
-       hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
-#else
+
        fib4_rules_init();
-#endif
 
        register_netdevice_notifier(&fib_netdev_notifier);
        register_inetaddr_notifier(&fib_inetaddr_notifier);
index f16839c6a721ab98d2402e16a9aa51087954afad..a0ada3a8d8dd8c2cfd931cc0c475c73aadf8d62b 100644 (file)
@@ -49,33 +49,6 @@ struct fib4_rule
 #endif
 };
 
-static struct fib4_rule default_rule = {
-       .common = {
-               .refcnt =       ATOMIC_INIT(2),
-               .pref =         0x7FFF,
-               .table =        RT_TABLE_DEFAULT,
-               .action =       FR_ACT_TO_TBL,
-       },
-};
-
-static struct fib4_rule main_rule = {
-       .common = {
-               .refcnt =       ATOMIC_INIT(2),
-               .pref =         0x7FFE,
-               .table =        RT_TABLE_MAIN,
-               .action =       FR_ACT_TO_TBL,
-       },
-};
-
-static struct fib4_rule local_rule = {
-       .common = {
-               .refcnt =       ATOMIC_INIT(2),
-               .table =        RT_TABLE_LOCAL,
-               .action =       FR_ACT_TO_TBL,
-               .flags =        FIB_RULE_PERMANENT,
-       },
-};
-
 #ifdef CONFIG_NET_CLS_ROUTE
 u32 fib_rules_tclass(struct fib_result *res)
 {
@@ -319,11 +292,27 @@ static struct fib_rules_ops fib4_rules_ops = {
        .owner          = THIS_MODULE,
 };
 
-void __init fib4_rules_init(void)
+static int __init fib_default_rules_init(void)
 {
-       list_add_tail(&local_rule.common.list, &fib4_rules_ops.rules_list);
-       list_add_tail(&main_rule.common.list, &fib4_rules_ops.rules_list);
-       list_add_tail(&default_rule.common.list, &fib4_rules_ops.rules_list);
+       int err;
+
+       err = fib_default_rule_add(&fib4_rules_ops, 0,
+                                  RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
+       if (err < 0)
+               return err;
+       err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE,
+                                  RT_TABLE_MAIN, 0);
+       if (err < 0)
+               return err;
+       err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF,
+                                  RT_TABLE_DEFAULT, 0);
+       if (err < 0)
+               return err;
+       return 0;
+}
 
+void __init fib4_rules_init(void)
+{
+       BUG_ON(fib_default_rules_init());
        fib_rules_register(&fib4_rules_ops);
 }
index dc429b6b0ba62bbca65f545f6a9a8630e02eaafa..b0170732b5e9e962ed1fca65cf930c3bf4cc98f0 100644 (file)
@@ -747,13 +747,14 @@ skip_listen_ht:
 
        for (i = s_i; i < hashinfo->ehash_size; i++) {
                struct inet_ehash_bucket *head = &hashinfo->ehash[i];
+               rwlock_t *lock = inet_ehash_lockp(hashinfo, i);
                struct sock *sk;
                struct hlist_node *node;
 
                if (i > s_i)
                        s_num = 0;
 
-               read_lock_bh(&head->lock);
+               read_lock_bh(lock);
                num = 0;
                sk_for_each(sk, node, &head->chain) {
                        struct inet_sock *inet = inet_sk(sk);
@@ -769,7 +770,7 @@ skip_listen_ht:
                            r->id.idiag_dport)
                                goto next_normal;
                        if (inet_csk_diag_dump(sk, skb, cb) < 0) {
-                               read_unlock_bh(&head->lock);
+                               read_unlock_bh(lock);
                                goto done;
                        }
 next_normal:
@@ -791,14 +792,14 @@ next_normal:
                                    r->id.idiag_dport)
                                        goto next_dying;
                                if (inet_twsk_diag_dump(tw, skb, cb) < 0) {
-                                       read_unlock_bh(&head->lock);
+                                       read_unlock_bh(lock);
                                        goto done;
                                }
 next_dying:
                                ++num;
                        }
                }
-               read_unlock_bh(&head->lock);
+               read_unlock_bh(lock);
        }
 
 done:
index 16eecc7046a346d6a2a22e1c33f71055a333f4c2..67704da04fc4ca98d88eeaae7db3e53d1a6157aa 100644 (file)
@@ -204,12 +204,13 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
        unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+       rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
        struct sock *sk2;
        const struct hlist_node *node;
        struct inet_timewait_sock *tw;
 
        prefetch(head->chain.first);
-       write_lock(&head->lock);
+       write_lock(lock);
 
        /* Check TIME-WAIT sockets first. */
        sk_for_each(sk2, node, &head->twchain) {
@@ -239,7 +240,7 @@ unique:
        BUG_TRAP(sk_unhashed(sk));
        __sk_add_node(sk, &head->chain);
        sock_prot_inc_use(sk->sk_prot);
-       write_unlock(&head->lock);
+       write_unlock(lock);
 
        if (twp) {
                *twp = tw;
@@ -255,7 +256,7 @@ unique:
        return 0;
 
 not_unique:
-       write_unlock(&head->lock);
+       write_unlock(lock);
        return -EADDRNOTAVAIL;
 }
 
index 4e189e28f3062f45f6aeca63476423ca386e757a..a60b99e0ebdc2d1dfa838a1134e361139ceeb910 100644 (file)
@@ -20,16 +20,16 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
        struct inet_bind_hashbucket *bhead;
        struct inet_bind_bucket *tb;
        /* Unlink from established hashes. */
-       struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, tw->tw_hash);
+       rwlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash);
 
-       write_lock(&ehead->lock);
+       write_lock(lock);
        if (hlist_unhashed(&tw->tw_node)) {
-               write_unlock(&ehead->lock);
+               write_unlock(lock);
                return;
        }
        __hlist_del(&tw->tw_node);
        sk_node_init(&tw->tw_node);
-       write_unlock(&ehead->lock);
+       write_unlock(lock);
 
        /* Disassociate with bind bucket. */
        bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)];
@@ -59,6 +59,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
        const struct inet_sock *inet = inet_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash);
+       rwlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
        struct inet_bind_hashbucket *bhead;
        /* Step 1: Put TW into bind hash. Original socket stays there too.
           Note, that any socket with inet->num != 0 MUST be bound in
@@ -71,7 +72,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
        inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
        spin_unlock(&bhead->lock);
 
-       write_lock(&ehead->lock);
+       write_lock(lock);
 
        /* Step 2: Remove SK from established hash. */
        if (__sk_del_node_init(sk))
@@ -81,7 +82,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
        inet_twsk_add_node(tw, &ehead->twchain);
        atomic_inc(&tw->tw_refcnt);
 
-       write_unlock(&ehead->lock);
+       write_unlock(lock);
 }
 
 EXPORT_SYMBOL_GPL(__inet_twsk_hashdance);
index 771031dfbd0f875c807a0f82fd96a870d770c2e7..af995198f643bf174c20b3570dd91b6bd7ccec47 100644 (file)
@@ -61,7 +61,7 @@
  *  4.  Global variable peer_total is modified under the pool lock.
  *  5.  struct inet_peer fields modification:
  *             avl_left, avl_right, avl_parent, avl_height: pool lock
- *             unused_next, unused_prevp: unused node list lock
+ *             unused: unused node list lock
  *             refcnt: atomically against modifications on other CPU;
  *                usually under some other lock to prevent node disappearing
  *             dtime: unused node list lock
@@ -94,8 +94,7 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ;    /* usual time to live: 10 min
 int inet_peer_gc_mintime __read_mostly = 10 * HZ;
 int inet_peer_gc_maxtime __read_mostly = 120 * HZ;
 
-static struct inet_peer *inet_peer_unused_head;
-static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
+static LIST_HEAD(unused_peers);
 static DEFINE_SPINLOCK(inet_peer_unused_lock);
 
 static void peer_check_expire(unsigned long dummy);
@@ -138,15 +137,7 @@ void __init inet_initpeers(void)
 static void unlink_from_unused(struct inet_peer *p)
 {
        spin_lock_bh(&inet_peer_unused_lock);
-       if (p->unused_prevp != NULL) {
-               /* On unused list. */
-               *p->unused_prevp = p->unused_next;
-               if (p->unused_next != NULL)
-                       p->unused_next->unused_prevp = p->unused_prevp;
-               else
-                       inet_peer_unused_tailp = p->unused_prevp;
-               p->unused_prevp = NULL; /* mark it as removed */
-       }
+       list_del_init(&p->unused);
        spin_unlock_bh(&inet_peer_unused_lock);
 }
 
@@ -337,24 +328,24 @@ static void unlink_from_pool(struct inet_peer *p)
 /* May be called with local BH enabled. */
 static int cleanup_once(unsigned long ttl)
 {
-       struct inet_peer *p;
+       struct inet_peer *p = NULL;
 
        /* Remove the first entry from the list of unused nodes. */
        spin_lock_bh(&inet_peer_unused_lock);
-       p = inet_peer_unused_head;
-       if (p != NULL) {
-               __u32 delta = (__u32)jiffies - p->dtime;
+       if (!list_empty(&unused_peers)) {
+               __u32 delta;
+
+               p = list_first_entry(&unused_peers, struct inet_peer, unused);
+               delta = (__u32)jiffies - p->dtime;
+
                if (delta < ttl) {
                        /* Do not prune fresh entries. */
                        spin_unlock_bh(&inet_peer_unused_lock);
                        return -1;
                }
-               inet_peer_unused_head = p->unused_next;
-               if (p->unused_next != NULL)
-                       p->unused_next->unused_prevp = p->unused_prevp;
-               else
-                       inet_peer_unused_tailp = p->unused_prevp;
-               p->unused_prevp = NULL; /* mark as not on the list */
+
+               list_del_init(&p->unused);
+
                /* Grab an extra reference to prevent node disappearing
                 * before unlink_from_pool() call. */
                atomic_inc(&p->refcnt);
@@ -412,7 +403,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create)
 
        /* Link the node. */
        link_to_pool(n);
-       n->unused_prevp = NULL; /* not on the list */
+       INIT_LIST_HEAD(&n->unused);
        peer_total++;
        write_unlock_bh(&peer_pool_lock);
 
@@ -467,10 +458,7 @@ void inet_putpeer(struct inet_peer *p)
 {
        spin_lock_bh(&inet_peer_unused_lock);
        if (atomic_dec_and_test(&p->refcnt)) {
-               p->unused_prevp = inet_peer_unused_tailp;
-               p->unused_next = NULL;
-               *inet_peer_unused_tailp = p;
-               inet_peer_unused_tailp = &p->unused_next;
+               list_add_tail(&p->unused, &unused_peers);
                p->dtime = (__u32)jiffies;
        }
        spin_unlock_bh(&inet_peer_unused_lock);
index e5f7dc2de30349c8045bdadc5e77940bcf97680d..fd99fbd685ea9512cc03aa57db5347d34dd1e2cb 100644 (file)
@@ -1183,6 +1183,17 @@ error:
        return err;
 }
 
+static void ip_cork_release(struct inet_sock *inet)
+{
+       inet->cork.flags &= ~IPCORK_OPT;
+       kfree(inet->cork.opt);
+       inet->cork.opt = NULL;
+       if (inet->cork.rt) {
+               ip_rt_put(inet->cork.rt);
+               inet->cork.rt = NULL;
+       }
+}
+
 /*
  *     Combined all pending IP fragments on the socket as one IP datagram
  *     and push them out.
@@ -1276,13 +1287,7 @@ int ip_push_pending_frames(struct sock *sk)
        }
 
 out:
-       inet->cork.flags &= ~IPCORK_OPT;
-       kfree(inet->cork.opt);
-       inet->cork.opt = NULL;
-       if (inet->cork.rt) {
-               ip_rt_put(inet->cork.rt);
-               inet->cork.rt = NULL;
-       }
+       ip_cork_release(inet);
        return err;
 
 error:
@@ -1295,19 +1300,12 @@ error:
  */
 void ip_flush_pending_frames(struct sock *sk)
 {
-       struct inet_sock *inet = inet_sk(sk);
        struct sk_buff *skb;
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
                kfree_skb(skb);
 
-       inet->cork.flags &= ~IPCORK_OPT;
-       kfree(inet->cork.opt);
-       inet->cork.opt = NULL;
-       if (inet->cork.rt) {
-               ip_rt_put(inet->cork.rt);
-               inet->cork.rt = NULL;
-       }
+       ip_cork_release(inet_sk(sk));
 }
 
 
index f51f20e487c8c74ec078781790d35e7302ba6cb3..82817e5543638e93299e017262693da28bf1bff8 100644 (file)
@@ -437,10 +437,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 
        /* If optlen==0, it is equivalent to val == 0 */
 
-#ifdef CONFIG_IP_MROUTE
-       if (optname >= MRT_BASE && optname <= (MRT_BASE + 10))
+       if (ip_mroute_opt(optname))
                return ip_mroute_setsockopt(sk,optname,optval,optlen);
-#endif
 
        err = 0;
        lock_sock(sk);
@@ -909,11 +907,9 @@ int ip_setsockopt(struct sock *sk, int level,
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
        if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
-               optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
-               && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
-          ) {
+                       optname != IP_IPSEC_POLICY &&
+                       optname != IP_XFRM_POLICY &&
+                       !ip_mroute_opt(optname)) {
                lock_sock(sk);
                err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
                release_sock(sk);
@@ -935,11 +931,9 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
        if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
-           optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
-           && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
-          ) {
+                       optname != IP_IPSEC_POLICY &&
+                       optname != IP_XFRM_POLICY &&
+                       !ip_mroute_opt(optname)) {
                lock_sock(sk);
                err = compat_nf_setsockopt(sk, PF_INET, optname,
                                           optval, optlen);
@@ -967,11 +961,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        if (level != SOL_IP)
                return -EOPNOTSUPP;
 
-#ifdef CONFIG_IP_MROUTE
-       if (optname >= MRT_BASE && optname <= MRT_BASE+10) {
+       if (ip_mroute_opt(optname))
                return ip_mroute_getsockopt(sk,optname,optval,optlen);
-       }
-#endif
 
        if (get_user(len,optlen))
                return -EFAULT;
@@ -1171,11 +1162,8 @@ int ip_getsockopt(struct sock *sk, int level,
        err = do_ip_getsockopt(sk, level, optname, optval, optlen);
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
-       if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
-               && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
-          ) {
+       if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
+                       !ip_mroute_opt(optname)) {
                int len;
 
                if (get_user(len,optlen))
@@ -1200,11 +1188,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
        int err = do_ip_getsockopt(sk, level, optname, optval, optlen);
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
-       if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
-           && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
-          ) {
+       if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
+                       !ip_mroute_opt(optname)) {
                int len;
 
                if (get_user(len, optlen))
index ca1b5fdb8d31387d6400e4188c486b8100059314..2c44a94c2135d80aebb3a8708292b829f6f3bcf6 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <asm/semaphore.h>
 #include <linux/crypto.h>
+#include <linux/err.h>
 #include <linux/pfkeyv2.h>
 #include <linux/percpu.h>
 #include <linux/smp.h>
@@ -344,7 +345,7 @@ static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name)
        for_each_possible_cpu(cpu) {
                struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
                                                            CRYPTO_ALG_ASYNC);
-               if (!tfm)
+               if (IS_ERR(tfm))
                        goto error;
                *per_cpu_ptr(tfms, cpu) = tfm;
        }
index 4b702f708d30637954662a1ccc7f66cd95586569..0a9f3c37e18d8caa939f22d40b7b66dc72df3753 100644 (file)
@@ -425,6 +425,24 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
 }
 
 
+/*
+ * Check if there is a destination for the connection, if so
+ * bind the connection to the destination.
+ */
+struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
+{
+       struct ip_vs_dest *dest;
+
+       if ((cp) && (!cp->dest)) {
+               dest = ip_vs_find_dest(cp->daddr, cp->dport,
+                                      cp->vaddr, cp->vport, cp->protocol);
+               ip_vs_bind_dest(cp, dest);
+               return dest;
+       } else
+               return NULL;
+}
+
+
 /*
  *     Unbind a connection entry with its VS destination
  *     Called by the ip_vs_conn_expire function.
index c6ed7654e839c652ccce23a4064b104b85435eeb..20c884a57721b472ec1c5e756aac3f38b703827d 100644 (file)
@@ -979,15 +979,23 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
                ret = NF_ACCEPT;
        }
 
-       /* increase its packet counter and check if it is needed
-          to be synchronized */
+       /* Increase its packet counter and check if it is needed
+        * to be synchronized
+        *
+        * Sync connection if it is about to close to
+        * encorage the standby servers to update the connections timeout
+        */
        atomic_inc(&cp->in_pkts);
        if ((ip_vs_sync_state & IP_VS_STATE_MASTER) &&
-           (cp->protocol != IPPROTO_TCP ||
-            cp->state == IP_VS_TCP_S_ESTABLISHED) &&
-           (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
-            == sysctl_ip_vs_sync_threshold[0]))
+           (((cp->protocol != IPPROTO_TCP ||
+              cp->state == IP_VS_TCP_S_ESTABLISHED) &&
+             (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
+              == sysctl_ip_vs_sync_threshold[0])) ||
+            ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
+             ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
+              (cp->state == IP_VS_TCP_S_CLOSE)))))
                ip_vs_sync_conn(cp);
+       cp->old_state = cp->state;
 
        ip_vs_conn_put(cp);
        return ret;
index 7345fc252a2315943b77c084a05ecaa45668d3e5..b64cf45a9eadde464169663688b53da624a2a0fd 100644 (file)
@@ -579,6 +579,31 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
        return NULL;
 }
 
+/*
+ * Find destination by {daddr,dport,vaddr,protocol}
+ * Cretaed to be used in ip_vs_process_message() in
+ * the backup synchronization daemon. It finds the
+ * destination to be bound to the received connection
+ * on the backup.
+ *
+ * ip_vs_lookup_real_service() looked promissing, but
+ * seems not working as expected.
+ */
+struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
+                                   __be32 vaddr, __be16 vport, __u16 protocol)
+{
+       struct ip_vs_dest *dest;
+       struct ip_vs_service *svc;
+
+       svc = ip_vs_service_get(0, protocol, vaddr, vport);
+       if (!svc)
+               return NULL;
+       dest = ip_vs_lookup_dest(svc, daddr, dport);
+       if (dest)
+               atomic_inc(&dest->refcnt);
+       ip_vs_service_put(svc);
+       return dest;
+}
 
 /*
  *  Lookup dest by {svc,addr,port} in the destination trash.
index 0d4d9721cbd403c5276151aa643cf6dcf4ea3010..bd930efc18dabb27e0058adc97d20900b02a4ef2 100644 (file)
@@ -284,6 +284,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
        struct ip_vs_sync_conn_options *opt;
        struct ip_vs_conn *cp;
        struct ip_vs_protocol *pp;
+       struct ip_vs_dest *dest;
        char *p;
        int i;
 
@@ -317,20 +318,34 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                                               s->caddr, s->cport,
                                               s->vaddr, s->vport);
                if (!cp) {
+                       /*
+                        * Find the appropriate destination for the connection.
+                        * If it is not found the connection will remain unbound
+                        * but still handled.
+                        */
+                       dest = ip_vs_find_dest(s->daddr, s->dport,
+                                              s->vaddr, s->vport,
+                                              s->protocol);
                        cp = ip_vs_conn_new(s->protocol,
                                            s->caddr, s->cport,
                                            s->vaddr, s->vport,
                                            s->daddr, s->dport,
-                                           flags, NULL);
+                                           flags, dest);
+                       if (dest)
+                               atomic_dec(&dest->refcnt);
                        if (!cp) {
                                IP_VS_ERR("ip_vs_conn_new failed\n");
                                return;
                        }
                        cp->state = ntohs(s->state);
                } else if (!cp->dest) {
-                       /* it is an entry created by the synchronization */
-                       cp->state = ntohs(s->state);
-                       cp->flags = flags | IP_VS_CONN_F_HASHED;
+                       dest = ip_vs_try_bind_dest(cp);
+                       if (!dest) {
+                               /* it is an unbound entry created by
+                                * synchronization */
+                               cp->flags = flags | IP_VS_CONN_F_HASHED;
+                       } else
+                               atomic_dec(&dest->refcnt);
                }       /* Note that we don't touch its state and flags
                           if it is a normal entry. */
 
@@ -342,6 +357,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                        p += SIMPLE_CONN_SIZE;
 
                atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
+               cp->state = ntohs(s->state);
                pp = ip_vs_proto_get(s->protocol);
                cp->timeout = pp->timeout_table[cp->state];
                ip_vs_conn_put(cp);
index 409d273f6f8232f68a71e7f4240d6a106285e513..7456833d6ade438f3b5c5f478fb6062cdaf5e3a2 100644 (file)
@@ -41,27 +41,27 @@ obj-$(CONFIG_NF_NAT) += iptable_nat.o
 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 
 # matches
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
-obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
-obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
-obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
-obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
 
 # targets
-obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
-obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
+obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
+obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
-obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
-obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
-obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
-obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
+obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
+obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 
 # generic ARP tables
 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
index 10a2ce09fd8e9e88065250c2ed4f96225e15d646..14d64a383db1a7223ed321e5dedfbc1942af1095 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/security.h>
 #include <linux/mutex.h>
 #include <net/net_namespace.h>
@@ -607,15 +608,11 @@ static ctl_table ipq_root_table[] = {
        { .ctl_name = 0 }
 };
 
-#ifdef CONFIG_PROC_FS
-static int
-ipq_get_info(char *buffer, char **start, off_t offset, int length)
+static int ip_queue_show(struct seq_file *m, void *v)
 {
-       int len;
-
        read_lock_bh(&queue_lock);
 
-       len = sprintf(buffer,
+       seq_printf(m,
                      "Peer PID          : %d\n"
                      "Copy mode         : %hu\n"
                      "Copy range        : %u\n"
@@ -632,16 +629,21 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
                      queue_user_dropped);
 
        read_unlock_bh(&queue_lock);
+       return 0;
+}
 
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
-       else if (len < 0)
-               len = 0;
-       return len;
+static int ip_queue_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ip_queue_show, NULL);
 }
-#endif /* CONFIG_PROC_FS */
+
+static const struct file_operations ip_queue_proc_fops = {
+       .open           = ip_queue_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .owner          = THIS_MODULE,
+};
 
 static struct nf_queue_handler nfqh = {
        .name   = "ip_queue",
@@ -661,10 +663,11 @@ static int __init ip_queue_init(void)
                goto cleanup_netlink_notifier;
        }
 
-       proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
-       if (proc)
+       proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+       if (proc) {
                proc->owner = THIS_MODULE;
-       else {
+               proc->proc_fops = &ip_queue_proc_fops;
+       } else {
                printk(KERN_ERR "ip_queue: failed to create proc entry\n");
                goto cleanup_ipqnl;
        }
index 35a5aa69cd92bb9b912c326a167c3233eb20032b..c31b876682502c5d6c13523ff086103e49c5fd7f 100644 (file)
@@ -69,7 +69,7 @@ static void __exit nf_nat_amanda_fini(void)
 
 static int __init nf_nat_amanda_init(void)
 {
-       BUG_ON(rcu_dereference(nf_nat_amanda_hook));
+       BUG_ON(nf_nat_amanda_hook != NULL);
        rcu_assign_pointer(nf_nat_amanda_hook, help);
        return 0;
 }
index 56e93f692e82b363c010de0eeef16428a8ce4ba5..70e7997ea2844aead26de3776008cbbdd73358c9 100644 (file)
@@ -681,7 +681,7 @@ static int clean_nat(struct nf_conn *i, void *data)
 
        if (!nat)
                return 0;
-       memset(nat, 0, sizeof(nat));
+       memset(nat, 0, sizeof(*nat));
        i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
        return 0;
 }
index e1a16d3ea4cbaba6df03e47ab57f590f4a140240..a1d5d58a58bf904b25115fe8dff4397e4d541a29 100644 (file)
@@ -147,7 +147,7 @@ static void __exit nf_nat_ftp_fini(void)
 
 static int __init nf_nat_ftp_init(void)
 {
-       BUG_ON(rcu_dereference(nf_nat_ftp_hook));
+       BUG_ON(nf_nat_ftp_hook != NULL);
        rcu_assign_pointer(nf_nat_ftp_hook, nf_nat_ftp);
        return 0;
 }
index a868c8c4132860275b89c87364ac0cb840a16cc8..93e18ef114f2e1052798d1b2d2f200cafb345b6a 100644 (file)
@@ -544,15 +544,15 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
 /****************************************************************************/
 static int __init init(void)
 {
-       BUG_ON(rcu_dereference(set_h245_addr_hook) != NULL);
-       BUG_ON(rcu_dereference(set_h225_addr_hook) != NULL);
-       BUG_ON(rcu_dereference(set_sig_addr_hook) != NULL);
-       BUG_ON(rcu_dereference(set_ras_addr_hook) != NULL);
-       BUG_ON(rcu_dereference(nat_rtp_rtcp_hook) != NULL);
-       BUG_ON(rcu_dereference(nat_t120_hook) != NULL);
-       BUG_ON(rcu_dereference(nat_h245_hook) != NULL);
-       BUG_ON(rcu_dereference(nat_callforwarding_hook) != NULL);
-       BUG_ON(rcu_dereference(nat_q931_hook) != NULL);
+       BUG_ON(set_h245_addr_hook != NULL);
+       BUG_ON(set_h225_addr_hook != NULL);
+       BUG_ON(set_sig_addr_hook != NULL);
+       BUG_ON(set_ras_addr_hook != NULL);
+       BUG_ON(nat_rtp_rtcp_hook != NULL);
+       BUG_ON(nat_t120_hook != NULL);
+       BUG_ON(nat_h245_hook != NULL);
+       BUG_ON(nat_callforwarding_hook != NULL);
+       BUG_ON(nat_q931_hook != NULL);
 
        rcu_assign_pointer(set_h245_addr_hook, set_h245_addr);
        rcu_assign_pointer(set_h225_addr_hook, set_h225_addr);
index 766e2c16c6b957c81eecc245ff0ff7521b7afe82..fe6f9cef6c854d4c13c9a8ecb5951a6f33f68b00 100644 (file)
@@ -74,7 +74,7 @@ static void __exit nf_nat_irc_fini(void)
 
 static int __init nf_nat_irc_init(void)
 {
-       BUG_ON(rcu_dereference(nf_nat_irc_hook));
+       BUG_ON(nf_nat_irc_hook != NULL);
        rcu_assign_pointer(nf_nat_irc_hook, help);
        return 0;
 }
index e1385a0990796f333b3ba5f903b8f3900235a1c1..6817e7995f35ca4963c1757e939e7e904f9f92f8 100644 (file)
@@ -281,16 +281,16 @@ static int __init nf_nat_helper_pptp_init(void)
 {
        nf_nat_need_gre();
 
-       BUG_ON(rcu_dereference(nf_nat_pptp_hook_outbound));
+       BUG_ON(nf_nat_pptp_hook_outbound != NULL);
        rcu_assign_pointer(nf_nat_pptp_hook_outbound, pptp_outbound_pkt);
 
-       BUG_ON(rcu_dereference(nf_nat_pptp_hook_inbound));
+       BUG_ON(nf_nat_pptp_hook_inbound != NULL);
        rcu_assign_pointer(nf_nat_pptp_hook_inbound, pptp_inbound_pkt);
 
-       BUG_ON(rcu_dereference(nf_nat_pptp_hook_exp_gre));
+       BUG_ON(nf_nat_pptp_hook_exp_gre != NULL);
        rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, pptp_exp_gre);
 
-       BUG_ON(rcu_dereference(nf_nat_pptp_hook_expectfn));
+       BUG_ON(nf_nat_pptp_hook_expectfn != NULL);
        rcu_assign_pointer(nf_nat_pptp_hook_expectfn, pptp_nat_expected);
        return 0;
 }
index ce9edbcc01e387dc8ca320f28adc40520718dbae..3ca98971a1e92c3385e7398fffb87168ad900c46 100644 (file)
@@ -293,8 +293,8 @@ static void __exit nf_nat_sip_fini(void)
 
 static int __init nf_nat_sip_init(void)
 {
-       BUG_ON(rcu_dereference(nf_nat_sip_hook));
-       BUG_ON(rcu_dereference(nf_nat_sdp_hook));
+       BUG_ON(nf_nat_sip_hook != NULL);
+       BUG_ON(nf_nat_sdp_hook != NULL);
        rcu_assign_pointer(nf_nat_sip_hook, ip_nat_sip);
        rcu_assign_pointer(nf_nat_sdp_hook, ip_nat_sdp);
        return 0;
index 0ecec701cb448dc23224182aec2489ddf43f9e49..1360a94766dd6321d7f1a07d719d88adce5a44f1 100644 (file)
@@ -43,7 +43,7 @@ static void __exit nf_nat_tftp_fini(void)
 
 static int __init nf_nat_tftp_init(void)
 {
-       BUG_ON(rcu_dereference(nf_nat_tftp_hook));
+       BUG_ON(nf_nat_tftp_hook != NULL);
        rcu_assign_pointer(nf_nat_tftp_hook, help);
        return 0;
 }
index ffdccc0972e039d52dd5e236ee71f677fb4474f2..ce34b281803f479ba29196aafaad416a01441191 100644 (file)
 #include <net/sock.h>
 #include <net/raw.h>
 
-static int fold_prot_inuse(struct proto *proto)
-{
-       int res = 0;
-       int cpu;
-
-       for_each_possible_cpu(cpu)
-               res += proto->stats[cpu].inuse;
-
-       return res;
-}
-
 /*
  *     Report socket allocation statistics [mea@utu.fi]
  */
@@ -64,12 +53,12 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
 {
        socket_seq_show(seq);
        seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
-                  fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
+                  sock_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
                   tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
                   atomic_read(&tcp_memory_allocated));
-       seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
-       seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
-       seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
+       seq_printf(seq, "UDP: inuse %d\n", sock_prot_inuse(&udp_prot));
+       seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse(&udplite_prot));
+       seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse(&raw_prot));
        seq_printf(seq,  "FRAG: inuse %d memory %d\n",
                        ip_frag_nqueues(), ip_frag_mem());
        return 0;
index 3916faca3afef64fcbc8d583715b384f364c56d7..66b42f547bf9c0b21bd2462a4534e54978b2813f 100644 (file)
@@ -760,6 +760,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
        }
 }
 
+DEFINE_PROTO_INUSE(raw)
+
 struct proto raw_prot = {
        .name              = "RAW",
        .owner             = THIS_MODULE,
@@ -781,6 +783,7 @@ struct proto raw_prot = {
        .compat_setsockopt = compat_raw_setsockopt,
        .compat_getsockopt = compat_raw_getsockopt,
 #endif
+       REF_PROTO_INUSE(raw)
 };
 
 #ifdef CONFIG_PROC_FS
index 21b12de9e6536663d5da2b60bd1d94b1d984acdd..1bff9ed349ff5a9e5d14ba1f09888e304bd88950 100644 (file)
@@ -578,6 +578,9 @@ static void rt_check_expire(struct work_struct *work)
                i = (i + 1) & rt_hash_mask;
                rthp = &rt_hash_table[i].chain;
 
+               if (need_resched())
+                       cond_resched();
+
                if (*rthp == NULL)
                        continue;
                spin_lock_bh(rt_hash_lock_addr(i));
@@ -851,9 +854,7 @@ restart:
                         */
                        rcu_assign_pointer(rt_hash_table[hash].chain, rth);
 
-                       rth->u.dst.__use++;
-                       dst_hold(&rth->u.dst);
-                       rth->u.dst.lastuse = now;
+                       dst_use(&rth->u.dst, now);
                        spin_unlock_bh(rt_hash_lock_addr(hash));
 
                        rt_drop(rt);
@@ -1813,11 +1814,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                goto martian_destination;
 
        err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
-       if (err == -ENOBUFS)
-               goto e_nobufs;
-       if (err == -EINVAL)
-               goto e_inval;
-
 done:
        in_dev_put(in_dev);
        if (free_res)
@@ -1935,9 +1931,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                    rth->fl.oif == 0 &&
                    rth->fl.mark == skb->mark &&
                    rth->fl.fl4_tos == tos) {
-                       rth->u.dst.lastuse = jiffies;
-                       dst_hold(&rth->u.dst);
-                       rth->u.dst.__use++;
+                       dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(in_hit);
                        rcu_read_unlock();
                        skb->dst = (struct dst_entry*)rth;
@@ -2331,9 +2325,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
                    rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
                            (IPTOS_RT_MASK | RTO_ONLINK))) {
-                       rth->u.dst.lastuse = jiffies;
-                       dst_hold(&rth->u.dst);
-                       rth->u.dst.__use++;
+                       dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(out_hit);
                        rcu_read_unlock_bh();
                        *rp = rth;
index c64072bb504b3f6debca30cf670c411c30944d37..8e65182f7af1cd04f71bb4d1f5b33bf8d2c2793c 100644 (file)
@@ -2456,11 +2456,11 @@ void __init tcp_init(void)
                                        thash_entries ? 0 : 512 * 1024);
        tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
        for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
-               rwlock_init(&tcp_hashinfo.ehash[i].lock);
                INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain);
                INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain);
        }
-
+       if (inet_ehash_locks_alloc(&tcp_hashinfo))
+               panic("TCP: failed to alloc ehash_locks");
        tcp_hashinfo.bhash =
                alloc_large_system_hash("TCP bind",
                                        sizeof(struct inet_bind_hashbucket),
index ca9590f4f520a4b08a2913659a1a48b374d341d9..0f0c1c9829a14b41e9654b3a108d2f1aa3b5e6f1 100644 (file)
@@ -1269,6 +1269,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window))
                return 0;
 
+       if (!tp->packets_out)
+               goto out;
+
        /* SACK fastpath:
         * if the only SACK change is the increase of the end_seq of
         * the first block then only apply that SACK block
@@ -1400,11 +1403,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                        /* DSACK info lost if out-of-mem, try SACK still */
                        if (in_sack <= 0)
                                in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq);
-                       if (in_sack < 0)
+                       if (unlikely(in_sack < 0))
                                break;
 
-                       fack_count += tcp_skb_pcount(skb);
-
                        sacked = TCP_SKB_CB(skb)->sacked;
 
                        /* Account D-SACK for retransmitted packet. */
@@ -1419,19 +1420,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                                        if ((dup_sack && in_sack) &&
                                            (sacked&TCPCB_SACKED_ACKED))
                                                reord = min(fack_count, reord);
-                               } else {
-                                       /* If it was in a hole, we detected reordering. */
-                                       if (fack_count < prior_fackets &&
-                                           !(sacked&TCPCB_SACKED_ACKED))
-                                               reord = min(fack_count, reord);
                                }
 
                                /* Nothing to do; acked frame is about to be dropped. */
+                               fack_count += tcp_skb_pcount(skb);
                                continue;
                        }
 
-                       if (!in_sack)
+                       if (!in_sack) {
+                               fack_count += tcp_skb_pcount(skb);
                                continue;
+                       }
 
                        if (!(sacked&TCPCB_SACKED_ACKED)) {
                                if (sacked & TCPCB_SACKED_RETRANS) {
@@ -1448,12 +1447,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                                                tp->retransmit_skb_hint = NULL;
                                        }
                                } else {
-                                       /* New sack for not retransmitted frame,
-                                        * which was in hole. It is reordering.
-                                        */
-                                       if (!(sacked & TCPCB_RETRANS) &&
-                                           fack_count < prior_fackets)
-                                               reord = min(fack_count, reord);
+                                       if (!(sacked & TCPCB_RETRANS)) {
+                                               /* New sack for not retransmitted frame,
+                                                * which was in hole. It is reordering.
+                                                */
+                                               if (fack_count < prior_fackets)
+                                                       reord = min(fack_count, reord);
+
+                                               /* SACK enhanced F-RTO (RFC4138; Appendix B) */
+                                               if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
+                                                       flag |= FLAG_ONLY_ORIG_SACKED;
+                                       }
 
                                        if (sacked & TCPCB_LOST) {
                                                TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
@@ -1462,24 +1466,13 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                                                /* clear lost hint */
                                                tp->retransmit_skb_hint = NULL;
                                        }
-                                       /* SACK enhanced F-RTO detection.
-                                        * Set flag if and only if non-rexmitted
-                                        * segments below frto_highmark are
-                                        * SACKed (RFC4138; Appendix B).
-                                        * Clearing correct due to in-order walk
-                                        */
-                                       if (after(end_seq, tp->frto_highmark)) {
-                                               flag &= ~FLAG_ONLY_ORIG_SACKED;
-                                       } else {
-                                               if (!(sacked & TCPCB_RETRANS))
-                                                       flag |= FLAG_ONLY_ORIG_SACKED;
-                                       }
                                }
 
                                TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
                                flag |= FLAG_DATA_SACKED;
                                tp->sacked_out += tcp_skb_pcount(skb);
 
+                               fack_count += tcp_skb_pcount(skb);
                                if (fack_count > tp->fackets_out)
                                        tp->fackets_out = fack_count;
 
@@ -1490,6 +1483,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                        } else {
                                if (dup_sack && (sacked&TCPCB_RETRANS))
                                        reord = min(fack_count, reord);
+
+                               fack_count += tcp_skb_pcount(skb);
                        }
 
                        /* D-SACK. We can detect redundant retransmission
@@ -1504,6 +1499,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                                tp->retransmit_skb_hint = NULL;
                        }
                }
+
+               /* SACK enhanced FRTO (RFC4138, Appendix B): Clearing correct
+                * due to in-order walk
+                */
+               if (after(end_seq, tp->frto_highmark))
+                       flag &= ~FLAG_ONLY_ORIG_SACKED;
        }
 
        if (tp->retrans_out &&
@@ -1515,7 +1516,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
 
        if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss &&
            (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark)))
-               tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0);
+               tcp_update_reordering(sk, tp->fackets_out - reord, 0);
+
+out:
 
 #if FASTRETRANS_DEBUG > 0
        BUG_TRAP((int)tp->sacked_out >= 0);
@@ -1671,6 +1674,9 @@ void tcp_enter_frto(struct sock *sk)
        }
        tcp_verify_left_out(tp);
 
+       /* Too bad if TCP was application limited */
+       tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp) + 1);
+
        /* Earlier loss recovery underway (see RFC4138; Appendix B).
         * The last condition is necessary at least in tp->frto_counter case.
         */
@@ -1703,6 +1709,8 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
        tcp_for_write_queue(skb, sk) {
                if (skb == tcp_send_head(sk))
                        break;
+
+               TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
                /*
                 * Count the retransmission made on RTO correctly (only when
                 * waiting for the first ACK and did not get it)...
@@ -1716,7 +1724,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
                } else {
                        if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
                                tp->undo_marker = 0;
-                       TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
+                       TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
                }
 
                /* Don't lost mark skbs that were fwd transmitted after RTO */
@@ -2630,7 +2638,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
  * is before the ack sequence we can discard it as it's confirmed to have
  * arrived at the other end.
  */
-static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
+static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
+                              int prior_fackets)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2639,6 +2648,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
        int fully_acked = 1;
        int flag = 0;
        int prior_packets = tp->packets_out;
+       u32 cnt = 0;
+       u32 reord = tp->packets_out;
        s32 seq_rtt = -1;
        ktime_t last_ackt = net_invalid_timestamp();
 
@@ -2679,10 +2690,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
                                if ((flag & FLAG_DATA_ACKED) ||
                                    (packets_acked > 1))
                                        flag |= FLAG_NONHEAD_RETRANS_ACKED;
-                       } else if (seq_rtt < 0) {
-                               seq_rtt = now - scb->when;
-                               if (fully_acked)
-                                       last_ackt = skb->tstamp;
+                       } else {
+                               if (seq_rtt < 0) {
+                                       seq_rtt = now - scb->when;
+                                       if (fully_acked)
+                                               last_ackt = skb->tstamp;
+                               }
+                               if (!(sacked & TCPCB_SACKED_ACKED))
+                                       reord = min(cnt, reord);
                        }
 
                        if (sacked & TCPCB_SACKED_ACKED)
@@ -2693,12 +2708,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
                        if ((sacked & TCPCB_URG) && tp->urg_mode &&
                            !before(end_seq, tp->snd_up))
                                tp->urg_mode = 0;
-               } else if (seq_rtt < 0) {
-                       seq_rtt = now - scb->when;
-                       if (fully_acked)
-                               last_ackt = skb->tstamp;
+               } else {
+                       if (seq_rtt < 0) {
+                               seq_rtt = now - scb->when;
+                               if (fully_acked)
+                                       last_ackt = skb->tstamp;
+                       }
+                       reord = min(cnt, reord);
                }
                tp->packets_out -= packets_acked;
+               cnt += packets_acked;
 
                /* Initial outgoing SYN's get put onto the write_queue
                 * just like anything else we transmit.  It is not
@@ -2730,13 +2749,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
                tcp_ack_update_rtt(sk, flag, seq_rtt);
                tcp_rearm_rto(sk);
 
+               if (tcp_is_reno(tp)) {
+                       tcp_remove_reno_sacks(sk, pkts_acked);
+               } else {
+                       /* Non-retransmitted hole got filled? That's reordering */
+                       if (reord < prior_fackets)
+                               tcp_update_reordering(sk, tp->fackets_out - reord, 0);
+               }
+
                tp->fackets_out -= min(pkts_acked, tp->fackets_out);
                /* hint's skb might be NULL but we don't need to care */
                tp->fastpath_cnt_hint -= min_t(u32, pkts_acked,
                                               tp->fastpath_cnt_hint);
-               if (tcp_is_reno(tp))
-                       tcp_remove_reno_sacks(sk, pkts_acked);
-
                if (ca_ops->pkts_acked) {
                        s32 rtt_us = -1;
 
@@ -3019,6 +3043,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
        u32 ack_seq = TCP_SKB_CB(skb)->seq;
        u32 ack = TCP_SKB_CB(skb)->ack_seq;
        u32 prior_in_flight;
+       u32 prior_fackets;
        s32 seq_rtt;
        int prior_packets;
        int frto_cwnd = 0;
@@ -3043,6 +3068,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
                        tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache);
        }
 
+       prior_fackets = tp->fackets_out;
+
        if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
                /* Window is constant, pure forward advance.
                 * No more checks are required.
@@ -3084,13 +3111,13 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
        prior_in_flight = tcp_packets_in_flight(tp);
 
        /* See if we can take anything off of the retransmit queue. */
-       flag |= tcp_clean_rtx_queue(sk, &seq_rtt);
+       flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets);
 
+       if (tp->frto_counter)
+               frto_cwnd = tcp_process_frto(sk, flag);
        /* Guarantee sacktag reordering detection against wrap-arounds */
        if (before(tp->frto_highmark, tp->snd_una))
                tp->frto_highmark = 0;
-       if (tp->frto_counter)
-               frto_cwnd = tcp_process_frto(sk, flag);
 
        if (tcp_ack_is_dubious(sk, flag)) {
                /* Advance CWND, if state allows this. */
index d438dfb0c8f38a9f53833a6283eb30a40741ff78..e566f3c676772d6a7141bb50213d7eb0430135d3 100644 (file)
@@ -2049,8 +2049,9 @@ static void *established_get_first(struct seq_file *seq)
                struct sock *sk;
                struct hlist_node *node;
                struct inet_timewait_sock *tw;
+               rwlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket);
 
-               read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_lock_bh(lock);
                sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
                        if (sk->sk_family != st->family) {
                                continue;
@@ -2067,7 +2068,7 @@ static void *established_get_first(struct seq_file *seq)
                        rc = tw;
                        goto out;
                }
-               read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_unlock_bh(lock);
                st->state = TCP_SEQ_STATE_ESTABLISHED;
        }
 out:
@@ -2094,11 +2095,11 @@ get_tw:
                        cur = tw;
                        goto out;
                }
-               read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
                st->state = TCP_SEQ_STATE_ESTABLISHED;
 
                if (++st->bucket < tcp_hashinfo.ehash_size) {
-                       read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+                       read_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
                        sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
                } else {
                        cur = NULL;
@@ -2206,7 +2207,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
        case TCP_SEQ_STATE_TIME_WAIT:
        case TCP_SEQ_STATE_ESTABLISHED:
                if (v)
-                       read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+                       read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
                break;
        }
 }
@@ -2417,6 +2418,8 @@ void tcp4_proc_exit(void)
 }
 #endif /* CONFIG_PROC_FS */
 
+DEFINE_PROTO_INUSE(tcp)
+
 struct proto tcp_prot = {
        .name                   = "TCP",
        .owner                  = THIS_MODULE,
@@ -2451,6 +2454,7 @@ struct proto tcp_prot = {
        .compat_setsockopt      = compat_tcp_setsockopt,
        .compat_getsockopt      = compat_tcp_getsockopt,
 #endif
+       REF_PROTO_INUSE(tcp)
 };
 
 void __init tcp_v4_init(struct net_proto_family *ops)
index a794a8ca8b4fd86e1b501448eab60a2a5a99e1bb..978b3fd61e65533f3cf01f26521fc6f406288fac 100644 (file)
@@ -17,6 +17,11 @@ static struct xfrm_tunnel *tunnel4_handlers;
 static struct xfrm_tunnel *tunnel64_handlers;
 static DEFINE_MUTEX(tunnel4_mutex);
 
+static inline struct xfrm_tunnel **fam_handlers(unsigned short family)
+{
+       return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
+}
+
 int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
 {
        struct xfrm_tunnel **pprev;
@@ -25,8 +30,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
 
        mutex_lock(&tunnel4_mutex);
 
-       for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
-            *pprev; pprev = &(*pprev)->next) {
+       for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
                if ((*pprev)->priority > priority)
                        break;
                if ((*pprev)->priority == priority)
@@ -53,8 +57,7 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
 
        mutex_lock(&tunnel4_mutex);
 
-       for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
-            *pprev; pprev = &(*pprev)->next) {
+       for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
                if (*pprev == handler) {
                        *pprev = handler->next;
                        ret = 0;
@@ -118,6 +121,17 @@ static void tunnel4_err(struct sk_buff *skb, u32 info)
                        break;
 }
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static void tunnel64_err(struct sk_buff *skb, u32 info)
+{
+       struct xfrm_tunnel *handler;
+
+       for (handler = tunnel64_handlers; handler; handler = handler->next)
+               if (!handler->err_handler(skb, info))
+                       break;
+}
+#endif
+
 static struct net_protocol tunnel4_protocol = {
        .handler        =       tunnel4_rcv,
        .err_handler    =       tunnel4_err,
@@ -127,7 +141,7 @@ static struct net_protocol tunnel4_protocol = {
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static struct net_protocol tunnel64_protocol = {
        .handler        =       tunnel64_rcv,
-       .err_handler    =       tunnel4_err,
+       .err_handler    =       tunnel64_err,
        .no_policy      =       1,
 };
 #endif
index 4bc25b46f33ff9138512e5da915d01007048e9d0..03c400ca14c5af07db1ab22686d95621b5cc8813 100644 (file)
@@ -1430,6 +1430,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
 }
 
+DEFINE_PROTO_INUSE(udp)
+
 struct proto udp_prot = {
        .name              = "UDP",
        .owner             = THIS_MODULE,
@@ -1452,6 +1454,7 @@ struct proto udp_prot = {
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
 #endif
+       REF_PROTO_INUSE(udp)
 };
 
 /* ------------------------------------------------------------------------ */
index 94977205abb47581686bfd46bc1f5232100f005a..f5baeb3e8b85d368e075cd57ca7cd8c48b68702b 100644 (file)
@@ -44,6 +44,8 @@ static        struct net_protocol udplite_protocol = {
        .no_policy      = 1,
 };
 
+DEFINE_PROTO_INUSE(udplite)
+
 struct proto   udplite_prot = {
        .name              = "UDP-Lite",
        .owner             = THIS_MODULE,
@@ -67,6 +69,7 @@ struct proto  udplite_prot = {
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
 #endif
+       REF_PROTO_INUSE(udplite)
 };
 
 static struct inet_protosw udplite4_protosw = {
index 706622af206f1f7f5a04479223a1c4aa84334238..428c6b0e26d8e7238530e6b3d1c886f5c398af98 100644 (file)
@@ -31,25 +31,6 @@ struct fib6_rule
 
 static struct fib_rules_ops fib6_rules_ops;
 
-static struct fib6_rule main_rule = {
-       .common = {
-               .refcnt =       ATOMIC_INIT(2),
-               .pref =         0x7FFE,
-               .action =       FR_ACT_TO_TBL,
-               .table =        RT6_TABLE_MAIN,
-       },
-};
-
-static struct fib6_rule local_rule = {
-       .common = {
-               .refcnt =       ATOMIC_INIT(2),
-               .pref =         0,
-               .action =       FR_ACT_TO_TBL,
-               .table =        RT6_TABLE_LOCAL,
-               .flags =        FIB_RULE_PERMANENT,
-       },
-};
-
 struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
                                   pol_lookup_t lookup)
 {
@@ -270,11 +251,23 @@ static struct fib_rules_ops fib6_rules_ops = {
        .owner                  = THIS_MODULE,
 };
 
-void __init fib6_rules_init(void)
+static int __init fib6_default_rules_init(void)
 {
-       list_add_tail(&local_rule.common.list, &fib6_rules_ops.rules_list);
-       list_add_tail(&main_rule.common.list, &fib6_rules_ops.rules_list);
+       int err;
+
+       err = fib_default_rule_add(&fib6_rules_ops, 0,
+                                  RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
+       if (err < 0)
+               return err;
+       err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0);
+       if (err < 0)
+               return err;
+       return 0;
+}
 
+void __init fib6_rules_init(void)
+{
+       BUG_ON(fib6_default_rules_init());
        fib_rules_register(&fib6_rules_ops);
 }
 
index d6f1026f19438114bfef264b1f669cf03f0fd131..adc73adadfae47a892da6527309396e57a530590 100644 (file)
@@ -37,9 +37,8 @@ void __inet6_hash(struct inet_hashinfo *hashinfo,
        } else {
                unsigned int hash;
                sk->sk_hash = hash = inet6_sk_ehashfn(sk);
-               hash &= (hashinfo->ehash_size - 1);
-               list = &hashinfo->ehash[hash].chain;
-               lock = &hashinfo->ehash[hash].lock;
+               list = &inet_ehash_bucket(hashinfo, hash)->chain;
+               lock = inet_ehash_lockp(hashinfo, hash);
                write_lock(lock);
        }
 
@@ -70,9 +69,10 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
         */
        unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
 
        prefetch(head->chain.first);
-       read_lock(&head->lock);
+       read_lock(lock);
        sk_for_each(sk, node, &head->chain) {
                /* For IPV6 do the cheaper port and family tests first. */
                if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
@@ -92,12 +92,12 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
                                goto hit;
                }
        }
-       read_unlock(&head->lock);
+       read_unlock(lock);
        return NULL;
 
 hit:
        sock_hold(sk);
-       read_unlock(&head->lock);
+       read_unlock(lock);
        return sk;
 }
 EXPORT_SYMBOL(__inet6_lookup_established);
@@ -175,12 +175,13 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
        const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
                                                inet->dport);
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+       rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
        struct sock *sk2;
        const struct hlist_node *node;
        struct inet_timewait_sock *tw;
 
        prefetch(head->chain.first);
-       write_lock(&head->lock);
+       write_lock(lock);
 
        /* Check TIME-WAIT sockets first. */
        sk_for_each(sk2, node, &head->twchain) {
@@ -216,7 +217,7 @@ unique:
        __sk_add_node(sk, &head->chain);
        sk->sk_hash = hash;
        sock_prot_inc_use(sk->sk_prot);
-       write_unlock(&head->lock);
+       write_unlock(lock);
 
        if (twp != NULL) {
                *twp = tw;
@@ -231,7 +232,7 @@ unique:
        return 0;
 
 not_unique:
-       write_unlock(&head->lock);
+       write_unlock(lock);
        return -EADDRNOTAVAIL;
 }
 
index 653fc0a8235b636e6e03921b77163a8ee8817b5c..86e1835ce4e4bcd71a25a9443f656872ab10c0a8 100644 (file)
@@ -1339,6 +1339,19 @@ error:
        return err;
 }
 
+static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
+{
+       inet->cork.flags &= ~IPCORK_OPT;
+       kfree(np->cork.opt);
+       np->cork.opt = NULL;
+       if (np->cork.rt) {
+               dst_release(&np->cork.rt->u.dst);
+               np->cork.rt = NULL;
+               inet->cork.flags &= ~IPCORK_ALLFRAG;
+       }
+       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+}
+
 int ip6_push_pending_frames(struct sock *sk)
 {
        struct sk_buff *skb, *tmp_skb;
@@ -1415,15 +1428,7 @@ int ip6_push_pending_frames(struct sock *sk)
        }
 
 out:
-       inet->cork.flags &= ~IPCORK_OPT;
-       kfree(np->cork.opt);
-       np->cork.opt = NULL;
-       if (np->cork.rt) {
-               dst_release(&np->cork.rt->u.dst);
-               np->cork.rt = NULL;
-               inet->cork.flags &= ~IPCORK_ALLFRAG;
-       }
-       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+       ip6_cork_release(inet, np);
        return err;
 error:
        goto out;
@@ -1431,8 +1436,6 @@ error:
 
 void ip6_flush_pending_frames(struct sock *sk)
 {
-       struct inet_sock *inet = inet_sk(sk);
-       struct ipv6_pinfo *np = inet6_sk(sk);
        struct sk_buff *skb;
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
@@ -1442,14 +1445,5 @@ void ip6_flush_pending_frames(struct sock *sk)
                kfree_skb(skb);
        }
 
-       inet->cork.flags &= ~IPCORK_OPT;
-
-       kfree(np->cork.opt);
-       np->cork.opt = NULL;
-       if (np->cork.rt) {
-               dst_release(&np->cork.rt->u.dst);
-               np->cork.rt = NULL;
-               inet->cork.flags &= ~IPCORK_ALLFRAG;
-       }
-       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+       ip6_cork_release(inet_sk(sk), inet6_sk(sk));
 }
index 85eb4798d8d2a856bb6810db6bf66ecc3556600b..0cd4056f9127e3434cbb63ed27ebcaddb404f54c 100644 (file)
@@ -36,6 +36,7 @@
 #include <net/ipcomp.h>
 #include <asm/semaphore.h>
 #include <linux/crypto.h>
+#include <linux/err.h>
 #include <linux/pfkeyv2.h>
 #include <linux/random.h>
 #include <linux/percpu.h>
@@ -358,7 +359,7 @@ static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name)
        for_each_possible_cpu(cpu) {
                struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
                                                            CRYPTO_ALG_ASYNC);
-               if (!tfm)
+               if (IS_ERR(tfm))
                        goto error;
                *per_cpu_ptr(tfms, cpu) = tfm;
        }
index 36f7dbfb6dbbd72cc36cca13157930c9fdc4915a..67997a74ddce15d85e43c8146a9ed62f91085f77 100644 (file)
@@ -1037,6 +1037,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
 
        ndmsg = nlmsg_data(nlh);
        ndmsg->nduseropt_family = AF_INET6;
+       ndmsg->nduseropt_ifindex = ra->dev->ifindex;
        ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
        ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
        ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
index 4513eab773973e3db0722394b550b7a961125d24..e789ec44d23b2e5cacdf154bf4709372d4e00d88 100644 (file)
@@ -4,25 +4,29 @@
 
 # Link order matters here.
 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
-obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
-obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
-obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
-obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
-obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
-obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
-obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
-obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
-obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
-obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
-obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
 
 # objects for l3 independent conntrack
 nf_conntrack_ipv6-objs  :=  nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
 
 # l3 independent conntrack
 obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
+
+# matches
+obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
+obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
+obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
+obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
+obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
+obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
+obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
+obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
+obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
+
+# targets
+obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
+obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
+obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
index 6413a30d9f68858cea06a0f6bac64233bdfd8aa0..e273605eef855469794849f9cdfd800d659e87e7 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/mutex.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
@@ -596,15 +597,11 @@ static ctl_table ipq_root_table[] = {
        { .ctl_name = 0 }
 };
 
-#ifdef CONFIG_PROC_FS
-static int
-ipq_get_info(char *buffer, char **start, off_t offset, int length)
+static int ip6_queue_show(struct seq_file *m, void *v)
 {
-       int len;
-
        read_lock_bh(&queue_lock);
 
-       len = sprintf(buffer,
+       seq_printf(m,
                      "Peer PID          : %d\n"
                      "Copy mode         : %hu\n"
                      "Copy range        : %u\n"
@@ -621,16 +618,21 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
                      queue_user_dropped);
 
        read_unlock_bh(&queue_lock);
+       return 0;
+}
 
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
-       else if (len < 0)
-               len = 0;
-       return len;
+static int ip6_queue_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ip6_queue_show, NULL);
 }
-#endif /* CONFIG_PROC_FS */
+
+static const struct file_operations ip6_queue_proc_fops = {
+       .open           = ip6_queue_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .owner          = THIS_MODULE,
+};
 
 static struct nf_queue_handler nfqh = {
        .name   = "ip6_queue",
@@ -650,10 +652,11 @@ static int __init ip6_queue_init(void)
                goto cleanup_netlink_notifier;
        }
 
-       proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
-       if (proc)
+       proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+       if (proc) {
                proc->owner = THIS_MODULE;
-       else {
+               proc->proc_fops = &ip6_queue_proc_fops;
+       } else {
                printk(KERN_ERR "ip6_queue: failed to create proc entry\n");
                goto cleanup_ipqnl;
        }
index be526ad925431b96040e26683ae63f8d2426b203..8631ed7fe8a9a84b65b398c9557e1f45ad20e220 100644 (file)
 
 static struct proc_dir_entry *proc_net_devsnmp6;
 
-static int fold_prot_inuse(struct proto *proto)
-{
-       int res = 0;
-       int cpu;
-
-       for_each_possible_cpu(cpu)
-               res += proto->stats[cpu].inuse;
-
-       return res;
-}
-
 static int sockstat6_seq_show(struct seq_file *seq, void *v)
 {
        seq_printf(seq, "TCP6: inuse %d\n",
-                      fold_prot_inuse(&tcpv6_prot));
+                      sock_prot_inuse(&tcpv6_prot));
        seq_printf(seq, "UDP6: inuse %d\n",
-                      fold_prot_inuse(&udpv6_prot));
+                      sock_prot_inuse(&udpv6_prot));
        seq_printf(seq, "UDPLITE6: inuse %d\n",
-                       fold_prot_inuse(&udplitev6_prot));
+                       sock_prot_inuse(&udplitev6_prot));
        seq_printf(seq, "RAW6: inuse %d\n",
-                      fold_prot_inuse(&rawv6_prot));
+                      sock_prot_inuse(&rawv6_prot));
        seq_printf(seq, "FRAG6: inuse %d memory %d\n",
                       ip6_frag_nqueues(), ip6_frag_mem());
        return 0;
index ca24ef19cd8f294c35d7d285751a5bb55c5d1838..807260d03586dd596314dc29614e33b3162861f0 100644 (file)
@@ -1144,6 +1144,8 @@ static int rawv6_init_sk(struct sock *sk)
        return(0);
 }
 
+DEFINE_PROTO_INUSE(rawv6)
+
 struct proto rawv6_prot = {
        .name              = "RAWv6",
        .owner             = THIS_MODULE,
@@ -1166,6 +1168,7 @@ struct proto rawv6_prot = {
        .compat_setsockopt = compat_rawv6_setsockopt,
        .compat_getsockopt = compat_rawv6_getsockopt,
 #endif
+       REF_PROTO_INUSE(rawv6)
 };
 
 #ifdef CONFIG_PROC_FS
index 95f8e4a62f68f6048f01e964ae1b619d9e90a947..6ecb5e6fae2eb9feff63496bd0749d02237af156 100644 (file)
 #include <linux/in6.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
-
-#ifdef         CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#endif
-
 #include <net/net_namespace.h>
 #include <net/snmp.h>
 #include <net/ipv6.h>
@@ -548,12 +544,8 @@ restart:
        rt = rt6_device_match(rt, fl->oif, flags);
        BACKTRACK(&fl->fl6_src);
 out:
-       dst_hold(&rt->u.dst);
+       dst_use(&rt->u.dst, jiffies);
        read_unlock_bh(&table->tb6_lock);
-
-       rt->u.dst.lastuse = jiffies;
-       rt->u.dst.__use++;
-
        return rt;
 
 }
@@ -2288,71 +2280,50 @@ struct rt6_proc_arg
 
 static int rt6_info_route(struct rt6_info *rt, void *p_arg)
 {
-       struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
-
-       if (arg->skip < arg->offset / RT6_INFO_LEN) {
-               arg->skip++;
-               return 0;
-       }
-
-       if (arg->len >= arg->length)
-               return 0;
+       struct seq_file *m = p_arg;
 
-       arg->len += sprintf(arg->buffer + arg->len,
-                           NIP6_SEQFMT " %02x ",
-                           NIP6(rt->rt6i_dst.addr),
-                           rt->rt6i_dst.plen);
+       seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
+                  rt->rt6i_dst.plen);
 
 #ifdef CONFIG_IPV6_SUBTREES
-       arg->len += sprintf(arg->buffer + arg->len,
-                           NIP6_SEQFMT " %02x ",
-                           NIP6(rt->rt6i_src.addr),
-                           rt->rt6i_src.plen);
+       seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
+                  rt->rt6i_src.plen);
 #else
-       arg->len += sprintf(arg->buffer + arg->len,
-                           "00000000000000000000000000000000 00 ");
+       seq_puts(m, "00000000000000000000000000000000 00 ");
 #endif
 
        if (rt->rt6i_nexthop) {
-               arg->len += sprintf(arg->buffer + arg->len,
-                                   NIP6_SEQFMT,
-                                   NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
+               seq_printf(m, NIP6_SEQFMT,
+                          NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
        } else {
-               arg->len += sprintf(arg->buffer + arg->len,
-                                   "00000000000000000000000000000000");
+               seq_puts(m, "00000000000000000000000000000000");
        }
-       arg->len += sprintf(arg->buffer + arg->len,
-                           " %08x %08x %08x %08x %8s\n",
-                           rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
-                           rt->u.dst.__use, rt->rt6i_flags,
-                           rt->rt6i_dev ? rt->rt6i_dev->name : "");
+       seq_printf(m, " %08x %08x %08x %08x %8s\n",
+                  rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
+                  rt->u.dst.__use, rt->rt6i_flags,
+                  rt->rt6i_dev ? rt->rt6i_dev->name : "");
        return 0;
 }
 
-static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
+static int ipv6_route_show(struct seq_file *m, void *v)
 {
-       struct rt6_proc_arg arg = {
-               .buffer = buffer,
-               .offset = offset,
-               .length = length,
-       };
-
-       fib6_clean_all(rt6_info_route, 0, &arg);
-
-       *start = buffer;
-       if (offset)
-               *start += offset % RT6_INFO_LEN;
-
-       arg.len -= offset % RT6_INFO_LEN;
-
-       if (arg.len > length)
-               arg.len = length;
-       if (arg.len < 0)
-               arg.len = 0;
+       fib6_clean_all(rt6_info_route, 0, m);
+       return 0;
+}
 
-       return arg.len;
+static int ipv6_route_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ipv6_route_show, NULL);
 }
 
+static const struct file_operations ipv6_route_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = ipv6_route_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int rt6_stats_seq_show(struct seq_file *seq, void *v)
 {
        seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
@@ -2489,22 +2460,14 @@ ctl_table ipv6_route_table[] = {
 
 void __init ip6_route_init(void)
 {
-#ifdef         CONFIG_PROC_FS
-       struct proc_dir_entry *p;
-#endif
        ip6_dst_ops.kmem_cachep =
                kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
        ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
 
        fib6_init();
-#ifdef         CONFIG_PROC_FS
-       p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
-       if (p)
-               p->owner = THIS_MODULE;
-
+       proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops);
        proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
-#endif
 #ifdef CONFIG_XFRM
        xfrm6_init();
 #endif
index 06be2a1f27303d761b63aa0ce5c30da3c253eb65..3aad861975a0a084d4ec952e2c1082d87cff7ba3 100644 (file)
@@ -2107,6 +2107,8 @@ void tcp6_proc_exit(void)
 }
 #endif
 
+DEFINE_PROTO_INUSE(tcpv6)
+
 struct proto tcpv6_prot = {
        .name                   = "TCPv6",
        .owner                  = THIS_MODULE,
@@ -2141,6 +2143,7 @@ struct proto tcpv6_prot = {
        .compat_setsockopt      = compat_tcp_setsockopt,
        .compat_getsockopt      = compat_tcp_getsockopt,
 #endif
+       REF_PROTO_INUSE(tcpv6)
 };
 
 static struct inet6_protocol tcpv6_protocol = {
index caebad6ee510d8927db4b0df4dd0d8c2dfb5ab42..ee1cc3f8599fd110bca8e77e38e2e9f50b607402 100644 (file)
@@ -205,12 +205,11 @@ out:
        return err;
 
 csum_copy_err:
+       UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
        skb_kill_datagram(sk, skb, flags);
 
-       if (flags & MSG_DONTWAIT) {
-               UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
+       if (flags & MSG_DONTWAIT)
                return -EAGAIN;
-       }
        goto try_again;
 }
 
@@ -971,6 +970,8 @@ void udp6_proc_exit(void) {
 
 /* ------------------------------------------------------------------------ */
 
+DEFINE_PROTO_INUSE(udpv6)
+
 struct proto udpv6_prot = {
        .name              = "UDPv6",
        .owner             = THIS_MODULE,
@@ -992,6 +993,7 @@ struct proto udpv6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
+       REF_PROTO_INUSE(udpv6)
 };
 
 static struct inet_protosw udpv6_protosw = {
index 766566f7de47dc6734db6f2fb769b012723c0947..5a0379f7141515f2ddc1841959ecde05f8a3ee66 100644 (file)
@@ -40,6 +40,8 @@ static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
        return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
 }
 
+DEFINE_PROTO_INUSE(udplitev6)
+
 struct proto udplitev6_prot = {
        .name              = "UDPLITEv6",
        .owner             = THIS_MODULE,
@@ -62,6 +64,7 @@ struct proto udplitev6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
+       REF_PROTO_INUSE(udplitev6)
 };
 
 static struct inet_protosw udplite6_protosw = {
index a195a66e0cc799192e258533a84c0b3a558b92ce..c76a9523091b2747f6b9c01dee54d478bd3b4ec7 100644 (file)
@@ -92,11 +92,6 @@ extern int ipxrtr_route_skb(struct sk_buff *skb);
 extern struct ipx_route *ipxrtr_lookup(__be32 net);
 extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
 
-#undef IPX_REFCNT_DEBUG
-#ifdef IPX_REFCNT_DEBUG
-atomic_t ipx_sock_nr;
-#endif
-
 struct ipx_interface *ipx_interfaces_head(void)
 {
        struct ipx_interface *rc = NULL;
@@ -151,14 +146,7 @@ static void ipx_destroy_socket(struct sock *sk)
 {
        ipx_remove_socket(sk);
        skb_queue_purge(&sk->sk_receive_queue);
-#ifdef IPX_REFCNT_DEBUG
-       atomic_dec(&ipx_sock_nr);
-       printk(KERN_DEBUG "IPX socket %p released, %d are still alive\n", sk,
-                       atomic_read(&ipx_sock_nr));
-       if (atomic_read(&sk->sk_refcnt) != 1)
-               printk(KERN_DEBUG "Destruction sock ipx %p delayed, cnt=%d\n",
-                               sk, atomic_read(&sk->sk_refcnt));
-#endif
+       sk_refcnt_debug_dec(sk);
        sock_put(sk);
 }
 
@@ -1384,11 +1372,8 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol)
        sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto);
        if (!sk)
                goto out;
-#ifdef IPX_REFCNT_DEBUG
-       atomic_inc(&ipx_sock_nr);
-       printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,
-                       atomic_read(&ipx_sock_nr));
-#endif
+
+       sk_refcnt_debug_inc(sk);
        sock_init_data(sock, sk);
        sk->sk_no_check = 1;            /* Checksum off by default */
        sock->ops = &ipx_dgram_ops;
@@ -1409,6 +1394,7 @@ static int ipx_release(struct socket *sock)
 
        sock_set_flag(sk, SOCK_DEAD);
        sock->sk = NULL;
+       sk_refcnt_debug_release(sk);
        ipx_destroy_socket(sk);
 out:
        return 0;
index 6fffb3845ab6c76b341819376def9f1c77e68424..ce176e691afec86281ffb1130f848c53ff641f9e 100644 (file)
@@ -13,6 +13,18 @@ config MAC80211
        This option enables the hardware independent IEEE 802.11
        networking stack.
 
+config MAC80211_RCSIMPLE
+       bool "'simple' rate control algorithm" if EMBEDDED
+       default y
+       depends on MAC80211
+       help
+         This option allows you to turn off the 'simple' rate
+         control algorithm in mac80211. If you do turn it off,
+         you absolutely need another rate control algorithm.
+
+         Say Y unless you know you will have another algorithm
+         available.
+
 config MAC80211_LEDS
        bool "Enable LED triggers"
        depends on MAC80211 && LEDS_TRIGGERS
index 219cd9f9341fe099bc0ce5ba69c2da7442339ab8..1e6237b3484662ffe65a207a3a35a5bbd202f7d2 100644 (file)
@@ -1,8 +1,9 @@
-obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
+obj-$(CONFIG_MAC80211) += mac80211.o
 
 mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
 mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
 mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
+mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o
 
 mac80211-objs := \
        ieee80211.o \
index f484ca7ade9ce9ff718015cef06517e7b52d13a4..e0ee65a969bc4537d5bccc35fb94d9a636e7a2d0 100644 (file)
@@ -1072,7 +1072,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
        ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
 
-       result = ieee80211_init_rate_ctrl_alg(local, NULL);
+       result = ieee80211_init_rate_ctrl_alg(local,
+                                             hw->rate_control_algorithm);
        if (result < 0) {
                printk(KERN_DEBUG "%s: Failed to initialize rate control "
                       "algorithm\n", wiphy_name(local->hw.wiphy));
@@ -1233,8 +1234,17 @@ static int __init ieee80211_init(void)
 
        BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
 
+#ifdef CONFIG_MAC80211_RCSIMPLE
+       ret = ieee80211_rate_control_register(&mac80211_rcsimple);
+       if (ret)
+               return ret;
+#endif
+
        ret = ieee80211_wme_register();
        if (ret) {
+#ifdef CONFIG_MAC80211_RCSIMPLE
+               ieee80211_rate_control_unregister(&mac80211_rcsimple);
+#endif
                printk(KERN_DEBUG "ieee80211_init: failed to "
                       "initialize WME (err=%d)\n", ret);
                return ret;
@@ -1248,6 +1258,10 @@ static int __init ieee80211_init(void)
 
 static void __exit ieee80211_exit(void)
 {
+#ifdef CONFIG_MAC80211_RCSIMPLE
+       ieee80211_rate_control_unregister(&mac80211_rcsimple);
+#endif
+
        ieee80211_wme_unregister();
        ieee80211_debugfs_netdev_exit();
 }
diff --git a/net/mac80211/ieee80211_common.h b/net/mac80211/ieee80211_common.h
deleted file mode 100644 (file)
index c15295d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * IEEE 802.11 driver (80211.o) -- hostapd interface
- * Copyright 2002-2004, Instant802 Networks, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef IEEE80211_COMMON_H
-#define IEEE80211_COMMON_H
-
-#include <linux/types.h>
-
-/*
- * This is common header information with user space. It is used on all
- * frames sent to wlan#ap interface.
- */
-
-#define IEEE80211_FI_VERSION 0x80211001
-
-struct ieee80211_frame_info {
-       __be32 version;
-       __be32 length;
-       __be64 mactime;
-       __be64 hosttime;
-       __be32 phytype;
-       __be32 channel;
-       __be32 datarate;
-       __be32 antenna;
-       __be32 priority;
-       __be32 ssi_type;
-       __be32 ssi_signal;
-       __be32 ssi_noise;
-       __be32 preamble;
-       __be32 encoding;
-
-       /* Note: this structure is otherwise identical to capture format used
-        * in linux-wlan-ng, but this additional field is used to provide meta
-        * data about the frame to hostapd. This was the easiest method for
-        * providing this information, but this might change in the future. */
-       __be32 msg_type;
-} __attribute__ ((packed));
-
-
-enum ieee80211_msg_type {
-       ieee80211_msg_normal = 0,
-       ieee80211_msg_tx_callback_ack = 1,
-       ieee80211_msg_tx_callback_fail = 2,
-       /* hole at 3, was ieee80211_msg_passive_scan but unused */
-       /* hole at 4, was ieee80211_msg_wep_frame_unknown_key but now unused */
-       ieee80211_msg_michael_mic_failure = 5,
-       /* hole at 6, was monitor but never sent to userspace */
-       ieee80211_msg_sta_not_assoc = 7,
-       /* 8 was ieee80211_msg_set_aid_for_sta */
-       /* 9 was ieee80211_msg_key_threshold_notification */
-       /* 11 was ieee80211_msg_radar */
-};
-
-struct ieee80211_msg_key_notification {
-       int tx_rx_count;
-       char ifname[IFNAMSIZ];
-       u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */
-};
-
-
-enum ieee80211_phytype {
-       ieee80211_phytype_fhss_dot11_97  = 1,
-       ieee80211_phytype_dsss_dot11_97  = 2,
-       ieee80211_phytype_irbaseband     = 3,
-       ieee80211_phytype_dsss_dot11_b   = 4,
-       ieee80211_phytype_pbcc_dot11_b   = 5,
-       ieee80211_phytype_ofdm_dot11_g   = 6,
-       ieee80211_phytype_pbcc_dot11_g   = 7,
-       ieee80211_phytype_ofdm_dot11_a   = 8,
-};
-
-enum ieee80211_ssi_type {
-       ieee80211_ssi_none = 0,
-       ieee80211_ssi_norm = 1, /* normalized, 0-1000 */
-       ieee80211_ssi_dbm = 2,
-       ieee80211_ssi_raw = 3, /* raw SSI */
-};
-
-struct ieee80211_radar_info {
-               int channel;
-               int radar;
-               int radar_type;
-};
-
-#endif /* IEEE80211_COMMON_H */
index 4b4ed2a5803c46f8e86ae550f9431fb4044e2a34..72e1c93dd87e4f2bfe520c57d753bb2354a1be44 100644 (file)
@@ -230,6 +230,7 @@ struct ieee80211_if_vlan {
 #define IEEE80211_STA_AUTO_SSID_SEL    BIT(10)
 #define IEEE80211_STA_AUTO_BSSID_SEL   BIT(11)
 #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
+#define IEEE80211_STA_PRIVACY_INVOKED  BIT(13)
 struct ieee80211_if_sta {
        enum {
                IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
@@ -241,6 +242,8 @@ struct ieee80211_if_sta {
        u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        size_t ssid_len;
+       u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
+       size_t scan_ssid_len;
        u16 aid;
        u16 ap_capab, capab;
        u8 *extra_ie; /* to be added to the end of AssocReq */
@@ -259,7 +262,6 @@ struct ieee80211_if_sta {
        unsigned long request;
        struct sk_buff_head skb_queue;
 
-       int key_management_enabled;
        unsigned long last_probe;
 
 #define IEEE80211_AUTH_ALG_OPEN BIT(0)
index 6caa3ec2cff7798ef13e1f604fc8bdfff50a0c4c..7027eed4d4ae3a374fff7439110e80d44069a8fb 100644 (file)
@@ -917,7 +917,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
                                   struct iw_request_info *info,
                                   struct iw_param *data, char *extra)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int ret = 0;
 
@@ -927,18 +926,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
        case IW_AUTH_CIPHER_GROUP:
        case IW_AUTH_WPA_ENABLED:
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               break;
        case IW_AUTH_KEY_MGMT:
+               break;
+       case IW_AUTH_PRIVACY_INVOKED:
                if (sdata->type != IEEE80211_IF_TYPE_STA)
                        ret = -EINVAL;
                else {
+                       sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
                        /*
-                        * Key management was set by wpa_supplicant,
-                        * we only need this to associate to a network
-                        * that has privacy enabled regardless of not
-                        * having a key.
+                        * Privacy invoked by wpa_supplicant, store the
+                        * value and allow associating to a protected
+                        * network without having a key up front.
                         */
-                       sdata->u.sta.key_management_enabled = !!data->value;
+                       if (data->value)
+                               sdata->u.sta.flags |=
+                                       IEEE80211_STA_PRIVACY_INVOKED;
                }
                break;
        case IW_AUTH_80211_AUTH_ALG:
@@ -948,11 +950,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
                else
                        ret = -EOPNOTSUPP;
                break;
-       case IW_AUTH_PRIVACY_INVOKED:
-               if (local->ops->set_privacy_invoked)
-                       ret = local->ops->set_privacy_invoked(
-                                       local_to_hw(local), data->value);
-               break;
        default:
                ret = -EOPNOTSUPP;
                break;
index 93abb8fff1410f254c9fb6adf04ad34823bc80a5..7254bd6098398e0f408afe8f6eff40922dfe3c71 100644 (file)
@@ -25,13 +25,25 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops)
 {
        struct rate_control_alg *alg;
 
+       if (!ops->name)
+               return -EINVAL;
+
+       mutex_lock(&rate_ctrl_mutex);
+       list_for_each_entry(alg, &rate_ctrl_algs, list) {
+               if (!strcmp(alg->ops->name, ops->name)) {
+                       /* don't register an algorithm twice */
+                       WARN_ON(1);
+                       return -EALREADY;
+               }
+       }
+
        alg = kzalloc(sizeof(*alg), GFP_KERNEL);
        if (alg == NULL) {
+               mutex_unlock(&rate_ctrl_mutex);
                return -ENOMEM;
        }
        alg->ops = ops;
 
-       mutex_lock(&rate_ctrl_mutex);
        list_add_tail(&alg->list, &rate_ctrl_algs);
        mutex_unlock(&rate_ctrl_mutex);
 
@@ -61,9 +73,12 @@ ieee80211_try_rate_control_ops_get(const char *name)
        struct rate_control_alg *alg;
        struct rate_control_ops *ops = NULL;
 
+       if (!name)
+               return NULL;
+
        mutex_lock(&rate_ctrl_mutex);
        list_for_each_entry(alg, &rate_ctrl_algs, list) {
-               if (!name || !strcmp(alg->ops->name, name))
+               if (!strcmp(alg->ops->name, name))
                        if (try_module_get(alg->ops->module)) {
                                ops = alg->ops;
                                break;
@@ -80,9 +95,12 @@ ieee80211_rate_control_ops_get(const char *name)
 {
        struct rate_control_ops *ops;
 
+       if (!name)
+               name = "simple";
+
        ops = ieee80211_try_rate_control_ops_get(name);
        if (!ops) {
-               request_module("rc80211_%s", name ? name : "default");
+               request_module("rc80211_%s", name);
                ops = ieee80211_try_rate_control_ops_get(name);
        }
        return ops;
index 7cd1ebab4f8345f4cdf008b17ecc134254c45c39..23688139ffb3ea399292ce2b6842f55c91371d34 100644 (file)
@@ -65,6 +65,9 @@ struct rate_control_ref {
        struct kref kref;
 };
 
+/* default 'simple' algorithm */
+extern struct rate_control_ops mac80211_rcsimple;
+
 int ieee80211_rate_control_register(struct rate_control_ops *ops);
 void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
 
index fda0e06453e85bc5f8d00867170dd41d17e9e65c..015b3f879aa921f41c0d11a52a632c39be407852 100644 (file)
@@ -704,10 +704,11 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sta_bss *bss;
-       int res = 0;
+       int bss_privacy;
+       int wep_privacy;
+       int privacy_invoked;
 
-       if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) ||
-           ifsta->key_management_enabled)
+       if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
                return 0;
 
        bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
@@ -715,13 +716,16 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
        if (!bss)
                return 0;
 
-       if (ieee80211_sta_wep_configured(dev) !=
-           !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
-               res = 1;
+       bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
+       wep_privacy = !!ieee80211_sta_wep_configured(dev);
+       privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
 
        ieee80211_rx_bss_put(dev, bss);
 
-       return res;
+       if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
+               return 0;
+
+       return 1;
 }
 
 
@@ -1998,7 +2002,10 @@ void ieee80211_sta_work(struct work_struct *work)
        if (ifsta->state != IEEE80211_AUTHENTICATE &&
            ifsta->state != IEEE80211_ASSOCIATE &&
            test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
-               ieee80211_sta_start_scan(dev, NULL, 0);
+               if (ifsta->scan_ssid_len)
+                       ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
+               else
+                       ieee80211_sta_start_scan(dev, NULL, 0);
                return;
        }
 
@@ -2868,6 +2875,9 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
                return -EBUSY;
        }
 
+       ifsta->scan_ssid_len = ssid_len;
+       if (ssid_len)
+               memcpy(ifsta->scan_ssid, ssid, ssid_len);
        set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
        queue_work(local->hw.workqueue, &ifsta->work);
        return 0;
index 314b8de888625c576a02fbd50caa01fc7787d84d..da72737364e42bb5d8fc68255603befad39bd535 100644 (file)
@@ -7,7 +7,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/types.h>
@@ -29,8 +28,6 @@
 #define RATE_CONTROL_INTERVAL (HZ / 20)
 #define RATE_CONTROL_MIN_TX 10
 
-MODULE_ALIAS("rc80211_default");
-
 static void rate_control_rate_inc(struct ieee80211_local *local,
                                  struct sta_info *sta)
 {
@@ -394,8 +391,7 @@ static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
 }
 #endif
 
-static struct rate_control_ops rate_control_simple = {
-       .module = THIS_MODULE,
+struct rate_control_ops mac80211_rcsimple = {
        .name = "simple",
        .tx_status = rate_control_simple_tx_status,
        .get_rate = rate_control_simple_get_rate,
@@ -410,22 +406,3 @@ static struct rate_control_ops rate_control_simple = {
        .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
 #endif
 };
-
-
-static int __init rate_control_simple_init(void)
-{
-       return ieee80211_rate_control_register(&rate_control_simple);
-}
-
-
-static void __exit rate_control_simple_exit(void)
-{
-       ieee80211_rate_control_unregister(&rate_control_simple);
-}
-
-
-subsys_initcall(rate_control_simple_init);
-module_exit(rate_control_simple_exit);
-
-MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
-MODULE_LICENSE("GPL");
index ece77766ea2bd798552152b67313e8c86ae0aa1c..428a9fcf57d62c90c6537490fd193d6342b47ee7 100644 (file)
@@ -509,9 +509,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
                rx->key->tx_rx_count++;
                /* TODO: add threshold stuff again */
        } else {
+#ifdef CONFIG_MAC80211_DEBUG
                if (net_ratelimit())
                        printk(KERN_DEBUG "%s: RX protected frame,"
                               " but have no key\n", rx->dev->name);
+#endif /* CONFIG_MAC80211_DEBUG */
                return TXRX_DROP;
        }
 
index a84a23310ff4576116cab6dcb625f6e27bcb6ae4..9bf0e1cc530ad5e9c8975d50cbca6cefddd673e3 100644 (file)
@@ -314,9 +314,11 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
 
        if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
                if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
+#ifdef CONFIG_MAC80211_DEBUG
                        if (net_ratelimit())
                                printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
                                       "failed\n", rx->dev->name);
+#endif /* CONFIG_MAC80211_DEBUG */
                        return TXRX_DROP;
                }
        } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
index 6695efba57ec12c52329c203da57d97d45f7946b..20cec1cb956fb38d6506139d757d8a983cf126d7 100644 (file)
@@ -323,9 +323,12 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
                                          &rx->u.rx.tkip_iv32,
                                          &rx->u.rx.tkip_iv16);
        if (res != TKIP_DECRYPT_OK || wpa_test) {
-               printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
-                      "%s (res=%d)\n",
-                      rx->dev->name, print_mac(mac, rx->sta->addr), res);
+#ifdef CONFIG_MAC80211_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: TKIP decrypt failed for RX "
+                              "frame from %s (res=%d)\n", rx->dev->name,
+                              print_mac(mac, rx->sta->addr), res);
+#endif /* CONFIG_MAC80211_DEBUG */
                return TXRX_DROP;
        }
 
@@ -594,9 +597,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
                            skb->data + hdrlen + CCMP_HDR_LEN, data_len,
                            skb->data + skb->len - CCMP_MIC_LEN,
                            skb->data + hdrlen + CCMP_HDR_LEN)) {
-                       printk(KERN_DEBUG "%s: CCMP decrypt failed for RX "
-                              "frame from %s\n", rx->dev->name,
-                              print_mac(mac, rx->sta->addr));
+#ifdef CONFIG_MAC80211_DEBUG
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "%s: CCMP decrypt failed "
+                                      "for RX frame from %s\n", rx->dev->name,
+                                      print_mac(mac, rx->sta->addr));
+#endif /* CONFIG_MAC80211_DEBUG */
                        return TXRX_DROP;
                }
        }
index 93c58f973831f5dd268bf9e114c009faa755350a..ad0e36ebea3d3f17a18bc973175d1d8358284bef 100644 (file)
@@ -40,15 +40,15 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 # targets
 obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
@@ -59,22 +59,22 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
index a1a65a1313b3ecb7e0f16254ae2514cf0d3f7ef3..cf6ba6659a8080938b3aaaa44c6ef46d0a47ad72 100644 (file)
@@ -109,7 +109,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
                        rcu_read_lock();
                        t = rcu_dereference(nf_ct_ext_types[i]);
                        if (t && t->move)
-                               t->move(ct, ct->ext + ct->ext->offset[id]);
+                               t->move(ct, ct->ext + ct->ext->offset[i]);
                        rcu_read_unlock();
                }
                kfree(ct->ext);
index aa2831587b821d1c3afb65d59f96d0eb739a9377..3dd4b3c76d811a6545a0a26140f59ac237020ea4 100644 (file)
@@ -23,14 +23,13 @@ static inline int overlap(int min1, int max1, int min2, int max2)
 /* Functions to register sockopt ranges (exclusive). */
 int nf_register_sockopt(struct nf_sockopt_ops *reg)
 {
-       struct list_head *i;
+       struct nf_sockopt_ops *ops;
        int ret = 0;
 
        if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
                return -EINTR;
 
-       list_for_each(i, &nf_sockopts) {
-               struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i;
+       list_for_each_entry(ops, &nf_sockopts, list) {
                if (ops->pf == reg->pf
                    && (overlap(ops->set_optmin, ops->set_optmax,
                                reg->set_optmin, reg->set_optmax)
@@ -61,48 +60,57 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
 }
 EXPORT_SYMBOL(nf_unregister_sockopt);
 
-/* Call get/setsockopt() */
-static int nf_sockopt(struct sock *sk, int pf, int val,
-                     char __user *opt, int *len, int get)
+static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, int pf,
+               int val, int get)
 {
-       struct list_head *i;
        struct nf_sockopt_ops *ops;
-       int ret;
 
        if (sk->sk_net != &init_net)
-               return -ENOPROTOOPT;
+               return ERR_PTR(-ENOPROTOOPT);
 
        if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
-               return -EINTR;
+               return ERR_PTR(-EINTR);
 
-       list_for_each(i, &nf_sockopts) {
-               ops = (struct nf_sockopt_ops *)i;
+       list_for_each_entry(ops, &nf_sockopts, list) {
                if (ops->pf == pf) {
                        if (!try_module_get(ops->owner))
                                goto out_nosup;
+
                        if (get) {
-                               if (val >= ops->get_optmin
-                                   && val < ops->get_optmax) {
-                                       mutex_unlock(&nf_sockopt_mutex);
-                                       ret = ops->get(sk, val, opt, len);
+                               if (val >= ops->get_optmin &&
+                                               val < ops->get_optmax)
                                        goto out;
-                               }
                        } else {
-                               if (val >= ops->set_optmin
-                                   && val < ops->set_optmax) {
-                                       mutex_unlock(&nf_sockopt_mutex);
-                                       ret = ops->set(sk, val, opt, *len);
+                               if (val >= ops->set_optmin &&
+                                               val < ops->set_optmax)
                                        goto out;
-                               }
                        }
                        module_put(ops->owner);
                }
        }
- out_nosup:
+out_nosup:
+       ops = ERR_PTR(-ENOPROTOOPT);
+out:
        mutex_unlock(&nf_sockopt_mutex);
-       return -ENOPROTOOPT;
+       return ops;
+}
+
+/* Call get/setsockopt() */
+static int nf_sockopt(struct sock *sk, int pf, int val,
+                     char __user *opt, int *len, int get)
+{
+       struct nf_sockopt_ops *ops;
+       int ret;
+
+       ops = nf_sockopt_find(sk, pf, val, get);
+       if (IS_ERR(ops))
+               return PTR_ERR(ops);
+
+       if (get)
+               ret = ops->get(sk, val, opt, len);
+       else
+               ret = ops->set(sk, val, opt, *len);
 
- out:
        module_put(ops->owner);
        return ret;
 }
@@ -124,56 +132,25 @@ EXPORT_SYMBOL(nf_getsockopt);
 static int compat_nf_sockopt(struct sock *sk, int pf, int val,
                             char __user *opt, int *len, int get)
 {
-       struct list_head *i;
        struct nf_sockopt_ops *ops;
        int ret;
 
-       if (sk->sk_net != &init_net)
-               return -ENOPROTOOPT;
-
-
-       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
-               return -EINTR;
-
-       list_for_each(i, &nf_sockopts) {
-               ops = (struct nf_sockopt_ops *)i;
-               if (ops->pf == pf) {
-                       if (!try_module_get(ops->owner))
-                               goto out_nosup;
-
-                       if (get) {
-                               if (val >= ops->get_optmin
-                                   && val < ops->get_optmax) {
-                                       mutex_unlock(&nf_sockopt_mutex);
-                                       if (ops->compat_get)
-                                               ret = ops->compat_get(sk,
-                                                       val, opt, len);
-                                       else
-                                               ret = ops->get(sk,
-                                                       val, opt, len);
-                                       goto out;
-                               }
-                       } else {
-                               if (val >= ops->set_optmin
-                                   && val < ops->set_optmax) {
-                                       mutex_unlock(&nf_sockopt_mutex);
-                                       if (ops->compat_set)
-                                               ret = ops->compat_set(sk,
-                                                       val, opt, *len);
-                                       else
-                                               ret = ops->set(sk,
-                                                       val, opt, *len);
-                                       goto out;
-                               }
-                       }
-                       module_put(ops->owner);
-               }
+       ops = nf_sockopt_find(sk, pf, val, get);
+       if (IS_ERR(ops))
+               return PTR_ERR(ops);
+
+       if (get) {
+               if (ops->compat_get)
+                       ret = ops->compat_get(sk, val, opt, len);
+               else
+                       ret = ops->get(sk, val, opt, len);
+       } else {
+               if (ops->compat_set)
+                       ret = ops->compat_set(sk, val, opt, *len);
+               else
+                       ret = ops->set(sk, val, opt, *len);
        }
- out_nosup:
-       mutex_unlock(&nf_sockopt_mutex);
-       return -ENOPROTOOPT;
 
- out:
        module_put(ops->owner);
        return ret;
 }
index 06cff1d13690909860a89275fc30dd4a861dbc54..d7becf08a93a3481fe587842f47f60d871f882d3 100644 (file)
@@ -4,7 +4,8 @@
  *   (c) 2000 Gerd Knorr <kraxel@bytesex.org>
  *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
  *             only ignore TIME_WAIT or gone connections
- *   Copyright Â© Jan Engelhardt <jengelh@gmx.de>, 2007
+ *   (C) CC Computer Consultants GmbH, 2007
+ *   Contact: <jengelh@computergmbh.de>
  *
  * based on ...
  *
@@ -306,7 +307,7 @@ static void __exit xt_connlimit_exit(void)
 
 module_init(xt_connlimit_init);
 module_exit(xt_connlimit_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
 MODULE_DESCRIPTION("netfilter xt_connlimit match module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connlimit");
index ef48bbd93573080b3489f378a4cb3755d8c20e36..f9c55dcd894b70e9cef74203a27f2d747d4f2d8e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *     xt_time
- *     Copyright Â© Jan Engelhardt <jengelh@computergmbh.de>, 2007
+ *     Copyright Â© CC Computer Consultants GmbH, 2007
+ *     Contact: <jengelh@computergmbh.de>
  *
  *     based on ipt_time by Fabrice MARIE <fabrice@netfilter.org>
  *     This is a module which is used for time matching
@@ -169,7 +170,7 @@ static bool xt_time_match(const struct sk_buff *skb,
        if (skb->tstamp.tv64 == 0)
                __net_timestamp((struct sk_buff *)skb);
 
-       stamp = skb->tstamp.tv64;
+       stamp = ktime_to_ns(skb->tstamp);
        do_div(stamp, NSEC_PER_SEC);
 
        if (info->flags & XT_TIME_LOCAL_TZ)
index bec427915b302fa2d9731de6045a9a6e8bd14ee4..af75b8c3f20b988af0df06b74382cee68e07c4cf 100644 (file)
@@ -2,7 +2,8 @@
  *     xt_u32 - kernel module to match u32 packet content
  *
  *     Original author: Don Cohen <don@isis.cs3-inc.com>
- *     Â© Jan Engelhardt <jengelh@gmx.de>, 2007
+ *     (C) CC Computer Consultants GmbH, 2007
+ *     Contact: <jengelh@computergmbh.de>
  */
 
 #include <linux/module.h>
@@ -129,7 +130,7 @@ static void __exit xt_u32_exit(void)
 
 module_init(xt_u32_init);
 module_exit(xt_u32_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
 MODULE_DESCRIPTION("netfilter u32 match module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_u32");
index 2601712555767b34d49fb694a5adbb12e734a44d..de3988ba1f46c45dd0831caeb71b4de0dedb0a63 100644 (file)
@@ -752,7 +752,7 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
  * 1: repeat lookup - reference dropped while waiting for socket memory.
  */
 int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
-               long timeo, struct sock *ssk)
+                     long *timeo, struct sock *ssk)
 {
        struct netlink_sock *nlk;
 
@@ -761,7 +761,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
        if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
            test_bit(0, &nlk->state)) {
                DECLARE_WAITQUEUE(wait, current);
-               if (!timeo) {
+               if (!*timeo) {
                        if (!ssk || netlink_is_kernel(ssk))
                                netlink_overrun(sk);
                        sock_put(sk);
@@ -775,7 +775,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
                if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
                     test_bit(0, &nlk->state)) &&
                    !sock_flag(sk, SOCK_DEAD))
-                       timeo = schedule_timeout(timeo);
+                       *timeo = schedule_timeout(*timeo);
 
                __set_current_state(TASK_RUNNING);
                remove_wait_queue(&nlk->wait, &wait);
@@ -783,7 +783,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
 
                if (signal_pending(current)) {
                        kfree_skb(skb);
-                       return sock_intr_errno(timeo);
+                       return sock_intr_errno(*timeo);
                }
                return 1;
        }
@@ -877,7 +877,7 @@ retry:
        if (netlink_is_kernel(sk))
                return netlink_unicast_kernel(sk, skb);
 
-       err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
+       err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
        if (err == 1)
                goto retry;
        if (err)
@@ -1888,7 +1888,7 @@ static void __net_exit netlink_net_exit(struct net *net)
 #endif
 }
 
-static struct pernet_operations netlink_net_ops = {
+static struct pernet_operations __net_initdata netlink_net_ops = {
        .init = netlink_net_init,
        .exit = netlink_net_exit,
 };
index 4cb2dfba09931225e151bf86f78d7e5ff7060cf9..8a7807dbba012bdc03b0b49a8a1f35a02e9ee288 100644 (file)
@@ -139,9 +139,6 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it)
 static HLIST_HEAD(packet_sklist);
 static DEFINE_RWLOCK(packet_sklist_lock);
 
-static atomic_t packet_socks_nr;
-
-
 /* Private packet socket structures. */
 
 struct packet_mclist
@@ -236,10 +233,7 @@ static void packet_sock_destruct(struct sock *sk)
                return;
        }
 
-       atomic_dec(&packet_socks_nr);
-#ifdef PACKET_REFCNT_DEBUG
-       printk(KERN_DEBUG "PACKET socket %p is free, %d are alive\n", sk, atomic_read(&packet_socks_nr));
-#endif
+       sk_refcnt_debug_dec(sk);
 }
 
 
@@ -515,7 +509,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
        sll->sll_hatype = dev->type;
        sll->sll_protocol = skb->protocol;
        sll->sll_pkttype = skb->pkt_type;
-       if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
+       if (unlikely(po->origdev))
                sll->sll_ifindex = orig_dev->ifindex;
        else
                sll->sll_ifindex = dev->ifindex;
@@ -661,7 +655,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
        sll->sll_hatype = dev->type;
        sll->sll_protocol = skb->protocol;
        sll->sll_pkttype = skb->pkt_type;
-       if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
+       if (unlikely(po->origdev))
                sll->sll_ifindex = orig_dev->ifindex;
        else
                sll->sll_ifindex = dev->ifindex;
@@ -849,6 +843,7 @@ static int packet_release(struct socket *sock)
        /* Purge queues */
 
        skb_queue_purge(&sk->sk_receive_queue);
+       sk_refcnt_debug_release(sk);
 
        sock_put(sk);
        return 0;
@@ -886,20 +881,14 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
        if (protocol == 0)
                goto out_unlock;
 
-       if (dev) {
-               if (dev->flags&IFF_UP) {
-                       dev_add_pack(&po->prot_hook);
-                       sock_hold(sk);
-                       po->running = 1;
-               } else {
-                       sk->sk_err = ENETDOWN;
-                       if (!sock_flag(sk, SOCK_DEAD))
-                               sk->sk_error_report(sk);
-               }
-       } else {
+       if (!dev || (dev->flags & IFF_UP)) {
                dev_add_pack(&po->prot_hook);
                sock_hold(sk);
                po->running = 1;
+       } else {
+               sk->sk_err = ENETDOWN;
+               if (!sock_flag(sk, SOCK_DEAD))
+                       sk->sk_error_report(sk);
        }
 
 out_unlock:
@@ -1010,7 +999,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
        po->num = proto;
 
        sk->sk_destruct = packet_sock_destruct;
-       atomic_inc(&packet_socks_nr);
+       sk_refcnt_debug_inc(sk);
 
        /*
         *      Attach a protocol block
index 51d151c0e9621169730881d3867fa70e50e20042..73d60a307129110de0aec93b57c6fdacd76d1b88 100644 (file)
 #include <linux/mutex.h>
 #include <linux/rfkill.h>
 
+/* Get declaration of rfkill_switch_all() to shut up sparse. */
+#include "rfkill-input.h"
+
+
 MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
 MODULE_VERSION("1.0");
 MODULE_DESCRIPTION("RF switch support");
@@ -276,21 +280,17 @@ static struct class rfkill_class = {
 
 static int rfkill_add_switch(struct rfkill *rfkill)
 {
-       int retval;
-
-       retval = mutex_lock_interruptible(&rfkill_mutex);
-       if (retval)
-               return retval;
+       int error;
 
-       retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
-       if (retval)
-               goto out;
+       mutex_lock(&rfkill_mutex);
 
-       list_add_tail(&rfkill->node, &rfkill_list);
+       error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
+       if (!error)
+               list_add_tail(&rfkill->node, &rfkill_list);
 
- out:
        mutex_unlock(&rfkill_mutex);
-       return retval;
+
+       return error;
 }
 
 static void rfkill_remove_switch(struct rfkill *rfkill)
@@ -387,20 +387,23 @@ int rfkill_register(struct rfkill *rfkill)
 
        if (!rfkill->toggle_radio)
                return -EINVAL;
+       if (rfkill->type >= RFKILL_TYPE_MAX)
+               return -EINVAL;
+
+       snprintf(dev->bus_id, sizeof(dev->bus_id),
+                "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
+
+       rfkill_led_trigger_register(rfkill);
 
        error = rfkill_add_switch(rfkill);
        if (error)
                return error;
 
-       snprintf(dev->bus_id, sizeof(dev->bus_id),
-                "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
-
        error = device_add(dev);
        if (error) {
                rfkill_remove_switch(rfkill);
                return error;
        }
-       rfkill_led_trigger_register(rfkill);
 
        return 0;
 }
@@ -416,9 +419,9 @@ EXPORT_SYMBOL(rfkill_register);
  */
 void rfkill_unregister(struct rfkill *rfkill)
 {
-       rfkill_led_trigger_unregister(rfkill);
        device_del(&rfkill->dev);
        rfkill_remove_switch(rfkill);
+       rfkill_led_trigger_unregister(rfkill);
        put_device(&rfkill->dev);
 }
 EXPORT_SYMBOL(rfkill_unregister);
@@ -448,5 +451,5 @@ static void __exit rfkill_exit(void)
        class_unregister(&rfkill_class);
 }
 
-module_init(rfkill_init);
+subsys_initcall(rfkill_init);
 module_exit(rfkill_exit);
index fe03f71f17da8e440c99780150c509bcd411b14b..f3a2bd747a8f6f09aa4e3006d3ddd66e24a5d370 100644 (file)
@@ -114,7 +114,7 @@ static int rxrpc_create_local(struct rxrpc_local *local)
        return 0;
 
 error:
-       local->socket->ops->shutdown(local->socket, 2);
+       kernel_sock_shutdown(local->socket, SHUT_RDWR);
        local->socket->sk->sk_user_data = NULL;
        sock_release(local->socket);
        local->socket = NULL;
@@ -267,7 +267,7 @@ static void rxrpc_destroy_local(struct work_struct *work)
        /* finish cleaning up the local descriptor */
        rxrpc_purge_queue(&local->accept_queue);
        rxrpc_purge_queue(&local->reject_queue);
-       local->socket->ops->shutdown(local->socket, 2);
+       kernel_sock_shutdown(local->socket, SHUT_RDWR);
        sock_release(local->socket);
 
        up_read(&rxrpc_local_sem);
index 9e98c6e567dde518ba28b29ed7211cb6baac19de..c3900820916425f23fbbcc93db63151a9b81305b 100644 (file)
@@ -91,7 +91,7 @@ static struct tc_u_common *u32_list;
 
 static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
 {
-       unsigned h = (key & sel->hmask)>>fshift;
+       unsigned h = ntohl(key & sel->hmask)>>fshift;
 
        return h;
 }
@@ -613,17 +613,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
        memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
        n->ht_up = ht;
        n->handle = handle;
-{
-       u8 i = 0;
-       u32 mask = s->hmask;
-       if (mask) {
-               while (!(mask & 1)) {
-                       i++;
-                       mask>>=1;
-               }
-       }
-       n->fshift = i;
-}
+       n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
 
 #ifdef CONFIG_CLS_U32_MARK
        if (tb[TCA_U32_MARK-1]) {
index fa1a6f45dc416173f8b6d853f9ce0c5fa3565bc7..e595e6570ce054245c6f8e355b7612a01521526b 100644 (file)
@@ -134,7 +134,7 @@ static inline int qdisc_restart(struct net_device *dev)
 {
        struct Qdisc *q = dev->qdisc;
        struct sk_buff *skb;
-       int ret;
+       int ret = NETDEV_TX_BUSY;
 
        /* Dequeue packet */
        if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
@@ -145,7 +145,8 @@ static inline int qdisc_restart(struct net_device *dev)
        spin_unlock(&dev->queue_lock);
 
        HARD_TX_LOCK(dev, smp_processor_id());
-       ret = dev_hard_start_xmit(skb, dev);
+       if (!netif_subqueue_stopped(dev, skb))
+               ret = dev_hard_start_xmit(skb, dev);
        HARD_TX_UNLOCK(dev);
 
        spin_lock(&dev->queue_lock);
index 421281d9dd1d3f9103b17c71b68b0d927d3807da..c0ed06d4a5046516c1e67d2b8f15df2aca07ae8b 100644 (file)
@@ -252,6 +252,9 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
 static inline int teql_resolve(struct sk_buff *skb,
                               struct sk_buff *skb_res, struct net_device *dev)
 {
+       if (dev->qdisc == &noop_qdisc)
+               return -ENODEV;
+
        if (dev->header_ops == NULL ||
            skb->dst == NULL ||
            skb->dst->neighbour == NULL)
index 03158e3665da0b34786843104d4ab5f4b5fa4736..013e3d3ab0f1a6217868785c5d160b0acb0eacb8 100644 (file)
@@ -262,10 +262,14 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
         */
        asoc->peer.sack_needed = 1;
 
-       /* Assume that the peer recongizes ASCONF until reported otherwise
-        * via an ERROR chunk.
+       /* Assume that the peer will tell us if he recognizes ASCONF
+        * as part of INIT exchange.
+        * The sctp_addip_noauth option is there for backward compatibilty
+        * and will revert old behavior.
         */
-       asoc->peer.asconf_capable = 1;
+       asoc->peer.asconf_capable = 0;
+       if (sctp_addip_noauth)
+               asoc->peer.asconf_capable = 1;
 
        /* Create an input queue.  */
        sctp_inq_init(&asoc->base.inqueue);
index dfffa94fb9f636366616ca3e349ffcfee746f5cb..cae95af9a8cc147f2652c7b2a3c6c80880fd0f7a 100644 (file)
@@ -180,9 +180,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 /* Delete an address from the bind address list in the SCTP_bind_addr
  * structure.
  */
-int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr,
-                       void fastcall (*rcu_call)(struct rcu_head *head,
-                                        void (*func)(struct rcu_head *head)))
+int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
 {
        struct sctp_sockaddr_entry *addr, *temp;
 
@@ -198,15 +196,10 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr,
                }
        }
 
-       /* Call the rcu callback provided in the args.  This function is
-        * called by both BH packet processing and user side socket option
-        * processing, but it works on different lists in those 2 contexts.
-        * Each context provides it's own callback, whether call_rcu_bh()
-        * or call_rcu(), to make sure that we wait for an appropriate time.
-        */
        if (addr && !addr->valid) {
-               rcu_call(&addr->rcu, sctp_local_addr_free);
+               call_rcu(&addr->rcu, sctp_local_addr_free);
                SCTP_DBG_OBJCNT_DEC(addr);
+               return 0;
        }
 
        return -EINVAL;
index 2d2d81ef4a69011d89e3dcc9ecdc15ce35dc806b..de6f505d6ff8250291972d4e53c391dcf1548e57 100644 (file)
@@ -328,24 +328,35 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
        const union sctp_addr *paddr,
        struct sctp_transport **transport)
 {
+       struct sctp_association *asoc = NULL;
+       struct sctp_transport *t = NULL;
+       struct sctp_hashbucket *head;
+       struct sctp_ep_common *epb;
+       struct hlist_node *node;
+       int hash;
        int rport;
-       struct sctp_association *asoc;
-       struct list_head *pos;
 
+       *transport = NULL;
        rport = ntohs(paddr->v4.sin_port);
 
-       list_for_each(pos, &ep->asocs) {
-               asoc = list_entry(pos, struct sctp_association, asocs);
-               if (rport == asoc->peer.port) {
-                       *transport = sctp_assoc_lookup_paddr(asoc, paddr);
-
-                       if (*transport)
-                               return asoc;
+       hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
+       head = &sctp_assoc_hashtable[hash];
+       read_lock(&head->lock);
+       sctp_for_each_hentry(epb, node, &head->chain) {
+               asoc = sctp_assoc(epb);
+               if (asoc->ep != ep || rport != asoc->peer.port)
+                       goto next;
+
+               t = sctp_assoc_lookup_paddr(asoc, paddr);
+               if (t) {
+                       *transport = t;
+                       break;
                }
+next:
+               asoc = NULL;
        }
-
-       *transport = NULL;
-       return NULL;
+       read_unlock(&head->lock);
+       return asoc;
 }
 
 /* Lookup association on an endpoint based on a peer address.  BH-safe.  */
index 86503e7fa21e7fa55bcb54f1762dc5840c11cdfe..91ae463b079b13bf62c89fa7d8e7529e7af85685 100644 (file)
@@ -656,7 +656,6 @@ discard:
 /* Insert endpoint into the hash table.  */
 static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
 {
-       struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
        struct sctp_hashbucket *head;
 
@@ -666,12 +665,7 @@ static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
        head = &sctp_ep_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-       epp = &head->chain;
-       epb->next = *epp;
-       if (epb->next)
-               (*epp)->pprev = &epb->next;
-       *epp = epb;
-       epb->pprev = epp;
+       hlist_add_head(&epb->node, &head->chain);
        sctp_write_unlock(&head->lock);
 }
 
@@ -691,19 +685,15 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
 
        epb = &ep->base;
 
+       if (hlist_unhashed(&epb->node))
+               return;
+
        epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
 
        head = &sctp_ep_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-
-       if (epb->pprev) {
-               if (epb->next)
-                       epb->next->pprev = epb->pprev;
-               *epb->pprev = epb->next;
-               epb->pprev = NULL;
-       }
-
+       __hlist_del(&epb->node);
        sctp_write_unlock(&head->lock);
 }
 
@@ -721,12 +711,13 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
        struct sctp_endpoint *ep;
+       struct hlist_node *node;
        int hash;
 
        hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
        head = &sctp_ep_hashtable[hash];
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                ep = sctp_ep(epb);
                if (sctp_endpoint_is_match(ep, laddr))
                        goto hit;
@@ -744,7 +735,6 @@ hit:
 /* Insert association into the hash table.  */
 static void __sctp_hash_established(struct sctp_association *asoc)
 {
-       struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
        struct sctp_hashbucket *head;
 
@@ -756,12 +746,7 @@ static void __sctp_hash_established(struct sctp_association *asoc)
        head = &sctp_assoc_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-       epp = &head->chain;
-       epb->next = *epp;
-       if (epb->next)
-               (*epp)->pprev = &epb->next;
-       *epp = epb;
-       epb->pprev = epp;
+       hlist_add_head(&epb->node, &head->chain);
        sctp_write_unlock(&head->lock);
 }
 
@@ -790,14 +775,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc)
        head = &sctp_assoc_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-
-       if (epb->pprev) {
-               if (epb->next)
-                       epb->next->pprev = epb->pprev;
-               *epb->pprev = epb->next;
-               epb->pprev = NULL;
-       }
-
+       __hlist_del(&epb->node);
        sctp_write_unlock(&head->lock);
 }
 
@@ -822,6 +800,7 @@ static struct sctp_association *__sctp_lookup_association(
        struct sctp_ep_common *epb;
        struct sctp_association *asoc;
        struct sctp_transport *transport;
+       struct hlist_node *node;
        int hash;
 
        /* Optimize here for direct hit, only listening connections can
@@ -830,7 +809,7 @@ static struct sctp_association *__sctp_lookup_association(
        hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
        head = &sctp_assoc_hashtable[hash];
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                asoc = sctp_assoc(epb);
                transport = sctp_assoc_is_match(asoc, local, peer);
                if (transport)
index f10fe7fbf24c425ca9609e46ed837d505a39552b..cf4b7eb023b3ba0819ce6d960128099c662360af 100644 (file)
@@ -90,6 +90,10 @@ void sctp_inq_free(struct sctp_inq *queue)
 void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
 {
        /* Directly call the packet handling routine. */
+       if (chunk->rcvr->dead) {
+               sctp_chunk_free(chunk);
+               return;
+       }
 
        /* We are now calling this either from the soft interrupt
         * or from the backlog processing.
index 28f4fe77ceee2e44e9b2e29eefd2be632464c331..fa76f235169bfac3cedcb8517d4c62b0cd8daa5c 100644 (file)
@@ -382,7 +382,7 @@ static void sctp_insert_list(struct list_head *head, struct list_head *new)
 /* Mark all the eligible packets on a transport for retransmission.  */
 void sctp_retransmit_mark(struct sctp_outq *q,
                          struct sctp_transport *transport,
-                         __u8 fast_retransmit)
+                         __u8 reason)
 {
        struct list_head *lchunk, *ltemp;
        struct sctp_chunk *chunk;
@@ -412,20 +412,20 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                        continue;
                }
 
-               /* If we are doing retransmission due to a fast retransmit,
-                * only the chunk's that are marked for fast retransmit
-                * should be added to the retransmit queue.  If we are doing
-                * retransmission due to a timeout or pmtu discovery, only the
-                * chunks that are not yet acked should be added to the
-                * retransmit queue.
+               /* If we are doing  retransmission due to a timeout or pmtu
+                * discovery, only the  chunks that are not yet acked should
+                * be added to the retransmit queue.
                 */
-               if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
-                  (!fast_retransmit && !chunk->tsn_gap_acked)) {
+               if ((reason == SCTP_RTXR_FAST_RTX  &&
+                           (chunk->fast_retransmit > 0)) ||
+                   (reason != SCTP_RTXR_FAST_RTX  && !chunk->tsn_gap_acked)) {
                        /* If this chunk was sent less then 1 rto ago, do not
                         * retransmit this chunk, but give the peer time
-                        * to acknowlege it.
+                        * to acknowlege it.  Do this only when
+                        * retransmitting due to T3 timeout.
                         */
-                       if ((jiffies - chunk->sent_at) < transport->rto)
+                       if (reason == SCTP_RTXR_T3_RTX &&
+                           (jiffies - chunk->sent_at) < transport->last_rto)
                                continue;
 
                        /* RFC 2960 6.2.1 Processing a Received SACK
@@ -467,10 +467,10 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                }
        }
 
-       SCTP_DEBUG_PRINTK("%s: transport: %p, fast_retransmit: %d, "
+       SCTP_DEBUG_PRINTK("%s: transport: %p, reason: %d, "
                          "cwnd: %d, ssthresh: %d, flight_size: %d, "
                          "pba: %d\n", __FUNCTION__,
-                         transport, fast_retransmit,
+                         transport, reason,
                          transport->cwnd, transport->ssthresh,
                          transport->flight_size,
                          transport->partial_bytes_acked);
@@ -484,7 +484,6 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
                     sctp_retransmit_reason_t reason)
 {
        int error = 0;
-       __u8 fast_retransmit = 0;
 
        switch(reason) {
        case SCTP_RTXR_T3_RTX:
@@ -499,16 +498,18 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
        case SCTP_RTXR_FAST_RTX:
                SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS);
                sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
-               fast_retransmit = 1;
                break;
        case SCTP_RTXR_PMTUD:
                SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS);
                break;
+       case SCTP_RTXR_T1_RTX:
+               SCTP_INC_STATS(SCTP_MIB_T1_RETRANSMITS);
+               break;
        default:
                BUG();
        }
 
-       sctp_retransmit_mark(q, transport, fast_retransmit);
+       sctp_retransmit_mark(q, transport, reason);
 
        /* PR-SCTP A5) Any time the T3-rtx timer expires, on any destination,
         * the sender SHOULD try to advance the "Advanced.Peer.Ack.Point" by
@@ -641,7 +642,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
 
                /* If we are here due to a retransmit timeout or a fast
                 * retransmit and if there are any chunks left in the retransmit
-                * queue that could not fit in the PMTU sized packet, they need                  * to be marked as ineligible for a subsequent fast retransmit.
+                * queue that could not fit in the PMTU sized packet, they need
+                * to be marked as ineligible for a subsequent fast retransmit.
                 */
                if (rtx_timeout && !lchunk) {
                        list_for_each(lchunk1, lqueue) {
@@ -660,10 +662,9 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
 int sctp_outq_uncork(struct sctp_outq *q)
 {
        int error = 0;
-       if (q->cork) {
+       if (q->cork)
                q->cork = 0;
-               error = sctp_outq_flush(q, 0);
-       }
+       error = sctp_outq_flush(q, 0);
        return error;
 }
 
index e4cd841a22e478793e85e2701dc4da30b60db4b7..249973204070bfb811085b3b2ce988b7dc093128 100644 (file)
@@ -225,6 +225,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
        struct sctp_ep_common *epb;
        struct sctp_endpoint *ep;
        struct sock *sk;
+       struct hlist_node *node;
        int    hash = *(loff_t *)v;
 
        if (hash >= sctp_ep_hashsize)
@@ -233,7 +234,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
        head = &sctp_ep_hashtable[hash];
        sctp_local_bh_disable();
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                ep = sctp_ep(epb);
                sk = epb->sk;
                seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
@@ -328,6 +329,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
        struct sctp_ep_common *epb;
        struct sctp_association *assoc;
        struct sock *sk;
+       struct hlist_node *node;
        int    hash = *(loff_t *)v;
 
        if (hash >= sctp_assoc_hashsize)
@@ -336,7 +338,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
        head = &sctp_assoc_hashtable[hash];
        sctp_local_bh_disable();
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                assoc = sctp_assoc(epb);
                sk = epb->sk;
                seq_printf(seq,
index 40c1a47d1b8dc2972abcf481dc42c5d30ed55229..d50f610d1b02a4b44ffde9dee0d651f5d01fa49e 100644 (file)
@@ -1137,7 +1137,7 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_assoc_hashsize; i++) {
                rwlock_init(&sctp_assoc_hashtable[i].lock);
-               sctp_assoc_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
        }
 
        /* Allocate and initialize the endpoint hash table.  */
@@ -1151,7 +1151,7 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_ep_hashsize; i++) {
                rwlock_init(&sctp_ep_hashtable[i].lock);
-               sctp_ep_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
        }
 
        /* Allocate and initialize the SCTP port hash table.  */
@@ -1170,7 +1170,7 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_port_hashsize; i++) {
                spin_lock_init(&sctp_port_hashtable[i].lock);
-               sctp_port_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
        }
 
        printk(KERN_INFO "SCTP: Hash tables configured "
@@ -1179,6 +1179,7 @@ SCTP_STATIC __init int sctp_init(void)
 
        /* Disable ADDIP by default. */
        sctp_addip_enable = 0;
+       sctp_addip_noauth = 0;
 
        /* Enable PR-SCTP by default. */
        sctp_prsctp_enable = 1;
index c377e4e8f6533486ece6de765d0303b7bfa7f6fa..5a9783c38de160c40d66894dbefab7b6e4c76f1c 100644 (file)
@@ -1788,9 +1788,14 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                                                sizeof(sctp_paramhdr_t);
 
 
+       /* This is a fatal error.  Any accumulated non-fatal errors are
+        * not reported.
+        */
+       if (*errp)
+               sctp_chunk_free(*errp);
+
        /* Create an error chunk and fill it in with our payload. */
-       if (!*errp)
-               *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
+       *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
 
        if (*errp) {
                sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
@@ -1813,9 +1818,15 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
 {
        __u16 len = ntohs(param.p->length);
 
-       /* Make an ERROR chunk. */
-       if (!*errp)
-               *errp = sctp_make_op_error_space(asoc, chunk, len);
+       /* Processing of the HOST_NAME parameter will generate an
+        * ABORT.  If we've accumulated any non-fatal errors, they
+        * would be unrecognized parameters and we should not include
+        * them in the ABORT.
+        */
+       if (*errp)
+               sctp_chunk_free(*errp);
+
+       *errp = sctp_make_op_error_space(asoc, chunk, len);
 
        if (*errp) {
                sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len);
@@ -1847,7 +1858,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
                            break;
                    case SCTP_CID_ASCONF:
                    case SCTP_CID_ASCONF_ACK:
-                           asoc->peer.addip_capable = 1;
+                           asoc->peer.asconf_capable = 1;
                            break;
                    default:
                            break;
@@ -1862,56 +1873,40 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
  * taken if the processing endpoint does not recognize the
  * Parameter Type.
  *
- * 00 - Stop processing this SCTP chunk and discard it,
- *     do not process any further chunks within it.
+ * 00 - Stop processing this parameter; do not process any further
+ *     parameters within this chunk
  *
- * 01 - Stop processing this SCTP chunk and discard it,
- *     do not process any further chunks within it, and report
- *     the unrecognized parameter in an 'Unrecognized
- *     Parameter Type' (in either an ERROR or in the INIT ACK).
+ * 01 - Stop processing this parameter, do not process any further
+ *     parameters within this chunk, and report the unrecognized
+ *     parameter in an 'Unrecognized Parameter' ERROR chunk.
  *
  * 10 - Skip this parameter and continue processing.
  *
  * 11 - Skip this parameter and continue processing but
  *     report the unrecognized parameter in an
- *     'Unrecognized Parameter Type' (in either an ERROR or in
- *     the INIT ACK).
+ *     'Unrecognized Parameter' ERROR chunk.
  *
  * Return value:
- *     0 - discard the chunk
- *     1 - continue with the chunk
+ *     SCTP_IERROR_NO_ERROR - continue with the chunk
+ *     SCTP_IERROR_ERROR    - stop and report an error.
+ *     SCTP_IERROR_NOMEME   - out of memory.
  */
-static int sctp_process_unk_param(const struct sctp_association *asoc,
-                                 union sctp_params param,
-                                 struct sctp_chunk *chunk,
-                                 struct sctp_chunk **errp)
+static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
+                                           union sctp_params param,
+                                           struct sctp_chunk *chunk,
+                                           struct sctp_chunk **errp)
 {
-       int retval = 1;
+       int retval = SCTP_IERROR_NO_ERROR;
 
        switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
        case SCTP_PARAM_ACTION_DISCARD:
-               retval =  0;
-               break;
-       case SCTP_PARAM_ACTION_DISCARD_ERR:
-               retval =  0;
-               /* Make an ERROR chunk, preparing enough room for
-                * returning multiple unknown parameters.
-                */
-               if (NULL == *errp)
-                       *errp = sctp_make_op_error_space(asoc, chunk,
-                                       ntohs(chunk->chunk_hdr->length));
-
-               if (*errp) {
-                       sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
-                                       WORD_ROUND(ntohs(param.p->length)));
-                       sctp_addto_chunk(*errp,
-                                       WORD_ROUND(ntohs(param.p->length)),
-                                       param.v);
-               }
-
+               retval =  SCTP_IERROR_ERROR;
                break;
        case SCTP_PARAM_ACTION_SKIP:
                break;
+       case SCTP_PARAM_ACTION_DISCARD_ERR:
+               retval =  SCTP_IERROR_ERROR;
+               /* Fall through */
        case SCTP_PARAM_ACTION_SKIP_ERR:
                /* Make an ERROR chunk, preparing enough room for
                 * returning multiple unknown parameters.
@@ -1932,9 +1927,8 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
                         * to the peer and the association won't be
                         * established.
                         */
-                       retval = 0;
+                       retval = SCTP_IERROR_NOMEM;
                }
-
                break;
        default:
                break;
@@ -1943,18 +1937,20 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
        return retval;
 }
 
-/* Find unrecognized parameters in the chunk.
+/* Verify variable length parameters
  * Return values:
- *     0 - discard the chunk
- *     1 - continue with the chunk
+ *     SCTP_IERROR_ABORT - trigger an ABORT
+ *     SCTP_IERROR_NOMEM - out of memory (abort)
+ *     SCTP_IERROR_ERROR - stop processing, trigger an ERROR
+ *     SCTP_IERROR_NO_ERROR - continue with the chunk
  */
-static int sctp_verify_param(const struct sctp_association *asoc,
-                            union sctp_params param,
-                            sctp_cid_t cid,
-                            struct sctp_chunk *chunk,
-                            struct sctp_chunk **err_chunk)
+static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
+                                       union sctp_params param,
+                                       sctp_cid_t cid,
+                                       struct sctp_chunk *chunk,
+                                       struct sctp_chunk **err_chunk)
 {
-       int retval = 1;
+       int retval = SCTP_IERROR_NO_ERROR;
 
        /* FIXME - This routine is not looking at each parameter per the
         * chunk type, i.e., unrecognized parameters should be further
@@ -1976,7 +1972,9 @@ static int sctp_verify_param(const struct sctp_association *asoc,
 
        case SCTP_PARAM_HOST_NAME_ADDRESS:
                /* Tell the peer, we won't support this param.  */
-               return sctp_process_hn_param(asoc, param, chunk, err_chunk);
+               sctp_process_hn_param(asoc, param, chunk, err_chunk);
+               retval = SCTP_IERROR_ABORT;
+               break;
 
        case SCTP_PARAM_FWD_TSN_SUPPORT:
                if (sctp_prsctp_enable)
@@ -1993,9 +1991,11 @@ static int sctp_verify_param(const struct sctp_association *asoc,
                 * cause 'Protocol Violation'.
                 */
                if (SCTP_AUTH_RANDOM_LENGTH !=
-                       ntohs(param.p->length) - sizeof(sctp_paramhdr_t))
-                       return sctp_process_inv_paramlength(asoc, param.p,
+                       ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) {
+                       sctp_process_inv_paramlength(asoc, param.p,
                                                        chunk, err_chunk);
+                       retval = SCTP_IERROR_ABORT;
+               }
                break;
 
        case SCTP_PARAM_CHUNKS:
@@ -2007,9 +2007,11 @@ static int sctp_verify_param(const struct sctp_association *asoc,
                 *  INIT-ACK chunk if the sender wants to receive authenticated
                 *  chunks.  Its maximum length is 260 bytes.
                 */
-               if (260 < ntohs(param.p->length))
-                       return sctp_process_inv_paramlength(asoc, param.p,
-                                                       chunk, err_chunk);
+               if (260 < ntohs(param.p->length)) {
+                       sctp_process_inv_paramlength(asoc, param.p,
+                                                    chunk, err_chunk);
+                       retval = SCTP_IERROR_ABORT;
+               }
                break;
 
        case SCTP_PARAM_HMAC_ALGO:
@@ -2020,8 +2022,7 @@ fallthrough:
        default:
                SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
                                ntohs(param.p->type), cid);
-               return sctp_process_unk_param(asoc, param, chunk, err_chunk);
-
+               retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
                break;
        }
        return retval;
@@ -2036,6 +2037,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 {
        union sctp_params param;
        int has_cookie = 0;
+       int result;
 
        /* Verify stream values are non-zero. */
        if ((0 == peer_init->init_hdr.num_outbound_streams) ||
@@ -2043,8 +2045,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
            (0 == peer_init->init_hdr.init_tag) ||
            (SCTP_DEFAULT_MINWINDOW > ntohl(peer_init->init_hdr.a_rwnd))) {
 
-               sctp_process_inv_mandatory(asoc, chunk, errp);
-               return 0;
+               return sctp_process_inv_mandatory(asoc, chunk, errp);
        }
 
        /* Check for missing mandatory parameters.  */
@@ -2062,29 +2063,29 @@ int sctp_verify_init(const struct sctp_association *asoc,
         * VIOLATION error.  We build the ERROR chunk here and let the normal
         * error handling code build and send the packet.
         */
-       if (param.v != (void*)chunk->chunk_end) {
-               sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
-               return 0;
-       }
+       if (param.v != (void*)chunk->chunk_end)
+               return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
 
        /* The only missing mandatory param possible today is
         * the state cookie for an INIT-ACK chunk.
         */
-       if ((SCTP_CID_INIT_ACK == cid) && !has_cookie) {
-               sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
-                                          chunk, errp);
-               return 0;
-       }
-
-       /* Find unrecognized parameters. */
+       if ((SCTP_CID_INIT_ACK == cid) && !has_cookie)
+               return sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
+                                                 chunk, errp);
 
+       /* Verify all the variable length parameters */
        sctp_walk_params(param, peer_init, init_hdr.params) {
 
-               if (!sctp_verify_param(asoc, param, cid, chunk, errp)) {
-                       if (SCTP_PARAM_HOST_NAME_ADDRESS == param.p->type)
+               result = sctp_verify_param(asoc, param, cid, chunk, errp);
+               switch (result) {
+                   case SCTP_IERROR_ABORT:
+                   case SCTP_IERROR_NOMEM:
                                return 0;
-                       else
+                   case SCTP_IERROR_ERROR:
                                return 1;
+                   case SCTP_IERROR_NO_ERROR:
+                   default:
+                               break;
                }
 
        } /* for (loop through all parameters) */
@@ -2137,11 +2138,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
 
        /* If the peer claims support for ADD-IP without support
         * for AUTH, disable support for ADD-IP.
+        * Do this only if backward compatible mode is turned off.
         */
-       if (asoc->peer.addip_capable && !asoc->peer.auth_capable) {
+       if (!sctp_addip_noauth &&
+            (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
                asoc->peer.addip_disabled_mask |= (SCTP_PARAM_ADD_IP |
                                                  SCTP_PARAM_DEL_IP |
                                                  SCTP_PARAM_SET_PRIMARY);
+               asoc->peer.asconf_capable = 0;
        }
 
        /* Walk list of transports, removing transports in the UNKNOWN state. */
@@ -2848,10 +2852,11 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
 
        __be16  err_code;
        int     length = 0;
-       int     chunk_len = asconf->skb->len;
+       int     chunk_len;
        __u32   serial;
        int     all_param_pass = 1;
 
+       chunk_len = ntohs(asconf->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
        hdr = (sctp_addiphdr_t *)asconf->skb->data;
        serial = ntohl(hdr->serial);
 
@@ -2952,13 +2957,17 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
                /* This is always done in BH context with a socket lock
                 * held, so the list can not change.
                 */
+               local_bh_disable();
                list_for_each_entry(saddr, &bp->address_list, list) {
                        if (sctp_cmp_addr_exact(&saddr->a, &addr))
                                saddr->use_as_src = 1;
                }
+               local_bh_enable();
                break;
        case SCTP_PARAM_DEL_IP:
-               retval = sctp_del_bind_addr(bp, &addr, call_rcu_bh);
+               local_bh_disable();
+               retval = sctp_del_bind_addr(bp, &addr);
+               local_bh_enable();
                list_for_each(pos, &asoc->peer.transport_addr_list) {
                        transport = list_entry(pos, struct sctp_transport,
                                                 transports);
@@ -2990,7 +2999,7 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
        sctp_addip_param_t      *asconf_ack_param;
        sctp_errhdr_t           *err_param;
        int                     length;
-       int                     asconf_ack_len = asconf_ack->skb->len;
+       int                     asconf_ack_len;
        __be16                  err_code;
 
        if (no_err)
@@ -2998,6 +3007,9 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
        else
                err_code = SCTP_ERROR_REQ_REFUSED;
 
+       asconf_ack_len = ntohs(asconf_ack->chunk_hdr->length) -
+                            sizeof(sctp_chunkhdr_t);
+
        /* Skip the addiphdr from the asconf_ack chunk and store a pointer to
         * the first asconf_ack parameter.
         */
index bbdc938da86fa37166866b27cd37fe2aa25efd05..78d1a8a49bd05bf53f4f58426d6ad4c7b0d498a0 100644 (file)
@@ -453,6 +453,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
         * maximum value discussed in rule C7 above (RTO.max) may be
         * used to provide an upper bound to this doubling operation.
         */
+       transport->last_rto = transport->rto;
        transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
 }
 
@@ -1267,6 +1268,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        sctp_ootb_pkt_free(packet);
                        break;
 
+               case SCTP_CMD_T1_RETRAN:
+                       /* Mark a transport for retransmission.  */
+                       sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
+                                       SCTP_RTXR_T1_RTX);
+                       break;
+
                case SCTP_CMD_RETRAN:
                        /* Mark a transport for retransmission.  */
                        sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
@@ -1393,7 +1400,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        list_for_each(pos, &asoc->peer.transport_addr_list) {
                                t = list_entry(pos, struct sctp_transport,
                                               transports);
-                               sctp_retransmit_mark(&asoc->outqueue, t, 0);
+                               sctp_retransmit_mark(&asoc->outqueue, t,
+                                           SCTP_RTXR_T1_RTX);
                        }
 
                        sctp_add_cmd_sf(commands,
index f01b408508ff6144b94851f1a67ae09c7a7953d4..5ebbe808d801030341fbe3bd3cf7ff49b1c2d6f2 100644 (file)
@@ -2305,7 +2305,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
        /* If we've sent any data bundled with COOKIE-ECHO we will need to
         * resend
         */
-       sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN,
+       sctp_add_cmd_sf(commands, SCTP_CMD_T1_RETRAN,
                        SCTP_TRANSPORT(asoc->peer.primary_path));
 
        /* Cast away the const modifier, as we want to just
@@ -4064,11 +4064,6 @@ static sctp_disposition_t sctp_sf_abort_violation(
        struct sctp_chunk *chunk =  arg;
        struct sctp_chunk *abort = NULL;
 
-       /* Make the abort chunk. */
-       abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
-       if (!abort)
-               goto nomem;
-
        /* SCTP-AUTH, Section 6.3:
         *    It should be noted that if the receiver wants to tear
         *    down an association in an authenticated way only, the
@@ -4083,6 +4078,11 @@ static sctp_disposition_t sctp_sf_abort_violation(
        if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
                goto discard;
 
+       /* Make the abort chunk. */
+       abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
+       if (!abort)
+               goto nomem;
+
        if (asoc) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
index bd6f42a15a4b9d85336396ef680d7bec78912986..ff8bc95670edbfa6af9ece6d74d2dc656a9c3cba 100644 (file)
@@ -660,7 +660,7 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
                 * socket routing and failover schemes. Refer to comments in
                 * sctp_do_bind(). -daisy
                 */
-               retval = sctp_del_bind_addr(bp, sa_addr, call_rcu);
+               retval = sctp_del_bind_addr(bp, sa_addr);
 
                addr_buf += af->sockaddr_len;
 err_bindx_rem:
@@ -5307,6 +5307,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
 {
        struct sctp_bind_hashbucket *head; /* hash list */
        struct sctp_bind_bucket *pp; /* hash list port iterator */
+       struct hlist_node *node;
        unsigned short snum;
        int ret;
 
@@ -5331,7 +5332,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
                        index = sctp_phashfn(rover);
                        head = &sctp_port_hashtable[index];
                        sctp_spin_lock(&head->lock);
-                       for (pp = head->chain; pp; pp = pp->next)
+                       sctp_for_each_hentry(pp, node, &head->chain)
                                if (pp->port == rover)
                                        goto next;
                        break;
@@ -5358,7 +5359,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
                 */
                head = &sctp_port_hashtable[sctp_phashfn(snum)];
                sctp_spin_lock(&head->lock);
-               for (pp = head->chain; pp; pp = pp->next) {
+               sctp_for_each_hentry(pp, node, &head->chain) {
                        if (pp->port == snum)
                                goto pp_found;
                }
@@ -5702,10 +5703,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
                pp->port = snum;
                pp->fastreuse = 0;
                INIT_HLIST_HEAD(&pp->owner);
-               if ((pp->next = head->chain) != NULL)
-                       pp->next->pprev = &pp->next;
-               head->chain = pp;
-               pp->pprev = &head->chain;
+               hlist_add_head(&pp->node, &head->chain);
        }
        return pp;
 }
@@ -5714,9 +5712,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
 static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
 {
        if (pp && hlist_empty(&pp->owner)) {
-               if (pp->next)
-                       pp->next->pprev = pp->pprev;
-               *(pp->pprev) = pp->next;
+               __hlist_del(&pp->node);
                kmem_cache_free(sctp_bucket_cachep, pp);
                SCTP_DBG_OBJCNT_DEC(bind_bucket);
        }
@@ -6455,6 +6451,8 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
 }
 
 
+DEFINE_PROTO_INUSE(sctp)
+
 /* This proto struct describes the ULP interface for SCTP.  */
 struct proto sctp_prot = {
        .name        =  "SCTP",
@@ -6483,9 +6481,12 @@ struct proto sctp_prot = {
        .memory_pressure = &sctp_memory_pressure,
        .enter_memory_pressure = sctp_enter_memory_pressure,
        .memory_allocated = &sctp_memory_allocated,
+       REF_PROTO_INUSE(sctp)
 };
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+DEFINE_PROTO_INUSE(sctpv6)
+
 struct proto sctpv6_prot = {
        .name           = "SCTPv6",
        .owner          = THIS_MODULE,
@@ -6513,5 +6514,6 @@ struct proto sctpv6_prot = {
        .memory_pressure = &sctp_memory_pressure,
        .enter_memory_pressure = sctp_enter_memory_pressure,
        .memory_allocated = &sctp_memory_allocated,
+       REF_PROTO_INUSE(sctpv6)
 };
 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
index 0669778e4335aeb22911315882084b6189612ff5..da4f15734fb11f4e739059d5d0be49300ca3bbe8 100644 (file)
@@ -263,6 +263,15 @@ static ctl_table sctp_table[] = {
                .proc_handler   = &proc_dointvec,
                .strategy       = &sysctl_intvec
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "addip_noauth_enable",
+               .data           = &sctp_addip_noauth,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+               .strategy       = &sysctl_intvec
+       },
        { .ctl_name = 0 }
 };
 
index 5f467c914f8025fe595cf2a87bc355308abb587f..d55ce83a020b7a32059b92758afa790e4d912e4e 100644 (file)
@@ -74,8 +74,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
         * given destination transport address, set RTO to the protocol
         * parameter 'RTO.Initial'.
         */
+       peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rtt = 0;
-       peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rttvar = 0;
        peer->srtt = 0;
        peer->rto_pending = 0;
@@ -385,6 +385,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
                tp->rto = tp->asoc->rto_max;
 
        tp->rtt = rtt;
+       tp->last_rto = tp->rto;
 
        /* Reset rto_pending so that a new RTT measurement is started when a
         * new data chunk is sent.
@@ -578,7 +579,7 @@ void sctp_transport_reset(struct sctp_transport *t)
         */
        t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
        t->ssthresh = asoc->peer.i.a_rwnd;
-       t->rto = asoc->rto_initial;
+       t->last_rto = t->rto = asoc->rto_initial;
        t->rtt = 0;
        t->srtt = 0;
        t->rttvar = 0;
index 4be92d0a2cab51b3c9821c55b29092792bc4c59c..4908041ffb319c57d8ef1925f01d358c54f489aa 100644 (file)
@@ -862,7 +862,7 @@ static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
                        continue;
 
                /* see if this ssn has been marked by skipping */
-               if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
+               if (!SSN_lte(cssn, sctp_ssn_peek(in, csid)))
                        break;
 
                __skb_unlink(pos, &ulpq->lobby);
index 5d879fd3d01dcaaadfe74a7032855554cbc4ad12..74784dfe8e5b2b6d304c68e34e9ba4c8194123e3 100644 (file)
@@ -2319,6 +2319,11 @@ int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
        return err;
 }
 
+int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
+{
+       return sock->ops->shutdown(sock, how);
+}
+
 /* ABI emulation layers need these two */
 EXPORT_SYMBOL(move_addr_to_kernel);
 EXPORT_SYMBOL(move_addr_to_user);
@@ -2345,3 +2350,4 @@ EXPORT_SYMBOL(kernel_getsockopt);
 EXPORT_SYMBOL(kernel_setsockopt);
 EXPORT_SYMBOL(kernel_sendpage);
 EXPORT_SYMBOL(kernel_sock_ioctl);
+EXPORT_SYMBOL(kernel_sock_shutdown);
index dc55cc974c906e78d974aa664bde940fe058637c..1afeb3eb8e4c2d2e6080f3d6e47853d1b8ff8e41 100644 (file)
@@ -320,9 +320,9 @@ xprt_setup_rdma(struct xprt_create *args)
        xprt->slot = kcalloc(xprt->max_reqs,
                                sizeof(struct rpc_rqst), GFP_KERNEL);
        if (xprt->slot == NULL) {
-               kfree(xprt);
                dprintk("RPC:       %s: couldn't allocate %d slots\n",
                        __func__, xprt->max_reqs);
+               kfree(xprt);
                return ERR_PTR(-ENOMEM);
        }
 
index 515e7a692f9bf85e263bf5a8752c22f0384595d0..e835da8fc09184f8e2dddcba9c471922af1b1165 100644 (file)
@@ -457,7 +457,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
         *        What the above comment does talk about? --ANK(980817)
         */
 
-       if (atomic_read(&unix_tot_inflight))
+       if (unix_tot_inflight)
                unix_gc();              /* Garbage collect fds */
 
        return 0;
@@ -599,15 +599,14 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
        struct sock *sk = NULL;
        struct unix_sock *u;
 
-       if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
+       atomic_inc(&unix_nr_socks);
+       if (atomic_read(&unix_nr_socks) > 2 * get_max_files())
                goto out;
 
        sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
        if (!sk)
                goto out;
 
-       atomic_inc(&unix_nr_socks);
-
        sock_init_data(sock,sk);
        lockdep_set_class(&sk->sk_receive_queue.lock,
                                &af_unix_sk_receive_queue_lock_key);
@@ -625,6 +624,8 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
        init_waitqueue_head(&u->peer_wait);
        unix_insert_socket(unix_sockets_unbound, sk);
 out:
+       if (sk == NULL)
+               atomic_dec(&unix_nr_socks);
        return sk;
 }
 
index 406b6433e467b4b4cbe697d24ec03f4cfa33e22e..ebdff3d877a1e3201f69af1ae60e92d58df7177a 100644 (file)
@@ -92,7 +92,7 @@ static LIST_HEAD(gc_inflight_list);
 static LIST_HEAD(gc_candidates);
 static DEFINE_SPINLOCK(unix_gc_lock);
 
-atomic_t unix_tot_inflight = ATOMIC_INIT(0);
+unsigned int unix_tot_inflight;
 
 
 static struct sock *unix_get_socket(struct file *filp)
@@ -133,7 +133,7 @@ void unix_inflight(struct file *fp)
                } else {
                        BUG_ON(list_empty(&u->link));
                }
-               atomic_inc(&unix_tot_inflight);
+               unix_tot_inflight++;
                spin_unlock(&unix_gc_lock);
        }
 }
@@ -147,7 +147,7 @@ void unix_notinflight(struct file *fp)
                BUG_ON(list_empty(&u->link));
                if (atomic_dec_and_test(&u->inflight))
                        list_del_init(&u->link);
-               atomic_dec(&unix_tot_inflight);
+               unix_tot_inflight--;
                spin_unlock(&unix_gc_lock);
        }
 }
@@ -161,7 +161,7 @@ static inline struct sk_buff *sock_queue_head(struct sock *sk)
        for (skb = sock_queue_head(sk)->next, next = skb->next; \
             skb != sock_queue_head(sk); skb = next, next = skb->next)
 
-static void scan_inflight(struct sock *x, void (*func)(struct sock *),
+static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
                          struct sk_buff_head *hitlist)
 {
        struct sk_buff *skb;
@@ -185,9 +185,9 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *),
                                 *      if it indeed does so
                                 */
                                struct sock *sk = unix_get_socket(*fp++);
-                               if(sk) {
+                               if (sk) {
                                        hit = true;
-                                       func(sk);
+                                       func(unix_sk(sk));
                                }
                        }
                        if (hit && hitlist != NULL) {
@@ -199,7 +199,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *),
        spin_unlock(&x->sk_receive_queue.lock);
 }
 
-static void scan_children(struct sock *x, void (*func)(struct sock *),
+static void scan_children(struct sock *x, void (*func)(struct unix_sock *),
                          struct sk_buff_head *hitlist)
 {
        if (x->sk_state != TCP_LISTEN)
@@ -235,20 +235,18 @@ static void scan_children(struct sock *x, void (*func)(struct sock *),
        }
 }
 
-static void dec_inflight(struct sock *sk)
+static void dec_inflight(struct unix_sock *usk)
 {
-       atomic_dec(&unix_sk(sk)->inflight);
+       atomic_dec(&usk->inflight);
 }
 
-static void inc_inflight(struct sock *sk)
+static void inc_inflight(struct unix_sock *usk)
 {
-       atomic_inc(&unix_sk(sk)->inflight);
+       atomic_inc(&usk->inflight);
 }
 
-static void inc_inflight_move_tail(struct sock *sk)
+static void inc_inflight_move_tail(struct unix_sock *u)
 {
-       struct unix_sock *u = unix_sk(sk);
-
        atomic_inc(&u->inflight);
        /*
         * If this is still a candidate, move it to the end of the
index e787c6d16dd77ace5f998a3f8a17e50f57b38fe3..05e438f8b4e2d8511e69a4961cf8e35b0dbbeebd 100644 (file)
@@ -19,7 +19,8 @@ static int my_open(struct inode *inode, struct file *file)
 {
        int i;
 
-       trace_mark(subsystem_event, "%d %s", 123, "example string");
+       trace_mark(subsystem_event, "integer %d string %s", 123,
+               "example string");
        for (i = 0; i < 10; i++)
                trace_mark(subsystem_eventb, MARK_NOARGS);
        return -EPERM;
index 238b2e384fc84187e7c7d63143c02a5cb42992ce..a36797535615dc77647260f12d2496d850bd4177 100644 (file)
@@ -53,7 +53,7 @@ void probe_subsystem_eventb(const struct marker *mdata, void *private,
 static struct probe_data probe_array[] =
 {
        {       .name = "subsystem_event",
-               .format = "%d %s",
+               .format = "integer %d string %s",
                .probe_func = probe_subsystem_event },
        {       .name = "subsystem_eventb",
                .format = MARK_NOARGS,
index 59594126e8b67d002de4624c2704178415de5c7b..1ad6f7fc490a1233b46bcb20fd8ea7e0562f02ba 100644 (file)
@@ -4,12 +4,7 @@
 
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 
-# If a arch/$(SRCARCH)/Kconfig.$(ARCH) file exist use it
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/Kconfig.$(ARCH)),)
-        Kconfig := arch/$(SRCARCH)/Kconfig.$(ARCH)
-else
-        Kconfig := arch/$(SRCARCH)/Kconfig
-endif
+Kconfig := arch/$(SRCARCH)/Kconfig
 
 xconfig: $(obj)/qconf
        $< $(Kconfig)
index b2913e9da495bf921b9d004012adef18996f4efa..e0f402f3b75d94d765875a6299f1f154e23a1c32 100644 (file)
@@ -83,6 +83,68 @@ char *conf_get_default_confname(void)
        return name;
 }
 
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+       char *p2;
+
+       switch (sym->type) {
+       case S_TRISTATE:
+               if (p[0] == 'm') {
+                       sym->def[def].tri = mod;
+                       sym->flags |= def_flags;
+                       break;
+               }
+       case S_BOOLEAN:
+               if (p[0] == 'y') {
+                       sym->def[def].tri = yes;
+                       sym->flags |= def_flags;
+                       break;
+               }
+               if (p[0] == 'n') {
+                       sym->def[def].tri = no;
+                       sym->flags |= def_flags;
+                       break;
+               }
+               conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+               break;
+       case S_OTHER:
+               if (*p != '"') {
+                       for (p2 = p; *p2 && !isspace(*p2); p2++)
+                               ;
+                       sym->type = S_STRING;
+                       goto done;
+               }
+       case S_STRING:
+               if (*p++ != '"')
+                       break;
+               for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+                       if (*p2 == '"') {
+                               *p2 = 0;
+                               break;
+                       }
+                       memmove(p2, p2 + 1, strlen(p2));
+               }
+               if (!p2) {
+                       conf_warning("invalid string found");
+                       return 1;
+               }
+       case S_INT:
+       case S_HEX:
+       done:
+               if (sym_string_valid(sym, p)) {
+                       sym->def[def].val = strdup(p);
+                       sym->flags |= def_flags;
+               } else {
+                       conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+                       return 1;
+               }
+               break;
+       default:
+               ;
+       }
+       return 0;
+}
+
 int conf_read_simple(const char *name, int def)
 {
        FILE *in = NULL;
@@ -213,61 +275,8 @@ load:
                                conf_warning("trying to reassign symbol %s", sym->name);
                                break;
                        }
-                       switch (sym->type) {
-                       case S_TRISTATE:
-                               if (p[0] == 'm') {
-                                       sym->def[def].tri = mod;
-                                       sym->flags |= def_flags;
-                                       break;
-                               }
-                       case S_BOOLEAN:
-                               if (p[0] == 'y') {
-                                       sym->def[def].tri = yes;
-                                       sym->flags |= def_flags;
-                                       break;
-                               }
-                               if (p[0] == 'n') {
-                                       sym->def[def].tri = no;
-                                       sym->flags |= def_flags;
-                                       break;
-                               }
-                               conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-                               break;
-                       case S_OTHER:
-                               if (*p != '"') {
-                                       for (p2 = p; *p2 && !isspace(*p2); p2++)
-                                               ;
-                                       sym->type = S_STRING;
-                                       goto done;
-                               }
-                       case S_STRING:
-                               if (*p++ != '"')
-                                       break;
-                               for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
-                                       if (*p2 == '"') {
-                                               *p2 = 0;
-                                               break;
-                                       }
-                                       memmove(p2, p2 + 1, strlen(p2));
-                               }
-                               if (!p2) {
-                                       conf_warning("invalid string found");
-                                       continue;
-                               }
-                       case S_INT:
-                       case S_HEX:
-                       done:
-                               if (sym_string_valid(sym, p)) {
-                                       sym->def[def].val = strdup(p);
-                                       sym->flags |= def_flags;
-                               } else {
-                                       conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-                                       continue;
-                               }
-                               break;
-                       default:
-                               ;
-                       }
+                       if (conf_set_sym_val(sym, def, def_flags, p))
+                               continue;
                        break;
                case '\r':
                case '\n':
index bf67871173efbabbe2ad47a04ba1f24cbc6d3eeb..302e8d0839a9c7afaacff955e4a67874192117be 100644 (file)
@@ -526,6 +526,10 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info,
        if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
                return 0;
 
+       /* sigcont is permitted within same session */
+       if (sig == SIGCONT && (task_session_nr(current) == task_session_nr(p)))
+               return 0;
+
        if (secid)
                /*
                 * Signal sent as a particular user.
index 7551af1f78994aea7203a3aa76bf2df8521c9706..9e70a160d7da4e5f90d9c57ad816b4e2ec4d5b16 100644 (file)
@@ -325,7 +325,7 @@ static uint16_t spec_order[] = {
        AVTAB_MEMBER
 };
 
-int avtab_read_item(void *fp, u32 vers, struct avtab *a,
+int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
                    int (*insertf)(struct avtab *a, struct avtab_key *k,
                                   struct avtab_datum *d, void *p),
                    void *p)
@@ -333,10 +333,11 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
        __le16 buf16[4];
        u16 enabled;
        __le32 buf32[7];
-       u32 items, items2, val;
+       u32 items, items2, val, vers = pol->policyvers;
        struct avtab_key key;
        struct avtab_datum datum;
        int i, rc;
+       unsigned set;
 
        memset(&key, 0, sizeof(struct avtab_key));
        memset(&datum, 0, sizeof(struct avtab_datum));
@@ -420,12 +421,35 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
        key.target_class = le16_to_cpu(buf16[items++]);
        key.specified = le16_to_cpu(buf16[items++]);
 
+       if (!policydb_type_isvalid(pol, key.source_type) ||
+           !policydb_type_isvalid(pol, key.target_type) ||
+           !policydb_class_isvalid(pol, key.target_class)) {
+               printk(KERN_WARNING "security: avtab: invalid type or class\n");
+               return -1;
+       }
+
+       set = 0;
+       for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
+               if (key.specified & spec_order[i])
+                       set++;
+       }
+       if (!set || set > 1) {
+               printk(KERN_WARNING
+                       "security:  avtab:  more than one specifier\n");
+               return -1;
+       }
+
        rc = next_entry(buf32, fp, sizeof(u32));
        if (rc < 0) {
                printk("security: avtab: truncated entry\n");
                return -1;
        }
        datum.data = le32_to_cpu(*buf32);
+       if ((key.specified & AVTAB_TYPE) &&
+           !policydb_type_isvalid(pol, datum.data)) {
+               printk(KERN_WARNING "security: avtab: invalid type\n");
+               return -1;
+       }
        return insertf(a, &key, &datum, p);
 }
 
@@ -435,7 +459,7 @@ static int avtab_insertf(struct avtab *a, struct avtab_key *k,
        return avtab_insert(a, k, d);
 }
 
-int avtab_read(struct avtab *a, void *fp, u32 vers)
+int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
 {
        int rc;
        __le32 buf[1];
@@ -459,7 +483,7 @@ int avtab_read(struct avtab *a, void *fp, u32 vers)
                goto bad;
 
        for (i = 0; i < nel; i++) {
-               rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
+               rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL);
                if (rc) {
                        if (rc == -ENOMEM)
                                printk(KERN_ERR "security: avtab: out of memory\n");
index d8edf8ca56d12de1eea45c374678b64896fb75ad..8da6a842808623f2ffe6f0244aaba80d9d4df111 100644 (file)
@@ -64,12 +64,13 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
 void avtab_destroy(struct avtab *h);
 void avtab_hash_eval(struct avtab *h, char *tag);
 
-int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
+struct policydb;
+int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
                    int (*insert)(struct avtab *a, struct avtab_key *k,
                                  struct avtab_datum *d, void *p),
                    void *p);
 
-int avtab_read(struct avtab *a, void *fp, u32 vers);
+int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
 
 struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
                                          struct avtab_datum *datum);
index 45b93a827c802f2b03dce5fef0c4a2551cbb9d28..50ad85d4b77c88c3ab61828ba2161bce8ad8315f 100644 (file)
@@ -362,7 +362,8 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list *
        data.head = NULL;
        data.tail = NULL;
        for (i = 0; i < len; i++) {
-               rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
+               rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
+                                    &data);
                if (rc)
                        return rc;
 
index c1a6b22d48d9aa14195673c3f27f9d638ea05ee7..920b5e36a1af97c00ea6294370a4717651a738aa 100644 (file)
@@ -129,8 +129,8 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
                        cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
                        c_iter->bitmap[cmap_idx]
                                |= e_iter->maps[cmap_idx] << cmap_sft;
-                       e_iter = e_iter->next;
                }
+               e_iter = e_iter->next;
        }
 
        return 0;
index 9a11deaaa9e71963f610829a908f9cf2bcf613ea..fb5d70a6628dfe79a31a5209f20e38eccdc00bbc 100644 (file)
@@ -157,49 +157,55 @@ void mls_sid_to_context(struct context *context,
        return;
 }
 
+int mls_level_isvalid(struct policydb *p, struct mls_level *l)
+{
+       struct level_datum *levdatum;
+       struct ebitmap_node *node;
+       int i;
+
+       if (!l->sens || l->sens > p->p_levels.nprim)
+               return 0;
+       levdatum = hashtab_search(p->p_levels.table,
+                                 p->p_sens_val_to_name[l->sens - 1]);
+       if (!levdatum)
+               return 0;
+
+       ebitmap_for_each_positive_bit(&l->cat, node, i) {
+               if (i > p->p_cats.nprim)
+                       return 0;
+               if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
+                       /*
+                        * Category may not be associated with
+                        * sensitivity.
+                        */
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+int mls_range_isvalid(struct policydb *p, struct mls_range *r)
+{
+       return (mls_level_isvalid(p, &r->level[0]) &&
+               mls_level_isvalid(p, &r->level[1]) &&
+               mls_level_dom(&r->level[1], &r->level[0]));
+}
+
 /*
  * Return 1 if the MLS fields in the security context
  * structure `c' are valid.  Return 0 otherwise.
  */
 int mls_context_isvalid(struct policydb *p, struct context *c)
 {
-       struct level_datum *levdatum;
        struct user_datum *usrdatum;
-       struct ebitmap_node *node;
-       int i, l;
 
        if (!selinux_mls_enabled)
                return 1;
 
-       /*
-        * MLS range validity checks: high must dominate low, low level must
-        * be valid (category set <-> sensitivity check), and high level must
-        * be valid (category set <-> sensitivity check)
-        */
-       if (!mls_level_dom(&c->range.level[1], &c->range.level[0]))
-               /* High does not dominate low. */
+       if (!mls_range_isvalid(p, &c->range))
                return 0;
 
-       for (l = 0; l < 2; l++) {
-               if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim)
-                       return 0;
-               levdatum = hashtab_search(p->p_levels.table,
-                       p->p_sens_val_to_name[c->range.level[l].sens - 1]);
-               if (!levdatum)
-                       return 0;
-
-               ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
-                       if (i > p->p_cats.nprim)
-                               return 0;
-                       if (!ebitmap_get_bit(&levdatum->level->cat, i))
-                               /*
-                                * Category may not be associated with
-                                * sensitivity in low level.
-                                */
-                               return 0;
-               }
-       }
-
        if (c->role == OBJECT_R_VAL)
                return 1;
 
index 096d1b4ef7fbb7cd7759cd9148840df3e0e2af5c..ab53663d9f5f96691915d568954712260e92f2ae 100644 (file)
@@ -27,6 +27,8 @@
 int mls_compute_context_len(struct context *context);
 void mls_sid_to_context(struct context *context, char **scontext);
 int mls_context_isvalid(struct policydb *p, struct context *c);
+int mls_range_isvalid(struct policydb *p, struct mls_range *r);
+int mls_level_isvalid(struct policydb *p, struct mls_level *l);
 
 int mls_context_to_sid(char oldc,
                       char **scontext,
index 539828b229b2e27f39ba6b9904f37308b38d6baa..b582aae3c62c339f320a11d067a14f53fdea3038 100644 (file)
@@ -713,6 +713,27 @@ out:
        return rc;
 }
 
+int policydb_class_isvalid(struct policydb *p, unsigned int class)
+{
+       if (!class || class > p->p_classes.nprim)
+               return 0;
+       return 1;
+}
+
+int policydb_role_isvalid(struct policydb *p, unsigned int role)
+{
+       if (!role || role > p->p_roles.nprim)
+               return 0;
+       return 1;
+}
+
+int policydb_type_isvalid(struct policydb *p, unsigned int type)
+{
+       if (!type || type > p->p_types.nprim)
+               return 0;
+       return 1;
+}
+
 /*
  * Return 1 if the fields in the security context
  * structure `c' are valid.  Return 0 otherwise.
@@ -1260,6 +1281,7 @@ static int mls_read_level(struct mls_level *lp, void *fp)
                       "categories\n");
                goto bad;
        }
+
        return 0;
 
 bad:
@@ -1563,7 +1585,7 @@ int policydb_read(struct policydb *p, void *fp)
                p->symtab[i].nprim = nprim;
        }
 
-       rc = avtab_read(&p->te_avtab, fp, p->policyvers);
+       rc = avtab_read(&p->te_avtab, fp, p);
        if (rc)
                goto bad;
 
@@ -1595,6 +1617,12 @@ int policydb_read(struct policydb *p, void *fp)
                tr->role = le32_to_cpu(buf[0]);
                tr->type = le32_to_cpu(buf[1]);
                tr->new_role = le32_to_cpu(buf[2]);
+               if (!policydb_role_isvalid(p, tr->role) ||
+                   !policydb_type_isvalid(p, tr->type) ||
+                   !policydb_role_isvalid(p, tr->new_role)) {
+                       rc = -EINVAL;
+                       goto bad;
+               }
                ltr = tr;
        }
 
@@ -1619,6 +1647,11 @@ int policydb_read(struct policydb *p, void *fp)
                        goto bad;
                ra->role = le32_to_cpu(buf[0]);
                ra->new_role = le32_to_cpu(buf[1]);
+               if (!policydb_role_isvalid(p, ra->role) ||
+                   !policydb_role_isvalid(p, ra->new_role)) {
+                       rc = -EINVAL;
+                       goto bad;
+               }
                lra = ra;
        }
 
@@ -1872,9 +1905,19 @@ int policydb_read(struct policydb *p, void *fp)
                                rt->target_class = le32_to_cpu(buf[0]);
                        } else
                                rt->target_class = SECCLASS_PROCESS;
+                       if (!policydb_type_isvalid(p, rt->source_type) ||
+                           !policydb_type_isvalid(p, rt->target_type) ||
+                           !policydb_class_isvalid(p, rt->target_class)) {
+                               rc = -EINVAL;
+                               goto bad;
+                       }
                        rc = mls_read_range_helper(&rt->target_range, fp);
                        if (rc)
                                goto bad;
+                       if (!mls_range_isvalid(p, &rt->target_range)) {
+                               printk(KERN_WARNING "security:  rangetrans:  invalid range\n");
+                               goto bad;
+                       }
                        lrt = rt;
                }
        }
index 844d310f4f1b54a49fce96f2cf2aa9bf60281737..ed6fc687c66fd44107afe0e475ab233399e2d0d2 100644 (file)
@@ -251,6 +251,9 @@ struct policydb {
 extern void policydb_destroy(struct policydb *p);
 extern int policydb_load_isids(struct policydb *p, struct sidtab *s);
 extern int policydb_context_isvalid(struct policydb *p, struct context *c);
+extern int policydb_class_isvalid(struct policydb *p, unsigned int class);
+extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
+extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
 extern int policydb_read(struct policydb *p, void *fp);
 
 #define PERM_SYMTAB_SIZE 32
index 36a191e7004e957fb38de4e9c5507f8941a33062..e076039690330675f6679edd39b18f02ab8e852d 100644 (file)
@@ -211,26 +211,27 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
        if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
                return -EINVAL;
 
-       if (uctx->ctx_len >= PAGE_SIZE)
+       str_len = uctx->ctx_len;
+       if (str_len >= PAGE_SIZE)
                return -ENOMEM;
 
        *ctxp = ctx = kmalloc(sizeof(*ctx) +
-                             uctx->ctx_len + 1,
+                             str_len + 1,
                              GFP_KERNEL);
 
        if (!ctx)
                return -ENOMEM;
 
        ctx->ctx_doi = uctx->ctx_doi;
-       ctx->ctx_len = uctx->ctx_len;
+       ctx->ctx_len = str_len;
        ctx->ctx_alg = uctx->ctx_alg;
 
        memcpy(ctx->ctx_str,
               uctx+1,
-              ctx->ctx_len);
-       ctx->ctx_str[ctx->ctx_len] = 0;
+              str_len);
+       ctx->ctx_str[str_len] = 0;
        rc = security_context_to_sid(ctx->ctx_str,
-                                    ctx->ctx_len,
+                                    str_len,
                                     &ctx->ctx_sid);
 
        if (rc)