Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 11 Jun 2007 18:39:25 +0000 (11:39 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 11 Jun 2007 18:39:25 +0000 (11:39 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] CIFS should honour umask
  [CIFS] Missing flag on negprot needed for some servers to force packet signing
  [CIFS] whitespace cleanup part 2
  [CIFS] whitespace cleanup
  [CIFS] fix mempool destroy done in wrong order in cifs error path
  [CIFS] typo in previous patch
  [CIFS] Fix oops on failed cifs mount (in kthread_stop)

881 files changed:
Documentation/BUG-HUNTING
Documentation/CodingStyle
Documentation/DocBook/gadget.tmpl
Documentation/DocBook/usb.tmpl
Documentation/HOWTO
Documentation/SubmitChecklist
Documentation/SubmittingPatches
Documentation/atomic_ops.txt
Documentation/block/capability.txt [new file with mode: 0644]
Documentation/dontdiff
Documentation/driver-model/platform.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/directory-locking
Documentation/filesystems/porting
Documentation/filesystems/tmpfs.txt
Documentation/firmware_class/README
Documentation/firmware_class/firmware_sample_driver.c
Documentation/firmware_class/firmware_sample_firmware_class.c
Documentation/hrtimer/timer_stats.txt
Documentation/i386/boot.txt
Documentation/ia64/aliasing-test.c
Documentation/initrd.txt
Documentation/kernel-parameters.txt
Documentation/memory-barriers.txt
Documentation/networking/00-INDEX
Documentation/networking/cxacru.txt [new file with mode: 0644]
Documentation/networking/xfrm_sysctl.txt [new file with mode: 0644]
Documentation/powerpc/booting-without-of.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/spi/spi-summary
Documentation/thinkpad-acpi.txt
Documentation/vm/slub.txt
Documentation/watchdog/pcwd-watchdog.txt
Documentation/watchdog/watchdog-api.txt
Documentation/watchdog/watchdog.txt [deleted file]
Documentation/watchdog/wdt.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/boot/tools/mkbb.c
arch/alpha/kernel/console.c
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/core_titan.c
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/proto.h
arch/alpha/kernel/setup.c
arch/alpha/kernel/signal.c
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_marvel.c
arch/alpha/kernel/sys_titan.c
arch/alpha/kernel/systbls.S
arch/alpha/lib/Makefile
arch/alpha/lib/fls.c [new file with mode: 0644]
arch/arm/boot/compressed/head.S
arch/arm/kernel/armksyms.c
arch/arm/kernel/stacktrace.c
arch/arm/mach-at91/board-dk.c
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9rlek.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/pm.c
arch/arm/mach-footbridge/cats-pci.c
arch/arm/mach-imx/generic.c
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2800.c
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp23xx/ixdp2351.c
arch/arm/mach-ixp23xx/pci.c
arch/arm/mach-ixp23xx/roadrunner.c
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/coyote-pci.c
arch/arm/mach-ixp4xx/dsmg600-setup.c
arch/arm/mach-ixp4xx/ixdpg425-pci.c
arch/arm/mach-ixp4xx/nas100d-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-s3c2410/bast.h [deleted file]
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2412/s3c2412.c
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/alignment.c
arch/arm/mm/proc-v7.S
arch/arm/mm/tlb-v7.S [new file with mode: 0644]
arch/arm/nwfpe/softfloat.h
arch/arm/oprofile/op_model_mpcore.c
arch/h8300/kernel/sys_h8300.c
arch/h8300/kernel/traps.c
arch/i386/Kconfig
arch/i386/kernel/cpu/mtrr/main.c
arch/i386/kernel/microcode.c
arch/i386/kernel/reboot.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/vmi.c
arch/i386/mach-generic/bigsmp.c
arch/i386/math-emu/fpu_entry.c
arch/i386/mm/fault.c
arch/i386/oprofile/nmi_int.c
arch/i386/pci/fixup.c
arch/ia64/kernel/acpi-processor.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/smpboot.c
arch/m68k/Kconfig
arch/m68k/Makefile
arch/m68k/kernel/Makefile
arch/m68k/kernel/module.c
arch/m68k/kernel/module.lds [new file with mode: 0644]
arch/m68k/kernel/setup.c
arch/m68k/kernel/vmlinux-std.lds
arch/m68k/kernel/vmlinux-sun3.lds
arch/m68k/mac/debug.c
arch/m68k/mm/init.c
arch/m68k/mm/memory.c
arch/m68k/mm/motorola.c
arch/m68k/sun3/config.c
arch/m68knommu/platform/5307/timers.c
arch/mips/Kconfig
arch/mips/emma2rh/markeins/setup.c
arch/mips/jmr3927/rbhma3100/kgdb_io.c
arch/mips/kernel/linux32.c
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/traps.c
arch/mips/mips-boards/atlas/atlas_setup.c
arch/mips/mips-boards/generic/display.c
arch/mips/mips-boards/generic/time.c
arch/mips/mips-boards/malta/malta_setup.c
arch/mips/mips-boards/sead/sead_setup.c
arch/mips/mm/dma-default.c
arch/mips/pci/pci-ocelot.c
arch/mips/qemu/q-irq.c
arch/mips/sgi-ip32/Makefile
arch/mips/sgi-ip32/ip32-platform.c [new file with mode: 0644]
arch/mips/sni/pcimt.c
arch/mips/sni/setup.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/crt0.S
arch/powerpc/boot/dts/lite5200.dts
arch/powerpc/boot/dts/lite5200b.dts
arch/powerpc/boot/wrapper
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/platforms/cell/cbe_cpufreq.c
arch/powerpc/platforms/cell/spufs/context.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/spufs.h
arch/powerpc/platforms/celleb/Makefile
arch/powerpc/platforms/chrp/pegasos_eth.c
arch/powerpc/platforms/pasemi/idle.c
arch/powerpc/platforms/pasemi/iommu.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/qe_lib/Kconfig
arch/ppc/kernel/entry.S
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/mm/hashtable.S
arch/ppc/mm/pgtable.c
arch/ppc/syslib/ibm_ocp.c
arch/ppc/syslib/qspan_pci.c
arch/s390/hypfs/hypfs_diag.c
arch/s390/kernel/debug.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/sh/Makefile
arch/sh/boards/se/73180/setup.c
arch/sh/boards/superh/microdev/irq.c
arch/sh/cchips/voyagergx/irq.c
arch/sh/drivers/dma/dma-api.c
arch/sh/kernel/cf-enabler.c
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/sh/kernel/cpu/sh4/probe.c
arch/sh/kernel/smp.c
arch/sh/kernel/timers/timer.c
arch/sh/kernel/vsyscall/vsyscall.c
arch/sh/mm/ioremap.c
arch/sh64/kernel/pci_sh5.c
arch/sparc/Kconfig
arch/sparc/kernel/time.c
arch/sparc/lib/atomic32.c
arch/sparc64/Kconfig
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/devices.c [deleted file]
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/head.S
arch/sparc64/kernel/hvapi.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/itlb_miss.S
arch/sparc64/kernel/mdesc.c [new file with mode: 0644]
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/power.c
arch/sparc64/kernel/process.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sstate.c [new file with mode: 0644]
arch/sparc64/kernel/sun4v_ivec.S
arch/sparc64/kernel/sysfs.c [new file with mode: 0644]
arch/sparc64/kernel/time.c
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/vmlinux.lds.S
arch/sparc64/mm/init.c
arch/sparc64/prom/misc.c
arch/um/Kconfig
arch/um/drivers/line.c
arch/um/drivers/stderr_console.c
arch/um/drivers/ubd_kern.c
arch/um/kernel/exitcode.c
arch/um/os-Linux/start_up.c
arch/x86_64/Kconfig
arch/x86_64/kernel/k8.c
arch/x86_64/kernel/traps.c
arch/x86_64/mm/fault.c
arch/x86_64/mm/init.c
arch/xtensa/kernel/asm-offsets.c
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/head.S
arch/xtensa/kernel/pci.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/signal.c
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/kernel/xtensa_ksyms.c
arch/xtensa/lib/strncpy_user.S
arch/xtensa/lib/strnlen_user.S
arch/xtensa/mm/init.c
arch/xtensa/platform-iss/network.c
block/genhd.c
crypto/cryptd.c
drivers/acpi/asus_acpi.c
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/tables/tbinstal.c
drivers/acpi/thermal.c
drivers/acpi/toshiba_acpi.c
drivers/acpi/utilities/utcopy.c
drivers/acpi/utilities/uteval.c
drivers/acpi/utilities/utobject.c
drivers/acpi/utilities/utxface.c
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_artop.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_isapnp.c
drivers/ata/pata_it821x.c
drivers/ata/pata_scc.c
drivers/ata/pata_sis.c
drivers/ata/pata_via.c
drivers/ata/sata_mv.c
drivers/ata/sata_promise.c
drivers/ata/sata_sis.c
drivers/ata/sata_via.c
drivers/atm/firestream.c
drivers/atm/idt77252.c
drivers/atm/idt77252.h
drivers/auxdisplay/Kconfig
drivers/auxdisplay/cfag12864bfb.c
drivers/base/class.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/firmware_class.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/bluetooth/hci_usb.c
drivers/cdrom/mcdx.c
drivers/char/agp/agp.h
drivers/char/agp/intel-agp.c
drivers/char/cyclades.c
drivers/char/drm/Kconfig
drivers/char/drm/drm_drawable.c
drivers/char/drm/drm_pciids.h
drivers/char/drm/i915_irq.c
drivers/char/n_tty.c
drivers/char/random.c
drivers/char/stallion.c
drivers/char/tty_io.c
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Makefile
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ks8695_wdt.c [new file with mode: 0644]
drivers/crypto/geode-aes.c
drivers/crypto/geode-aes.h
drivers/firewire/Kconfig
drivers/firewire/Makefile
drivers/firewire/fw-card.c
drivers/firewire/fw-cdev.c
drivers/firewire/fw-device.h
drivers/firewire/fw-ohci.c
drivers/firewire/fw-sbp2.c
drivers/hwmon/Kconfig
drivers/hwmon/applesmc.c
drivers/hwmon/coretemp.c
drivers/hwmon/ds1621.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/w83627hf.c
drivers/i2c/busses/i2c-pxa.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/atiixp.c
drivers/ide/pci/generic.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it821x.c
drivers/ide/pci/serverworks.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c
drivers/infiniband/core/cm.c
drivers/infiniband/hw/amso1100/c2.c
drivers/infiniband/hw/ehca/hcp_if.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/input/evdev.c
drivers/input/joydev.c
drivers/input/joystick/db9.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/keyboard/pxa27x_keyboard.c
drivers/input/misc/input-polldev.c
drivers/input/mouse/Kconfig
drivers/input/mouse/alps.c
drivers/input/mouse/logips2pp.c
drivers/input/mousedev.c
drivers/input/serio/sa1111ps2.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/input/tsdev.c
drivers/isdn/Kconfig
drivers/isdn/hardware/eicon/capifunc.c
drivers/isdn/hardware/eicon/diva_didd.c
drivers/isdn/hardware/eicon/divasfunc.c
drivers/isdn/hardware/eicon/message.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hisax/st5481_init.c
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/i4l/isdn_tty.c
drivers/kvm/vmx.c
drivers/macintosh/Kconfig
drivers/macintosh/adbhid.c
drivers/md/bitmap.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/raid0.c
drivers/media/common/Kconfig
drivers/media/dvb/b2c2/Makefile
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/frontends/tda10086.c
drivers/media/dvb/frontends/tda826x.c
drivers/media/video/Kconfig
drivers/media/video/ivtv/ivtv-cards.h
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-irq.c
drivers/media/video/ivtv/ivtv-queue.c
drivers/media/video/ivtv/ivtv-queue.h
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtv-vbi.c
drivers/media/video/ivtv/ivtv-vbi.h
drivers/media/video/saa7111.c
drivers/media/video/usbvision/usbvision-core.c
drivers/media/video/usbvision/usbvision.h
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptscsih.c
drivers/message/i2o/driver.c
drivers/mfd/ucb1x00-ts.c
drivers/misc/phantom.c
drivers/misc/thinkpad_acpi.c
drivers/misc/thinkpad_acpi.h
drivers/misc/tifm_7xx1.c
drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/card/queue.h
drivers/mmc/core/sd.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/au1xmmc.c
drivers/mtd/Makefile
drivers/mtd/devices/pmc551.c
drivers/mtd/maps/uclinux.c
drivers/mtd/mtdsuper.c [new file with mode: 0644]
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/ppchameleonevb.c
drivers/net/8139cp.c
drivers/net/Kconfig
drivers/net/acenic.c
drivers/net/acenic.h
drivers/net/amd8111e.c
drivers/net/amd8111e.h
drivers/net/arcnet/Kconfig
drivers/net/atl1/atl1_main.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/cassini.c
drivers/net/chelsio/cxgb2.c
drivers/net/chelsio/suni1x10gexp_regs.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/defxx.c
drivers/net/e1000/e1000_main.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/fec_8xx/fec_main.c
drivers/net/forcedeth.c
drivers/net/gianfar.c
drivers/net/hp100.c
drivers/net/meth.c
drivers/net/mlx4/alloc.c
drivers/net/myri10ge/myri10ge.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/ns83820.c
drivers/net/phy/fixed.c
drivers/net/qla3xxx.c
drivers/net/r8169.c
drivers/net/s2io.c
drivers/net/skfp/smt.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/smc91x.h
drivers/net/spider_net.c
drivers/net/tg3.c
drivers/net/tokenring/Kconfig
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/ucc_geth_mii.c
drivers/net/usb/asix.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/rndis_host.c
drivers/net/usb/usbnet.c
drivers/net/usb/usbnet.h
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/fw.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/pci/msi.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pcmcia/at91_cf.c
drivers/rtc/rtc-cmos.c
drivers/s390/block/dasd_eer.c
drivers/s390/char/raw3270.c
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/sbus/char/flash.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/NCR5380.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
drivers/scsi/aic94xx/aic94xx_tmf.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/ipr.c
drivers/scsi/jazz_esp.c
drivers/scsi/libsrp.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/pluto.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_scan.c
drivers/scsi/sd.c
drivers/scsi/stex.c
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/serial_ks8695.c
drivers/serial/suncore.c
drivers/serial/sunzilog.c
drivers/spi/atmel_spi.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/omap_uwire.c
drivers/spi/spi.c
drivers/spi/spi_imx.c
drivers/spi/spidev.c
drivers/tc/zs.c
drivers/usb/atm/cxacru.c
drivers/usb/class/usblp.c
drivers/usb/core/Kconfig
drivers/usb/core/config.c
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/core/usb.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/u132-hcd.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/ldusb.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/mos7840.c
drivers/usb/serial/omninet.c
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
drivers/usb/storage/onetouch.c
drivers/usb/storage/unusual_devs.h
drivers/video/Kconfig
drivers/video/arkfb.c
drivers/video/console/Makefile
drivers/video/console/fbcon.h
drivers/video/ffb.c
drivers/video/imxfb.c
drivers/video/neofb.c
drivers/video/pm2fb.c
drivers/video/pm3fb.c
drivers/video/ps3fb.c
drivers/video/skeletonfb.c
drivers/video/sunxvr2500.c
drivers/video/sunxvr500.c
drivers/video/vt8623fb.c
drivers/video/w100fb.c
fs/afs/internal.h
fs/binfmt_flat.c
fs/compat.c
fs/compat_ioctl.c
fs/ecryptfs/file.c
fs/ecryptfs/mmap.c
fs/exec.c
fs/ext4/balloc.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/super.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/ioctl.c
fs/jffs2/readinode.c
fs/jffs2/super.c
fs/jffs2/xattr.c
fs/nfs/direct.c
fs/nfs/pagelist.c
fs/nfs/write.c
fs/ntfs/inode.c
fs/ocfs2/aops.c
fs/ocfs2/cluster/masklog.c
fs/ocfs2/file.c
fs/ocfs2/localalloc.c
fs/ramfs/file-nommu.c
fs/reiserfs/dir.c
fs/signalfd.c
fs/splice.c
fs/udf/inode.c
fs/udf/super.c
fs/xfs/linux-2.6/xfs_aops.c
include/acpi/acpi_numa.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/acutils.h
include/asm-alpha/bitops.h
include/asm-alpha/core_t2.h
include/asm-alpha/core_titan.h
include/asm-alpha/core_tsunami.h
include/asm-alpha/core_wildfire.h
include/asm-alpha/thread_info.h
include/asm-alpha/unistd.h
include/asm-alpha/vga.h
include/asm-arm/arch-at91/at91_shdwc.h
include/asm-arm/arch-at91/at91_wdt.h
include/asm-arm/arch-ixp4xx/nas100d.h
include/asm-arm/arch-ixp4xx/nslu2.h
include/asm-arm/arch-ixp4xx/platform.h
include/asm-arm/arch-pxa/gpio.h
include/asm-arm/arch-s3c2410/map.h
include/asm-arm/arch-s3c2410/regs-gpioj.h
include/asm-arm/arch-s3c2410/regs-s3c2412.h [new file with mode: 0644]
include/asm-arm/ioctls.h
include/asm-arm/mach/arch.h
include/asm-arm/setup.h
include/asm-arm/termbits.h
include/asm-arm/termios.h
include/asm-arm/tlbflush.h
include/asm-arm26/setup.h
include/asm-frv/system.h
include/asm-generic/bug.h
include/asm-generic/vmlinux.lds.h
include/asm-h8300/processor.h
include/asm-i386/atomic.h
include/asm-i386/local.h
include/asm-ia64/acpi.h
include/asm-m68k/mmzone.h [new file with mode: 0644]
include/asm-m68k/module.h
include/asm-m68k/motorola_pgtable.h
include/asm-m68k/page.h
include/asm-m68k/pgalloc.h
include/asm-m68k/pgtable.h
include/asm-m68k/sun3_pgtable.h
include/asm-m68k/virtconvert.h
include/asm-mips/asmmacro.h
include/asm-mips/mips-boards/prom.h
include/asm-mips/unistd.h
include/asm-powerpc/pgalloc-64.h
include/asm-powerpc/tlb.h
include/asm-sh/cpu-sh4/freq.h
include/asm-sh/dma.h
include/asm-sh/io.h
include/asm-sh/se73180.h
include/asm-sh/smp.h
include/asm-sh/spinlock.h
include/asm-sh/spinlock_types.h
include/asm-sparc/atomic.h
include/asm-sparc64/bugs.h
include/asm-sparc64/cpudata.h
include/asm-sparc64/dma-mapping.h
include/asm-sparc64/hypervisor.h
include/asm-sparc64/kdebug.h
include/asm-sparc64/mdesc.h [new file with mode: 0644]
include/asm-sparc64/oplib.h
include/asm-sparc64/percpu.h
include/asm-sparc64/prom.h
include/asm-sparc64/smp.h
include/asm-sparc64/sstate.h [new file with mode: 0644]
include/asm-sparc64/thread_info.h
include/asm-sparc64/topology.h
include/asm-sparc64/tsb.h
include/asm-xtensa/bitops.h
include/asm-xtensa/byteorder.h
include/asm-xtensa/coprocessor.h
include/asm-xtensa/div64.h
include/asm-xtensa/elf.h
include/asm-xtensa/fcntl.h
include/asm-xtensa/mmu_context.h
include/asm-xtensa/page.h
include/asm-xtensa/param.h
include/asm-xtensa/ptrace.h
include/asm-xtensa/shmparam.h
include/asm-xtensa/sigcontext.h
include/asm-xtensa/thread_info.h
include/asm-xtensa/unistd.h
include/linux/Kbuild
include/linux/ata.h
include/linux/bootmem.h
include/linux/capability.h
include/linux/console_struct.h
include/linux/errno.h
include/linux/ext4_fs.h
include/linux/ext4_fs_extents.h
include/linux/ext4_fs_i.h
include/linux/fb.h
include/linux/firewire-cdev.h
include/linux/freezer.h
include/linux/fs.h
include/linux/genhd.h
include/linux/ide.h
include/linux/inetdevice.h
include/linux/ipv6.h
include/linux/kernel.h
include/linux/libata.h
include/linux/mtd/super.h [new file with mode: 0644]
include/linux/netdevice.h
include/linux/netfilter/nf_conntrack_ftp.h
include/linux/netfilter/nf_conntrack_h323_types.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/nfs_page.h
include/linux/pci_ids.h
include/linux/pipe_fs_i.h
include/linux/raid/bitmap.h
include/linux/rfkill.h
include/linux/sched.h
include/linux/serial_core.h
include/linux/slub_def.h
include/linux/timer.h
include/linux/videodev2.h
include/net/af_unix.h
include/net/bluetooth/l2cap.h
include/net/cipso_ipv4.h
include/net/dst.h
include/net/fib_rules.h
include/net/genetlink.h
include/net/ip.h
include/net/ip_fib.h
include/net/ipv6.h
include/net/netlabel.h
include/net/netlink.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/net/udplite.h
include/net/xfrm.h
include/sound/version.h
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/futex_compat.c
kernel/irq/spurious.c
kernel/kallsyms.c
kernel/kthread.c
kernel/power/process.c
kernel/power/swap.c
kernel/rtmutex.c
kernel/sched.c
kernel/signal.c
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
kernel/time/timer_stats.c
kernel/timer.c
kernel/workqueue.c
lib/Kconfig.debug
lib/hexdump.c
lib/kobject.c
mm/memory_hotplug.c
mm/page_alloc.c
mm/shmem.c
mm/slab.c
mm/slub.c
mm/sparse.c
net/8021q/vlan.c
net/bluetooth/l2cap.c
net/bridge/br_fdb.c
net/bridge/br_stp.c
net/bridge/br_stp_timer.c
net/core/dev.c
net/core/dst.c
net/core/neighbour.c
net/core/rtnetlink.c
net/core/sock.c
net/core/sysctl_net_core.c
net/core/utils.c
net/dccp/Kconfig
net/dccp/ccids/ccid3.c
net/dccp/ipv6.c
net/dccp/probe.c
net/decnet/dn_dev.c
net/decnet/dn_rules.c
net/ieee80211/ieee80211_module.c
net/ieee80211/softmac/ieee80211softmac_module.c
net/ipv4/arp.c
net/ipv4/cipso_ipv4.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/ipmr.c
net/ipv4/ipvs/Kconfig
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_nat_ftp.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/proc.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_probe.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv4/udp_impl.h
net/ipv4/udplite.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/addrconf.c
net/ipv6/ah6.c
net/ipv6/datagram.c
net/ipv6/fib6_rules.c
net/ipv6/ip6_fib.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipv6/udplite.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_mode_tunnel.c
net/key/af_key.c
net/mac80211/ieee80211.c
net/mac80211/ieee80211_sta.c
net/netfilter/nf_conntrack_amanda.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_h323_types.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto_gre.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_kapi.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlink/attr.c
net/netlink/genetlink.c
net/packet/af_packet.c
net/rxrpc/Kconfig
net/rxrpc/ar-call.c
net/rxrpc/ar-proc.c
net/sched/act_pedit.c
net/sched/sch_atm.c
net/sched/sch_cbq.c
net/sched/sch_generic.c
net/sched/sch_htb.c
net/sctp/Kconfig
net/sctp/debug.c
net/sctp/sm_statetable.c
net/tipc/Kconfig
net/tipc/eth_media.c
net/unix/af_unix.c
net/wanrouter/wanmain.c
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/checkpatch.pl [new file with mode: 0755]
security/selinux/netlabel.c
sound/arm/sa11xx-uda1341.c
sound/pci/ali5451/ali5451.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_sigmatel.c
sound/soc/s3c24xx/s3c24xx-pcm.c

index 65b97e1dbf70cabf7a92dee53831f191f16b4015..35f5bd243336aeb1927f42483e26fa7586bcb205 100644 (file)
@@ -191,6 +191,30 @@ e.g. crash dump output as shown by Dave Miller.
 >        mov        0x8(%ebp), %ebx         ! %ebx = skb->sk
 >        mov        0x13c(%ebx), %eax       ! %eax = inet_sk(sk)->opt
 
+In addition, you can use GDB to figure out the exact file and line
+number of the OOPS from the vmlinux file. If you have
+CONFIG_DEBUG_INFO enabled, you can simply copy the EIP value from the
+OOPS:
+
+ EIP:    0060:[<c021e50e>]    Not tainted VLI
+
+And use GDB to translate that to human-readable form:
+
+  gdb vmlinux
+  (gdb) l *0xc021e50e
+
+If you don't have CONFIG_DEBUG_INFO enabled, you use the function
+offset from the OOPS:
+
+ EIP is at vt_ioctl+0xda8/0x1482
+
+And recompile the kernel with CONFIG_DEBUG_INFO enabled:
+
+  make vmlinux
+  gdb vmlinux
+  (gdb) p vt_ioctl
+  (gdb) l *(0x<address of vt_ioctl> + 0xda8)
+
 Another very useful option of the Kernel Hacking section in menuconfig is
 Debug memory allocations. This will help you see whether data has been
 initialised and not set before use etc. To see the values that get assigned
index afc2867758914e952e9bc33f2cce4751acc70cfc..b49b92edb396835632781470f18bb31ab0055387 100644 (file)
@@ -495,29 +495,40 @@ re-formatting you may want to take a look at the man page.  But
 remember: "indent" is not a fix for bad programming.
 
 
-               Chapter 10: Configuration-files
+               Chapter 10: Kconfig configuration files
 
-For configuration options (arch/xxx/Kconfig, and all the Kconfig files),
-somewhat different indentation is used.
+For all of the Kconfig* configuration files throughout the source tree,
+the indentation is somewhat different.  Lines under a "config" definition
+are indented with one tab, while help text is indented an additional two
+spaces.  Example:
 
-Help text is indented with 2 spaces.
-
-if CONFIG_EXPERIMENTAL
-       tristate CONFIG_BOOM
-       default n
-       help
-         Apply nitroglycerine inside the keyboard (DANGEROUS)
-       bool CONFIG_CHEER
-       depends on CONFIG_BOOM
-       default y
+config AUDIT
+       bool "Auditing support"
+       depends on NET
        help
-         Output nice messages when you explode
-endif
+         Enable auditing infrastructure that can be used with another
+         kernel subsystem, such as SELinux (which requires this for
+         logging of avc messages output).  Does not do system-call
+         auditing without CONFIG_AUDITSYSCALL.
+
+Features that might still be considered unstable should be defined as
+dependent on "EXPERIMENTAL":
+
+config SLUB
+       depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
+       bool "SLUB (Unqueued Allocator)"
+       ...
+
+while seriously dangerous features (such as write support for certain
+filesystems) should advertise this prominently in their prompt string:
+
+config ADFS_FS_RW
+       bool "ADFS write support (DANGEROUS)"
+       depends on ADFS_FS
+       ...
 
-Generally, CONFIG_EXPERIMENTAL should surround all options not considered
-stable. All options that are known to trash data (experimental write-
-support for file-systems, for instance) should be denoted (DANGEROUS), other
-experimental options should be denoted (EXPERIMENTAL).
+For full documentation on the configuration files, see the file
+Documentation/kbuild/kconfig-language.txt.
 
 
                Chapter 11: Data structures
index e7fc964334086403ea4a4b73b35ef253464b2d0e..6996d977bf8fe0fc077a034e02d1acaa75f29f57 100644 (file)
@@ -52,7 +52,7 @@
 
 <toc></toc>
 
-<chapter><title>Introduction</title>
+<chapter id="intro"><title>Introduction</title>
 
 <para>This document presents a Linux-USB "Gadget"
 kernel mode
index a2ebd651b05a8d241dc529ae29c3ee05fd7459ac..af293606fbe39adba3f592bd2cd3b5a380c126b6 100644 (file)
 
     </chapter>
 
-<chapter><title>USB-Standard Types</title>
+<chapter id="types"><title>USB-Standard Types</title>
 
     <para>In <filename>&lt;linux/usb/ch9.h&gt;</filename> you will find
     the USB data types defined in chapter 9 of the USB specification.
 
     </chapter>
 
-<chapter><title>Host-Side Data Types and Macros</title>
+<chapter id="hostside"><title>Host-Side Data Types and Macros</title>
 
     <para>The host side API exposes several layers to drivers, some of
     which are more necessary than others.
 
     </chapter>
 
-    <chapter><title>USB Core APIs</title>
+    <chapter id="usbcore"><title>USB Core APIs</title>
 
     <para>There are two basic I/O models in the USB API.
     The most elemental one is asynchronous:  drivers submit requests
 !Edrivers/usb/core/hub.c
     </chapter>
 
-    <chapter><title>Host Controller APIs</title>
+    <chapter id="hcd"><title>Host Controller APIs</title>
 
     <para>These APIs are only for use by host controller drivers,
     most of which implement standard register interfaces such as
 !Idrivers/usb/core/buffer.c
     </chapter>
 
-    <chapter>
+    <chapter id="usbfs">
        <title>The USB Filesystem (usbfs)</title>
 
        <para>This chapter presents the Linux <emphasis>usbfs</emphasis>.
        not it has a kernel driver.
        </para>
 
-       <sect1>
+       <sect1 id="usbfs-files">
            <title>What files are in "usbfs"?</title>
 
            <para>Conventionally mounted at
 
        </sect1>
 
-       <sect1>
+       <sect1 id="usbfs-fstab">
            <title>Mounting and Access Control</title>
 
            <para>There are a number of mount options for usbfs, which will
 
        </sect1>
 
-       <sect1>
+       <sect1 id="usbfs-devices">
            <title>/proc/bus/usb/devices</title>
 
            <para>This file is handy for status viewing tools in user
@@ -473,7 +473,7 @@ for (;;) {
            </para>
        </sect1>
 
-       <sect1>
+       <sect1 id="usbfs-bbbddd">
            <title>/proc/bus/usb/BBB/DDD</title>
 
            <para>Use these files in one of these basic ways:
@@ -510,7 +510,7 @@ for (;;) {
            </sect1>
 
 
-       <sect1>
+       <sect1 id="usbfs-lifecycle">
            <title>Life Cycle of User Mode Drivers</title>
 
            <para>Such a driver first needs to find a device file
@@ -565,7 +565,7 @@ for (;;) {
 
            </sect1>
 
-       <sect1><title>The ioctl() Requests</title>
+       <sect1 id="usbfs-ioctl"><title>The ioctl() Requests</title>
 
            <para>To use these ioctls, you need to include the following
            headers in your userspace program:
@@ -604,7 +604,7 @@ for (;;) {
            </para>
 
 
-           <sect2>
+           <sect2 id="usbfs-mgmt">
                <title>Management/Status Requests</title>
 
                <para>A number of usbfs requests don't deal very directly
@@ -736,7 +736,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
 
                </sect2>
 
-           <sect2>
+           <sect2 id="usbfs-sync">
                <title>Synchronous I/O Support</title>
 
                <para>Synchronous requests involve the kernel blocking
@@ -865,7 +865,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
                </variablelist>
            </sect2>
 
-           <sect2>
+           <sect2 id="usbfs-async">
                <title>Asynchronous I/O Support</title>
 
                <para>As mentioned above, there are situations where it may be
index 48123dba5e6abe4fb1d106dde0d80ca75bb601a7..ced9207bedcfc9d7a27aa1476bee94ddca6fd606 100644 (file)
@@ -396,26 +396,6 @@ bugme-janitor mailing list (every change in the bugzilla is mailed here)
 
 
 
-Managing bug reports
---------------------
-
-One of the best ways to put into practice your hacking skills is by fixing
-bugs reported by other people. Not only you will help to make the kernel
-more stable, you'll learn to fix real world problems and you will improve
-your skills, and other developers will be aware of your presence. Fixing
-bugs is one of the best ways to get merits among other developers, because
-not many people like wasting time fixing other people's bugs.
-
-To work in the already reported bug reports, go to http://bugzilla.kernel.org.
-If you want to be advised of the future bug reports, you can subscribe to the
-bugme-new mailing list (only new bug reports are mailed here) or to the
-bugme-janitor mailing list (every change in the bugzilla is mailed here)
-
-       http://lists.osdl.org/mailman/listinfo/bugme-new
-       http://lists.osdl.org/mailman/listinfo/bugme-janitors
-
-
-
 Mailing lists
 -------------
 
index 3af3e65cf43b54ccfb150824e9338b8567234812..6ebffb57e3dbf326c6db594da4206c2f30bf1050 100644 (file)
@@ -84,3 +84,9 @@ kernel patches.
 24: Avoid whitespace damage such as indenting with spaces or whitespace
     at the end of lines.  You can test this by feeding the patch to
     "git apply --check --whitespace=error-all"
+
+25: Check your patch for general style as detailed in
+    Documentation/CodingStyle.  Check for trivial violations with the
+    patch style checker prior to submission (scripts/checkpatch.pl).
+    You should be able to justify all violations that remain in
+    your patch.
index a417b25fb1aa40f62234c222db0a4be1cfaa938d..0958e97d4bf4326ad0f6bc6418263f403d168eda 100644 (file)
@@ -118,7 +118,20 @@ then only post say 15 or so at a time and wait for review and integration.
 
 
 
-4) Select e-mail destination.
+4) Style check your changes.
+
+Check your patch for basic style violations, details of which can be
+found in Documentation/CodingStyle.  Failure to do so simply wastes
+the reviewers time and will get your patch rejected, probabally
+without even being read.
+
+At a minimum you should check your patches with the patch style
+checker prior to submission (scripts/patchcheck.pl).  You should
+be able to justify all violations that remain in your patch.
+
+
+
+5) Select e-mail destination.
 
 Look through the MAINTAINERS file and the source code, and determine
 if your change applies to a specific subsystem of the kernel, with
@@ -146,7 +159,7 @@ discussed should the patch then be submitted to Linus.
 
 
 
-5) Select your CC (e-mail carbon copy) list.
+6) Select your CC (e-mail carbon copy) list.
 
 Unless you have a reason NOT to do so, CC linux-kernel@vger.kernel.org.
 
@@ -187,8 +200,7 @@ URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
 
 
 
-
-6) No MIME, no links, no compression, no attachments.  Just plain text.
+7) No MIME, no links, no compression, no attachments.  Just plain text.
 
 Linus and other kernel developers need to be able to read and comment
 on the changes you are submitting.  It is important for a kernel
@@ -223,9 +235,9 @@ pref("mailnews.display.disable_format_flowed_support", true);
 
 
 
-7) E-mail size.
+8) E-mail size.
 
-When sending patches to Linus, always follow step #6.
+When sending patches to Linus, always follow step #7.
 
 Large changes are not appropriate for mailing lists, and some
 maintainers.  If your patch, uncompressed, exceeds 40 kB in size,
@@ -234,7 +246,7 @@ server, and provide instead a URL (link) pointing to your patch.
 
 
 
-8) Name your kernel version.
+9) Name your kernel version.
 
 It is important to note, either in the subject line or in the patch
 description, the kernel version to which this patch applies.
@@ -244,7 +256,7 @@ Linus will not apply it.
 
 
 
-9) Don't get discouraged.  Re-submit.
+10) Don't get discouraged.  Re-submit.
 
 After you have submitted your change, be patient and wait.  If Linus
 likes your change and applies it, it will appear in the next version
@@ -270,7 +282,7 @@ When in doubt, solicit comments on linux-kernel mailing list.
 
 
 
-10) Include PATCH in the subject
+11) Include PATCH in the subject
 
 Due to high e-mail traffic to Linus, and to linux-kernel, it is common
 convention to prefix your subject line with [PATCH].  This lets Linus
@@ -279,7 +291,7 @@ e-mail discussions.
 
 
 
-11) Sign your work
+12) Sign your work
 
 To improve tracking of who did what, especially with patches that can
 percolate to their final resting place in the kernel through several
@@ -328,7 +340,32 @@ now, but you can do this to mark internal company procedures or just
 point out some special detail about the sign-off. 
 
 
-12) The canonical patch format
+13) When to use Acked-by:
+
+The Signed-off-by: tag indicates that the signer was involved in the
+development of the patch, or that he/she was in the patch's delivery path.
+
+If a person was not directly involved in the preparation or handling of a
+patch but wishes to signify and record their approval of it then they can
+arrange to have an Acked-by: line added to the patch's changelog.
+
+Acked-by: is often used by the maintainer of the affected code when that
+maintainer neither contributed to nor forwarded the patch.
+
+Acked-by: is not as formal as Signed-off-by:.  It is a record that the acker
+has at least reviewed the patch and has indicated acceptance.  Hence patch
+mergers will sometimes manually convert an acker's "yep, looks good to me"
+into an Acked-by:.
+
+Acked-by: does not necessarily indicate acknowledgement of the entire patch.
+For example, if a patch affects multiple subsystems and has an Acked-by: from
+one subsystem maintainer then this usually indicates acknowledgement of just
+the part which affects that maintainer's code.  Judgement should be used here.
+ When in doubt people should refer to the original discussion in the mailing
+list archives.
+
+
+14) The canonical patch format
 
 The canonical patch subject line is:
 
@@ -427,6 +464,10 @@ section Linus Computer Science 101.
 Nuff said.  If your code deviates too much from this, it is likely
 to be rejected without further review, and without comment.
 
+Check your patches with the patch style checker prior to submission
+(scripts/checkpatch.pl).  You should be able to justify all
+violations that remain in your patch.
+
 
 
 2) #ifdefs are ugly
index 2a63d5662a93a1fd2e0889bc6aab93c1ae987102..05851e9982edfefbab5ead5b774ab976926a12e4 100644 (file)
@@ -149,7 +149,7 @@ defined which accomplish this:
        void smp_mb__before_atomic_dec(void);
        void smp_mb__after_atomic_dec(void);
        void smp_mb__before_atomic_inc(void);
-       void smp_mb__after_atomic_dec(void);
+       void smp_mb__after_atomic_inc(void);
 
 For example, smp_mb__before_atomic_dec() can be used like so:
 
diff --git a/Documentation/block/capability.txt b/Documentation/block/capability.txt
new file mode 100644 (file)
index 0000000..2f17294
--- /dev/null
@@ -0,0 +1,15 @@
+Generic Block Device Capability
+===============================================================================
+This file documents the sysfs file block/<disk>/capability
+
+capability is a hex word indicating which capabilities a specific disk
+supports.  For more information on bits not listed here, see
+include/linux/genhd.h
+
+Capability                             Value
+-------------------------------------------------------------------------------
+GENHD_FL_MEDIA_CHANGE_NOTIFY           4
+       When this bit is set, the disk supports Asynchronous Notification
+       of media change events.  These events will be broadcast to user
+       space via kernel uevent.
+
index 64e9f6c4826b01cfcfea27ae5f0d51891be9078f..595a5ea4c690340294de4fde47a57ece245fec59 100644 (file)
 *.grp
 *.gz
 *.html
+*.i
 *.jpeg
 *.ko
 *.log
 *.lst
+*.moc
 *.mod.c
 *.o
 *.orig
@@ -25,6 +27,9 @@
 *.s
 *.sgml
 *.so
+*.symtypes
+*.tab.c
+*.tab.h
 *.tex
 *.ver
 *.xml
 *_vga16.c
 *cscope*
 *~
+*.9
+*.9.gz
 .*
 .cscope
 53c700_d.h
+53c7xx_d.h
+53c7xx_u.h
 53c8xx_d.h*
 BitKeeper
 COPYING
@@ -70,9 +79,11 @@ bzImage*
 classlist.h*
 comp*.log
 compile.h*
+conf
 config
 config-*
 config_data.h*
+config_data.gz*
 conmakehash
 consolemap_deftbl.c*
 crc32table.h*
@@ -81,18 +92,23 @@ defkeymap.c*
 devlist.h*
 docproc
 dummy_sym.c*
+elf2ecoff
 elfconfig.h*
 filelist
 fixdep
 fore200e_mkfirm
 fore200e_pca_fw.c*
+gconf
 gen-devlist
 gen-kdb_cmds.c*
 gen_crc32table
 gen_init_cpio
 genksyms
 gentbl
+*_gray256.c
 ikconfig.h*
+initramfs_data.cpio
+initramfs_data.cpio.gz
 initramfs_list
 kallsyms
 kconfig
@@ -100,19 +116,30 @@ kconfig.tk
 keywords.c*
 ksym.c*
 ksym.h*
+kxgettext
+lkc_defs.h
 lex.c*
+lex.*.c
+lk201-map.c
 logo_*.c
 logo_*_clut224.c
 logo_*_mono.c
 lxdialog
 mach-types
 mach-types.h
+machtypes.h
 make_times_h
 map
 maui_boot.h
+mconf
+miboot*
 mk_elfconfig
+mkboot
+mkbugboot
 mkdep
+mkprep
 mktables
+mktree
 modpost
 modversions.h*
 offset.h
@@ -120,18 +147,28 @@ offsets.h
 oui.c*
 parse.c*
 parse.h*
+patches*
+pca200e.bin
+pca200e_ecd.bin2
+piggy.gz
+piggyback
 pnmtologo
 ppc_defs.h*
 promcon_tbl.c*
 pss_boot.h
+qconf
 raid6altivec*.c
 raid6int*.c
 raid6tables.c
+relocs
+series
 setup
 sim710_d.h*
+sImage
 sm_tbl*
 split-include
 tags
+tftpboot.img
 times.h*
 tkparse
 trix_boot.h
@@ -139,8 +176,11 @@ utsrelease.h*
 version.h*
 vmlinux
 vmlinux-*
+vmlinux.aout
 vmlinux.lds
 vsyscall.lds
 wanxlfw.inc
 uImage
-zImage
+unifdef
+zImage*
+zconf.hash.c
index 19c4a6e136760750365483d49751edb4853daad6..2a97320ee17f1d1b1c5a9b1efc138bbea4631f0e 100644 (file)
@@ -96,6 +96,46 @@ System setup also associates those clocks with the device, so that that
 calls to clk_get(&pdev->dev, clock_name) return them as needed.
 
 
+Legacy Drivers:  Device Probing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Some drivers are not fully converted to the driver model, because they take
+on a non-driver role:  the driver registers its platform device, rather than
+leaving that for system infrastructure.  Such drivers can't be hotplugged
+or coldplugged, since those mechanisms require device creation to be in a
+different system component than the driver.
+
+The only "good" reason for this is to handle older system designs which, like
+original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware
+configuration.  Newer systems have largely abandoned that model, in favor of
+bus-level support for dynamic configuration (PCI, USB), or device tables
+provided by the boot firmware (e.g. PNPACPI on x86).  There are too many
+conflicting options about what might be where, and even educated guesses by
+an operating system will be wrong often enough to make trouble.
+
+This style of driver is discouraged.  If you're updating such a driver,
+please try to move the device enumeration to a more appropriate location,
+outside the driver.  This will usually be cleanup, since such drivers
+tend to already have "normal" modes, such as ones using device nodes that
+were created by PNP or by platform device setup.
+
+None the less, there are some APIs to support such legacy drivers.  Avoid
+using these calls except with such hotplug-deficient drivers.
+
+       struct platform_device *platform_device_alloc(
+                       char *name, unsigned id);
+
+You can use platform_device_alloc() to dynamically allocate a device, which
+you will then initialize with resources and platform_device_register().
+A better solution is usually:
+
+       struct platform_device *platform_device_register_simple(
+                       char *name, unsigned id,
+                       struct resource *res, unsigned nres);
+
+You can use platform_device_register_simple() as a one-step call to allocate
+and register a device.
+
+
 Device Naming and Driver Binding
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The platform_device.dev.bus_id is the canonical name for the devices.
index 5c8695a3d1399d57ed984472674667a063767613..7d3f205b0ba50fddc8da631ba9fad29063239256 100644 (file)
@@ -62,7 +62,7 @@ Who:  Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
 What:  old NCR53C9x driver
 When:  October 2007
 Why:   Replaced by the much better esp_scsi driver.  Actual low-level
-       driver can ported over almost trivially.
+       driver can be ported over almost trivially.
 Who:   David Miller <davem@davemloft.net>
        Christoph Hellwig <hch@lst.de>
 
@@ -70,6 +70,7 @@ Who:  David Miller <davem@davemloft.net>
 
 What:  Video4Linux API 1 ioctls and video_decoder.h from Video devices.
 When:  December 2006
+Files: include/linux/video_decoder.h
 Why:   V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
        series. The old API have lots of drawbacks and don't provide enough
        means to work with all video and audio standards. The newer API is
@@ -103,6 +104,7 @@ Who:        Dominik Brodowski <linux@brodo.de>
 What:  remove EXPORT_SYMBOL(kernel_thread)
 When:  August 2006
 Files: arch/*/kernel/*_ksyms.c
+Funcs: kernel_thread
 Why:   kernel_thread is a low-level implementation detail.  Drivers should
         use the <linux/kthread.h> API instead which shields them from
        implementation details and provides a higherlevel interface that
index d7099a9266fb3e4703ea471b2a3bb08d69f75348..ff7b611abf330d11b8a5aef416e06106a39abbca 100644 (file)
@@ -1,5 +1,6 @@
        Locking scheme used for directory operations is based on two
-kinds of locks - per-inode (->i_sem) and per-filesystem (->s_vfs_rename_sem).
+kinds of locks - per-inode (->i_mutex) and per-filesystem
+(->s_vfs_rename_mutex).
 
        For our purposes all operations fall in 5 classes:
 
@@ -63,7 +64,7 @@ objects - A < B iff A is an ancestor of B.
 attempt to acquire some lock and already holds at least one lock.  Let's
 consider the set of contended locks.  First of all, filesystem lock is
 not contended, since any process blocked on it is not holding any locks.
-Thus all processes are blocked on ->i_sem.
+Thus all processes are blocked on ->i_mutex.
 
        Non-directory objects are not contended due to (3).  Thus link
 creation can't be a part of deadlock - it can't be blocked on source
index 5531694059ab1678c1f206690b2d747bab1033f2..dac45c92d872b977312372210243ffa318ad08cb 100644 (file)
@@ -107,7 +107,7 @@ free to drop it...
 ---
 [informational]
 
-->link() callers hold ->i_sem on the object we are linking to.  Some of your
+->link() callers hold ->i_mutex on the object we are linking to.  Some of your
 problems might be over...
 
 ---
@@ -130,9 +130,9 @@ went in - and hadn't been documented ;-/).  Just remove it from fs_flags
 ---
 [mandatory]
 
-->setattr() is called without BKL now.  Caller _always_ holds ->i_sem, so
-watch for ->i_sem-grabbing code that might be used by your ->setattr().
-Callers of notify_change() need ->i_sem now.
+->setattr() is called without BKL now.  Caller _always_ holds ->i_mutex, so
+watch for ->i_mutex-grabbing code that might be used by your ->setattr().
+Callers of notify_change() need ->i_mutex now.
 
 ---
 [recommended]
index 6dd050878a2087269b9891f704177dc7f1dc1462..145e44086358653e4b8b6b17302f3b7652246194 100644 (file)
@@ -94,10 +94,10 @@ largest node numbers in the range.  For example, mpol=bind:0-3,5,7,9-15
 
 Note that trying to mount a tmpfs with an mpol option will fail if the
 running kernel does not support NUMA; and will fail if its nodelist
-specifies a node >= MAX_NUMNODES.  If your system relies on that tmpfs
-being mounted, but from time to time runs a kernel built without NUMA
-capability (perhaps a safe recovery kernel), or configured to support
-fewer nodes, then it is advisable to omit the mpol option from automatic
+specifies a node which is not online.  If your system relies on that
+tmpfs being mounted, but from time to time runs a kernel built without
+NUMA capability (perhaps a safe recovery kernel), or with fewer nodes
+online, then it is advisable to omit the mpol option from automatic
 mount options.  It can be added later, when the tmpfs is already mounted
 on MountPoint, by 'mount -o remount,mpol=Policy:NodeList MountPoint'.
 
@@ -121,4 +121,4 @@ RAM/SWAP in 10240 inodes and it is only accessible by root.
 Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
 Updated:
-   Hugh Dickins <hugh@veritas.com>, 19 February 2006
+   Hugh Dickins <hugh@veritas.com>, 4 June 2007
index e9cc8bb26f7d0952b0226c66e6a43abe8e00a211..c3480aa66ba8048bf46483544ed6fb3ebb7151eb 100644 (file)
@@ -1,7 +1,7 @@
 
  request_firmware() hotplug interface:
  ------------------------------------
-       Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
+       Copyright (C) 2003 Manuel Estrada Sainz
 
  Why:
  ---
index 87feccdb5c9f8f67b2739358edca07c76a9a24a1..6865cbe075ec3549cf033fa3c11c07bb0ee4eef6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * firmware_sample_driver.c -
  *
- * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ * Copyright (c) 2003 Manuel Estrada Sainz
  *
  * Sample code on how to use request_firmware() from drivers.
  *
index 9e1b0e4051cd0546985b9985fd308d301d537c41..4994f1f28f8ce23bf56ec61976cbefe19c008d41 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * firmware_sample_firmware_class.c -
  *
- * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ * Copyright (c) 2003 Manuel Estrada Sainz
  *
  * NOTE: This is just a probe of concept, if you think that your driver would
  * be well served by this mechanism please contact me first.
@@ -19,7 +19,7 @@
 #include <linux/firmware.h>
 
 
-MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_AUTHOR("Manuel Estrada Sainz");
 MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
 MODULE_LICENSE("GPL");
 
index 27f782e3593f2f86047fbc2e74e387710f3a0f9a..22b0814d0ad0927024de028303a4af9cce0afc11 100644 (file)
@@ -2,9 +2,10 @@ timer_stats - timer usage statistics
 ------------------------------------
 
 timer_stats is a debugging facility to make the timer (ab)usage in a Linux
-system visible to kernel and userspace developers. It is not intended for
-production usage as it adds significant overhead to the (hr)timer code and the
-(hr)timer data structures.
+system visible to kernel and userspace developers. If enabled in the config
+but not used it has almost zero runtime overhead, and a relatively small
+data structure overhead. Even if collection is enabled runtime all the
+locking is per-CPU and lookup is hashed.
 
 timer_stats should be used by kernel and userspace developers to verify that
 their code does not make unduly use of timers. This helps to avoid unnecessary
index 66fa67fec2a764fbac91acffc8c69cdec1686125..35985b34d5a6cc194e48ce9281bac676a959dcba 100644 (file)
@@ -2,7 +2,7 @@
                     ----------------------------
 
                    H. Peter Anvin <hpa@zytor.com>
-                       Last update 2007-05-16
+                       Last update 2007-05-23
 
 On the i386 platform, the Linux kernel uses a rather complicated boot
 convention.  This has evolved partially due to historical aspects, as
@@ -202,6 +202,8 @@ All general purpose boot loaders should write the fields marked
 nonstandard address should fill in the fields marked (reloc); other
 boot loaders can ignore those fields.
 
+The byte order of all fields is littleendian (this is x86, after all.)
+
 Field name:    setup_secs
 Type:          read
 Offset/size:   0x1f1/1
@@ -280,14 +282,16 @@ Type:             read
 Offset/size:   0x206/2
 Protocol:      2.00+
 
-  Contains the boot protocol version, e.g. 0x0204 for version 2.04.
+  Contains the boot protocol version, in (major << 8)+minor format,
+  e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
+  10.17.
 
 Field name:    readmode_swtch
 Type:          modify (optional)
 Offset/size:   0x208/4
 Protocol:      2.00+
 
-  Boot loader hook (see separate chapter.)
+  Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
 
 Field name:    start_sys
 Type:          read
@@ -304,10 +308,17 @@ Protocol: 2.00+
   If set to a nonzero value, contains a pointer to a NUL-terminated
   human-readable kernel version number string, less 0x200.  This can
   be used to display the kernel version to the user.  This value
-  should be less than (0x200*setup_sects).  For example, if this value
-  is set to 0x1c00, the kernel version number string can be found at
-  offset 0x1e00 in the kernel file.  This is a valid value if and only
-  if the "setup_sects" field contains the value 14 or higher.
+  should be less than (0x200*setup_sects).
+
+  For example, if this value is set to 0x1c00, the kernel version
+  number string can be found at offset 0x1e00 in the kernel file.
+  This is a valid value if and only if the "setup_sects" field
+  contains the value 15 or higher, as:
+
+       0x1c00  < 15*0x200 (= 0x1e00) but
+       0x1c00 >= 14*0x200 (= 0x1c00)
+
+       0x1c00 >> 9 = 14, so the minimum value for setup_secs is 15.
 
 Field name:    type_of_loader
 Type:          write (obligatory)
@@ -377,7 +388,7 @@ Protocol:   2.00+
 
   This field can be modified for two purposes:
 
-  1. as a boot loader hook (see separate chapter.)
+  1. as a boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
 
   2. if a bootloader which does not install a hook loads a
      relocatable kernel at a nonstandard address it will have to modify
@@ -715,7 +726,7 @@ switched off, especially if the loaded kernel has the floppy driver as
 a demand-loaded module!
 
 
-**** ADVANCED BOOT TIME HOOKS
+**** ADVANCED BOOT LOADER HOOKS
 
 If the boot loader runs in a particularly hostile environment (such as
 LOADLIN, which runs under DOS) it may be impossible to follow the
@@ -740,4 +751,5 @@ IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
        set them up to BOOT_DS (0x18) yourself.
 
        After completing your hook, you should jump to the address
-       that was in this field before your boot loader overwrote it.
+       that was in this field before your boot loader overwrote it
+       (relocated, if appropriate.)
index 3153167b41c3c39b999822df7f283aa1dd686d9e..d485256ee1cead1c71b20610c0db3e458cbd10db 100644 (file)
@@ -197,7 +197,7 @@ skip:
        return rc;
 }
 
-main()
+int main()
 {
        int rc;
 
index 15f1b35deb3410932fcf5d9ef7fad28f69080408..d3dc505104da67897db9201875e4fc7c9493b3cc 100644 (file)
@@ -27,16 +27,20 @@ When using initrd, the system typically boots as follows:
   1) the boot loader loads the kernel and the initial RAM disk
   2) the kernel converts initrd into a "normal" RAM disk and
      frees the memory used by initrd
-  3) initrd is mounted read-write as root
-  4) /linuxrc is executed (this can be any valid executable, including
+  3) if the root device is not /dev/ram0, the old (deprecated)
+     change_root procedure is followed. see the "Obsolete root change
+     mechanism" section below.
+  4) root device is mounted. if it is /dev/ram0, the initrd image is
+     then mounted as root
+  5) /sbin/init is executed (this can be any valid executable, including
      shell scripts; it is run with uid 0 and can do basically everything
-     init can do)
-  5) linuxrc mounts the "real" root file system
-  6) linuxrc places the root file system at the root directory using the
+     init can do).
+  6) init mounts the "real" root file system
+  7) init places the root file system at the root directory using the
      pivot_root system call
-  7) the usual boot sequence (e.g. invocation of /sbin/init) is performed
-     on the root file system
-  8) the initrd file system is removed
+  8) init execs the /sbin/init on the new root filesystem, performing
+     the usual boot sequence
+  9) the initrd file system is removed
 
 Note that changing the root directory does not involve unmounting it.
 It is therefore possible to leave processes running on initrd during that
@@ -70,7 +74,7 @@ initrd adds the following new options:
   root=/dev/ram0
 
     initrd is mounted as root, and the normal boot procedure is followed,
-    with the RAM disk still mounted as root.
+    with the RAM disk mounted as root.
 
 Compressed cpio images
 ----------------------
@@ -137,11 +141,11 @@ We'll describe the loopback device method:
     # mkdir /mnt/dev
     # mknod /mnt/dev/console c 5 1
  5) copy all the files that are needed to properly use the initrd
-    environment. Don't forget the most important file, /linuxrc
-    Note that /linuxrc's permissions must include "x" (execute).
+    environment. Don't forget the most important file, /sbin/init
+    Note that /sbin/init's permissions must include "x" (execute).
  6) correct operation the initrd environment can frequently be tested
     even without rebooting with the command
-    # chroot /mnt /linuxrc
+    # chroot /mnt /sbin/init
     This is of course limited to initrds that do not interfere with the
     general system state (e.g. by reconfiguring network interfaces,
     overwriting mounted devices, trying to start already running demons,
@@ -154,7 +158,7 @@ We'll describe the loopback device method:
     # gzip -9 initrd
 
 For experimenting with initrd, you may want to take a rescue floppy and
-only add a symbolic link from /linuxrc to /bin/sh. Alternatively, you
+only add a symbolic link from /sbin/init to /bin/sh. Alternatively, you
 can try the experimental newlib environment [2] to create a small
 initrd.
 
@@ -163,15 +167,14 @@ boot loaders support initrd. Since the boot process is still compatible
 with an older mechanism, the following boot command line parameters
 have to be given:
 
-  root=/dev/ram0 init=/linuxrc rw
+  root=/dev/ram0 rw
 
 (rw is only necessary if writing to the initrd file system.)
 
 With LOADLIN, you simply execute
 
      LOADLIN <kernel> initrd=<disk_image>
-e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0
-       init=/linuxrc rw
+e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 rw
 
 With LILO, you add the option INITRD=<path> to either the global section
 or to the section of the respective kernel in /etc/lilo.conf, and pass
@@ -179,7 +182,7 @@ the options using APPEND, e.g.
 
   image = /bzImage
     initrd = /boot/initrd.gz
-    append = "root=/dev/ram0 init=/linuxrc rw"
+    append = "root=/dev/ram0 rw"
 
 and run /sbin/lilo
 
@@ -191,7 +194,7 @@ Now you can boot and enjoy using initrd.
 Changing the root device
 ------------------------
 
-When finished with its duties, linuxrc typically changes the root device
+When finished with its duties, init typically changes the root device
 and proceeds with starting the Linux system on the "real" root device.
 
 The procedure involves the following steps:
@@ -217,7 +220,7 @@ must exist before calling pivot_root. Example:
 # mkdir initrd
 # pivot_root . initrd
 
-Now, the linuxrc process may still access the old root via its
+Now, the init process may still access the old root via its
 executable, shared libraries, standard input/output/error, and its
 current root directory. All these references are dropped by the
 following command:
@@ -249,10 +252,6 @@ disk can be freed:
 It is also possible to use initrd with an NFS-mounted root, see the
 pivot_root(8) man page for details.
 
-Note: if linuxrc or any program exec'ed from it terminates for some
-reason, the old change_root mechanism is invoked (see section "Obsolete
-root change mechanism").
-
 
 Usage scenarios
 ---------------
@@ -264,15 +263,15 @@ as follows:
   1) system boots from floppy or other media with a minimal kernel
      (e.g. support for RAM disks, initrd, a.out, and the Ext2 FS) and
      loads initrd
-  2) /linuxrc determines what is needed to (1) mount the "real" root FS
+  2) /sbin/init determines what is needed to (1) mount the "real" root FS
      (i.e. device type, device drivers, file system) and (2) the
      distribution media (e.g. CD-ROM, network, tape, ...). This can be
      done by asking the user, by auto-probing, or by using a hybrid
      approach.
-  3) /linuxrc loads the necessary kernel modules
-  4) /linuxrc creates and populates the root file system (this doesn't
+  3) /sbin/init loads the necessary kernel modules
+  4) /sbin/init creates and populates the root file system (this doesn't
      have to be a very usable system yet)
-  5) /linuxrc invokes pivot_root to change the root file system and
+  5) /sbin/init invokes pivot_root to change the root file system and
      execs - via chroot - a program that continues the installation
   6) the boot loader is installed
   7) the boot loader is configured to load an initrd with the set of
@@ -291,7 +290,7 @@ different hardware configurations in a single administrative domain. In
 such cases, it is desirable to generate only a small set of kernels
 (ideally only one) and to keep the system-specific part of configuration
 information as small as possible. In this case, a common initrd could be
-generated with all the necessary modules. Then, only /linuxrc or a file
+generated with all the necessary modules. Then, only /sbin/init or a file
 read by it would have to be different.
 
 A third scenario are more convenient recovery disks, because information
@@ -337,6 +336,25 @@ This old, deprecated mechanism is commonly called "change_root", while
 the new, supported mechanism is called "pivot_root".
 
 
+Mixed change_root and pivot_root mechanism
+------------------------------------------
+
+In case you did not want to use root=/dev/ram0 to trig the pivot_root mechanism,
+you may create both /linuxrc and /sbin/init in your initrd image.
+
+/linuxrc would contain only the following:
+
+#! /bin/sh
+mount -n -t proc proc /proc
+echo 0x0100 >/proc/sys/kernel/real-root-dev
+umount -n /proc
+
+Once linuxrc exited, the kernel would mount again your initrd as root,
+this time executing /sbin/init. Again, it would be duty of this init
+to build the right environment (maybe using the root= device passed on
+the cmdline) before the final execution of the real /sbin/init.
+
+
 Resources
 ---------
 
index 09220a1e22d964b3ad19a235952a77c2bd9d1cef..5d0283cd3a81997fde0eaf901417ac0de33bf16b 100644 (file)
@@ -170,7 +170,10 @@ and is between 256 and 4096 characters. It is defined in the file
        acpi_os_name=   [HW,ACPI] Tell ACPI BIOS the name of the OS
                        Format: To spoof as Windows 98: ="Microsoft Windows"
 
-       acpi_osi=       [HW,ACPI] empty param disables _OSI
+       acpi_osi=       [HW,ACPI] Modify list of supported OS interface strings
+                       acpi_osi="string1"      # add string1 -- only one string
+                       acpi_osi="!string2"     # remove built-in string2
+                       acpi_osi=               # disable all strings
 
        acpi_serialize  [HW,ACPI] force serialization of AML methods
 
@@ -396,6 +399,26 @@ and is between 256 and 4096 characters. It is defined in the file
                        clocksource is not available, it defaults to PIT.
                        Format: { pit | tsc | cyclone | pmtmr }
 
+       clocksource=    [GENERIC_TIME] Override the default clocksource
+                       Format: <string>
+                       Override the default clocksource and use the clocksource
+                       with the name specified.
+                       Some clocksource names to choose from, depending on
+                       the platform:
+                       [all] jiffies (this is the base, fallback clocksource)
+                       [ACPI] acpi_pm
+                       [ARM] imx_timer1,OSTS,netx_timer,mpu_timer2,
+                               pxa_timer,timer3,32k_counter,timer0_1
+                       [AVR32] avr32
+                       [IA-32] pit,hpet,tsc,vmi-timer;
+                               scx200_hrt on Geode; cyclone on IBM x440
+                       [MIPS] MIPS
+                       [PARISC] cr16
+                       [S390] tod
+                       [SH] SuperH
+                       [SPARC64] tick
+                       [X86-64] hpet,tsc
+
        code_bytes      [IA32] How many bytes of object code to print in an
                        oops report.
                        Range: 0 - 8192
@@ -1112,9 +1135,9 @@ and is between 256 and 4096 characters. It is defined in the file
                        when set.
                        Format: <int>
 
-       noaliencache    [MM, NUMA] Disables the allcoation of alien caches in
-                       the slab allocator.  Saves per-node memory, but will
-                       impact performance on real NUMA hardware.
+       noaliencache    [MM, NUMA, SLAB] Disables the allocation of alien
+                       caches in the slab allocator.  Saves per-node memory,
+                       but will impact performance.
 
        noalign         [KNL,ARM]
 
@@ -1593,6 +1616,37 @@ and is between 256 and 4096 characters. It is defined in the file
 
        slram=          [HW,MTD]
 
+       slub_debug      [MM, SLUB]
+                       Enabling slub_debug allows one to determine the culprit
+                       if slab objects become corrupted. Enabling slub_debug
+                       creates guard zones around objects and poisons objects
+                       when not in use. Also tracks the last alloc / free.
+                       For more information see Documentation/vm/slub.txt.
+
+       slub_max_order= [MM, SLUB]
+                       Determines the maximum allowed order for slabs. Setting
+                       this too high may cause fragmentation.
+                       For more information see Documentation/vm/slub.txt.
+
+       slub_min_objects=       [MM, SLUB]
+                       The minimum objects per slab. SLUB will increase the
+                       slab order up to slub_max_order to generate a
+                       sufficiently big slab to satisfy the number of objects.
+                       The higher the number of objects the smaller the overhead
+                       of tracking slabs.
+                       For more information see Documentation/vm/slub.txt.
+
+       slub_min_order= [MM, SLUB]
+                       Determines the mininum page order for slabs. Must be
+                       lower than slub_max_order
+                       For more information see Documentation/vm/slub.txt.
+
+       slub_nomerge    [MM, SLUB]
+                       Disable merging of slabs of similar size. May be
+                       necessary if there is some reason to distinguish
+                       allocs to different slabs.
+                       For more information see Documentation/vm/slub.txt.
+
        smart2=         [HW]
                        Format: <io1>[,<io2>[,...,<io8>]]
 
@@ -1807,10 +1861,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        time            Show timing data prefixed to each printk message line
 
-       clocksource=    [GENERIC_TIME] Override the default clocksource
-                       Override the default clocksource and use the clocksource
-                       with the name specified.
-
        tipar.timeout=  [HW,PPT]
                        Set communications timeout in tenths of a second
                        (default 15).
index 58408dd023c77e0e0712d02811fc0238c5ee1742..650657c5473340dcd8f5ffe5f097c6776a754441 100644 (file)
@@ -24,7 +24,7 @@ Contents:
  (*) Explicit kernel barriers.
 
      - Compiler barrier.
-     - The CPU memory barriers.
+     - CPU memory barriers.
      - MMIO write barrier.
 
  (*) Implicit kernel memory barriers.
@@ -265,7 +265,7 @@ Memory barriers are such interventions.  They impose a perceived partial
 ordering over the memory operations on either side of the barrier.
 
 Such enforcement is important because the CPUs and other devices in a system
-can use a variety of tricks to improve performance - including reordering,
+can use a variety of tricks to improve performance, including reordering,
 deferral and combination of memory operations; speculative loads; speculative
 branch prediction and various types of caching.  Memory barriers are used to
 override or suppress these tricks, allowing the code to sanely control the
@@ -457,7 +457,7 @@ sequence, Q must be either &A or &B, and that:
        (Q == &A) implies (D == 1)
        (Q == &B) implies (D == 4)
 
-But! CPU 2's perception of P may be updated _before_ its perception of B, thus
+But!  CPU 2's perception of P may be updated _before_ its perception of B, thus
 leading to the following situation:
 
        (Q == &B) and (D == 2) ????
@@ -573,7 +573,7 @@ Basically, the read barrier always has to be there, even though it can be of
 the "weaker" type.
 
 [!] Note that the stores before the write barrier would normally be expected to
-match the loads after the read barrier or data dependency barrier, and vice
+match the loads after the read barrier or the data dependency barrier, and vice
 versa:
 
        CPU 1                           CPU 2
@@ -588,7 +588,7 @@ versa:
 EXAMPLES OF MEMORY BARRIER SEQUENCES
 ------------------------------------
 
-Firstly, write barriers act as partial orderings on store operations.
+Firstly, write barriers act as partial orderings on store operations.
 Consider the following sequence of events:
 
        CPU 1
@@ -608,15 +608,15 @@ STORE B, STORE C } all occurring before the unordered set of { STORE D, STORE E
        +-------+       :      :
        |       |       +------+
        |       |------>| C=3  |     }     /\
-       |       |  :    +------+     }-----  \  -----> Events perceptible
-       |       |  :    | A=1  |     }        \/       to rest of system
+       |       |  :    +------+     }-----  \  -----> Events perceptible to
+       |       |  :    | A=1  |     }        \/       the rest of the system
        |       |  :    +------+     }
        | CPU 1 |  :    | B=2  |     }
        |       |       +------+     }
        |       |   wwwwwwwwwwwwwwww }   <--- At this point the write barrier
        |       |       +------+     }        requires all stores prior to the
        |       |  :    | E=5  |     }        barrier to be committed before
-       |       |  :    +------+     }        further stores may be take place.
+       |       |  :    +------+     }        further stores may take place
        |       |------>| D=4  |     }
        |       |       +------+
        +-------+       :      :
@@ -626,7 +626,7 @@ STORE B, STORE C } all occurring before the unordered set of { STORE D, STORE E
                           V
 
 
-Secondly, data dependency barriers act as partial orderings on data-dependent
+Secondly, data dependency barriers act as partial orderings on data-dependent
 loads.  Consider the following sequence of events:
 
        CPU 1                   CPU 2
@@ -975,7 +975,7 @@ compiler from moving the memory accesses either side of it to the other side:
 
        barrier();
 
-This a general barrier - lesser varieties of compiler barrier do not exist.
+This is a general barrier - lesser varieties of compiler barrier do not exist.
 
 The compiler barrier has no direct effect on the CPU, which may then reorder
 things however it wishes.
@@ -997,7 +997,7 @@ The Linux kernel has eight basic CPU memory barriers:
 All CPU memory barriers unconditionally imply compiler barriers.
 
 SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
-systems because it is assumed that a CPU will be appear to be self-consistent,
+systems because it is assumed that a CPU will appear to be self-consistent,
 and will order overlapping accesses correctly with respect to itself.
 
 [!] Note that SMP memory barriers _must_ be used to control the ordering of
@@ -1146,9 +1146,9 @@ for each construct.  These operations all imply certain barriers:
 Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is
 equivalent to a full barrier, but a LOCK followed by an UNLOCK is not.
 
-[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way
-    barriers is that the effects instructions outside of a critical section may
-    seep into the inside of the critical section.
+[!] Note: one of the consequences of LOCKs and UNLOCKs being only one-way
+    barriers is that the effects of instructions outside of a critical section
+    may seep into the inside of the critical section.
 
 A LOCK followed by an UNLOCK may not be assumed to be full memory barrier
 because it is possible for an access preceding the LOCK to happen after the
@@ -1239,7 +1239,7 @@ three CPUs; then should the following sequence of events occur:
        UNLOCK M                        UNLOCK Q
        *D = d;                         *H = h;
 
-Then there is no guarantee as to what order CPU #3 will see the accesses to *A
+Then there is no guarantee as to what order CPU 3 will see the accesses to *A
 through *H occur in, other than the constraints imposed by the separate locks
 on the separate CPUs. It might, for example, see:
 
@@ -1269,12 +1269,12 @@ However, if the following occurs:
                                        UNLOCK M        [2]
                                        *H = h;
 
-CPU #3 might see:
+CPU 3 might see:
 
        *E, LOCK M [1], *C, *B, *A, UNLOCK M [1],
                LOCK M [2], *H, *F, *G, UNLOCK M [2], *D
 
-But assuming CPU #1 gets the lock first, it won't see any of:
+But assuming CPU 1 gets the lock first, CPU 3 won't see any of:
 
        *B, *C, *D, *F, *G or *H preceding LOCK M [1]
        *A, *B or *C following UNLOCK M [1]
@@ -1327,12 +1327,12 @@ spinlock, for example:
                                        mmiowb();
                                        spin_unlock(Q);
 
-this will ensure that the two stores issued on CPU #1 appear at the PCI bridge
-before either of the stores issued on CPU #2.
+this will ensure that the two stores issued on CPU 1 appear at the PCI bridge
+before either of the stores issued on CPU 2.
 
 
-Furthermore, following a store by a load to the same device obviates the need
-for an mmiowb(), because the load forces the store to complete before the load
+Furthermore, following a store by a load from the same device obviates the need
+for the mmiowb(), because the load forces the store to complete before the load
 is performed:
 
        CPU 1                           CPU 2
@@ -1363,7 +1363,7 @@ circumstances in which reordering definitely _could_ be a problem:
 
  (*) Atomic operations.
 
- (*) Accessing devices (I/O).
+ (*) Accessing devices.
 
  (*) Interrupts.
 
@@ -1399,7 +1399,7 @@ To wake up a particular waiter, the up_read() or up_write() functions have to:
  (1) read the next pointer from this waiter's record to know as to where the
      next waiter record is;
 
- (4) read the pointer to the waiter's task structure;
+ (2) read the pointer to the waiter's task structure;
 
  (3) clear the task pointer to tell the waiter it has been given the semaphore;
 
@@ -1407,7 +1407,7 @@ To wake up a particular waiter, the up_read() or up_write() functions have to:
 
  (5) release the reference held on the waiter's task struct.
 
-In otherwords, it has to perform this sequence of events:
+In other words, it has to perform this sequence of events:
 
        LOAD waiter->list.next;
        LOAD waiter->task;
@@ -1502,7 +1502,7 @@ operations and adjusting reference counters towards object destruction, and as
 such the implicit memory barrier effects are necessary.
 
 
-The following operation are potential problems as they do _not_ imply memory
+The following operations are potential problems as they do _not_ imply memory
 barriers, but might be used for implementing such things as UNLOCK-class
 operations:
 
@@ -1517,7 +1517,7 @@ With these the appropriate explicit memory barrier should be used if necessary
 
 The following also do _not_ imply memory barriers, and so may require explicit
 memory barriers under some circumstances (smp_mb__before_atomic_dec() for
-instance)):
+instance):
 
        atomic_add();
        atomic_sub();
@@ -1641,8 +1641,8 @@ functions:
      indeed have special I/O space access cycles and instructions, but many
      CPUs don't have such a concept.
 
-     The PCI bus, amongst others, defines an I/O space concept - which on such
-     CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O
+     The PCI bus, amongst others, defines an I/O space concept which - on such
+     CPUs as i386 and x86_64 - readily maps to the CPU's concept of I/O
      space.  However, it may also be mapped as a virtual I/O space in the CPU's
      memory map, particularly on those CPUs that don't support alternate I/O
      spaces.
@@ -1664,7 +1664,7 @@ functions:
      i386 architecture machines, for example, this is controlled by way of the
      MTRR registers.
 
-     Ordinarily, these will be guaranteed to be fully ordered and uncombined,,
+     Ordinarily, these will be guaranteed to be fully ordered and uncombined,
      provided they're not accessing a prefetchable device.
 
      However, intermediary hardware (such as a PCI bridge) may indulge in
@@ -1689,7 +1689,7 @@ functions:
 
  (*) ioreadX(), iowriteX()
 
-     These will perform as appropriate for the type of access they're actually
+     These will perform appropriately for the type of access they're actually
      doing, be it inX()/outX() or readX()/writeX().
 
 
@@ -1705,7 +1705,7 @@ of arch-specific code.
 
 This means that it must be considered that the CPU will execute its instruction
 stream in any order it feels like - or even in parallel - provided that if an
-instruction in the stream depends on the an earlier instruction, then that
+instruction in the stream depends on an earlier instruction, then that
 earlier instruction must be sufficiently complete[*] before the later
 instruction may proceed; in other words: provided that the appearance of
 causality is maintained.
@@ -1795,8 +1795,8 @@ eventually become visible on all CPUs, there's no guarantee that they will
 become apparent in the same order on those other CPUs.
 
 
-Consider dealing with a system that has pair of CPUs (1 & 2), each of which has
-a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
+Consider dealing with a system that has a pair of CPUs (1 & 2), each of which
+has a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
 
                    :
                    :                          +--------+
@@ -1835,7 +1835,7 @@ Imagine the system has the following properties:
 
  (*) the coherency queue is not flushed by normal loads to lines already
      present in the cache, even though the contents of the queue may
-     potentially effect those loads.
+     potentially affect those loads.
 
 Imagine, then, that two writes are made on the first CPU, with a write barrier
 between them to guarantee that they will appear to reach that CPU's caches in
@@ -1845,7 +1845,7 @@ the requisite order:
        =============== =============== =======================================
                                        u == 0, v == 1 and p == &u, q == &u
        v = 2;
-       smp_wmb();                      Make sure change to v visible before
+       smp_wmb();                      Make sure change to v is visible before
                                         change to p
        <A:modify v=2>                  v is now in cache A exclusively
        p = &v;
@@ -1853,7 +1853,7 @@ the requisite order:
 
 The write memory barrier forces the other CPUs in the system to perceive that
 the local CPU's caches have apparently been updated in the correct order.  But
-now imagine that the second CPU that wants to read those values:
+now imagine that the second CPU wants to read those values:
 
        CPU 1           CPU 2           COMMENT
        =============== =============== =======================================
@@ -1861,7 +1861,7 @@ now imagine that the second CPU that wants to read those values:
                        q = p;
                        x = *q;
 
-The above pair of reads may then fail to happen in expected order, as the
+The above pair of reads may then fail to happen in the expected order, as the
 cacheline holding p may get updated in one of the second CPU's caches whilst
 the update to the cacheline holding v is delayed in the other of the second
 CPU's caches by some other cache event:
@@ -1916,7 +1916,7 @@ access depends on a read, not all do, so it may not be relied on.
 
 Other CPUs may also have split caches, but must coordinate between the various
 cachelets for normal memory accesses.  The semantics of the Alpha removes the
-need for coordination in absence of memory barriers.
+need for coordination in the absence of memory barriers.
 
 
 CACHE COHERENCY VS DMA
@@ -1931,10 +1931,10 @@ invalidate them as well).
 
 In addition, the data DMA'd to RAM by a device may be overwritten by dirty
 cache lines being written back to RAM from a CPU's cache after the device has
-installed its own data, or cache lines simply present in a CPUs cache may
-simply obscure the fact that RAM has been updated, until at such time as the
-cacheline is discarded from the CPU's cache and reloaded.  To deal with this,
-the appropriate part of the kernel must invalidate the overlapping bits of the
+installed its own data, or cache lines present in the CPU's cache may simply
+obscure the fact that RAM has been updated, until at such time as the cacheline
+is discarded from the CPU's cache and reloaded.  To deal with this, the
+appropriate part of the kernel must invalidate the overlapping bits of the
 cache on each CPU.
 
 See Documentation/cachetlb.txt for more information on cache management.
@@ -1944,7 +1944,7 @@ CACHE COHERENCY VS MMIO
 -----------------------
 
 Memory mapped I/O usually takes place through memory locations that are part of
-a window in the CPU's memory space that have different properties assigned than
+a window in the CPU's memory space that has different properties assigned than
 the usual RAM directed window.
 
 Amongst these properties is usually the fact that such accesses bypass the
@@ -1960,7 +1960,7 @@ THE THINGS CPUS GET UP TO
 =========================
 
 A programmer might take it for granted that the CPU will perform memory
-operations in exactly the order specified, so that if a CPU is, for example,
+operations in exactly the order specified, so that if the CPU is, for example,
 given the following piece of code to execute:
 
        a = *A;
@@ -1969,7 +1969,7 @@ given the following piece of code to execute:
        d = *D;
        *E = e;
 
-They would then expect that the CPU will complete the memory operation for each
+they would then expect that the CPU will complete the memory operation for each
 instruction before moving on to the next one, leading to a definite sequence of
 operations as seen by external observers in the system:
 
@@ -1986,8 +1986,8 @@ assumption doesn't hold because:
  (*) loads may be done speculatively, and the result discarded should it prove
      to have been unnecessary;
 
- (*) loads may be done speculatively, leading to the result having being
-     fetched at the wrong time in the expected sequence of events;
+ (*) loads may be done speculatively, leading to the result having been fetched
+     at the wrong time in the expected sequence of events;
 
  (*) the order of the memory accesses may be rearranged to promote better use
      of the CPU buses and caches;
@@ -2069,12 +2069,12 @@ AND THEN THERE'S THE ALPHA
 
 The DEC Alpha CPU is one of the most relaxed CPUs there is.  Not only that,
 some versions of the Alpha CPU have a split data cache, permitting them to have
-two semantically related cache lines updating at separate times.  This is where
+two semantically-related cache lines updated at separate times.  This is where
 the data dependency barrier really becomes necessary as this synchronises both
 caches with the memory coherence system, thus making it seem like pointer
 changes vs new data occur in the right order.
 
-The Alpha defines the Linux's kernel's memory barrier model.
+The Alpha defines the Linux kernel's memory barrier model.
 
 See the subsection on "Cache Coherency" above.
 
index e06b6e3c1db577d5fe513cc2ea045e3d57507564..153d84d281e6aa6fa8c1bb6e001d39f8660c0444 100644 (file)
@@ -32,6 +32,8 @@ cops.txt
        - info on the COPS LocalTalk Linux driver
 cs89x0.txt
        - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver
+cxacru.txt
+       - Conexant AccessRunner USB ADSL Modem
 de4x5.txt
        - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
 decnet.txt
diff --git a/Documentation/networking/cxacru.txt b/Documentation/networking/cxacru.txt
new file mode 100644 (file)
index 0000000..b074681
--- /dev/null
@@ -0,0 +1,84 @@
+Firmware is required for this device: http://accessrunner.sourceforge.net/
+
+While it is capable of managing/maintaining the ADSL connection without the
+module loaded, the device will sometimes stop responding after unloading the
+driver and it is necessary to unplug/remove power to the device to fix this.
+
+Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/
+these are directories named cxacruN where N is the device number. A symlink
+named device points to the USB interface device's directory which contains
+several sysfs attribute files for retrieving device statistics:
+
+* adsl_controller_version
+
+* adsl_headend
+* adsl_headend_environment
+       Information about the remote headend.
+
+* downstream_attenuation (dB)
+* downstream_bits_per_frame
+* downstream_rate (kbps)
+* downstream_snr_margin (dB)
+       Downstream stats.
+
+* upstream_attenuation (dB)
+* upstream_bits_per_frame
+* upstream_rate (kbps)
+* upstream_snr_margin (dB)
+* transmitter_power (dBm/Hz)
+       Upstream stats.
+
+* downstream_crc_errors
+* downstream_fec_errors
+* downstream_hec_errors
+* upstream_crc_errors
+* upstream_fec_errors
+* upstream_hec_errors
+       Error counts.
+
+* line_startable
+       Indicates that ADSL support on the device
+       is/can be enabled, see adsl_start.
+
+* line_status
+       "initialising"
+       "down"
+       "attempting to activate"
+       "training"
+       "channel analysis"
+       "exchange"
+       "waiting"
+       "up"
+
+       Changes between "down" and "attempting to activate"
+       if there is no signal.
+
+* link_status
+       "not connected"
+       "connected"
+       "lost"
+
+* mac_address
+
+* modulation
+       "ANSI T1.413"
+       "ITU-T G.992.1 (G.DMT)"
+       "ITU-T G.992.2 (G.LITE)"
+
+* startup_attempts
+       Count of total attempts to initialise ADSL.
+
+To enable/disable ADSL, the following can be written to the adsl_state file:
+       "start"
+       "stop
+       "restart" (stops, waits 1.5s, then starts)
+       "poll" (used to resume status polling if it was disabled due to failure)
+
+Changes in adsl/line state are reported via kernel log messages:
+       [4942145.150704] ATM dev 0: ADSL state: running
+       [4942243.663766] ATM dev 0: ADSL line: down
+       [4942249.665075] ATM dev 0: ADSL line: attempting to activate
+       [4942253.654954] ATM dev 0: ADSL line: training
+       [4942255.666387] ATM dev 0: ADSL line: channel analysis
+       [4942259.656262] ATM dev 0: ADSL line: exchange
+       [2635357.696901] ATM dev 0: ADSL line: up (8128 kb/s down | 832 kb/s up)
diff --git a/Documentation/networking/xfrm_sysctl.txt b/Documentation/networking/xfrm_sysctl.txt
new file mode 100644 (file)
index 0000000..5bbd167
--- /dev/null
@@ -0,0 +1,4 @@
+/proc/sys/net/core/xfrm_* Variables:
+
+xfrm_acq_expires - INTEGER
+       default 30 - hard timeout in seconds for acquire requests
index b49ce169a63aa27d75271a45948b0c1ed8d15ecd..d42d98107d494d906ded560a3e61bfad829e8911 100644 (file)
@@ -1,7 +1,6 @@
            Booting the Linux/ppc kernel without Open Firmware
            --------------------------------------------------
 
-
 (c) 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>,
     IBM Corp.
 (c) 2005 Becky Bruce <becky.bruce at freescale.com>,
@@ -9,6 +8,62 @@
 (c) 2006 MontaVista Software, Inc.
     Flash chip node definition
 
+Table of Contents
+=================
+
+  I - Introduction
+    1) Entry point for arch/powerpc
+    2) Board support
+
+  II - The DT block format
+    1) Header
+    2) Device tree generalities
+    3) Device tree "structure" block
+    4) Device tree "strings" block
+
+  III - Required content of the device tree
+    1) Note about cells and address representation
+    2) Note about "compatible" properties
+    3) Note about "name" properties
+    4) Note about node and property names and character set
+    5) Required nodes and properties
+      a) The root node
+      b) The /cpus node
+      c) The /cpus/* nodes
+      d) the /memory node(s)
+      e) The /chosen node
+      f) the /soc<SOCname> node
+
+  IV - "dtc", the device tree compiler
+
+  V - Recommendations for a bootloader
+
+  VI - System-on-a-chip devices and nodes
+    1) Defining child nodes of an SOC
+    2) Representing devices without a current OF specification
+      a) MDIO IO device
+      c) PHY nodes
+      b) Gianfar-compatible ethernet nodes
+      d) Interrupt controllers
+      e) I2C
+      f) Freescale SOC USB controllers
+      g) Freescale SOC SEC Security Engines
+      h) Board Control and Status (BCSR)
+      i) Freescale QUICC Engine module (QE)
+      g) Flash chip nodes
+
+  VII - Specifying interrupt information for devices
+    1) interrupts property
+    2) interrupt-parent property
+    3) OpenPIC Interrupt Controllers
+    4) ISA Interrupt Controllers
+
+  Appendix A - Sample SOC node for MPC8540
+
+
+Revision Information
+====================
+
    May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet.
 
    May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or
@@ -1687,7 +1742,7 @@ platforms are moved over to use the flattened-device-tree model.
                };
        };
 
-    g) Flash chip nodes
+    j) Flash chip nodes
 
     Flash chips (Memory Technology Devices) are often used for solid state
     file systems on embedded devices.
index 57b878cc393c20ebd04c7713f83e3c249ae83db3..355ff0a2bb7c5a1cdc9862c4f827e9e49497c165 100644 (file)
@@ -917,6 +917,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          ref           Reference board, base config
          m2-2          Some Gateway MX series laptops
          m6            Some Gateway NX series laptops
+         pa6           Gateway NX860 series
 
        STAC9227/9228/9229/927x
          ref           Reference board
index 795fbb48ffa7f080c88ccfd39e5afc7827183d3d..76ea6c837be568c104e393ef0b2ff465febb7e98 100644 (file)
@@ -1,26 +1,30 @@
 Overview of Linux kernel SPI support
 ====================================
 
-02-Dec-2005
+21-May-2007
 
 What is SPI?
 ------------
 The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial
 link used to connect microcontrollers to sensors, memory, and peripherals.
+It's a simple "de facto" standard, not complicated enough to acquire a
+standardization body.  SPI uses a master/slave configuration.
 
 The three signal wires hold a clock (SCK, often on the order of 10 MHz),
 and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In,
 Slave Out" (MISO) signals.  (Other names are also used.)  There are four
 clocking modes through which data is exchanged; mode-0 and mode-3 are most
 commonly used.  Each clock cycle shifts data out and data in; the clock
-doesn't cycle except when there is data to shift.
+doesn't cycle except when there is a data bit to shift.  Not all data bits
+are used though; not every protocol uses those full duplex capabilities.
 
-SPI masters may use a "chip select" line to activate a given SPI slave
+SPI masters use a fourth "chip select" line to activate a given SPI slave
 device, so those three signal wires may be connected to several chips
-in parallel.  All SPI slaves support chipselects.  Some devices have
+in parallel.  All SPI slaves support chipselects; they are usually active
+low signals, labeled nCSx for slave 'x' (e.g. nCS0).  Some devices have
 other signals, often including an interrupt to the master.
 
-Unlike serial busses like USB or SMBUS, even low level protocols for
+Unlike serial busses like USB or SMBus, even low level protocols for
 SPI slave functions are usually not interoperable between vendors
 (except for commodities like SPI memory chips).
 
@@ -33,6 +37,11 @@ SPI slave functions are usually not interoperable between vendors
   - Some devices may use eight bit words.  Others may different word
     lengths, such as streams of 12-bit or 20-bit digital samples.
 
+  - Words are usually sent with their most significant bit (MSB) first,
+    but sometimes the least significant bit (LSB) goes first instead.
+
+  - Sometimes SPI is used to daisy-chain devices, like shift registers.
+
 In the same way, SPI slaves will only rarely support any kind of automatic
 discovery/enumeration protocol.  The tree of slave devices accessible from
 a given SPI master will normally be set up manually, with configuration
@@ -44,6 +53,14 @@ half-duplex SPI, for request/response protocols), SSP ("Synchronous
 Serial Protocol"), PSP ("Programmable Serial Protocol"), and other
 related protocols.
 
+Some chips eliminate a signal line by combining MOSI and MISO, and
+limiting themselves to half-duplex at the hardware level.  In fact
+some SPI chips have this signal mode as a strapping option.  These
+can be accessed using the same programming interface as SPI, but of
+course they won't handle full duplex transfers.  You may find such
+chips described as using "three wire" signaling: SCK, data, nCSx.
+(That data line is sometimes called MOMI or SISO.)
+
 Microcontrollers often support both master and slave sides of the SPI
 protocol.  This document (and Linux) currently only supports the master
 side of SPI interactions.
@@ -74,6 +91,32 @@ interfaces with SPI modes.  Given SPI support, they could use MMC or SD
 cards without needing a special purpose MMC/SD/SDIO controller.
 
 
+I'm confused.  What are these four SPI "clock modes"?
+-----------------------------------------------------
+It's easy to be confused here, and the vendor documentation you'll
+find isn't necessarily helpful.  The four modes combine two mode bits:
+
+ - CPOL indicates the initial clock polarity.  CPOL=0 means the
+   clock starts low, so the first (leading) edge is rising, and
+   the second (trailing) edge is falling.  CPOL=1 means the clock
+   starts high, so the first (leading) edge is falling.
+
+ - CPHA indicates the clock phase used to sample data; CPHA=0 says
+   sample on the leading edge, CPHA=1 means the trailing edge.
+
+   Since the signal needs to stablize before it's sampled, CPHA=0
+   implies that its data is written half a clock before the first
+   clock edge.  The chipselect may have made it become available.
+
+Chip specs won't always say "uses SPI mode X" in as many words,
+but their timing diagrams will make the CPOL and CPHA modes clear.
+
+In the SPI mode number, CPOL is the high order bit and CPHA is the
+low order bit.  So when a chip's timing diagram shows the clock
+starting low (CPOL=0) and data stabilized for sampling during the
+trailing clock edge (CPHA=1), that's SPI mode 1.
+
+
 How do these driver programming interfaces work?
 ------------------------------------------------
 The <linux/spi/spi.h> header file includes kerneldoc, as does the
index 2d4803359a043e228292d9f8e82eeffc14ff454b..9e6b94face4bb2a11f0ea743246f0b85adbbd105 100644 (file)
@@ -138,7 +138,7 @@ Hot keys
 --------
 
 procfs: /proc/acpi/ibm/hotkey
-sysfs device attribute: hotkey/*
+sysfs device attribute: hotkey_*
 
 Without this driver, only the Fn-F4 key (sleep button) generates an
 ACPI event. With the driver loaded, the hotkey feature enabled and the
@@ -196,10 +196,7 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file:
 
 sysfs notes:
 
-       The hot keys attributes are in a hotkey/ subdirectory off the
-       thinkpad device.
-
-       bios_enabled:
+       hotkey_bios_enabled:
                Returns the status of the hot keys feature when
                thinkpad-acpi was loaded.  Upon module unload, the hot
                key feature status will be restored to this value.
@@ -207,19 +204,19 @@ sysfs notes:
                0: hot keys were disabled
                1: hot keys were enabled
 
-       bios_mask:
+       hotkey_bios_mask:
                Returns the hot keys mask when thinkpad-acpi was loaded.
                Upon module unload, the hot keys mask will be restored
                to this value.
 
-       enable:
+       hotkey_enable:
                Enables/disables the hot keys feature, and reports
                current status of the hot keys feature.
 
                0: disables the hot keys feature / feature disabled
                1: enables the hot keys feature / feature enabled
 
-       mask:
+       hotkey_mask:
                bit mask to enable ACPI event generation for each hot
                key (see above).  Returns the current status of the hot
                keys mask, and allows one to modify it.
@@ -229,7 +226,7 @@ Bluetooth
 ---------
 
 procfs: /proc/acpi/ibm/bluetooth
-sysfs device attribute: bluetooth/enable
+sysfs device attribute: bluetooth_enable
 
 This feature shows the presence and current state of a ThinkPad
 Bluetooth device in the internal ThinkPad CDC slot.
@@ -244,7 +241,7 @@ If Bluetooth is installed, the following commands can be used:
 Sysfs notes:
 
        If the Bluetooth CDC card is installed, it can be enabled /
-       disabled through the "bluetooth/enable" thinkpad-acpi device
+       disabled through the "bluetooth_enable" thinkpad-acpi device
        attribute, and its current status can also be queried.
 
        enable:
@@ -252,7 +249,7 @@ Sysfs notes:
                1: enables Bluetooth / Bluetooth is enabled.
 
        Note: this interface will be probably be superseeded by the
-       generic rfkill class.
+       generic rfkill class, so it is NOT to be considered stable yet.
 
 Video output control -- /proc/acpi/ibm/video
 --------------------------------------------
@@ -898,7 +895,7 @@ EXPERIMENTAL: WAN
 -----------------
 
 procfs: /proc/acpi/ibm/wan
-sysfs device attribute: wwan/enable
+sysfs device attribute: wwan_enable
 
 This feature is marked EXPERIMENTAL because the implementation
 directly accesses hardware registers and may not work as expected. USE
@@ -921,7 +918,7 @@ If the W-WAN card is installed, the following commands can be used:
 Sysfs notes:
 
        If the W-WAN card is installed, it can be enabled /
-       disabled through the "wwan/enable" thinkpad-acpi device
+       disabled through the "wwan_enable" thinkpad-acpi device
        attribute, and its current status can also be queried.
 
        enable:
@@ -929,7 +926,7 @@ Sysfs notes:
                1: enables WWAN card / WWAN card is enabled.
 
        Note: this interface will be probably be superseeded by the
-       generic rfkill class.
+       generic rfkill class, so it is NOT to be considered stable yet.
 
 Multiple Commands, Module Parameters
 ------------------------------------
index 727c8d81aeaf01da2ea02a5a9986aeff959cc003..1523320abd87e6fdfcf2d099869a54f2d3deea3c 100644 (file)
@@ -1,13 +1,9 @@
 Short users guide for SLUB
 --------------------------
 
-First of all slub should transparently replace SLAB. If you enable
-SLUB then everything should work the same (Note the word "should".
-There is likely not much value in that word at this point).
-
 The basic philosophy of SLUB is very different from SLAB. SLAB
 requires rebuilding the kernel to activate debug options for all
-SLABS. SLUB always includes full debugging but its off by default.
+slab caches. SLUB always includes full debugging but it is off by default.
 SLUB can enable debugging only for selected slabs in order to avoid
 an impact on overall system performance which may make a bug more
 difficult to find.
@@ -76,13 +72,28 @@ of objects.
 Careful with tracing: It may spew out lots of information and never stop if
 used on the wrong slab.
 
-SLAB Merging
+Slab merging
 ------------
 
-If no debugging is specified then SLUB may merge similar slabs together
+If no debug options are specified then SLUB may merge similar slabs together
 in order to reduce overhead and increase cache hotness of objects.
 slabinfo -a displays which slabs were merged together.
 
+Slab validation
+---------------
+
+SLUB can validate all object if the kernel was booted with slub_debug. In
+order to do so you must have the slabinfo tool. Then you can do
+
+slabinfo -v
+
+which will test all objects. Output will be generated to the syslog.
+
+This also works in a more limited way if boot was without slab debug.
+In that case slabinfo -v simply tests all reachable objects. Usually
+these are in the cpu slabs and the partial slabs. Full slabs are not
+tracked by SLUB in a non debug situation.
+
 Getting more performance
 ------------------------
 
@@ -91,9 +102,9 @@ list_lock once in a while to deal with partial slabs. That overhead is
 governed by the order of the allocation for each slab. The allocations
 can be influenced by kernel parameters:
 
-slub_min_objects=x             (default 8)
+slub_min_objects=x             (default 4)
 slub_min_order=x               (default 0)
-slub_max_order=x               (default 4)
+slub_max_order=x               (default 1)
 
 slub_min_objects allows to specify how many objects must at least fit
 into one slab in order for the allocation order to be acceptable.
@@ -109,5 +120,107 @@ longer be checked. This is useful to avoid SLUB trying to generate
 super large order pages to fit slub_min_objects of a slab cache with
 large object sizes into one high order page.
 
-
-Christoph Lameter, <clameter@sgi.com>, April 10, 2007
+SLUB Debug output
+-----------------
+
+Here is a sample of slub debug output:
+
+*** SLUB kmalloc-8: Redzone Active@0xc90f6d20 slab 0xc528c530 offset=3360 flags=0x400000c3 inuse=61 freelist=0xc90f6d58
+  Bytes b4 0xc90f6d10:  00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
+    Object 0xc90f6d20:  31 30 31 39 2e 30 30 35                         1019.005
+   Redzone 0xc90f6d28:  00 cc cc cc                                     .
+FreePointer 0xc90f6d2c -> 0xc90f6d58
+Last alloc: get_modalias+0x61/0xf5 jiffies_ago=53 cpu=1 pid=554
+Filler 0xc90f6d50:  5a 5a 5a 5a 5a 5a 5a 5a                         ZZZZZZZZ
+  [<c010523d>] dump_trace+0x63/0x1eb
+  [<c01053df>] show_trace_log_lvl+0x1a/0x2f
+  [<c010601d>] show_trace+0x12/0x14
+  [<c0106035>] dump_stack+0x16/0x18
+  [<c017e0fa>] object_err+0x143/0x14b
+  [<c017e2cc>] check_object+0x66/0x234
+  [<c017eb43>] __slab_free+0x239/0x384
+  [<c017f446>] kfree+0xa6/0xc6
+  [<c02e2335>] get_modalias+0xb9/0xf5
+  [<c02e23b7>] dmi_dev_uevent+0x27/0x3c
+  [<c027866a>] dev_uevent+0x1ad/0x1da
+  [<c0205024>] kobject_uevent_env+0x20a/0x45b
+  [<c020527f>] kobject_uevent+0xa/0xf
+  [<c02779f1>] store_uevent+0x4f/0x58
+  [<c027758e>] dev_attr_store+0x29/0x2f
+  [<c01bec4f>] sysfs_write_file+0x16e/0x19c
+  [<c0183ba7>] vfs_write+0xd1/0x15a
+  [<c01841d7>] sys_write+0x3d/0x72
+  [<c0104112>] sysenter_past_esp+0x5f/0x99
+  [<b7f7b410>] 0xb7f7b410
+  =======================
+@@@ SLUB kmalloc-8: Restoring redzone (0xcc) from 0xc90f6d28-0xc90f6d2b
+
+
+
+If SLUB encounters a corrupted object then it will perform the following
+actions:
+
+1. Isolation and report of the issue
+
+This will be a message in the system log starting with
+
+*** SLUB <slab cache affected>: <What went wrong>@<object address>
+offset=<offset of object into slab> flags=<slabflags>
+inuse=<objects in use in this slab> freelist=<first free object in slab>
+
+2. Report on how the problem was dealt with in order to ensure the continued
+operation of the system.
+
+These are messages in the system log beginning with
+
+@@@ SLUB <slab cache affected>: <corrective action taken>
+
+
+In the above sample SLUB found that the Redzone of an active object has
+been overwritten. Here a string of 8 characters was written into a slab that
+has the length of 8 characters. However, a 8 character string needs a
+terminating 0. That zero has overwritten the first byte of the Redzone field.
+After reporting the details of the issue encountered the @@@ SLUB message
+tell us that SLUB has restored the redzone to its proper value and then
+system operations continue.
+
+Various types of lines can follow the @@@ SLUB line:
+
+Bytes b4 <address> : <bytes>
+       Show a few bytes before the object where the problem was detected.
+       Can be useful if the corruption does not stop with the start of the
+       object.
+
+Object <address> : <bytes>
+       The bytes of the object. If the object is inactive then the bytes
+       typically contain poisoning values. Any non-poison value shows a
+       corruption by a write after free.
+
+Redzone <address> : <bytes>
+       The redzone following the object. The redzone is used to detect
+       writes after the object. All bytes should always have the same
+       value. If there is any deviation then it is due to a write after
+       the object boundary.
+
+Freepointer
+       The pointer to the next free object in the slab. May become
+       corrupted if overwriting continues after the red zone.
+
+Last alloc:
+Last free:
+       Shows the address from which the object was allocated/freed last.
+       We note the pid, the time and the CPU that did so. This is usually
+       the most useful information to figure out where things went wrong.
+       Here get_modalias() did an kmalloc(8) instead of a kmalloc(9).
+
+Filler <address> : <bytes>
+       Unused data to fill up the space in order to get the next object
+       properly aligned. In the debug case we make sure that there are
+       at least 4 bytes of filler. This allow for the detection of writes
+       before the object.
+
+Following the filler will be a stackdump. That stackdump describes the
+location where the error was detected. The cause of the corruption is more
+likely to be found by looking at the information about the last alloc / free.
+
+Christoph Lameter, <clameter@sgi.com>, May 23, 2007
index d9ee6336c1d49e6cf262d814251741cd340a1036..4f68052395c0323278caa14d003a0924695e0887 100644 (file)
@@ -1,3 +1,5 @@
+Last reviewed: 10/05/2007
+
                      Berkshire Products PC Watchdog Card
                    Support for ISA Cards  Revision A and C
            Documentation and Driver by Ken Hollis <kenji@bitgate.com>
@@ -14,8 +16,8 @@
 
  The Watchdog Driver will automatically find your watchdog card, and will
  attach a running driver for use with that card.  After the watchdog
- drivers have initialized, you can then talk to the card using the PC
- Watchdog program, available from http://ftp.bitgate.com/pcwd/.
+ drivers have initialized, you can then talk to the card using a PC
+ Watchdog program.
 
  I suggest putting a "watchdog -d" before the beginning of an fsck, and
  a "watchdog -e -t 1" immediately after the end of an fsck.  (Remember
@@ -62,5 +64,3 @@
  -- Ken Hollis
     (kenji@bitgate.com)
 
-(This documentation may be out of date.  Check
- http://ftp.bitgate.com/pcwd/ for the absolute latest additions.)
index 8d16f6f3c4eccbbba5e28f1e7f60db24ad942fa7..bb7cb1d31ec70f3424e41e7b99b15c0ce5dbc87a 100644 (file)
@@ -1,3 +1,6 @@
+Last reviewed: 10/05/2007
+
+
 The Linux Watchdog driver API.
 
 Copyright 2002 Christer Weingel <wingel@nano-system.com>
@@ -22,7 +25,7 @@ the system.  If userspace fails (RAM error, kernel bug, whatever), the
 notifications cease to occur, and the hardware watchdog will reset the
 system (causing a reboot) after the timeout occurs.
 
-The Linux watchdog API is a rather AD hoc construction and different
+The Linux watchdog API is a rather ad-hoc construction and different
 drivers implement different, and sometimes incompatible, parts of it.
 This file is an attempt to document the existing usage and allow
 future driver writers to use it as a reference.
@@ -46,14 +49,16 @@ some of the drivers support the configuration option "Disable watchdog
 shutdown on close", CONFIG_WATCHDOG_NOWAYOUT.  If it is set to Y when
 compiling the kernel, there is no way of disabling the watchdog once
 it has been started.  So, if the watchdog daemon crashes, the system
-will reboot after the timeout has passed.
+will reboot after the timeout has passed. Watchdog devices also usually
+support the nowayout module parameter so that this option can be controlled
+at runtime.
 
-Some other drivers will not disable the watchdog, unless a specific
-magic character 'V' has been sent /dev/watchdog just before closing
-the file.  If the userspace daemon closes the file without sending
-this special character, the driver will assume that the daemon (and
-userspace in general) died, and will stop pinging the watchdog without
-disabling it first.  This will then cause a reboot.
+Drivers will not disable the watchdog, unless a specific magic character 'V'
+has been sent /dev/watchdog just before closing the file.  If the userspace
+daemon closes the file without sending this special character, the driver
+will assume that the daemon (and userspace in general) died, and will stop
+pinging the watchdog without disabling it first.  This will then cause a
+reboot if the watchdog is not re-opened in sufficient time.
 
 The ioctl API:
 
@@ -227,218 +232,3 @@ The following options are available:
 
 [FIXME -- better explanations]
 
-Implementations in the current drivers in the kernel tree:
-
-Here I have tried to summarize what the different drivers support and
-where they do strange things compared to the other drivers.
-
-acquirewdt.c -- Acquire Single Board Computer
-
-       This driver has a hardcoded timeout of 1 minute
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns KEEPALIVEPING.  GETSTATUS will return 1 if
-       the device is open, 0 if not.  [FIXME -- isn't this rather
-       silly?  To be able to use the ioctl, the device must be open
-       and so GETSTATUS will always return 1].
-
-advantechwdt.c -- Advantech Single Board Computer
-
-       Timeout that defaults to 60 seconds, supports SETTIMEOUT.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
-       The GETSTATUS call returns if the device is open or not.
-       [FIXME -- silliness again?]
-       
-booke_wdt.c -- PowerPC BookE Watchdog Timer
-
-       Timeout default varies according to frequency, supports
-       SETTIMEOUT
-
-       Watchdog cannot be turned off, CONFIG_WATCHDOG_NOWAYOUT
-       does not make sense
-
-       GETSUPPORT returns the watchdog_info struct, and
-       GETSTATUS returns the supported options. GETBOOTSTATUS
-       returns a 1 if the last reset was caused by the
-       watchdog and a 0 otherwise. This watchdog cannot be
-       disabled once it has been started. The wdt_period kernel
-       parameter selects which bit of the time base changing
-       from 0->1 will trigger the watchdog exception. Changing
-       the timeout from the ioctl calls will change the
-       wdt_period as defined above. Finally if you would like to
-       replace the default Watchdog Handler you can implement the
-       WatchdogHandler() function in your own code.
-
-eurotechwdt.c -- Eurotech CPU-1220/1410
-
-       The timeout can be set using the SETTIMEOUT ioctl and defaults
-       to 60 seconds.
-
-       Also has a module parameter "ev", event type which controls
-       what should happen on a timeout, the string "int" or anything
-       else that causes a reboot.  [FIXME -- better description]
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns CARDRESET and WDIOF_SETTIMEOUT but
-       GETSTATUS is not supported and GETBOOTSTATUS just returns 0.
-
-i810-tco.c -- Intel 810 chipset
-
-       Also has support for a lot of other i8x0 stuff, but the
-       watchdog is one of the things.
-
-       The timeout is set using the module parameter "i810_margin",
-       which is in steps of 0.6 seconds where 2<i810_margin<64.  The
-       driver supports the SETTIMEOUT ioctl.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT.
-
-       GETSUPPORT returns WDIOF_SETTIMEOUT.  The GETSTATUS call
-       returns some kind of timer value which ist not compatible with
-       the other drivers.  GETBOOT status returns some kind of
-       hardware specific boot status.  [FIXME -- describe this]
-
-ib700wdt.c -- IB700 Single Board Computer
-
-       Default timeout of 30 seconds and the timeout is settable
-       using the SETTIMEOUT ioctl.  Note that only a few timeout
-       values are supported.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
-       The GETSTATUS call returns if the device is open or not.
-       [FIXME -- silliness again?]
-
-machzwd.c -- MachZ ZF-Logic
-
-       Hardcoded timeout of 10 seconds
-
-       Has a module parameter "action" that controls what happens
-       when the timeout runs out which can be 0 = RESET (default), 
-       1 = SMI, 2 = NMI, 3 = SCI.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT and the magic character
-       'V' close handling.
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING, and the GETSTATUS call
-       returns if the device is open or not.  [FIXME -- silliness
-       again?]
-
-mixcomwd.c -- MixCom Watchdog
-
-       [FIXME -- I'm unable to tell what the timeout is]
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING, GETSTATUS returns if
-       the device is opened or not [FIXME -- I'm not really sure how
-       this works, there seems to be some magic connected to
-       CONFIG_WATCHDOG_NOWAYOUT]
-
-pcwd.c -- Berkshire PC Watchdog
-
-       Hardcoded timeout of 1.5 seconds
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_OVERHEAT|WDIOF_CARDRESET and both
-       GETSTATUS and GETBOOTSTATUS return something useful.
-
-       The SETOPTIONS call can be used to enable and disable the card
-       and to ask the driver to call panic if the system overheats.
-
-sbc60xxwdt.c -- 60xx Single Board Computer
-
-       Hardcoded timeout of 10 seconds
-
-       Does not support CONFIG_WATCHDOG_NOWAYOUT, but has the magic
-       character 'V' close handling.
-
-       No bits set in GETSUPPORT
-
-scx200.c -- National SCx200 CPUs
-
-       Not in the kernel yet.
-
-       The timeout is set using a module parameter "margin" which
-       defaults to 60 seconds.  The timeout can also be set using
-       SETTIMEOUT and read using GETTIMEOUT.
-
-       Supports a module parameter "nowayout" that is initialized
-       with the value of CONFIG_WATCHDOG_NOWAYOUT.  Also supports the
-       magic character 'V' handling.
-
-shwdt.c -- SuperH 3/4 processors
-
-       [FIXME -- I'm unable to tell what the timeout is]
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING, and the GETSTATUS call
-       returns if the device is open or not.  [FIXME -- silliness
-       again?]
-
-softdog.c -- Software watchdog
-
-       The timeout is set with the module parameter "soft_margin"
-       which defaults to 60 seconds, the timeout is also settable
-       using the SETTIMEOUT ioctl.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       WDIOF_SETTIMEOUT bit set in GETSUPPORT
-
-w83877f_wdt.c -- W83877F Computer
-
-       Hardcoded timeout of 30 seconds
-
-       Does not support CONFIG_WATCHDOG_NOWAYOUT, but has the magic
-       character 'V' close handling.
-
-       No bits set in GETSUPPORT
-
-w83627hf_wdt.c -- w83627hf watchdog
-
-       Timeout that defaults to 60 seconds, supports SETTIMEOUT.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
-       The GETSTATUS call returns if the device is open or not.
-
-wdt.c -- ICS WDT500/501 ISA and
-wdt_pci.c -- ICS WDT500/501 PCI
-
-       Default timeout of 60 seconds.  The timeout is also settable
-        using the SETTIMEOUT ioctl.
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       GETSUPPORT returns with bits set depending on the actual
-       card. The WDT501 supports a lot of external monitoring, the
-       WDT500 much less.
-
-wdt285.c -- Footbridge watchdog
-
-       The timeout is set with the module parameter "soft_margin"
-       which defaults to 60 seconds.  The timeout is also settable
-       using the SETTIMEOUT ioctl.
-
-       Does not support CONFIG_WATCHDOG_NOWAYOUT
-
-       WDIOF_SETTIMEOUT bit set in GETSUPPORT
-
-wdt977.c -- Netwinder W83977AF chip
-
-       Hardcoded timeout of 3 minutes
-
-       Supports CONFIG_WATCHDOG_NOWAYOUT
-
-       Does not support any ioctls at all.
-
diff --git a/Documentation/watchdog/watchdog.txt b/Documentation/watchdog/watchdog.txt
deleted file mode 100644 (file)
index 4b1ff69..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-       Watchdog Timer Interfaces For The Linux Operating System
-
-               Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-            Custom Linux Driver And Program Development
-
-
-The following watchdog drivers are currently implemented:
-
-       ICS     WDT501-P
-       ICS     WDT501-P (no fan tachometer)
-       ICS     WDT500-P
-       Software Only
-       SA1100 Internal Watchdog
-       Berkshire Products PC Watchdog Revision A & C (by Ken Hollis)
-
-
-All six interfaces provide /dev/watchdog, which when open must be written
-to within a timeout or the machine will reboot. Each write delays the reboot
-time another timeout. In the case of the software watchdog the ability to 
-reboot will depend on the state of the machines and interrupts. The hardware
-boards physically pull the machine down off their own onboard timers and
-will reboot from almost anything.
-
-A second temperature monitoring interface is available on the WDT501P cards
-and some Berkshire cards. This provides /dev/temperature. This is the machine 
-internal temperature in degrees Fahrenheit. Each read returns a single byte 
-giving the temperature.
-
-The third interface logs kernel messages on additional alert events.
-
-Both software and hardware watchdog drivers are available in the standard
-kernel. If you are using the software watchdog, you probably also want
-to use "panic=60" as a boot argument as well.
-
-The wdt card cannot be safely probed for. Instead you need to pass
-wdt=ioaddr,irq as a boot parameter - eg "wdt=0x240,11".
-
-The SA1100 watchdog module can be configured with the "sa1100_margin"
-commandline argument which specifies timeout value in seconds.
-
-The i810 TCO watchdog modules can be configured with the "i810_margin"
-commandline argument which specifies the counter initial value. The counter
-is decremented every 0.6 seconds and default to 50 (30 seconds). Values can
-range between 3 and 63.
-
-The i810 TCO watchdog driver also implements the WDIOC_GETSTATUS and
-WDIOC_GETBOOTSTATUS ioctl()s. WDIOC_GETSTATUS returns the actual counter value
-and WDIOC_GETBOOTSTATUS returns the value of TCO2 Status Register (see Intel's
-documentation for the 82801AA and 82801AB datasheet). 
-
-Features
---------
-               WDT501P         WDT500P         Software        Berkshire       i810 TCO        SA1100WD
-Reboot Timer      X               X                X               X               X               X
-External Reboot           X               X                o               o               o               X
-I/O Port Monitor   o              o                o               X               o               o
-Temperature       X               o                o               X               o               o
-Fan Speed          X              o                o               o               o               o
-Power Under       X               o                o               o               o               o
-Power Over         X               o                o               o               o               o
-Overheat           X               o                o               o               o               o
-
-The external event interfaces on the WDT boards are not currently supported.
-Minor numbers are however allocated for it.
-
-
-Example Watchdog Driver:  see Documentation/watchdog/src/watchdog-simple.c
-
-
-Contact Information
-
-People keep asking about the WDT watchdog timer hardware: The phone contacts
-for Industrial Computer Source are:
-Industrial Computer Source
-http://www.indcompsrc.com
-ICS Advent, San Diego
-6260 Sequence Dr.
-San Diego, CA 92121-4371
-Phone (858) 677-0877
-FAX: (858) 677-0895
->
-ICS Advent Europe, UK
-Oving Road
-Chichester,
-West Sussex,
-PO19 4ET, UK
-Phone: 00.44.1243.533900
-
-
-and please mention Linux when enquiring.
-
-For full information about the PCWD cards see the pcwd-watchdog.txt document.
diff --git a/Documentation/watchdog/wdt.txt b/Documentation/watchdog/wdt.txt
new file mode 100644 (file)
index 0000000..03fd756
--- /dev/null
@@ -0,0 +1,43 @@
+Last Reviewed: 10/05/2007
+
+       WDT Watchdog Timer Interfaces For The Linux Operating System
+               Alan Cox <alan@lxorguk.ukuu.org.uk>
+
+       ICS     WDT501-P
+       ICS     WDT501-P (no fan tachometer)
+       ICS     WDT500-P
+
+All the interfaces provide /dev/watchdog, which when open must be written
+to within a timeout or the machine will reboot. Each write delays the reboot
+time another timeout. In the case of the software watchdog the ability to
+reboot will depend on the state of the machines and interrupts. The hardware
+boards physically pull the machine down off their own onboard timers and
+will reboot from almost anything.
+
+A second temperature monitoring interface is available on the WDT501P cards
+This provides /dev/temperature. This is the machine internal temperature in
+degrees Fahrenheit. Each read returns a single byte giving the temperature.
+
+The third interface logs kernel messages on additional alert events.
+
+The wdt card cannot be safely probed for. Instead you need to pass
+wdt=ioaddr,irq as a boot parameter - eg "wdt=0x240,11".
+
+Features
+--------
+               WDT501P         WDT500P
+Reboot Timer      X               X
+External Reboot           X               X
+I/O Port Monitor   o              o
+Temperature       X               o
+Fan Speed          X              o
+Power Under       X               o
+Power Over         X               o
+Overheat           X               o
+
+The external event interfaces on the WDT boards are not currently supported.
+Minor numbers are however allocated for it.
+
+
+Example Watchdog Driver:  see Documentation/watchdog/src/watchdog-simple.c
+
index 22ab4019972b6c5565d6e87728fde69767b5631c..4c715a7e059a70f914ad49f9d6b747964e129c5f 100644 (file)
@@ -30,8 +30,11 @@ trivial patch so apply some common sense.
        job the maintainers (and especially Linus) do is to keep things
        looking the same. Sometimes this means that the clever hack in
        your driver to get around a problem actually needs to become a
-       generalized kernel feature ready for next time. See
-       Documentation/CodingStyle for guidance here.
+       generalized kernel feature ready for next time.
+
+       PLEASE check your patch with the automated style checker
+       (scripts/checkpatch.pl) to catch trival style violations.
+       See Documentation/CodingStyle for guidance here.
 
        PLEASE try to include any credit lines you want added with the
        patch. It avoids people being missed off by mistake and makes
@@ -332,6 +335,9 @@ L:  linux-usb-devel@lists.sourceforge.net
 W:     http://www.linux-usb.org/SpeedTouch/
 S:     Maintained
 
+ALCHEMY AU1XX0 MMC DRIVER
+S:     Orphan
+
 ALI1563 I2C DRIVER
 P:     Rudolf Marek
 M:     r.marek@assembler.cz
@@ -418,6 +424,12 @@ P: Ian Molton
 M:     spyro@f2s.com
 S:     Maintained
 
+ARM PRIMECELL MMCI PL180/1 DRIVER
+P:     Russell King
+M:     rmk@arm.linux.org.uk
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:     Maintained
+
 ARM/ADI ROADRUNNER MACHINE SUPPORT
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
@@ -649,6 +661,9 @@ L:  linux-atm-general@lists.sourceforge.net (subscribers-only)
 W:     http://linux-atm.sourceforge.net
 S:     Maintained
 
+ATMEL AT91 MCI DRIVER
+S:     Orphan
+
 ATMEL MACB ETHERNET DRIVER
 P:     Haavard Skinnemoen
 M:     hskinnemoen@atmel.com
@@ -767,11 +782,6 @@ M: rathamahata@php4.ru
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
-P:     Kenji Hollis
-W:     http://ftp.bitgate.com/pcwd/
-S:     Maintained
-
 BFS FILE SYSTEM
 P:     Tigran A. Aivazian
 M:     tigran@aivazian.fsnet.co.uk
@@ -960,6 +970,15 @@ M: johannes@sipsolutions.net
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
 
+CHECKPATCH
+P:     Andy Whitcroft
+M:     apw@shadowen.org
+P:     Randy Dunlap
+M:     rdunlap@xenotime.net
+P:     Joel Schopp
+M:     jschopp@austin.ibm.com
+S:     Supported
+
 COMMON INTERNET FILE SYSTEM (CIFS)
 P:     Steve French
 M:     sfrench@samba.org
@@ -1463,6 +1482,13 @@ L:       linux-usb-devel@lists.sourceforge.net
 L:     linuxppc-embedded@ozlabs.org
 S:     Maintained
 
+FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
+P:     Li Yang
+M:     leoli@freescale.com
+L:     netdev@vger.kernel.org
+L:     linuxppc-embedded@ozlabs.org
+S:     Maintained
+
 FILE LOCKING (flock() and fcntl()/lockf())
 P:     Matthew Wilcox
 M:     matthew@wil.cx
@@ -1474,6 +1500,14 @@ P:       Alexander Viro
 M:     viro@zeniv.linux.org.uk
 S:     Maintained
 
+FIREWIRE SUBSYSTEM
+P:     Kristian Hoegsberg, Stefan Richter
+M:     krh@redhat.com, stefanr@s5r6.in-berlin.de
+L:     linux1394-devel@lists.sourceforge.net
+W:     http://www.linux1394.org/
+T:     git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
+S:     Maintained
+
 FIRMWARE LOADER (request_firmware)
 L:     linux-kernel@vger.kernel.org
 S:     Orphan
@@ -2322,7 +2356,7 @@ S:        Maintained
 
 MEGARAID SCSI DRIVERS
 P:     Neela Syam Kolli
-M:     Neela.Kolli@engenio.com
+M:     megaraidlinux@lsi.com
 S:     linux-scsi@vger.kernel.org
 W:     http://megaraid.lsilogic.com
 S:     Maintained
@@ -2380,6 +2414,13 @@ M:       stelian@popies.net
 W:     http://popies.net/meye/
 S:     Maintained
 
+MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
+P:     Pavel Pisa
+M:     ppisa@pikron.com
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W:     http://mmc.drzeus.cx/wiki/Controllers/Freescale/SDHC
+S:     Maintained
+
 MOUSE AND MISC DEVICES [GENERAL]
 P:     Alessandro Rubini
 M:     rubini@ipvvis.unipv.it
@@ -2861,8 +2902,8 @@ W:        ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel
 S:     Supported
 
 PRISM54 WIRELESS DRIVER
-P:     Prism54 Development Team
-M:     developers@islsm.org
+P:     Luis R. Rodriguez
+M:     mcgrof@gmail.com
 L:     linux-wireless@vger.kernel.org
 W:     http://prism54.org
 S:     Maintained
@@ -2900,6 +2941,9 @@ M:        nico@cam.org
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
+PXA MMCI DRIVER
+S:     Orphan
+
 QLOGIC QLA2XXX FC-SCSI DRIVER
 P:     Andrew Vasquez
 M:     linux-driver@qlogic.com
@@ -2976,7 +3020,7 @@ S:        Maintained
 REISERFS FILE SYSTEM
 P:     Hans Reiser
 M:     reiserfs-dev@namesys.com
-L:     reiserfs-list@namesys.com
+L:     reiserfs-devel@vger.kernel.org
 W:     http://www.namesys.com
 S:     Supported
 
@@ -3416,6 +3460,13 @@ P:      Alex Dubov
 M:      oakad@yahoo.com
 S:      Maintained
 
+TI OMAP MMC INTERFACE DRIVER
+P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
+M:     linux-omap-open-source@linux.omap.com 
+W:     http://linux.omap.com
+W:     http://www.muru.com/linux/omap/
+S:     Maintained
+
 TI OMAP RANDOM NUMBER GENERATOR SUPPORT
 P:     Deepak Saxena
 M:     dsaxena@plexity.net
@@ -3496,7 +3547,7 @@ S:        Maintained
 
 TULIP NETWORK DRIVER
 P:     Valerie Henson
-M:     val_henson@linux.intel.com
+M:     val@nmt.edu
 L:     tulip-users@lists.sourceforge.net
 W:     http://sourceforge.net/projects/tulip/
 S:     Maintained
@@ -3848,10 +3899,6 @@ S:       Maintained
 
 UCLINUX FOR NEC V850
 P:     Miles Bader
-M:     uclinux-v850@lsi.nec.co.jp
-W:     http://www.ic.nec.co.jp/micro/uclinux/eng/
-W:     http://www.ee.nec.de/uclinux/
-S:     Supported
 
 UCLINUX FOR RENESAS H8/300
 P:     Yoshinori Sato
@@ -3860,10 +3907,10 @@ W:      http://uclinux-h8.sourceforge.jp/
 S:     Supported
 
 UFS FILESYSTEM
-P: Evgeniy Dushistov
-M: dushistov@mail.ru
-L: linux-kernel@vger.kernel.org
-S: Maintained
+P:     Evgeniy Dushistov
+M:     dushistov@mail.ru
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
 
 USB DIAMOND RIO500 DRIVER
 P:     Cesar Miquel
index 34210af91ce2f575d770bd7de61a646768ace9d2..30d685b629a46a84f5ccbd022a4ac52eb97fdefe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 22
-EXTRAVERSION = -rc2
-NAME = Nocturnal Monster Puppy
+EXTRAVERSION = -rc4
+NAME = Jeff Thinks I Should Change This, But To What?
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 770f717bd250c2c0965b6477e2b6b205b8f37dbe..79c6e5a2445652679b4aafa5d647e06248fe27b2 100644 (file)
@@ -83,22 +83,20 @@ choice
          check out the Linux/Alpha FAQ, accessible on the WWW from
          <http://www.alphalinux.org/>. In summary:
 
-         Alcor/Alpha-XLT     AS 600
+         Alcor/Alpha-XLT     AS 600, AS 500, XL-300, XL-366
          Alpha-XL            XL-233, XL-266
          AlphaBook1          Alpha laptop
          Avanti              AS 200, AS 205, AS 250, AS 255, AS 300, AS 400
          Cabriolet           AlphaPC64, AlphaPCI64
-         DP264               DP264
+         DP264               DP264 / DS20 / ES40 / DS10 / DS10L
          EB164               EB164 21164 evaluation board
          EB64+               EB64+ 21064 evaluation board
          EB66                EB66 21066 evaluation board
          EB66+               EB66+ 21066 evaluation board
-         Jensen              DECpc 150, DEC 2000 model 300,
-         DEC 2000 model 500
+         Jensen              DECpc 150, DEC 2000 models 300, 500
          LX164               AlphaPC164-LX
          Lynx                AS 2100A
-         Miata               Personal Workstation 433a, 433au, 500a,
-         500au, 600a, or 600au
+         Miata               Personal Workstation 433/500/600 a/au
          Marvel              AlphaServer ES47 / ES80 / GS1280
          Mikasa              AS 1000
          Noname              AXPpci33, UDB (Multia)
@@ -108,9 +106,9 @@ choice
          Ruffian             RPX164-2, AlphaPC164-UX, AlphaPC164-BX
          SX164               AlphaPC164-SX
          Sable               AS 2000, AS 2100
-         Shark               DS 20L
-         Takara              Takara
-         Titan               AlphaServer ES45 / DS25
+         Shark               DS 20L
+         Takara              Takara (OEM)
+         Titan               AlphaServer ES45 / DS25 / DS15
          Wildfire            AlphaServer GS 40/80/160/320
 
          If you don't know what to do, choose "generic".
@@ -481,6 +479,15 @@ config ALPHA_BROKEN_IRQ_MASK
        depends on ALPHA_GENERIC || ALPHA_PC164
        default y
 
+config VGA_HOSE
+       bool
+       depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI
+       default y
+       help
+         Support VGA on an arbitrary hose; needed for several platforms
+         which always have multiple hoses, and whose consoles support it.
+
+
 config ALPHA_SRM
        bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
        default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
@@ -537,10 +544,14 @@ config HAVE_DEC_LOCK
        default y
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-64)"
-       range 2 64
+       int "Maximum number of CPUs (2-32)"
+       range 2 32
        depends on SMP
-       default "64"
+       default "32" if ALPHA_GENERIC || ALPHA_MARVEL
+       default "4" if !ALPHA_GENERIC && !ALPHA_MARVEL
+       help
+         MARVEL support can handle a maximum of 32 CPUs, all the others
+          with working support have a maximum of 4 CPUs.
 
 config ARCH_DISCONTIGMEM_ENABLE
        bool "Discontiguous Memory Support (EXPERIMENTAL)"
@@ -644,6 +655,13 @@ source "arch/alpha/oprofile/Kconfig"
 
 source "arch/alpha/Kconfig.debug"
 
+# DUMMY_CONSOLE may be defined in drivers/video/console/Kconfig
+# but we also need it if VGA_HOSE is set
+config DUMMY_CONSOLE
+       bool
+       depends on VGA_HOSE
+       default y
+
 source "security/Kconfig"
 
 source "crypto/Kconfig"
index 23c7190b047c2d716303d1beefa69342280c5a43..632a7fd6d7dcfeb42efd837e8188d55b5ebd933d 100644 (file)
@@ -81,7 +81,7 @@ typedef union __bootblock {
 #define        bootblock_label         __u1.__label
 #define bootblock_checksum     __u2.__checksum
 
-main(int argc, char ** argv)
+int main(int argc, char ** argv)
 {
     bootblock          bootblock_from_disk;
     bootblock          bootloader_image;
index f313b34939bbc5516894e64e2d047322bfa69bae..da711e37fc975af1041b7229d02b5aea84856f40 100644 (file)
@@ -9,16 +9,20 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/vt.h>
 #include <asm/vga.h>
 #include <asm/machvec.h>
 
+#include "pci_impl.h"
+
 #ifdef CONFIG_VGA_HOSE
 
-/*
- * Externally-visible vga hose bases
- */
-unsigned long __vga_hose_io_base = 0;  /* base for default hose */
-unsigned long __vga_hose_mem_base = 0; /* base for default hose */
+struct pci_controller *pci_vga_hose;
+static struct resource alpha_vga = {
+       .name   = "alpha-vga+",
+       .start  = 0x3C0,
+       .end    = 0x3DF
+};
 
 static struct pci_controller * __init 
 default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
@@ -29,37 +33,59 @@ default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
        return h1;
 }
 
-void __init 
-set_vga_hose(struct pci_controller *hose)
-{
-       if (hose) {
-               __vga_hose_io_base = hose->io_space->start;
-               __vga_hose_mem_base = hose->mem_space->start;
-       }
-}
-
 void __init 
 locate_and_init_vga(void *(*sel_func)(void *, void *))
 {
        struct pci_controller *hose = NULL;
        struct pci_dev *dev = NULL;
 
+       /* Default the select function */
        if (!sel_func) sel_func = (void *)default_vga_hose_select;
 
+       /* Find the console VGA device */
        for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
-               if (!hose) hose = dev->sysdata;
-               else hose = sel_func(hose, dev->sysdata);
+               if (!hose)
+                       hose = dev->sysdata;
+               else
+                       hose = sel_func(hose, dev->sysdata);
        }
 
-       /* Did we already inititialize the correct one? */
-       if (conswitchp == &vga_con &&
-           __vga_hose_io_base == hose->io_space->start &&
-           __vga_hose_mem_base == hose->mem_space->start)
+       /* Did we already initialize the correct one? Is there one? */
+       if (!hose || (conswitchp == &vga_con && pci_vga_hose == hose))
                return;
 
-       /* Set the VGA hose and init the new console */
-       set_vga_hose(hose);
+       /* Create a new VGA ioport resource WRT the hose it is on. */
+       alpha_vga.start += hose->io_space->start;
+       alpha_vga.end += hose->io_space->start;
+       request_resource(hose->io_space, &alpha_vga);
+
+       /* Set the VGA hose and init the new console. */
+       pci_vga_hose = hose;
        take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
 }
 
+void __init
+find_console_vga_hose(void)
+{
+       u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
+
+       if (pu64[7] == 3) {     /* TERM_TYPE == graphics */
+               struct pci_controller *hose;
+               int h = (pu64[30] >> 24) & 0xff;        /* console hose # */
+
+               /*
+                * Our hose numbering DOES match the console's, so find
+                * the right one...
+                */
+               for (hose = hose_head; hose; hose = hose->next) {
+                       if (hose->index == h) break;
+               }
+
+               if (hose) {
+                       printk("Console graphics on hose %d\n", h);
+                       pci_vga_hose = hose;
+               }
+       }
+}
+
 #endif
index 7f6a98455e74e52f666893b457f138a0eedc3cda..f10d2eddd2c309a807d58df12c48f01156f99efc 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/rtc.h>
+#include <asm/vga.h>
 
 #include "proto.h"
 #include "pci_impl.h"
@@ -367,9 +368,8 @@ marvel_io7_present(gct6_node *node)
 }
 
 static void __init
-marvel_init_vga_hose(void)
+marvel_find_console_vga_hose(void)
 {
-#ifdef CONFIG_VGA_HOSE
        u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
 
        if (pu64[7] == 3) {     /* TERM_TYPE == graphics */
@@ -403,7 +403,6 @@ marvel_init_vga_hose(void)
                        pci_vga_hose = hose;
                }
        }
-#endif /* CONFIG_VGA_HOSE */
 }
 
 gct6_search_struct gct_wanted_node_list[] = {
@@ -459,7 +458,7 @@ marvel_init_arch(void)
                marvel_init_io7(io7);
 
        /* Check for graphic console location (if any).  */
-       marvel_init_vga_hose();
+       marvel_find_console_vga_hose();
 }
 
 void
@@ -684,9 +683,6 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
 /*
  * IO map support.
  */
-
-#define __marvel_is_mem_vga(a) (((a) >= 0xa0000) && ((a) <= 0xc0000))
-
 void __iomem *
 marvel_ioremap(unsigned long addr, unsigned long size)
 {
@@ -698,13 +694,9 @@ marvel_ioremap(unsigned long addr, unsigned long size)
        unsigned long pfn;
 
        /*
-        * Adjust the addr.
+        * Adjust the address.
         */ 
-#ifdef CONFIG_VGA_HOSE
-       if (pci_vga_hose && __marvel_is_mem_vga(addr)) {
-               addr += pci_vga_hose->mem_space->start;
-       }
-#endif
+       FIXUP_MEMADDR_VGA(addr);
 
        /*
         * Find the hose.
@@ -781,7 +773,9 @@ marvel_ioremap(unsigned long addr, unsigned long size)
                return (void __iomem *) vaddr;
        }
 
-       return NULL;
+       /* Assume it was already a reasonable address */
+       vaddr = baddr + hose->mem_space->start;
+       return (void __iomem *) vaddr;
 }
 
 void
@@ -803,21 +797,12 @@ marvel_is_mmio(const volatile void __iomem *xaddr)
                return (addr & 0xFF000000UL) == 0;
 }
 
-#define __marvel_is_port_vga(a)        \
-  (((a) >= 0x3b0) && ((a) < 0x3e0) && ((a) != 0x3b3) && ((a) != 0x3d3))
 #define __marvel_is_port_kbd(a)        (((a) == 0x60) || ((a) == 0x64))
 #define __marvel_is_port_rtc(a)        (((a) == 0x70) || ((a) == 0x71))
 
 void __iomem *marvel_ioportmap (unsigned long addr)
 {
-       if (__marvel_is_port_rtc (addr) || __marvel_is_port_kbd(addr))
-               ;
-#ifdef CONFIG_VGA_HOSE
-       else if (__marvel_is_port_vga (addr) && pci_vga_hose)
-               addr += pci_vga_hose->io_space->start;
-#endif
-       else
-               return NULL;
+       FIXUP_IOADDR_VGA(addr);
        return (void __iomem *)addr;
 }
 
@@ -829,8 +814,14 @@ marvel_ioread8(void __iomem *xaddr)
                return 0;
        else if (__marvel_is_port_rtc(addr))
                return __marvel_rtc_io(0, addr, 0);
-       else
+       else if (marvel_is_ioaddr(addr))
                return __kernel_ldbu(*(vucp)addr);
+       else
+               /* this should catch other legacy addresses
+                  that would normally fail on MARVEL,
+                  because there really is nothing there...
+               */
+               return ~0;
 }
 
 void
@@ -841,7 +832,7 @@ marvel_iowrite8(u8 b, void __iomem *xaddr)
                return;
        else if (__marvel_is_port_rtc(addr)) 
                __marvel_rtc_io(b, addr, 1);
-       else
+       else if (marvel_is_ioaddr(addr))
                __kernel_stb(b, *(vucp)addr);
 }
 
index 3662fef7db9a9c19413f01e06edf5de013e2edf9..819326627b966c3f166f76b38a11614ad51e11ec 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
+#include <asm/vga.h>
 
 #include "proto.h"
 #include "pci_impl.h"
@@ -34,6 +35,11 @@ struct
        unsigned long tba[4];
 } saved_config[4] __attribute__((common));
 
+/*
+ * Is PChip 1 present? No need to query it more than once.
+ */
+static int titan_pchip1_present;
+
 /*
  * BIOS32-style PCI interface:
  */
@@ -344,43 +350,17 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index)
 static void __init
 titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
 {
-       int pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
+       titan_pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
 
        /* Init the ports in hose order... */
        titan_init_one_pachip_port(&pachip0->g_port, 0);        /* hose 0 */
-       if (pchip1_present)
+       if (titan_pchip1_present)
                titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */
        titan_init_one_pachip_port(&pachip0->a_port, 2);        /* hose 2 */
-       if (pchip1_present)
+       if (titan_pchip1_present)
                titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */
 }
 
-static void __init
-titan_init_vga_hose(void)
-{
-#ifdef CONFIG_VGA_HOSE
-       u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
-
-       if (pu64[7] == 3) {     /* TERM_TYPE == graphics */
-               struct pci_controller *hose;
-               int h = (pu64[30] >> 24) & 0xff;        /* console hose # */
-
-               /*
-                * Our hose numbering matches the console's, so just find
-                * the right one...
-                */
-               for (hose = hose_head; hose; hose = hose->next) {
-                       if (hose->index == h) break;
-               }
-
-               if (hose) {
-                       printk("Console graphics on hose %d\n", hose->index);
-                       pci_vga_hose = hose;
-               }
-       }
-#endif /* CONFIG_VGA_HOSE */
-}
-
 void __init
 titan_init_arch(void)
 {
@@ -406,6 +386,7 @@ titan_init_arch(void)
 
        /* With multiple PCI busses, we play with I/O as physical addrs.  */
        ioport_resource.end = ~0UL;
+       iomem_resource.end = ~0UL;
 
        /* PCI DMA Direct Mapping is 1GB at 2GB.  */
        __direct_map_base = 0x80000000;
@@ -415,7 +396,7 @@ titan_init_arch(void)
        titan_init_pachips(TITAN_pachip0, TITAN_pachip1);
 
        /* Check for graphic console location (if any).  */
-       titan_init_vga_hose();
+       find_console_vga_hose();
 }
 
 static void
@@ -441,9 +422,7 @@ titan_kill_one_pachip_port(titan_pachip_port *port, int index)
 static void
 titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
 {
-       int pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
-
-       if (pchip1_present) {
+       if (titan_pchip1_present) {
                titan_kill_one_pachip_port(&pachip1->g_port, 1);
                titan_kill_one_pachip_port(&pachip1->a_port, 3);
        }
@@ -462,6 +441,14 @@ titan_kill_arch(int mode)
  * IO map support.
  */
 
+void __iomem *
+titan_ioportmap(unsigned long addr)
+{
+       FIXUP_IOADDR_VGA(addr);
+       return (void __iomem *)(addr + TITAN_IO_BIAS);
+}
+
+
 void __iomem *
 titan_ioremap(unsigned long addr, unsigned long size)
 {
@@ -475,14 +462,12 @@ titan_ioremap(unsigned long addr, unsigned long size)
        unsigned long pfn;
 
        /*
-        * Adjust the addr.
+        * Adjust the address and hose, if necessary.
         */ 
-#ifdef CONFIG_VGA_HOSE
-       if (pci_vga_hose && __titan_is_mem_vga(addr)) {
+       if (pci_vga_hose && __is_mem_vga(addr)) {
                h = pci_vga_hose->index;
                addr += pci_vga_hose->mem_space->start;
        }
-#endif
 
        /*
         * Find the hose.
@@ -521,8 +506,10 @@ titan_ioremap(unsigned long addr, unsigned long size)
                 * Map it
                 */
                area = get_vm_area(size, VM_IOREMAP);
-               if (!area)
+               if (!area) {
+                       printk("ioremap failed... no vm_area...\n");
                        return NULL;
+               }
 
                ptes = hose->sg_pci->ptes;
                for (vaddr = (unsigned long)area->addr; 
@@ -539,7 +526,7 @@ titan_ioremap(unsigned long addr, unsigned long size)
                        if (__alpha_remap_area_pages(vaddr,
                                                     pfn << PAGE_SHIFT, 
                                                     PAGE_SIZE, 0)) {
-                               printk("FAILED to map...\n");
+                               printk("FAILED to remap_area_pages...\n");
                                vfree(area->addr);
                                return NULL;
                        }
@@ -551,7 +538,8 @@ titan_ioremap(unsigned long addr, unsigned long size)
                return (void __iomem *) vaddr;
        }
 
-       return NULL;
+       /* Assume a legacy (read: VGA) address, and return appropriately. */
+       return (void __iomem *)(addr + TITAN_MEM_BIAS);
 }
 
 void
@@ -574,6 +562,7 @@ titan_is_mmio(const volatile void __iomem *xaddr)
 }
 
 #ifndef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(titan_ioportmap);
 EXPORT_SYMBOL(titan_ioremap);
 EXPORT_SYMBOL(titan_iounmap);
 EXPORT_SYMBOL(titan_is_mmio);
@@ -750,6 +739,7 @@ titan_agp_info(void)
        if (titan_query_agp(port))
                hosenum = 2;
        if (hosenum < 0 && 
+           titan_pchip1_present &&
            titan_query_agp(port = &TITAN_pachip1->a_port)) 
                hosenum = 3;
        
index ce623c6e55e1c9c30d1521a95309496273a2889f..ef91e09590d4d1aefe76772e81b29c83d9f73b78 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/smp.h>
+#include <asm/vga.h>
 
 #include "proto.h"
 #include "pci_impl.h"
@@ -349,6 +350,26 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
        tsunami_pci_tbi(hose, 0, -1);
 }
 
+
+void __iomem *
+tsunami_ioportmap(unsigned long addr)
+{
+       FIXUP_IOADDR_VGA(addr);
+       return (void __iomem *)(addr + TSUNAMI_IO_BIAS);
+}
+
+void __iomem *
+tsunami_ioremap(unsigned long addr, unsigned long size)
+{
+       FIXUP_MEMADDR_VGA(addr);
+       return (void __iomem *)(addr + TSUNAMI_MEM_BIAS);
+}
+
+#ifndef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(tsunami_ioportmap);
+EXPORT_SYMBOL(tsunami_ioremap);
+#endif
+
 void __init
 tsunami_init_arch(void)
 {
@@ -393,6 +414,9 @@ tsunami_init_arch(void)
        tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
        if (TSUNAMI_cchip->csc.csr & 1L<<14)
                tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
+
+       /* Check for graphic console location (if any).  */
+       find_console_vga_hose();
 }
 
 static void
index c95e95e1ab0423b2664e8359a32ff2da0d13372d..debc8f03886cf9edafa577664a90a6c8ec59c9ad 100644 (file)
@@ -391,11 +391,10 @@ $work_resched:
        bne     $2, $work_resched
 
 $work_notifysig:
-       mov     $sp, $17
+       mov     $sp, $16
        br      $1, do_switch_stack
-       mov     $5, $21
-       mov     $sp, $18
-       mov     $31, $16
+       mov     $sp, $17
+       mov     $5, $18
        jsr     $26, do_notify_resume
        bsr     $1, undo_switch_stack
        br      restore_all
index 6e7d1fe6e93532daa923ae6d6b69839e639954b6..28c84e55feb9b80440deda421730ff0c126e2963 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/log2.h>
 
 #include <asm/io.h>
 #include <asm/hwrpb.h>
@@ -53,7 +54,7 @@ size_for_memory(unsigned long max)
 {
        unsigned long mem = max_low_pfn << PAGE_SHIFT;
        if (mem < max)
-               max = 1UL << ceil_log2(mem);
+               max = roundup_pow_of_two(mem);
        return max;
 }
 \f
index 95912ecc65e1bb63af2f6991c08f485bfe938e40..708d5ca87782ad011019250399787e6e1c4258e5 100644 (file)
@@ -108,6 +108,15 @@ extern int wildfire_cpuid_to_nid(int);
 extern unsigned long wildfire_node_mem_start(int);
 extern unsigned long wildfire_node_mem_size(int);
 
+/* console.c */
+#ifdef CONFIG_VGA_HOSE
+extern void find_console_vga_hose(void);
+extern void locate_and_init_vga(void *(*)(void *, void *));
+#else
+static inline void find_console_vga_hose(void) { }
+static inline void locate_and_init_vga(void *(*sel_func)(void *, void *)) { }
+#endif
+
 /* setup.c */
 extern unsigned long srm_hae;
 extern int boot_cpuid;
index 915f26345c45c91a1105d97ed7256c40a859455b..bd5e68cd61e84fb440bd0a618b6c90019d48fb75 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/notifier.h>
 #include <asm/setup.h>
 #include <asm/io.h>
+#include <linux/log2.h>
 
 extern struct atomic_notifier_head panic_notifier_list;
 static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
@@ -1303,7 +1304,7 @@ external_cache_probe(int minsize, int width)
        long size = minsize, maxsize = MAX_BCACHE_SIZE * 2;
 
        if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT)
-               maxsize = 1 << (floor_log2(max_low_pfn + 1) + PAGE_SHIFT);
+               maxsize = 1 << (ilog2(max_low_pfn + 1) + PAGE_SHIFT);
 
        /* Get the first block cached. */
        read_mem_block(__va(0), stride, size);
index 7f64aa767d5a2f92aa8dfca13d466b3983dc64c3..410af4f3140e3ce4ff83256753f8e41d81c12106 100644 (file)
@@ -32,8 +32,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 asmlinkage void ret_from_sys_call(void);
-static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *,
-                    unsigned long, unsigned long);
+static void do_signal(struct pt_regs *, struct switch_stack *,
+                     unsigned long, unsigned long);
 
 
 /*
@@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act,
 asmlinkage int
 do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
 {
-       sigset_t oldset;
-
        mask &= _BLOCKABLE;
        spin_lock_irq(&current->sighand->siglock);
-       oldset = current->blocked;
+       current->saved_sigmask = current->blocked;
        siginitset(&current->blocked, mask);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
@@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
        regs->r0 = EINTR;
        regs->r19 = 1;
 
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&oldset, regs, sw, 0, 0))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 
 asmlinkage int
 do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
                 struct pt_regs *regs, struct switch_stack *sw)
 {
-       sigset_t oldset, set;
+       sigset_t set;
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
        if (sigsetsize != sizeof(sigset_t))
@@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
 
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sighand->siglock);
-       oldset = current->blocked;
+       current->saved_sigmask = current->blocked;
        current->blocked = set;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
@@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
        regs->r0 = EINTR;
        regs->r19 = 1;
 
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&oldset, regs, sw, 0, 0))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 
 asmlinkage int
@@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        return err;
 }
 
-static void
+static int
 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
            struct pt_regs *regs, struct switch_stack * sw)
 {
@@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
                current->comm, current->pid, frame, regs->pc, regs->r26);
 #endif
 
-       return;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
+       return -EFAULT;
 }
 
-static void
+static int
 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
               sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
 {
@@ -543,34 +538,38 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                current->comm, current->pid, frame, regs->pc, regs->r26);
 #endif
 
-       return;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
+       return -EFAULT;
 }
 
 
 /*
  * OK, we're invoking a handler.
  */
-static inline void
+static inline int
 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
              sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
 {
+       int ret;
+
        if (ka->sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame(sig, ka, info, oldset, regs, sw);
+               ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
        else
-               setup_frame(sig, ka, oldset, regs, sw);
+               ret = setup_frame(sig, ka, oldset, regs, sw);
 
-       if (ka->sa.sa_flags & SA_RESETHAND)
-               ka->sa.sa_handler = SIG_DFL;
+       if (ret == 0) {
+               spin_lock_irq(&current->sighand->siglock);
+               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+               if (!(ka->sa.sa_flags & SA_NODEFER)) 
+                       sigaddset(&current->blocked,sig);
+               recalc_sigpending();
+               spin_unlock_irq(&current->sighand->siglock);
+       }
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER)) 
-               sigaddset(&current->blocked,sig);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       return ret;
 }
 
 static inline void
@@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19,
  * restart. "r0" is also used as an indicator whether we can restart at
  * all (if we get here from anything but a syscall return, it will be 0)
  */
-static int
-do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
+static void
+do_signal(struct pt_regs * regs, struct switch_stack * sw,
          unsigned long r0, unsigned long r19)
 {
        siginfo_t info;
        int signr;
        unsigned long single_stepping = ptrace_cancel_bpt(current);
        struct k_sigaction ka;
+       sigset_t *oldset;
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
 
        /* This lets the debugger run, ... */
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
        /* ... so re-check the single stepping. */
        single_stepping |= ptrace_cancel_bpt(current);
 
        if (signr > 0) {
                /* Whee!  Actually deliver the signal.  */
-               if (r0) syscall_restart(r0, r19, regs, &ka);
-               handle_signal(signr, &ka, &info, oldset, regs, sw);
+               if (r0)
+                       syscall_restart(r0, r19, regs, &ka);
+               if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) {
+                       /* A signal was successfully delivered, and the
+                          saved sigmask was stored on the signal frame,
+                          and will be restored by sigreturn.  So we can
+                          simply clear the restore sigmask flag.  */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               }
                if (single_stepping) 
                        ptrace_set_bpt(current); /* re-set bpt */
-               return 1;
+               return;
        }
 
        if (r0) {
@@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
                        break;
                }
        }
+
+       /* If there's no signal to deliver, we just restore the saved mask.  */
+       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+       }
+
        if (single_stepping)
                ptrace_set_bpt(current);        /* re-set breakpoint */
-
-       return 0;
 }
 
 void
-do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
-                struct switch_stack *sw, unsigned long r0,
-                unsigned long r19, unsigned long thread_info_flags)
+do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
+                unsigned long thread_info_flags,
+                unsigned long r0, unsigned long r19)
 {
-       if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(oldset, regs, sw, r0, r19);
+       if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+               do_signal(regs, sw, r0, r19);
 }
index 85d2f933dd07b0b8d9ca88f13646e302d13e1328..c71b0fd7a61f8748b857463c03854006ec5b91a1 100644 (file)
@@ -543,6 +543,7 @@ dp264_init_pci(void)
 {
        common_init_pci();
        SMC669_Init(0);
+       locate_and_init_vga(NULL);
 }
 
 static void __init
@@ -551,6 +552,14 @@ monet_init_pci(void)
        common_init_pci();
        SMC669_Init(1);
        es1888_init();
+       locate_and_init_vga(NULL);
+}
+
+static void __init
+clipper_init_pci(void)
+{
+       common_init_pci();
+       locate_and_init_vga(NULL);
 }
 
 static void __init
@@ -655,7 +664,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
        .init_arch              = tsunami_init_arch,
        .init_irq               = clipper_init_irq,
        .init_rtc               = common_init_rtc,
-       .init_pci               = common_init_pci,
+       .init_pci               = clipper_init_pci,
        .kill_arch              = tsunami_kill_arch,
        .pci_map_irq            = clipper_map_irq,
        .pci_swizzle            = common_swizzle,
index e349f03b830e9c96826646877006e640dcf0edad..0bcb968cb60a72b7a71b99d98947a53882f620be 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/core_marvel.h>
 #include <asm/hwrpb.h>
 #include <asm/tlbflush.h>
+#include <asm/vga.h>
 
 #include "proto.h"
 #include "err_impl.h"
@@ -412,10 +413,7 @@ marvel_init_pci(void)
 
        pci_probe_only = 1;
        common_init_pci();
-
-#ifdef CONFIG_VGA_HOSE
        locate_and_init_vga(NULL);
-#endif
 
        /* Clear any io7 errors.  */
        for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) 
index f009b7bc094310da51ff2f154df86911e01d24cc..1d3c1398c428d324d42f67b4fc24284831278b2b 100644 (file)
@@ -331,9 +331,7 @@ titan_init_pci(void)
        pci_probe_only = 1;
        common_init_pci();
        SMC669_Init(0);
-#ifdef CONFIG_VGA_HOSE
        locate_and_init_vga(NULL);
-#endif
 }
 
 \f
index f6cfe8ce3f966b68cd5827c215eca6df94ffc57e..79de99e32c35f91ad2fcebc0ab8513bc5fd612d7 100644 (file)
@@ -465,6 +465,38 @@ sys_call_table:
        .quad sys_inotify_init
        .quad sys_inotify_add_watch             /* 445 */
        .quad sys_inotify_rm_watch
+       .quad sys_fdatasync
+       .quad sys_kexec_load
+       .quad sys_migrate_pages
+       .quad sys_openat                        /* 450 */
+       .quad sys_mkdirat
+       .quad sys_mknodat
+       .quad sys_fchownat
+       .quad sys_futimesat
+       .quad sys_fstatat64                     /* 455 */
+       .quad sys_unlinkat
+       .quad sys_renameat
+       .quad sys_linkat
+       .quad sys_symlinkat
+       .quad sys_readlinkat                    /* 460 */
+       .quad sys_fchmodat
+       .quad sys_faccessat
+       .quad sys_pselect6
+       .quad sys_ppoll
+       .quad sys_unshare                       /* 465 */
+       .quad sys_set_robust_list
+       .quad sys_get_robust_list
+       .quad sys_splice
+       .quad sys_sync_file_range
+       .quad sys_tee                           /* 470 */
+       .quad sys_vmsplice
+       .quad sys_move_pages
+       .quad sys_getcpu
+       .quad sys_epoll_pwait
+       .quad sys_utimensat                     /* 475 */
+       .quad sys_signalfd
+       .quad sys_timerfd
+       .quad sys_eventfd
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index ea098f3b629f166c703720f65cf358429d10cf03..266f78e130766f5dc3ad1c1af261d368a92ef610 100644 (file)
@@ -37,7 +37,8 @@ lib-y =       __divqu.o __remqu.o __divlu.o __remlu.o \
        $(ev6-y)clear_page.o \
        $(ev6-y)copy_page.o \
        fpreg.o \
-       callback_srm.o srm_puts.o srm_printk.o
+       callback_srm.o srm_puts.o srm_printk.o \
+       fls.o
 
 lib-$(CONFIG_SMP) += dec_and_lock.o
 
diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c
new file mode 100644 (file)
index 0000000..7ad84ea
--- /dev/null
@@ -0,0 +1,38 @@
+/* 
+ * arch/alpha/lib/fls.c
+ */
+
+#include <linux/module.h>
+#include <asm/bitops.h>
+
+/* This is fls(x)-1, except zero is held to zero.  This allows most
+   efficent input into extbl, plus it allows easy handling of fls(0)=0.  */
+
+const unsigned char __flsm1_tab[256] = 
+{
+  0,
+  0,
+  1, 1,
+  2, 2, 2, 2,
+  3, 3, 3, 3, 3, 3, 3, 3,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+EXPORT_SYMBOL(__flsm1_tab);
index 2568d311be215a7301bc752f4813a9e64e866999..23348e9561b92070406f4d40a7a5060190561e6e 100644 (file)
@@ -247,7 +247,7 @@ not_relocated:      mov     r0, #0
                mov     r3, r7
                bl      decompress_kernel
 
-               add     r0, r0, #127
+               add     r0, r0, #127 + 128      @ alignment + stack
                bic     r0, r0, #127            @ align the kernel length
 /*
  * r0     = decompressed kernel length
@@ -269,6 +269,7 @@ not_relocated:      mov     r0, #0
                stmia   r1!, {r9 - r14}
                cmp     r2, r3
                blo     1b
+               add     sp, r1, #128            @ relocate the stack
 
                bl      cache_clean_flush
                add     pc, r5, r0              @ call relocation code
@@ -476,6 +477,7 @@ __common_mmu_cache_on:
  */
                .align  5
 reloc_start:   add     r9, r5, r0
+               sub     r9, r9, #128            @ do not copy the stack
                debug_reloc_start
                mov     r1, r4
 1:
@@ -486,6 +488,7 @@ reloc_start:        add     r9, r5, r0
 
                cmp     r5, r9
                blo     1b
+               add     sp, r1, #128            @ relocate the stack
                debug_reloc_end
 
 call_kernel:   bl      cache_clean_flush
index 9179e82203142bec7678ab20051b52590549396a..f73d62e8ab606473b4cc69e4f25775493f3a8af8 100644 (file)
@@ -57,7 +57,7 @@ extern void fp_enter(void);
 #define EXPORT_SYMBOL_ALIAS(sym,orig)          \
  EXPORT_CRC_ALIAS(sym)                         \
  static const struct kernel_symbol __ksymtab_##sym     \
-  __attribute_used__ __attribute__((section("__ksymtab"))) =   \
+  __used __attribute__((section("__ksymtab"))) =       \
     { (unsigned long)&orig, #sym };
 
 /*
index 8b63ad89d0a815c2cde57f138b951bffba33471a..ae31deb2d0653a6a8fe57b000fb2827de9acdf13 100644 (file)
@@ -13,7 +13,7 @@ int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
                /*
                 * Check current frame pointer is within bounds
                 */
-               if ((fp - 12) < low || fp + 4 >= high)
+               if (fp < (low + 12) || fp + 4 >= high)
                        break;
 
                frame = (struct stackframe *)(fp - 12);
index 6043c38c0a9e84b6063d52111cb9c9b2173b8eb6..af497896a96ce761dcb6a45281a7148e1c7e3bd6 100644 (file)
@@ -132,7 +132,7 @@ static struct mtd_partition __initdata dk_nand_partition[] = {
        },
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
        *num_partitions = ARRAY_SIZE(dk_nand_partition);
        return dk_nand_partition;
index 76f6e1e553eaeabc252b1f4e60d9ba86b59101db..7d9b1a278fd63feb961e3ff21466952bae530dd2 100644 (file)
@@ -96,7 +96,7 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = {
        },
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
        *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
        return kb9202_nand_partition;
index 1f0c8a400b3a6c219dc981d9b84fba471559bbd9..26ca8ab3f62a7dc3df8f620178cf2695614ce44e 100644 (file)
@@ -178,7 +178,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
        *num_partitions = ARRAY_SIZE(ek_nand_partition);
        return ek_nand_partition;
index f57458559fb66da229df4273f2aebf56f79739dd..c164c8e58ae6a037cdfbbf4b9b5a9842b9b094e2 100644 (file)
@@ -180,7 +180,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
        *num_partitions = ARRAY_SIZE(ek_nand_partition);
        return ek_nand_partition;
index 30c79aca84d420f2b67eb0da8393ce9c01395d2c..9b61320f295aca158355be2ad7ead7596a2cb385 100644 (file)
@@ -87,7 +87,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
        *num_partitions = ARRAY_SIZE(ek_nand_partition);
        return ek_nand_partition;
index 06c9a0507d0d8316137507979a62d631f2861769..848efb2a4ebfbc14cc7bf9426dadc04ca5c194e1 100644 (file)
@@ -364,19 +364,14 @@ static int at91_clk_show(struct seq_file *s, void *unused)
 {
        u32             scsr, pcsr, sr;
        struct clk      *clk;
-       unsigned        i;
 
        seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
        seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR));
-
        seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
        seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
        seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
        seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
-
        seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
-       for (i = 0; i < 4; i++)
-               seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i)));
        seq_printf(s, "SR   = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
 
        seq_printf(s, "\n");
index ff8db29e989e2f39c420a9de219f63b435ace081..47ff676aca5f07e8155a4380a5f9da99f05546a5 100644 (file)
@@ -76,12 +76,11 @@ static int at91_pm_verify_clocks(void)
                        pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
                        return 0;
                }
-       } else if (cpu_is_at91sam9260()) {
-#warning "Check SAM9260 USB clocks"
-       } else if (cpu_is_at91sam9261()) {
-#warning "Check SAM9261 USB clocks"
-       } else if (cpu_is_at91sam9263()) {
-#warning "Check SAM9263 USB clocks"
+       } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
+               if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
+                       pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+                       return 0;
+               }
        }
 
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
index 4f984fde7375fc867d865bfae26ed53668c93f0c..35eb232a649a2b11aae684fdc169e3cf69fcefd2 100644 (file)
@@ -45,7 +45,7 @@ static struct hw_pci cats_pci __initdata = {
        .postinit               = dc21285_postinit,
 };
 
-static int cats_pci_init(void)
+static int __init cats_pci_init(void)
 {
        if (machine_is_cats())
                pci_common_init(&cats_pci);
index 7a7fa51ec62c11882e8833c94368536e3c77be2d..1c474cf709ca9b4a4241a112fceba2c1560244ea 100644 (file)
@@ -201,7 +201,6 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
 {
        imx_mmc_device.dev.platform_data = info;
 }
-EXPORT_SYMBOL(imx_set_mmc_info);
 
 static struct imxfb_mach_info imx_fb_info;
 
index 0fdd03ab36e6c4cbbcfd7da57a7cb8c4d8684c68..ce7c15c73004e6e9a353abb66f04946cdc660f03 100644 (file)
@@ -164,7 +164,7 @@ int __init ixdp2400_pci_init(void)
 
 subsys_initcall(ixdp2400_pci_init);
 
-void ixdp2400_init_irq(void)
+void __init ixdp2400_init_irq(void)
 {
        ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS);
 }
index 70d247f09a7ecebe5451f4290efdea4c362b0bbb..14f09b80ab77180977da17826c0b8b8170203862 100644 (file)
@@ -279,7 +279,7 @@ int __init ixdp2800_pci_init(void)
 
 subsys_initcall(ixdp2800_pci_init);
 
-void ixdp2800_init_irq(void)
+void __init ixdp2800_init_irq(void)
 {
        ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS);
 }
index 011065b967b45db3080d8e6dfe45d8546853755e..73c651e83d92e5fe98dd2b1ecaa0f7c15c402a2e 100644 (file)
@@ -145,7 +145,7 @@ static struct irq_chip ixdp2x00_cpld_irq_chip = {
        .unmask = ixdp2x00_irq_unmask
 };
 
-void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
 {
        unsigned int irq;
 
index 7a86a2516eaa57e30fc74c7330116fbff53bb02d..c41a6b5a0accbe986eafbbbf50f603c5c203e669 100644 (file)
@@ -124,7 +124,7 @@ static struct irq_chip ixdp2351_intb_chip = {
        .unmask = ixdp2351_intb_unmask
 };
 
-void ixdp2351_init_irq(void)
+void __init ixdp2351_init_irq(void)
 {
        int irq;
 
index ac7d43d23c28f1f35d6dd5abc62adee1dee95e0b..227f808dc0ecc8a52723d1003ed30d9c014907e9 100644 (file)
@@ -284,7 +284,7 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
        return 1;
 }
 
-void ixp23xx_pci_slave_init(void)
+void __init ixp23xx_pci_slave_init(void)
 {
        ixp23xx_pci_common_init();
 }
index d06e21b70de57e4e9c627489a762fd0bf3a543cb..e35644961aa442d9766a168088bee79713bd3151 100644 (file)
@@ -110,7 +110,7 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
        return NO_IRQ;
 }
 
-static void roadrunner_pci_preinit(void)
+static void __init roadrunner_pci_preinit(void)
 {
        set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW);
        set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW);
index 9715ef506c24b363f09164ac2cde59c4acba9e92..060909870b505b582ee4a2ee684cdd9ddd311e67 100644 (file)
@@ -104,9 +104,6 @@ config MACH_DSMG600
          DSM-G600 RevA device. For more information on this platform,
          see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
 
-#
-# Avila and IXDP share the same source for now. Will change in future
-#
 config ARCH_IXDP4XX
        bool
        depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
index 64685da1462d644c35dbc66434f07cdb105a9e23..8112f726ffa0885e2edd505b3a0e17ad5e925b0f 100644 (file)
@@ -283,7 +283,7 @@ static struct irqaction ixp4xx_timer_irq = {
        .handler        = ixp4xx_timer_interrupt,
 };
 
-static void __init ixp4xx_timer_init(void)
+void __init ixp4xx_timer_init(void)
 {
        /* Reset/disable counter */
        *IXP4XX_OSRT1 = 0;
index 7bc94f3def1c8dc8d3b882de548747ced6c99c79..ad2e5b97966ecfbb221d6260489f320c5e64e087 100644 (file)
 
 #include <asm/mach/pci.h>
 
-extern void ixp4xx_pci_preinit(void);
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
-
 void __init coyote_pci_preinit(void)
 {
        set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
index 1caff65e22cc398ce5df87f87c64ea0207418e34..1e75e105c4f7fe4638d6da3d6224b6b79a6a811a 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 static struct flash_platform_data dsmg600_flash_data = {
        .map_name               = "cfi_probe",
@@ -128,6 +129,19 @@ static void dsmg600_power_off(void)
        gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
 }
 
+static void __init dsmg600_timer_init(void)
+{
+    /* The xtal on this machine is non-standard. */
+    ixp4xx_timer_freq = DSMG600_FREQ;
+
+    /* Call standard timer_init function. */
+    ixp4xx_timer_init();
+}
+
+static struct sys_timer dsmg600_timer = {
+    .init   = dsmg600_timer_init,
+};
+
 static void __init dsmg600_init(void)
 {
        ixp4xx_sys_init();
@@ -155,21 +169,13 @@ static void __init dsmg600_init(void)
 #endif
 }
 
-static void __init dsmg600_fixup(struct machine_desc *desc,
-                struct tag *tags, char **cmdline, struct meminfo *mi)
-{
-       /* The xtal on this machine is non-standard. */
-        ixp4xx_timer_freq = DSMG600_FREQ;
-}
-
 MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
        /* Maintainer: www.nslu2-linux.org */
        .phys_io        = IXP4XX_PERIPHERAL_BASE_PHYS,
        .io_pg_offst    = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
        .boot_params    = 0x00000100,
-       .fixup          = dsmg600_fixup,
        .map_io         = ixp4xx_map_io,
        .init_irq       = ixp4xx_init_irq,
-       .timer          = &ixp4xx_timer,
+       .timer          = &dsmg600_timer,
        .init_machine   = dsmg600_init,
 MACHINE_END
index 509a95a692a419b569a8514bc08cb87434f39031..d1e75b7dc3b1a1263ed545c3f3a43dace8037a60 100644 (file)
 
 #include <asm/mach/pci.h>
 
-extern void ixp4xx_pci_preinit(void);
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
-
 void __init ixdpg425_pci_preinit(void)
 {
        set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
index 9a31444d9214e82aea76b803c6bff835ce187829..78a17413ceca702549b1b6a0d7720bef782c6f67 100644 (file)
@@ -155,7 +155,8 @@ static void __init nas100d_init(void)
 
        pm_power_off = nas100d_power_off;
 
-       /* This is only useful on a modified machine, but it is valuable
+       /*
+        * This is only useful on a modified machine, but it is valuable
         * to have it first in order to see debug messages, and so that
         * it does *not* get removed if platform_add_devices fails!
         */
index 162c266e5f8fb8ff3883f4df29ddc69c7f80e3ab..9bf8ccbcaccfd009baa0c07da854e38cbda96010 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 static struct flash_platform_data nslu2_flash_data = {
        .map_name               = "cfi_probe",
@@ -49,26 +50,26 @@ static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
 static struct resource nslu2_led_resources[] = {
        {
                .name           = "ready",  /* green led */
-               .start          = NSLU2_LED_GRN,
-               .end            = NSLU2_LED_GRN,
+               .start          = NSLU2_LED_GRN_GPIO,
+               .end            = NSLU2_LED_GRN_GPIO,
                .flags          = IXP4XX_GPIO_HIGH,
        },
        {
                .name           = "status", /* red led */
-               .start          = NSLU2_LED_RED,
-               .end            = NSLU2_LED_RED,
+               .start          = NSLU2_LED_RED_GPIO,
+               .end            = NSLU2_LED_RED_GPIO,
                .flags          = IXP4XX_GPIO_HIGH,
        },
        {
                .name           = "disk-1",
-               .start          = NSLU2_LED_DISK1,
-               .end            = NSLU2_LED_DISK1,
+               .start          = NSLU2_LED_DISK1_GPIO,
+               .end            = NSLU2_LED_DISK1_GPIO,
                .flags          = IXP4XX_GPIO_LOW,
        },
        {
                .name           = "disk-2",
-               .start          = NSLU2_LED_DISK2,
-               .end            = NSLU2_LED_DISK2,
+               .start          = NSLU2_LED_DISK2_GPIO,
+               .end            = NSLU2_LED_DISK2_GPIO,
                .flags          = IXP4XX_GPIO_LOW,
        },
 };
@@ -157,10 +158,21 @@ static void nslu2_power_off(void)
        gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
 }
 
-static void __init nslu2_init(void)
+static void __init nslu2_timer_init(void)
 {
-       ixp4xx_timer_freq = NSLU2_FREQ;
+    /* The xtal on this machine is non-standard. */
+    ixp4xx_timer_freq = NSLU2_FREQ;
+
+    /* Call standard timer_init function. */
+    ixp4xx_timer_init();
+}
 
+static struct sys_timer nslu2_timer = {
+    .init   = nslu2_timer_init,
+};
+
+static void __init nslu2_init(void)
+{
        ixp4xx_sys_init();
 
        nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
@@ -169,7 +181,8 @@ static void __init nslu2_init(void)
 
        pm_power_off = nslu2_power_off;
 
-       /* This is only useful on a modified machine, but it is valuable
+       /*
+        * This is only useful on a modified machine, but it is valuable
         * to have it first in order to see debug messages, and so that
         * it does *not* get removed if platform_add_devices fails!
         */
@@ -185,6 +198,6 @@ MACHINE_START(NSLU2, "Linksys NSLU2")
        .boot_params    = 0x00000100,
        .map_io         = ixp4xx_map_io,
        .init_irq       = ixp4xx_init_irq,
-       .timer          = &ixp4xx_timer,
+       .timer          = &nslu2_timer,
        .init_machine   = nslu2_init,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h
deleted file mode 100644 (file)
index e985437..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/bast.h
-extern void bast_init_irq(void);
index bc308ceb91c31788c972b97b262dd72f3709f0dd..435adcce6482a369e5898de40bfc4bdfb690a6e1 100644 (file)
@@ -160,7 +160,7 @@ static struct platform_device *amlm5900_devices[] __initdata = {
 #endif
 };
 
-void __init amlm5900_map_io(void)
+static void __init amlm5900_map_io(void)
 {
        s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
        s3c24xx_init_clocks(0);
index c602aa39f9c4080671a6525c4e4cd2ecbde7d475..782b5814ced24411f356a4566c8f19265de3601b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
@@ -29,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+#include <asm/arch/reset.h>
 #include <asm/arch/idle.h>
 
 #include <asm/arch/regs-clock.h>
@@ -38,6 +40,7 @@
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
 #include <asm/arch/regs-spi.h>
+#include <asm/arch/regs-s3c2412.h>
 
 #include <asm/plat-s3c24xx/s3c2412.h>
 #include <asm/plat-s3c24xx/cpu.h>
@@ -106,6 +109,23 @@ static void s3c2412_idle(void)
        cpu_do_idle();
 }
 
+static void s3c2412_hard_reset(void)
+{
+       /* errata "Watch-dog/Software Reset Problem" specifies that
+        * this reset must be done with the SYSCLK sourced from
+        * EXTCLK instead of FOUT to avoid a glitch in the reset
+        * mechanism.
+        *
+        * See the watchdog section of the S3C2412 manual for more
+        * information on this fix.
+        */
+
+       __raw_writel(0x00, S3C2412_CLKSRC);
+       __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
+
+       mdelay(1);
+}
+
 /* s3c2412_map_io
  *
  * register the standard cpu IO areas, and any passed in from the
@@ -122,6 +142,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
 
        s3c24xx_idle = s3c2412_idle;
 
+       /* set custom reset hook */
+
+       s3c24xx_reset_hook = s3c2412_hard_reset;
+
        /* register our io-tables */
 
        iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
index 5955efb5de8d8b4af1032ef739e2ca67c6d2ee82..58402948c47cd6c9a7099ef1ec233577ed18f833 100644 (file)
@@ -394,7 +394,7 @@ static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-struct clk clk_usb_bus_host = {
+static struct clk clk_usb_bus_host = {
        .name           = "usb-bus-host-parent",
        .id             = -1,
        .parent         = &clk_esysclk,
@@ -758,7 +758,6 @@ static struct clk init_clocks[] = {
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_CFC,
-               .ctrlbit        = S3C2443_HCLKCON_HSMMC,
        }, {
                .name           = "ssmc",
                .id             = -1,
index d7c038a0256bf9cfd82d9ea7d2b9f7e1676897a3..4cbf9468f654c970b226262c7e1d4a481436f9c5 100644 (file)
@@ -139,12 +139,12 @@ static u_int neponset_get_mctrl(struct uart_port *port)
        return ret;
 }
 
-static struct sa1100_port_fns neponset_port_fns __initdata = {
+static struct sa1100_port_fns neponset_port_fns __devinitdata = {
        .set_mctrl      = neponset_set_mctrl,
        .get_mctrl      = neponset_get_mctrl,
 };
 
-static int neponset_probe(struct platform_device *dev)
+static int __devinit neponset_probe(struct platform_device *dev)
 {
        sa1100_register_uart_fns(&neponset_port_fns);
 
index 5f472a8b406a554dc0033a6dedba517f8192c247..e7904bc92c73f846abda2b872f3c3e86139c0cfd 100644 (file)
@@ -379,7 +379,7 @@ config CPU_V7
        select CPU_CP15_MMU
        select CPU_HAS_ASID
        select CPU_COPY_V6 if MMU
-       select CPU_TLB_V6 if MMU
+       select CPU_TLB_V7 if MMU
 
 # Figure out what processor architecture version we should be using.
 # This defines the compiler instruction set which depends on the machine type.
@@ -498,6 +498,9 @@ config CPU_TLB_V4WBI
 config CPU_TLB_V6
        bool
 
+config CPU_TLB_V7
+       bool
+
 endif
 
 config CPU_HAS_ASID
index b5bd335ff14aad48f44331c0c17e5462f38d433d..762702765fc3f03d4e3c30ea52cb9cf0b0673793 100644 (file)
@@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_TLB_V4WT)    += tlb-v4.o
 obj-$(CONFIG_CPU_TLB_V4WB)     += tlb-v4wb.o
 obj-$(CONFIG_CPU_TLB_V4WBI)    += tlb-v4wbi.o
 obj-$(CONFIG_CPU_TLB_V6)       += tlb-v6.o
+obj-$(CONFIG_CPU_TLB_V7)       += tlb-v7.o
 
 obj-$(CONFIG_CPU_ARM610)       += proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM710)       += proc-arm6_7.o
index 36440c899583b9131143e9fc30a54fb8b9be70ab..074b7cb0774349d6a51e7c4d210e472a892c4e01 100644 (file)
@@ -630,7 +630,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 
        fs = get_fs();
        set_fs(KERNEL_DS);
-       if thumb_mode(regs) {
+       if (thumb_mode(regs)) {
                fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
                if (!(fault))
                        instr = thumb2arm(tinstr);
index dd823dd4a374545031a11fd890bb8344411b8a14..718f4782ee8b943e14d6a4bb6dc9f515ff9c47b4 100644 (file)
@@ -256,7 +256,7 @@ __v7_proc_info:
        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
        .long   cpu_v7_name
        .long   v7_processor_functions
-       .long   v6wbi_tlb_fns
+       .long   v7wbi_tlb_fns
        .long   v6_user_fns
        .long   v7_cache_fns
        .size   __v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
new file mode 100644 (file)
index 0000000..b56dda8
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  linux/arch/arm/mm/tlb-v7.S
+ *
+ *  Copyright (C) 1997-2002 Russell King
+ *  Modified for ARMv7 by Catalin Marinas
+ *
+ * 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.
+ *
+ *  ARM architecture version 6 TLB handling functions.
+ *  These assume a split I/D TLB.
+ */
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+/*
+ *     v7wbi_flush_user_tlb_range(start, end, vma)
+ *
+ *     Invalidate a range of TLB entries in the specified address space.
+ *
+ *     - start - start address (may not be aligned)
+ *     - end   - end address (exclusive, may not be aligned)
+ *     - vma   - vma_struct describing address range
+ *
+ *     It is assumed that:
+ *     - the "Invalidate single entry" instruction will invalidate
+ *       both the I and the D TLBs on Harvard-style TLBs
+ */
+ENTRY(v7wbi_flush_user_tlb_range)
+       vma_vm_mm r3, r2                        @ get vma->vm_mm
+       mmid    r3, r3                          @ get vm_mm->context.id
+       dsb
+       mov     r0, r0, lsr #PAGE_SHIFT         @ align address
+       mov     r1, r1, lsr #PAGE_SHIFT
+       asid    r3, r3                          @ mask ASID
+       orr     r0, r3, r0, lsl #PAGE_SHIFT     @ Create initial MVA
+       mov     r1, r1, lsl #PAGE_SHIFT
+       vma_vm_flags r2, r2                     @ get vma->vm_flags
+1:
+       mcr     p15, 0, r0, c8, c6, 1           @ TLB invalidate D MVA (was 1)
+       tst     r2, #VM_EXEC                    @ Executable area ?
+       mcrne   p15, 0, r0, c8, c5, 1           @ TLB invalidate I MVA (was 1)
+       add     r0, r0, #PAGE_SZ
+       cmp     r0, r1
+       blo     1b
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c5, 6           @ flush BTAC/BTB
+       dsb
+       mov     pc, lr
+
+/*
+ *     v7wbi_flush_kern_tlb_range(start,end)
+ *
+ *     Invalidate a range of kernel TLB entries
+ *
+ *     - start - start address (may not be aligned)
+ *     - end   - end address (exclusive, may not be aligned)
+ */
+ENTRY(v7wbi_flush_kern_tlb_range)
+       dsb
+       mov     r0, r0, lsr #PAGE_SHIFT         @ align address
+       mov     r1, r1, lsr #PAGE_SHIFT
+       mov     r0, r0, lsl #PAGE_SHIFT
+       mov     r1, r1, lsl #PAGE_SHIFT
+1:
+       mcr     p15, 0, r0, c8, c6, 1           @ TLB invalidate D MVA
+       mcr     p15, 0, r0, c8, c5, 1           @ TLB invalidate I MVA
+       add     r0, r0, #PAGE_SZ
+       cmp     r0, r1
+       blo     1b
+       mov     r2, #0
+       mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
+       dsb
+       isb
+       mov     pc, lr
+
+       .section ".text.init", #alloc, #execinstr
+
+       .type   v7wbi_tlb_fns, #object
+ENTRY(v7wbi_tlb_fns)
+       .long   v7wbi_flush_user_tlb_range
+       .long   v7wbi_flush_kern_tlb_range
+       .long   v6wbi_tlb_flags
+       .size   v7wbi_tlb_fns, . - v7wbi_tlb_fns
index 0a3067452cd29767544cc4b3198d7eabc0a32b7c..260fe29d73f576d4e6d8df64420c3ed8eb8f283f 100644 (file)
@@ -273,4 +273,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b)
 extern flag float32_is_nan( float32 a );
 extern flag float64_is_nan( float64 a );
 
+extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
+extern int32 float64_to_uint32_round_to_zero( float64 a );
+
 #endif
index 898500718249dc59da11a9b76359c0e72481c3a0..75bae067922d1c55fdef728f67e8f952062009be 100644 (file)
@@ -200,8 +200,10 @@ static int em_call_function(int (*fn)(void))
        data.fn = fn;
        data.ret = 0;
 
+       preempt_disable();
        smp_call_function(em_func, &data, 1, 1);
        em_func(&data);
+       preempt_enable();
 
        return data.ret;
 }
@@ -257,8 +259,13 @@ static void em_stop(void)
  */
 static void em_route_irq(int irq, unsigned int cpu)
 {
-       irq_desc[irq].affinity = cpumask_of_cpu(cpu);
-       irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu));
+       struct irq_desc *desc = irq_desc + irq;
+       cpumask_t mask = cpumask_of_cpu(cpu);
+
+       spin_lock_irq(&desc->lock);
+       desc->affinity = mask;
+       desc->chip->set_affinity(irq, mask);
+       spin_unlock_irq(&desc->lock);
 }
 
 static int em_setup(void)
index 11ba75a05220bc7cfefe8febcbfd19b7c29b9315..de7688cfd573e6f73373b754efc1aecbcdf5571c 100644 (file)
@@ -288,9 +288,9 @@ asmlinkage void syscall_print(void *dummy,...)
 int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
        register long res __asm__("er0");
+       register char *const *_c __asm__("er3") = envp;
+       register char *const *_b __asm__("er2") = argv;
        register const char * _a __asm__("er1") = filename;
-       register void *_b __asm__("er2") = argv;
-       register void *_c __asm__("er3") = envp;
        __asm__ __volatile__ ("mov.l %1,er0\n\t"
                        "trapa  #0\n\t"
                        : "=r" (res)
index 300e3279ca5abb5b25c3afab13fd8748dba41382..f97183011c2cb501ccf6cb07de9d12a87e00d93a 100644 (file)
@@ -136,7 +136,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
        printk("\nCall Trace:");
        i = 0;
        stack = esp;
-       while (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) {
+       while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) {
                addr = *stack++;
                /*
                 * If the address is either in the text segment of the
index c2d54b80223287174d3cabee4ddd932f4355e401..8770a5d0b1433fbad255d0de00bb8b21fecfb592 100644 (file)
@@ -891,7 +891,7 @@ config PHYSICAL_ALIGN
          Don't change this unless you know what you are doing.
 
 config HOTPLUG_CPU
-       bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+       bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
        depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
        ---help---
          Say Y here to experiment with turning CPUs off and on, and to
index 1cf466df330ad567c26355aeda582b98196534ae..7202b98aac4f2f53516e421ef935545538e5466a 100644 (file)
@@ -734,10 +734,13 @@ void mtrr_ap_init(void)
  */
 void mtrr_save_state(void)
 {
-       if (smp_processor_id() == 0)
+       int cpu = get_cpu();
+
+       if (cpu == 0)
                mtrr_save_fixed_ranges(NULL);
        else
                smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1);
+       put_cpu();
 }
 
 static int __init mtrr_init_finialize(void)
index 83f825f2e2d7db0ee5b5a002d78792219fb64b8f..d865d041bea1dc7c25d9a8e1eaa63f54c6812ea0 100644 (file)
@@ -478,7 +478,7 @@ static int __init microcode_dev_init (void)
        return 0;
 }
 
-static void __exit microcode_dev_exit (void)
+static void microcode_dev_exit (void)
 {
        misc_deregister(&microcode_dev);
 }
index 50dfc65319cda0392ae1c79152d148b694fa7c86..5513f8d5b5becff34c9e77cceb77835aeb90b0ec 100644 (file)
@@ -89,6 +89,14 @@ static int __init set_bios_reboot(struct dmi_system_id *d)
 }
 
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
+       {       /* Handle problems with rebooting on Dell E520's */
+               .callback = set_bios_reboot,
+               .ident = "Dell E520",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"),
+               },
+       },
        {       /* Handle problems with rebooting on Dell 1300's */
                .callback = set_bios_reboot,
                .ident = "Dell PowerEdge 1300",
index 08f07a74a9d3753184ab7a3096697eaac4d2cb98..88baed1e7e83a1469ecc33f1ed5e6e1c17a00af4 100644 (file)
@@ -943,10 +943,9 @@ exit:
 
 static void smp_tune_scheduling(void)
 {
-       unsigned long cachesize;       /* kB   */
-
        if (cpu_khz) {
-               cachesize = boot_cpu_data.x86_cache_size;
+               /* cache size in kB */
+               long cachesize = boot_cpu_data.x86_cache_size;
 
                if (cachesize > 0)
                        max_cache_size = cachesize * 1024;
index c8726c424b3549a2b45aaa839dc21a3d464769ba..c12720d7cbc50b8b0bc0804ba19df993128a574d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/bootmem.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/sched.h>
 #include <asm/vmi.h>
 #include <asm/io.h>
 #include <asm/fixmap.h>
index e932d3485ae2526a91c4122e49b3ae59e6aeaf9d..58a477baec30b575e94300f82210c938e80ef970 100644 (file)
@@ -21,7 +21,7 @@
 
 static int dmi_bigsmp; /* can be set by dmi scanners */
 
-static __init int hp_ht_bigsmp(struct dmi_system_id *d)
+static int hp_ht_bigsmp(struct dmi_system_id *d)
 {
 #ifdef CONFIG_X86_GENERICARCH
        printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
@@ -31,7 +31,7 @@ static __init int hp_ht_bigsmp(struct dmi_system_id *d)
 }
 
 
-static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
+static struct dmi_system_id bigsmp_dmi_table[] = {
        { hp_ht_bigsmp, "HP ProLiant DL760 G2", {
                DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
                DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
@@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
 };
 
 
-static int __init probe_bigsmp(void)
+static int probe_bigsmp(void)
 { 
        if (def_to_bigsmp)
                dmi_bigsmp = 1;
index ddf8fa3bbd01d7c15ef03abf6c7c55c5356ebd57..1853524c8b576f5420de5cbd746aecb30f594d50 100644 (file)
@@ -754,7 +754,7 @@ int save_i387_soft(void *s387, struct _fpstate __user * buf)
     return -1;
   if ( offset )
     if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset))
-      return -1
+      return -1;
   RE_ENTRANT_CHECK_ON;
 
   return 1;
index 29d7d61543a1dec88f2e2a1c348e5a696c1e70d2..1ecb3e43b523387388a99e2ed7cccdf0a7cdd131 100644 (file)
@@ -458,6 +458,11 @@ bad_area:
 bad_area_nosemaphore:
        /* User mode accesses just cause a SIGSEGV */
        if (error_code & 4) {
+               /*
+                * It's possible to have interrupts off here.
+                */
+               local_irq_enable();
+
                /* 
                 * Valid to do another page fault here because this one came 
                 * from user space.
index a7c0783b269a5ecaf9d74feaa4d8b8350291a7df..11b7a51566a8cb4715dc606bf82534e374a210c8 100644 (file)
@@ -154,7 +154,7 @@ static int allocate_msrs(void)
        size_t counters_size = sizeof(struct op_msr) * model->num_counters;
 
        int i;
-       for_each_online_cpu(i) {
+       for_each_possible_cpu(i) {
                cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
                if (!cpu_msrs[i].counters) {
                        success = 0;
@@ -211,8 +211,14 @@ static int nmi_setup(void)
        /* Assume saved/restored counters are the same on all CPUs */
        model->fill_in_addresses(&cpu_msrs[0]);
        for_each_possible_cpu (cpu) {
-               if (cpu != 0)
-                       cpu_msrs[cpu] = cpu_msrs[0];
+               if (cpu != 0) {
+                       memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters,
+                               sizeof(struct op_msr) * model->num_counters);
+
+                       memcpy(cpu_msrs[cpu].controls, cpu_msrs[0].controls,
+                               sizeof(struct op_msr) * model->num_controls);
+               }
+
        }
        on_each_cpu(nmi_save_registers, NULL, 0, 1);
        on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
index b62eafb997bce2b1bf4dcd379ef06ca954bceae7..b95b42950ed447d2774fe2aac9e6e66830d91960 100644 (file)
@@ -436,3 +436,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
                        pci_early_fixup_cyrix_5530);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
                        pci_early_fixup_cyrix_5530);
+
+/*
+ * Siemens Nixdorf AG FSC Multiprocessor Interrupt Controller:
+ * prevent update of the BAR0, which doesn't look like a normal BAR.
+ */
+static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev)
+{
+       dev->resource[0].flags |= IORESOURCE_PCI_FIXED;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
+                         pci_siemens_interrupt_controller);
index 4d4993a47e559fe6aa27c06f45182e8478338300..5a216c019924ff22fbce7da38aaebea97da7c732 100644 (file)
@@ -44,7 +44,7 @@ static void init_intel_pdc(struct acpi_processor *pr)
 
        buf[0] = ACPI_PDC_REVISION_ID;
        buf[1] = 1;
-       buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+       buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
 
        obj->type = ACPI_TYPE_BUFFER;
        obj->buffer.length = 12;
index c4784494970e5ed0ebf54d67bffbbedf5c31783a..103dd8edda71bc161762b810b8d792a2079570bf 100644 (file)
@@ -67,7 +67,8 @@ EXPORT_SYMBOL(pm_power_off);
 unsigned int acpi_cpei_override;
 unsigned int acpi_cpei_phys_cpuid;
 
-const char *acpi_get_sysname(void)
+const char __init *
+acpi_get_sysname(void)
 {
 #ifdef CONFIG_IA64_GENERIC
        unsigned long rsdp_phys;
index 542958079f1b1eb4b0da70f0dc0beeca8260257e..3c9d8e6089cf9b5134bca8e86610dfe810891415 100644 (file)
@@ -370,7 +370,7 @@ smp_setup_percpu_timer (void)
 {
 }
 
-static void __devinit
+static void __cpuinit
 smp_callin (void)
 {
        int cpuid, phys_id, itc_master;
@@ -456,7 +456,7 @@ smp_callin (void)
 /*
  * Activate a secondary processor.  head.S calls this.
  */
-int __devinit
+int __cpuinit
 start_secondary (void *unused)
 {
        /* Early console may use I/O ports */
index b8536c7c0877577541f1a7ab0b977f29a44b82b0..85cdd23b0447e2dafd1ed517a2a2cd66910da365 100644 (file)
@@ -355,8 +355,9 @@ config RMW_INSNS
          adventurous.
 
 config SINGLE_MEMORY_CHUNK
-       bool "Use one physical chunk of memory only"
-       depends on ADVANCED && !SUN3
+       bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
+       default y if SUN3
+       select NEED_MULTIPLE_NODES
        help
          Ignore all but the first contiguous chunk of physical memory for VM
          purposes.  This will save a few bytes kernel size and may speed up
@@ -377,6 +378,14 @@ config 060_WRITETHROUGH
          is hardwired on.  The 53c710 SCSI driver is known to suffer from
          this problem.
 
+config ARCH_DISCONTIGMEM_ENABLE
+       def_bool !SINGLE_MEMORY_CHUNK
+
+config NODES_SHIFT
+       int
+       default "3"
+       depends on !SINGLE_MEMORY_CHUNK
+
 source "mm/Kconfig"
 
 endmenu
index c20831a7e1a9e1a064261ab861d5ea960ea322a9..aa383a5ea7acbcd34191e77867a3f969c5635c48 100644 (file)
@@ -19,6 +19,7 @@ COMPILE_ARCH = $(shell uname -m)
 # override top level makefile
 AS += -m68020
 LDFLAGS := -m m68kelf
+LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
 ifneq ($(COMPILE_ARCH),$(ARCH))
        # prefix for cross-compiling binaries
        CROSS_COMPILE = m68k-linux-gnu-
index 0b68ab8d63d1d5a120f9e4403b317ecdbfd71308..a806208c7fb5fadea24701d9d7b4dab68582aee6 100644 (file)
@@ -9,13 +9,12 @@ else
 endif
 extra-y        += vmlinux.lds
 
-obj-y  := entry.o process.o traps.o ints.o signal.o ptrace.o \
+obj-y  := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
           sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o
 
 devres-y = ../../../kernel/irq/devres.o
 
 obj-$(CONFIG_PCI)      += bios32.o
-obj-$(CONFIG_MODULES)  += module.o
 obj-y$(CONFIG_MMU_SUN3) += dma.o       # no, it's not a typo
 
 EXTRA_AFLAGS := -traditional
index 3b1a2ff61ddcf18846fc108859e964a6d28110fd..774862bc6977297c0099c4bdfa96980820dcf1df 100644 (file)
@@ -1,3 +1,9 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
@@ -11,6 +17,8 @@
 #define DEBUGP(fmt...)
 #endif
 
+#ifdef CONFIG_MODULES
+
 void *module_alloc(unsigned long size)
 {
        if (size == 0)
@@ -118,11 +126,32 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
 
 int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
-                   struct module *me)
+                   struct module *mod)
 {
+       module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
+
        return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 }
+
+#endif /* CONFIG_MODULES */
+
+void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+                 struct m68k_fixup_info *end)
+{
+       struct m68k_fixup_info *fixup;
+
+       for (fixup = start; fixup < end; fixup++) {
+               switch (fixup->type) {
+               case m68k_fixup_memoffset:
+                       *(u32 *)fixup->addr = m68k_memoffset;
+                       break;
+               case m68k_fixup_vnode_shift:
+                       *(u16 *)fixup->addr += m68k_virt_to_node_shift;
+                       break;
+               }
+       }
+}
diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/kernel/module.lds
new file mode 100644 (file)
index 0000000..fda94fa
--- /dev/null
@@ -0,0 +1,7 @@
+SECTIONS {
+       .m68k_fixup : {
+               __start_fixup = .;
+               *(.m68k_fixup)
+               __stop_fixup = .;
+       }
+}
index 610319356691d2fda4d8796cbcdffa3b9e18b3e7..215c7bd43924f43a21ce8b55d90ef3acc54e6da2 100644 (file)
@@ -60,14 +60,12 @@ extern unsigned long availmem;
 int m68k_num_memory;
 int m68k_realnum_memory;
 EXPORT_SYMBOL(m68k_realnum_memory);
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long m68k_memoffset;
 EXPORT_SYMBOL(m68k_memoffset);
-#endif
 struct mem_info m68k_memory[NUM_MEMINFO];
 EXPORT_SYMBOL(m68k_memory);
 
-static struct mem_info m68k_ramdisk;
+struct mem_info m68k_ramdisk;
 
 static char m68k_command_line[CL_SIZE];
 
@@ -208,9 +206,6 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
 void __init setup_arch(char **cmdline_p)
 {
        extern int _etext, _edata, _end;
-#ifndef CONFIG_SUN3
-       unsigned long endmem, startmem;
-#endif
        int i;
 
        /* The bootinfo is located right after the kernel bss */
@@ -320,30 +315,16 @@ void __init setup_arch(char **cmdline_p)
                panic("No configuration setup");
        }
 
-#ifndef CONFIG_SUN3
-       startmem= m68k_memory[0].addr;
-       endmem = startmem + m68k_memory[0].size;
-       high_memory = (void *)PAGE_OFFSET;
-       for (i = 0; i < m68k_num_memory; i++) {
-               m68k_memory[i].size &= MASK_256K;
-               if (m68k_memory[i].addr < startmem)
-                       startmem = m68k_memory[i].addr;
-               if (m68k_memory[i].addr+m68k_memory[i].size > endmem)
-                       endmem = m68k_memory[i].addr+m68k_memory[i].size;
-               high_memory += m68k_memory[i].size;
-       }
-
-       availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT,
-                                     startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT);
-
-       for (i = 0; i < m68k_num_memory; i++)
-               free_bootmem(m68k_memory[i].addr, m68k_memory[i].size);
-
-       reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
+       paging_init();
 
+#ifndef CONFIG_SUN3
+       for (i = 1; i < m68k_num_memory; i++)
+               free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
+                                 m68k_memory[i].size);
 #ifdef CONFIG_BLK_DEV_INITRD
        if (m68k_ramdisk.size) {
-               reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size);
+               reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
+                                    m68k_ramdisk.addr, m68k_ramdisk.size);
                initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
                initrd_end = initrd_start + m68k_ramdisk.size;
                printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
@@ -362,8 +343,6 @@ void __init setup_arch(char **cmdline_p)
 
 #endif /* !CONFIG_SUN3 */
 
-       paging_init();
-
 /* set ISA defs early as possible */
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
 #if defined(CONFIG_Q40)
index 78f139226a1ba1dee2fce98e7c1e7a7ee2e3af3c..40f02b128f22bb3a62ebce9d66349f3f78dc7fdc 100644 (file)
@@ -60,6 +60,11 @@ SECTIONS
   __con_initcall_start = .;
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
+  .m68k_fixup : {
+       __start_fixup = .;
+       *(.m68k_fixup)
+       __stop_fixup = .;
+  }
   SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(8192);
index c8999b2db23b01f86f0aff8d269b78894147f623..f06425b6d20643a9fc32d74bfdc5af6c3487a394 100644 (file)
@@ -54,6 +54,11 @@ __init_begin = .;
        __con_initcall_start = .;
        .con_initcall.init : { *(.con_initcall.init) }
        __con_initcall_end = .;
+       .m68k_fixup : {
+               __start_fixup = .;
+               *(.m68k_fixup)
+               __stop_fixup = .;
+       }
        SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
        . = ALIGN(8192);
index 7a5bed5bdc574d11a29daaa65a859655a2ede48f..e8a57138b4a6e54980247110f56c7310a32dad4f 100644 (file)
@@ -71,7 +71,7 @@ void mac_debugging_short(int pos, short num)
 
        /* calculate current offset */
        pengoffset = (unsigned char *)mac_videobase +
-               (150+line*2) * mac_rowbytes) + 80 * peng;
+               (150+line*2) * mac_rowbytes + 80 * peng;
 
        pptr = pengoffset;
 
index ab90213e5c54030bb1872b68e3342c31c0fb40b7..f1de19e1dde66f50317db6f7a40992fdba481f2f 100644 (file)
@@ -7,6 +7,7 @@
  *  to motorola.c and sun3mmu.c
  */
 
+#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
+static bootmem_data_t __initdata bootmem_data[MAX_NUMNODES];
+
+pg_data_t pg_data_map[MAX_NUMNODES];
+EXPORT_SYMBOL(pg_data_map);
+
+int m68k_virt_to_node_shift;
+
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+pg_data_t *pg_data_table[65];
+EXPORT_SYMBOL(pg_data_table);
+#endif
+
+void m68k_setup_node(int node)
+{
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+       struct mem_info *info = m68k_memory + node;
+       int i, end;
+
+       i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();
+       end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();
+       for (; i <= end; i++) {
+               if (pg_data_table[i])
+                       printk("overlap at %u for chunk %u\n", i, node);
+               pg_data_table[i] = pg_data_map + node;
+       }
+#endif
+       pg_data_map[node].bdata = bootmem_data + node;
+       node_set_online(node);
+}
+
+
 /*
  * ZERO_PAGE is a special page that is used for zero-initialized
  * data and COW.
@@ -40,52 +72,51 @@ void *empty_zero_page;
 
 void show_mem(void)
 {
-    unsigned long i;
-    int free = 0, total = 0, reserved = 0, shared = 0;
-    int cached = 0;
-
-    printk("\nMem-info:\n");
-    show_free_areas();
-    printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-    i = max_mapnr;
-    while (i-- > 0) {
-       total++;
-       if (PageReserved(mem_map+i))
-           reserved++;
-       else if (PageSwapCache(mem_map+i))
-           cached++;
-       else if (!page_count(mem_map+i))
-           free++;
-       else
-           shared += page_count(mem_map+i) - 1;
-    }
-    printk("%d pages of RAM\n",total);
-    printk("%d free pages\n",free);
-    printk("%d reserved pages\n",reserved);
-    printk("%d pages shared\n",shared);
-    printk("%d pages swap cached\n",cached);
+       pg_data_t *pgdat;
+       int free = 0, total = 0, reserved = 0, shared = 0;
+       int cached = 0;
+       int i;
+
+       printk("\nMem-info:\n");
+       show_free_areas();
+       printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+       for_each_online_pgdat(pgdat) {
+               for (i = 0; i < pgdat->node_spanned_pages; i++) {
+                       struct page *page = pgdat->node_mem_map + i;
+                       total++;
+                       if (PageReserved(page))
+                               reserved++;
+                       else if (PageSwapCache(page))
+                               cached++;
+                       else if (!page_count(page))
+                               free++;
+                       else
+                               shared += page_count(page) - 1;
+               }
+       }
+       printk("%d pages of RAM\n",total);
+       printk("%d free pages\n",free);
+       printk("%d reserved pages\n",reserved);
+       printk("%d pages shared\n",shared);
+       printk("%d pages swap cached\n",cached);
 }
 
 extern void init_pointer_table(unsigned long ptable);
 
 /* References to section boundaries */
 
-extern char _text, _etext, _edata, __bss_start, _end;
-extern char __init_begin, __init_end;
+extern char _text[], _etext[];
+extern char __init_begin[], __init_end[];
 
 extern pmd_t *zero_pgtable;
 
 void __init mem_init(void)
 {
+       pg_data_t *pgdat;
        int codepages = 0;
        int datapages = 0;
        int initpages = 0;
-       unsigned long tmp;
-#ifndef CONFIG_SUN3
        int i;
-#endif
-
-       max_mapnr = num_physpages = (((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT);
 
 #ifdef CONFIG_ATARI
        if (MACH_IS_ATARI)
@@ -93,19 +124,25 @@ void __init mem_init(void)
 #endif
 
        /* this will put all memory onto the freelists */
-       totalram_pages = free_all_bootmem();
-
-       for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) {
-               if (PageReserved(virt_to_page(tmp))) {
-                       if (tmp >= (unsigned long)&_text
-                           && tmp < (unsigned long)&_etext)
+       totalram_pages = num_physpages = 0;
+       for_each_online_pgdat(pgdat) {
+               num_physpages += pgdat->node_present_pages;
+
+               totalram_pages += free_all_bootmem_node(pgdat);
+               for (i = 0; i < pgdat->node_spanned_pages; i++) {
+                       struct page *page = pgdat->node_mem_map + i;
+                       char *addr = page_to_virt(page);
+
+                       if (!PageReserved(page))
+                               continue;
+                       if (addr >= _text &&
+                           addr < _etext)
                                codepages++;
-                       else if (tmp >= (unsigned long) &__init_begin
-                                && tmp < (unsigned long) &__init_end)
+                       else if (addr >= __init_begin &&
+                                addr < __init_end)
                                initpages++;
                        else
                                datapages++;
-                       continue;
                }
        }
 
@@ -124,7 +161,7 @@ void __init mem_init(void)
 
        printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
               (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
-              max_mapnr << (PAGE_SHIFT-10),
+              totalram_pages << (PAGE_SHIFT-10),
               codepages << (PAGE_SHIFT-10),
               datapages << (PAGE_SHIFT-10),
               initpages << (PAGE_SHIFT-10));
index 13c0b4ad01eb5977384b333a7f761303bfa1b56c..b7473525b43179fa9066d3a1d978120f1caac164 100644 (file)
@@ -127,67 +127,6 @@ int free_pointer_table (pmd_t *ptable)
        return 0;
 }
 
-#ifdef DEBUG_INVALID_PTOV
-int mm_inv_cnt = 5;
-#endif
-
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * The following two routines map from a physical address to a kernel
- * virtual address and vice versa.
- */
-unsigned long mm_vtop(unsigned long vaddr)
-{
-       int i=0;
-       unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
-
-       do {
-               if (voff < m68k_memory[i].size) {
-#ifdef DEBUGPV
-                       printk ("VTOP(%p)=%lx\n", vaddr,
-                               m68k_memory[i].addr + voff);
-#endif
-                       return m68k_memory[i].addr + voff;
-               }
-               voff -= m68k_memory[i].size;
-       } while (++i < m68k_num_memory);
-
-       /* As a special case allow `__pa(high_memory)'.  */
-       if (voff == 0)
-               return m68k_memory[i-1].addr + m68k_memory[i-1].size;
-
-       return -1;
-}
-EXPORT_SYMBOL(mm_vtop);
-
-unsigned long mm_ptov (unsigned long paddr)
-{
-       int i = 0;
-       unsigned long poff, voff = PAGE_OFFSET;
-
-       do {
-               poff = paddr - m68k_memory[i].addr;
-               if (poff < m68k_memory[i].size) {
-#ifdef DEBUGPV
-                       printk ("PTOV(%lx)=%lx\n", paddr, poff + voff);
-#endif
-                       return poff + voff;
-               }
-               voff += m68k_memory[i].size;
-       } while (++i < m68k_num_memory);
-
-#ifdef DEBUG_INVALID_PTOV
-       if (mm_inv_cnt > 0) {
-               mm_inv_cnt--;
-               printk("Invalid use of phys_to_virt(0x%lx) at 0x%p!\n",
-                       paddr, __builtin_return_address(0));
-       }
-#endif
-       return -1;
-}
-EXPORT_SYMBOL(mm_ptov);
-#endif
-
 /* invalidate page in both caches */
 static inline void clear040(unsigned long paddr)
 {
@@ -354,15 +293,3 @@ void cache_push (unsigned long paddr, int len)
 }
 EXPORT_SYMBOL(cache_push);
 
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
-int mm_end_of_chunk (unsigned long addr, int len)
-{
-       int i;
-
-       for (i = 0; i < m68k_num_memory; i++)
-               if (m68k_memory[i].addr + m68k_memory[i].size == addr + len)
-                       return 1;
-       return 0;
-}
-EXPORT_SYMBOL(mm_end_of_chunk);
-#endif
index afcccdc6ad45db38b9b656b08cd5e5e7f3a2e95d..7d571a2b44dd0bd2d61e6d3dcc9239146fe5d4c4 100644 (file)
@@ -43,6 +43,11 @@ unsigned long mm_cachebits;
 EXPORT_SYMBOL(mm_cachebits);
 #endif
 
+/* size of memory already mapped in head.S */
+#define INIT_MAPPED_SIZE       (4UL<<20)
+
+extern unsigned long availmem;
+
 static pte_t * __init kernel_page_table(void)
 {
        pte_t *ptablep;
@@ -98,19 +103,20 @@ static pmd_t * __init kernel_ptr_table(void)
        return last_pgtable;
 }
 
-static unsigned long __init
-map_chunk (unsigned long addr, long size)
+static void __init map_node(int node)
 {
 #define PTRTREESIZE (256*1024)
 #define ROOTTREESIZE (32*1024*1024)
-       static unsigned long virtaddr = PAGE_OFFSET;
-       unsigned long physaddr;
+       unsigned long physaddr, virtaddr, size;
        pgd_t *pgd_dir;
        pmd_t *pmd_dir;
        pte_t *pte_dir;
 
-       physaddr = (addr | m68k_supervisor_cachemode |
-                   _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+       size = m68k_memory[node].size;
+       physaddr = m68k_memory[node].addr;
+       virtaddr = (unsigned long)phys_to_virt(physaddr);
+       physaddr |= m68k_supervisor_cachemode |
+                   _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY;
        if (CPU_IS_040_OR_060)
                physaddr |= _PAGE_GLOBAL040;
 
@@ -190,8 +196,6 @@ map_chunk (unsigned long addr, long size)
 #ifdef DEBUG
        printk("\n");
 #endif
-
-       return virtaddr;
 }
 
 /*
@@ -200,15 +204,16 @@ map_chunk (unsigned long addr, long size)
  */
 void __init paging_init(void)
 {
-       int chunk;
-       unsigned long mem_avail = 0;
        unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+       unsigned long min_addr, max_addr;
+       unsigned long addr, size, end;
+       int i;
 
 #ifdef DEBUG
        {
                extern unsigned long availmem;
-               printk ("start of paging_init (%p, %lx, %lx, %lx)\n",
-                       kernel_pg_dir, availmem, start_mem, end_mem);
+               printk ("start of paging_init (%p, %lx)\n",
+                       kernel_pg_dir, availmem);
        }
 #endif
 
@@ -222,24 +227,62 @@ void __init paging_init(void)
                        pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
        }
 
+       min_addr = m68k_memory[0].addr;
+       max_addr = min_addr + m68k_memory[0].size;
+       for (i = 1; i < m68k_num_memory;) {
+               if (m68k_memory[i].addr < min_addr) {
+                       printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
+                               m68k_memory[i].addr, m68k_memory[i].size);
+                       printk("Fix your bootloader or use a memfile to make use of this area!\n");
+                       m68k_num_memory--;
+                       memmove(m68k_memory + i, m68k_memory + i + 1,
+                               (m68k_num_memory - i) * sizeof(struct mem_info));
+                       continue;
+               }
+               addr = m68k_memory[i].addr + m68k_memory[i].size;
+               if (addr > max_addr)
+                       max_addr = addr;
+               i++;
+       }
+       m68k_memoffset = min_addr - PAGE_OFFSET;
+       m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
+
+       module_fixup(NULL, __start_fixup, __stop_fixup);
+       flush_icache();
+
+       high_memory = phys_to_virt(max_addr);
+
+       min_low_pfn = availmem >> PAGE_SHIFT;
+       max_low_pfn = max_addr >> PAGE_SHIFT;
+
+       for (i = 0; i < m68k_num_memory; i++) {
+               addr = m68k_memory[i].addr;
+               end = addr + m68k_memory[i].size;
+               m68k_setup_node(i);
+               availmem = PAGE_ALIGN(availmem);
+               availmem += init_bootmem_node(NODE_DATA(i),
+                                             availmem >> PAGE_SHIFT,
+                                             addr >> PAGE_SHIFT,
+                                             end >> PAGE_SHIFT);
+       }
+
        /*
         * Map the physical memory available into the kernel virtual
-        * address space.  It may allocate some memory for page
-        * tables and thus modify availmem.
+        * address space. First initialize the bootmem allocator with
+        * the memory we already mapped, so map_node() has something
+        * to allocate.
         */
+       addr = m68k_memory[0].addr;
+       size = m68k_memory[0].size;
+       free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr));
+       map_node(0);
+       if (size > INIT_MAPPED_SIZE)
+               free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE);
 
-       for (chunk = 0; chunk < m68k_num_memory; chunk++) {
-               mem_avail = map_chunk (m68k_memory[chunk].addr,
-                                      m68k_memory[chunk].size);
-
-       }
+       for (i = 1; i < m68k_num_memory; i++)
+               map_node(i);
 
        flush_tlb_all();
-#ifdef DEBUG
-       printk ("memory available is %ldKB\n", mem_avail >> 10);
-       printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
-               start_mem, end_mem);
-#endif
 
        /*
         * initialize the bad page table and bad page to point
@@ -256,14 +299,11 @@ void __init paging_init(void)
 #ifdef DEBUG
        printk ("before free_area_init\n");
 #endif
-       zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ?
-                               (mach_max_dma_address+1) : (unsigned long)high_memory);
-       zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0];
-
-       zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT;
-       zones_size[ZONE_NORMAL] >>= PAGE_SHIFT;
-
-       free_area_init(zones_size);
+       for (i = 0; i < m68k_num_memory; i++) {
+               zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
+               free_area_init_node(i, pg_data_map + i, zones_size,
+                                   m68k_memory[i].addr >> PAGE_SHIFT, NULL);
+       }
 }
 
 extern char __init_begin, __init_end;
index 4851b8437a87f69d1d6ab9659d534819d367aca7..c0fbd278fbb151e30821a66bb25b4c902f2573ee 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/contregs.h>
 #include <asm/movs.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/sun3-head.h>
 #include <asm/sun3mmu.h>
 #include <asm/rtc.h>
@@ -127,6 +128,7 @@ void __init sun3_bootmem_alloc(unsigned long memory_start, unsigned long memory_
        high_memory = (void *)memory_end;
        availmem = memory_start;
 
+       m68k_setup_node(0);
        availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
        availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
 
index 92e58070b01664f31d10625b02822ddc2ede3bff..fb66eadd589633cf02ecc9e9f89dffe395a808ef 100644 (file)
@@ -62,10 +62,13 @@ void coldfire_tick(void)
 
 /***************************************************************************/
 
+static int ticks_per_intr;
+
 void coldfire_timer_init(irq_handler_t handler)
 {
        __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
-       __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR));
+       ticks_per_intr = (MCF_BUSCLK / 16) / HZ;
+       __raw_writetrr(ticks_per_intr - 1, TA(MCFTIMER_TRR));
        __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
                MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
 
@@ -81,11 +84,10 @@ void coldfire_timer_init(irq_handler_t handler)
 
 unsigned long coldfire_timer_offset(void)
 {
-       unsigned long trr, tcn, offset;
+       unsigned long tcn, offset;
 
        tcn = __raw_readw(TA(MCFTIMER_TCN));
-       trr = __raw_readtrr(TA(MCFTIMER_TRR));
-       offset = (tcn * (1000000 / HZ)) / trr;
+       offset = ((tcn + 1) * (1000000 / HZ)) / ticks_per_intr;
 
        /* Check if we just wrapped the counters and maybe missed a tick */
        if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1))
index 0f09412e1b7f249629166b5dce4d4f95cc59fd76..9528ee90640acc9ac99923f454e9db262405fc27 100644 (file)
@@ -747,9 +747,9 @@ config EARLY_PRINTK
          to print messages very early in the bootup process.
 
          This is useful for kernel debugging when your machine crashes very
-         early before the console code is initialized. For normal operation
-         it is not recommended because it looks on some machines ugly and
-         oesn't cooperate with an X server. You should normally N here,
+         early before the console code is initialized. For normal operation,
+         it is not recommended because it looks ugly on some machines and
+         doesn't cooperate with an X server. You should normally say N here,
          unless you want to debug such a crash.
 
 config SYS_HAS_EARLY_PRINTK
index b29a447392306056bdbe2ca877d171c39e876f94..2f060e1ed36c674c0e9da4e0d11f281edc8d07a0 100644 (file)
@@ -115,30 +115,6 @@ extern void markeins_irq_setup(void);
 
 static void inline __init markeins_sio_setup(void)
 {
-#ifdef CONFIG_KGDB_8250
-       struct uart_port emma_port;
-
-       memset(&emma_port, 0, sizeof(emma_port));
-
-       emma_port.flags =
-           UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
-       emma_port.iotype = UPIO_MEM;
-       emma_port.regshift = 4; /* I/O addresses are every 8 bytes */
-       emma_port.uartclk = 18544000;   /* Clock rate of the chip */
-
-       emma_port.line = 0;
-       emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3);
-       emma_port.membase = (u8*)emma_port.mapbase;
-       early_serial_setup(&emma_port);
-
-       emma_port.line = 1;
-       emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3);
-       emma_port.membase = (u8*)emma_port.mapbase;
-       early_serial_setup(&emma_port);
-
-       emma_port.irq = EMMA2RH_IRQ_PFUR1;
-       kgdb8250_add_port(1, &emma_port);
-#endif
 }
 
 void __init plat_mem_setup(void)
index 2604f2c9a96e0c89359553ec747e25a65d78da89..342579cfdc01d3b37ca739b96c862753734cc202 100644 (file)
@@ -36,7 +36,7 @@
 #define TIMEOUT       0xffffff
 
 static int remoteDebugInitialized = 0;
-static void debugInit(int baud)
+static void debugInit(int baud);
 
 int putDebugChar(unsigned char c)
 {
index 37849edd0645df1d611613a0838c351f3f98f552..06e04da211d57ec9f36a07dae2a34f2d56289d9c 100644 (file)
@@ -556,6 +556,16 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad,
                        flags);
 }
 
+asmlinkage long sys32_fadvise64_64(int fd, int __pad,
+       unsigned long a2, unsigned long a3,
+       unsigned long a4, unsigned long a5,
+       int flags)
+{
+       return sys_fadvise64_64(fd,
+                       merge_64(a2, a3), merge_64(a4, a5),
+                       flags);
+}
+
 save_static_function(sys32_clone);
 __attribute_used__ noinline static int
 _sys32_clone(nabi_no_regargs struct pt_regs regs)
index cc566cf122464f8672685766dd595bc8cc50cceb..06729596812f744581cce609938fee82d36d25cc 100644 (file)
@@ -174,7 +174,7 @@ LEAF(_init_fpu)
        or      t0, t1
        mtc0    t0, CP0_STATUS
 #endif /* CONFIG_MIPS_MT_SMTC */
-       fpu_enable_hazard
+       enable_fpu_hazard
 
        li      t1, FPU_DEFAULT
        ctc1    t1, fcr31
index 6eac28337423536c3f1bf19988b0606611706f39..1631035ffc243aa5fdf730828127d87dcf0d3685 100644 (file)
@@ -299,7 +299,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_ni_syscall                  /* res. for afs_syscall */
        PTR     sys_ni_syscall                  /* res. for security */
        PTR     sys_gettid
-       PTR     sys32_readahead
+       PTR     sys_readahead
        PTR     sys_setxattr                    /* 6180 */
        PTR     sys_lsetxattr
        PTR     sys_fsetxattr
index 7e74b412a782b8133b1557a6d69c58a710872a14..2aa99426ac1c11332e4e430a4131b6b8817ff01e 100644 (file)
@@ -459,7 +459,7 @@ sys_call_table:
        PTR     sys_remap_file_pages
        PTR     sys_set_tid_address
        PTR     sys_restart_syscall
-       PTR     sys_fadvise64_64
+       PTR     sys32_fadvise64_64
        PTR     compat_sys_statfs64             /* 4255 */
        PTR     compat_sys_fstatfs64
        PTR     compat_sys_timer_create
index 200de027f354ec8e0bb0919ab707f0ff4e640af1..3f58b6ac135815fe5944d3f98ec943f1529ce41d 100644 (file)
@@ -927,12 +927,6 @@ asmlinkage void do_reserved(struct pt_regs *regs)
              (regs->cp0_cause & 0x7f) >> 2);
 }
 
-static asmlinkage void do_default_vi(void)
-{
-       show_regs(get_irq_regs());
-       panic("Caught unexpected vectored interrupt.");
-}
-
 /*
  * Some MIPS CPUs can enable/disable for cache parity detection, but do
  * it different ways.
@@ -1128,6 +1122,12 @@ void mips_srs_free(int set)
        clear_bit(set, &sr->sr_allocated);
 }
 
+static asmlinkage void do_default_vi(void)
+{
+       show_regs(get_irq_regs());
+       panic("Caught unexpected vectored interrupt.");
+}
+
 static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 {
        unsigned long handler;
index 0c6b0ce15028827c6e1e069bcf2ee497d23dfc3b..1cc6ebbedfdd8cc89d611f71522478dd90f96adf 100644 (file)
@@ -48,6 +48,8 @@ const char *get_system_type(void)
        return "MIPS Atlas";
 }
 
+const char display_string[] = "        LINUX ON ATLAS       ";
+
 void __init plat_mem_setup(void)
 {
        mips_pcibios_init();
index 548dbe5ce7c8c889447ee24df97e2987ceca5d28..5d600054090a5c258a448a77340de12d205fd906 100644 (file)
  */
 
 #include <linux/compiler.h>
+#include <linux/timer.h>
 #include <asm/io.h>
 #include <asm/mips-boards/generic.h>
 
+extern const char display_string[];
+static unsigned int display_count;
+static unsigned int max_display_count;
+
 void mips_display_message(const char *str)
 {
        static unsigned int __iomem *display = NULL;
@@ -37,3 +42,22 @@ void mips_display_message(const char *str)
                         writel(' ', display + i);
        }
 }
+
+static void scroll_display_message(unsigned long data);
+static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0);
+
+static void scroll_display_message(unsigned long data)
+{
+       mips_display_message(&display_string[display_count++]);
+       if (display_count == max_display_count)
+               display_count = 0;
+
+       mod_timer(&mips_scroll_timer, jiffies + HZ);
+}
+
+void mips_scroll_message(void)
+{
+       del_timer_sync(&mips_scroll_timer);
+       max_display_count = strlen(display_string) + 1 - 8;
+       mod_timer(&mips_scroll_timer, jiffies + 1);
+}
index df2a2bd3aa5d198188e0fc3f8e1eadb167ee5dfd..37735bfc3afda540f7bb56adae0cfc0dcd7d075e 100644 (file)
 
 unsigned long cpu_khz;
 
-#if defined(CONFIG_MIPS_ATLAS)
-static char display_string[] = "        LINUX ON ATLAS       ";
-#endif
-#if defined(CONFIG_MIPS_MALTA)
-#if defined(CONFIG_MIPS_MT_SMTC)
-static char display_string[] = "       SMTC LINUX ON MALTA       ";
-#else
-static char display_string[] = "        LINUX ON MALTA       ";
-#endif /* CONFIG_MIPS_MT_SMTC */
-#endif
-#if defined(CONFIG_MIPS_SEAD)
-static char display_string[] = "        LINUX ON SEAD       ";
-#endif
-static unsigned int display_count;
-#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
-
 #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR)
 
-static unsigned int timer_tick_count;
 static int mips_cpu_timer_irq;
 extern void smtc_timer_broadcast(int);
 
-static inline void scroll_display_message(void)
-{
-       if ((timer_tick_count++ % HZ) == 0) {
-               mips_display_message(&display_string[display_count++]);
-               if (display_count == MAX_DISPLAY_COUNT)
-                       display_count = 0;
-       }
-}
-
 static void mips_timer_dispatch(void)
 {
        do_IRQ(mips_cpu_timer_irq);
@@ -143,7 +117,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
                if (cpu_data[cpu].vpe_id == 0) {
                                timer_interrupt(irq, NULL);
                                smtc_timer_broadcast(cpu_data[cpu].vpe_id);
-                               scroll_display_message();
                } else {
                        write_c0_compare(read_c0_count() +
                                         (mips_hpt_frequency/HZ));
@@ -167,8 +140,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
                /* we keep interrupt disabled all the time */
                if (!r2 || (read_c0_cause() & (1 << 30)))
                        timer_interrupt(irq, NULL);
-
-               scroll_display_message();
        } else {
                /* Everyone else needs to reset the timer int here as
                   ll_local_timer_interrupt doesn't */
@@ -262,6 +233,8 @@ void __init mips_time_init(void)
               (est_freq%1000000)*100/1000000);
 
         cpu_khz = est_freq / 1000;
+
+       mips_scroll_message();
 }
 
 void __init plat_timer_setup(struct irqaction *irq)
index 7873932532a10b9fc2c8186bf6bfdca2d6ef3923..c14b7bf89950cb131445c509ef0dbec189645417 100644 (file)
@@ -56,6 +56,12 @@ const char *get_system_type(void)
        return "MIPS Malta";
 }
 
+#if defined(CONFIG_MIPS_MT_SMTC)
+const char display_string[] = "       SMTC LINUX ON MALTA       ";
+#else
+const char display_string[] = "        LINUX ON MALTA       ";
+#endif /* CONFIG_MIPS_MT_SMTC */
+
 #ifdef CONFIG_BLK_DEV_FD
 void __init fd_activate(void)
 {
index a189dec7c7bc8603ebecce5eab41570144ca236e..811aba100605aa53711930e400f21f82b17cac15 100644 (file)
@@ -43,6 +43,8 @@ const char *get_system_type(void)
        return "MIPS SEAD";
 }
 
+const char display_string[] = "        LINUX ON SEAD       ";
+
 void __init plat_mem_setup(void)
 {
        ioport_resource.end = 0x7fffffff;
index f0eb29917d9aa3443a44c404f7ca3b5762eb0a99..76903c7276475145fa1661ae8d08df5bde458747 100644 (file)
@@ -168,8 +168,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
                addr = (unsigned long) page_address(sg->page);
                if (!plat_device_is_coherent(dev) && addr)
                        __dma_sync(addr + sg->offset, sg->length, direction);
-               sg->dma_address = plat_map_dma_mem_page(dev, sg->page) +
-                                 sg->offset;
+               sg->dma_address = plat_map_dma_mem(dev,
+                                                  (void *)(addr + sg->offset),
+                                                  sg->length);
        }
 
        return nents;
index 7f94f26d35ae054abc028298e6aacc77321486c1..1421d34535efecf29475c631492010480feb4942 100644 (file)
@@ -71,19 +71,19 @@ static inline void pci0WriteConfigReg(unsigned int offset, unsigned int data)
 }
 
 static struct resource ocelot_mem_resource = {
-       start   = GT_PCI_MEM_BASE;
-       end     = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1;
+       .start  = GT_PCI_MEM_BASE,
+       .end    = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1,
 };
 
 static struct resource ocelot_io_resource = {
-       start   = GT_PCI_IO_BASE;
-       end     = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+       .start  = GT_PCI_IO_BASE,
+       .end    = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
 };
 
 static struct pci_controller ocelot_pci_controller = {
-       .pci_ops        = gt64xxx_pci0_ops;
-       .mem_resource   = &ocelot_mem_resource;
-       .io_resource    = &ocelot_io_resource;
+       .pci_ops        = gt64xxx_pci0_ops,
+       .mem_resource   = &ocelot_mem_resource,
+       .io_resource    = &ocelot_io_resource,
 };
 
 static int __init ocelot_pcibios_init(void)
index f5ea2fe10f141d598b70a85f3d6514b73c54331c..89891e984b3bc3c67f0c66ee81a65bb691311941 100644 (file)
@@ -7,8 +7,6 @@
 #include <asm/system.h>
 #include <asm/time.h>
 
-extern asmlinkage void qemu_handle_int(void);
-
 asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
index 7e1416768a60bd7f9c17551d0eaed0d1abc7122a..60f0227425e709ba82a9a882158a1b2e5ecb4e49 100644 (file)
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y  += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \
+obj-y  += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
           crime.o ip32-memory.o
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
new file mode 100644 (file)
index 0000000..120b159
--- /dev/null
@@ -0,0 +1,20 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+static __init int meth_devinit(void)
+{
+       struct platform_device *pd;
+       int ret;
+
+       pd = platform_device_alloc("meth", -1);
+       if (!pd)
+               return -ENOMEM;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               platform_device_put(pd);
+
+       return ret;
+}
+
+device_initcall(meth_devinit);
index 9ee208daa8b12f238adb47a4d796f4706b5fff2a..97b234361b4d0afa8d5c0b64434c2bf07a253292 100644 (file)
@@ -6,7 +6,7 @@
  * for more details.
  *
  * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  */
 
 #include <linux/init.h>
@@ -131,6 +131,19 @@ static struct resource pcimt_io_resources[] = {
        }
 };
 
+static struct resource pcimt_mem_resources[] = {
+       {
+               /*
+                * this region should only be 4 bytes long,
+                * but it's 16MB on all RM300C I've checked
+                */
+               .start  = 0x1a000000,
+               .end    = 0x1affffff,
+               .name   = "PCI INT ACK",
+               .flags  = IORESOURCE_BUSY
+       }
+};
+
 static struct resource sni_mem_resource = {
        .start  = 0x18000000UL,
        .end    = 0x1fbfffffUL,
@@ -145,6 +158,9 @@ static void __init sni_pcimt_resource_init(void)
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
                request_resource(&sni_io_resource, pcimt_io_resources + i);
+       /* request MEM space for devices used on all i[345]86 PCs */
+       for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
+               request_resource(&sni_mem_resource, pcimt_mem_resources + i);
 }
 
 extern struct pci_ops sni_pcimt_ops;
index 68d7cf609b4fcabd36396ec85c4838b203ff1f89..4fedfbda0c791b71a8ccfa94080fa80c6a0eee27 100644 (file)
@@ -6,7 +6,7 @@
  * for more details.
  *
  * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  */
 #include <linux/eisa.h>
 #include <linux/init.h>
@@ -92,3 +92,34 @@ void __init plat_mem_setup(void)
 
        sni_display_setup();
 }
+
+#if CONFIG_PCI
+
+#include <linux/pci.h>
+#include <video/vga.h>
+#include <video/cirrus.h>
+
+static void __devinit quirk_cirrus_ram_size(struct pci_dev *dev)
+{
+       u16 cmd;
+
+       /*
+        * firmware doesn't set the ram size correct, so we
+        * need to do it here, otherwise we get screen corruption
+        * on older Cirrus chips
+        */
+       pci_read_config_word (dev, PCI_COMMAND, &cmd);
+       if ((cmd & (PCI_COMMAND_IO|PCI_COMMAND_MEMORY))
+               == (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) {
+               vga_wseq (NULL, CL_SEQR6, 0x12);        /* unlock all extension registers */
+               vga_wseq (NULL, CL_SEQRF, 0x18);
+       }
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8,
+                        quirk_cirrus_ram_size);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5436,
+                        quirk_cirrus_ram_size);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446,
+                        quirk_cirrus_ram_size);
+#endif
index 56d3c0dcd2b802f8c5f4a4dd2847c15f8f0ca864..5eaeafd30bdfe2710b7e35f325fee9692b751d44 100644 (file)
@@ -118,6 +118,7 @@ config GENERIC_BUG
        depends on BUG
 
 config SYS_SUPPORTS_APM_EMULATION
+       default y if PMAC_APM_EMU
        bool
 
 config DEFAULT_UIMAGE
index 6238b5875fd1c746f2f5a9fc838167bb0f3443d8..fbafd965dcd298049338d84d9b8fca406ab27825 100644 (file)
@@ -142,7 +142,6 @@ drivers-$(CONFIG_OPROFILE)  += arch/powerpc/oprofile/
 
 # Default to zImage, override when needed
 defaultimage-y                 := zImage
-defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
 defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage
 KBUILD_IMAGE := $(defaultimage-y)
 all: $(KBUILD_IMAGE)
index 83788986b93b3418adb02d1b352e1a277b009f49..ff2701949ee18616021fee3af3332f7043a25ba7 100644 (file)
 #      bootloader and increase compatibility with OpenFirmware.
 #
 #      To this end we need to define BOOTCC, etc, as the tools
-#      needed to build the 32 bit image.  These are normally HOSTCC,
-#      but may be a third compiler if, for example, you are cross
-#      compiling from an intel box.  Once the 64bit ppc gcc is
-#      stable it will probably simply be a compiler switch to
-#      compile for 32bit mode.
+#      needed to build the 32 bit image.  That's normally the same
+#      compiler for the rest of the kernel, with the -m32 flag added.
 #      To make it easier to setup a cross compiler,
 #      CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
 #      in the toplevel makefile.
 
 all: $(obj)/zImage
 
-HOSTCC         := gcc
-BOOTCFLAGS     := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
-                  $(shell $(CROSS32CC) -print-file-name=include) -fPIC
+BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+                -fno-strict-aliasing -Os -msoft-float -pipe \
+                -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+                -isystem $(shell $(CROSS32CC) -print-file-name=include)
 BOOTAFLAGS     := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
 
 ifeq ($(call cc-option-yn, -fstack-protector),y)
@@ -33,8 +31,8 @@ endif
 
 BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj)
 
-$(obj)/44x.o: BOOTCFLAGS += -Wa,-mbooke
-$(obj)/ebony.o: BOOTCFLAGS += -Wa,-mbooke
+$(obj)/44x.o: BOOTCFLAGS += -mcpu=440
+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
 
 zlib       := inffast.c inflate.c inftrees.c
 zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
@@ -136,6 +134,7 @@ image-$(CONFIG_PPC_EFIKA)           += zImage.chrp
 image-$(CONFIG_PPC_PMAC)               += zImage.pmac
 image-$(CONFIG_PPC_HOLLY)              += zImage.holly-elf
 image-$(CONFIG_PPC_PRPMC2800)          += zImage.prpmc2800
+image-$(CONFIG_PPC_ISERIES)            += zImage.iseries
 image-$(CONFIG_DEFAULT_UIMAGE)         += uImage
 
 ifneq ($(CONFIG_DEVICE_TREE),"")
@@ -185,6 +184,9 @@ $(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
 $(obj)/zImage.%: vmlinux $(wrapperbits)
        $(call if_changed,wrap,$*)
 
+$(obj)/zImage.iseries: vmlinux
+       $(STRIP) -s -R .comment $< -o $@
+
 $(obj)/zImage.ps3: vmlinux
        $(STRIP) -s -R .comment $< -o $@
 
index 5a4215c4b0146aa063fe87c5bb503a398232f6d3..f1c4dfc635be20380d6a718d420cb83b6e4a6068 100644 (file)
@@ -13,6 +13,7 @@
 
        .text
        /* a procedure descriptor used when booting this as a COFF file */
+       .globl  _zimage_start_opd
 _zimage_start_opd:
        .long   _zimage_start, 0, 0, 0
 
index eae68ab1177f77660e00a8cc31e97f71b7a48719..d29308fe4c24d35e4fefd9ecff0e45c1a965b904 100644 (file)
@@ -67,7 +67,7 @@
                        interrupt-controller;
                        #interrupt-cells = <3>;
                        device_type = "interrupt-controller";
-                       compatible = "mpc5200_pic";
+                       compatible = "mpc5200-pic";
                        reg = <500 80>;
                        built-in;
                };
index 5185625a9419d1304e9c5c7b6a43abd989de7bea..f242531f04514a56668e0f3ea525e086e442fb5b 100644 (file)
@@ -67,7 +67,7 @@
                        interrupt-controller;
                        #interrupt-cells = <3>;
                        device_type = "interrupt-controller";
-                       compatible = "mpc5200b-pic\0mpc5200_pic";
+                       compatible = "mpc5200b-pic\0mpc5200-pic";
                        reg = <500 80>;
                        built-in;
                };
index 2ed8b8b3f0ec0f10c1764017969b622c71718ba3..da77adc73078d3561144edf3d335dab4c901dbdc 100755 (executable)
@@ -129,7 +129,7 @@ case "$platform" in
 pmac|pseries|chrp)
     platformo=$object/of.o
     ;;
-pmaccoff)
+coff)
     platformo=$object/of.o
     lds=$object/zImage.coff.lds
     ;;
@@ -220,7 +220,7 @@ case "$platform" in
 pseries|chrp)
     $object/addnote "$ofile"
     ;;
-pmaccoff)
+coff)
     ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
     $object/hack-coff "$ofile"
     ;;
index 068377a2a8dc021b008f7cb56d3d82b2e94994cb..42c8ed6ed528be8a6a62c35e71a0a2e130811753 100644 (file)
@@ -489,7 +489,7 @@ struct irq_host *irq_alloc_host(unsigned int revmap_type,
        case IRQ_HOST_MAP_LINEAR:
                rmap = (unsigned int *)(host + 1);
                for (i = 0; i < revmap_arg; i++)
-                       rmap[i] = IRQ_NONE;
+                       rmap[i] = NO_IRQ;
                host->revmap_data.linear.size = revmap_arg;
                smp_wmb();
                host->revmap_data.linear.revmap = rmap;
@@ -614,7 +614,7 @@ unsigned int irq_create_mapping(struct irq_host *host,
         * host->ops->map() to update the flags
         */
        virq = irq_find_mapping(host, hwirq);
-       if (virq != IRQ_NONE) {
+       if (virq != NO_IRQ) {
                if (host->ops->remap)
                        host->ops->remap(host, virq, hwirq);
                pr_debug("irq: -> existing mapping on virq %d\n", virq);
@@ -741,7 +741,7 @@ void irq_dispose_mapping(unsigned int virq)
        switch(host->revmap_type) {
        case IRQ_HOST_MAP_LINEAR:
                if (hwirq < host->revmap_data.linear.size)
-                       host->revmap_data.linear.revmap[hwirq] = IRQ_NONE;
+                       host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
                break;
        case IRQ_HOST_MAP_TREE:
                /* Check if radix tree allocated yet */
index d501c23e5159559ca493caf512e888ca6671e73a..d454f61c9c7c7b5a84c00ef3f66b730e436171ee 100644 (file)
@@ -433,7 +433,7 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
         * Note also that we don't do ISA, this will also be fixed with a
         * more massive rework.
         */
-       pci_setup_phb_io(phb, 0);
+       pci_setup_phb_io(phb, pci_io_base == 0);
 
        /* Init pci_dn data structures */
        pci_devs_phb_init_dynamic(phb);
index 066a6a7a25b88c2bb41017459c938287b4db521f..af42ddab3ab473ba7f9085c3a28d2f37fb4672c7 100644 (file)
@@ -1171,11 +1171,12 @@ EXPORT_SYMBOL(of_find_node_by_name);
 
 /**
  *     of_find_node_by_type - Find a node by its "device_type" property
- *     @from:  The node to start searching from or NULL, the node
- *             you pass will not be searched, only the next one
- *             will; typically, you pass what the previous call
- *             returned. of_node_put() will be called on it
- *     @name:  The type string to match against
+ *     @from:  The node to start searching from, or NULL to start searching
+ *             the entire device tree. The node you pass will not be
+ *             searched, only the next one will; typically, you pass
+ *             what the previous call returned. of_node_put() will be
+ *             called on from for you.
+ *     @type:  The type string to match against
  *
  *     Returns a node pointer with refcount incremented, use
  *     of_node_put() on it when done.
index f4f391cdd8f5e8bb45c059cf2779fd97d7f1cd3f..bf76562167c34dc4334332b65cdc4bc14f90aa6e 100644 (file)
@@ -218,6 +218,7 @@ set_single_step(struct task_struct *task)
                regs->msr |= MSR_SE;
 #endif
        }
+       set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
 static inline void
@@ -233,6 +234,7 @@ clear_single_step(struct task_struct *task)
                regs->msr &= ~MSR_SE;
 #endif
        }
+       clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 #endif /* CONFIG_PPC32 */
 
index d8232b7a08f70043e45246e3c8018b093c7e37cc..f6ae1a57d652999c679545ae21fd5b6499cfae58 100644 (file)
@@ -93,7 +93,7 @@ void pgd_free(pgd_t *pgd)
        free_pages((unsigned long)pgd, PGDIR_ORDER);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
        pte_t *pte;
        extern int mem_init_done;
index f9ac3fe3be9767fbf04a73296dfc365d3efbbec7..ac445998d8313d087964e0e6133f272a6b080ab8 100644 (file)
@@ -67,6 +67,7 @@ static u64 MIC_Slow_Next_Timer_table[] = {
        0x00003FC000000000ull,
 };
 
+static unsigned int pmi_frequency_limit = 0;
 /*
  * hardware specific functions
  */
@@ -164,7 +165,6 @@ static int set_pmode(int cpu, unsigned int slow_mode) {
 
 static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
 {
-       struct cpufreq_policy policy;
        u8 cpu;
        u8 cbe_pmode_new;
 
@@ -173,15 +173,27 @@ static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
        cpu = cbe_node_to_cpu(pmi_msg.data1);
        cbe_pmode_new = pmi_msg.data2;
 
-       cpufreq_get_policy(&policy, cpu);
+       pmi_frequency_limit = cbe_freqs[cbe_pmode_new].frequency;
 
-       policy.max = min(policy.max, cbe_freqs[cbe_pmode_new].frequency);
-       policy.min = min(policy.min, policy.max);
+       pr_debug("cbe_handle_pmi: max freq=%d\n", pmi_frequency_limit);
+}
+
+static int pmi_notifier(struct notifier_block *nb,
+                                      unsigned long event, void *data)
+{
+       struct cpufreq_policy *policy = data;
 
-       pr_debug("cbe_handle_pmi: new policy.min=%d policy.max=%d\n", policy.min, policy.max);
-       cpufreq_set_policy(&policy);
+       if (event != CPUFREQ_INCOMPATIBLE)
+               return 0;
+
+       cpufreq_verify_within_limits(policy, 0, pmi_frequency_limit);
+       return 0;
 }
 
+static struct notifier_block pmi_notifier_block = {
+       .notifier_call = pmi_notifier,
+};
+
 static struct pmi_handler cbe_pmi_handler = {
        .type                   = PMI_TYPE_FREQ_CHANGE,
        .handle_pmi_message     = cbe_cpufreq_handle_pmi,
@@ -238,12 +250,21 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
 
+       if (pmi_dev) {
+               /* frequency might get limited later, initialize limit with max_freq */
+               pmi_frequency_limit = max_freq;
+               cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+       }
+
        /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */
        return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs);
 }
 
 static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
+       if (pmi_dev)
+               cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
        cpufreq_frequency_table_put_attr(policy->cpu);
        return 0;
 }
index 8654749e317bae0aa67795dda4ba2eebdae50c3f..7c51cb54bca1ca8ba78c5074631247465dc784e7 100644 (file)
@@ -39,7 +39,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
        if (spu_init_csa(&ctx->csa))
                goto out_free;
        spin_lock_init(&ctx->mmio_lock);
-       spin_lock_init(&ctx->mapping_lock);
+       mutex_init(&ctx->mapping_lock);
        kref_init(&ctx->kref);
        mutex_init(&ctx->state_mutex);
        mutex_init(&ctx->run_mutex);
@@ -103,6 +103,7 @@ void spu_forget(struct spu_context *ctx)
 
 void spu_unmap_mappings(struct spu_context *ctx)
 {
+       mutex_lock(&ctx->mapping_lock);
        if (ctx->local_store)
                unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
        if (ctx->mfc)
@@ -117,6 +118,7 @@ void spu_unmap_mappings(struct spu_context *ctx)
                unmap_mapping_range(ctx->mss, 0, 0x1000, 1);
        if (ctx->psmap)
                unmap_mapping_range(ctx->psmap, 0, 0x20000, 1);
+       mutex_unlock(&ctx->mapping_lock);
 }
 
 /**
index 45614c73c7841824d1a1f47834ebc2838bfbbe0a..b1e7e2f8a2e9256f4263a1ee72a589de6c592408 100644 (file)
@@ -45,11 +45,11 @@ spufs_mem_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = ctx;
        if (!i->i_openers++)
                ctx->local_store = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -59,10 +59,10 @@ spufs_mem_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->local_store = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -217,6 +217,7 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr,
 
 static const struct file_operations spufs_mem_fops = {
        .open                   = spufs_mem_open,
+       .release                = spufs_mem_release,
        .read                   = spufs_mem_read,
        .write                  = spufs_mem_write,
        .llseek                 = generic_file_llseek,
@@ -309,11 +310,11 @@ static int spufs_cntl_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = ctx;
        if (!i->i_openers++)
                ctx->cntl = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return simple_attr_open(inode, file, spufs_cntl_get,
                                        spufs_cntl_set, "0x%08lx");
 }
@@ -326,10 +327,10 @@ spufs_cntl_release(struct inode *inode, struct file *file)
 
        simple_attr_close(inode, file);
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->cntl = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -812,11 +813,11 @@ static int spufs_signal1_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = ctx;
        if (!i->i_openers++)
                ctx->signal1 = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return nonseekable_open(inode, file);
 }
 
@@ -826,10 +827,10 @@ spufs_signal1_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->signal1 = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -936,11 +937,11 @@ static int spufs_signal2_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = ctx;
        if (!i->i_openers++)
                ctx->signal2 = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return nonseekable_open(inode, file);
 }
 
@@ -950,10 +951,10 @@ spufs_signal2_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->signal2 = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -1154,10 +1155,10 @@ static int spufs_mss_open(struct inode *inode, struct file *file)
 
        file->private_data = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!i->i_openers++)
                ctx->mss = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return nonseekable_open(inode, file);
 }
 
@@ -1167,10 +1168,10 @@ spufs_mss_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->mss = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -1211,11 +1212,11 @@ static int spufs_psmap_open(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = i->i_ctx;
        if (!i->i_openers++)
                ctx->psmap = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return nonseekable_open(inode, file);
 }
 
@@ -1225,10 +1226,10 @@ spufs_psmap_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->psmap = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
@@ -1281,11 +1282,11 @@ static int spufs_mfc_open(struct inode *inode, struct file *file)
        if (atomic_read(&inode->i_count) != 1)
                return -EBUSY;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        file->private_data = ctx;
        if (!i->i_openers++)
                ctx->mfc = inode->i_mapping;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return nonseekable_open(inode, file);
 }
 
@@ -1295,10 +1296,10 @@ spufs_mfc_release(struct inode *inode, struct file *file)
        struct spufs_inode_info *i = SPUFS_I(inode);
        struct spu_context *ctx = i->i_ctx;
 
-       spin_lock(&ctx->mapping_lock);
+       mutex_lock(&ctx->mapping_lock);
        if (!--i->i_openers)
                ctx->mfc = NULL;
-       spin_unlock(&ctx->mapping_lock);
+       mutex_unlock(&ctx->mapping_lock);
        return 0;
 }
 
index 7150730e2ff11b9896039bd46a05ef83c8d26931..9807206e02196d479b1ea171ecc754fae9c7a746 100644 (file)
@@ -177,7 +177,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
 static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
                          int mode, struct spu_context *ctx)
 {
-       struct dentry *dentry;
+       struct dentry *dentry, *tmp;
        int ret;
 
        while (files->name && files->name[0]) {
@@ -193,7 +193,20 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
        }
        return 0;
 out:
-       spufs_prune_dir(dir);
+       /*
+        * remove all children from dir. dir->inode is not set so don't
+        * just simply use spufs_prune_dir() and panic afterwards :)
+        * dput() looks like it will do the right thing:
+        * - dec parent's ref counter
+        * - remove child from parent's child list
+        * - free child's inode if possible
+        * - free child
+        */
+       list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
+               dput(dentry);
+       }
+
+       shrink_dcache_parent(dir);
        return ret;
 }
 
@@ -274,6 +287,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
        goto out;
 
 out_free_ctx:
+       spu_forget(ctx);
        put_spu_context(ctx);
 out_iput:
        iput(inode);
@@ -349,37 +363,6 @@ out:
        return ret;
 }
 
-static int spufs_rmgang(struct inode *root, struct dentry *dir)
-{
-       /* FIXME: this fails if the dir is not empty,
-                 which causes a leak of gangs. */
-       return simple_rmdir(root, dir);
-}
-
-static int spufs_gang_close(struct inode *inode, struct file *file)
-{
-       struct inode *parent;
-       struct dentry *dir;
-       int ret;
-
-       dir = file->f_path.dentry;
-       parent = dir->d_parent->d_inode;
-
-       ret = spufs_rmgang(parent, dir);
-       WARN_ON(ret);
-
-       return dcache_dir_close(inode, file);
-}
-
-const struct file_operations spufs_gang_fops = {
-       .open           = dcache_dir_open,
-       .release        = spufs_gang_close,
-       .llseek         = dcache_dir_lseek,
-       .read           = generic_read_dir,
-       .readdir        = dcache_readdir,
-       .fsync          = simple_sync_file,
-};
-
 static int
 spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
 {
@@ -407,7 +390,6 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
        inode->i_fop = &simple_dir_operations;
 
        d_instantiate(dentry, inode);
-       dget(dentry);
        dir->i_nlink++;
        dentry->d_inode->i_nlink++;
        return ret;
@@ -437,7 +419,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
                goto out;
        }
 
-       filp->f_op = &spufs_gang_fops;
+       filp->f_op = &simple_dir_operations;
        fd_install(ret, filp);
 out:
        return ret;
@@ -458,8 +440,10 @@ static int spufs_create_gang(struct inode *inode,
         * in error path of *_open().
         */
        ret = spufs_gang_open(dget(dentry), mntget(mnt));
-       if (ret < 0)
-               WARN_ON(spufs_rmgang(inode, dentry));
+       if (ret < 0) {
+               int err = simple_rmdir(inode, dentry);
+               WARN_ON(err);
+       }
 
 out:
        mutex_unlock(&inode->i_mutex);
@@ -600,6 +584,10 @@ spufs_create_root(struct super_block *sb, void *data)
        struct inode *inode;
        int ret;
 
+       ret = -ENODEV;
+       if (!spu_management_ops)
+               goto out;
+
        ret = -ENOMEM;
        inode = spufs_new_inode(sb, S_IFDIR | 0775);
        if (!inode)
index b6ecb30e7d58b71ef8530f13bd02ea4bfe21039e..3b831e07f1ed740eabf0cd95fcafb985f105a8f2 100644 (file)
@@ -93,43 +93,6 @@ void spu_stop_tick(struct spu_context *ctx)
        }
 }
 
-void spu_sched_tick(struct work_struct *work)
-{
-       struct spu_context *ctx =
-               container_of(work, struct spu_context, sched_work.work);
-       struct spu *spu;
-       int preempted = 0;
-
-       /*
-        * If this context is being stopped avoid rescheduling from the
-        * scheduler tick because we would block on the state_mutex.
-        * The caller will yield the spu later on anyway.
-        */
-       if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags))
-               return;
-
-       mutex_lock(&ctx->state_mutex);
-       spu = ctx->spu;
-       if (spu) {
-               int best = sched_find_first_bit(spu_prio->bitmap);
-               if (best <= ctx->prio) {
-                       spu_deactivate(ctx);
-                       preempted = 1;
-               }
-       }
-       mutex_unlock(&ctx->state_mutex);
-
-       if (preempted) {
-               /*
-                * We need to break out of the wait loop in spu_run manually
-                * to ensure this context gets put on the runqueue again
-                * ASAP.
-                */
-               wake_up(&ctx->stop_wq);
-       } else
-               spu_start_tick(ctx);
-}
-
 /**
  * spu_add_to_active_list - add spu to active list
  * @spu:       spu to add to the active list
@@ -273,34 +236,6 @@ static void spu_prio_wait(struct spu_context *ctx)
        remove_wait_queue(&ctx->stop_wq, &wait);
 }
 
-/**
- * spu_reschedule - try to find a runnable context for a spu
- * @spu:       spu available
- *
- * This function is called whenever a spu becomes idle.  It looks for the
- * most suitable runnable spu context and schedules it for execution.
- */
-static void spu_reschedule(struct spu *spu)
-{
-       int best;
-
-       spu_free(spu);
-
-       spin_lock(&spu_prio->runq_lock);
-       best = sched_find_first_bit(spu_prio->bitmap);
-       if (best < MAX_PRIO) {
-               struct list_head *rq = &spu_prio->runq[best];
-               struct spu_context *ctx;
-
-               BUG_ON(list_empty(rq));
-
-               ctx = list_entry(rq->next, struct spu_context, rq);
-               __spu_del_from_rq(ctx);
-               wake_up(&ctx->stop_wq);
-       }
-       spin_unlock(&spu_prio->runq_lock);
-}
-
 static struct spu *spu_get_idle(struct spu_context *ctx)
 {
        struct spu *spu = NULL;
@@ -428,6 +363,51 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
        return -ERESTARTSYS;
 }
 
+/**
+ * grab_runnable_context - try to find a runnable context
+ *
+ * Remove the highest priority context on the runqueue and return it
+ * to the caller.  Returns %NULL if no runnable context was found.
+ */
+static struct spu_context *grab_runnable_context(int prio)
+{
+       struct spu_context *ctx = NULL;
+       int best;
+
+       spin_lock(&spu_prio->runq_lock);
+       best = sched_find_first_bit(spu_prio->bitmap);
+       if (best < prio) {
+               struct list_head *rq = &spu_prio->runq[best];
+
+               BUG_ON(list_empty(rq));
+
+               ctx = list_entry(rq->next, struct spu_context, rq);
+               __spu_del_from_rq(ctx);
+       }
+       spin_unlock(&spu_prio->runq_lock);
+
+       return ctx;
+}
+
+static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
+{
+       struct spu *spu = ctx->spu;
+       struct spu_context *new = NULL;
+
+       if (spu) {
+               new = grab_runnable_context(max_prio);
+               if (new || force) {
+                       spu_unbind_context(spu, ctx);
+                       spu_free(spu);
+                       if (new)
+                               wake_up(&new->stop_wq);
+               }
+
+       }
+
+       return new != NULL;
+}
+
 /**
  * spu_deactivate - unbind a context from it's physical spu
  * @ctx:       spu context to unbind
@@ -437,12 +417,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
  */
 void spu_deactivate(struct spu_context *ctx)
 {
-       struct spu *spu = ctx->spu;
-
-       if (spu) {
-               spu_unbind_context(spu, ctx);
-               spu_reschedule(spu);
-       }
+       __spu_deactivate(ctx, 1, MAX_PRIO);
 }
 
 /**
@@ -455,21 +430,43 @@ void spu_deactivate(struct spu_context *ctx)
  */
 void spu_yield(struct spu_context *ctx)
 {
-       struct spu *spu;
-
-       if (mutex_trylock(&ctx->state_mutex)) {
-               if ((spu = ctx->spu) != NULL) {
-                       int best = sched_find_first_bit(spu_prio->bitmap);
-                       if (best < MAX_PRIO) {
-                               pr_debug("%s: yielding SPU %d NODE %d\n",
-                                        __FUNCTION__, spu->number, spu->node);
-                               spu_deactivate(ctx);
-                       }
-               }
+       if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
+               mutex_lock(&ctx->state_mutex);
+               __spu_deactivate(ctx, 0, MAX_PRIO);
                mutex_unlock(&ctx->state_mutex);
        }
 }
 
+void spu_sched_tick(struct work_struct *work)
+{
+       struct spu_context *ctx =
+               container_of(work, struct spu_context, sched_work.work);
+       int preempted;
+
+       /*
+        * If this context is being stopped avoid rescheduling from the
+        * scheduler tick because we would block on the state_mutex.
+        * The caller will yield the spu later on anyway.
+        */
+       if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags))
+               return;
+
+       mutex_lock(&ctx->state_mutex);
+       preempted = __spu_deactivate(ctx, 0, ctx->prio + 1);
+       mutex_unlock(&ctx->state_mutex);
+
+       if (preempted) {
+               /*
+                * We need to break out of the wait loop in spu_run manually
+                * to ensure this context gets put on the runqueue again
+                * ASAP.
+                */
+               wake_up(&ctx->stop_wq);
+       } else {
+               spu_start_tick(ctx);
+       }
+}
+
 int __init spu_sched_init(void)
 {
        int i;
index 0a947fd7de57c3da11e2444b64d5d020637a9323..47617e8014a5acc402f1c0222dfb1d1c6c3bf972 100644 (file)
@@ -55,7 +55,7 @@ struct spu_context {
        struct address_space *signal2;     /* 'signal2' area mappings. */
        struct address_space *mss;         /* 'mss' area mappings. */
        struct address_space *psmap;       /* 'psmap' area mappings. */
-       spinlock_t mapping_lock;
+       struct mutex mapping_lock;
        u64 object_id;             /* user space pointer for oprofile */
 
        enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
index f4f82520dc4f59aa1d0f35d387f43637185251d8..5240046d86715275156d7adf6b41434f28b1155a 100644 (file)
@@ -4,5 +4,5 @@ obj-y                           += interrupt.o iommu.o setup.o \
 
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)    += udbg_beat.o
-obj-$(CONFIG_HAS_TXX9_SERIAL)  += scc_sio.o
+obj-$(CONFIG_SERIAL_TXX9)      += scc_sio.o
 obj-$(CONFIG_SPU_BASE)         += spu_priv1.o
index 71045677559a6b0f7deed4da21e66b925b9a2fed..5bcc58d9a4dd39ad451785b36ad00d1ecb8e3e70 100644 (file)
@@ -169,7 +169,7 @@ static int Enable_SRAM(void)
 
 /***********/
 /***********/
-int mv643xx_eth_add_pds(void)
+static int __init mv643xx_eth_add_pds(void)
 {
        int ret = 0;
        static struct pci_device_id pci_marvell_mv64360[] = {
index 03cd45d8fefa3b5fcc86a34974ff768a52025525..3c962d5757be797446c5195ff32278929f3489ab 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <asm/machdep.h>
 #include <asm/reg.h>
+#include <asm/smp.h>
 
 #include "pasemi.h"
 
index 95fa6a7d15ee4d11aab9e8543d8ac59d11f4c1f7..f33b21b9f5d4338d9ad9c01ba610a90250b7e132 100644 (file)
@@ -31,8 +31,6 @@
 #define IOBMAP_PAGE_SIZE       (1 << IOBMAP_PAGE_SHIFT)
 #define IOBMAP_PAGE_MASK       (IOBMAP_PAGE_SIZE - 1)
 
-#define IOBMAP_PAGE_FACTOR     (PAGE_SHIFT - IOBMAP_PAGE_SHIFT)
-
 #define IOB_BASE               0xe0000000
 #define IOB_SIZE               0x3000
 /* Configuration registers */
@@ -97,9 +95,6 @@ static void iobmap_build(struct iommu_table *tbl, long index,
 
        bus_addr = (tbl->it_offset + index) << PAGE_SHIFT;
 
-       npages <<= IOBMAP_PAGE_FACTOR;
-       index <<= IOBMAP_PAGE_FACTOR;
-
        ip = ((u32 *)tbl->it_base) + index;
 
        while (npages--) {
@@ -125,9 +120,6 @@ static void iobmap_free(struct iommu_table *tbl, long index,
 
        bus_addr = (tbl->it_offset + index) << PAGE_SHIFT;
 
-       npages <<= IOBMAP_PAGE_FACTOR;
-       index <<= IOBMAP_PAGE_FACTOR;
-
        ip = ((u32 *)tbl->it_base) + index;
 
        while (npages--) {
index a410bc76a8a8ee5cc4bb2226a0906e37e7054329..07b1c4ec428d590daa4882638118dbee161a343c 100644 (file)
@@ -384,7 +384,7 @@ int boot_part;
 static dev_t boot_dev;
 
 #ifdef CONFIG_SCSI
-void __init note_scsi_host(struct device_node *node, void *host)
+void note_scsi_host(struct device_node *node, void *host)
 {
        int l;
        char *p;
index 9da82c266ba9ccc45110a5b2daa9f32004253001..ec9030dbb5f1ba13fc86c116d1675f6a5c82dc15 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/machdep.h>
 #include <asm/udbg.h>
 #include <asm/lv1call.h>
+#include <asm/smp.h>
 
 #include "platform.h"
 
index b854e7f1001c60c79697cd96c957b388a0fe7b98..f1df942072bbdefdb3e7a397e2c7637c53423d43 100644 (file)
@@ -752,6 +752,7 @@ skip_gserver_check:
 void xics_request_IPIs(void)
 {
        unsigned int ipi;
+       int rc;
 
        ipi = irq_create_mapping(xics_host, XICS_IPI);
        BUG_ON(ipi == NO_IRQ);
@@ -762,11 +763,12 @@ void xics_request_IPIs(void)
         */
        set_irq_handler(ipi, handle_percpu_irq);
        if (firmware_has_feature(FW_FEATURE_LPAR))
-               request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED,
-                           "IPI", NULL);
+               rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED,
+                               "IPI", NULL);
        else
-               request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED,
-                           "IPI", NULL);
+               rc = request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED,
+                               "IPI", NULL);
+       BUG_ON(rc);
 }
 #endif /* CONFIG_SMP */
 
index 887739f3badc6a18ed203c9af86e25a4a9185368..f611d344a126e5dc05dd6a913859b5a97d486abc 100644 (file)
@@ -5,15 +5,13 @@
 config UCC_SLOW
        bool
        default n
-       select UCC
        help
          This option provides qe_lib support to UCC slow
          protocols: UART, BISYNC, QMC
 
 config UCC_FAST
        bool
-       default n
-       select UCC
+       default y if UCC_GETH
        help
          This option provides qe_lib support to UCC fast
          protocols: HDLC, Ethernet, ATM, transparent
index ab64256110bd2ab2547d34f359877b40874b0717..fba7ca17a67e1565cdb8cb83628f828b7640b77d 100644 (file)
@@ -596,7 +596,11 @@ fast_exception_return:
        mr      r12,r4          /* restart at exc_exit_restart */
        b       2b
 
-       .comm   fee_restarts,4
+       .section .bss
+       .align  2
+fee_restarts:
+       .space  4
+       .previous
 
 /* aargh, a nonrecoverable interrupt, panic */
 /* aargh, we don't know which trap this is */
@@ -851,7 +855,11 @@ load_dbcr0:
        mtspr   SPRN_DBSR,r11   /* clear all pending debug events */
        blr
 
-       .comm   global_dbcr0,8
+       .section .bss
+       .align  4
+global_dbcr0:
+       .space  8
+       .previous
 #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
 
 do_work:                       /* r10 contains MSR_KERNEL here */
@@ -926,4 +934,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
        /* shouldn't return */
        b       4b
 
-       .comm   ee_restarts,4
+       .section .bss
+       .align  2
+ee_restarts:
+       .space  4
+       .previous
index 4ad499605d056b2ce07e31f1ce25db4f7f9b0cbd..a4165209ac7cd738499087a71cb74c92336f6d0d 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/time.h>
 #include <asm/cputable.h>
 #include <asm/btext.h>
-#include <asm/div64.h>
 #include <asm/xmon.h>
 #include <asm/signal.h>
 #include <asm/dcr.h>
@@ -93,7 +92,6 @@ EXPORT_SYMBOL(strncpy);
 EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(__div64_32);
 
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
index e756942e65c40fe482f3f223321938ffc9103f65..5f364dc501549bc41ab5a9a079c98529953234e3 100644 (file)
 #include <asm/asm-offsets.h>
 
 #ifdef CONFIG_SMP
-       .comm   mmu_hash_lock,4
+       .section .bss
+       .align  2
+       .globl mmu_hash_lock
+mmu_hash_lock:
+       .space  4
 #endif /* CONFIG_SMP */
 
 /*
@@ -461,9 +465,17 @@ found_slot:
        sync            /* make sure pte updates get to memory */
        blr
 
-       .comm   next_slot,4
-       .comm   primary_pteg_full,4
-       .comm   htab_hash_searches,4
+       .section .bss
+       .align  2
+next_slot:
+       .space  4
+       .globl primary_pteg_full
+primary_pteg_full:
+       .space  4
+       .globl htab_hash_searches
+htab_hash_searches:
+       .space  4
+       .previous
 
 /*
  * Flush the entry for a particular page from the hash table.
index c023b7298809b282639168eb2125f4e9d3218de0..35ebb6395ae3329d5117d4d0611d21e60d12a361 100644 (file)
@@ -92,7 +92,7 @@ void pgd_free(pgd_t *pgd)
        free_pages((unsigned long)pgd, PGDIR_ORDER);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
        pte_t *pte;
        extern int mem_init_done;
index 3f6e55c79181167f7730963704d1801487228fcc..2ee176610e7c684a477fe7ffa3efce91c1a1c103 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/module.h>
+#include <asm/ibm4xx.h>
 #include <asm/ocp.h>
 
 struct ocp_sys_info_data ocp_sys_info = {
index 85053b2816a9dd9a40a394ca5cc7299118f13953..7a97c7440b30267f84e45b2773e85bd8f545bdd0 100644 (file)
@@ -365,13 +365,13 @@ int qspan_pcibios_find_class(unsigned int class_code, unsigned short index,
 }
 
 void __init
-m8xx_pcibios_fixup(void))
+m8xx_pcibios_fixup(void)
 {
    /* Lots to do here, all board and configuration specific. */
 }
 
 void __init
-m8xx_setup_pci_ptrs(void))
+m8xx_setup_pci_ptrs(void)
 {
        set_config_access_method(qspan);
 
index 2782cf9da5b47b2057d20314e4af604183c01196..b9a1ce1f28e488e25ab251350316475f1f114395 100644 (file)
@@ -481,9 +481,17 @@ out:
 
 /* Diagnose 224 functions */
 
-static void diag224(void *ptr)
+static int diag224(void *ptr)
 {
-       asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory");
+       int rc = -ENOTSUPP;
+
+       asm volatile(
+               "       diag    %1,%2,0x224\n"
+               "0:     lhi     %0,0x0\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "+d" (rc) :"d" (0), "d" (ptr) : "memory");
+       return rc;
 }
 
 static int diag224_get_name_table(void)
@@ -492,7 +500,10 @@ static int diag224_get_name_table(void)
        diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
        if (!diag224_cpu_names)
                return -ENOMEM;
-       diag224(diag224_cpu_names);
+       if (diag224(diag224_cpu_names)) {
+               kfree(diag224_cpu_names);
+               return -ENOTSUPP;
+       }
        EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
        return 0;
 }
index dca6eaf82c80859a847802a1d6e975e8682a7691..1b2f5ce45320967275e3da19d6d33d43707e1a21 100644 (file)
@@ -163,7 +163,7 @@ unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION;
 
 static debug_info_t *debug_area_first = NULL;
 static debug_info_t *debug_area_last = NULL;
-static DECLARE_MUTEX(debug_lock);
+static DEFINE_MUTEX(debug_mutex);
 
 static int initialized;
 
@@ -576,7 +576,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length,
        int rc = 0;
        file_private_info_t *p_info;
 
-       down(&debug_lock);
+       mutex_lock(&debug_mutex);
        p_info = ((file_private_info_t *) file->private_data);
        if (p_info->view->input_proc)
                rc = p_info->view->input_proc(p_info->debug_info_org,
@@ -584,7 +584,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length,
                                              length, offset);
        else
                rc = -EPERM;
-       up(&debug_lock);
+       mutex_unlock(&debug_mutex);
        return rc;              /* number of input characters */
 }
 
@@ -602,7 +602,7 @@ debug_open(struct inode *inode, struct file *file)
        file_private_info_t *p_info;
        debug_info_t *debug_info, *debug_info_snapshot;
 
-       down(&debug_lock);
+       mutex_lock(&debug_mutex);
        debug_info = file->f_path.dentry->d_inode->i_private;
        /* find debug view */
        for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
@@ -653,7 +653,7 @@ found:
        file->private_data = p_info;
        debug_info_get(debug_info);
 out:
-       up(&debug_lock);
+       mutex_unlock(&debug_mutex);
        return rc;
 }
 
@@ -688,7 +688,7 @@ debug_register (char *name, int pages_per_area, int nr_areas, int buf_size)
 
        if (!initialized)
                BUG();
-       down(&debug_lock);
+       mutex_lock(&debug_mutex);
 
         /* create new debug_info */
 
@@ -702,7 +702,7 @@ out:
         if (!rc){
                printk(KERN_ERR "debug: debug_register failed for %s\n",name);
         }
-       up(&debug_lock);
+       mutex_unlock(&debug_mutex);
        return rc;
 }
 
@@ -716,9 +716,9 @@ debug_unregister(debug_info_t * id)
 {
        if (!id)
                goto out;
-       down(&debug_lock);
+       mutex_lock(&debug_mutex);
        debug_info_put(id);
-       up(&debug_lock);
+       mutex_unlock(&debug_mutex);
 
 out:
        return;
@@ -1054,11 +1054,11 @@ __init debug_init(void)
        int rc = 0;
 
        s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
-       down(&debug_lock);
+       mutex_lock(&debug_mutex);
        debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
        printk(KERN_INFO "debug: Initialization complete\n");
        initialized = 1;
-       up(&debug_lock);
+       mutex_unlock(&debug_mutex);
 
        return rc;
 }
index 6bfb0889eb1076510f4856a84ea76d5820de4f7c..51d6309e7f3bc90939335c6269c04170ab987481 100644 (file)
@@ -102,7 +102,7 @@ static struct resource data_resource = {
 /*
  * cpu_init() initializes state that is per-CPU.
  */
-void __devinit cpu_init (void)
+void __cpuinit cpu_init(void)
 {
         int addr = hard_smp_processor_id();
 
@@ -915,7 +915,7 @@ setup_arch(char **cmdline_p)
        setup_zfcpdump(console_devno);
 }
 
-void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 {
    printk("cpu %d "
 #ifdef CONFIG_SMP
index 09f028a3266ba7698061422c3dfd5c0f2998827a..8ff2feaf9b00357996efe466410da5181f70ce39 100644 (file)
@@ -492,7 +492,7 @@ static unsigned int __init smp_count_cpus(void)
 /*
  *     Activate a secondary processor.
  */
-int __devinit start_secondary(void *cpuvoid)
+int __cpuinit start_secondary(void *cpuvoid)
 {
        /* Setup the cpu */
        cpu_init();
@@ -741,7 +741,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                        smp_create_idle(cpu);
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void __init smp_prepare_boot_cpu(void)
 {
        BUG_ON(smp_processor_id() != 0);
 
@@ -750,7 +750,7 @@ void __devinit smp_prepare_boot_cpu(void)
        current_set[0] = current;
 }
 
-void smp_cpus_done(unsigned int max_cpus)
+void __init smp_cpus_done(unsigned int max_cpus)
 {
        cpu_present_map = cpu_possible_map;
 }
index 7b1122417050a8cd01c991f876398e98f86506f5..883b03b040c455c471c704e605c62e8163c607e1 100644 (file)
@@ -39,7 +39,7 @@ cflags-$(CONFIG_CPU_SH2A)             := -m2a $(call cc-option,-m2a-nofpu,)
 cflags-$(CONFIG_CPU_SH3)               := -m3
 cflags-$(CONFIG_CPU_SH4)               := -m4 \
        $(call cc-option,-mno-implicit-fp,-m4-nofpu)
-cflags-$(CONFIG_CPU_SH4A)              := -m4a $(call cc-option,-m4a-nofpu,)
+cflags-$(CONFIG_CPU_SH4A)              := $(call cc-option,-m4a,) $(call cc-option,-m4a-nofpu,)
 
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += -mb
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -ml
index 911ce1cdbd7f86865bb903ac054b359f0f6be82b..e143017c8975a0662ca64c2116106e8f97389533 100644 (file)
@@ -38,8 +38,8 @@ static struct platform_device *se73180_devices[] __initdata = {
 
 static int __init se73180_devices_setup(void)
 {
-       return platform_add_devices(sh7343se_platform_devices,
-                                   ARRAY_SIZE(sh7343se_platform_devices));
+       return platform_add_devices(se73180_devices,
+                                   ARRAY_SIZE(se73180_devices));
 }
 __initcall(se73180_devices_setup);
 
index cc1cb04fa61832975ebfde104dc24e1066b2b6ca..4d335077a3ffc8c590594f6065ece5573be91d31 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/microdev.h>
index 70f12907647f13a32e73b3476c967dcb3cd0d237..d70e5c8461b56e4b60c72c43ae9204c4b0637a8e 100644 (file)
@@ -28,7 +28,7 @@ static void disable_voyagergx_irq(unsigned int irq)
        unsigned long val;
        unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-       pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+       pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
        val = readl((void __iomem *)VOYAGER_INT_MASK);
        val &= ~mask;
        writel(val, (void __iomem *)VOYAGER_INT_MASK);
@@ -39,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq)
        unsigned long val;
        unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-       pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+       pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
        val = readl((void __iomem *)VOYAGER_INT_MASK);
        val |= mask;
        writel(val, (void __iomem *)VOYAGER_INT_MASK);
@@ -125,11 +125,12 @@ int voyagergx_irq_demux(int irq)
                        i = 17;
                else
                        printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
-               pr_debug("voyagergx_irq_demux %d \n", i);
-               if (i < VOYAGER_IRQ_NUM) {
+               pr_debug("voyagergx_irq_demux %ld \n", i);
+               if (i < VOYAGER_IRQ_NUM) {
                        irq = VOYAGER_IRQ_BASE + i;
-                       if (voyagergx_demux[i].func != 0)
-                               irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev);
+                       if (voyagergx_demux[i].func != 0)
+                               irq = voyagergx_demux[i].func(irq,
+                                               voyagergx_demux[i].dev);
                }
        }
        return irq;
index 8057a27a1bc6bb760d81ce01ee800b7638ceebaf..cf8e119943306abd598cd1c761c7ce118891cb14 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <asm/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
index 849a9e191391dee23ea1d4c48a85b7c541471513..ebc73b85094a9b9b63a3667556c077c432e0e624 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -149,6 +150,11 @@ static int __init cf_init_se(void)
        ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
        return 0;
 }
+#else
+static int __init cf_init_se(void)
+{
+       return -1;
+}
 #endif
 
 int __init cf_init(void)
index 832c0b4a1e6ca2fe78583e57af93ebd44f78d7bc..b0b59d4a33ca8ada675d624481d76b1708c9a4fc 100644 (file)
@@ -320,6 +320,9 @@ skip_restore:
 
        .align  2
 5:     .long   0x00001000      ! DSP
+#ifdef CONFIG_KGDB_NMI
+6:     .long   in_nmi
+#endif
 7:     .long   0x30000000
 
 ! common exception handler
index fcb2c41bc34e766c9a6650abdde04e6904846230..a33429463e96cd0c758b9f05f631a5d610025d6e 100644 (file)
@@ -111,7 +111,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static int shoc_clk_set_rate(struct clk *clk, unsigned long rate)
+static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
 {
        unsigned long frqcr3;
        unsigned int tmp;
index 8cd04904c77a02c9fc6dfff2f28756fc8ca8f282..fab2eb07196b2538ac24bf5b05733df66fb1ee73 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/smp.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
 
index dbebaddcfe394974686c833a39f837d562720fa5..283e1425ced57046d63cd850317f1c6b5e8dd766 100644 (file)
@@ -10,6 +10,8 @@
  * Free Software Foundation; either version 2 of the License, or (at your
  * option) any later version.
  */
+
+#include <linux/err.h>
 #include <linux/cache.h>
 #include <linux/cpumask.h>
 #include <linux/delay.h>
index a6bcc913d25e8687f96ad783220fbdfaa64f111b..4e7e747d1b696c59a16016cb42aedbe516ae734b 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/string.h>
 #include <asm/timer.h>
 
-static struct sys_timer *sys_timers[] __initdata = {
+static struct sys_timer *sys_timers[] = {
 #ifdef CONFIG_SH_TMU
        &tmu_timer,
 #endif
@@ -26,7 +26,7 @@ static struct sys_timer *sys_timers[] __initdata = {
        NULL,
 };
 
-static char timer_override[10] __initdata;
+static char timer_override[10];
 static int __init timer_setup(char *str)
 {
        if (str)
@@ -53,4 +53,3 @@ struct sys_timer *get_sys_timer(void)
 
        return NULL;
 }
-
index e146bafcd14fb11459e60f1db77549502b22644e..2aa9438361bcb99a75ac7369dd0c1c2ea8ba5997 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/elf.h>
+#include <linux/sched.h>
 
 /*
  * Should the kernel map a VDSO page into processes and pass its
index be03d74e99cbc4412c713ba96141b66a0443a21d..0c7b7e33abdcfd6e2ddf242623683d3ee89d7b6c 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/addrspace.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/mmu.h>
 
 /*
  * Remap an arbitrary physical address space into the kernel virtual
index fb51660847c8380e92b315099c659b432f86f191..3334f99b5835f0a113514fa3e25dcf886690dbd5 100644 (file)
@@ -521,10 +521,10 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
                bus->resource[0]->start = PCIBIOS_MIN_IO;
                bus->resource[1]->start = PCIBIOS_MIN_MEM;
 #else
-               bus->resource[0]->end = 0
-               bus->resource[1]->end = 0
-               bus->resource[0]->start =0
-                 bus->resource[1]->start = 0;
+               bus->resource[0]->end = 0;
+               bus->resource[1]->end = 0;
+               bus->resource[0]->start =0;
+               bus->resource[1]->start = 0;
 #endif
                /* Turn off downstream PF memory address range by default */
                bus->resource[2]->start = 1024*1024;
index bd992c0048f0aa1d8801b6dde2b3380982268ef9..fbcc00c6c06ea6dff4c0706ac86a5806b1b63b4e 100644 (file)
@@ -178,6 +178,13 @@ config ARCH_HAS_ILOG2_U64
        bool
        default n
 
+config EMULATED_CMPXCHG
+       bool
+       default y
+       help
+         Sparc32 does not have a CAS instruction like sparc64. cmpxchg()
+         is emulated, and therefore it is not completely atomic.
+
 config SUN_PM
        bool
        default y
index f1401b57ccc70992424e6d391805d988a75e1b85..7b4612da74a6ff0f830beba61d8eea3142c2b515 100644 (file)
@@ -148,7 +148,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
 }
 
 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
-static void __init kick_start_clock(void)
+static void __devinit kick_start_clock(void)
 {
        struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
        unsigned char sec;
@@ -223,7 +223,7 @@ static __inline__ int has_low_battery(void)
        return (data1 == data2);        /* Was the write blocked? */
 }
 
-static void __init mostek_set_system_time(void)
+static void __devinit mostek_set_system_time(void)
 {
        unsigned int year, mon, day, hour, min, sec;
        struct mostek48t02 *mregs;
index 559335f4917d1d1d03ee7ea28b9ff8e7d6948c6e..cbddeb38ffdab2bf5f25562190dd833bf2f9ded4 100644 (file)
@@ -2,6 +2,7 @@
  * atomic32.c: 32-bit atomic_t implementation
  *
  * Copyright (C) 2004 Keith M Wesolowski
+ * Copyright (C) 2007 Kyle McMartin
  * 
  * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf
  */
@@ -117,3 +118,17 @@ unsigned long ___change_bit(unsigned long *addr, unsigned long mask)
        return old & mask;
 }
 EXPORT_SYMBOL(___change_bit);
+
+unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
+{
+       unsigned long flags;
+       u32 prev;
+
+       spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
+       if ((prev = *ptr) == old)
+               *ptr = new;
+       spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
+
+       return (unsigned long)prev;
+}
+EXPORT_SYMBOL(__cmpxchg_u32);
index 831781cab271826827a29c404d5dc1509fb85ba9..89a1b469b93df149b21c1c65c5d1723d36e97e09 100644 (file)
@@ -147,10 +147,10 @@ config SMP
          If you don't know what to do here, say N.
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-64)"
-       range 2 64
+       int "Maximum number of CPUs (2-1024)"
+       range 2 1024
        depends on SMP
-       default "32"
+       default "64"
 
 source "drivers/cpufreq/Kconfig"
 
@@ -396,6 +396,15 @@ config SCHED_SMT
          when dealing with UltraSPARC cpus 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 CMDLINE_BOOL
index c749dccacc3203083255b6b6ea2a35764b5cecc9..f964bf28d21a2568fed3a436af906c3e78d238ea 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.70 2002/02/09 19:49:30 davem Exp $
+#
 # Makefile for the linux kernel.
 #
 
@@ -8,11 +8,11 @@ EXTRA_CFLAGS := -Werror
 extra-y                := head.o init_task.o vmlinux.lds
 
 obj-y          := process.o setup.o cpu.o idprom.o \
-                  traps.o devices.o auxio.o una_asm.o \
+                  traps.o auxio.o una_asm.o sysfs.o \
                   irq.o ptrace.o time.o sys_sparc.o signal.o \
                   unaligned.o central.o pci.o starfire.o semaphore.o \
                   power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
-                  visemul.o prom.o of_device.o hvapi.o
+                  visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-$(CONFIG_PCI)       += ebus.o isa.o pci_common.o pci_iommu.o \
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
deleted file mode 100644 (file)
index 0e03c8e..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/* devices.c: Initial scan of the prom device tree for important
- *            Sparc device nodes which we need to find.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/threads.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/bootmem.h>
-
-#include <asm/page.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/smp.h>
-#include <asm/spitfire.h>
-#include <asm/timer.h>
-#include <asm/cpudata.h>
-
-/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
- * operations in asm/ns87303.h
- */
-DEFINE_SPINLOCK(ns87303_lock);
-
-extern void cpu_probe(void);
-extern void central_probe(void);
-
-static const char *cpu_mid_prop(void)
-{
-       if (tlb_type == spitfire)
-               return "upa-portid";
-       return "portid";
-}
-
-static int get_cpu_mid(struct device_node *dp)
-{
-       struct property *prop;
-
-       if (tlb_type == hypervisor) {
-               struct linux_prom64_registers *reg;
-               int len;
-
-               prop = of_find_property(dp, "cpuid", &len);
-               if (prop && len == 4)
-                       return *(int *) prop->value;
-
-               prop = of_find_property(dp, "reg", NULL);
-               reg = prop->value;
-               return (reg[0].phys_addr >> 32) & 0x0fffffffUL;
-       } else {
-               const char *prop_name = cpu_mid_prop();
-
-               prop = of_find_property(dp, prop_name, NULL);
-               if (prop)
-                       return *(int *) prop->value;
-               return 0;
-       }
-}
-
-static int check_cpu_node(struct device_node *dp, int *cur_inst,
-                         int (*compare)(struct device_node *, int, void *),
-                         void *compare_arg,
-                         struct device_node **dev_node, int *mid)
-{
-       if (!compare(dp, *cur_inst, compare_arg)) {
-               if (dev_node)
-                       *dev_node = dp;
-               if (mid)
-                       *mid = get_cpu_mid(dp);
-               return 0;
-       }
-
-       (*cur_inst)++;
-
-       return -ENODEV;
-}
-
-static int __cpu_find_by(int (*compare)(struct device_node *, int, void *),
-                        void *compare_arg,
-                        struct device_node **dev_node, int *mid)
-{
-       struct device_node *dp;
-       int cur_inst;
-
-       cur_inst = 0;
-       for_each_node_by_type(dp, "cpu") {
-               int err = check_cpu_node(dp, &cur_inst,
-                                        compare, compare_arg,
-                                        dev_node, mid);
-               if (err == 0)
-                       return 0;
-       }
-
-       return -ENODEV;
-}
-
-static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg)
-{
-       int desired_instance = (int) (long) _arg;
-
-       if (instance == desired_instance)
-               return 0;
-       return -ENODEV;
-}
-
-int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid)
-{
-       return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
-                            dev_node, mid);
-}
-
-static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg)
-{
-       int desired_mid = (int) (long) _arg;
-       int this_mid;
-
-       this_mid = get_cpu_mid(dp);
-       if (this_mid == desired_mid)
-               return 0;
-       return -ENODEV;
-}
-
-int cpu_find_by_mid(int mid, struct device_node **dev_node)
-{
-       return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
-                            dev_node, NULL);
-}
-
-void __init device_scan(void)
-{
-       /* FIX ME FAST... -DaveM */
-       ioport_resource.end = 0xffffffffffffffffUL;
-
-       prom_printf("Booting Linux...\n");
-
-#ifndef CONFIG_SMP
-       {
-               struct device_node *dp;
-               int err, def;
-
-               err = cpu_find_by_instance(0, &dp, NULL);
-               if (err) {
-                       prom_printf("No cpu nodes, cannot continue\n");
-                       prom_halt();
-               }
-               cpu_data(0).clock_tick =
-                       of_getintprop_default(dp, "clock-frequency", 0);
-
-               def = ((tlb_type == hypervisor) ?
-                      (8 * 1024) :
-                      (16 * 1024));
-               cpu_data(0).dcache_size = of_getintprop_default(dp,
-                                                               "dcache-size",
-                                                               def);
-
-               def = 32;
-               cpu_data(0).dcache_line_size =
-                       of_getintprop_default(dp, "dcache-line-size", def);
-
-               def = 16 * 1024;
-               cpu_data(0).icache_size = of_getintprop_default(dp,
-                                                               "icache-size",
-                                                               def);
-
-               def = 32;
-               cpu_data(0).icache_line_size =
-                       of_getintprop_default(dp, "icache-line-size", def);
-
-               def = ((tlb_type == hypervisor) ?
-                      (3 * 1024 * 1024) :
-                      (4 * 1024 * 1024));
-               cpu_data(0).ecache_size = of_getintprop_default(dp,
-                                                               "ecache-size",
-                                                               def);
-
-               def = 64;
-               cpu_data(0).ecache_line_size =
-                       of_getintprop_default(dp, "ecache-line-size", def);
-               printk("CPU[0]: Caches "
-                      "D[sz(%d):line_sz(%d)] "
-                      "I[sz(%d):line_sz(%d)] "
-                      "E[sz(%d):line_sz(%d)]\n",
-                      cpu_data(0).dcache_size, cpu_data(0).dcache_line_size,
-                      cpu_data(0).icache_size, cpu_data(0).icache_line_size,
-                      cpu_data(0).ecache_size, cpu_data(0).ecache_line_size);
-       }
-#endif
-
-       central_probe();
-
-       cpu_probe();
-}
index 732b77cb71f84fd0b356177a3341946969634cff..7d1a11822a1e2c5407300ac346792397af9d21cf 100644 (file)
@@ -1725,96 +1725,142 @@ real_hard_smp_processor_id:
         * returns %o0: sysino
         */
        .globl  sun4v_devino_to_sysino
+       .type   sun4v_devino_to_sysino,#function
 sun4v_devino_to_sysino:
        mov     HV_FAST_INTR_DEVINO2SYSINO, %o5
        ta      HV_FAST_TRAP
        retl
         mov    %o1, %o0
+       .size   sun4v_devino_to_sysino, .-sun4v_devino_to_sysino
 
        /* %o0: sysino
         *
         * returns %o0: intr_enabled (HV_INTR_{DISABLED,ENABLED})
         */
        .globl  sun4v_intr_getenabled
+       .type   sun4v_intr_getenabled,#function
 sun4v_intr_getenabled:
        mov     HV_FAST_INTR_GETENABLED, %o5
        ta      HV_FAST_TRAP
        retl
         mov    %o1, %o0
+       .size   sun4v_intr_getenabled, .-sun4v_intr_getenabled
 
        /* %o0: sysino
         * %o1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
         */
        .globl  sun4v_intr_setenabled
+       .type   sun4v_intr_setenabled,#function
 sun4v_intr_setenabled:
        mov     HV_FAST_INTR_SETENABLED, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_intr_setenabled, .-sun4v_intr_setenabled
 
        /* %o0: sysino
         *
         * returns %o0: intr_state (HV_INTR_STATE_*)
         */
        .globl  sun4v_intr_getstate
+       .type   sun4v_intr_getstate,#function
 sun4v_intr_getstate:
        mov     HV_FAST_INTR_GETSTATE, %o5
        ta      HV_FAST_TRAP
        retl
         mov    %o1, %o0
+       .size   sun4v_intr_getstate, .-sun4v_intr_getstate
 
        /* %o0: sysino
         * %o1: intr_state (HV_INTR_STATE_*)
         */
        .globl  sun4v_intr_setstate
+       .type   sun4v_intr_setstate,#function
 sun4v_intr_setstate:
        mov     HV_FAST_INTR_SETSTATE, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_intr_setstate, .-sun4v_intr_setstate
 
        /* %o0: sysino
         *
         * returns %o0: cpuid
         */
        .globl  sun4v_intr_gettarget
+       .type   sun4v_intr_gettarget,#function
 sun4v_intr_gettarget:
        mov     HV_FAST_INTR_GETTARGET, %o5
        ta      HV_FAST_TRAP
        retl
         mov    %o1, %o0
+       .size   sun4v_intr_gettarget, .-sun4v_intr_gettarget
 
        /* %o0: sysino
         * %o1: cpuid
         */
        .globl  sun4v_intr_settarget
+       .type   sun4v_intr_settarget,#function
 sun4v_intr_settarget:
        mov     HV_FAST_INTR_SETTARGET, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_intr_settarget, .-sun4v_intr_settarget
 
-       /* %o0: type
-        * %o1: queue paddr
-        * %o2: num queue entries
+       /* %o0: cpuid
+        * %o1: pc
+        * %o2: rtba
+        * %o3: arg0
         *
         * returns %o0: status
         */
-       .globl  sun4v_cpu_qconf
-sun4v_cpu_qconf:
-       mov     HV_FAST_CPU_QCONF, %o5
+       .globl  sun4v_cpu_start
+       .type   sun4v_cpu_start,#function
+sun4v_cpu_start:
+       mov     HV_FAST_CPU_START, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_cpu_start, .-sun4v_cpu_start
 
-       /* returns %o0: status
+       /* %o0: cpuid
+        *
+        * returns %o0: status
         */
+       .globl  sun4v_cpu_stop
+       .type   sun4v_cpu_stop,#function
+sun4v_cpu_stop:
+       mov     HV_FAST_CPU_STOP, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_cpu_stop, .-sun4v_cpu_stop
+
+       /* returns %o0: status  */
        .globl  sun4v_cpu_yield
+       .type   sun4v_cpu_yield, #function
 sun4v_cpu_yield:
        mov     HV_FAST_CPU_YIELD, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_cpu_yield, .-sun4v_cpu_yield
+
+       /* %o0: type
+        * %o1: queue paddr
+        * %o2: num queue entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_cpu_qconf
+       .type   sun4v_cpu_qconf,#function
+sun4v_cpu_qconf:
+       mov     HV_FAST_CPU_QCONF, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_cpu_qconf, .-sun4v_cpu_qconf
 
        /* %o0: num cpus in cpu list
         * %o1: cpu list paddr
@@ -1823,11 +1869,13 @@ sun4v_cpu_yield:
         * returns %o0: status
         */
        .globl  sun4v_cpu_mondo_send
+       .type   sun4v_cpu_mondo_send,#function
 sun4v_cpu_mondo_send:
        mov     HV_FAST_CPU_MONDO_SEND, %o5
        ta      HV_FAST_TRAP
        retl
         nop
+       .size   sun4v_cpu_mondo_send, .-sun4v_cpu_mondo_send
 
        /* %o0: CPU ID
         *
@@ -1835,6 +1883,7 @@ sun4v_cpu_mondo_send:
         *         %o0: cpu state as HV_CPU_STATE_*
         */
        .globl  sun4v_cpu_state
+       .type   sun4v_cpu_state,#function
 sun4v_cpu_state:
        mov     HV_FAST_CPU_STATE, %o5
        ta      HV_FAST_TRAP
@@ -1843,6 +1892,37 @@ sun4v_cpu_state:
        mov     %o1, %o0
 1:     retl
         nop
+       .size   sun4v_cpu_state, .-sun4v_cpu_state
+
+       /* %o0: virtual address
+        * %o1: must be zero
+        * %o2: TTE
+        * %o3: HV_MMU_* flags
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_mmu_map_perm_addr
+       .type   sun4v_mmu_map_perm_addr,#function
+sun4v_mmu_map_perm_addr:
+       mov     HV_FAST_MMU_MAP_PERM_ADDR, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_mmu_map_perm_addr, .-sun4v_mmu_map_perm_addr
+
+       /* %o0: number of TSB descriptions
+        * %o1: TSB descriptions real address
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_mmu_tsb_ctx0
+       .type   sun4v_mmu_tsb_ctx0,#function
+sun4v_mmu_tsb_ctx0:
+       mov     HV_FAST_MMU_TSB_CTX0, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_mmu_tsb_ctx0, .-sun4v_mmu_tsb_ctx0
 
        /* %o0: API group number
         * %o1: pointer to unsigned long major number storage
@@ -1851,6 +1931,7 @@ sun4v_cpu_state:
         * returns %o0: status
         */
        .globl  sun4v_get_version
+       .type   sun4v_get_version,#function
 sun4v_get_version:
        mov     HV_CORE_GET_VER, %o5
        mov     %o1, %o3
@@ -1859,6 +1940,7 @@ sun4v_get_version:
        stx     %o1, [%o3]
        retl
         stx    %o2, [%o4]
+       .size   sun4v_get_version, .-sun4v_get_version
 
        /* %o0: API group number
         * %o1: desired major number
@@ -1868,18 +1950,49 @@ sun4v_get_version:
         * returns %o0: status
         */
        .globl  sun4v_set_version
+       .type   sun4v_set_version,#function
 sun4v_set_version:
        mov     HV_CORE_SET_VER, %o5
        mov     %o3, %o4
        ta      HV_CORE_TRAP
        retl
         stx    %o1, [%o4]
+       .size   sun4v_set_version, .-sun4v_set_version
+
+       /* %o0: pointer to unsigned long time
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_tod_get
+       .type   sun4v_tod_get,#function
+sun4v_tod_get:
+       mov     %o0, %o4
+       mov     HV_FAST_TOD_GET, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_tod_get, .-sun4v_tod_get
+
+       /* %o0: time
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_tod_set
+       .type   sun4v_tod_set,#function
+sun4v_tod_set:
+       mov     HV_FAST_TOD_SET, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_tod_set, .-sun4v_tod_set
 
        /* %o0: pointer to unsigned long status
         *
         * returns %o0: signed character
         */
        .globl  sun4v_con_getchar
+       .type   sun4v_con_getchar,#function
 sun4v_con_getchar:
        mov     %o0, %o4
        mov     HV_FAST_CONS_GETCHAR, %o5
@@ -1889,17 +2002,20 @@ sun4v_con_getchar:
        stx     %o0, [%o4]
        retl
         sra    %o1, 0, %o0
+       .size   sun4v_con_getchar, .-sun4v_con_getchar
 
        /* %o0: signed long character
         *
         * returns %o0: status
         */
        .globl  sun4v_con_putchar
+       .type   sun4v_con_putchar,#function
 sun4v_con_putchar:
        mov     HV_FAST_CONS_PUTCHAR, %o5
        ta      HV_FAST_TRAP
        retl
         sra    %o0, 0, %o0
+       .size   sun4v_con_putchar, .-sun4v_con_putchar
 
        /* %o0: buffer real address
         * %o1: buffer size
@@ -1908,6 +2024,7 @@ sun4v_con_putchar:
         * returns %o0: status
         */
        .globl  sun4v_con_read
+       .type   sun4v_con_read,#function
 sun4v_con_read:
        mov     %o2, %o4
        mov     HV_FAST_CONS_READ, %o5
@@ -1922,6 +2039,7 @@ sun4v_con_read:
        stx     %o1, [%o4]
 1:     retl
         nop
+       .size   sun4v_con_read, .-sun4v_con_read
 
        /* %o0: buffer real address
         * %o1: buffer size
@@ -1930,6 +2048,7 @@ sun4v_con_read:
         * returns %o0: status
         */
        .globl  sun4v_con_write
+       .type   sun4v_con_write,#function
 sun4v_con_write:
        mov     %o2, %o4
        mov     HV_FAST_CONS_WRITE, %o5
@@ -1937,3 +2056,539 @@ sun4v_con_write:
        stx     %o1, [%o4]
        retl
         nop
+       .size   sun4v_con_write, .-sun4v_con_write
+
+       /* %o0: soft state
+        * %o1: address of description string
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_mach_set_soft_state
+       .type   sun4v_mach_set_soft_state,#function
+sun4v_mach_set_soft_state:
+       mov     HV_FAST_MACH_SET_SOFT_STATE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_mach_set_soft_state, .-sun4v_mach_set_soft_state
+
+       /* %o0: exit code
+        *
+        * Does not return.
+        */
+       .globl  sun4v_mach_exit
+       .type   sun4v_mach_exit,#function
+sun4v_mach_exit:
+       mov     HV_FAST_MACH_EXIT, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_mach_exit, .-sun4v_mach_exit
+
+       /* %o0: buffer real address
+        * %o1: buffer length
+        * %o2: pointer to unsigned long real_buf_len
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_mach_desc
+       .type   sun4v_mach_desc,#function
+sun4v_mach_desc:
+       mov     %o2, %o4
+       mov     HV_FAST_MACH_DESC, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_mach_desc, .-sun4v_mach_desc
+
+       /* %o0: new timeout in milliseconds
+        * %o1: pointer to unsigned long orig_timeout
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_mach_set_watchdog
+       .type   sun4v_mach_set_watchdog,#function
+sun4v_mach_set_watchdog:
+       mov     %o1, %o4
+       mov     HV_FAST_MACH_SET_WATCHDOG, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_mach_set_watchdog, .-sun4v_mach_set_watchdog
+
+       /* No inputs and does not return.  */
+       .globl  sun4v_mach_sir
+       .type   sun4v_mach_sir,#function
+sun4v_mach_sir:
+       mov     %o1, %o4
+       mov     HV_FAST_MACH_SIR, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_mach_sir, .-sun4v_mach_sir
+
+       /* %o0: channel
+        * %o1: ra
+        * %o2: num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_tx_qconf
+       .type   sun4v_ldc_tx_qconf,#function
+sun4v_ldc_tx_qconf:
+       mov     HV_FAST_LDC_TX_QCONF, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_tx_qconf, .-sun4v_ldc_tx_qconf
+
+       /* %o0: channel
+        * %o1: pointer to unsigned long ra
+        * %o2: pointer to unsigned long num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_tx_qinfo
+       .type   sun4v_ldc_tx_qinfo,#function
+sun4v_ldc_tx_qinfo:
+       mov     %o1, %g1
+       mov     %o2, %g2
+       mov     HV_FAST_LDC_TX_QINFO, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       retl
+        nop
+       .size   sun4v_ldc_tx_qinfo, .-sun4v_ldc_tx_qinfo
+
+       /* %o0: channel
+        * %o1: pointer to unsigned long head_off
+        * %o2: pointer to unsigned long tail_off
+        * %o2: pointer to unsigned long chan_state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_tx_get_state
+       .type   sun4v_ldc_tx_get_state,#function
+sun4v_ldc_tx_get_state:
+       mov     %o1, %g1
+       mov     %o2, %g2
+       mov     %o3, %g3
+       mov     HV_FAST_LDC_TX_GET_STATE, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       stx     %o3, [%g3]
+       retl
+        nop
+       .size   sun4v_ldc_tx_get_state, .-sun4v_ldc_tx_get_state
+
+       /* %o0: channel
+        * %o1: tail_off
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_tx_set_qtail
+       .type   sun4v_ldc_tx_set_qtail,#function
+sun4v_ldc_tx_set_qtail:
+       mov     HV_FAST_LDC_TX_SET_QTAIL, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_tx_set_qtail, .-sun4v_ldc_tx_set_qtail
+
+       /* %o0: channel
+        * %o1: ra
+        * %o2: num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_rx_qconf
+       .type   sun4v_ldc_rx_qconf,#function
+sun4v_ldc_rx_qconf:
+       mov     HV_FAST_LDC_RX_QCONF, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_rx_qconf, .-sun4v_ldc_rx_qconf
+
+       /* %o0: channel
+        * %o1: pointer to unsigned long ra
+        * %o2: pointer to unsigned long num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_rx_qinfo
+       .type   sun4v_ldc_rx_qinfo,#function
+sun4v_ldc_rx_qinfo:
+       mov     %o1, %g1
+       mov     %o2, %g2
+       mov     HV_FAST_LDC_RX_QINFO, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       retl
+        nop
+       .size   sun4v_ldc_rx_qinfo, .-sun4v_ldc_rx_qinfo
+
+       /* %o0: channel
+        * %o1: pointer to unsigned long head_off
+        * %o2: pointer to unsigned long tail_off
+        * %o2: pointer to unsigned long chan_state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_rx_get_state
+       .type   sun4v_ldc_rx_get_state,#function
+sun4v_ldc_rx_get_state:
+       mov     %o1, %g1
+       mov     %o2, %g2
+       mov     %o3, %g3
+       mov     HV_FAST_LDC_RX_GET_STATE, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       stx     %o3, [%g3]
+       retl
+        nop
+       .size   sun4v_ldc_rx_get_state, .-sun4v_ldc_rx_get_state
+
+       /* %o0: channel
+        * %o1: head_off
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_rx_set_qhead
+       .type   sun4v_ldc_rx_set_qhead,#function
+sun4v_ldc_rx_set_qhead:
+       mov     HV_FAST_LDC_RX_SET_QHEAD, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_rx_set_qhead, .-sun4v_ldc_rx_set_qhead
+
+       /* %o0: channel
+        * %o1: ra
+        * %o2: num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_set_map_table
+       .type   sun4v_ldc_set_map_table,#function
+sun4v_ldc_set_map_table:
+       mov     HV_FAST_LDC_SET_MAP_TABLE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_set_map_table, .-sun4v_ldc_set_map_table
+
+       /* %o0: channel
+        * %o1: pointer to unsigned long ra
+        * %o2: pointer to unsigned long num_entries
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_get_map_table
+       .type   sun4v_ldc_get_map_table,#function
+sun4v_ldc_get_map_table:
+       mov     %o1, %g1
+       mov     %o2, %g2
+       mov     HV_FAST_LDC_GET_MAP_TABLE, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       retl
+        nop
+       .size   sun4v_ldc_get_map_table, .-sun4v_ldc_get_map_table
+
+       /* %o0: channel
+        * %o1: dir_code
+        * %o2: tgt_raddr
+        * %o3: lcl_raddr
+        * %o4: len
+        * %o5: pointer to unsigned long actual_len
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_copy
+       .type   sun4v_ldc_copy,#function
+sun4v_ldc_copy:
+       mov     %o5, %g1
+       mov     HV_FAST_LDC_COPY, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       retl
+        nop
+       .size   sun4v_ldc_copy, .-sun4v_ldc_copy
+
+       /* %o0: channel
+        * %o1: cookie
+        * %o2: pointer to unsigned long ra
+        * %o3: pointer to unsigned long perm
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_mapin
+       .type   sun4v_ldc_mapin,#function
+sun4v_ldc_mapin:
+       mov     %o2, %g1
+       mov     %o3, %g2
+       mov     HV_FAST_LDC_MAPIN, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       stx     %o2, [%g2]
+       retl
+        nop
+       .size   sun4v_ldc_mapin, .-sun4v_ldc_mapin
+
+       /* %o0: ra
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_unmap
+       .type   sun4v_ldc_unmap,#function
+sun4v_ldc_unmap:
+       mov     HV_FAST_LDC_UNMAP, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_unmap, .-sun4v_ldc_unmap
+
+       /* %o0: cookie
+        * %o1: mte_cookie
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ldc_revoke
+       .type   sun4v_ldc_revoke,#function
+sun4v_ldc_revoke:
+       mov     HV_FAST_LDC_REVOKE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ldc_revoke, .-sun4v_ldc_revoke
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: pointer to unsigned long cookie
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_get_cookie
+       .type   sun4v_vintr_get_cookie,#function
+sun4v_vintr_get_cookie:
+       mov     %o2, %g1
+       mov     HV_FAST_VINTR_GET_COOKIE, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       retl
+        nop
+       .size   sun4v_vintr_get_cookie, .-sun4v_vintr_get_cookie
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: cookie
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_set_cookie
+       .type   sun4v_vintr_set_cookie,#function
+sun4v_vintr_set_cookie:
+       mov     HV_FAST_VINTR_SET_COOKIE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_vintr_set_cookie, .-sun4v_vintr_set_cookie
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: pointer to unsigned long valid_state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_get_valid
+       .type   sun4v_vintr_get_valid,#function
+sun4v_vintr_get_valid:
+       mov     %o2, %g1
+       mov     HV_FAST_VINTR_GET_VALID, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       retl
+        nop
+       .size   sun4v_vintr_get_valid, .-sun4v_vintr_get_valid
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: valid_state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_set_valid
+       .type   sun4v_vintr_set_valid,#function
+sun4v_vintr_set_valid:
+       mov     HV_FAST_VINTR_SET_VALID, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_vintr_set_valid, .-sun4v_vintr_set_valid
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: pointer to unsigned long state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_get_state
+       .type   sun4v_vintr_get_state,#function
+sun4v_vintr_get_state:
+       mov     %o2, %g1
+       mov     HV_FAST_VINTR_GET_STATE, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       retl
+        nop
+       .size   sun4v_vintr_get_state, .-sun4v_vintr_get_state
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: state
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_set_state
+       .type   sun4v_vintr_set_state,#function
+sun4v_vintr_set_state:
+       mov     HV_FAST_VINTR_SET_STATE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_vintr_set_state, .-sun4v_vintr_set_state
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: pointer to unsigned long cpuid
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_get_target
+       .type   sun4v_vintr_get_target,#function
+sun4v_vintr_get_target:
+       mov     %o2, %g1
+       mov     HV_FAST_VINTR_GET_TARGET, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%g1]
+       retl
+        nop
+       .size   sun4v_vintr_get_target, .-sun4v_vintr_get_target
+
+       /* %o0: device handle
+        * %o1: device INO
+        * %o2: cpuid
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_vintr_set_target
+       .type   sun4v_vintr_set_target,#function
+sun4v_vintr_set_target:
+       mov     HV_FAST_VINTR_SET_TARGET, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_vintr_set_target, .-sun4v_vintr_set_target
+
+       /* %o0: NCS sub-function
+        * %o1: sub-function arg real-address
+        * %o2: sub-function arg size
+        *
+        * returns %o0: status
+        */
+       .globl  sun4v_ncs_request
+       .type   sun4v_ncs_request,#function
+sun4v_ncs_request:
+       mov     HV_FAST_NCS_REQUEST, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_ncs_request, .-sun4v_ncs_request
+
+       .globl  sun4v_svc_send
+       .type   sun4v_svc_send,#function
+sun4v_svc_send:
+       save    %sp, -192, %sp
+       mov     %i0, %o0
+       mov     %i1, %o1
+       mov     %i2, %o2
+       mov     HV_FAST_SVC_SEND, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%i3]
+       ret
+       restore
+       .size   sun4v_svc_send, .-sun4v_svc_send
+
+       .globl  sun4v_svc_recv
+       .type   sun4v_svc_recv,#function
+sun4v_svc_recv:
+       save    %sp, -192, %sp
+       mov     %i0, %o0
+       mov     %i1, %o1
+       mov     %i2, %o2
+       mov     HV_FAST_SVC_RECV, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%i3]
+       ret
+       restore
+       .size   sun4v_svc_recv, .-sun4v_svc_recv
+
+       .globl  sun4v_svc_getstatus
+       .type   sun4v_svc_getstatus,#function
+sun4v_svc_getstatus:
+       mov     HV_FAST_SVC_GETSTATUS, %o5
+       mov     %o1, %o4
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_svc_getstatus, .-sun4v_svc_getstatus
+
+       .globl  sun4v_svc_setstatus
+       .type   sun4v_svc_setstatus,#function
+sun4v_svc_setstatus:
+       mov     HV_FAST_SVC_SETSTATUS, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_svc_setstatus, .-sun4v_svc_setstatus
+
+       .globl  sun4v_svc_clrstatus
+       .type   sun4v_svc_clrstatus,#function
+sun4v_svc_clrstatus:
+       mov     HV_FAST_SVC_CLRSTATUS, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+       .size   sun4v_svc_clrstatus, .-sun4v_svc_clrstatus
+
+       .globl  sun4v_mmustat_conf
+       .type   sun4v_mmustat_conf,#function
+sun4v_mmustat_conf:
+       mov     %o1, %o4
+       mov     HV_FAST_MMUSTAT_CONF, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_mmustat_conf, .-sun4v_mmustat_conf
+
+       .globl  sun4v_mmustat_info
+       .type   sun4v_mmustat_info,#function
+sun4v_mmustat_info:
+       mov     %o0, %o4
+       mov     HV_FAST_MMUSTAT_INFO, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        nop
+       .size   sun4v_mmustat_info, .-sun4v_mmustat_info
index baea10a9819681cb409d1ae205ec36a468d3c4aa..77259526cb152daff39c213176ac02db1cae3346 100644 (file)
@@ -523,7 +523,7 @@ tlb_fixup_done:
 #else
        mov     0, %o0
 #endif
-       stb     %o0, [%g6 + TI_CPU]
+       sth     %o0, [%g6 + TI_CPU]
 
        /* Off we go.... */
        call    start_kernel
@@ -653,33 +653,54 @@ setup_tba:
         restore
 sparc64_boot_end:
 
-#include "ktlb.S"
-#include "tsb.S"
 #include "etrap.S"
 #include "rtrap.S"
 #include "winfixup.S"
 #include "entry.S"
 #include "sun4v_tlb_miss.S"
 #include "sun4v_ivec.S"
+#include "ktlb.S"
+#include "tsb.S"
 
 /*
  * The following skip makes sure the trap table in ttable.S is aligned
  * on a 32K boundary as required by the v9 specs for TBA register.
  *
  * We align to a 32K boundary, then we have the 32K kernel TSB,
- * then the 32K aligned trap table.
+ * the 64K kernel 4MB TSB, and then the 32K aligned trap table.
  */
 1:
        .skip   0x4000 + _start - 1b
 
+! 0x0000000000408000
+
        .globl  swapper_tsb
 swapper_tsb:
        .skip   (32 * 1024)
 
-! 0x0000000000408000
+       .globl  swapper_4m_tsb
+swapper_4m_tsb:
+       .skip   (64 * 1024)
+
+! 0x0000000000420000
 
+       /* Some care needs to be exercised if you try to move the
+        * location of the trap table relative to other things.  For
+        * one thing there are br* instructions in some of the
+        * trap table entires which branch back to code in ktlb.S
+        * Those instructions can only handle a signed 16-bit
+        * displacement.
+        *
+        * There is a binutils bug (bugzilla #4558) which causes
+        * the relocation overflow checks for such instructions to
+        * not be done correctly.  So bintuils will not notice the
+        * error and will instead write junk into the relocation and
+        * you'll have an unbootable kernel.
+        */
 #include "ttable.S"
 
+! 0x0000000000428000
+
 #include "systbls.S"
 
        .data
index f03ffc829c7a96fe52927b30c541a71dfff360d0..f34f5d6181eff1af2dbd4197cf5ad9eeaae11996 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <asm/hypervisor.h>
 #include <asm/oplib.h>
+#include <asm/sstate.h>
 
 /* If the hypervisor indicates that the API setting
  * calls are unsupported, by returning HV_EBADTRAP or
@@ -107,7 +108,7 @@ int sun4v_hvapi_register(unsigned long group, unsigned long major,
                                p->minor = actual_minor;
                                ret = 0;
                        } else if (hv_ret == HV_EBADTRAP ||
-                                  HV_ENOTSUPPORTED) {
+                                  hv_ret == HV_ENOTSUPPORTED) {
                                if (p->flags & FLAG_PRE_API) {
                                        if (major == 1) {
                                                p->major = 1;
@@ -179,6 +180,8 @@ void __init sun4v_hvapi_init(void)
        if (sun4v_hvapi_register(group, major, &minor))
                goto bad;
 
+       sun4v_sstate_init();
+
        return;
 
 bad:
index 3edc18e1b818da7dda4032634c1360b6e1c94072..a36f8dd0c0216e9244896736af33682a6ac7e889 100644 (file)
@@ -171,8 +171,6 @@ skip:
        return 0;
 }
 
-extern unsigned long real_hard_smp_processor_id(void);
-
 static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid)
 {
        unsigned int tid;
@@ -694,9 +692,20 @@ void init_irqwork_curcpu(void)
        trap_block[cpu].irq_worklist = 0;
 }
 
-static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type)
+/* Please be very careful with register_one_mondo() and
+ * sun4v_register_mondo_queues().
+ *
+ * On SMP this gets invoked from the CPU trampoline before
+ * the cpu has fully taken over the trap table from OBP,
+ * and it's kernel stack + %g6 thread register state is
+ * not fully cooked yet.
+ *
+ * Therefore you cannot make any OBP calls, not even prom_printf,
+ * from these two routines.
+ */
+static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
 {
-       unsigned long num_entries = 128;
+       unsigned long num_entries = (qmask + 1) / 64;
        unsigned long status;
 
        status = sun4v_cpu_qconf(type, paddr, num_entries);
@@ -711,44 +720,58 @@ static void __cpuinit sun4v_register_mondo_queues(int this_cpu)
 {
        struct trap_per_cpu *tb = &trap_block[this_cpu];
 
-       register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO);
-       register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO);
-       register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR);
-       register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR);
+       register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO,
+                          tb->cpu_mondo_qmask);
+       register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO,
+                          tb->dev_mondo_qmask);
+       register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR,
+                          tb->resum_qmask);
+       register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR,
+                          tb->nonresum_qmask);
 }
 
-static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, int use_bootmem)
+static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
 {
-       void *page;
+       unsigned long size = PAGE_ALIGN(qmask + 1);
+       unsigned long order = get_order(size);
+       void *p = NULL;
 
-       if (use_bootmem)
-               page = alloc_bootmem_low_pages(PAGE_SIZE);
-       else
-               page = (void *) get_zeroed_page(GFP_ATOMIC);
+       if (use_bootmem) {
+               p = __alloc_bootmem_low(size, size, 0);
+       } else {
+               struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
+               if (page)
+                       p = page_address(page);
+       }
 
-       if (!page) {
+       if (!p) {
                prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
                prom_halt();
        }
 
-       *pa_ptr = __pa(page);
+       *pa_ptr = __pa(p);
 }
 
-static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, int use_bootmem)
+static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
 {
-       void *page;
+       unsigned long size = PAGE_ALIGN(qmask + 1);
+       unsigned long order = get_order(size);
+       void *p = NULL;
 
-       if (use_bootmem)
-               page = alloc_bootmem_low_pages(PAGE_SIZE);
-       else
-               page = (void *) get_zeroed_page(GFP_ATOMIC);
+       if (use_bootmem) {
+               p = __alloc_bootmem_low(size, size, 0);
+       } else {
+               struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
+               if (page)
+                       p = page_address(page);
+       }
 
-       if (!page) {
+       if (!p) {
                prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
                prom_halt();
        }
 
-       *pa_ptr = __pa(page);
+       *pa_ptr = __pa(p);
 }
 
 static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem)
@@ -779,12 +802,12 @@ void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int
        struct trap_per_cpu *tb = &trap_block[cpu];
 
        if (alloc) {
-               alloc_one_mondo(&tb->cpu_mondo_pa, use_bootmem);
-               alloc_one_mondo(&tb->dev_mondo_pa, use_bootmem);
-               alloc_one_mondo(&tb->resum_mondo_pa, use_bootmem);
-               alloc_one_kbuf(&tb->resum_kernel_buf_pa, use_bootmem);
-               alloc_one_mondo(&tb->nonresum_mondo_pa, use_bootmem);
-               alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, use_bootmem);
+               alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem);
+               alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem);
+               alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem);
+               alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem);
+               alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem);
+               alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem);
 
                init_cpu_send_mondo_info(tb, use_bootmem);
        }
index ad46e2024f4b7400f1c6c44176fa3a0c7c3d970f..5a8377b54955b3ff57ff82414575a237b1c0d787 100644 (file)
 /* ITLB ** ICACHE line 2: TSB compare and TLB load     */
        bne,pn  %xcc, tsb_miss_itlb             ! Miss
         mov    FAULT_CODE_ITLB, %g3
-       andcc   %g5, _PAGE_EXEC_4U, %g0         ! Executable?
+       sethi   %hi(_PAGE_EXEC_4U), %g4
+       andcc   %g5, %g4, %g0                   ! Executable?
        be,pn   %xcc, tsb_do_fault
         nop                                    ! Delay slot, fill me
        stxa    %g5, [%g0] ASI_ITLB_DATA_IN     ! Load TLB
        retry                                   ! Trap done
-       nop
 
 /* ITLB ** ICACHE line 3:                              */
        nop
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
new file mode 100644 (file)
index 0000000..f0e1604
--- /dev/null
@@ -0,0 +1,672 @@
+/* mdesc.c: Sun4V machine description handling.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/log2.h>
+
+#include <asm/hypervisor.h>
+#include <asm/mdesc.h>
+#include <asm/prom.h>
+#include <asm/oplib.h>
+#include <asm/smp.h>
+
+/* Unlike the OBP device tree, the machine description is a full-on
+ * DAG.  An arbitrary number of ARCs are possible from one
+ * node to other nodes and thus we can't use the OBP device_node
+ * data structure to represent these nodes inside of the kernel.
+ *
+ * Actually, it isn't even a DAG, because there are back pointers
+ * which create cycles in the graph.
+ *
+ * mdesc_hdr and mdesc_elem describe the layout of the data structure
+ * we get from the Hypervisor.
+ */
+struct mdesc_hdr {
+       u32     version; /* Transport version */
+       u32     node_sz; /* node block size */
+       u32     name_sz; /* name block size */
+       u32     data_sz; /* data block size */
+};
+
+struct mdesc_elem {
+       u8      tag;
+#define MD_LIST_END    0x00
+#define MD_NODE                0x4e
+#define MD_NODE_END    0x45
+#define MD_NOOP                0x20
+#define MD_PROP_ARC    0x61
+#define MD_PROP_VAL    0x76
+#define MD_PROP_STR    0x73
+#define MD_PROP_DATA   0x64
+       u8      name_len;
+       u16     resv;
+       u32     name_offset;
+       union {
+               struct {
+                       u32     data_len;
+                       u32     data_offset;
+               } data;
+               u64     val;
+       } d;
+};
+
+static struct mdesc_hdr *main_mdesc;
+static struct mdesc_node *allnodes;
+
+static struct mdesc_node *allnodes_tail;
+static unsigned int unique_id;
+
+static struct mdesc_node **mdesc_hash;
+static unsigned int mdesc_hash_size;
+
+static inline unsigned int node_hashfn(u64 node)
+{
+       return ((unsigned int) (node ^ (node >> 8) ^ (node >> 16)))
+               & (mdesc_hash_size - 1);
+}
+
+static inline void hash_node(struct mdesc_node *mp)
+{
+       struct mdesc_node **head = &mdesc_hash[node_hashfn(mp->node)];
+
+       mp->hash_next = *head;
+       *head = mp;
+
+       if (allnodes_tail) {
+               allnodes_tail->allnodes_next = mp;
+               allnodes_tail = mp;
+       } else {
+               allnodes = allnodes_tail = mp;
+       }
+}
+
+static struct mdesc_node *find_node(u64 node)
+{
+       struct mdesc_node *mp = mdesc_hash[node_hashfn(node)];
+
+       while (mp) {
+               if (mp->node == node)
+                       return mp;
+
+               mp = mp->hash_next;
+       }
+       return NULL;
+}
+
+struct property *md_find_property(const struct mdesc_node *mp,
+                                 const char *name,
+                                 int *lenp)
+{
+       struct property *pp;
+
+       for (pp = mp->properties; pp != 0; pp = pp->next) {
+               if (strcasecmp(pp->name, name) == 0) {
+                       if (lenp)
+                               *lenp = pp->length;
+                       break;
+               }
+       }
+       return pp;
+}
+EXPORT_SYMBOL(md_find_property);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+const void *md_get_property(const struct mdesc_node *mp, const char *name,
+                           int *lenp)
+{
+       struct property *pp = md_find_property(mp, name, lenp);
+       return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(md_get_property);
+
+struct mdesc_node *md_find_node_by_name(struct mdesc_node *from,
+                                       const char *name)
+{
+       struct mdesc_node *mp;
+
+       mp = from ? from->allnodes_next : allnodes;
+       for (; mp != NULL; mp = mp->allnodes_next) {
+               if (strcmp(mp->name, name) == 0)
+                       break;
+       }
+       return mp;
+}
+EXPORT_SYMBOL(md_find_node_by_name);
+
+static unsigned int mdesc_early_allocated;
+
+static void * __init mdesc_early_alloc(unsigned long size)
+{
+       void *ret;
+
+       ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+       if (ret == NULL) {
+               prom_printf("MDESC: alloc of %lu bytes failed.\n", size);
+               prom_halt();
+       }
+
+       memset(ret, 0, size);
+
+       mdesc_early_allocated += size;
+
+       return ret;
+}
+
+static unsigned int __init count_arcs(struct mdesc_elem *ep)
+{
+       unsigned int ret = 0;
+
+       ep++;
+       while (ep->tag != MD_NODE_END) {
+               if (ep->tag == MD_PROP_ARC)
+                       ret++;
+               ep++;
+       }
+       return ret;
+}
+
+static void __init mdesc_node_alloc(u64 node, struct mdesc_elem *ep, const char *names)
+{
+       unsigned int num_arcs = count_arcs(ep);
+       struct mdesc_node *mp;
+
+       mp = mdesc_early_alloc(sizeof(*mp) +
+                              (num_arcs * sizeof(struct mdesc_arc)));
+       mp->name = names + ep->name_offset;
+       mp->node = node;
+       mp->unique_id = unique_id++;
+       mp->num_arcs = num_arcs;
+
+       hash_node(mp);
+}
+
+static inline struct mdesc_elem *node_block(struct mdesc_hdr *mdesc)
+{
+       return (struct mdesc_elem *) (mdesc + 1);
+}
+
+static inline void *name_block(struct mdesc_hdr *mdesc)
+{
+       return ((void *) node_block(mdesc)) + mdesc->node_sz;
+}
+
+static inline void *data_block(struct mdesc_hdr *mdesc)
+{
+       return ((void *) name_block(mdesc)) + mdesc->name_sz;
+}
+
+/* In order to avoid recursion (the graph can be very deep) we use a
+ * two pass algorithm.  First we allocate all the nodes and hash them.
+ * Then we iterate over each node, filling in the arcs and properties.
+ */
+static void __init build_all_nodes(struct mdesc_hdr *mdesc)
+{
+       struct mdesc_elem *start, *ep;
+       struct mdesc_node *mp;
+       const char *names;
+       void *data;
+       u64 last_node;
+
+       start = ep = node_block(mdesc);
+       last_node = mdesc->node_sz / 16;
+
+       names = name_block(mdesc);
+
+       while (1) {
+               u64 node = ep - start;
+
+               if (ep->tag == MD_LIST_END)
+                       break;
+
+               if (ep->tag != MD_NODE) {
+                       prom_printf("MDESC: Inconsistent element list.\n");
+                       prom_halt();
+               }
+
+               mdesc_node_alloc(node, ep, names);
+
+               if (ep->d.val >= last_node) {
+                       printk("MDESC: Warning, early break out of node scan.\n");
+                       printk("MDESC: Next node [%lu] last_node [%lu].\n",
+                              node, last_node);
+                       break;
+               }
+
+               ep = start + ep->d.val;
+       }
+
+       data = data_block(mdesc);
+       for (mp = allnodes; mp; mp = mp->allnodes_next) {
+               struct mdesc_elem *ep = start + mp->node;
+               struct property **link = &mp->properties;
+               unsigned int this_arc = 0;
+
+               ep++;
+               while (ep->tag != MD_NODE_END) {
+                       switch (ep->tag) {
+                       case MD_PROP_ARC: {
+                               struct mdesc_node *target;
+
+                               if (this_arc >= mp->num_arcs) {
+                                       prom_printf("MDESC: ARC overrun [%u:%u]\n",
+                                                   this_arc, mp->num_arcs);
+                                       prom_halt();
+                               }
+                               target = find_node(ep->d.val);
+                               if (!target) {
+                                       printk("MDESC: Warning, arc points to "
+                                              "missing node, ignoring.\n");
+                                       break;
+                               }
+                               mp->arcs[this_arc].name =
+                                       (names + ep->name_offset);
+                               mp->arcs[this_arc].arc = target;
+                               this_arc++;
+                               break;
+                       }
+
+                       case MD_PROP_VAL:
+                       case MD_PROP_STR:
+                       case MD_PROP_DATA: {
+                               struct property *p = mdesc_early_alloc(sizeof(*p));
+
+                               p->unique_id = unique_id++;
+                               p->name = (char *) names + ep->name_offset;
+                               if (ep->tag == MD_PROP_VAL) {
+                                       p->value = &ep->d.val;
+                                       p->length = 8;
+                               } else {
+                                       p->value = data + ep->d.data.data_offset;
+                                       p->length = ep->d.data.data_len;
+                               }
+                               *link = p;
+                               link = &p->next;
+                               break;
+                       }
+
+                       case MD_NOOP:
+                               break;
+
+                       default:
+                               printk("MDESC: Warning, ignoring unknown tag type %02x\n",
+                                      ep->tag);
+                       }
+                       ep++;
+               }
+       }
+}
+
+static unsigned int __init count_nodes(struct mdesc_hdr *mdesc)
+{
+       struct mdesc_elem *ep = node_block(mdesc);
+       struct mdesc_elem *end;
+       unsigned int cnt = 0;
+
+       end = ((void *)ep) + mdesc->node_sz;
+       while (ep < end) {
+               if (ep->tag == MD_NODE)
+                       cnt++;
+               ep++;
+       }
+       return cnt;
+}
+
+static void __init report_platform_properties(void)
+{
+       struct mdesc_node *pn = md_find_node_by_name(NULL, "platform");
+       const char *s;
+       const u64 *v;
+
+       if (!pn) {
+               prom_printf("No platform node in machine-description.\n");
+               prom_halt();
+       }
+
+       s = md_get_property(pn, "banner-name", NULL);
+       printk("PLATFORM: banner-name [%s]\n", s);
+       s = md_get_property(pn, "name", NULL);
+       printk("PLATFORM: name [%s]\n", s);
+
+       v = md_get_property(pn, "hostid", NULL);
+       if (v)
+               printk("PLATFORM: hostid [%08lx]\n", *v);
+       v = md_get_property(pn, "serial#", NULL);
+       if (v)
+               printk("PLATFORM: serial# [%08lx]\n", *v);
+       v = md_get_property(pn, "stick-frequency", NULL);
+       printk("PLATFORM: stick-frequency [%08lx]\n", *v);
+       v = md_get_property(pn, "mac-address", NULL);
+       if (v)
+               printk("PLATFORM: mac-address [%lx]\n", *v);
+       v = md_get_property(pn, "watchdog-resolution", NULL);
+       if (v)
+               printk("PLATFORM: watchdog-resolution [%lu ms]\n", *v);
+       v = md_get_property(pn, "watchdog-max-timeout", NULL);
+       if (v)
+               printk("PLATFORM: watchdog-max-timeout [%lu ms]\n", *v);
+       v = md_get_property(pn, "max-cpus", NULL);
+       if (v)
+               printk("PLATFORM: max-cpus [%lu]\n", *v);
+}
+
+static int inline find_in_proplist(const char *list, const char *match, int len)
+{
+       while (len > 0) {
+               int l;
+
+               if (!strcmp(list, match))
+                       return 1;
+               l = strlen(list) + 1;
+               list += l;
+               len -= l;
+       }
+       return 0;
+}
+
+static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp)
+{
+       const u64 *level = md_get_property(mp, "level", NULL);
+       const u64 *size = md_get_property(mp, "size", NULL);
+       const u64 *line_size = md_get_property(mp, "line-size", NULL);
+       const char *type;
+       int type_len;
+
+       type = md_get_property(mp, "type", &type_len);
+
+       switch (*level) {
+       case 1:
+               if (find_in_proplist(type, "instn", type_len)) {
+                       c->icache_size = *size;
+                       c->icache_line_size = *line_size;
+               } else if (find_in_proplist(type, "data", type_len)) {
+                       c->dcache_size = *size;
+                       c->dcache_line_size = *line_size;
+               }
+               break;
+
+       case 2:
+               c->ecache_size = *size;
+               c->ecache_line_size = *line_size;
+               break;
+
+       default:
+               break;
+       }
+
+       if (*level == 1) {
+               unsigned int i;
+
+               for (i = 0; i < mp->num_arcs; i++) {
+                       struct mdesc_node *t = mp->arcs[i].arc;
+
+                       if (strcmp(mp->arcs[i].name, "fwd"))
+                               continue;
+
+                       if (!strcmp(t->name, "cache"))
+                               fill_in_one_cache(c, t);
+               }
+       }
+}
+
+static void __init mark_core_ids(struct mdesc_node *mp, int core_id)
+{
+       unsigned int i;
+
+       for (i = 0; i < mp->num_arcs; i++) {
+               struct mdesc_node *t = mp->arcs[i].arc;
+               const u64 *id;
+
+               if (strcmp(mp->arcs[i].name, "back"))
+                       continue;
+
+               if (!strcmp(t->name, "cpu")) {
+                       id = md_get_property(t, "id", NULL);
+                       if (*id < NR_CPUS)
+                               cpu_data(*id).core_id = core_id;
+               } else {
+                       unsigned int j;
+
+                       for (j = 0; j < t->num_arcs; j++) {
+                               struct mdesc_node *n = t->arcs[j].arc;
+
+                               if (strcmp(t->arcs[j].name, "back"))
+                                       continue;
+
+                               if (strcmp(n->name, "cpu"))
+                                       continue;
+
+                               id = md_get_property(n, "id", NULL);
+                               if (*id < NR_CPUS)
+                                       cpu_data(*id).core_id = core_id;
+                       }
+               }
+       }
+}
+
+static void __init set_core_ids(void)
+{
+       struct mdesc_node *mp;
+       int idx;
+
+       idx = 1;
+       md_for_each_node_by_name(mp, "cache") {
+               const u64 *level = md_get_property(mp, "level", NULL);
+               const char *type;
+               int len;
+
+               if (*level != 1)
+                       continue;
+
+               type = md_get_property(mp, "type", &len);
+               if (!find_in_proplist(type, "instn", len))
+                       continue;
+
+               mark_core_ids(mp, idx);
+
+               idx++;
+       }
+}
+
+static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id)
+{
+       int i;
+
+       for (i = 0; i < mp->num_arcs; i++) {
+               struct mdesc_node *t = mp->arcs[i].arc;
+               const u64 *id;
+
+               if (strcmp(mp->arcs[i].name, "back"))
+                       continue;
+
+               if (strcmp(t->name, "cpu"))
+                       continue;
+
+               id = md_get_property(t, "id", NULL);
+               if (*id < NR_CPUS)
+                       cpu_data(*id).proc_id = proc_id;
+       }
+}
+
+static void __init __set_proc_ids(const char *exec_unit_name)
+{
+       struct mdesc_node *mp;
+       int idx;
+
+       idx = 0;
+       md_for_each_node_by_name(mp, exec_unit_name) {
+               const char *type;
+               int len;
+
+               type = md_get_property(mp, "type", &len);
+               if (!find_in_proplist(type, "int", len) &&
+                   !find_in_proplist(type, "integer", len))
+                       continue;
+
+               mark_proc_ids(mp, idx);
+
+               idx++;
+       }
+}
+
+static void __init set_proc_ids(void)
+{
+       __set_proc_ids("exec_unit");
+       __set_proc_ids("exec-unit");
+}
+
+static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def)
+{
+       u64 val;
+
+       if (!p)
+               goto use_default;
+       val = *p;
+
+       if (!val || val >= 64)
+               goto use_default;
+
+       *mask = ((1U << val) * 64U) - 1U;
+       return;
+
+use_default:
+       *mask = ((1U << def) * 64U) - 1U;
+}
+
+static void __init get_mondo_data(struct mdesc_node *mp, struct trap_per_cpu *tb)
+{
+       const u64 *val;
+
+       val = md_get_property(mp, "q-cpu-mondo-#bits", NULL);
+       get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7);
+
+       val = md_get_property(mp, "q-dev-mondo-#bits", NULL);
+       get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7);
+
+       val = md_get_property(mp, "q-resumable-#bits", NULL);
+       get_one_mondo_bits(val, &tb->resum_qmask, 6);
+
+       val = md_get_property(mp, "q-nonresumable-#bits", NULL);
+       get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
+}
+
+static void __init mdesc_fill_in_cpu_data(void)
+{
+       struct mdesc_node *mp;
+
+       ncpus_probed = 0;
+       md_for_each_node_by_name(mp, "cpu") {
+               const u64 *id = md_get_property(mp, "id", NULL);
+               const u64 *cfreq = md_get_property(mp, "clock-frequency", NULL);
+               struct trap_per_cpu *tb;
+               cpuinfo_sparc *c;
+               unsigned int i;
+               int cpuid;
+
+               ncpus_probed++;
+
+               cpuid = *id;
+
+#ifdef CONFIG_SMP
+               if (cpuid >= NR_CPUS)
+                       continue;
+#else
+               /* On uniprocessor we only want the values for the
+                * real physical cpu the kernel booted onto, however
+                * cpu_data() only has one entry at index 0.
+                */
+               if (cpuid != real_hard_smp_processor_id())
+                       continue;
+               cpuid = 0;
+#endif
+
+               c = &cpu_data(cpuid);
+               c->clock_tick = *cfreq;
+
+               tb = &trap_block[cpuid];
+               get_mondo_data(mp, tb);
+
+               for (i = 0; i < mp->num_arcs; i++) {
+                       struct mdesc_node *t = mp->arcs[i].arc;
+                       unsigned int j;
+
+                       if (strcmp(mp->arcs[i].name, "fwd"))
+                               continue;
+
+                       if (!strcmp(t->name, "cache")) {
+                               fill_in_one_cache(c, t);
+                               continue;
+                       }
+
+                       for (j = 0; j < t->num_arcs; j++) {
+                               struct mdesc_node *n;
+
+                               n = t->arcs[j].arc;
+                               if (strcmp(t->arcs[j].name, "fwd"))
+                                       continue;
+
+                               if (!strcmp(n->name, "cache"))
+                                       fill_in_one_cache(c, n);
+                       }
+               }
+
+#ifdef CONFIG_SMP
+               cpu_set(cpuid, cpu_present_map);
+               cpu_set(cpuid, phys_cpu_present_map);
+#endif
+
+               c->core_id = 0;
+               c->proc_id = -1;
+       }
+
+#ifdef CONFIG_SMP
+       sparc64_multi_core = 1;
+#endif
+
+       set_core_ids();
+       set_proc_ids();
+
+       smp_fill_in_sib_core_maps();
+}
+
+void __init sun4v_mdesc_init(void)
+{
+       unsigned long len, real_len, status;
+
+       (void) sun4v_mach_desc(0UL, 0UL, &len);
+
+       printk("MDESC: Size is %lu bytes.\n", len);
+
+       main_mdesc = mdesc_early_alloc(len);
+
+       status = sun4v_mach_desc(__pa(main_mdesc), len, &real_len);
+       if (status != HV_EOK || real_len > len) {
+               prom_printf("sun4v_mach_desc fails, err(%lu), "
+                           "len(%lu), real_len(%lu)\n",
+                           status, len, real_len);
+               prom_halt();
+       }
+
+       len = count_nodes(main_mdesc);
+       printk("MDESC: %lu nodes.\n", len);
+
+       len = roundup_pow_of_two(len);
+
+       mdesc_hash = mdesc_early_alloc(len * sizeof(struct mdesc_node *));
+       mdesc_hash_size = len;
+
+       printk("MDESC: Hash size %lu entries.\n", len);
+
+       build_all_nodes(main_mdesc);
+
+       printk("MDESC: Built graph with %u bytes of memory.\n",
+              mdesc_early_allocated);
+
+       report_platform_properties();
+       mdesc_fill_in_cpu_data();
+}
index 16cc46a718724cc5cd93a99beb3b5c43fb08fb23..6676b93219dcd51cee5454cb2577854074c4ec80 100644 (file)
@@ -343,6 +343,15 @@ static int of_bus_simba_match(struct device_node *np)
 
        if (model && !strcmp(model, "SUNW,simba"))
                return 1;
+
+       /* Treat PCI busses lacking ranges property just like
+        * simba.
+        */
+       if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+               if (!of_find_property(np, "ranges", NULL))
+                       return 1;
+       }
+
        return 0;
 }
 
@@ -549,8 +558,6 @@ static int __init build_one_resource(struct device_node *parent,
 
 static int __init use_1to1_mapping(struct device_node *pp)
 {
-       const char *model;
-
        /* If this is on the PMU bus, don't try to translate it even
         * if a ranges property exists.
         */
@@ -567,9 +574,11 @@ static int __init use_1to1_mapping(struct device_node *pp)
        if (!strcmp(pp->name, "dma"))
                return 0;
 
-       /* Similarly for Simba PCI bridges.  */
-       model = of_get_property(pp, "model", NULL);
-       if (model && !strcmp(model, "SUNW,simba"))
+       /* Similarly for all PCI bridges, if we get this far
+        * it lacks a ranges property, and this will include
+        * cases like Simba.
+        */
+       if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex"))
                return 0;
 
        return 1;
index d4c077dc5e857b0347c9eb1e9bb4622bf2a1e758..81f4a5ea05f7ab948e307daa1853f53d1b554fbd 100644 (file)
@@ -306,6 +306,20 @@ static void __init pci_controller_probe(void)
        pci_controller_scan(pci_controller_init);
 }
 
+static int ofpci_verbose;
+
+static int __init ofpci_debug(char *str)
+{
+       int val = 0;
+
+       get_option(&str, &val);
+       if (val)
+               ofpci_verbose = 1;
+       return 1;
+}
+
+__setup("ofpci_debug=", ofpci_debug);
+
 static unsigned long pci_parse_of_flags(u32 addr0)
 {
        unsigned long flags = 0;
@@ -337,7 +351,9 @@ static void pci_parse_of_addrs(struct of_device *op,
        addrs = of_get_property(node, "assigned-addresses", &proplen);
        if (!addrs)
                return;
-       printk("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
+       if (ofpci_verbose)
+               printk("    parse addresses (%d bytes) @ %p\n",
+                      proplen, addrs);
        op_res = &op->resource[0];
        for (; proplen >= 20; proplen -= 20, addrs += 5, op_res++) {
                struct resource *res;
@@ -348,8 +364,9 @@ static void pci_parse_of_addrs(struct of_device *op,
                if (!flags)
                        continue;
                i = addrs[0] & 0xff;
-               printk("  start: %lx, end: %lx, i: %x\n",
-                      op_res->start, op_res->end, i);
+               if (ofpci_verbose)
+                       printk("  start: %lx, end: %lx, i: %x\n",
+                              op_res->start, op_res->end, i);
 
                if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
                        res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
@@ -393,8 +410,9 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        if (type == NULL)
                type = "";
 
-       printk("    create device, devfn: %x, type: %s hostcontroller(%d)\n",
-              devfn, type, host_controller);
+       if (ofpci_verbose)
+               printk("    create device, devfn: %x, type: %s\n",
+                      devfn, type);
 
        dev->bus = bus;
        dev->sysdata = node;
@@ -434,8 +452,9 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
                sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                        dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
        }
-       printk("    class: 0x%x device name: %s\n",
-              dev->class, pci_name(dev));
+       if (ofpci_verbose)
+               printk("    class: 0x%x device name: %s\n",
+                      dev->class, pci_name(dev));
 
        /* I have seen IDE devices which will not respond to
         * the bmdma simplex check reads if bus mastering is
@@ -469,7 +488,8 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        }
        pci_parse_of_addrs(sd->op, node, dev);
 
-       printk("    adding to system ...\n");
+       if (ofpci_verbose)
+               printk("    adding to system ...\n");
 
        pci_device_add(dev, bus);
 
@@ -502,6 +522,89 @@ static void pci_resource_adjust(struct resource *res,
        res->end += root->start;
 }
 
+/* For PCI bus devices which lack a 'ranges' property we interrogate
+ * the config space values to set the resources, just like the generic
+ * Linux PCI probing code does.
+ */
+static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
+                                         struct pci_bus *bus,
+                                         struct pci_pbm_info *pbm)
+{
+       struct resource *res;
+       u8 io_base_lo, io_limit_lo;
+       u16 mem_base_lo, mem_limit_lo;
+       unsigned long base, limit;
+
+       pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
+       pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
+       base = (io_base_lo & PCI_IO_RANGE_MASK) << 8;
+       limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8;
+
+       if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
+               u16 io_base_hi, io_limit_hi;
+
+               pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi);
+               pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi);
+               base |= (io_base_hi << 16);
+               limit |= (io_limit_hi << 16);
+       }
+
+       res = bus->resource[0];
+       if (base <= limit) {
+               res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
+               if (!res->start)
+                       res->start = base;
+               if (!res->end)
+                       res->end = limit + 0xfff;
+               pci_resource_adjust(res, &pbm->io_space);
+       }
+
+       pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
+       pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
+       base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
+       limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
+
+       res = bus->resource[1];
+       if (base <= limit) {
+               res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
+                             IORESOURCE_MEM);
+               res->start = base;
+               res->end = limit + 0xfffff;
+               pci_resource_adjust(res, &pbm->mem_space);
+       }
+
+       pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
+       pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
+       base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
+       limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
+
+       if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+               u32 mem_base_hi, mem_limit_hi;
+
+               pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
+               pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
+
+               /*
+                * Some bridges set the base > limit by default, and some
+                * (broken) BIOSes do not initialize them.  If we find
+                * this, just assume they are not being used.
+                */
+               if (mem_base_hi <= mem_limit_hi) {
+                       base |= ((long) mem_base_hi) << 32;
+                       limit |= ((long) mem_limit_hi) << 32;
+               }
+       }
+
+       res = bus->resource[2];
+       if (base <= limit) {
+               res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
+                             IORESOURCE_MEM | IORESOURCE_PREFETCH);
+               res->start = base;
+               res->end = limit + 0xfffff;
+               pci_resource_adjust(res, &pbm->mem_space);
+       }
+}
+
 /* Cook up fake bus resources for SUNW,simba PCI bridges which lack
  * a proper 'ranges' property.
  */
@@ -547,7 +650,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
        unsigned int flags;
        u64 size;
 
-       printk("of_scan_pci_bridge(%s)\n", node->full_name);
+       if (ofpci_verbose)
+               printk("of_scan_pci_bridge(%s)\n", node->full_name);
 
        /* parse bus-range property */
        busrange = of_get_property(node, "bus-range", &len);
@@ -560,13 +664,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
        simba = 0;
        if (ranges == NULL) {
                const char *model = of_get_property(node, "model", NULL);
-               if (model && !strcmp(model, "SUNW,simba")) {
+               if (model && !strcmp(model, "SUNW,simba"))
                        simba = 1;
-               } else {
-                       printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
-                              node->full_name);
-                       return;
-               }
        }
 
        bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
@@ -590,7 +689,10 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
        }
        if (simba) {
                apb_fake_ranges(dev, bus, pbm);
-               goto simba_cont;
+               goto after_ranges;
+       } else if (ranges == NULL) {
+               pci_cfg_fake_ranges(dev, bus, pbm);
+               goto after_ranges;
        }
        i = 1;
        for (; len >= 32; len -= 32, ranges += 8) {
@@ -629,10 +731,11 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
                 */
                pci_resource_adjust(res, root);
        }
-simba_cont:
+after_ranges:
        sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
                bus->number);
-       printk("    bus name: %s\n", bus->name);
+       if (ofpci_verbose)
+               printk("    bus name: %s\n", bus->name);
 
        pci_of_scan_bus(pbm, node, bus);
 }
@@ -646,12 +749,14 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
        int reglen, devfn;
        struct pci_dev *dev;
 
-       printk("PCI: scan_bus[%s] bus no %d\n",
-              node->full_name, bus->number);
+       if (ofpci_verbose)
+               printk("PCI: scan_bus[%s] bus no %d\n",
+                      node->full_name, bus->number);
 
        child = NULL;
        while ((child = of_get_next_child(node, child)) != NULL) {
-               printk("  * %s\n", child->full_name);
+               if (ofpci_verbose)
+                       printk("  * %s\n", child->full_name);
                reg = of_get_property(child, "reg", &reglen);
                if (reg == NULL || reglen < 20)
                        continue;
@@ -661,7 +766,9 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
                dev = of_create_pci_dev(pbm, child, bus, devfn, 0);
                if (!dev)
                        continue;
-               printk("PCI: dev header type: %x\n", dev->hdr_type);
+               if (ofpci_verbose)
+                       printk("PCI: dev header type: %x\n",
+                              dev->hdr_type);
 
                if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
                    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
index e2377796de894e6f08164cfca6f4870f4192eb36..22e1be5c7489aaf1420da8fb1c4becf437c2eb49 100644 (file)
@@ -636,13 +636,18 @@ static void apb_init(struct pci_bus *sabre_bus)
 static void sabre_scan_bus(struct pci_pbm_info *pbm)
 {
        static int once;
-       struct pci_bus *pbus;
 
        /* The APB bridge speaks to the Sabre host PCI bridge
         * at 66Mhz, but the front side of APB runs at 33Mhz
         * for both segments.
+        *
+        * Hummingbird systems do not use APB, so they run
+        * at 66MHZ.
         */
-       pbm->is_66mhz_capable = 0;
+       if (hummingbird_p)
+               pbm->is_66mhz_capable = 1;
+       else
+               pbm->is_66mhz_capable = 0;
 
        /* This driver has not been verified to handle
         * multiple SABREs yet, so trap this.
@@ -656,13 +661,13 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm)
        }
        once++;
 
-       pbus = pci_scan_one_pbm(pbm);
-       if (!pbus)
+       pbm->pci_bus = pci_scan_one_pbm(pbm);
+       if (!pbm->pci_bus)
                return;
 
-       sabre_root_bus = pbus;
+       sabre_root_bus = pbm->pci_bus;
 
-       apb_init(pbus);
+       apb_init(pbm->pci_bus);
 
        sabre_register_error_handlers(pbm);
 }
@@ -762,9 +767,10 @@ void sabre_init(struct device_node *dp, char *model_name)
                        /* Of course, Sun has to encode things a thousand
                         * different ways, inconsistently.
                         */
-                       cpu_find_by_instance(0, &dp, NULL);
-                       if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
-                               hummingbird_p = 1;
+                       for_each_node_by_type(dp, "cpu") {
+                               if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
+                                       hummingbird_p = 1;
+                       }
                }
        }
 
index 044e8ec4c0f593d17113d58e0c4aa89369f22c65..6b3fe2c1d65e990ca95cd6d0eb9eaea1a8700675 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
+#include <linux/log2.h>
 
 #include <asm/iommu.h>
 #include <asm/irq.h>
@@ -26,6 +27,9 @@
 
 #include "pci_sun4v.h"
 
+static unsigned long vpci_major = 1;
+static unsigned long vpci_minor = 1;
+
 #define PGLIST_NENTS   (PAGE_SIZE / sizeof(u64))
 
 struct iommu_batch {
@@ -638,9 +642,8 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
 {
        struct iommu *iommu = pbm->iommu;
        struct property *prop;
-       unsigned long num_tsb_entries, sz;
+       unsigned long num_tsb_entries, sz, tsbsize;
        u32 vdma[2], dma_mask, dma_offset;
-       int tsbsize;
 
        prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
        if (prop) {
@@ -654,31 +657,15 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
                vdma[1] = 0x80000000;
        }
 
-       dma_mask = vdma[0];
-       switch (vdma[1]) {
-               case 0x20000000:
-                       dma_mask |= 0x1fffffff;
-                       tsbsize = 64;
-                       break;
-
-               case 0x40000000:
-                       dma_mask |= 0x3fffffff;
-                       tsbsize = 128;
-                       break;
-
-               case 0x80000000:
-                       dma_mask |= 0x7fffffff;
-                       tsbsize = 256;
-                       break;
-
-               default:
-                       prom_printf("PCI-SUN4V: strange virtual-dma size.\n");
-                       prom_halt();
+       if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) {
+               prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n",
+                           vdma[0], vdma[1]);
+               prom_halt();
        };
 
-       tsbsize *= (8 * 1024);
-
-       num_tsb_entries = tsbsize / sizeof(iopte_t);
+       dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL);
+       num_tsb_entries = vdma[1] / IO_PAGE_SIZE;
+       tsbsize = num_tsb_entries * sizeof(iopte_t);
 
        dma_offset = vdma[0];
 
@@ -689,7 +676,7 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
        iommu->dma_addr_mask = dma_mask;
 
        /* Allocate and initialize the free area map.  */
-       sz = num_tsb_entries / 8;
+       sz = (num_tsb_entries + 7) / 8;
        sz = (sz + 7UL) & ~7UL;
        iommu->arena.map = kzalloc(sz, GFP_KERNEL);
        if (!iommu->arena.map) {
@@ -1178,6 +1165,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
 
 void sun4v_pci_init(struct device_node *dp, char *model_name)
 {
+       static int hvapi_negotiated = 0;
        struct pci_controller_info *p;
        struct pci_pbm_info *pbm;
        struct iommu *iommu;
@@ -1186,6 +1174,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
        u32 devhandle;
        int i;
 
+       if (!hvapi_negotiated++) {
+               int err = sun4v_hvapi_register(HV_GRP_PCI,
+                                              vpci_major,
+                                              &vpci_minor);
+
+               if (err) {
+                       prom_printf("SUN4V_PCI: Could not register hvapi, "
+                                   "err=%d\n", err);
+                       prom_halt();
+               }
+               printk("SUN4V_PCI: Registered hvapi major[%lu] minor[%lu]\n",
+                      vpci_major, vpci_minor);
+       }
+
        prop = of_find_property(dp, "reg", NULL);
        regs = prop->value;
 
index 699b24b890dfc5dc398e6a04ade5bf9f3a8b67c7..5d6adea3967f32255da6bcbd59dc4cbf393c3660 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/prom.h>
 #include <asm/of_device.h>
 #include <asm/io.h>
+#include <asm/sstate.h>
 
 #include <linux/unistd.h>
 
@@ -53,6 +54,7 @@ static void (*poweroff_method)(void) = machine_alt_power_off;
 
 void machine_power_off(void)
 {
+       sstate_poweroff();
        if (!serial_console || scons_pwroff) {
 #ifdef CONFIG_PCI
                if (power_reg) {
index 952762bfb4c04c47bcc3118dee8e73b50ac903ed..f5f97e2c669c53d71a9429c9eeaa5f624e767a8a 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/mmu_context.h>
 #include <asm/unistd.h>
 #include <asm/hypervisor.h>
+#include <asm/sstate.h>
 
 /* #define VERBOSE_SHOWREGS */
 
@@ -106,6 +107,7 @@ extern void (*prom_keyboard)(void);
 
 void machine_halt(void)
 {
+       sstate_halt();
        if (!serial_console && prom_palette)
                prom_palette (1);
        if (prom_keyboard)
@@ -116,6 +118,7 @@ void machine_halt(void)
 
 void machine_alt_power_off(void)
 {
+       sstate_poweroff();
        if (!serial_console && prom_palette)
                prom_palette(1);
        if (prom_keyboard)
@@ -128,6 +131,7 @@ void machine_restart(char * cmd)
 {
        char *p;
        
+       sstate_reboot();
        p = strchr (reboot_command, '\n');
        if (p) *p = 0;
        if (!serial_console && prom_palette)
index 02830e4671f5824c9a9216d496037e562cfc275a..61036b346664b994cf329e90eef89305f7a28be3 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/irq.h>
 #include <asm/asi.h>
 #include <asm/upa.h>
+#include <asm/smp.h>
 
 static struct device_node *allnodes;
 
@@ -932,29 +933,29 @@ static void __init fire_irq_trans_init(struct device_node *dp)
  * This should conform to both Sunfire/Wildfire server and Fusion
  * desktop designs.
  */
-#define SYSIO_IMAP_SLOT0       0x2c04UL
-#define SYSIO_IMAP_SLOT1       0x2c0cUL
-#define SYSIO_IMAP_SLOT2       0x2c14UL
-#define SYSIO_IMAP_SLOT3       0x2c1cUL
-#define SYSIO_IMAP_SCSI                0x3004UL
-#define SYSIO_IMAP_ETH         0x300cUL
-#define SYSIO_IMAP_BPP         0x3014UL
-#define SYSIO_IMAP_AUDIO       0x301cUL
-#define SYSIO_IMAP_PFAIL       0x3024UL
-#define SYSIO_IMAP_KMS         0x302cUL
-#define SYSIO_IMAP_FLPY                0x3034UL
-#define SYSIO_IMAP_SHW         0x303cUL
-#define SYSIO_IMAP_KBD         0x3044UL
-#define SYSIO_IMAP_MS          0x304cUL
-#define SYSIO_IMAP_SER         0x3054UL
-#define SYSIO_IMAP_TIM0                0x3064UL
-#define SYSIO_IMAP_TIM1                0x306cUL
-#define SYSIO_IMAP_UE          0x3074UL
-#define SYSIO_IMAP_CE          0x307cUL
-#define SYSIO_IMAP_SBERR       0x3084UL
-#define SYSIO_IMAP_PMGMT       0x308cUL
-#define SYSIO_IMAP_GFX         0x3094UL
-#define SYSIO_IMAP_EUPA                0x309cUL
+#define SYSIO_IMAP_SLOT0       0x2c00UL
+#define SYSIO_IMAP_SLOT1       0x2c08UL
+#define SYSIO_IMAP_SLOT2       0x2c10UL
+#define SYSIO_IMAP_SLOT3       0x2c18UL
+#define SYSIO_IMAP_SCSI                0x3000UL
+#define SYSIO_IMAP_ETH         0x3008UL
+#define SYSIO_IMAP_BPP         0x3010UL
+#define SYSIO_IMAP_AUDIO       0x3018UL
+#define SYSIO_IMAP_PFAIL       0x3020UL
+#define SYSIO_IMAP_KMS         0x3028UL
+#define SYSIO_IMAP_FLPY                0x3030UL
+#define SYSIO_IMAP_SHW         0x3038UL
+#define SYSIO_IMAP_KBD         0x3040UL
+#define SYSIO_IMAP_MS          0x3048UL
+#define SYSIO_IMAP_SER         0x3050UL
+#define SYSIO_IMAP_TIM0                0x3060UL
+#define SYSIO_IMAP_TIM1                0x3068UL
+#define SYSIO_IMAP_UE          0x3070UL
+#define SYSIO_IMAP_CE          0x3078UL
+#define SYSIO_IMAP_SBERR       0x3080UL
+#define SYSIO_IMAP_PMGMT       0x3088UL
+#define SYSIO_IMAP_GFX         0x3090UL
+#define SYSIO_IMAP_EUPA                0x3098UL
 
 #define bogon     ((unsigned long) -1)
 static unsigned long sysio_irq_offsets[] = {
@@ -1005,10 +1006,10 @@ static unsigned long sysio_irq_offsets[] = {
  * Interrupt Clear register pointer, SYSIO specific version.
  */
 #define SYSIO_ICLR_UNUSED0     0x3400UL
-#define SYSIO_ICLR_SLOT0       0x340cUL
-#define SYSIO_ICLR_SLOT1       0x344cUL
-#define SYSIO_ICLR_SLOT2       0x348cUL
-#define SYSIO_ICLR_SLOT3       0x34ccUL
+#define SYSIO_ICLR_SLOT0       0x3408UL
+#define SYSIO_ICLR_SLOT1       0x3448UL
+#define SYSIO_ICLR_SLOT2       0x3488UL
+#define SYSIO_ICLR_SLOT3       0x34c8UL
 static unsigned long sysio_imap_to_iclr(unsigned long imap)
 {
        unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
@@ -1665,6 +1666,155 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
        return ret;
 }
 
+static const char *get_mid_prop(void)
+{
+       return (tlb_type == spitfire ? "upa-portid" : "portid");
+}
+
+struct device_node *of_find_node_by_cpuid(int cpuid)
+{
+       struct device_node *dp;
+       const char *mid_prop = get_mid_prop();
+
+       for_each_node_by_type(dp, "cpu") {
+               int id = of_getintprop_default(dp, mid_prop, -1);
+               const char *this_mid_prop = mid_prop;
+
+               if (id < 0) {
+                       this_mid_prop = "cpuid";
+                       id = of_getintprop_default(dp, this_mid_prop, -1);
+               }
+
+               if (id < 0) {
+                       prom_printf("OF: Serious problem, cpu lacks "
+                                   "%s property", this_mid_prop);
+                       prom_halt();
+               }
+               if (cpuid == id)
+                       return dp;
+       }
+       return NULL;
+}
+
+static void __init of_fill_in_cpu_data(void)
+{
+       struct device_node *dp;
+       const char *mid_prop = get_mid_prop();
+
+       ncpus_probed = 0;
+       for_each_node_by_type(dp, "cpu") {
+               int cpuid = of_getintprop_default(dp, mid_prop, -1);
+               const char *this_mid_prop = mid_prop;
+               struct device_node *portid_parent;
+               int portid = -1;
+
+               portid_parent = NULL;
+               if (cpuid < 0) {
+                       this_mid_prop = "cpuid";
+                       cpuid = of_getintprop_default(dp, this_mid_prop, -1);
+                       if (cpuid >= 0) {
+                               int limit = 2;
+
+                               portid_parent = dp;
+                               while (limit--) {
+                                       portid_parent = portid_parent->parent;
+                                       if (!portid_parent)
+                                               break;
+                                       portid = of_getintprop_default(portid_parent,
+                                                                      "portid", -1);
+                                       if (portid >= 0)
+                                               break;
+                               }
+                       }
+               }
+
+               if (cpuid < 0) {
+                       prom_printf("OF: Serious problem, cpu lacks "
+                                   "%s property", this_mid_prop);
+                       prom_halt();
+               }
+
+               ncpus_probed++;
+
+#ifdef CONFIG_SMP
+               if (cpuid >= NR_CPUS)
+                       continue;
+#else
+               /* On uniprocessor we only want the values for the
+                * real physical cpu the kernel booted onto, however
+                * cpu_data() only has one entry at index 0.
+                */
+               if (cpuid != real_hard_smp_processor_id())
+                       continue;
+               cpuid = 0;
+#endif
+
+               cpu_data(cpuid).clock_tick =
+                       of_getintprop_default(dp, "clock-frequency", 0);
+
+               if (portid_parent) {
+                       cpu_data(cpuid).dcache_size =
+                               of_getintprop_default(dp, "l1-dcache-size",
+                                                     16 * 1024);
+                       cpu_data(cpuid).dcache_line_size =
+                               of_getintprop_default(dp, "l1-dcache-line-size",
+                                                     32);
+                       cpu_data(cpuid).icache_size =
+                               of_getintprop_default(dp, "l1-icache-size",
+                                                     8 * 1024);
+                       cpu_data(cpuid).icache_line_size =
+                               of_getintprop_default(dp, "l1-icache-line-size",
+                                                     32);
+                       cpu_data(cpuid).ecache_size =
+                               of_getintprop_default(dp, "l2-cache-size", 0);
+                       cpu_data(cpuid).ecache_line_size =
+                               of_getintprop_default(dp, "l2-cache-line-size", 0);
+                       if (!cpu_data(cpuid).ecache_size ||
+                           !cpu_data(cpuid).ecache_line_size) {
+                               cpu_data(cpuid).ecache_size =
+                                       of_getintprop_default(portid_parent,
+                                                             "l2-cache-size",
+                                                             (4 * 1024 * 1024));
+                               cpu_data(cpuid).ecache_line_size =
+                                       of_getintprop_default(portid_parent,
+                                                             "l2-cache-line-size", 64);
+                       }
+
+                       cpu_data(cpuid).core_id = portid + 1;
+                       cpu_data(cpuid).proc_id = portid;
+#ifdef CONFIG_SMP
+                       sparc64_multi_core = 1;
+#endif
+               } else {
+                       cpu_data(cpuid).dcache_size =
+                               of_getintprop_default(dp, "dcache-size", 16 * 1024);
+                       cpu_data(cpuid).dcache_line_size =
+                               of_getintprop_default(dp, "dcache-line-size", 32);
+
+                       cpu_data(cpuid).icache_size =
+                               of_getintprop_default(dp, "icache-size", 16 * 1024);
+                       cpu_data(cpuid).icache_line_size =
+                               of_getintprop_default(dp, "icache-line-size", 32);
+
+                       cpu_data(cpuid).ecache_size =
+                               of_getintprop_default(dp, "ecache-size",
+                                                     (4 * 1024 * 1024));
+                       cpu_data(cpuid).ecache_line_size =
+                               of_getintprop_default(dp, "ecache-line-size", 64);
+
+                       cpu_data(cpuid).core_id = 0;
+                       cpu_data(cpuid).proc_id = -1;
+               }
+
+#ifdef CONFIG_SMP
+               cpu_set(cpuid, cpu_present_map);
+               cpu_set(cpuid, phys_cpu_present_map);
+#endif
+       }
+
+       smp_fill_in_sib_core_maps();
+}
+
 void __init prom_build_devicetree(void)
 {
        struct device_node **nextp;
@@ -1679,4 +1829,7 @@ void __init prom_build_devicetree(void)
                                     &nextp);
        printk("PROM: Built device tree with %u bytes of memory.\n",
               prom_early_allocated);
+
+       if (tlb_type != hypervisor)
+               of_fill_in_cpu_data();
 }
index 91f6e2a74ad5fdc263c94fec5dd41dfb06ea254c..a1fd9bcc0b872a5485bb6514b9a835cad583ee49 100644 (file)
@@ -629,29 +629,29 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts)
  * This should conform to both Sunfire/Wildfire server and Fusion
  * desktop designs.
  */
-#define SYSIO_IMAP_SLOT0       0x2c04UL
-#define SYSIO_IMAP_SLOT1       0x2c0cUL
-#define SYSIO_IMAP_SLOT2       0x2c14UL
-#define SYSIO_IMAP_SLOT3       0x2c1cUL
-#define SYSIO_IMAP_SCSI                0x3004UL
-#define SYSIO_IMAP_ETH         0x300cUL
-#define SYSIO_IMAP_BPP         0x3014UL
-#define SYSIO_IMAP_AUDIO       0x301cUL
-#define SYSIO_IMAP_PFAIL       0x3024UL
-#define SYSIO_IMAP_KMS         0x302cUL
-#define SYSIO_IMAP_FLPY                0x3034UL
-#define SYSIO_IMAP_SHW         0x303cUL
-#define SYSIO_IMAP_KBD         0x3044UL
-#define SYSIO_IMAP_MS          0x304cUL
-#define SYSIO_IMAP_SER         0x3054UL
-#define SYSIO_IMAP_TIM0                0x3064UL
-#define SYSIO_IMAP_TIM1                0x306cUL
-#define SYSIO_IMAP_UE          0x3074UL
-#define SYSIO_IMAP_CE          0x307cUL
-#define SYSIO_IMAP_SBERR       0x3084UL
-#define SYSIO_IMAP_PMGMT       0x308cUL
-#define SYSIO_IMAP_GFX         0x3094UL
-#define SYSIO_IMAP_EUPA                0x309cUL
+#define SYSIO_IMAP_SLOT0       0x2c00UL
+#define SYSIO_IMAP_SLOT1       0x2c08UL
+#define SYSIO_IMAP_SLOT2       0x2c10UL
+#define SYSIO_IMAP_SLOT3       0x2c18UL
+#define SYSIO_IMAP_SCSI                0x3000UL
+#define SYSIO_IMAP_ETH         0x3008UL
+#define SYSIO_IMAP_BPP         0x3010UL
+#define SYSIO_IMAP_AUDIO       0x3018UL
+#define SYSIO_IMAP_PFAIL       0x3020UL
+#define SYSIO_IMAP_KMS         0x3028UL
+#define SYSIO_IMAP_FLPY                0x3030UL
+#define SYSIO_IMAP_SHW         0x3038UL
+#define SYSIO_IMAP_KBD         0x3040UL
+#define SYSIO_IMAP_MS          0x3048UL
+#define SYSIO_IMAP_SER         0x3050UL
+#define SYSIO_IMAP_TIM0                0x3060UL
+#define SYSIO_IMAP_TIM1                0x3068UL
+#define SYSIO_IMAP_UE          0x3070UL
+#define SYSIO_IMAP_CE          0x3078UL
+#define SYSIO_IMAP_SBERR       0x3080UL
+#define SYSIO_IMAP_PMGMT       0x3088UL
+#define SYSIO_IMAP_GFX         0x3090UL
+#define SYSIO_IMAP_EUPA                0x3098UL
 
 #define bogon     ((unsigned long) -1)
 static unsigned long sysio_irq_offsets[] = {
@@ -700,10 +700,10 @@ static unsigned long sysio_irq_offsets[] = {
  * Interrupt Clear register pointer, SYSIO specific version.
  */
 #define SYSIO_ICLR_UNUSED0     0x3400UL
-#define SYSIO_ICLR_SLOT0       0x340cUL
-#define SYSIO_ICLR_SLOT1       0x344cUL
-#define SYSIO_ICLR_SLOT2       0x348cUL
-#define SYSIO_ICLR_SLOT3       0x34ccUL
+#define SYSIO_ICLR_SLOT0       0x3408UL
+#define SYSIO_ICLR_SLOT1       0x3448UL
+#define SYSIO_ICLR_SLOT2       0x3488UL
+#define SYSIO_ICLR_SLOT3       0x34c8UL
 static unsigned long sysio_imap_to_iclr(unsigned long imap)
 {
        unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
index dea9c3c9ec5f61954ce452ca646442623d828322..7490cc670a530e495a81e1d5d7d762b8228f7f22 100644 (file)
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/mmu.h>
+#include <asm/ns87303.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
 #endif
 
+/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
+ * operations in asm/ns87303.h
+ */
+DEFINE_SPINLOCK(ns87303_lock);
+
 struct screen_info screen_info = {
        0, 0,                   /* orig-x, orig-y */
        0,                      /* unused */
@@ -370,8 +376,6 @@ void __init setup_arch(char **cmdline_p)
        init_cur_cpu_trap(current_thread_info());
 
        paging_init();
-
-       smp_setup_cpu_possible_map();
 }
 
 static int __init set_preferred_console(void)
@@ -424,7 +428,7 @@ extern void mmu_info(struct seq_file *);
 unsigned int dcache_parity_tl1_occurred;
 unsigned int icache_parity_tl1_occurred;
 
-static int ncpus_probed;
+int ncpus_probed;
 
 static int show_cpuinfo(struct seq_file *m, void *__unused)
 {
@@ -509,30 +513,3 @@ void sun_do_break(void)
 
 int serial_console = -1;
 int stop_a_enabled = 1;
-
-static int __init topology_init(void)
-{
-       int i, err;
-
-       err = -ENOMEM;
-
-       /* Count the number of physically present processors in
-        * the machine, even on uniprocessor, so that /proc/cpuinfo
-        * output is consistent with 2.4.x
-        */
-       ncpus_probed = 0;
-       while (!cpu_find_by_instance(ncpus_probed, NULL, NULL))
-               ncpus_probed++;
-
-       for_each_possible_cpu(i) {
-               struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
-               if (p) {
-                       register_cpu(p, i);
-                       err = 0;
-               }
-       }
-
-       return err;
-}
-
-subsys_initcall(topology_init);
index 24fdf1d0adc512feac2b429288035a8eb67fa58d..4dcd7d0b60f2d8abb8e8ad7630df207cfc39ad21 100644 (file)
 #include <asm/tlb.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
+#include <asm/mdesc.h>
 
 extern void calibrate_delay(void);
 
+int sparc64_multi_core __read_mostly;
+
 /* Please don't make this stuff initdata!!!  --DaveM */
 unsigned char boot_cpu_id;
 
@@ -50,6 +53,8 @@ cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
 cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE;
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
        { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
+       { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
 static cpumask_t smp_commenced_mask;
 static cpumask_t cpu_callout_map;
 
@@ -75,53 +80,6 @@ void smp_bogo(struct seq_file *m)
                           i, cpu_data(i).clock_tick);
 }
 
-void __init smp_store_cpu_info(int id)
-{
-       struct device_node *dp;
-       int def;
-
-       cpu_data(id).udelay_val                 = loops_per_jiffy;
-
-       cpu_find_by_mid(id, &dp);
-       cpu_data(id).clock_tick =
-               of_getintprop_default(dp, "clock-frequency", 0);
-
-       def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
-       cpu_data(id).dcache_size =
-               of_getintprop_default(dp, "dcache-size", def);
-
-       def = 32;
-       cpu_data(id).dcache_line_size =
-               of_getintprop_default(dp, "dcache-line-size", def);
-
-       def = 16 * 1024;
-       cpu_data(id).icache_size =
-               of_getintprop_default(dp, "icache-size", def);
-
-       def = 32;
-       cpu_data(id).icache_line_size =
-               of_getintprop_default(dp, "icache-line-size", def);
-
-       def = ((tlb_type == hypervisor) ?
-              (3 * 1024 * 1024) :
-              (4 * 1024 * 1024));
-       cpu_data(id).ecache_size =
-               of_getintprop_default(dp, "ecache-size", def);
-
-       def = 64;
-       cpu_data(id).ecache_line_size =
-               of_getintprop_default(dp, "ecache-line-size", def);
-
-       printk("CPU[%d]: Caches "
-              "D[sz(%d):line_sz(%d)] "
-              "I[sz(%d):line_sz(%d)] "
-              "E[sz(%d):line_sz(%d)]\n",
-              id,
-              cpu_data(id).dcache_size, cpu_data(id).dcache_line_size,
-              cpu_data(id).icache_size, cpu_data(id).icache_line_size,
-              cpu_data(id).ecache_size, cpu_data(id).ecache_line_size);
-}
-
 extern void setup_sparc64_timer(void);
 
 static volatile unsigned long callin_flag = 0;
@@ -145,7 +103,7 @@ void __init smp_callin(void)
        local_irq_enable();
 
        calibrate_delay();
-       smp_store_cpu_info(cpuid);
+       cpu_data(cpuid).udelay_val = loops_per_jiffy;
        callin_flag = 1;
        __asm__ __volatile__("membar #Sync\n\t"
                             "flush  %%g6" : : : "memory");
@@ -340,9 +298,8 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu)
 
                prom_startcpu_cpuid(cpu, entry, cookie);
        } else {
-               struct device_node *dp;
+               struct device_node *dp = of_find_node_by_cpuid(cpu);
 
-               cpu_find_by_mid(cpu, &dp);
                prom_startcpu(dp->node, entry, cookie);
        }
 
@@ -447,7 +404,7 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c
 static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
 {
        u64 pstate, ver;
-       int nack_busy_id, is_jbus;
+       int nack_busy_id, is_jbus, need_more;
 
        if (cpus_empty(mask))
                return;
@@ -463,6 +420,7 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
        __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
 
 retry:
+       need_more = 0;
        __asm__ __volatile__("wrpr %0, %1, %%pstate\n\t"
                             : : "r" (pstate), "i" (PSTATE_IE));
 
@@ -491,6 +449,10 @@ retry:
                                : /* no outputs */
                                : "r" (target), "i" (ASI_INTR_W));
                        nack_busy_id++;
+                       if (nack_busy_id == 32) {
+                               need_more = 1;
+                               break;
+                       }
                }
        }
 
@@ -507,6 +469,16 @@ retry:
                        if (dispatch_stat == 0UL) {
                                __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
                                                     : : "r" (pstate));
+                               if (unlikely(need_more)) {
+                                       int i, cnt = 0;
+                                       for_each_cpu_mask(i, mask) {
+                                               cpu_clear(i, mask);
+                                               cnt++;
+                                               if (cnt == 32)
+                                                       break;
+                                       }
+                                       goto retry;
+                               }
                                return;
                        }
                        if (!--stuck)
@@ -544,6 +516,8 @@ retry:
                                if ((dispatch_stat & check_mask) == 0)
                                        cpu_clear(i, mask);
                                this_busy_nack += 2;
+                               if (this_busy_nack == 64)
+                                       break;
                        }
 
                        goto retry;
@@ -1191,23 +1165,14 @@ int setup_profiling_timer(unsigned int multiplier)
 
 static void __init smp_tune_scheduling(void)
 {
-       struct device_node *dp;
-       int instance;
-       unsigned int def, smallest = ~0U;
-
-       def = ((tlb_type == hypervisor) ?
-              (3 * 1024 * 1024) :
-              (4 * 1024 * 1024));
+       unsigned int smallest = ~0U;
+       int i;
 
-       instance = 0;
-       while (!cpu_find_by_instance(instance, &dp, NULL)) {
-               unsigned int val;
+       for (i = 0; i < NR_CPUS; i++) {
+               unsigned int val = cpu_data(i).ecache_size;
 
-               val = of_getintprop_default(dp, "ecache-size", def);
-               if (val < smallest)
+               if (val && val < smallest)
                        smallest = val;
-
-               instance++;
        }
 
        /* Any value less than 256K is nonsense.  */
@@ -1230,60 +1195,59 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        int i;
 
        if (num_possible_cpus() > max_cpus) {
-               int instance, mid;
-
-               instance = 0;
-               while (!cpu_find_by_instance(instance, NULL, &mid)) {
-                       if (mid != boot_cpu_id) {
-                               cpu_clear(mid, phys_cpu_present_map);
-                               cpu_clear(mid, cpu_present_map);
+               for_each_possible_cpu(i) {
+                       if (i != boot_cpu_id) {
+                               cpu_clear(i, phys_cpu_present_map);
+                               cpu_clear(i, cpu_present_map);
                                if (num_possible_cpus() <= max_cpus)
                                        break;
                        }
-                       instance++;
                }
        }
 
+       cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy;
+       smp_tune_scheduling();
+}
+
+void __devinit smp_prepare_boot_cpu(void)
+{
+}
+
+void __devinit smp_fill_in_sib_core_maps(void)
+{
+       unsigned int i;
+
        for_each_possible_cpu(i) {
-               if (tlb_type == hypervisor) {
-                       int j;
+               unsigned int j;
 
-                       /* XXX get this mapping from machine description */
-                       for_each_possible_cpu(j) {
-                               if ((j >> 2) == (i >> 2))
-                                       cpu_set(j, cpu_sibling_map[i]);
-                       }
-               } else {
-                       cpu_set(i, cpu_sibling_map[i]);
+               if (cpu_data(i).core_id == 0) {
+                       cpu_set(i, cpu_core_map[i]);
+                       continue;
+               }
+
+               for_each_possible_cpu(j) {
+                       if (cpu_data(i).core_id ==
+                           cpu_data(j).core_id)
+                               cpu_set(j, cpu_core_map[i]);
                }
        }
 
-       smp_store_cpu_info(boot_cpu_id);
-       smp_tune_scheduling();
-}
+       for_each_possible_cpu(i) {
+               unsigned int j;
 
-/* Set this up early so that things like the scheduler can init
- * properly.  We use the same cpu mask for both the present and
- * possible cpu map.
- */
-void __init smp_setup_cpu_possible_map(void)
-{
-       int instance, mid;
+               if (cpu_data(i).proc_id == -1) {
+                       cpu_set(i, cpu_sibling_map[i]);
+                       continue;
+               }
 
-       instance = 0;
-       while (!cpu_find_by_instance(instance, NULL, &mid)) {
-               if (mid < NR_CPUS) {
-                       cpu_set(mid, phys_cpu_present_map);
-                       cpu_set(mid, cpu_present_map);
+               for_each_possible_cpu(j) {
+                       if (cpu_data(i).proc_id ==
+                           cpu_data(j).proc_id)
+                               cpu_set(j, cpu_sibling_map[i]);
                }
-               instance++;
        }
 }
 
-void __devinit smp_prepare_boot_cpu(void)
-{
-}
-
 int __cpuinit __cpu_up(unsigned int cpu)
 {
        int ret = smp_boot_one_cpu(cpu);
@@ -1337,7 +1301,7 @@ unsigned long __per_cpu_shift __read_mostly;
 EXPORT_SYMBOL(__per_cpu_base);
 EXPORT_SYMBOL(__per_cpu_shift);
 
-void __init setup_per_cpu_areas(void)
+void __init real_setup_per_cpu_areas(void)
 {
        unsigned long goal, size, i;
        char *ptr;
index d00f51a5683fd46234954ffa3648bb8a6822b851..6fa76161289910680c8bb3f350429f18248553a9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/syscalls.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
+#include <linux/rwsem.h>
 #include <net/compat.h>
 
 #include <asm/oplib.h>
@@ -58,7 +59,6 @@
 #include <asm/ns87303.h>
 #include <asm/timer.h>
 #include <asm/cpudata.h>
-#include <asm/rwsem.h>
 
 struct poll {
        int fd;
diff --git a/arch/sparc64/kernel/sstate.c b/arch/sparc64/kernel/sstate.c
new file mode 100644 (file)
index 0000000..5b6e75b
--- /dev/null
@@ -0,0 +1,104 @@
+/* sstate.c: System soft state support.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+
+#include <asm/hypervisor.h>
+#include <asm/sstate.h>
+#include <asm/oplib.h>
+#include <asm/head.h>
+#include <asm/io.h>
+
+static int hv_supports_soft_state;
+
+static unsigned long kimage_addr_to_ra(const char *p)
+{
+       unsigned long val = (unsigned long) p;
+
+       return kern_base + (val - KERNBASE);
+}
+
+static void do_set_sstate(unsigned long state, const char *msg)
+{
+       unsigned long err;
+
+       if (!hv_supports_soft_state)
+               return;
+
+       err = sun4v_mach_set_soft_state(state, kimage_addr_to_ra(msg));
+       if (err) {
+               printk(KERN_WARNING "SSTATE: Failed to set soft-state to "
+                      "state[%lx] msg[%s], err=%lu\n",
+                      state, msg, err);
+       }
+}
+
+static const char booting_msg[32] __attribute__((aligned(32))) =
+       "Linux booting";
+static const char running_msg[32] __attribute__((aligned(32))) =
+       "Linux running";
+static const char halting_msg[32] __attribute__((aligned(32))) =
+       "Linux halting";
+static const char poweroff_msg[32] __attribute__((aligned(32))) =
+       "Linux powering off";
+static const char rebooting_msg[32] __attribute__((aligned(32))) =
+       "Linux rebooting";
+static const char panicing_msg[32] __attribute__((aligned(32))) =
+       "Linux panicing";
+
+void sstate_booting(void)
+{
+       do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
+}
+
+void sstate_running(void)
+{
+       do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
+}
+
+void sstate_halt(void)
+{
+       do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg);
+}
+
+void sstate_poweroff(void)
+{
+       do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg);
+}
+
+void sstate_reboot(void)
+{
+       do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg);
+}
+
+static int sstate_panic_event(struct notifier_block *n, unsigned long event, void *ptr)
+{
+       do_set_sstate(HV_SOFT_STATE_TRANSITION, panicing_msg);
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block sstate_panic_block = {
+       .notifier_call  =       sstate_panic_event,
+       .priority       =       INT_MAX,
+};
+
+void __init sun4v_sstate_init(void)
+{
+       unsigned long major, minor;
+
+       major = 1;
+       minor = 0;
+       if (sun4v_hvapi_register(HV_GRP_SOFT_STATE, major, &minor))
+               return;
+
+       hv_supports_soft_state = 1;
+
+       prom_sun4v_guest_soft_state();
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                      &sstate_panic_block);
+}
index 405855dd886bc9f7afd0795b7ca93a496e2a2db6..574bc248bca6f9edf5f5116e399ae1fe1024f65a 100644 (file)
@@ -22,12 +22,12 @@ sun4v_cpu_mondo:
        be,pn   %xcc, sun4v_cpu_mondo_queue_empty
         nop
 
-       /* Get &trap_block[smp_processor_id()] into %g3.  */
-       ldxa    [%g0] ASI_SCRATCHPAD, %g3
-       sub     %g3, TRAP_PER_CPU_FAULT_INFO, %g3
+       /* Get &trap_block[smp_processor_id()] into %g4.  */
+       ldxa    [%g0] ASI_SCRATCHPAD, %g4
+       sub     %g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
        /* Get CPU mondo queue base phys address into %g7.  */
-       ldx     [%g3 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
+       ldx     [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
 
        /* Now get the cross-call arguments and handler PC, same
         * layout as sun4u:
@@ -47,8 +47,7 @@ sun4v_cpu_mondo:
        add     %g2, 0x40 - 0x8 - 0x8, %g2
 
        /* Update queue head pointer.  */
-       sethi   %hi(8192 - 1), %g4
-       or      %g4, %lo(8192 - 1), %g4
+       lduw    [%g4 + TRAP_PER_CPU_CPU_MONDO_QMASK], %g4
        and     %g2, %g4, %g2
 
        mov     INTRQ_CPU_MONDO_HEAD, %g4
@@ -71,12 +70,12 @@ sun4v_dev_mondo:
        be,pn   %xcc, sun4v_dev_mondo_queue_empty
         nop
 
-       /* Get &trap_block[smp_processor_id()] into %g3.  */
-       ldxa    [%g0] ASI_SCRATCHPAD, %g3
-       sub     %g3, TRAP_PER_CPU_FAULT_INFO, %g3
+       /* Get &trap_block[smp_processor_id()] into %g4.  */
+       ldxa    [%g0] ASI_SCRATCHPAD, %g4
+       sub     %g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
        /* Get DEV mondo queue base phys address into %g5.  */
-       ldx     [%g3 + TRAP_PER_CPU_DEV_MONDO_PA], %g5
+       ldx     [%g4 + TRAP_PER_CPU_DEV_MONDO_PA], %g5
 
        /* Load IVEC into %g3.  */
        ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
@@ -90,8 +89,7 @@ sun4v_dev_mondo:
         */
 
        /* Update queue head pointer, this frees up some registers.  */
-       sethi   %hi(8192 - 1), %g4
-       or      %g4, %lo(8192 - 1), %g4
+       lduw    [%g4 + TRAP_PER_CPU_DEV_MONDO_QMASK], %g4
        and     %g2, %g4, %g2
 
        mov     INTRQ_DEVICE_MONDO_HEAD, %g4
@@ -143,6 +141,8 @@ sun4v_res_mondo:
        brnz,pn %g1, sun4v_res_mondo_queue_full
         nop
 
+       lduw    [%g3 + TRAP_PER_CPU_RESUM_QMASK], %g4
+
        /* Remember this entry's offset in %g1.  */
        mov     %g2, %g1
 
@@ -173,8 +173,6 @@ sun4v_res_mondo:
        add     %g2, 0x08, %g2
 
        /* Update queue head pointer.  */
-       sethi   %hi(8192 - 1), %g4
-       or      %g4, %lo(8192 - 1), %g4
        and     %g2, %g4, %g2
 
        mov     INTRQ_RESUM_MONDO_HEAD, %g4
@@ -254,6 +252,8 @@ sun4v_nonres_mondo:
        brnz,pn %g1, sun4v_nonres_mondo_queue_full
         nop
 
+       lduw    [%g3 + TRAP_PER_CPU_NONRESUM_QMASK], %g4
+
        /* Remember this entry's offset in %g1.  */
        mov     %g2, %g1
 
@@ -284,8 +284,6 @@ sun4v_nonres_mondo:
        add     %g2, 0x08, %g2
 
        /* Update queue head pointer.  */
-       sethi   %hi(8192 - 1), %g4
-       or      %g4, %lo(8192 - 1), %g4
        and     %g2, %g4, %g2
 
        mov     INTRQ_NONRESUM_MONDO_HEAD, %g4
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c
new file mode 100644 (file)
index 0000000..cdb1477
--- /dev/null
@@ -0,0 +1,297 @@
+/* sysfs.c: Toplogy sysfs support code for sparc64.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+
+#include <asm/hypervisor.h>
+#include <asm/spitfire.h>
+
+static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64)));
+
+#define SHOW_MMUSTAT_ULONG(NAME) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+       struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \
+       return sprintf(buf, "%lu\n", p->NAME); \
+} \
+static SYSDEV_ATTR(NAME, 0444, show_##NAME, NULL)
+
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte);
+
+static struct attribute *mmu_stat_attrs[] = {
+       &attr_immu_tsb_hits_ctx0_8k_tte.attr,
+       &attr_immu_tsb_ticks_ctx0_8k_tte.attr,
+       &attr_immu_tsb_hits_ctx0_64k_tte.attr,
+       &attr_immu_tsb_ticks_ctx0_64k_tte.attr,
+       &attr_immu_tsb_hits_ctx0_4mb_tte.attr,
+       &attr_immu_tsb_ticks_ctx0_4mb_tte.attr,
+       &attr_immu_tsb_hits_ctx0_256mb_tte.attr,
+       &attr_immu_tsb_ticks_ctx0_256mb_tte.attr,
+       &attr_immu_tsb_hits_ctxnon0_8k_tte.attr,
+       &attr_immu_tsb_ticks_ctxnon0_8k_tte.attr,
+       &attr_immu_tsb_hits_ctxnon0_64k_tte.attr,
+       &attr_immu_tsb_ticks_ctxnon0_64k_tte.attr,
+       &attr_immu_tsb_hits_ctxnon0_4mb_tte.attr,
+       &attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr,
+       &attr_immu_tsb_hits_ctxnon0_256mb_tte.attr,
+       &attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr,
+       &attr_dmmu_tsb_hits_ctx0_8k_tte.attr,
+       &attr_dmmu_tsb_ticks_ctx0_8k_tte.attr,
+       &attr_dmmu_tsb_hits_ctx0_64k_tte.attr,
+       &attr_dmmu_tsb_ticks_ctx0_64k_tte.attr,
+       &attr_dmmu_tsb_hits_ctx0_4mb_tte.attr,
+       &attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr,
+       &attr_dmmu_tsb_hits_ctx0_256mb_tte.attr,
+       &attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr,
+       &attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr,
+       &attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr,
+       &attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr,
+       &attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr,
+       &attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr,
+       &attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr,
+       &attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr,
+       &attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr,
+       NULL,
+};
+
+static struct attribute_group mmu_stat_group = {
+       .attrs = mmu_stat_attrs,
+       .name = "mmu_stats",
+};
+
+/* XXX convert to rusty's on_one_cpu */
+static unsigned long run_on_cpu(unsigned long cpu,
+                               unsigned long (*func)(unsigned long),
+                               unsigned long arg)
+{
+       cpumask_t old_affinity = current->cpus_allowed;
+       unsigned long ret;
+
+       /* should return -EINVAL to userspace */
+       if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+               return 0;
+
+       ret = func(arg);
+
+       set_cpus_allowed(current, old_affinity);
+
+       return ret;
+}
+
+static unsigned long read_mmustat_enable(unsigned long junk)
+{
+       unsigned long ra = 0;
+
+       sun4v_mmustat_info(&ra);
+
+       return ra != 0;
+}
+
+static unsigned long write_mmustat_enable(unsigned long val)
+{
+       unsigned long ra, orig_ra;
+
+       if (val)
+               ra = __pa(&per_cpu(mmu_stats, smp_processor_id()));
+       else
+               ra = 0UL;
+
+       return sun4v_mmustat_conf(ra, &orig_ra);
+}
+
+static ssize_t show_mmustat_enable(struct sys_device *s, char *buf)
+{
+       unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0);
+       return sprintf(buf, "%lx\n", val);
+}
+
+static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count)
+{
+       unsigned long val, err;
+       int ret = sscanf(buf, "%ld", &val);
+
+       if (ret != 1)
+               return -EINVAL;
+
+       err = run_on_cpu(s->id, write_mmustat_enable, val);
+       if (err)
+               return -EIO;
+
+       return count;
+}
+
+static SYSDEV_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable);
+
+static int mmu_stats_supported;
+
+static int register_mmu_stats(struct sys_device *s)
+{
+       if (!mmu_stats_supported)
+               return 0;
+       sysdev_create_file(s, &attr_mmustat_enable);
+       return sysfs_create_group(&s->kobj, &mmu_stat_group);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_mmu_stats(struct sys_device *s)
+{
+       if (!mmu_stats_supported)
+               return;
+       sysfs_remove_group(&s->kobj, &mmu_stat_group);
+       sysdev_remove_file(s, &attr_mmustat_enable);
+}
+#endif
+
+#define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+       cpuinfo_sparc *c = &cpu_data(dev->id); \
+       return sprintf(buf, "%lu\n", c->MEMBER); \
+}
+
+#define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+       cpuinfo_sparc *c = &cpu_data(dev->id); \
+       return sprintf(buf, "%u\n", c->MEMBER); \
+}
+
+SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick);
+SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val);
+SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size);
+SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size);
+SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size);
+SHOW_CPUDATA_UINT_NAME(l1_icache_line_size, icache_line_size);
+SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size);
+SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size);
+
+static struct sysdev_attribute cpu_core_attrs[] = {
+       _SYSDEV_ATTR(clock_tick,          0444, show_clock_tick, NULL),
+       _SYSDEV_ATTR(udelay_val,          0444, show_udelay_val, NULL),
+       _SYSDEV_ATTR(l1_dcache_size,      0444, show_l1_dcache_size, NULL),
+       _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL),
+       _SYSDEV_ATTR(l1_icache_size,      0444, show_l1_icache_size, NULL),
+       _SYSDEV_ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL),
+       _SYSDEV_ATTR(l2_cache_size,       0444, show_l2_cache_size, NULL),
+       _SYSDEV_ATTR(l2_cache_line_size,  0444, show_l2_cache_line_size, NULL),
+};
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+static void register_cpu_online(unsigned int cpu)
+{
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
+       struct sys_device *s = &c->sysdev;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+               sysdev_create_file(s, &cpu_core_attrs[i]);
+
+       register_mmu_stats(s);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_cpu_online(unsigned int cpu)
+{
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
+       struct sys_device *s = &c->sysdev;
+       int i;
+
+       unregister_mmu_stats(s);
+       for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+               sysdev_remove_file(s, &cpu_core_attrs[i]);
+}
+#endif
+
+static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
+                                     unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned int)(long)hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               register_cpu_online(cpu);
+               break;
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               unregister_cpu_online(cpu);
+               break;
+#endif
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+       .notifier_call  = sysfs_cpu_notify,
+};
+
+static void __init check_mmu_stats(void)
+{
+       unsigned long dummy1, err;
+
+       if (tlb_type != hypervisor)
+               return;
+
+       err = sun4v_mmustat_info(&dummy1);
+       if (!err)
+               mmu_stats_supported = 1;
+}
+
+static int __init topology_init(void)
+{
+       int cpu;
+
+       check_mmu_stats();
+
+       register_cpu_notifier(&sysfs_cpu_nb);
+
+       for_each_possible_cpu(cpu) {
+               struct cpu *c = &per_cpu(cpu_devices, cpu);
+
+               register_cpu(c, cpu);
+               if (cpu_online(cpu))
+                       register_cpu_online(cpu);
+       }
+
+       return 0;
+}
+
+subsys_initcall(topology_init);
index 2d63d7689962edba455edfe4c44e45eb72ef708c..a31a0439244f387973893d3a9d215ebd4ae0555c 100644 (file)
@@ -680,22 +680,14 @@ static int starfire_set_time(u32 val)
 
 static u32 hypervisor_get_time(void)
 {
-       register unsigned long func asm("%o5");
-       register unsigned long arg0 asm("%o0");
-       register unsigned long arg1 asm("%o1");
+       unsigned long ret, time;
        int retries = 10000;
 
 retry:
-       func = HV_FAST_TOD_GET;
-       arg0 = 0;
-       arg1 = 0;
-       __asm__ __volatile__("ta        %6"
-                            : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
-                            : "0" (func), "1" (arg0), "2" (arg1),
-                              "i" (HV_FAST_TRAP));
-       if (arg0 == HV_EOK)
-               return arg1;
-       if (arg0 == HV_EWOULDBLOCK) {
+       ret = sun4v_tod_get(&time);
+       if (ret == HV_EOK)
+               return time;
+       if (ret == HV_EWOULDBLOCK) {
                if (--retries > 0) {
                        udelay(100);
                        goto retry;
@@ -709,20 +701,14 @@ retry:
 
 static int hypervisor_set_time(u32 secs)
 {
-       register unsigned long func asm("%o5");
-       register unsigned long arg0 asm("%o0");
+       unsigned long ret;
        int retries = 10000;
 
 retry:
-       func = HV_FAST_TOD_SET;
-       arg0 = secs;
-       __asm__ __volatile__("ta        %4"
-                            : "=&r" (func), "=&r" (arg0)
-                            : "0" (func), "1" (arg0),
-                              "i" (HV_FAST_TRAP));
-       if (arg0 == HV_EOK)
+       ret = sun4v_tod_set(secs);
+       if (ret == HV_EOK)
                return 0;
-       if (arg0 == HV_EWOULDBLOCK) {
+       if (ret == HV_EWOULDBLOCK) {
                if (--retries > 0) {
                        udelay(100);
                        goto retry;
@@ -862,7 +848,6 @@ fs_initcall(clock_init);
 static unsigned long sparc64_init_timers(void)
 {
        struct device_node *dp;
-       struct property *prop;
        unsigned long clock;
 #ifdef CONFIG_SMP
        extern void smp_tick_init(void);
@@ -879,17 +864,15 @@ static unsigned long sparc64_init_timers(void)
                if (manuf == 0x17 && impl == 0x13) {
                        /* Hummingbird, aka Ultra-IIe */
                        tick_ops = &hbtick_operations;
-                       prop = of_find_property(dp, "stick-frequency", NULL);
+                       clock = of_getintprop_default(dp, "stick-frequency", 0);
                } else {
                        tick_ops = &tick_operations;
-                       cpu_find_by_instance(0, &dp, NULL);
-                       prop = of_find_property(dp, "clock-frequency", NULL);
+                       clock = local_cpu_data().clock_tick;
                }
        } else {
                tick_ops = &stick_operations;
-               prop = of_find_property(dp, "stick-frequency", NULL);
+               clock = of_getintprop_default(dp, "stick-frequency", 0);
        }
-       clock = *(unsigned int *) prop->value;
 
 #ifdef CONFIG_SMP
        smp_tick_init();
@@ -1365,6 +1348,7 @@ static int hypervisor_set_rtc_time(struct rtc_time *time)
        return hypervisor_set_time(seconds);
 }
 
+#ifdef CONFIG_PCI
 static void bq4802_get_rtc_time(struct rtc_time *time)
 {
        unsigned char val = readb(bq4802_regs + 0x0e);
@@ -1436,6 +1420,7 @@ static int bq4802_set_rtc_time(struct rtc_time *time)
 
        return 0;
 }
+#endif /* CONFIG_PCI */
 
 struct mini_rtc_ops {
        void (*get_rtc_time)(struct rtc_time *);
@@ -1452,10 +1437,12 @@ static struct mini_rtc_ops hypervisor_rtc_ops = {
        .set_rtc_time = hypervisor_set_rtc_time,
 };
 
+#ifdef CONFIG_PCI
 static struct mini_rtc_ops bq4802_rtc_ops = {
        .get_rtc_time = bq4802_get_rtc_time,
        .set_rtc_time = bq4802_set_rtc_time,
 };
+#endif /* CONFIG_PCI */
 
 static struct mini_rtc_ops *mini_rtc_ops;
 
@@ -1579,8 +1566,10 @@ static int __init rtc_mini_init(void)
                mini_rtc_ops = &hypervisor_rtc_ops;
        else if (this_is_starfire)
                mini_rtc_ops = &starfire_rtc_ops;
+#ifdef CONFIG_PCI
        else if (bq4802_regs)
                mini_rtc_ops = &bq4802_rtc_ops;
+#endif /* CONFIG_PCI */
        else
                return -ENODEV;
 
index d0fde36395b4a07e9dfa7586b8cc90d8a69bb782..00a9e3286c837e2acab7bf5a155bc3729c7da0b6 100644 (file)
@@ -795,8 +795,7 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector
 void __init cheetah_ecache_flush_init(void)
 {
        unsigned long largest_size, smallest_linesize, order, ver;
-       struct device_node *dp;
-       int i, instance, sz;
+       int i, sz;
 
        /* Scan all cpu device tree nodes, note two values:
         * 1) largest E-cache size
@@ -805,18 +804,20 @@ void __init cheetah_ecache_flush_init(void)
        largest_size = 0UL;
        smallest_linesize = ~0UL;
 
-       instance = 0;
-       while (!cpu_find_by_instance(instance, &dp, NULL)) {
+       for (i = 0; i < NR_CPUS; i++) {
                unsigned long val;
 
-               val = of_getintprop_default(dp, "ecache-size",
-                                           (2 * 1024 * 1024));
+               val = cpu_data(i).ecache_size;
+               if (!val)
+                       continue;
+
                if (val > largest_size)
                        largest_size = val;
-               val = of_getintprop_default(dp, "ecache-line-size", 64);
+
+               val = cpu_data(i).ecache_line_size;
                if (val < smallest_linesize)
                        smallest_linesize = val;
-               instance++;
+
        }
 
        if (largest_size == 0UL || smallest_linesize == ~0UL) {
@@ -2564,7 +2565,15 @@ void __init trap_init(void)
            (TRAP_PER_CPU_TSB_HUGE_TEMP !=
             offsetof(struct trap_per_cpu, tsb_huge_temp)) ||
            (TRAP_PER_CPU_IRQ_WORKLIST !=
-            offsetof(struct trap_per_cpu, irq_worklist)))
+            offsetof(struct trap_per_cpu, irq_worklist)) ||
+           (TRAP_PER_CPU_CPU_MONDO_QMASK !=
+            offsetof(struct trap_per_cpu, cpu_mondo_qmask)) ||
+           (TRAP_PER_CPU_DEV_MONDO_QMASK !=
+            offsetof(struct trap_per_cpu, dev_mondo_qmask)) ||
+           (TRAP_PER_CPU_RESUM_QMASK !=
+            offsetof(struct trap_per_cpu, resum_qmask)) ||
+           (TRAP_PER_CPU_NONRESUM_QMASK !=
+            offsetof(struct trap_per_cpu, nonresum_qmask)))
                trap_per_cpu_offsets_are_bolixed_dave();
 
        if ((TSB_CONFIG_TSB !=
index fb648de18a8d0b6350c06cc0c76191831907d304..3ad10f3027e4b2e82790dd826db811bf136b72f8 100644 (file)
@@ -1,5 +1,6 @@
 /* ld script to make UltraLinux kernel */
 
+#include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 
 OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc")
@@ -23,7 +24,7 @@ SECTIONS
   _etext = .;
   PROVIDE (etext = .);
 
-  RODATA
+  RO_DATA(PAGE_SIZE)
 
   .data    :
   {
@@ -44,7 +45,7 @@ SECTIONS
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(8192);
+  . = ALIGN(PAGE_SIZE);
   __init_begin = .;
   .init.text : { 
        _sinittext = .;
@@ -83,17 +84,17 @@ SECTIONS
   __sun4v_2insn_patch_end = .;
 
 #ifdef CONFIG_BLK_DEV_INITRD
-  . = ALIGN(8192); 
+  . = ALIGN(PAGE_SIZE);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
   __initramfs_end = .;
 #endif
 
-  . = ALIGN(8192);
+  . = ALIGN(PAGE_SIZE);
   __per_cpu_start = .;
   .data.percpu  : { *(.data.percpu) }
   __per_cpu_end = .;
-  . = ALIGN(8192);
+  . = ALIGN(PAGE_SIZE);
   __init_end = .;
   __bss_start = .;
   .sbss      : { *(.sbss) *(.scommon) }
index 6e5b01d779d2d484fc60728010058fdd70dc4280..3010227fe24313ccddc630068c9503aa77b7c409 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kprobes.h>
 #include <linux/cache.h>
 #include <linux/sort.h>
+#include <linux/percpu.h>
 
 #include <asm/head.h>
 #include <asm/system.h>
@@ -43,8 +44,8 @@
 #include <asm/tsb.h>
 #include <asm/hypervisor.h>
 #include <asm/prom.h>
-
-extern void device_scan(void);
+#include <asm/sstate.h>
+#include <asm/mdesc.h>
 
 #define MAX_PHYS_ADDRESS       (1UL << 42UL)
 #define KPTE_BITMAP_CHUNK_SZ   (256UL * 1024UL * 1024UL)
@@ -60,8 +61,11 @@ unsigned long kern_linear_pte_xor[2] __read_mostly;
 unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
 
 #ifndef CONFIG_DEBUG_PAGEALLOC
-/* A special kernel TSB for 4MB and 256MB linear mappings.  */
-struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
+/* A special kernel TSB for 4MB and 256MB linear mappings.
+ * Space is allocated for this right after the trap table
+ * in arch/sparc64/kernel/head.S
+ */
+extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
 #endif
 
 #define MAX_BANKS      32
@@ -190,12 +194,9 @@ inline void flush_dcache_page_impl(struct page *page)
 }
 
 #define PG_dcache_dirty                PG_arch_1
-#define PG_dcache_cpu_shift    24UL
-#define PG_dcache_cpu_mask     (256UL - 1UL)
-
-#if NR_CPUS > 256
-#error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus
-#endif
+#define PG_dcache_cpu_shift    32UL
+#define PG_dcache_cpu_mask     \
+       ((1UL<<ilog2(roundup_pow_of_two(NR_CPUS)))-1UL)
 
 #define dcache_dirty_cpu(page) \
        (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
@@ -557,26 +558,11 @@ static void __init hypervisor_tlb_lock(unsigned long vaddr,
                                       unsigned long pte,
                                       unsigned long mmu)
 {
-       register unsigned long func asm("%o5");
-       register unsigned long arg0 asm("%o0");
-       register unsigned long arg1 asm("%o1");
-       register unsigned long arg2 asm("%o2");
-       register unsigned long arg3 asm("%o3");
-
-       func = HV_FAST_MMU_MAP_PERM_ADDR;
-       arg0 = vaddr;
-       arg1 = 0;
-       arg2 = pte;
-       arg3 = mmu;
-       __asm__ __volatile__("ta        0x80"
-                            : "=&r" (func), "=&r" (arg0),
-                              "=&r" (arg1), "=&r" (arg2),
-                              "=&r" (arg3)
-                            : "0" (func), "1" (arg0), "2" (arg1),
-                              "3" (arg2), "4" (arg3));
-       if (arg0 != 0) {
+       unsigned long ret = sun4v_mmu_map_perm_addr(vaddr, 0, pte, mmu);
+
+       if (ret != 0) {
                prom_printf("hypervisor_tlb_lock[%lx:%lx:%lx:%lx]: "
-                           "errors with %lx\n", vaddr, 0, pte, mmu, arg0);
+                           "errors with %lx\n", vaddr, 0, pte, mmu, ret);
                prom_halt();
        }
 }
@@ -1313,20 +1299,16 @@ static void __init sun4v_ktsb_init(void)
 
 void __cpuinit sun4v_ktsb_register(void)
 {
-       register unsigned long func asm("%o5");
-       register unsigned long arg0 asm("%o0");
-       register unsigned long arg1 asm("%o1");
-       unsigned long pa;
+       unsigned long pa, ret;
 
        pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE);
 
-       func = HV_FAST_MMU_TSB_CTX0;
-       arg0 = NUM_KTSB_DESCR;
-       arg1 = pa;
-       __asm__ __volatile__("ta        %6"
-                            : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
-                            : "0" (func), "1" (arg0), "2" (arg1),
-                              "i" (HV_FAST_TRAP));
+       ret = sun4v_mmu_tsb_ctx0(NUM_KTSB_DESCR, pa);
+       if (ret != 0) {
+               prom_printf("hypervisor_mmu_tsb_ctx0[%lx]: "
+                           "errors with %lx\n", pa, ret);
+               prom_halt();
+       }
 }
 
 /* paging_init() sets up the page tables */
@@ -1334,6 +1316,9 @@ void __cpuinit sun4v_ktsb_register(void)
 extern void cheetah_ecache_flush_init(void);
 extern void sun4v_patch_tlb_handlers(void);
 
+extern void cpu_probe(void);
+extern void central_probe(void);
+
 static unsigned long last_valid_pfn;
 pgd_t swapper_pg_dir[2048];
 
@@ -1345,9 +1330,24 @@ void __init paging_init(void)
        unsigned long end_pfn, pages_avail, shift, phys_base;
        unsigned long real_end, i;
 
+       /* These build time checkes make sure that the dcache_dirty_cpu()
+        * page->flags usage will work.
+        *
+        * When a page gets marked as dcache-dirty, we store the
+        * cpu number starting at bit 32 in the page->flags.  Also,
+        * functions like clear_dcache_dirty_cpu use the cpu mask
+        * in 13-bit signed-immediate instruction fields.
+        */
+       BUILD_BUG_ON(FLAGS_RESERVED != 32);
+       BUILD_BUG_ON(SECTIONS_WIDTH + NODES_WIDTH + ZONES_WIDTH +
+                    ilog2(roundup_pow_of_two(NR_CPUS)) > FLAGS_RESERVED);
+       BUILD_BUG_ON(NR_CPUS > 4096);
+
        kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
        kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
 
+       sstate_booting();
+
        /* Invalidate both kernel TSBs.  */
        memset(swapper_tsb, 0x40, sizeof(swapper_tsb));
 #ifndef CONFIG_DEBUG_PAGEALLOC
@@ -1416,8 +1416,13 @@ void __init paging_init(void)
 
        kernel_physical_mapping_init();
 
+       real_setup_per_cpu_areas();
+
        prom_build_devicetree();
 
+       if (tlb_type == hypervisor)
+               sun4v_mdesc_init();
+
        {
                unsigned long zones_size[MAX_NR_ZONES];
                unsigned long zholes_size[MAX_NR_ZONES];
@@ -1434,7 +1439,10 @@ void __init paging_init(void)
                                    zholes_size);
        }
 
-       device_scan();
+       prom_printf("Booting Linux...\n");
+
+       central_probe();
+       cpu_probe();
 }
 
 static void __init taint_real_pages(void)
index 0b4213720d439167e3ba7f59ab5b78849df072d3..f3e0c14e9eef001ba157307375555e2adf5efc57 100644 (file)
 #include <asm/oplib.h>
 #include <asm/system.h>
 
+int prom_service_exists(const char *service_name)
+{
+       int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
+                           P1275_INOUT(1, 1), service_name);
+
+       if (err)
+               return 0;
+       return 1;
+}
+
+void prom_sun4v_guest_soft_state(void)
+{
+       const char *svc = "SUNW,soft-state-supported";
+
+       if (!prom_service_exists(svc))
+               return;
+       p1275_cmd(svc, P1275_INOUT(0, 0));
+}
+
 /* Reset and reboot the machine with the command 'bcommand'. */
 void prom_reboot(const char *bcommand)
 {
index c504312219b42b8f9797c50fe1569e5f05163a84..e6ff30266542a79b8909a5ef5f4e7991e58e16ca 100644 (file)
@@ -278,6 +278,7 @@ config HIGHMEM
 config KERNEL_STACK_ORDER
        int "Kernel stack size order"
        default 1 if 64BIT
+       range 1 10 if 64BIT
        default 0 if !64BIT
        help
        This option determines the size of UML kernel stacks.  They will
index ced99106f7982b84a13eed11a71890f04ba4ae2e..4bd40bb43ec27f3935306fb784e84bdf160172a4 100644 (file)
@@ -3,6 +3,7 @@
  * Licensed under the GPL
  */
 
+#include "linux/kernel.h"
 #include "linux/sched.h"
 #include "linux/slab.h"
 #include "linux/list.h"
index 911539293871d271ed306c36fd1b113f6acc9203..4739dd527b43ab8ff5cf59ab007cfbbd033b90d8 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/console.h>
 
index 70509ddaac035cd60537e286883614323410be6d..2e09f162c42f01b6ac39f3689eae208f5d4b75b1 100644 (file)
@@ -20,6 +20,7 @@
 #define MAJOR_NR UBD_MAJOR
 #define UBD_SHIFT 4
 
+#include "linux/kernel.h"
 #include "linux/module.h"
 #include "linux/blkdev.h"
 #include "linux/hdreg.h"
index 8b7f2cdedf945148ffd96306ac04024dc9a0a7ee..c716b5a6db13d9552a59e7f7ec5688229ca9bf0e 100644 (file)
@@ -1,8 +1,9 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 
+#include "linux/kernel.h"
 #include "linux/init.h"
 #include "linux/ctype.h"
 #include "linux/proc_fs.h"
@@ -24,11 +25,14 @@ static int read_proc_exitcode(char *page, char **start, off_t off,
        val = uml_exitcode;
        len = sprintf(page, "%d\n", val);
        len -= off;
-       if(len <= off+count) *eof = 1;
+       if(len <= off+count)
+               *eof = 1;
        *start = page + off;
-       if(len > count) len = count;
-       if(len < 0) len = 0;
-       return(len);
+       if(len > count)
+               len = count;
+       if(len < 0)
+               len = 0;
+       return len;
 }
 
 static int write_proc_exitcode(struct file *file, const char __user *buffer,
@@ -38,12 +42,14 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer,
        int tmp;
 
        if(copy_from_user(buf, buffer, count))
-               return(-EFAULT);
+               return -EFAULT;
+
        tmp = simple_strtol(buf, &end, 0);
        if((*end != '\0') && !isspace(*end))
-               return(-EINVAL);
+               return -EINVAL;
+
        uml_exitcode = tmp;
-       return(count);
+       return count;
 }
 
 static int make_proc_exitcode(void)
@@ -54,24 +60,13 @@ static int make_proc_exitcode(void)
        if(ent == NULL){
                printk(KERN_WARNING "make_proc_exitcode : Failed to register "
                       "/proc/exitcode\n");
-               return(0);
+               return 0;
        }
 
        ent->read_proc = read_proc_exitcode;
        ent->write_proc = write_proc_exitcode;
-       
-       return(0);
+
+       return 0;
 }
 
 __initcall(make_proc_exitcode);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 79471f85eb8963d79654484fa3af9fd50aa5908b..3fc13fa8729d27c5578459eab5b9742d1ee1f842 100644 (file)
@@ -144,9 +144,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
                int exit_with = WEXITSTATUS(status);
                if (exit_with == 2)
                        non_fatal("check_ptrace : child exited with status 2. "
-                                 "Serious trouble happening! Try updating "
-                                 "your host skas patch!\nDisabling SYSEMU "
-                                 "support.");
+                                 "\nDisabling SYSEMU support.\n");
                non_fatal("check_ptrace : child exited with exitcode %d, while "
                          "expecting %d; status 0x%x\n", exit_with,
                          exitcode, status);
@@ -209,6 +207,7 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
 static void __init check_sysemu(void)
 {
        void *stack;
+       unsigned long regs[MAX_REG_NR];
        int pid, n, status, count=0;
 
        non_fatal("Checking syscall emulation patch for ptrace...");
@@ -225,11 +224,20 @@ static void __init check_sysemu(void)
                fatal("check_sysemu : expected SIGTRAP, got status = %d",
                      status);
 
-       n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
-                  os_getpid());
-       if(n < 0)
-               fatal_perror("check_sysemu : failed to modify system call "
-                            "return");
+       if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+               fatal_perror("check_sysemu : PTRACE_GETREGS failed");
+       if(PT_SYSCALL_NR(regs) != __NR_getpid){
+               non_fatal("check_sysemu got system call number %d, "
+                         "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
+               goto fail;
+       }
+
+       n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
+       if(n < 0){
+               non_fatal("check_sysemu : failed to modify system call "
+                         "return");
+               goto fail;
+       }
 
        if (stop_ptraced_child(pid, stack, 0, 0) < 0)
                goto fail_stopped;
index 145bb824b2a878fcd0334021e8d434d1898d5a7f..5ce94430c019cfe90bb647082d0c63e41e0c09e5 100644 (file)
@@ -428,12 +428,15 @@ config NR_CPUS
          memory in the static kernel configuration.
 
 config HOTPLUG_CPU
-       bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+       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#.
-               Say N if you want to disable CPU hotplug.
+               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
index bc11b32e8b4d41fb000692825048d1dcd3a0339c..7377ccb213350242ad7e7777ad266541b05a3e8b 100644 (file)
@@ -39,10 +39,10 @@ int cache_k8_northbridges(void)
 {
        int i;
        struct pci_dev *dev;
+
        if (num_k8_northbridges)
                return 0;
 
-       num_k8_northbridges = 0;
        dev = NULL;
        while ((dev = next_k8_northbridge(dev)) != NULL)
                num_k8_northbridges++;
@@ -52,6 +52,11 @@ int cache_k8_northbridges(void)
        if (!k8_northbridges)
                return -ENOMEM;
 
+       if (!num_k8_northbridges) {
+               k8_northbridges[0] = NULL;
+               return 0;
+       }
+
        flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL);
        if (!flush_words) {
                kfree(k8_northbridges);
index cb29fb96948dd2653886e2fe444fb35ea55dae48..aac1c0be54c6b8f99c032f61f6b29f904d91977d 100644 (file)
@@ -465,13 +465,14 @@ static unsigned int die_nest_count;
 
 unsigned __kprobes long oops_begin(void)
 {
-       int cpu = smp_processor_id();
+       int cpu;
        unsigned long flags;
 
        oops_enter();
 
        /* racy, but better than risking deadlock. */
        local_irq_save(flags);
+       cpu = smp_processor_id();
        if (!spin_trylock(&die_lock)) { 
                if (cpu == die_owner) 
                        /* nested oops. should stop eventually */;
index bfb62a13d7eee005f2b364b159b21096e811ae53..635e58d443d7c555f118cca839656bfad2adb15e 100644 (file)
@@ -476,6 +476,12 @@ bad_area:
 bad_area_nosemaphore:
        /* User mode accesses just cause a SIGSEGV */
        if (error_code & PF_USER) {
+
+               /*
+                * It's possible to have interrupts off here.
+                */
+               local_irq_enable();
+
                if (is_prefetch(regs, address, error_code))
                        return;
 
index 1336da8bdee125f5b0ba227360d89c4709264323..efb6e845114ec727430860981b03b22495f9d299 100644 (file)
@@ -79,6 +79,8 @@ void show_mem(void)
                        if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) {
                                touch_nmi_watchdog();
                        }
+                       if (!pfn_valid(pgdat->node_start_pfn + i))
+                               continue;
                        page = pfn_to_page(pgdat->node_start_pfn + i);
                        total++;
                        if (PageReserved(page))
@@ -761,3 +763,9 @@ int in_gate_area_no_task(unsigned long addr)
 {
        return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
 }
+
+void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
+{
+       return __alloc_bootmem_core(pgdat->bdata, size,
+                       SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0);
+}
index 698079b3a3368f86735a584daa26384456d11dc1..d0323cd6a2ead094411a48109e2512d76c17e9e1 100644 (file)
@@ -39,6 +39,7 @@ int main(void)
        DEFINE(PT_LEND, offsetof (struct pt_regs, lend));
        DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount));
        DEFINE(PT_SAR, offsetof (struct pt_regs, sar));
+       DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel));
        DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
        DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
        DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
index 9e271ba009bfd88645008e0adca5d7b3e87a4e0d..8dc7a2c26ff9f87f9854118d0c1006f544c8202f 100644 (file)
@@ -125,8 +125,9 @@ _user_exception:
 
        movi    a2, 0
        rsr     a3, SAR
-       wsr     a2, ICOUNTLEVEL
+       xsr     a2, ICOUNTLEVEL
        s32i    a3, a1, PT_SAR
+       s32i    a2, a1, PT_ICOUNTLEVEL
 
        /* Rotate ws so that the current windowbase is at bit0. */
        /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
@@ -276,8 +277,9 @@ _kernel_exception:
 
        movi    a2, 0
        rsr     a3, SAR
-       wsr     a2, ICOUNTLEVEL
+       xsr     a2, ICOUNTLEVEL
        s32i    a3, a1, PT_SAR
+       s32i    a2, a1, PT_ICOUNTLEVEL
 
        /* Rotate ws so that the current windowbase is at bit0. */
        /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
@@ -330,14 +332,16 @@ _kernel_exception:
 
 common_exception:
 
-       /* Save EXCVADDR, DEBUGCAUSE, and PC, and clear LCOUNT */
+       /* Save some registers, disable loops and clear the syscall flag. */
 
        rsr     a2, DEBUGCAUSE
        rsr     a3, EPC_1
        s32i    a2, a1, PT_DEBUGCAUSE
        s32i    a3, a1, PT_PC
 
+       movi    a2, -1
        rsr     a3, EXCVADDR
+       s32i    a2, a1, PT_SYSCALL
        movi    a2, 0
        s32i    a3, a1, PT_EXCVADDR
        xsr     a2, LCOUNT
@@ -450,27 +454,8 @@ common_exception_return:
 
        /* Restore the state of the task and return from the exception. */
 
-
-       /* If we are returning from a user exception, and the process
-        * to run next has PT_SINGLESTEP set, we want to setup
-        * ICOUNT and ICOUNTLEVEL to step one instruction.
-        * PT_SINGLESTEP is set by sys_ptrace (ptrace.c)
-        */
-
 4:     /* a2 holds GET_CURRENT(a2,a1)  */
 
-       l32i    a3, a2, TI_TASK
-       l32i    a3, a3, TASK_PTRACE
-       bbci.l  a3, PT_SINGLESTEP_BIT, 1f # jump if single-step flag is not set
-
-       movi    a3, -2                  # PT_SINGLESTEP flag is set,
-       movi    a4, 1                   # icountlevel of 1 means it won't
-       wsr     a3, ICOUNT              # start counting until after rfe
-       wsr     a4, ICOUNTLEVEL         # so setup icount & icountlevel.
-       isync
-
-1:
-
 #if XCHAL_EXTRA_SA_SIZE
 
        /* For user exceptions, restore the extra state from the user's TCB. */
@@ -665,6 +650,13 @@ common_exception_exit:
        wsr     a3, LEND
        wsr     a2, LCOUNT
 
+       /* We control single stepping through the ICOUNTLEVEL register. */
+
+       l32i    a2, a1, PT_ICOUNTLEVEL
+       movi    a3, -2
+       wsr     a2, ICOUNTLEVEL
+       wsr     a3, ICOUNT
+
        /* Check if it was double exception. */
 
        l32i    a0, a1, PT_DEPC
index ea89910efa44f523e928ffc6a1b33938e5e97d45..67e69139520bd91cb834dbfc68d591039712d3b7 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/page.h>
 #include <asm/cacheasm.h>
 
+#include <linux/linkage.h>
+
 /*
  * This module contains the entry code for kernel images. It performs the
  * minimal setup needed to call the generic C routines.
@@ -227,13 +229,14 @@ _startup:
 should_never_return:
        j       should_never_return
 
-       /* Define some common data structures here.  We define them
-        * here in this assembly file due to their unusual alignment
-        * requirements.
-        */
 
-       .comm   swapper_pg_dir,PAGE_SIZE,PAGE_SIZE
-       .comm   empty_bad_page_table,PAGE_SIZE,PAGE_SIZE
-       .comm   empty_bad_page,PAGE_SIZE,PAGE_SIZE
-       .comm   empty_zero_page,PAGE_SIZE,PAGE_SIZE
+/*
+ * BSS section
+ */
+       
+.section ".bss.page_aligned", "w"
+ENTRY(swapper_pg_dir)
+       .fill   PAGE_SIZE, 1, 0
+ENTRY(empty_zero_page)
+       .fill   PAGE_SIZE, 1, 0
 
index 45571ccb72d63e16b169b3aa2301676d0917fc52..77deae5290f06e43f64c379ba1bc33646b325afb 100644 (file)
@@ -401,7 +401,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
  * Also, think for a moment about likes of floppy.c that
  * include architecture specific parts. They may want to redefine ins/outs.
  *
- * We do not use horroble macroses here because we want to
+ * We do not use horrible macros here because we want to
  * advance pointer by sizeof(size).
  */
 void outsb(unsigned long addr, const void *src, unsigned long count) {
index 1ecf6716c3274a1ce2575236b036e864c57e6127..2e8d398cf19627aef6db11a8e6d723ae7b106fa7 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/platform.h>
 #include <asm/page.h>
 #include <asm/setup.h>
+#include <asm/param.h>
 
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16};
index 58107672a619eeebf783b8249658bfc6396274ed..033aae0336d260d323f07c3abaad1ea521690d7c 100644 (file)
-// TODO coprocessor stuff
 /*
- *  linux/arch/xtensa/kernel/signal.c
+ * arch/xtensa/kernel/signal.c
  *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
- *
- *  Joe Taylor <joe@tensilica.com>
- *  Chris Zankel <chris@zankel.net>
+ * Default platform functions.
  *
+ * 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) 2005, 2006 Tensilica Inc.
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * 1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  *
+ * Chris Zankel <chris@zankel.net>
+ * Joe Taylor <joe@tensilica.com>
  */
 
-#include <asm/variant/core.h>
-#include <asm/coprocessor.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
-#include <linux/wait.h>
 #include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
 #include <linux/personality.h>
+#include <linux/freezer.h>
+
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
-#include <asm/pgtable.h>
 #include <asm/cacheflush.h>
+#include <asm/coprocessor.h>
+#include <asm/unistd.h>
 
 #define DEBUG_SIG  0
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
-                         struct rusage * ru);
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 
 extern struct task_struct *coproc_owners[];
 
+extern void release_all_cp (struct task_struct *);
 
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
+struct rt_sigframe
+{
+       struct siginfo info;
+       struct ucontext uc;
+       cp_state_t cpstate;
+       unsigned char retcode[6];
+       unsigned int window[4];
+};
+
+/* 
+ * Flush register windows stored in pt_regs to stack.
+ * Returns 1 for errors.
+ *
+ * Note that windowbase, windowstart, and wmask are not updated!
  */
 
-int xtensa_sigsuspend(struct pt_regs *regs)
+int
+flush_window_regs_user(struct pt_regs *regs)
 {
-       old_sigset_t mask = (old_sigset_t) regs->areg[3];
-       sigset_t saveset;
+       const unsigned long ws = regs->windowstart;
+       const unsigned long wb = regs->windowbase;
+       unsigned long sp = 0;
+       unsigned long wm;
+       int err = 1;
+       int base;
 
-       mask &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       /* Return if no other frames. */
 
-       regs->areg[2] = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
-}
+       if (regs->wmask == 1)
+               return 0;
 
-asmlinkage int
-xtensa_rt_sigsuspend(struct pt_regs *regs)
-{
-       sigset_t *unewset = (sigset_t *) regs->areg[4];
-       size_t sigsetsize = (size_t) regs->areg[3];
-       sigset_t saveset, newset;
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
+       /* Rotate windowmask and skip empty frames. */
 
-       if (copy_from_user(&newset, unewset, sizeof(newset)))
-               return -EFAULT;
-       sigdelsetmask(&newset, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb));
+       base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4);
+               
+       /* For call8 or call12 frames, we need the previous stack pointer. */
 
-       regs->areg[2] = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
-}
+       if ((regs->wmask & 2) == 0)
+               if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12)))
+                       goto errout;
 
-asmlinkage int
-xtensa_sigaction(int sig, const struct old_sigaction *act,
-             struct old_sigaction *oact)
-{
-       struct k_sigaction new_ka, old_ka;
-       int ret;
+       /* Spill frames to stack. */
 
-       if (act) {
-               old_sigset_t mask;
-               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
-                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
-                       return -EFAULT;
-               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               __get_user(mask, &act->sa_mask);
-               siginitset(&new_ka.sa.sa_mask, mask);
-       }
+       while (base < XCHAL_NUM_AREGS / 4) {
 
-       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+               int m = (wm >> base);
+               int inc = 0;
 
-       if (!ret && oact) {
-               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
-                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
-                       return -EFAULT;
-               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-       }
+               /* Save registers a4..a7 (call8) or a4...a11 (call12) */
 
-       return ret;
-}
+               if (m & 2) {                    /* call4 */
+                       inc = 1;
 
-asmlinkage int
-xtensa_sigaltstack(struct pt_regs *regs)
-{
-       const stack_t *uss = (stack_t *) regs->areg[4];
-       stack_t *uoss = (stack_t *) regs->areg[3];
+               } else if (m & 4) {             /* call8 */
+                       if (copy_to_user((void*)(sp - 32),
+                                          &regs->areg[(base + 1) * 4], 16))
+                               goto errout;
+                       inc = 2;
 
-       if (regs->depc > 64)
-               panic ("Double exception sys_sigreturn\n");
+               } else if (m & 8) {     /* call12 */
+                       if (copy_to_user((void*)(sp - 48),
+                                          &regs->areg[(base + 1) * 4], 32))
+                               goto errout;
+                       inc = 3;
+               }
 
+               /* Save current frame a0..a3 under next SP */
 
-       return do_sigaltstack(uss, uoss, regs->areg[1]);
-}
+               sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS];
+               if (copy_to_user((void*)(sp - 16), &regs->areg[base * 4], 16))
+                       goto errout;
+
+               /* Get current stack pointer for next loop iteration. */
+
+               sp = regs->areg[base * 4 + 1];
+               base += inc;
+       }
+
+       return 0;
 
+errout:
+       return err;
+}
 
 /*
- * Do a signal return; undo the signal stack.
+ * Note: We don't copy double exception 'regs', we have to finish double exc. 
+ * first before we return to signal handler! This dbl.exc.handler might cause 
+ * another double exception, but I think we are fine as the situation is the 
+ * same as if we had returned to the signal handerl and got an interrupt 
+ * immediately...
  */
 
-struct sigframe
-{
-       struct sigcontext sc;
-       struct _cpstate cpstate;
-       unsigned long extramask[_NSIG_WORDS-1];
-       unsigned char retcode[6];
-       unsigned int reserved[4]; /* Reserved area for chaining */
-       unsigned int window[4]; /* Window of 4 registers for initial context */
-};
-
-struct rt_sigframe
+static int
+setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
+                struct pt_regs *regs, unsigned long mask)
 {
-       struct siginfo info;
-       struct ucontext uc;
-       struct _cpstate cpstate;
-       unsigned char retcode[6];
-       unsigned int reserved[4]; /* Reserved area for chaining */
-       unsigned int window[4]; /* Window of 4 registers for initial context */
-};
+       int err = 0;
 
-extern void release_all_cp (struct task_struct *);
+#define COPY(x)        err |= __put_user(regs->x, &sc->sc_##x)
+       COPY(pc);
+       COPY(ps);
+       COPY(lbeg);
+       COPY(lend);
+       COPY(lcount);
+       COPY(sar);
+#undef COPY
 
+       err |= flush_window_regs_user(regs);
+       err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
 
-// FIXME restore_cpextra
-static inline int
-restore_cpextra (struct _cpstate *buf)
-{
-#if 0
-       /* The signal handler may have used coprocessors in which
-        * case they are still enabled.  We disable them to force a
-        * reloading of the original task's CP state by the lazy
-        * context-switching mechanisms of CP exception handling.
-        * Also, we essentially discard any coprocessor state that the
-        * signal handler created. */
+       // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4)
 
-       struct task_struct *tsk = current;
-       release_all_cp(tsk);
-       return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
+#if XCHAL_HAVE_CP
+# error Coprocessors unsupported
+       err |= save_cpextra(cpstate);
+       err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
 #endif
-       return 0;
-}
-
-/* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
- */
+       /* non-iBCS2 extensions.. */
+       err |= __put_user(mask, &sc->oldmask);
 
+       return err;
+}
 
 static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
-       struct thread_struct *thread;
        unsigned int err = 0;
        unsigned long ps;
-       struct _cpstate *buf;
 
 #define COPY(x)        err |= __get_user(regs->x, &sc->sc_##x)
        COPY(pc);
-       COPY(depc);
-       COPY(wmask);
        COPY(lbeg);
        COPY(lend);
        COPY(lcount);
        COPY(sar);
-       COPY(windowbase);
-       COPY(windowstart);
 #undef COPY
 
+       /* All registers were flushed to stack. Start with a prestine frame. */
+
+       regs->wmask = 1;
+       regs->windowbase = 0;
+       regs->windowstart = 1;
+
        /* For PS, restore only PS.CALLINC.
         * Assume that all other bits are either the same as for the signal
         * handler, or the user mode value doesn't matter (e.g. PS.OWB).
         */
        err |= __get_user(ps, &sc->sc_ps);
-       regs->ps = (regs->ps & ~PS_CALLINC_MASK)
-               | (ps & PS_CALLINC_MASK);
+       regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK);
 
        /* Additional corruption checks */
 
-       if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
-       || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
-               err = 1;
        if ((regs->lcount > 0)
-       && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
+           && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
                err = 1;
 
-       /* Restore extended register state.
-        * See struct thread_struct in processor.h.
-        */
-       thread = &current->thread;
-
-       err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
-       err |= __get_user(buf, &sc->sc_cpstate);
-       if (buf) {
-               if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
-                       goto badframe;
-               err |= restore_cpextra(buf);
-       }
-
-       regs->syscall = -1;             /* disable syscall checks */
-       return err;
-
-badframe:
-       return 1;
-}
-
-static inline void
-flush_my_cpstate(struct task_struct *tsk)
-{
-       unsigned long flags;
-       local_irq_save(flags);
-
-#if 0  // FIXME
-       for (i = 0; i < XCHAL_CP_NUM; i++) {
-               if (tsk == coproc_owners[i]) {
-                       xthal_validate_cp(i);
-                       xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
+       err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
 
-                       /* Invalidate and "disown" the cp to allow
-                        * callers the chance to reset cp state in the
-                        * task_struct. */
+#if XCHAL_HAVE_CP
+# error Coprocessors unsupported
+       /* The signal handler may have used coprocessors in which
+        * case they are still enabled.  We disable them to force a
+        * reloading of the original task's CP state by the lazy
+        * context-switching mechanisms of CP exception handling.
+        * Also, we essentially discard any coprocessor state that the
+        * signal handler created. */
 
-                       xthal_invalidate_cp(i);
-                       coproc_owners[i] = 0;
-               }
+       if (!err) {
+         struct task_struct *tsk = current;
+         release_all_cp(tsk);
+         err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, 
+                                 XTENSA_CP_EXTRA_SIZE);
        }
 #endif
-       local_irq_restore(flags);
-}
-
-/* Return codes:
-       0:  nothing saved
-       1:  stuff to save, successful
-       -1:  stuff to save, error happened
-*/
-static int
-save_cpextra (struct _cpstate *buf)
-{
-#if XCHAL_CP_NUM == 0
-       return 0;
-#else
-
-       /* FIXME: If a task has never used a coprocessor, there is
-        * no need to save and restore anything.  Tracking this
-        * information would allow us to optimize this section.
-        * Perhaps we can use current->used_math or (current->flags &
-        * PF_USEDFPU) or define a new field in the thread
-        * structure. */
-
-       /* We flush any live, task-owned cp state to the task_struct,
-        * then copy it all to the sigframe.  Then we clear all
-        * cp/extra state in the task_struct, effectively
-        * clearing/resetting all cp/extra state for the signal
-        * handler (cp-exception handling will load these new values
-        * into the cp/extra registers.)  This step is important for
-        * things like a floating-point cp, where the OS must reset
-        * the FCR to the default rounding mode. */
-
-       int err = 0;
-       struct task_struct *tsk = current;
-
-       flush_my_cpstate(tsk);
-       /* Note that we just copy everything: 'extra' and 'cp' state together.*/
-       err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
-       memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
-
-#if (XTENSA_CP_EXTRA_SIZE == 0)
-#error Sanity check on memset above, cpextra_size should not be zero.
-#endif
-
-       return err ? -1 : 1;
-#endif
-}
-
-static int
-setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
-                struct pt_regs *regs, unsigned long mask)
-{
-       struct thread_struct *thread;
-       int err = 0;
-
-//printk("setup_sigcontext\n");
-#define COPY(x)        err |= __put_user(regs->x, &sc->sc_##x)
-       COPY(pc);
-       COPY(ps);
-       COPY(depc);
-       COPY(wmask);
-       COPY(lbeg);
-       COPY(lend);
-       COPY(lcount);
-       COPY(sar);
-       COPY(windowbase);
-       COPY(windowstart);
-#undef COPY
-
-       /* Save extended register state.
-        * See struct thread_struct in processor.h.
-        */
-       thread = &current->thread;
-       err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
-       err |= save_cpextra(cpstate);
-       err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
-       /* non-iBCS2 extensions.. */
-       err |= __put_user(mask, &sc->oldmask);
 
+       regs->syscall = -1;             /* disable syscall checks */
        return err;
 }
 
-asmlinkage int xtensa_sigreturn(struct pt_regs *regs)
-{
-       struct sigframe *frame = (struct sigframe *)regs->areg[1];
-       sigset_t set;
-       if (regs->depc > 64)
-               panic ("Double exception sys_sigreturn\n");
-
-       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
-               goto badframe;
-
-       if (__get_user(set.sig[0], &frame->sc.oldmask)
-           || (_NSIG_WORDS > 1
-               && __copy_from_user(&set.sig[1], &frame->extramask,
-                                   sizeof(frame->extramask))))
-               goto badframe;
-
-       sigdelsetmask(&set, ~_BLOCKABLE);
-
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(regs, &frame->sc))
-               goto badframe;
-       return regs->areg[2];
 
-badframe:
-       force_sig(SIGSEGV, current);
-       return 0;
-}
+/*
+ * Do a signal return; undo the signal stack.
+ */
 
-asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
+                                   long a4, long a5, struct pt_regs *regs)
 {
-       struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
+       struct rt_sigframe __user *frame;
        sigset_t set;
-       stack_t st;
        int ret;
+
        if (regs->depc > 64)
-       {
-               printk("!!!!!!! DEPC !!!!!!!\n");
-               return 0;
-       }
+               panic("rt_sigreturn in double exception!\n");
+
+       frame = (struct rt_sigframe __user *) regs->areg[1];
 
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
@@ -407,13 +249,11 @@ asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs)
 
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
+
        ret = regs->areg[2];
 
-       if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->areg[1]) == -EFAULT)
                goto badframe;
-       /* It is more difficult to avoid calling this function than to
-          call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs->areg[1]);
 
        return ret;
 
@@ -422,77 +262,50 @@ badframe:
        return 0;
 }
 
-/*
- * Set up a signal frame.
- */
+
 
 /*
- * Determine which stack to use..
+ * Set up a signal frame.
  */
-static inline void *
-get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
-{
-       if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
-               sp = current->sas_ss_sp + current->sas_ss_size;
-
-       return (void *)((sp - frame_size) & -16ul);
-}
-
-#define USE_SIGRETURN          0
-#define USE_RT_SIGRETURN       1
 
 static int
-gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
+gen_return_code(unsigned char *codemem)
 {
-       unsigned int retcall;
        int err = 0;
 
-#if 0
-       /* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
-        * and the xtensa glibc doesn't use it.
+       /*
+        * The 12-bit immediate is really split up within the 24-bit MOVI
+        * instruction.  As long as the above system call numbers fit within
+        * 8-bits, the following code works fine. See the Xtensa ISA for
+        * details.
         */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               regs->pr = (unsigned long) ka->sa.sa_restorer;
-       } else
-#endif /* 0 */
-       {
-
-#if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
-
-/* The 12-bit immediate is really split up within the 24-bit MOVI
- * instruction.  As long as the above system call numbers fit within
- * 8-bits, the following code works fine. See the Xtensa ISA for
- * details.
- */
 
-#error Generating the MOVI instruction below breaks!
+#if __NR_rt_sigreturn > 255
+# error Generating the MOVI instruction below breaks!
 #endif
 
-               retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
-
 #ifdef __XTENSA_EB__   /* Big Endian version */
-               /* Generate instruction:  MOVI a2, retcall */
-               err |= __put_user(0x22, &codemem[0]);
-               err |= __put_user(0x0a, &codemem[1]);
-               err |= __put_user(retcall, &codemem[2]);
-               /* Generate instruction:  SYSCALL */
-               err |= __put_user(0x00, &codemem[3]);
-               err |= __put_user(0x05, &codemem[4]);
-               err |= __put_user(0x00, &codemem[5]);
+       /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
+       err |= __put_user(0x22, &codemem[0]);
+       err |= __put_user(0x0a, &codemem[1]);
+       err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
+       /* Generate instruction:  SYSCALL */
+       err |= __put_user(0x00, &codemem[3]);
+       err |= __put_user(0x05, &codemem[4]);
+       err |= __put_user(0x00, &codemem[5]);
 
 #elif defined __XTENSA_EL__   /* Little Endian version */
-               /* Generate instruction:  MOVI a2, retcall */
-               err |= __put_user(0x22, &codemem[0]);
-               err |= __put_user(0xa0, &codemem[1]);
-               err |= __put_user(retcall, &codemem[2]);
-               /* Generate instruction:  SYSCALL */
-               err |= __put_user(0x00, &codemem[3]);
-               err |= __put_user(0x50, &codemem[4]);
-               err |= __put_user(0x00, &codemem[5]);
+       /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
+       err |= __put_user(0x22, &codemem[0]);
+       err |= __put_user(0xa0, &codemem[1]);
+       err |= __put_user(__NR_rt_sigreturn, &codemem[2]);
+       /* Generate instruction:  SYSCALL */
+       err |= __put_user(0x00, &codemem[3]);
+       err |= __put_user(0x50, &codemem[4]);
+       err |= __put_user(0x00, &codemem[5]);
 #else
-#error Must use compiler for Xtensa processors.
+# error Must use compiler for Xtensa processors.
 #endif
-       }
 
        /* Flush generated code out of the data cache */
 
@@ -504,97 +317,29 @@ gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
        return err;
 }
 
-static void
-set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
-       void *handler, unsigned long arg1, void *arg2, void *arg3)
-{
-       /* Set up registers for signal handler */
-       start_thread(regs, (unsigned long) handler, (unsigned long) stack);
-
-       /* Set up a stack frame for a call4
-        * Note: PS.CALLINC is set to one by start_thread
-        */
-       regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
-       regs->areg[6] = arg1;
-       regs->areg[7] = (unsigned long) arg2;
-       regs->areg[8] = (unsigned long) arg3;
-}
 
-static void setup_frame(int sig, struct k_sigaction *ka,
+static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                        sigset_t *set, struct pt_regs *regs)
 {
-       struct sigframe *frame;
+       struct rt_sigframe *frame;
        int err = 0;
        int signal;
+       unsigned long sp, ra;
 
-       frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
-       if (regs->depc > 64)
-       {
-               printk("!!!!!!! DEPC !!!!!!!\n");
-               return;
-       }
-
-
-       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
-
-       signal = current_thread_info()->exec_domain
-               && current_thread_info()->exec_domain->signal_invmap
-               && sig < 32
-               ? current_thread_info()->exec_domain->signal_invmap[sig]
-               : sig;
-
-       err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
+       sp = regs->areg[1];
 
-       if (_NSIG_WORDS > 1) {
-               err |= __copy_to_user(frame->extramask, &set->sig[1],
-                                     sizeof(frame->extramask));
+       if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) {
+               sp = current->sas_ss_sp + current->sas_ss_size;
        }
 
-       /* Create sys_sigreturn syscall in stack frame */
-       err |= gen_return_code(frame->retcode, USE_SIGRETURN);
-
-       if (err)
-               goto give_sigsegv;
-
-       /* Create signal handler execution context.
-        * Return context not modified until this point.
-        */
-       set_thread_state(regs, frame, frame->retcode,
-               ka->sa.sa_handler, signal, &frame->sc, NULL);
-
-       /* Set access mode to USER_DS.  Nomenclature is outdated, but
-        * functionality is used in uaccess.h
-        */
-       set_fs(USER_DS);
-
-
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
-               current->comm, current->pid, signal, frame, regs->pc);
-#endif
-
-       return;
-
-give_sigsegv:
-       if (sig == SIGSEGV)
-               ka->sa.sa_handler = SIG_DFL;
-       force_sig(SIGSEGV, current);
-}
-
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
-{
-       struct rt_sigframe *frame;
-       int err = 0;
-       int signal;
+       frame = (void *)((sp - sizeof(*frame)) & -16ul);
 
-       frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
        if (regs->depc > 64)
                panic ("Double exception sys_sigreturn\n");
 
-       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
                goto give_sigsegv;
+       }
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -602,9 +347,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                ? current_thread_info()->exec_domain->signal_invmap[sig]
                : sig;
 
-       err |= copy_siginfo_to_user(&frame->info, info);
+       if (ka->sa.sa_flags & SA_SIGINFO) {
+               err |= copy_siginfo_to_user(&frame->info, info);
+       }
+
+       /* Create the user context.  */
 
-       /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
        err |= __put_user((void *)current->sas_ss_sp,
@@ -617,16 +365,31 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
        /* Create sys_rt_sigreturn syscall in stack frame */
-       err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
 
-       if (err)
+       err |= gen_return_code(frame->retcode);
+
+       if (err) {
                goto give_sigsegv;
+       }
+               
 
-       /* Create signal handler execution context.
+       /* 
+        * Create signal handler execution context.
         * Return context not modified until this point.
         */
-       set_thread_state(regs, frame, frame->retcode,
-               ka->sa.sa_handler, signal, &frame->info, &frame->uc);
+
+       /* Set up registers for signal handler */
+       start_thread(regs, (unsigned long) ka->sa.sa_handler, 
+                    (unsigned long) frame);
+
+       /* Set up a stack frame for a call4
+        * Note: PS.CALLINC is set to one by start_thread
+        */
+       ra = (unsigned long) frame->retcode;
+       regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
+       regs->areg[6] = (unsigned long) signal;
+       regs->areg[7] = (unsigned long) &frame->info;
+       regs->areg[8] = (unsigned long) &frame->uc;
 
        /* Set access mode to USER_DS.  Nomenclature is outdated, but
         * functionality is used in uaccess.h
@@ -646,6 +409,48 @@ give_sigsegv:
        force_sig(SIGSEGV, current);
 }
 
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset, 
+                                    size_t sigsetsize,
+                                    long a2, long a3, long a4, long a5, 
+                                    struct pt_regs *regs)
+{
+       sigset_t saveset, newset;
+
+       /* XXX: Don't preclude handling different sized sigset_t's.  */
+       if (sigsetsize != sizeof(sigset_t))
+               return -EINVAL;
+
+       if (copy_from_user(&newset, unewset, sizeof(newset)))
+               return -EFAULT;
+
+       sigdelsetmask(&newset, ~_BLOCKABLE);
+       spin_lock_irq(&current->sighand->siglock);
+       saveset = current->blocked;
+       current->blocked = newset;
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+
+       regs->areg[2] = -EINTR;
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+               if (do_signal(regs, &saveset))
+                       return -EINTR;
+       }
+}
+
+asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, 
+                                  stack_t __user *uoss,
+                                  long a2, long a3, long a4, long a5,
+                                  struct pt_regs *regs)
+{
+       return do_sigaltstack(uss, uoss, regs->areg[1]);
+}
+
 
 
 /*
@@ -663,51 +468,89 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        int signr;
        struct k_sigaction ka;
 
+       if (!user_mode(regs))
+               return 0;
+
+       if (try_to_freeze())
+               goto no_signal;
+
        if (!oldset)
                oldset = &current->blocked;
 
+       task_pt_regs(current)->icountlevel = 0;
+
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       /* Are we from a system call? */
-       if (regs->syscall >= 0) {
-               /* If so, check system call restarting.. */
-               switch (regs->areg[2]) {
-                       case ERESTARTNOHAND:
-                       case ERESTART_RESTARTBLOCK:
-                               regs->areg[2] = -EINTR;
-                               break;
+       if (signr > 0) {
+
+               /* Are we from a system call? */
+
+               if ((signed)regs->syscall >= 0) {
 
-                       case ERESTARTSYS:
-                               if (!(ka.sa.sa_flags & SA_RESTART)) {
+                       /* If so, check system call restarting.. */
+
+                       switch (regs->areg[2]) {
+                               case -ERESTARTNOHAND:
+                               case -ERESTART_RESTARTBLOCK:
                                        regs->areg[2] = -EINTR;
                                        break;
-                               }
-                       /* fallthrough */
-                       case ERESTARTNOINTR:
-                               regs->areg[2] = regs->syscall;
-                               regs->pc -= 3;
+
+                               case -ERESTARTSYS:
+                                       if (!(ka.sa.sa_flags & SA_RESTART)) {
+                                               regs->areg[2] = -EINTR;
+                                               break;
+                                       }
+                                       /* fallthrough */
+                               case -ERESTARTNOINTR:
+                                       regs->areg[2] = regs->syscall;
+                                       regs->pc -= 3;
+                                       break;
+
+                               default:
+                                       /* nothing to do */
+                                       if (regs->areg[2] != 0)
+                                       break;
+                       }
                }
-       }
 
-       if (signr == 0)
-               return 0;               /* no signals delivered */
+               /* Whee!  Actually deliver the signal.  */
+               /* Set up the stack frame */
+               setup_frame(signr, &ka, &info, oldset, regs);
 
-       /* Whee!  Actually deliver the signal.  */
+               if (ka.sa.sa_flags & SA_ONESHOT)
+                       ka.sa.sa_handler = SIG_DFL;
 
-       /* Set up the stack frame */
-       if (ka.sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame(signr, &ka, &info, oldset, regs);
-       else
-               setup_frame(signr, &ka, oldset, regs);
+               spin_lock_irq(&current->sighand->siglock);
+               sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
+               if (!(ka.sa.sa_flags & SA_NODEFER))
+                       sigaddset(&current->blocked, signr);
+               recalc_sigpending();
+               spin_unlock_irq(&current->sighand->siglock);
+               if (current->ptrace & PT_SINGLESTEP)
+                       task_pt_regs(current)->icountlevel = 1;
 
-       if (ka.sa.sa_flags & SA_ONESHOT)
-               ka.sa.sa_handler = SIG_DFL;
+               return 1;
+       }
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
-       if (!(ka.sa.sa_flags & SA_NODEFER))
-               sigaddset(&current->blocked, signr);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-       return 1;
+no_signal:
+       /* Did we come from a system call? */
+       if ((signed) regs->syscall >= 0) {
+               /* Restart the system call - no handlers present */
+               switch (regs->areg[2]) {
+               case -ERESTARTNOHAND:
+               case -ERESTARTSYS:
+               case -ERESTARTNOINTR:
+                       regs->areg[2] = regs->syscall;
+                       regs->pc -= 3;
+                       break;
+               case -ERESTART_RESTARTBLOCK:
+                       regs->areg[2] = __NR_restart_syscall;
+                       regs->pc -= 3;
+                       break;
+               }
+       }
+       if (current->ptrace & PT_SINGLESTEP)
+               task_pt_regs(current)->icountlevel = 1;
+       return 0;
 }
+
index 4b7b4ff7997349abfb994becb0fade83492ad28b..b0582c3c5f8da9dad2f43eb5b9d81ca9a14cbfb0 100644 (file)
@@ -84,9 +84,7 @@ SECTIONS
   {
     /* The .head.text section must be the first section! */
     *(.head.text)
-    *(.literal)
-    TEXT_TEXT
-    *(.srom.text)
+    *(.literal .text)
     VMLINUX_SYMBOL(__sched_text_start) = .;
     *(.sched.literal .sched.text)
     VMLINUX_SYMBOL(__sched_text_end) = .;
@@ -96,6 +94,7 @@ SECTIONS
 
   }
   _etext = .;
+  PROVIDE (etext = .);
 
   . = ALIGN(16);
 
@@ -103,32 +102,6 @@ SECTIONS
 
   /*  Relocation table */
 
-  . = ALIGN(16);
-  __boot_reloc_table_start = ABSOLUTE(.);
-
-  __relocate : {
-
-    RELOCATE_ENTRY(_WindowVectors_text,
-                  .WindowVectors.text);
-#if 0
-    RELOCATE_ENTRY(_KernelExceptionVector_literal,
-                  .KernelExceptionVector.literal);
-#endif
-    RELOCATE_ENTRY(_KernelExceptionVector_text,
-                  .KernelExceptionVector.text);
-#if 0
-    RELOCATE_ENTRY(_UserExceptionVector_literal,
-                  .UserExceptionVector.literal);
-#endif
-    RELOCATE_ENTRY(_UserExceptionVector_text,
-                  .UserExceptionVector.text);
-    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
-                  .DoubleExceptionVector.literal);
-    RELOCATE_ENTRY(_DoubleExceptionVector_text,
-                  .DoubleExceptionVector.text);
-  }
-  __boot_reloc_table_end = ABSOLUTE(.) ;
-
   .fixup   : { *(.fixup) }
 
   . = ALIGN(16);
@@ -145,8 +118,7 @@ SECTIONS
   _fdata = .;
   .data :
   {
-    DATA_DATA
-    CONSTRUCTORS
+    *(.data) CONSTRUCTORS
     . = ALIGN(XCHAL_ICACHE_LINESIZE);
     *(.data.cacheline_aligned)
   }
@@ -174,6 +146,22 @@ SECTIONS
     __tagtable_begin = .;
     *(.taglist)
     __tagtable_end = .;
+
+    . = ALIGN(16);
+    __boot_reloc_table_start = ABSOLUTE(.);
+
+    RELOCATE_ENTRY(_WindowVectors_text,
+                  .WindowVectors.text);
+    RELOCATE_ENTRY(_KernelExceptionVector_text,
+                  .KernelExceptionVector.text);
+    RELOCATE_ENTRY(_UserExceptionVector_text,
+                  .UserExceptionVector.text);
+    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
+                  .DoubleExceptionVector.literal);
+    RELOCATE_ENTRY(_DoubleExceptionVector_text,
+                  .DoubleExceptionVector.text);
+  
+    __boot_reloc_table_end = ABSOLUTE(.) ;
   }
 
   . = ALIGN(XCHAL_ICACHE_LINESIZE);
@@ -194,16 +182,6 @@ SECTIONS
 
   SECURITY_INIT
 
-  . = ALIGN(4);
-
-  __start___ftr_fixup = .;
-  __ftr_fixup : { *(__ftr_fixup) }
-  __stop___ftr_fixup = .;
-
-  . = ALIGN(4096);
-  __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
-  __per_cpu_end = .;
 
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(4096);
@@ -212,6 +190,12 @@ SECTIONS
   __initramfs_end = .;
 #endif
 
+  . = ALIGN(4096);
+  __per_cpu_start = .;
+  .data.percpu  : { *(.data.percpu) }
+  __per_cpu_end = .;
+
+
   /* We need this dummy segment here */
 
   . = ALIGN(4);
@@ -273,9 +257,9 @@ SECTIONS
 
   /* BSS section */
   _bss_start = .;
-  .sbss : { *(.sbss) *(.scommon) }
-  .bss : { *(COMMON) *(.bss) }
+  .bss : { *(.bss.page_aligned) *(.bss) }
   _bss_end = .;
+
   _end = .;
 
   /* only used by the boot loader  */
@@ -293,16 +277,16 @@ SECTIONS
     *(.ResetVector.text)
   }
 
-
   /* Sections to be discarded */
   /DISCARD/ :
   {
-        *(.text.exit)
-       *(.text.exit.literal)
-        *(.data.exit)
+       *(.exit.literal .exit.text)
+       *(.exit.data)
         *(.exitcall.exit)
   }
 
+  .xt.lit : { *(.xt.lit) }
+  .xt.prop : { *(.xt.prop) }
 
   .debug  0 :  { *(.debug) }
   .line  0 :  { *(.line) }
index cd7e6a0206024a835daf7aff2c545ef06f808be6..60dbdb43fb4c92d27e12f15cba95d8195601721f 100644 (file)
 /*
  * String functions
  */
-EXPORT_SYMBOL(memcmp);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memchr);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
 
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
 
 /*
index a834057bda6b45040a6182705e9610fb1448377e..b2655d94558d8db837e248d09856c3246cfa78e5 100644 (file)
 /*
  * char *__strncpy_user(char *dst, const char *src, size_t len)
  */
-.text
-.begin literal
-.align 4
-.Lmask0:
-       .byte   0xff, 0x00, 0x00, 0x00
-.Lmask1:
-       .byte   0x00, 0xff, 0x00, 0x00
-.Lmask2:
-       .byte   0x00, 0x00, 0xff, 0x00
-.Lmask3:
-       .byte   0x00, 0x00, 0x00, 0xff
-.end literal
+
+#ifdef __XTENSA_EB__
+# define MASK0 0xff000000
+# define MASK1 0x00ff0000
+# define MASK2 0x0000ff00
+# define MASK3 0x000000ff
+#else
+# define MASK0 0x000000ff
+# define MASK1 0x0000ff00
+# define MASK2 0x00ff0000
+# define MASK3 0xff000000
+#endif
 
 # Register use
 #   a0/ return address
@@ -53,6 +53,7 @@
 #   a11/ dst
 #   a12/ tmp
 
+.text
 .align 4
 .global        __strncpy_user
 .type  __strncpy_user,@function
@@ -61,10 +62,10 @@ __strncpy_user:
        # a2/ dst, a3/ src, a4/ len
        mov     a11, a2         # leave dst in return value register
        beqz    a4, .Lret       # if len is zero
-       l32r    a5, .Lmask0     # mask for byte 0
-       l32r    a6, .Lmask1     # mask for byte 1
-       l32r    a7, .Lmask2     # mask for byte 2
-       l32r    a8, .Lmask3     # mask for byte 3
+       movi    a5, MASK0       # mask for byte 0
+       movi    a6, MASK1       # mask for byte 1
+       movi    a7, MASK2       # mask for byte 2
+       movi    a8, MASK3       # mask for byte 3
        bbsi.l  a3, 0, .Lsrc1mod2 # if only  8-bit aligned
        bbsi.l  a3, 1, .Lsrc2mod4 # if only 16-bit aligned
 .Lsrcaligned:  # return here when src is word-aligned
index 5e9c1e709b2eaf33d32d883a4681453398027313..ad3f616322caaa31bd54c9a56f87b892d5e0726d 100644 (file)
 /*
  * size_t __strnlen_user(const char *s, size_t len)
  */
-.text
-.begin literal
-.align 4
-.Lmask0:
-       .byte   0xff, 0x00, 0x00, 0x00
-.Lmask1:
-       .byte   0x00, 0xff, 0x00, 0x00
-.Lmask2:
-       .byte   0x00, 0x00, 0xff, 0x00
-.Lmask3:
-       .byte   0x00, 0x00, 0x00, 0xff
-.end literal
+
+#ifdef __XTENSA_EB__
+# define MASK0 0xff000000
+# define MASK1 0x00ff0000
+# define MASK2 0x0000ff00
+# define MASK3 0x000000ff
+#else
+# define MASK0 0x000000ff
+# define MASK1 0x0000ff00
+# define MASK2 0x00ff0000
+# define MASK3 0xff000000
+#endif
 
 # Register use:
 #   a2/ src
@@ -48,6 +48,7 @@
 #   a9/ tmp
 #   a10/ tmp
 
+.text
 .align 4
 .global        __strnlen_user
 .type  __strnlen_user,@function
@@ -56,10 +57,10 @@ __strnlen_user:
        # a2/ s, a3/ len
        addi    a4, a2, -4      # because we overincrement at the end;
                                # we compensate with load offsets of 4
-       l32r    a5, .Lmask0     # mask for byte 0
-       l32r    a6, .Lmask1     # mask for byte 1
-       l32r    a7, .Lmask2     # mask for byte 2
-       l32r    a8, .Lmask3     # mask for byte 3
+       movi    a5, MASK0       # mask for byte 0
+       movi    a6, MASK1       # mask for byte 1
+       movi    a7, MASK2       # mask for byte 2
+       movi    a8, MASK3       # mask for byte 3
        bbsi.l  a2, 0, .L1mod2  # if only  8-bit aligned
        bbsi.l  a2, 1, .L2mod4  # if only 16-bit aligned
 
index e1ec2d1e8189e64c998ba8dba7d9b3a9d30d5cc1..8415c76f11c2a75ea69f080ec334a46a22ba715e 100644 (file)
@@ -205,7 +205,7 @@ void __init init_mmu (void)
        /* Writing zeros to the <t>TLBCFG special registers ensure
         * that valid values exist in the register.  For existing
         * PGSZID<w> fields, zero selects the first element of the
-        * page-size array.  For nonexistant PGSZID<w> fields, zero is
+        * page-size array.  For nonexistent PGSZID<w> fields, zero is
         * the best value to write.  Also, when changing PGSZID<w>
         * fields, the corresponding TLB must be flushed.
         */
index 4bfe333be22943558a8448679b71f4bcd2b273e8..f09962fa98c09a5594358d22c23b0b7d993209f0 100644 (file)
@@ -473,7 +473,7 @@ static int iss_net_open(struct net_device *dev)
        netif_start_queue(dev);
 
        /* clear buffer - it can happen that the host side of the interface
-        * is full when we gethere. In this case, new data is never queued,
+        * is full when we get here. In this case, new data is never queued,
         * SIGIOs never arrive, and the net never works.
         */
        while ((err = iss_net_rx(dev)) > 0)
index 93a2cf654597c25502da7fb128745c11c01581c9..863a8c0623ed824e27d85f32a52cf10ea39d1c02 100644 (file)
@@ -423,7 +423,10 @@ static ssize_t disk_size_read(struct gendisk * disk, char *page)
 {
        return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
 }
-
+static ssize_t disk_capability_read(struct gendisk *disk, char *page)
+{
+       return sprintf(page, "%x\n", disk->flags);
+}
 static ssize_t disk_stats_read(struct gendisk * disk, char *page)
 {
        preempt_disable();
@@ -466,6 +469,10 @@ static struct disk_attribute disk_attr_size = {
        .attr = {.name = "size", .mode = S_IRUGO },
        .show   = disk_size_read
 };
+static struct disk_attribute disk_attr_capability = {
+       .attr = {.name = "capability", .mode = S_IRUGO },
+       .show   = disk_capability_read
+};
 static struct disk_attribute disk_attr_stat = {
        .attr = {.name = "stat", .mode = S_IRUGO },
        .show   = disk_stats_read
@@ -506,6 +513,7 @@ static struct attribute * default_attrs[] = {
        &disk_attr_removable.attr,
        &disk_attr_size.attr,
        &disk_attr_stat.attr,
+       &disk_attr_capability.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &disk_attr_fail.attr,
 #endif
@@ -688,6 +696,27 @@ struct seq_operations diskstats_op = {
        .show   = diskstats_show
 };
 
+static void media_change_notify_thread(struct work_struct *work)
+{
+       struct gendisk *gd = container_of(work, struct gendisk, async_notify);
+       char event[] = "MEDIA_CHANGE=1";
+       char *envp[] = { event, NULL };
+
+       /*
+        * set enviroment vars to indicate which event this is for
+        * so that user space will know to go check the media status.
+        */
+       kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
+       put_device(gd->driverfs_dev);
+}
+
+void genhd_media_change_notify(struct gendisk *disk)
+{
+       get_device(disk->driverfs_dev);
+       schedule_work(&disk->async_notify);
+}
+EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+
 struct gendisk *alloc_disk(int minors)
 {
        return alloc_disk_node(minors, -1);
@@ -717,6 +746,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
                kobj_set_kset_s(disk,block_subsys);
                kobject_init(&disk->kobj);
                rand_initialize_disk(disk);
+               INIT_WORK(&disk->async_notify,
+                       media_change_notify_thread);
        }
        return disk;
 }
index 3ff4e1f0f0328d9acb023628e4233b0b1acd607e..ac6dce2e7596c4518287bdc355c088eb1a1e5a37 100644 (file)
@@ -298,7 +298,7 @@ static inline int cryptd_create_thread(struct cryptd_state *state,
        mutex_init(&state->mutex);
        crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN);
 
-       state->task = kthread_create(fn, state, name);
+       state->task = kthread_run(fn, state, name);
        if (IS_ERR(state->task))
                return PTR_ERR(state->task);
 
@@ -316,6 +316,8 @@ static int cryptd_thread(void *data)
        struct cryptd_state *state = data;
        int stop;
 
+       current->flags |= PF_NOFREEZE;
+
        do {
                struct crypto_async_request *req, *backlog;
 
index b770deab968c492322eaee25c2cbd84f0c4b92fb..6d7d4157e049f6d624069900de980629ae3ea866 100644 (file)
@@ -1357,7 +1357,7 @@ static struct backlight_ops asus_backlight_data = {
         .update_status  = set_brightness_status,
 };
 
-static void __exit asus_acpi_exit(void)
+static void asus_acpi_exit(void)
 {
        if (asus_backlight_device)
                backlight_device_unregister(asus_backlight_device);
index a2efae8a4c4eec093bcfda836e96b49e97f2251e..0c9f15c54e8c6265d3eaec4ea14f0b4e7991cc52 100644 (file)
@@ -59,7 +59,7 @@ int node_to_pxm(int node)
        return node_to_pxm_map[node];
 }
 
-int __cpuinit acpi_map_pxm_to_node(int pxm)
+int acpi_map_pxm_to_node(int pxm)
 {
        int node = pxm_to_node_map[pxm];
 
index b998340e23d4126074a36cc1af38d05461b4bde9..58ceb18ec997f7c16b62c1bba6035411a61450ab 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/workqueue.h>
 #include <linux/nmi.h>
 #include <linux/acpi.h>
@@ -73,6 +74,21 @@ static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
 static struct workqueue_struct *kacpi_notify_wq;
 
+#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
+static char osi_additional_string[OSI_STRING_LENGTH_MAX];
+
+#define OSI_LINUX_ENABLED
+#ifdef OSI_LINUX_ENABLED
+int osi_linux = 1;     /* enable _OSI(Linux) by default */
+#else
+int osi_linux;         /* disable _OSI(Linux) by default */
+#endif
+
+
+#ifdef CONFIG_DMI
+static struct __initdata dmi_system_id acpi_osl_dmi_table[];
+#endif
+
 static void __init acpi_request_region (struct acpi_generic_address *addr,
        unsigned int length, char *desc)
 {
@@ -121,8 +137,9 @@ static int __init acpi_reserve_resources(void)
 }
 device_initcall(acpi_reserve_resources);
 
-acpi_status acpi_os_initialize(void)
+acpi_status __init acpi_os_initialize(void)
 {
+       dmi_check_system(acpi_osl_dmi_table);
        return AE_OK;
 }
 
@@ -960,20 +977,38 @@ static int __init acpi_os_name_setup(char *str)
 
 __setup("acpi_os_name=", acpi_os_name_setup);
 
+static void enable_osi_linux(int enable) {
+
+       if (osi_linux != enable)
+               printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
+                       enable ? "En": "Dis");
+
+       osi_linux = enable;
+       return;
+}
+
 /*
- * _OSI control
+ * Modify the list of "OS Interfaces" reported to BIOS via _OSI
+ *
  * empty string disables _OSI
- * TBD additional string adds to _OSI
+ * string starting with '!' disables that string
+ * otherwise string is added to list, augmenting built-in strings
  */
 static int __init acpi_osi_setup(char *str)
 {
        if (str == NULL || *str == '\0') {
                printk(KERN_INFO PREFIX "_OSI method disabled\n");
                acpi_gbl_create_osi_method = FALSE;
-       } else {
-               /* TBD */
-               printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n",
-                      str);
+       } else if (*str == '!') {
+               if (acpi_osi_invalidate(++str) == AE_OK)
+                       printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+       } else if (!strcmp("!Linux", str)) {
+               enable_osi_linux(0);
+       } else if (!strcmp("Linux", str)) {
+               enable_osi_linux(1);
+       } else if (*osi_additional_string == '\0') {
+               strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
+               printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
        }
 
        return 1;
@@ -1143,11 +1178,28 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
 acpi_status
 acpi_os_validate_interface (char *interface)
 {
-
-    return AE_SUPPORT;
+       if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
+               return AE_OK;
+       if (!strcmp("Linux", interface)) {
+               printk(KERN_WARNING PREFIX
+                       "System BIOS is requesting _OSI(Linux)\n");
+#ifdef OSI_LINUX_ENABLED
+               printk(KERN_WARNING PREFIX
+                       "Please test with \"acpi_osi=!Linux\"\n"
+                       "Please send dmidecode "
+                       "to linux-acpi@vger.kernel.org\n");
+#else
+               printk(KERN_WARNING PREFIX
+                       "If \"acpi_osi=Linux\" works better,\n"
+                       "Please send dmidecode "
+                       "to linux-acpi@vger.kernel.org\n");
+#endif
+               if(osi_linux)
+                       return AE_OK;
+       }
+       return AE_SUPPORT;
 }
 
-
 /******************************************************************************
  *
  * FUNCTION:    acpi_os_validate_address
@@ -1174,5 +1226,51 @@ acpi_os_validate_address (
     return AE_OK;
 }
 
+#ifdef CONFIG_DMI
+#ifdef OSI_LINUX_ENABLED
+static int dmi_osi_not_linux(struct dmi_system_id *d)
+{
+       printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
+       enable_osi_linux(0);
+       return 0;
+}
+#else
+static int dmi_osi_linux(struct dmi_system_id *d)
+{
+       printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident);
+       enable_osi_linux(1);
+       return 0;
+}
+#endif
+
+static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
+#ifdef OSI_LINUX_ENABLED
+       /*
+        * Boxes that need NOT _OSI(Linux)
+        */
+       {
+        .callback = dmi_osi_not_linux,
+        .ident = "Toshiba Satellite P100",
+        .matches = {
+                    DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
+                    DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
+                    },
+        },
+#else
+       /*
+        * Boxes that need _OSI(Linux)
+        */
+       {
+        .callback = dmi_osi_linux,
+        .ident = "Intel Napa CRB",
+        .matches = {
+                    DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                    DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
+                    },
+        },
+#endif
+       {}
+};
+#endif /* CONFIG_DMI */
 
 #endif
index 0e7b121a99ce6b163961a61d16b8952d143ca497..3bc0c67a9283e395943ee0e42c5db83b3c43f134 100644 (file)
@@ -123,14 +123,14 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
                }
        }
 
-       /* The table must be either an SSDT or a PSDT */
+       /* The table must be either an SSDT or a PSDT or an OEMx */
 
        if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
            &&
-           (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
-       {
+           (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
+           && (strncmp(table_desc->pointer->signature, "OEM", 3))) {
                ACPI_ERROR((AE_INFO,
-                           "Table has invalid signature [%4.4s], must be SSDT or PSDT",
+                           "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx",
                            table_desc->pointer->signature));
                return_ACPI_STATUS(AE_BAD_SIGNATURE);
        }
index 1ada017d01efb8c8d03630b7c87bd7b01565fd5b..194ecfe8b3600d6195a491eae99483546f1a3abe 100644 (file)
@@ -827,6 +827,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_thermal *tz = seq->private;
+       struct acpi_device *device;
        int i = 0;
        int j = 0;
 
@@ -849,9 +850,8 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
                           tz->trips.passive.tc1, tz->trips.passive.tc2,
                           tz->trips.passive.tsp);
                for (j = 0; j < tz->trips.passive.devices.count; j++) {
-
-                       seq_printf(seq, "0x%p ",
-                                  tz->trips.passive.devices.handles[j]);
+                       acpi_bus_get_device(tz->trips.passive.devices.handles[j], &device);
+                       seq_printf(seq, "%4.4s ", acpi_device_bid(device));
                }
                seq_puts(seq, "\n");
        }
@@ -862,9 +862,10 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
                seq_printf(seq, "active[%d]:               %ld C: devices=",
                           i,
                           KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
-               for (j = 0; j < tz->trips.active[i].devices.count; j++)
-                       seq_printf(seq, "0x%p ",
-                                  tz->trips.active[i].devices.handles[j]);
+               for (j = 0; j < tz->trips.active[i].devices.count; j++){
+                       acpi_bus_get_device(tz->trips.active[i].devices.handles[j], &device);
+                       seq_printf(seq, "%4.4s ", acpi_device_bid(device));
+               }
                seq_puts(seq, "\n");
        }
 
index 3906d47b9783521683bcf001ad5ead9b29639c30..1cfbecb0ac10463fa5dfe0afb8741cfc384d2cae 100644 (file)
@@ -538,7 +538,7 @@ static struct backlight_ops toshiba_backlight_data = {
         .update_status  = set_lcd_status,
 };
 
-static void __exit toshiba_acpi_exit(void)
+static void toshiba_acpi_exit(void)
 {
        if (toshiba_backlight_device)
                backlight_device_unregister(toshiba_backlight_device);
index 4c1e00874dffab04407ddaf8975e7700d72dc5c5..879eaa10d3ae77cf92777f4198dc60eb1b4c7058 100644 (file)
@@ -67,6 +67,10 @@ static acpi_status
 acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
                                union acpi_operand_object **return_obj);
 
+static acpi_status
+acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
+                                 union acpi_operand_object **internal_object);
+
 static acpi_status
 acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
                           union acpi_operand_object *dest_desc);
@@ -518,77 +522,73 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
        return_ACPI_STATUS(AE_NO_MEMORY);
 }
 
-#ifdef ACPI_FUTURE_IMPLEMENTATION
-/* Code to convert packages that are parameters to control methods */
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
  *
- * PARAMETERS:  *internal_object   - Pointer to the object we are returning
- *              *Buffer            - Where the object is returned
- *              *space_used        - Where the length of the object is returned
+ * PARAMETERS:  external_object     - The external object to be converted
+ *              internal_object     - Where the internal object is returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to place a package object in a user
- *              buffer.  A package object by definition contains other objects.
- *
- *              The buffer is assumed to have sufficient space for the object.
- *              The caller must have verified the buffer length needed using the
- *              acpi_ut_get_object_size function before calling this function.
+ * DESCRIPTION: Copy an external package object to an internal package.
+ *              Handles nested packages.
  *
  ******************************************************************************/
 
 static acpi_status
-acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object,
-                                 u8 * buffer, u32 * space_used)
+acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
+                                 union acpi_operand_object **internal_object)
 {
-       u8 *free_space;
-       union acpi_object *external_object;
-       u32 length = 0;
-       u32 this_index;
-       u32 object_space = 0;
-       union acpi_operand_object *this_internal_obj;
-       union acpi_object *this_external_obj;
+       acpi_status status = AE_OK;
+       union acpi_operand_object *package_object;
+       union acpi_operand_object **package_elements;
+       acpi_native_uint i;
 
        ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
 
-       /*
-        * First package at head of the buffer
-        */
-       external_object = (union acpi_object *)buffer;
+       /* Create the package object */
 
-       /*
-        * Free space begins right after the first package
-        */
-       free_space = buffer + sizeof(union acpi_object);
+       package_object =
+           acpi_ut_create_package_object(external_object->package.count);
+       if (!package_object) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
+       }
 
-       external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
-       external_object->package.count = internal_object->package.count;
-       external_object->package.elements = (union acpi_object *)free_space;
+       package_elements = package_object->package.elements;
 
        /*
-        * Build an array of ACPI_OBJECTS in the buffer
-        * and move the free space past it
+        * Recursive implementation. Probably ok, since nested external packages
+        * as parameters should be very rare.
         */
-       free_space +=
-           external_object->package.count * sizeof(union acpi_object);
+       for (i = 0; i < external_object->package.count; i++) {
+               status =
+                   acpi_ut_copy_eobject_to_iobject(&external_object->package.
+                                                   elements[i],
+                                                   &package_elements[i]);
+               if (ACPI_FAILURE(status)) {
 
-       /* Call walk_package */
+                       /* Truncate package and delete it */
 
-}
+                       package_object->package.count = i;
+                       package_elements[i] = NULL;
+                       acpi_ut_remove_reference(package_object);
+                       return_ACPI_STATUS(status);
+               }
+       }
 
-#endif                         /* Future implementation */
+       *internal_object = package_object;
+       return_ACPI_STATUS(status);
+}
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_copy_eobject_to_iobject
  *
- * PARAMETERS:  *internal_object   - The external object to be converted
- *              *buffer_ptr     - Where the internal object is returned
+ * PARAMETERS:  external_object     - The external object to be converted
+ *              internal_object     - Where the internal object is returned
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status              - the status of the call
  *
  * DESCRIPTION: Converts an external object to an internal object.
  *
@@ -603,16 +603,10 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
        ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
 
        if (external_object->type == ACPI_TYPE_PACKAGE) {
-               /*
-                * Packages as external input to control methods are not supported,
-                */
-               ACPI_ERROR((AE_INFO,
-                           "Packages as parameters not implemented!"));
-
-               return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
-       }
-
-       else {
+               status =
+                   acpi_ut_copy_epackage_to_ipackage(external_object,
+                                                     internal_object);
+       } else {
                /*
                 * Build a simple object (no nested objects)
                 */
@@ -803,33 +797,19 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
                 * Create and build the package object
                 */
                target_object =
-                   acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
+                   acpi_ut_create_package_object(source_object->package.count);
                if (!target_object) {
                        return (AE_NO_MEMORY);
                }
 
-               target_object->package.count = source_object->package.count;
                target_object->common.flags = source_object->common.flags;
 
-               /*
-                * Create the object array
-                */
-               target_object->package.elements =
-                   ACPI_ALLOCATE_ZEROED(((acpi_size) source_object->package.
-                                         count + 1) * sizeof(void *));
-               if (!target_object->package.elements) {
-                       status = AE_NO_MEMORY;
-                       goto error_exit;
-               }
+               /* Pass the new package object back to the package walk routine */
 
-               /*
-                * Pass the new package object back to the package walk routine
-                */
                state->pkg.this_target_obj = target_object;
 
-               /*
-                * Store the object pointer in the parent package object
-                */
+               /* Store the object pointer in the parent package object */
+
                *this_target_ptr = target_object;
                break;
 
index 13d5879cd98b92148acb215ac411a8280b862090..8ec6f8e481385d2908f286249903d44db35cf184 100644 (file)
@@ -59,10 +59,9 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
 /*
  * Strings supported by the _OSI predefined (internal) method.
  */
-static const char *acpi_interfaces_supported[] = {
+static char *acpi_interfaces_supported[] = {
        /* Operating System Vendor Strings */
 
-       "Linux",
        "Windows 2000",
        "Windows 2001",
        "Windows 2001 SP0",
@@ -156,6 +155,31 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
        return_ACPI_STATUS(AE_CTRL_TERMINATE);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_osi_invalidate
+ *
+ * PARAMETERS:  interface_string
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: invalidate string in pre-defiend _OSI string list
+ *
+ ******************************************************************************/
+
+acpi_status acpi_osi_invalidate(char *interface)
+{
+       int i;
+
+       for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
+               if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
+                       *acpi_interfaces_supported[i] = '\0';
+                       return AE_OK;
+               }
+       }
+       return AE_NOT_FOUND;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_evaluate_object
index 4696124759e1546b16cde08d99d15bcc4515abb2..db0b9bac7945f7bd55b55a0561b37104630ca23b 100644 (file)
@@ -144,6 +144,48 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
        return_PTR(object);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_package_object
+ *
+ * PARAMETERS:  Count               - Number of package elements
+ *
+ * RETURN:      Pointer to a new Package object, null on failure
+ *
+ * DESCRIPTION: Create a fully initialized package object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *acpi_ut_create_package_object(u32 count)
+{
+       union acpi_operand_object *package_desc;
+       union acpi_operand_object **package_elements;
+
+       ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
+
+       /* Create a new Package object */
+
+       package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
+       if (!package_desc) {
+               return_PTR(NULL);
+       }
+
+       /*
+        * Create the element array. Count+1 allows the array to be null
+        * terminated.
+        */
+       package_elements = ACPI_ALLOCATE_ZEROED((acpi_size)
+                                               (count + 1) * sizeof(void *));
+       if (!package_elements) {
+               ACPI_FREE(package_desc);
+               return_PTR(NULL);
+       }
+
+       package_desc->package.count = count;
+       package_desc->package.elements = package_elements;
+       return_PTR(package_desc);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_create_buffer_object
index e9a57806cd34ecc32c1ab9d9881efabbeb96bfbc..2d496918b3cda4593d383b36cce08f18e2535253 100644 (file)
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("utxface")
  *              called, so any early initialization belongs here.
  *
  ******************************************************************************/
-acpi_status acpi_initialize_subsystem(void)
+acpi_status __init acpi_initialize_subsystem(void)
 {
        acpi_status status;
 
@@ -108,8 +108,6 @@ acpi_status acpi_initialize_subsystem(void)
        return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_enable_subsystem
index 7baeaffefe7aeb1b1f501c28d190ae068a98dd68..545f330e59a54bd5c6aebfca56a798d8cdd8a431 100644 (file)
@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },            /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },            /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },            /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci },            /* MCP73 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci },            /* MCP77 */
+       { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci },            /* MCP77 */
 
        /* SiS */
        { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
index 0458811010fda00d047f3d414e5ea5b5cc03d36a..9c07b88631be6d50635d292d67fa632996c57e4f 100644 (file)
@@ -578,6 +578,7 @@ static const struct ich_laptop ich_laptop[] = {
        { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
        { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
        { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
+       { 0x24CA, 0x1025, 0x0061 },     /* ICH4 on ACER Aspire 2023WLMi */
        /* end marker */
        { 0, }
 };
index a6de57e020473293c2a043ebdcefc4ab01a6a5bd..047eabd75363a110d56e88edd54d899624ab0c6b 100644 (file)
@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 
        /* sanity check */
        rc = -EINVAL;
-       reason = "device reports illegal type";
+       reason = "device reports invalid type";
 
        if (class == ATA_DEV_ATA) {
                if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
        if (ata_msg_probe(ap))
                ata_dump_id(id);
 
+       /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+       ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+                       sizeof(fwrevbuf));
+
+       ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+                       sizeof(modelbuf));
+
        /* ATA-specific feature tests */
        if (dev->class == ATA_DEV_ATA) {
                if (ata_id_is_cfa(id)) {
@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)
 
                dev->n_sectors = ata_id_n_sectors(id);
 
-               /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
-               ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
-                               sizeof(fwrevbuf));
-
-               ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
-                               sizeof(modelbuf));
-
                if (dev->id[59] & 0x100)
                        dev->multi_count = dev->id[59] & 0xff;
 
@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
 
                /* print device info to dmesg */
                if (ata_msg_drv(ap) && print_info)
-                       ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
+                       ata_dev_printk(dev, KERN_INFO,
+                                      "ATAPI: %s, %s, max %s%s\n",
+                                      modelbuf, fwrevbuf,
                                       ata_mode_string(xfer_mask),
                                       cdb_intr_string);
        }
@@ -3022,7 +3024,7 @@ int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
 
                if (!(status & ATA_BUSY))
                        return 0;
-               if (status == 0xff)
+               if (!ata_port_online(ap) && status == 0xff)
                        return -ENODEV;
                if (time_after(now, deadline))
                        return -EBUSY;
@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
                }
        }
 
-       /* if device 1 was found in ata_devchk, wait for
-        * register access, then wait for BSY to clear
+       /* if device 1 was found in ata_devchk, wait for register
+        * access briefly, then wait for BSY to clear.
         */
-       while (dev1) {
-               u8 nsect, lbal;
+       if (dev1) {
+               int i;
 
                ap->ops->dev_select(ap, 1);
-               nsect = ioread8(ioaddr->nsect_addr);
-               lbal = ioread8(ioaddr->lbal_addr);
-               if ((nsect == 1) && (lbal == 1))
-                       break;
-               if (time_after(jiffies, deadline))
-                       return -EBUSY;
-               msleep(50);     /* give drive a breather */
-       }
-       if (dev1) {
+
+               /* Wait for register access.  Some ATAPI devices fail
+                * to set nsect/lbal after reset, so don't waste too
+                * much time on it.  We're gonna wait for !BSY anyway.
+                */
+               for (i = 0; i < 2; i++) {
+                       u8 nsect, lbal;
+
+                       nsect = ioread8(ioaddr->nsect_addr);
+                       lbal = ioread8(ioaddr->lbal_addr);
+                       if ((nsect == 1) && (lbal == 1))
+                               break;
+                       msleep(50);     /* give drive a breather */
+               }
+
                rc = ata_wait_ready(ap, deadline);
                if (rc) {
                        if (rc != -ENODEV)
@@ -3368,7 +3376,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
         */
        if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) {
                rc = ata_wait_ready(ap, deadline);
-               if (rc) {
+               if (rc && rc != -ENODEV) {
                        ata_port_printk(ap, KERN_WARNING, "device not ready "
                                        "(errno=%d), forcing hardreset\n", rc);
                        ehc->i.action |= ATA_EH_HARDRESET;
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
        { "SAMSUNG CD-ROM SN-124","N001",       ATA_HORKAGE_NODMA },
        { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
+       { "IOMEGA  ZIP 250       ATAPI", NULL,  ATA_HORKAGE_NODMA }, /* temporary fix */
 
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 |
@@ -3783,6 +3792,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "FUJITSU MHT2060BH",  NULL,           ATA_HORKAGE_NONCQ },
        /* NCQ is broken */
        { "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+       { "Maxtor 6B200M0",     "BANC1B10",     ATA_HORKAGE_NONCQ },
        /* NCQ hard hangs device under heavier load, needs hard power cycle */
        { "Maxtor 6B250S0",     "BANC1B70",     ATA_HORKAGE_NONCQ },
        /* Blacklist entries taken from Silicon Image 3124/3132
@@ -3790,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
        { "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
        { "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
+       /* Drives which do spurious command completion */
+       { "HTS541680J9SA00",    "SB2IC7EP",     ATA_HORKAGE_NONCQ, },
 
        /* Devices with NCQ limits */
 
@@ -3932,10 +3944,13 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
        /* set up set-features taskfile */
        DPRINTK("set features - xfer mode\n");
 
+       /* Some controllers and ATAPI devices show flaky interrupt
+        * behavior after setting xfer mode.  Use polling instead.
+        */
        ata_tf_init(dev, &tf);
        tf.command = ATA_CMD_SET_FEATURES;
        tf.feature = SETFEATURES_XFER;
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING;
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = dev->xfer_mode;
 
@@ -5413,14 +5428,6 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
                }
        }
 
-       /* Some controllers show flaky interrupt behavior after
-        * setting xfer mode.  Use polling instead.
-        */
-       if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
-                    qc->tf.feature == SETFEATURES_XFER) &&
-           (ap->flags & ATA_FLAG_SETXFER_POLLING))
-               qc->tf.flags |= ATA_TFLAG_POLLING;
-
        /* select the device */
        ata_dev_select(ap, qc->dev->devno, 1, 0);
 
@@ -6317,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                /* init sata_spd_limit to the current value */
                if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
                        int spd = (scontrol >> 4) & 0xf;
-                       ap->hw_sata_spd_limit &= (1 << spd) - 1;
+                       if (spd)
+                               ap->hw_sata_spd_limit &= (1 << spd) - 1;
                }
                ap->sata_spd_limit = ap->hw_sata_spd_limit;
 
@@ -6437,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
        if (rc)
                devm_free_irq(host->dev, irq, host);
 
+       /* Used to print device info at probe */
+       host->irq = irq;
+
        return rc;
 }
 
@@ -6822,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_data_xfer);
index 242c43eef80773a29e08ab9b18587a7c9376e366..c228df298bd898ae6e1379d31dc6d6c9dc41eb1a 100644 (file)
@@ -1050,14 +1050,15 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
 static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
 {
        u64 lba = 0;
-       u32 len = 0;
+       u32 len;
 
        VPRINTK("six-byte command\n");
 
+       lba |= ((u64)(cdb[1] & 0x1f)) << 16;
        lba |= ((u64)cdb[2]) << 8;
        lba |= ((u64)cdb[3]);
 
-       len |= ((u32)cdb[4]);
+       len = cdb[4];
 
        *plba = lba;
        *plen = len;
@@ -1362,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
         * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
         * cache
         */
-       if (ap->ops->error_handler &&
-           !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
-           ((qc->tf.feature == SETFEATURES_WC_ON) ||
-            (qc->tf.feature == SETFEATURES_WC_OFF))) {
-               ap->eh_info.action |= ATA_EH_REVALIDATE;
-               ata_port_schedule_eh(ap);
+       if (ap->ops->error_handler && !need_sense) {
+               switch (qc->tf.command) {
+               case ATA_CMD_SET_FEATURES:
+                       if ((qc->tf.feature == SETFEATURES_WC_ON) ||
+                           (qc->tf.feature == SETFEATURES_WC_OFF)) {
+                               ap->eh_info.action |= ATA_EH_REVALIDATE;
+                               ata_port_schedule_eh(ap);
+                       }
+                       break;
+
+               case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
+               case ATA_CMD_SET_MULTI: /* multi_count changed */
+                       ap->eh_info.action |= ATA_EH_REVALIDATE;
+                       ata_port_schedule_eh(ap);
+                       break;
+               }
        }
 
        /* For ATA pass thru (SAT) commands, generate a sense block if
@@ -2505,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
                        return ATA_PROT_NODATA;
 
                case 6:         /* DMA */
+               case 10:        /* UDMA Data-in */
+               case 11:        /* UDMA Data-Out */
                        return ATA_PROT_DMA;
 
                case 4:         /* PIO Data-in */
                case 5:         /* PIO Data-out */
                        return ATA_PROT_PIO;
 
-               case 10:        /* Device Reset */
                case 0:         /* Hard Reset */
                case 1:         /* SRST */
-               case 2:         /* Bus Idle */
-               case 7:         /* Packet */
-               case 8:         /* DMA Queued */
-               case 9:         /* Device Diagnostic */
-               case 11:        /* UDMA Data-in */
-               case 12:        /* UDMA Data-Out */
-               case 13:        /* FPDMA */
+               case 8:         /* Device Diagnostic */
+               case 9:         /* Device Reset */
+               case 7:         /* DMA Queued */
+               case 12:        /* FPDMA */
+               case 15:        /* Return Response Info */
                default:        /* Reserved */
                        break;
        }
@@ -2551,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
        if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
                goto invalid_fld;
 
-       if (cdb[1] & 0xe0)
-               /* PIO multi not supported yet */
-               goto invalid_fld;
-
        /*
         * 12 and 16 byte CDBs use different offsets to
         * provide the various register values.
@@ -2599,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                tf->device = cdb[8];
                tf->command = cdb[9];
        }
-       /*
-        * If slave is possible, enforce correct master/slave bit
-       */
-       if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
-               tf->device = qc->dev->devno ?
-                       tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+       /* enforce correct master/slave bit */
+       tf->device = dev->devno ?
+               tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+       /* sanity check for pio multi commands */
+       if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
+               goto invalid_fld;
+
+       if (is_multi_taskfile(tf)) {
+               unsigned int multi_count = 1 << (cdb[1] >> 5);
+
+               /* compare the passed through multi_count
+                * with the cached multi_count of libata
+                */
+               if (multi_count != dev->multi_count)
+                       ata_dev_printk(dev, KERN_WARNING,
+                                      "invalid multi_count %u ignored\n",
+                                      multi_count);
+       }       
 
        /* READ/WRITE LONG use a non-standard sect_size */
        qc->sect_size = ATA_SECT_SIZE;
index e35d13466c69092c68e822f4cb150b6f492cefab..ce84805ba5f14e80093efa1056ddd3a18de36f20 100644 (file)
@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap)   { return 0; }
 u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 {
        unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-       u8 host_stat, post_stat, status;
+       u8 host_stat = 0, post_stat = 0, status;
 
        status = ata_busy_wait(ap, bits, 1000);
        if (status & bits)
                if (ata_msg_err(ap))
                        printk(KERN_ERR "abnormal status 0x%X\n", status);
 
-       /* get controller status; clear intr, err bits */
-       host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-       iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
-                ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
-       post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+       if (ap->ioaddr.bmdma_addr) {
+               /* get controller status; clear intr, err bits */
+               host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+               iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+                        ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
 
+               post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+       }
        if (ata_msg_intr(ap))
                printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
                        __FUNCTION__,
                        host_stat, post_stat, status);
-
        return status;
 }
 
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
                ata_bmdma_stop(qc);
 }
 
+/**
+ *     ata_sff_port_start - Set port up for dma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Allocates space for PRD table if the device
+ *     is DMA capable SFF.
+ *
+ *     May be used as the port_start() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+int ata_sff_port_start(struct ata_port *ap)
+{
+       if (ap->ioaddr.bmdma_addr)
+               return ata_port_start(ap);
+       return 0;
+}
+
 #ifdef CONFIG_PCI
 
 static int ata_resources_present(struct pci_dev *pdev, int port)
index 7b4810c171b7d5aa1c9f5bed056130e574ddada7..03b6ddd2abd246ab3ad427c756fe98894e84c5b0 100644 (file)
@@ -97,7 +97,7 @@ static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline)
  *     artop6260_cable_detect  -       identify cable type
  *     @ap: Port
  *
- *     Identify the cable type for the ARTOp interface in question
+ *     Identify the cable type for the ARTOP interface in question
  */
 
 static int artop6260_cable_detect(struct ata_port *ap)
index a54c17433eef0b7dc40be4ea5bd5429a4f73c511..6446735a46e04a523c079cdb68c9170ca78cd5e4 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt37x"
-#define DRV_VERSION    "0.6.5"
+#define DRV_VERSION    "0.6.6"
 
 struct hpt_clock {
        u8      xfer_speed;
@@ -931,15 +931,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x7f,
                .port_ops = &hpt372_port_ops
        };
-       /* HPT371, 372 and friends - UDMA100 at 50MHz clock */
-       static const struct ata_port_info info_hpt372_50 = {
-               .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
-               .pio_mask = 0x1f,
-               .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
-               .port_ops = &hpt372_port_ops
-       };
        /* HPT374 - UDMA133 */
        static const struct ata_port_info info_hpt374 = {
                .sht = &hpt37x_sht,
@@ -1098,17 +1089,21 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                 *      use a 50MHz DPLL by choice
                 */
                unsigned int f_low, f_high;
-               int adjust;
+               int dpll, adjust;
 
-               clock_slot = 2;
+               /* Compute DPLL */
+               dpll = 2;
                if (port->udma_mask & 0xE0)
-                       clock_slot = 3;
+                       dpll = 3;
 
-               f_low = (MHz[clock_slot] * chip_table->base) / 192;
+               f_low = (MHz[clock_slot] * 48) / MHz[dpll];
                f_high = f_low + 2;
+               if (clock_slot > 1)
+                       f_high += 2;
 
                /* Select the DPLL clock. */
                pci_write_config_byte(dev, 0x5b, 0x21);
+               pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
 
                for(adjust = 0; adjust < 8; adjust++) {
                        if (hpt37x_calibrate_dpll(dev))
@@ -1124,12 +1119,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
                        return -ENODEV;
                }
-               if (clock_slot == 3)
+               if (dpll == 3)
                        private_data = (void *)hpt37x_timings_66;
                else
                        private_data = (void *)hpt37x_timings_50;
 
-               printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
+               printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
        } else {
                private_data = (void *)chip_table->clocks[clock_slot];
                /*
index f25154aed75dbd9aab82df2bac041a71c16fecfd..e947433cb37dd3177b902557aad23ea7d52686f8 100644 (file)
@@ -521,8 +521,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        /* 371N if rev > 1 */
                        break;
                case PCI_DEVICE_ID_TTI_HPT372:
-                       /* 372N if rev >= 1*/
-                       if (class_rev == 0)
+                       /* 372N if rev >= 2*/
+                       if (class_rev < 2)
                                return -ENODEV;
                        break;
                case PCI_DEVICE_ID_TTI_HPT302:
index 1f647b648204fffa172d761677f43bb0367572c3..5525518204e65dc07850f2283f8a5e1b775a9703 100644 (file)
@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
        struct ata_host *host;
        struct ata_port *ap;
        void __iomem *cmd_addr, *ctl_addr;
-       int rc;
 
        if (pnp_port_valid(idev, 0) == 0)
                return -ENODEV;
index ff9a6fd366577af8a36a83765ae66b231eb26dfd..b3456d7a592c18701cb762197ca9accfaa4f9087 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ata-it821x.c        - IT821x PATA for new ATA layer
+ * pata_it821x.c       - IT821x PATA for new ATA layer
  *                       (C) 2005 Red Hat Inc
  *                       Alan Cox <alan@redhat.com>
  *
@@ -65,7 +65,6 @@
  *
  *  TODO
  *     -       ATAPI and other speed filtering
- *     -       Command filter in smart mode
  *     -       RAID configuration ioctls
  */
 
index aa138d211b091f6b4d6dcb4a346233732de38ae1..61502bc7bf1d4bcf06a74fc2452371eb0da21aa8 100644 (file)
@@ -489,23 +489,26 @@ static unsigned int scc_devchk (struct ata_port *ap,
  *     Note: Original code is ata_bus_post_reset().
  */
 
-static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
+static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
+                              unsigned long deadline)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
        unsigned int dev0 = devmask & (1 << 0);
        unsigned int dev1 = devmask & (1 << 1);
-       unsigned long timeout;
+       int rc;
 
        /* if device 0 was found in ata_devchk, wait for its
         * BSY bit to clear
         */
-       if (dev0)
-               ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+       if (dev0) {
+               rc = ata_wait_ready(ap, deadline);
+               if (rc && rc != -ENODEV)
+                       return rc;
+       }
 
        /* if device 1 was found in ata_devchk, wait for
         * register access, then wait for BSY to clear
         */
-       timeout = jiffies + ATA_TMOUT_BOOT;
        while (dev1) {
                u8 nsect, lbal;
 
@@ -514,14 +517,15 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
                lbal = in_be32(ioaddr->lbal_addr);
                if ((nsect == 1) && (lbal == 1))
                        break;
-               if (time_after(jiffies, timeout)) {
-                       dev1 = 0;
-                       break;
-               }
+               if (time_after(jiffies, deadline))
+                       return -EBUSY;
                msleep(50);     /* give drive a breather */
        }
-       if (dev1)
-               ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+       if (dev1) {
+               rc = ata_wait_ready(ap, deadline);
+               if (rc && rc != -ENODEV)
+                       return rc;
+       }
 
        /* is all this really necessary? */
        ap->ops->dev_select(ap, 0);
@@ -529,6 +533,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
                ap->ops->dev_select(ap, 1);
        if (dev0)
                ap->ops->dev_select(ap, 0);
+
+       return 0;
 }
 
 /**
@@ -537,8 +543,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
  *     Note: Original code is ata_bus_softreset().
  */
 
-static unsigned int scc_bus_softreset (struct ata_port *ap,
-                                      unsigned int devmask)
+static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
+                                      unsigned long deadline)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
@@ -570,7 +576,7 @@ static unsigned int scc_bus_softreset (struct ata_port *ap,
        if (scc_check_status(ap) == 0xFF)
                return 0;
 
-       scc_bus_post_reset(ap, devmask);
+       scc_bus_post_reset(ap, devmask, deadline);
 
        return 0;
 }
@@ -579,11 +585,13 @@ static unsigned int scc_bus_softreset (struct ata_port *ap,
  *     scc_std_softreset - reset host port via ATA SRST
  *     @ap: port to reset
  *     @classes: resulting classes of attached devices
+ *     @deadline: deadline jiffies for the operation
  *
  *     Note: Original code is ata_std_softreset().
  */
 
-static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
+static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
+                              unsigned long deadline)
 {
        unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
        unsigned int devmask = 0, err_mask;
@@ -607,7 +615,7 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
 
        /* issue bus reset */
        DPRINTK("about to softreset, devmask=%x\n", devmask);
-       err_mask = scc_bus_softreset(ap, devmask);
+       err_mask = scc_bus_softreset(ap, devmask, deadline);
        if (err_mask) {
                ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
                                err_mask);
@@ -676,10 +684,11 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
 
                if (reg & INTSTS_BMSINT) {
                        unsigned int classes;
+                       unsigned long deadline = jiffies + ATA_TMOUT_BOOT;
                        printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
                        out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
                        /* TBD: SW reset */
-                       scc_std_softreset(ap, &classes);
+                       scc_std_softreset(ap, &classes, deadline);
                        continue;
                }
 
@@ -862,9 +871,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
 /**
  *     scc_pata_prereset - prepare for reset
  *     @ap: ATA port to be reset
+ *     @deadline: deadline jiffies for the operation
  */
 
-static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
+static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
 {
        ap->cbl = ATA_CBL_PATA80;
        return ata_std_prereset(ap, deadline);
index f2231267e01120f918736a73fc7a18e3f0d3e2a5..ec3ae9375015a194f408f02e0a7690d4fed74b2d 100644 (file)
@@ -73,14 +73,14 @@ static int sis_short_ata40(struct pci_dev *dev)
 }
 
 /**
- *     sis_port_base           -       return PCI configuration base for dev
+ *     sis_old_port_base               -       return PCI configuration base for dev
  *     @adev: device
  *
  *     Returns the base of the PCI configuration registers for this port
  *     number.
  */
 
-static int sis_port_base(struct ata_device *adev)
+static int sis_old_port_base(struct ata_device *adev)
 {
        return  0x40 + (4 * adev->ap->port_no) +  (2 * adev->devno);
 }
@@ -211,7 +211,7 @@ static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev)
 static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
-       int port = sis_port_base(adev);
+       int port = sis_old_port_base(adev);
        u8 t1, t2;
        int speed = adev->pio_mode - XFER_PIO_0;
 
@@ -248,7 +248,7 @@ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
 static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
-       int port = sis_port_base(adev);
+       int port = sis_old_port_base(adev);
        int speed = adev->pio_mode - XFER_PIO_0;
 
        const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
@@ -328,7 +328,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
+       int drive_pci = sis_old_port_base(adev);
        u16 timing;
 
        const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -367,7 +367,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
+       int drive_pci = sis_old_port_base(adev);
        u16 timing;
 
        const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -378,12 +378,12 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
        if (adev->dma_mode < XFER_UDMA_0) {
                /* bits 3-0 hold recovery timing bits 8-10 active timing and
                   the higer bits are dependant on the device, bit 15 udma */
-               timing &= ~ 0x870F;
+               timing &= ~0x870F;
                timing |= mwdma_bits[speed];
        } else {
                /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x6000;
+               timing &= ~0xF000;
                timing |= udma_bits[speed];
        }
        pci_write_config_word(pdev, drive_pci, timing);
@@ -405,22 +405,22 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
-       u16 timing;
+       int drive_pci = sis_old_port_base(adev);
+       u8 timing;
 
-       const u16 udma_bits[]  = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+       const u8 udma_bits[]  = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-       pci_read_config_word(pdev, drive_pci, &timing);
+       pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
        if (adev->dma_mode < XFER_UDMA_0) {
                /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
        } else {
-               /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+               /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x0F00;
+               timing &= ~0x8F;
                timing |= udma_bits[speed];
        }
-       pci_write_config_word(pdev, drive_pci, timing);
+       pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**
@@ -440,22 +440,22 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
 {
        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
        int speed = adev->dma_mode - XFER_MW_DMA_0;
-       int drive_pci = sis_port_base(adev);
-       u16 timing;
-
-       static const u16 udma_bits[]  = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+       int drive_pci = sis_old_port_base(adev);
+       u8 timing;
+       /* Low 4 bits are timing */
+       static const u8 udma_bits[]  = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-       pci_read_config_word(pdev, drive_pci, &timing);
+       pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
        if (adev->dma_mode < XFER_UDMA_0) {
                /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
        } else {
-               /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+               /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
                speed = adev->dma_mode - XFER_UDMA_0;
-               timing &= ~0x0F00;
+               timing &= ~0x8F;
                timing |= udma_bits[speed];
        }
-       pci_write_config_word(pdev, drive_pci, timing);
+       pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**
index e4c71f76bd55ba701eea332594707880e3480f16..63eca299c62bce1a80c0446c9ec277075d8c839b 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
+#include <linux/dmi.h>
 
 #define DRV_NAME "pata_via"
 #define DRV_VERSION "0.3.1"
@@ -122,6 +123,31 @@ static const struct via_isa_bridge {
        { NULL }
 };
 
+
+/*
+ *     Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+       {
+               .ident = "Acer Ferrari 3400",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
+               },
+       },
+       { }
+};
+
+static int via_cable_override(struct pci_dev *pdev)
+{
+       /* Systems by DMI */
+       if (dmi_check_system(cable_dmi_table))
+               return 1;
+       return 0;
+}
+
+
 /**
  *     via_cable_detect        -       cable detection
  *     @ap: ATA port
@@ -139,6 +165,9 @@ static int via_cable_detect(struct ata_port *ap) {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u32 ata66;
 
+       if (via_cable_override(pdev))
+               return ATA_CBL_PATA40_SHORT;
+
        /* Early chips are 40 wire */
        if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
                return ATA_CBL_PATA40;
@@ -423,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* Early VIA without UDMA support */
        static const struct ata_port_info via_mwdma_info = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &via_port_ops
@@ -431,7 +460,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* Ditto with IRQ masking required */
        static const struct ata_port_info via_mwdma_info_borked = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &via_port_ops_noirq,
@@ -439,7 +468,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* VIA UDMA 33 devices (and borked 66) */
        static const struct ata_port_info via_udma33_info = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x7,
@@ -448,7 +477,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* VIA UDMA 66 devices */
        static const struct ata_port_info via_udma66_info = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x1f,
@@ -457,7 +486,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* VIA UDMA 100 devices */
        static const struct ata_port_info via_udma100_info = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x3f,
@@ -466,7 +495,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* UDMA133 with bad AST (All current 133) */
        static const struct ata_port_info via_udma133_info = {
                .sht = &via_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x7f,      /* FIXME: should check north bridge */
@@ -592,10 +621,11 @@ static int via_reinit_one(struct pci_dev *pdev)
 #endif
 
 static const struct pci_device_id via[] = {
-       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
-       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
-       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
-       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
+       { PCI_VDEVICE(VIA, 0x0571), },
+       { PCI_VDEVICE(VIA, 0x0581), },
+       { PCI_VDEVICE(VIA, 0x1571), },
+       { PCI_VDEVICE(VIA, 0x3164), },
+       { PCI_VDEVICE(VIA, 0x5324), },
 
        { },
 };
index 705a020e1597e0d7eaab86b7aed75f17d45bcd6f..c957e6e54ba1b61e493386dd92cb5a1a4ebebddd 100644 (file)
  *
  */
 
+/*
+  sata_mv TODO list:
+
+  1) Needs a full errata audit for all chipsets.  I implemented most
+  of the errata workarounds found in the Marvell vendor driver, but
+  I distinctly remember a couple workarounds (one related to PCI-X)
+  are still needed.
+
+  2) Convert to LibATA new EH.  Required for hotplug, NCQ, and sane
+  probing/error handling in general.  MUST HAVE.
+
+  3) Add hotplug support (easy, once new-EH support appears)
+
+  4) Add NCQ support (easy to intermediate, once new-EH support appears)
+
+  5) Investigate problems with PCI Message Signalled Interrupts (MSI).
+
+  6) Add port multiplier support (intermediate)
+
+  7) Test and verify 3.0 Gbps support
+
+  8) Develop a low-power-consumption strategy, and implement it.
+
+  9) [Experiment, low priority] See if ATAPI can be supported using
+  "unknown FIS" or "vendor-specific FIS" support, or something creative
+  like that.
+
+  10) [Experiment, low priority] Investigate interrupt coalescing.
+  Quite often, especially with PCI Message Signalled Interrupts (MSI),
+  the overhead reduced by interrupt mitigation is quite often not
+  worth the latency cost.
+
+  11) [Experiment, Marvell value added] Is it possible to use target
+  mode to cross-connect two Linux boxes with Marvell cards?  If so,
+  creating LibATA target mode support would be very interesting.
+
+  Target mode, for those without docs, is the ability to directly
+  connect two SATA controllers.
+
+  13) Verify that 7042 is fully supported.  I only have a 6042.
+
+*/
+
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
index 3a7d9b5332af93fd8daf709613a190aa8ab849b2..6dc0b011a6b7c5a10febc2a0242c5dc431939a23 100644 (file)
@@ -297,7 +297,7 @@ static const struct ata_port_info pdc_port_info[] = {
 
        /* board_2057x_pata */
        {
-               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
                                  PDC_FLAG_GEN_II,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
@@ -784,9 +784,12 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
                if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
                        break;
                /*FALLTHROUGH*/
+       case ATA_PROT_NODATA:
+               if (qc->tf.flags & ATA_TFLAG_POLLING)
+                       break;
+               /*FALLTHROUGH*/
        case ATA_PROT_ATAPI_DMA:
        case ATA_PROT_DMA:
-       case ATA_PROT_NODATA:
                pdc_packet_start(qc);
                return 0;
 
@@ -800,7 +803,7 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
        WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_NODATA);
+                tf->protocol == ATA_PROT_ATAPI_DMA);
        ata_tf_load(ap, tf);
 }
 
@@ -808,7 +811,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
        WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_NODATA);
+                tf->protocol == ATA_PROT_ATAPI_DMA);
        ata_exec_command(ap, tf);
 }
 
index 51d9251b0898a5f3351b32925e09231ee4cb8864..221099d1d08fd493a268d496261d3147142d3fc9 100644 (file)
@@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        struct ata_port_info pi = sis_port_info;
-       const struct ata_port_info *ppi[] = { &pi, NULL };
+       const struct ata_port_info *ppi[] = { &pi, &pi };
        struct ata_host *host;
        u32 genctl, val;
        u8 pmr;
index 01bba26d8d1afda79b2740c50cd5250f8f257a4c..e8b90e7b42ddcfa56e5253941bc33532258aeed0 100644 (file)
@@ -85,6 +85,9 @@ static const struct pci_device_id svia_pci_tbl[] = {
        { PCI_VDEVICE(VIA, 0x0591), vt6420 },
        { PCI_VDEVICE(VIA, 0x3149), vt6420 },
        { PCI_VDEVICE(VIA, 0x3249), vt6421 },
+       { PCI_VDEVICE(VIA, 0x5287), vt6420 },
+       { PCI_VDEVICE(VIA, 0x5372), vt6420 },
+       { PCI_VDEVICE(VIA, 0x7372), vt6420 },
 
        { }     /* terminate list */
 };
index 9c67df5ccfa432df69acf4c335ca0707724e7363..7f6d02ce1b5f53da024bddd9e1ef0976c593ad01 100644 (file)
@@ -1475,6 +1475,7 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
        struct FS_BPENTRY *qe, *ne;
        struct sk_buff *skb;
        int n = 0;
+       u32 qe_tmp;
 
        fs_dprintk (FS_DEBUG_QUEUE, "Topping off queue at %x (%d-%d/%d)\n", 
                    fp->offset, read_fs (dev, FP_CNT (fp->offset)), fp->n, 
@@ -1502,10 +1503,16 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
                ne->skb = skb;
                ne->fp = fp;
 
-               qe = (struct FS_BPENTRY *) (read_fs (dev, FP_EA(fp->offset)));
-               fs_dprintk (FS_DEBUG_QUEUE, "link at %p\n", qe);
-               if (qe) {
-                       qe = bus_to_virt ((long) qe);
+               /*
+                * FIXME: following code encodes and decodes
+                * machine pointers (could be 64-bit) into a
+                * 32-bit register.
+                */
+
+               qe_tmp = read_fs (dev, FP_EA(fp->offset));
+               fs_dprintk (FS_DEBUG_QUEUE, "link at %x\n", qe_tmp);
+               if (qe_tmp) {
+                       qe = bus_to_virt ((long) qe_tmp);
                        qe->next = virt_to_bus(ne);
                        qe->flags &= ~FP_FLAGS_EPI;
                } else
index 057efbc55d3829665d76b6e264424a6a4b229db9..3800bc0cb2efe8d9016f54fd19e007096cda1842 100644 (file)
@@ -47,7 +47,8 @@ static char const rcsid[] =
 #include <linux/bitops.h>
 #include <linux/wait.h>
 #include <linux/jiffies.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -2435,7 +2436,7 @@ idt77252_open(struct atm_vcc *vcc)
 
        set_bit(ATM_VF_ADDR, &vcc->flags);
 
-       down(&card->mutex);
+       mutex_lock(&card->mutex);
 
        OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci);
 
@@ -2446,7 +2447,7 @@ idt77252_open(struct atm_vcc *vcc)
                break;
        default:
                printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-               up(&card->mutex);
+               mutex_unlock(&card->mutex);
                return -EPROTONOSUPPORT;
        }
 
@@ -2455,7 +2456,7 @@ idt77252_open(struct atm_vcc *vcc)
                card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
                if (!card->vcs[index]) {
                        printk("%s: can't alloc vc in open()\n", card->name);
-                       up(&card->mutex);
+                       mutex_unlock(&card->mutex);
                        return -ENOMEM;
                }
                card->vcs[index]->card = card;
@@ -2484,14 +2485,14 @@ idt77252_open(struct atm_vcc *vcc)
        if (inuse) {
                printk("%s: %s vci already in use.\n", card->name,
                       inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
-               up(&card->mutex);
+               mutex_unlock(&card->mutex);
                return -EADDRINUSE;
        }
 
        if (vcc->qos.txtp.traffic_class != ATM_NONE) {
                error = idt77252_init_tx(card, vc, vcc, &vcc->qos);
                if (error) {
-                       up(&card->mutex);
+                       mutex_unlock(&card->mutex);
                        return error;
                }
        }
@@ -2499,14 +2500,14 @@ idt77252_open(struct atm_vcc *vcc)
        if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
                error = idt77252_init_rx(card, vc, vcc, &vcc->qos);
                if (error) {
-                       up(&card->mutex);
+                       mutex_unlock(&card->mutex);
                        return error;
                }
        }
 
        set_bit(ATM_VF_READY, &vcc->flags);
 
-       up(&card->mutex);
+       mutex_unlock(&card->mutex);
        return 0;
 }
 
@@ -2520,7 +2521,7 @@ idt77252_close(struct atm_vcc *vcc)
        unsigned long addr;
        unsigned long timeout;
 
-       down(&card->mutex);
+       mutex_lock(&card->mutex);
 
        IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n",
                card->name, vc->index, vcc->vpi, vcc->vci);
@@ -2591,7 +2592,7 @@ done:
                free_scq(card, vc->scq);
        }
 
-       up(&card->mutex);
+       mutex_unlock(&card->mutex);
 }
 
 static int
@@ -2602,7 +2603,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
        struct vc_map *vc = vcc->dev_data;
        int error = 0;
 
-       down(&card->mutex);
+       mutex_lock(&card->mutex);
 
        if (qos->txtp.traffic_class != ATM_NONE) {
                if (!test_bit(VCF_TX, &vc->flags)) {
@@ -2648,7 +2649,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
        set_bit(ATM_VF_HASQOS, &vcc->flags);
 
 out:
-       up(&card->mutex);
+       mutex_unlock(&card->mutex);
        return error;
 }
 
@@ -3709,7 +3710,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
        membase = pci_resource_start(pcidev, 1);
        srambase = pci_resource_start(pcidev, 2);
 
-       init_MUTEX(&card->mutex);
+       mutex_init(&card->mutex);
        spin_lock_init(&card->cmd_lock);
        spin_lock_init(&card->tst_lock);
 
index 544b397382916dc842f0931abd2397f200d1ea90..6f2b4a5875fb9b68a2501d144fd9405a6f8e3cd9 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/ptrace.h>
 #include <linux/skbuff.h>
 #include <linux/workqueue.h>
-
+#include <linux/mutex.h>
 
 /*****************************************************************************/
 /*                                                                           */
@@ -359,7 +359,7 @@ struct idt77252_dev
        unsigned long           srambase;       /* SAR's sram  base address */
        void __iomem            *fbq[4];        /* FBQ fill addresses */
 
-       struct semaphore        mutex;
+       struct mutex            mutex;
        spinlock_t              cmd_lock;       /* for r/w utility/sram */
 
        unsigned long           softstat;
index 2e18a63ead36d735049d7297fedbc1c77b53d5db..ea4fe3e48f33c3213b9c0447a26fbeddb3d38148 100644 (file)
@@ -68,6 +68,10 @@ config CFAG12864B
        depends on X86
        depends on FB
        depends on KS0108
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
        default n
        ---help---
          If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
index 66fafbb1d0871896ebf36d0d5c78debcc17a8f2b..307c190699e04193815004207549a5f7d8706284 100644 (file)
@@ -73,9 +73,11 @@ static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 static struct fb_ops cfag12864bfb_ops = {
        .owner = THIS_MODULE,
-       .fb_fillrect = cfb_fillrect,
-       .fb_copyarea = cfb_copyarea,
-       .fb_imageblit = cfb_imageblit,
+       .fb_read = fb_sys_read,
+       .fb_write = fb_sys_write,
+       .fb_fillrect = sys_fillrect,
+       .fb_copyarea = sys_copyarea,
+       .fb_imageblit = sys_imageblit,
        .fb_mmap = cfag12864bfb_mmap,
 };
 
index 20c4ea6eb50d0a8836e2f89af145fc88634c02ba..8c506dbe39138bc11b8901944a81461c5a424e79 100644 (file)
@@ -369,36 +369,6 @@ char *make_class_name(const char *name, struct kobject *kobj)
        return class_name;
 }
 
-static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index,
-                                  char *buffer, int buffer_size,
-                                  int *cur_len,
-                                  struct class_device *class_dev)
-{
-       struct device *dev = class_dev->dev;
-       char *path;
-
-       if (!dev)
-               return 0;
-
-       /* add device, backing this class device (deprecated) */
-       path = kobject_get_path(&dev->kobj, GFP_KERNEL);
-
-       add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size,
-                      cur_len, "PHYSDEVPATH=%s", path);
-       kfree(path);
-
-       if (dev->bus)
-               add_uevent_var(envp, num_envp, cur_index,
-                              buffer, buffer_size, cur_len,
-                              "PHYSDEVBUS=%s", dev->bus->name);
-
-       if (dev->driver)
-               add_uevent_var(envp, num_envp, cur_index,
-                              buffer, buffer_size, cur_len,
-                              "PHYSDEVDRIVER=%s", dev->driver->name);
-       return 0;
-}
-
 static int make_deprecated_class_device_links(struct class_device *class_dev)
 {
        char *class_name;
@@ -430,11 +400,6 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
        kfree(class_name);
 }
 #else
-static inline int deprecated_class_uevent(char **envp, int num_envp,
-                                         int *cur_index, char *buffer,
-                                         int buffer_size, int *cur_len,
-                                         struct class_device *class_dev)
-{ return 0; }
 static inline int make_deprecated_class_device_links(struct class_device *cd)
 { return 0; }
 static void remove_deprecated_class_device_links(struct class_device *cd)
@@ -445,15 +410,13 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
                         int num_envp, char *buffer, int buffer_size)
 {
        struct class_device *class_dev = to_class_dev(kobj);
+       struct device *dev = class_dev->dev;
        int i = 0;
        int length = 0;
        int retval = 0;
 
        pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
 
-       deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size,
-                               &length, class_dev);
-
        if (MAJOR(class_dev->devt)) {
                add_uevent_var(envp, num_envp, &i,
                               buffer, buffer_size, &length,
@@ -464,6 +427,26 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
                               "MINOR=%u", MINOR(class_dev->devt));
        }
 
+       if (dev) {
+               const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
+               if (path) {
+                       add_uevent_var(envp, num_envp, &i,
+                                      buffer, buffer_size, &length,
+                                      "PHYSDEVPATH=%s", path);
+                       kfree(path);
+               }
+
+               if (dev->bus)
+                       add_uevent_var(envp, num_envp, &i,
+                                      buffer, buffer_size, &length,
+                                      "PHYSDEVBUS=%s", dev->bus->name);
+
+               if (dev->driver)
+                       add_uevent_var(envp, num_envp, &i,
+                                      buffer, buffer_size, &length,
+                                      "PHYSDEVDRIVER=%s", dev->driver->name);
+       }
+
        /* terminate, set to next free slot, shrink available space */
        envp[i] = NULL;
        envp = &envp[i];
index b78fc1e68264872a196c6a7b1e454b080a9831bd..dd40d78a023dd1f2fde9712ac7700d5ade4893cf 100644 (file)
@@ -180,10 +180,12 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
                        const char *path;
 
                        path = kobject_get_path(&parent->kobj, GFP_KERNEL);
-                       add_uevent_var(envp, num_envp, &i,
-                                      buffer, buffer_size, &length,
-                                      "PHYSDEVPATH=%s", path);
-                       kfree(path);
+                       if (path) {
+                               add_uevent_var(envp, num_envp, &i,
+                                              buffer, buffer_size, &length,
+                                              "PHYSDEVPATH=%s", path);
+                               kfree(path);
+                       }
 
                        add_uevent_var(envp, num_envp, &i,
                                       buffer, buffer_size, &length,
index 92428e55b0c210a8c00cf8e656a934fa9e21f2d3..b0088b0efecdd1e5395e4104d23d0fe34dbb9a0d 100644 (file)
@@ -207,19 +207,6 @@ static int __device_attach(struct device_driver * drv, void * data)
        return driver_probe_device(drv, dev);
 }
 
-static int device_probe_drivers(void *data)
-{
-       struct device *dev = data;
-       int ret = 0;
-
-       if (dev->bus) {
-               down(&dev->sem);
-               ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
-               up(&dev->sem);
-       }
-       return ret;
-}
-
 /**
  *     device_attach - try to attach device to a driver.
  *     @dev:   device.
index 97ab5bd1c4d62ebb72ef9babc07f2c35571c484b..89a5f4a5491391e2270069090f43c6e82b6ef601 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * firmware_class.c - Multi purpose firmware loading support
  *
- * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ * Copyright (c) 2003 Manuel Estrada Sainz
  *
  * Please see Documentation/firmware_class/ for more information.
  *
@@ -23,7 +23,7 @@
 
 #define to_dev(obj) container_of(obj, struct device, kobj)
 
-MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_AUTHOR("Manuel Estrada Sainz");
 MODULE_DESCRIPTION("Multi purpose firmware loading support");
 MODULE_LICENSE("GPL");
 
index 3587cb434371f10a3219b9405a1dc6225cff93c9..fe088045dd08a97b400f40dd47d36e3cc92962b1 100644 (file)
@@ -670,7 +670,7 @@ static void __reschedule_timeout(int drive, const char *message, int marg)
        if (drive == current_reqD)
                drive = current_drive;
        del_timer(&fd_timeout);
-       if (drive < 0 || drive > N_DRIVE) {
+       if (drive < 0 || drive >= N_DRIVE) {
                fd_timeout.expires = jiffies + 20UL * HZ;
                drive = 0;
        } else
index 5526eadb65926d4318b790a0ede84d9f272a7059..0ed5470d25339674a5c449feab66f5505db5f3c2 100644 (file)
@@ -1354,7 +1354,7 @@ static struct block_device_operations lo_fops = {
  */
 static int max_loop;
 module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand");
+MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1394,16 +1394,11 @@ int loop_unregister_transfer(int number)
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);
 
-static struct loop_device *loop_init_one(int i)
+static struct loop_device *loop_alloc(int i)
 {
        struct loop_device *lo;
        struct gendisk *disk;
 
-       list_for_each_entry(lo, &loop_devices, lo_list) {
-               if (lo->lo_number == i)
-                       return lo;
-       }
-
        lo = kzalloc(sizeof(*lo), GFP_KERNEL);
        if (!lo)
                goto out;
@@ -1427,8 +1422,6 @@ static struct loop_device *loop_init_one(int i)
        disk->private_data      = lo;
        disk->queue             = lo->lo_queue;
        sprintf(disk->disk_name, "loop%d", i);
-       add_disk(disk);
-       list_add_tail(&lo->lo_list, &loop_devices);
        return lo;
 
 out_free_queue:
@@ -1439,15 +1432,37 @@ out:
        return NULL;
 }
 
-static void loop_del_one(struct loop_device *lo)
+static void loop_free(struct loop_device *lo)
 {
-       del_gendisk(lo->lo_disk);
        blk_cleanup_queue(lo->lo_queue);
        put_disk(lo->lo_disk);
        list_del(&lo->lo_list);
        kfree(lo);
 }
 
+static struct loop_device *loop_init_one(int i)
+{
+       struct loop_device *lo;
+
+       list_for_each_entry(lo, &loop_devices, lo_list) {
+               if (lo->lo_number == i)
+                       return lo;
+       }
+
+       lo = loop_alloc(i);
+       if (lo) {
+               add_disk(lo->lo_disk);
+               list_add_tail(&lo->lo_list, &loop_devices);
+       }
+       return lo;
+}
+
+static void loop_del_one(struct loop_device *lo)
+{
+       del_gendisk(lo->lo_disk);
+       loop_free(lo);
+}
+
 static struct kobject *loop_probe(dev_t dev, int *part, void *data)
 {
        struct loop_device *lo;
@@ -1464,28 +1479,77 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
 
 static int __init loop_init(void)
 {
-       if (register_blkdev(LOOP_MAJOR, "loop"))
-               return -EIO;
-       blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
-                                 THIS_MODULE, loop_probe, NULL, NULL);
+       int i, nr;
+       unsigned long range;
+       struct loop_device *lo, *next;
+
+       /*
+        * loop module now has a feature to instantiate underlying device
+        * structure on-demand, provided that there is an access dev node.
+        * However, this will not work well with user space tool that doesn't
+        * know about such "feature".  In order to not break any existing
+        * tool, we do the following:
+        *
+        * (1) if max_loop is specified, create that many upfront, and this
+        *     also becomes a hard limit.
+        * (2) if max_loop is not specified, create 8 loop device on module
+        *     load, user can further extend loop device by create dev node
+        *     themselves and have kernel automatically instantiate actual
+        *     device on-demand.
+        */
+       if (max_loop > 1UL << MINORBITS)
+               return -EINVAL;
 
        if (max_loop) {
-               printk(KERN_INFO "loop: the max_loop option is obsolete "
-                                "and will be removed in March 2008\n");
+               nr = max_loop;
+               range = max_loop;
+       } else {
+               nr = 8;
+               range = 1UL << MINORBITS;
+       }
+
+       if (register_blkdev(LOOP_MAJOR, "loop"))
+               return -EIO;
 
+       for (i = 0; i < nr; i++) {
+               lo = loop_alloc(i);
+               if (!lo)
+                       goto Enomem;
+               list_add_tail(&lo->lo_list, &loop_devices);
        }
+
+       /* point of no return */
+
+       list_for_each_entry(lo, &loop_devices, lo_list)
+               add_disk(lo->lo_disk);
+
+       blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
+                                 THIS_MODULE, loop_probe, NULL, NULL);
+
        printk(KERN_INFO "loop: module loaded\n");
        return 0;
+
+Enomem:
+       printk(KERN_INFO "loop: out of memory\n");
+
+       list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+               loop_free(lo);
+
+       unregister_blkdev(LOOP_MAJOR, "loop");
+       return -ENOMEM;
 }
 
 static void __exit loop_exit(void)
 {
+       unsigned long range;
        struct loop_device *lo, *next;
 
+       range = max_loop ? max_loop :  1UL << MINORBITS;
+
        list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
                loop_del_one(lo);
 
-       blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
+       blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
        if (unregister_blkdev(LOOP_MAJOR, "loop"))
                printk(KERN_WARNING "loop: cannot unregister blkdev\n");
 }
index b0238b46ddedb6ca1f472f0b502634995181f67d..7e04dd69f60976abc4a203acd7dc3d04e25bd3f3 100644 (file)
@@ -115,11 +115,11 @@ static struct usb_device_id blacklist_ids[] = {
        { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
 
        /* Broadcom BCM2045 */
-       { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* IBM/Lenovo ThinkPad with Broadcom chip */
-       { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
-       { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* Targus ACB10US */
        { USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET },
@@ -128,17 +128,17 @@ static struct usb_device_id blacklist_ids[] = {
        { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
 
        /* HP laptop with Broadcom chip */
-       { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* Dell laptop with Broadcom chip */
-       { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
        { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
        /* Kensington Bluetooth USB adapter */
        { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
-       { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* ISSC Bluetooth Adapter v3.1 */
        { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
@@ -148,8 +148,8 @@ static struct usb_device_id blacklist_ids[] = {
        { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
 
        /* Belkin F8T012 and F8T013 devices */
-       { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
-       { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
 
        /* Digianswer devices */
        { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
index f574962f4288d36233491eb0d98f8968e2d0da2b..4310cc84dfedb4c3b59dc20751e91ed076ace202 100644 (file)
@@ -1053,11 +1053,11 @@ static void __exit mcdx_exit(void)
        if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
                xwarn("cleanup() unregister_blkdev() failed\n");
        }
-       blk_cleanup_queue(mcdx_queue);
 #if !MCDX_QUIET
        else
        xinfo("cleanup() succeeded\n");
 #endif
+       blk_cleanup_queue(mcdx_queue);
 }
 
 #ifdef MODULE
index fdbca25a3948a14437181d2bd4b89567dfcdcf2e..35ab1a9f8e8b42269ea1e7a7e9d13f9c86f16d0b 100644 (file)
@@ -176,7 +176,7 @@ struct agp_bridge_data {
 #define I830_GMCH_MEM_MASK             0x1
 #define I830_GMCH_MEM_64M              0x1
 #define I830_GMCH_MEM_128M             0
-#define I830_GMCH_GMS_MASK             0x70
+#define I830_GMCH_GMS_MASK             0xF0
 #define I830_GMCH_GMS_DISABLED         0x00
 #define I830_GMCH_GMS_LOCAL            0x10
 #define I830_GMCH_GMS_STOLEN_512       0x20
@@ -231,6 +231,10 @@ struct agp_bridge_data {
 #define I965_PGETBL_SIZE_512KB (0 << 1)
 #define I965_PGETBL_SIZE_256KB (1 << 1)
 #define I965_PGETBL_SIZE_128KB (2 << 1)
+#define G33_PGETBL_SIZE_MASK    (3 << 8)
+#define G33_PGETBL_SIZE_1M      (1 << 8)
+#define G33_PGETBL_SIZE_2M      (2 << 8)
+
 #define I810_DRAM_CTL          0x3000
 #define I810_DRAM_ROW_0                0x00000001
 #define I810_DRAM_ROW_0_SDRAM  0x00000001
index 9c69f2e761f568cb56af191690be641d7aefffd2..d383168b75fa280fa9f5d411f30b2a3c8e8b86ce 100644 (file)
 #define PCI_DEVICE_ID_INTEL_82965G_IG       0x29A2
 #define PCI_DEVICE_ID_INTEL_82965GM_HB      0x2A00
 #define PCI_DEVICE_ID_INTEL_82965GM_IG      0x2A02
+#define PCI_DEVICE_ID_INTEL_82965GME_IG     0x2A12
+#define PCI_DEVICE_ID_INTEL_82945GME_IG     0x27AE
+#define PCI_DEVICE_ID_INTEL_G33_HB          0x29C0
+#define PCI_DEVICE_ID_INTEL_G33_IG          0x29C2
+#define PCI_DEVICE_ID_INTEL_Q35_HB          0x29B0
+#define PCI_DEVICE_ID_INTEL_Q35_IG          0x29B2
+#define PCI_DEVICE_ID_INTEL_Q33_HB          0x29D0
+#define PCI_DEVICE_ID_INTEL_Q33_IG          0x29D2
 
 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
@@ -27,6 +35,9 @@
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
 
+#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
 
 extern int agp_memory_reserved;
 
@@ -53,6 +64,8 @@ extern int agp_memory_reserved;
 #define I915_PTEADDR   0x1C
 #define I915_GMCH_GMS_STOLEN_48M       (0x6 << 4)
 #define I915_GMCH_GMS_STOLEN_64M       (0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M       (0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M       (0x9 << 4)
 
 /* Intel 965G registers */
 #define I965_MSAC 0x62
@@ -86,11 +99,18 @@ static struct gatt_mask intel_i810_masks[] =
         .type = INTEL_AGP_CACHED_MEMORY}
 };
 
-static struct _intel_i810_private {
-       struct pci_dev *i810_dev;       /* device one */
-       volatile u8 __iomem *registers;
+static struct _intel_private {
+       struct pci_dev *pcidev; /* device one */
+       u8 __iomem *registers;
+       u32 __iomem *gtt;               /* I915G */
        int num_dcache_entries;
-} intel_i810_private;
+       /* gtt_entries is the number of gtt entries that are already mapped
+        * to stolen memory.  Stolen memory is larger than the memory mapped
+        * through gtt_entries, as it includes some reserved space for the BIOS
+        * popup and for the GTT.
+        */
+       int gtt_entries;                        /* i830+ */
+} intel_private;
 
 static int intel_i810_fetch_size(void)
 {
@@ -127,32 +147,32 @@ static int intel_i810_configure(void)
 
        current_size = A_SIZE_FIX(agp_bridge->current_size);
 
-       if (!intel_i810_private.registers) {
-               pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+       if (!intel_private.registers) {
+               pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp);
                temp &= 0xfff80000;
 
-               intel_i810_private.registers = ioremap(temp, 128 * 4096);
-               if (!intel_i810_private.registers) {
+               intel_private.registers = ioremap(temp, 128 * 4096);
+               if (!intel_private.registers) {
                        printk(KERN_ERR PFX "Unable to remap memory.\n");
                        return -ENOMEM;
                }
        }
 
-       if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
+       if ((readl(intel_private.registers+I810_DRAM_CTL)
                & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
                /* This will need to be dynamically assigned */
                printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
-               intel_i810_private.num_dcache_entries = 1024;
+               intel_private.num_dcache_entries = 1024;
        }
-       pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+       pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-       writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
-       readl(intel_i810_private.registers+I810_PGETBL_CTL);    /* PCI Posting. */
+       writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+       readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
 
        if (agp_bridge->driver->needs_scratch_page) {
                for (i = 0; i < current_size->num_entries; i++) {
-                       writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
-                       readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));        /* PCI posting. */
+                       writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+                       readl(intel_private.registers+I810_PTE_BASE+(i*4));     /* PCI posting. */
                }
        }
        global_cache_flush();
@@ -161,9 +181,9 @@ static int intel_i810_configure(void)
 
 static void intel_i810_cleanup(void)
 {
-       writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
-       readl(intel_i810_private.registers);    /* PCI Posting. */
-       iounmap(intel_i810_private.registers);
+       writel(0, intel_private.registers+I810_PGETBL_CTL);
+       readl(intel_private.registers); /* PCI Posting. */
+       iounmap(intel_private.registers);
 }
 
 static void intel_i810_tlbflush(struct agp_memory *mem)
@@ -261,9 +281,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
                        global_cache_flush();
                for (i = pg_start; i < (pg_start + mem->page_count); i++) {
                        writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
-                              intel_i810_private.registers+I810_PTE_BASE+(i*4));
+                              intel_private.registers+I810_PTE_BASE+(i*4));
                }
-               readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+               readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
                break;
        case AGP_PHYS_MEMORY:
        case AGP_NORMAL_MEMORY:
@@ -273,9 +293,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
                        writel(agp_bridge->driver->mask_memory(agp_bridge,
                                                               mem->memory[i],
                                                               mask_type),
-                              intel_i810_private.registers+I810_PTE_BASE+(j*4));
+                              intel_private.registers+I810_PTE_BASE+(j*4));
                }
-               readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
+               readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
                break;
        default:
                goto out_err;
@@ -298,9 +318,9 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
                return 0;
 
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-               writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+               writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
        }
-       readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+       readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
 
        agp_bridge->driver->tlb_flush(mem);
        return 0;
@@ -354,7 +374,7 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
        struct agp_memory *new;
 
        if (type == AGP_DCACHE_MEMORY) {
-               if (pg_count != intel_i810_private.num_dcache_entries)
+               if (pg_count != intel_private.num_dcache_entries)
                        return NULL;
 
                new = agp_create_memory(1);
@@ -404,18 +424,6 @@ static struct aper_size_info_fixed intel_i830_sizes[] =
        {512, 131072, 7},
 };
 
-static struct _intel_i830_private {
-       struct pci_dev *i830_dev;               /* device one */
-       volatile u8 __iomem *registers;
-       volatile u32 __iomem *gtt;              /* I915G */
-       /* gtt_entries is the number of gtt entries that are already mapped
-        * to stolen memory.  Stolen memory is larger than the memory mapped
-        * through gtt_entries, as it includes some reserved space for the BIOS
-        * popup and for the GTT.
-        */
-       int gtt_entries;
-} intel_i830_private;
-
 static void intel_i830_init_gtt_entries(void)
 {
        u16 gmch_ctrl;
@@ -429,7 +437,7 @@ static void intel_i830_init_gtt_entries(void)
 
        if (IS_I965) {
                u32 pgetbl_ctl;
-               pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
+               pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
 
                /* The 965 has a field telling us the size of the GTT,
                 * which may be larger than what is necessary to map the
@@ -451,6 +459,22 @@ static void intel_i830_init_gtt_entries(void)
                        size = 512;
                }
                size += 4; /* add in BIOS popup space */
+       } else if (IS_G33) {
+       /* G33's GTT size defined in gmch_ctrl */
+               switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
+               case G33_PGETBL_SIZE_1M:
+                       size = 1024;
+                       break;
+               case G33_PGETBL_SIZE_2M:
+                       size = 2048;
+                       break;
+               default:
+                       printk(KERN_INFO PFX "Unknown page table size 0x%x, "
+                               "assuming 512KB\n",
+                               (gmch_ctrl & G33_PGETBL_SIZE_MASK));
+                       size = 512;
+               }
+               size += 4;
        } else {
                /* On previous hardware, the GTT size was just what was
                 * required to map the aperture.
@@ -471,7 +495,7 @@ static void intel_i830_init_gtt_entries(void)
                        gtt_entries = MB(8) - KB(size);
                        break;
                case I830_GMCH_GMS_LOCAL:
-                       rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
+                       rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
                        gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
                                        MB(ddt[I830_RDRAM_DDT(rdct)]);
                        local = 1;
@@ -502,7 +526,8 @@ static void intel_i830_init_gtt_entries(void)
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
                            agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
                            agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+                           IS_I965 || IS_G33)
                                gtt_entries = MB(48) - KB(size);
                        else
                                gtt_entries = 0;
@@ -512,10 +537,24 @@ static void intel_i830_init_gtt_entries(void)
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
                            agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
                            agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+                           IS_I965 || IS_G33)
                                gtt_entries = MB(64) - KB(size);
                        else
                                gtt_entries = 0;
+                       break;
+               case G33_GMCH_GMS_STOLEN_128M:
+                       if (IS_G33)
+                               gtt_entries = MB(128) - KB(size);
+                       else
+                               gtt_entries = 0;
+                       break;
+               case G33_GMCH_GMS_STOLEN_256M:
+                       if (IS_G33)
+                               gtt_entries = MB(256) - KB(size);
+                       else
+                               gtt_entries = 0;
+                       break;
                default:
                        gtt_entries = 0;
                        break;
@@ -529,7 +568,7 @@ static void intel_i830_init_gtt_entries(void)
                       "No pre-allocated video memory detected.\n");
        gtt_entries /= KB(4);
 
-       intel_i830_private.gtt_entries = gtt_entries;
+       intel_private.gtt_entries = gtt_entries;
 }
 
 /* The intel i830 automatically initializes the agp aperture during POST.
@@ -547,14 +586,14 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
        num_entries = size->num_entries;
        agp_bridge->gatt_table_real = NULL;
 
-       pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+       pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp);
        temp &= 0xfff80000;
 
-       intel_i830_private.registers = ioremap(temp,128 * 4096);
-       if (!intel_i830_private.registers)
+       intel_private.registers = ioremap(temp,128 * 4096);
+       if (!intel_private.registers)
                return -ENOMEM;
 
-       temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+       temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
        global_cache_flush();   /* FIXME: ?? */
 
        /* we have to call this as early as possible after the MMIO base address is known */
@@ -614,20 +653,20 @@ static int intel_i830_configure(void)
 
        current_size = A_SIZE_FIX(agp_bridge->current_size);
 
-       pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+       pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp);
        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
        pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
        gmch_ctrl |= I830_GMCH_ENABLED;
        pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-       writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
-       readl(intel_i830_private.registers+I810_PGETBL_CTL);    /* PCI Posting. */
+       writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+       readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
 
        if (agp_bridge->driver->needs_scratch_page) {
-               for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
-                       writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
-                       readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));        /* PCI Posting. */
+               for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+                       writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+                       readl(intel_private.registers+I810_PTE_BASE+(i*4));     /* PCI Posting. */
                }
        }
 
@@ -637,7 +676,7 @@ static int intel_i830_configure(void)
 
 static void intel_i830_cleanup(void)
 {
-       iounmap(intel_i830_private.registers);
+       iounmap(intel_private.registers);
 }
 
 static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
@@ -653,9 +692,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
        temp = agp_bridge->current_size;
        num_entries = A_SIZE_FIX(temp)->num_entries;
 
-       if (pg_start < intel_i830_private.gtt_entries) {
-               printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
-                               pg_start,intel_i830_private.gtt_entries);
+       if (pg_start < intel_private.gtt_entries) {
+               printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+                               pg_start,intel_private.gtt_entries);
 
                printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
                goto out_err;
@@ -683,9 +722,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
                                                       mem->memory[i], mask_type),
-                      intel_i830_private.registers+I810_PTE_BASE+(j*4));
+                      intel_private.registers+I810_PTE_BASE+(j*4));
        }
-       readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
+       readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
        agp_bridge->driver->tlb_flush(mem);
 
 out:
@@ -703,15 +742,15 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
        if (mem->page_count == 0)
                return 0;
 
-       if (pg_start < intel_i830_private.gtt_entries) {
+       if (pg_start < intel_private.gtt_entries) {
                printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
                return -EINVAL;
        }
 
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-               writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+               writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
        }
-       readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
+       readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
 
        agp_bridge->driver->tlb_flush(mem);
        return 0;
@@ -734,7 +773,7 @@ static int intel_i915_configure(void)
 
        current_size = A_SIZE_FIX(agp_bridge->current_size);
 
-       pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
+       pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp);
 
        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
@@ -742,13 +781,13 @@ static int intel_i915_configure(void)
        gmch_ctrl |= I830_GMCH_ENABLED;
        pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-       writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
-       readl(intel_i830_private.registers+I810_PGETBL_CTL);    /* PCI Posting. */
+       writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+       readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
 
        if (agp_bridge->driver->needs_scratch_page) {
-               for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
-                       writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
-                       readl(intel_i830_private.gtt+i);        /* PCI Posting. */
+               for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+                       writel(agp_bridge->scratch_page, intel_private.gtt+i);
+                       readl(intel_private.gtt+i);     /* PCI Posting. */
                }
        }
 
@@ -758,8 +797,8 @@ static int intel_i915_configure(void)
 
 static void intel_i915_cleanup(void)
 {
-       iounmap(intel_i830_private.gtt);
-       iounmap(intel_i830_private.registers);
+       iounmap(intel_private.gtt);
+       iounmap(intel_private.registers);
 }
 
 static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
@@ -776,9 +815,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
        temp = agp_bridge->current_size;
        num_entries = A_SIZE_FIX(temp)->num_entries;
 
-       if (pg_start < intel_i830_private.gtt_entries) {
-               printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
-                               pg_start,intel_i830_private.gtt_entries);
+       if (pg_start < intel_private.gtt_entries) {
+               printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+                               pg_start,intel_private.gtt_entries);
 
                printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
                goto out_err;
@@ -805,10 +844,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
-                       mem->memory[i], mask_type), intel_i830_private.gtt+j);
+                       mem->memory[i], mask_type), intel_private.gtt+j);
        }
 
-       readl(intel_i830_private.gtt+j-1);
+       readl(intel_private.gtt+j-1);
        agp_bridge->driver->tlb_flush(mem);
 
  out:
@@ -826,15 +865,15 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
        if (mem->page_count == 0)
                return 0;
 
-       if (pg_start < intel_i830_private.gtt_entries) {
+       if (pg_start < intel_private.gtt_entries) {
                printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
                return -EINVAL;
        }
 
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-               writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+               writel(agp_bridge->scratch_page, intel_private.gtt+i);
        }
-       readl(intel_i830_private.gtt+i-1);
+       readl(intel_private.gtt+i-1);
 
        agp_bridge->driver->tlb_flush(mem);
        return 0;
@@ -850,7 +889,7 @@ static int intel_i9xx_fetch_size(void)
        int aper_size; /* size in megabytes */
        int i;
 
-       aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
+       aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1);
 
        for (i = 0; i < num_sizes; i++) {
                if (aper_size == intel_i830_sizes[i].size) {
@@ -878,20 +917,20 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
        num_entries = size->num_entries;
        agp_bridge->gatt_table_real = NULL;
 
-       pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
-       pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
+       pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
+       pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
 
-       intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
-       if (!intel_i830_private.gtt)
+       intel_private.gtt = ioremap(temp2, 256 * 1024);
+       if (!intel_private.gtt)
                return -ENOMEM;
 
        temp &= 0xfff80000;
 
-       intel_i830_private.registers = ioremap(temp,128 * 4096);
-       if (!intel_i830_private.registers)
+       intel_private.registers = ioremap(temp,128 * 4096);
+       if (!intel_private.registers)
                return -ENOMEM;
 
-       temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+       temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
        global_cache_flush();   /* FIXME: ? */
 
        /* we have to call this as early as possible after the MMIO base address is known */
@@ -938,20 +977,20 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
        num_entries = size->num_entries;
        agp_bridge->gatt_table_real = NULL;
 
-       pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
+       pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
 
        temp &= 0xfff00000;
-       intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
+       intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
 
-       if (!intel_i830_private.gtt)
+       if (!intel_private.gtt)
                return -ENOMEM;
 
 
-       intel_i830_private.registers = ioremap(temp,128 * 4096);
-       if (!intel_i830_private.registers)
+       intel_private.registers = ioremap(temp,128 * 4096);
+       if (!intel_private.registers)
                return -ENOMEM;
 
-       temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+       temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
        global_cache_flush();   /* FIXME: ? */
 
        /* we have to call this as early as possible after the MMIO base address is known */
@@ -1722,41 +1761,126 @@ static const struct agp_bridge_driver intel_7505_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static int find_i810(u16 device)
-{
-       struct pci_dev *i810_dev;
-
-       i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
-       if (!i810_dev)
-               return 0;
-       intel_i810_private.i810_dev = i810_dev;
-       return 1;
-}
+static const struct agp_bridge_driver intel_g33_driver = {
+       .owner                  = THIS_MODULE,
+       .aperture_sizes         = intel_i830_sizes,
+       .size_type              = FIXED_APER_SIZE,
+       .num_aperture_sizes     = 4,
+       .needs_scratch_page     = TRUE,
+       .configure              = intel_i915_configure,
+       .fetch_size             = intel_i9xx_fetch_size,
+       .cleanup                = intel_i915_cleanup,
+       .tlb_flush              = intel_i810_tlbflush,
+       .mask_memory            = intel_i965_mask_memory,
+       .masks                  = intel_i810_masks,
+       .agp_enable             = intel_i810_agp_enable,
+       .cache_flush            = global_cache_flush,
+       .create_gatt_table      = intel_i915_create_gatt_table,
+       .free_gatt_table        = intel_i830_free_gatt_table,
+       .insert_memory          = intel_i915_insert_entries,
+       .remove_memory          = intel_i915_remove_entries,
+       .alloc_by_type          = intel_i830_alloc_by_type,
+       .free_by_type           = intel_i810_free_by_type,
+       .agp_alloc_page         = agp_generic_alloc_page,
+       .agp_destroy_page       = agp_generic_destroy_page,
+       .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
+};
 
-static int find_i830(u16 device)
+static int find_gmch(u16 device)
 {
-       struct pci_dev *i830_dev;
+       struct pci_dev *gmch_device;
 
-       i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
-       if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
-               i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
-                               device, i830_dev);
+       gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
+       if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
+               gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                device, gmch_device);
        }
 
-       if (!i830_dev)
+       if (!gmch_device)
                return 0;
 
-       intel_i830_private.i830_dev = i830_dev;
+       intel_private.pcidev = gmch_device;
        return 1;
 }
 
+/* Table to describe Intel GMCH and AGP/PCIE GART drivers.  At least one of
+ * driver and gmch_driver must be non-null, and find_gmch will determine
+ * which one should be used if a gmch_chip_id is present.
+ */
+static const struct intel_driver_description {
+       unsigned int chip_id;
+       unsigned int gmch_chip_id;
+       char *name;
+       const struct agp_bridge_driver *driver;
+       const struct agp_bridge_driver *gmch_driver;
+} intel_agp_chipsets[] = {
+       { PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810",
+               NULL, &intel_810_driver },
+       { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810",
+               NULL, &intel_810_driver },
+       { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810",
+               NULL, &intel_810_driver },
+       { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815",
+               &intel_810_driver, &intel_815_driver },
+       { PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M",
+               &intel_830mp_driver, &intel_830_driver },
+       { PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M",
+               &intel_845_driver, &intel_830_driver },
+       { PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM",
+               &intel_845_driver, &intel_830_driver },
+       { PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865",
+               &intel_845_driver, &intel_830_driver },
+       { PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G",
+               &intel_845_driver, &intel_915_driver },
+       { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM",
+               &intel_845_driver, &intel_915_driver },
+       { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G",
+               &intel_845_driver, &intel_915_driver },
+       { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM",
+               &intel_845_driver, &intel_915_driver },
+       { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME",
+               &intel_845_driver, &intel_915_driver },
+       { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, "965G",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE",
+               &intel_845_driver, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL },
+       { PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, "G33",
+               &intel_845_driver, &intel_g33_driver },
+       { PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, "Q35",
+               &intel_845_driver, &intel_g33_driver },
+       { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, "Q33",
+               &intel_845_driver, &intel_g33_driver },
+       { 0, 0, NULL, NULL, NULL }
+};
+
 static int __devinit agp_intel_probe(struct pci_dev *pdev,
                                     const struct pci_device_id *ent)
 {
        struct agp_bridge_data *bridge;
-       char *name = "(unknown)";
        u8 cap_ptr = 0;
        struct resource *r;
+       int i;
 
        cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 
@@ -1764,195 +1888,42 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
        if (!bridge)
                return -ENOMEM;
 
-       switch (pdev->device) {
-       case PCI_DEVICE_ID_INTEL_82443LX_0:
-               bridge->driver = &intel_generic_driver;
-               name = "440LX";
-               break;
-       case PCI_DEVICE_ID_INTEL_82443BX_0:
-               bridge->driver = &intel_generic_driver;
-               name = "440BX";
-               break;
-       case PCI_DEVICE_ID_INTEL_82443GX_0:
-               bridge->driver = &intel_generic_driver;
-               name = "440GX";
-               break;
-       case PCI_DEVICE_ID_INTEL_82810_MC1:
-               name = "i810";
-               if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
-                       goto fail;
-               bridge->driver = &intel_810_driver;
-               break;
-       case PCI_DEVICE_ID_INTEL_82810_MC3:
-               name = "i810 DC100";
-               if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
-                       goto fail;
-               bridge->driver = &intel_810_driver;
-               break;
-       case PCI_DEVICE_ID_INTEL_82810E_MC:
-               name = "i810 E";
-               if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
-                       goto fail;
-               bridge->driver = &intel_810_driver;
-               break;
-        case PCI_DEVICE_ID_INTEL_82815_MC:
-               /*
-                * The i815 can operate either as an i810 style
-                * integrated device, or as an AGP4X motherboard.
-                */
-               if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
-                       bridge->driver = &intel_810_driver;
-               else
-                       bridge->driver = &intel_815_driver;
-               name = "i815";
-               break;
-       case PCI_DEVICE_ID_INTEL_82820_HB:
-       case PCI_DEVICE_ID_INTEL_82820_UP_HB:
-               bridge->driver = &intel_820_driver;
-               name = "i820";
-               break;
-       case PCI_DEVICE_ID_INTEL_82830_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
-                       bridge->driver = &intel_830_driver;
-               else
-                       bridge->driver = &intel_830mp_driver;
-               name = "830M";
-               break;
-       case PCI_DEVICE_ID_INTEL_82840_HB:
-               bridge->driver = &intel_840_driver;
-               name = "i840";
-               break;
-       case PCI_DEVICE_ID_INTEL_82845_HB:
-               bridge->driver = &intel_845_driver;
-               name = "i845";
-               break;
-       case PCI_DEVICE_ID_INTEL_82845G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
-                       bridge->driver = &intel_830_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "845G";
-               break;
-       case PCI_DEVICE_ID_INTEL_82850_HB:
-               bridge->driver = &intel_850_driver;
-               name = "i850";
-               break;
-       case PCI_DEVICE_ID_INTEL_82855PM_HB:
-               bridge->driver = &intel_845_driver;
-               name = "855PM";
-               break;
-       case PCI_DEVICE_ID_INTEL_82855GM_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
-                       bridge->driver = &intel_830_driver;
-                       name = "855";
-               } else {
-                       bridge->driver = &intel_845_driver;
-                       name = "855GM";
-               }
-               break;
-       case PCI_DEVICE_ID_INTEL_82860_HB:
-               bridge->driver = &intel_860_driver;
-               name = "i860";
-               break;
-       case PCI_DEVICE_ID_INTEL_82865_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
-                       bridge->driver = &intel_830_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "865";
-               break;
-       case PCI_DEVICE_ID_INTEL_82875_HB:
-               bridge->driver = &intel_845_driver;
-               name = "i875";
-               break;
-       case PCI_DEVICE_ID_INTEL_82915G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
-                       bridge->driver = &intel_915_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "915G";
-               break;
-       case PCI_DEVICE_ID_INTEL_82915GM_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
-                       bridge->driver = &intel_915_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "915GM";
-               break;
-       case PCI_DEVICE_ID_INTEL_82945G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
-                       bridge->driver = &intel_915_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "945G";
-               break;
-       case PCI_DEVICE_ID_INTEL_82945GM_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
-                       bridge->driver = &intel_915_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "945GM";
-               break;
-       case PCI_DEVICE_ID_INTEL_82946GZ_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
-                       bridge->driver = &intel_i965_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "946GZ";
-               break;
-       case PCI_DEVICE_ID_INTEL_82965G_1_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
-                       bridge->driver = &intel_i965_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "965G";
-               break;
-       case PCI_DEVICE_ID_INTEL_82965Q_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
-                       bridge->driver = &intel_i965_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "965Q";
-               break;
-       case PCI_DEVICE_ID_INTEL_82965G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
-                       bridge->driver = &intel_i965_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "965G";
-               break;
-       case PCI_DEVICE_ID_INTEL_82965GM_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
-                       bridge->driver = &intel_i965_driver;
-               else
-                       bridge->driver = &intel_845_driver;
-               name = "965GM";
-               break;
-       case PCI_DEVICE_ID_INTEL_7505_0:
-               bridge->driver = &intel_7505_driver;
-               name = "E7505";
-               break;
-       case PCI_DEVICE_ID_INTEL_7205_0:
-               bridge->driver = &intel_7505_driver;
-               name = "E7205";
-               break;
-       default:
+       for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
+               /* In case that multiple models of gfx chip may
+                  stand on same host bridge type, this can be
+                  sure we detect the right IGD. */
+               if ((pdev->device == intel_agp_chipsets[i].chip_id) &&
+                       ((intel_agp_chipsets[i].gmch_chip_id == 0) ||
+                               find_gmch(intel_agp_chipsets[i].gmch_chip_id)))
+                       break;
+       }
+
+       if (intel_agp_chipsets[i].name == NULL) {
                if (cap_ptr)
-                       printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
-                           pdev->device);
+                       printk(KERN_WARNING PFX "Unsupported Intel chipset"
+                               "(device id: %04x)\n", pdev->device);
                agp_put_bridge(bridge);
                return -ENODEV;
-       };
+       }
+
+       if (intel_agp_chipsets[i].gmch_chip_id != 0)
+           bridge->driver = intel_agp_chipsets[i].gmch_driver;
+       else
+           bridge->driver = intel_agp_chipsets[i].driver;
+
+       if (bridge->driver == NULL) {
+               printk(KERN_WARNING PFX "Failed to find bridge device "
+                       "(chip_id: %04x)\n", intel_agp_chipsets[i].gmch_chip_id);
+               agp_put_bridge(bridge);
+               return -ENODEV;
+        }
 
        bridge->dev = pdev;
        bridge->capndx = cap_ptr;
+       bridge->dev_private_data = &intel_private;
 
-       if (bridge->driver == &intel_810_driver)
-               bridge->dev_private_data = &intel_i810_private;
-       else if (bridge->driver == &intel_830_driver)
-               bridge->dev_private_data = &intel_i830_private;
-
-       printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
+       printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n",
+               intel_agp_chipsets[i].name);
 
        /*
        * The following fixes the case where the BIOS has "forgotten" to
@@ -1988,12 +1959,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, bridge);
        return agp_add_bridge(bridge);
-
-fail:
-       printk(KERN_ERR PFX "Detected an Intel %s chipset, "
-               "but could not find the secondary device.\n", name);
-       agp_put_bridge(bridge);
-       return -ENODEV;
 }
 
 static void __devexit agp_intel_remove(struct pci_dev *pdev)
@@ -2002,10 +1967,8 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
 
        agp_remove_bridge(bridge);
 
-       if (intel_i810_private.i810_dev)
-               pci_dev_put(intel_i810_private.i810_dev);
-       if (intel_i830_private.i830_dev)
-               pci_dev_put(intel_i830_private.i830_dev);
+       if (intel_private.pcidev)
+               pci_dev_put(intel_private.pcidev);
 
        agp_put_bridge(bridge);
 }
@@ -2021,10 +1984,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
         * as host bridge (00:00) resumes before graphics device (02:00),
         * then our access to its pci space can work right.
         */
-       if (intel_i810_private.i810_dev)
-               pci_restore_state(intel_i810_private.i810_dev);
-       if (intel_i830_private.i830_dev)
-               pci_restore_state(intel_i830_private.i830_dev);
+       if (intel_private.pcidev)
+               pci_restore_state(intel_private.pcidev);
 
        if (bridge->driver == &intel_generic_driver)
                intel_configure();
@@ -2087,6 +2048,9 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
        ID(PCI_DEVICE_ID_INTEL_82965G_HB),
        ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
+       ID(PCI_DEVICE_ID_INTEL_G33_HB),
+       ID(PCI_DEVICE_ID_INTEL_Q35_HB),
+       ID(PCI_DEVICE_ID_INTEL_Q33_HB),
        { }
 };
 
index c72ee97d3892543f6e8d2ebd053657776bba49dc..ca376b92162c293fe3508852971305b14538b528 100644 (file)
@@ -1061,6 +1061,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
 
                                if (data & info->ignore_status_mask) {
                                        info->icount.rx++;
+                                       spin_unlock(&cinfo->card_lock);
                                        return;
                                }
                                if (tty_buffer_request_room(tty, 1)) {
index ef833a1c27eb1c60a49eca9566f8d987add2d262..0b7ffa5191c64e3c22433e3303c841265cc20a0d 100644 (file)
@@ -6,7 +6,7 @@
 #
 config DRM
        tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-       depends on (AGP || AGP=n) && PCI
+       depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
        help
          Kernel-level support for the Direct Rendering Infrastructure (DRI)
          introduced in XFree86 4.0. If you say Y here, you need to select
index de37d5f7456357867965e0881e262a1cdbab7cad..b33313be25477dc3689d9253c1792e4b46164dd9 100644 (file)
@@ -172,38 +172,49 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
 
                bitfield_length = idx + 1;
 
-               if (idx != id / (8 * sizeof(*bitfield)))
-                       bitfield = drm_alloc(bitfield_length *
-                                            sizeof(*bitfield), DRM_MEM_BUFS);
+               bitfield = NULL;
 
-               if (!bitfield && bitfield_length) {
-                       bitfield = dev->drw_bitfield;
-                       bitfield_length = dev->drw_bitfield_length;
+               if (bitfield_length) {
+                       if (bitfield_length != dev->drw_bitfield_length)
+                               bitfield = drm_alloc(bitfield_length *
+                                                    sizeof(*bitfield),
+                                                    DRM_MEM_BUFS);
+
+                       if (!bitfield) {
+                               bitfield = dev->drw_bitfield;
+                               bitfield_length = dev->drw_bitfield_length;
+                       }
                }
        }
 
        if (bitfield != dev->drw_bitfield) {
                info_length = 8 * sizeof(*bitfield) * bitfield_length;
 
-               info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS);
+               if (info_length) {
+                       info = drm_alloc(info_length * sizeof(*info),
+                                        DRM_MEM_BUFS);
 
-               if (!info && info_length) {
-                       info = dev->drw_info;
-                       info_length = dev->drw_info_length;
-               }
+                       if (!info) {
+                               info = dev->drw_info;
+                               info_length = dev->drw_info_length;
+                       }
+               } else
+                       info = NULL;
 
                spin_lock_irqsave(&dev->drw_lock, irqflags);
 
-               memcpy(bitfield, dev->drw_bitfield, bitfield_length *
-                      sizeof(*bitfield));
+               if (bitfield)
+                       memcpy(bitfield, dev->drw_bitfield, bitfield_length *
+                              sizeof(*bitfield));
                drm_free(dev->drw_bitfield, sizeof(*bitfield) *
                         dev->drw_bitfield_length, DRM_MEM_BUFS);
                dev->drw_bitfield = bitfield;
                dev->drw_bitfield_length = bitfield_length;
 
                if (info != dev->drw_info) {
-                       memcpy(info, dev->drw_info, info_length *
-                              sizeof(*info));
+                       if (info)
+                               memcpy(info, dev->drw_info, info_length *
+                                      sizeof(*info));
                        drm_free(dev->drw_info, sizeof(*info) *
                                 dev->drw_info_length, DRM_MEM_BUFS);
                        dev->drw_info = info;
index 31cdde83713b4e44c576424edcafb113b7b9652d..177ccc07f96821d02a305f29d7a499405e109d7f 100644 (file)
        {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
        {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+       {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+       {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
index 78c1ae28f17cd65f1441609359aea708f7149394..b92062a239f1a8c0d92e60405af0eeccdfa59a85 100644 (file)
@@ -582,7 +582,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-       dev_priv->swaps_lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&dev_priv->swaps_lock);
        INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
        dev_priv->swaps_pending = 0;
 
index b3d4ccc33a47e777d1a391ae9a85bde2f450051e..154f42203b0569c4f53c306376c6720e73cfa33d 100644 (file)
@@ -1191,6 +1191,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
                            is_current_pgrp_orphaned())
                                return -EIO;
                        kill_pgrp(task_pgrp(current), SIGTTIN, 1);
+                       set_thread_flag(TIF_SIGPENDING);
                        return -ERESTARTSYS;
                }
        }
index 46c1b97748b6bab76c58fe5aeed784c62c49fcc3..0474cac4a84ed882e4bb92d825beb1afcb6db69f 100644 (file)
@@ -760,7 +760,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
 
 static void extract_buf(struct entropy_store *r, __u8 *out)
 {
-       int i, x;
+       int i;
        __u32 data[16], buf[5 + SHA_WORKSPACE_WORDS];
 
        sha_init(buf);
@@ -772,9 +772,11 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
         * attempts to find previous ouputs), unless the hash
         * function can be inverted.
         */
-       for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
-               sha_transform(buf, (__u8 *)r->pool+i, buf + 5);
-               add_entropy_words(r, &buf[x % 5], 1);
+       for (i = 0; i < r->poolinfo->poolwords; i += 16) {
+               /* hash blocks of 16 words = 512 bits */
+               sha_transform(buf, (__u8 *)(r->pool + i), buf + 5);
+               /* feed back portion of the resulting hash */
+               add_entropy_words(r, &buf[i % 5], 1);
        }
 
        /*
@@ -782,7 +784,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
         * portion of the pool while mixing, and hash one
         * final time.
         */
-       __add_entropy_words(r, &buf[x % 5], 1, data);
+       __add_entropy_words(r, &buf[i % 5], 1, data);
        sha_transform(buf, (__u8 *)data, buf + 5);
 
        /*
@@ -1018,37 +1020,44 @@ random_poll(struct file *file, poll_table * wait)
        return mask;
 }
 
-static ssize_t
-random_write(struct file * file, const char __user * buffer,
-            size_t count, loff_t *ppos)
+static int
+write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
 {
-       int ret = 0;
        size_t bytes;
        __u32 buf[16];
        const char __user *p = buffer;
-       size_t c = count;
 
-       while (c > 0) {
-               bytes = min(c, sizeof(buf));
+       while (count > 0) {
+               bytes = min(count, sizeof(buf));
+               if (copy_from_user(&buf, p, bytes))
+                       return -EFAULT;
 
-               bytes -= copy_from_user(&buf, p, bytes);
-               if (!bytes) {
-                       ret = -EFAULT;
-                       break;
-               }
-               c -= bytes;
+               count -= bytes;
                p += bytes;
 
-               add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
-       }
-       if (p == buffer) {
-               return (ssize_t)ret;
-       } else {
-               struct inode *inode = file->f_path.dentry->d_inode;
-               inode->i_mtime = current_fs_time(inode->i_sb);
-               mark_inode_dirty(inode);
-               return (ssize_t)(p - buffer);
+               add_entropy_words(r, buf, (bytes + 3) / 4);
        }
+
+       return 0;
+}
+
+static ssize_t
+random_write(struct file * file, const char __user * buffer,
+            size_t count, loff_t *ppos)
+{
+       size_t ret;
+       struct inode *inode = file->f_path.dentry->d_inode;
+
+       ret = write_pool(&blocking_pool, buffer, count);
+       if (ret)
+               return ret;
+       ret = write_pool(&nonblocking_pool, buffer, count);
+       if (ret)
+               return ret;
+
+       inode->i_mtime = current_fs_time(inode->i_sb);
+       mark_inode_dirty(inode);
+       return (ssize_t)count;
 }
 
 static int
@@ -1087,8 +1096,8 @@ random_ioctl(struct inode * inode, struct file * file,
                        return -EINVAL;
                if (get_user(size, p++))
                        return -EFAULT;
-               retval = random_write(file, (const char __user *) p,
-                                     size, &file->f_pos);
+               retval = write_pool(&input_pool, (const char __user *)p,
+                                   size);
                if (retval < 0)
                        return retval;
                credit_entropy_store(&input_pool, ent_count);
index e45113a7a472f7f1035d3fd92b2909b237bd298b..45bf2a262a858c144c74388f271bfb13cb4e9b9a 100644 (file)
@@ -2172,11 +2172,12 @@ static int __devinit stl_initech(struct stlbrd *brdp)
                }
                status = inb(ioaddr + ECH_PNLSTATUS);
                if ((status & ECH_PNLIDMASK) != nxtid)
-                       goto err_fr;
+                       break;
                panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL);
                if (!panelp) {
                        printk("STALLION: failed to allocate memory "
                                "(size=%Zd)\n", sizeof(struct stlpanel));
+                       retval = -ENOMEM;
                        goto err_fr;
                }
                panelp->magic = STL_PANELMAGIC;
@@ -2223,8 +2224,10 @@ static int __devinit stl_initech(struct stlbrd *brdp)
                brdp->nrports += panelp->nrports;
                brdp->panels[panelnr++] = panelp;
                if ((brdp->brdtype != BRD_ECHPCI) &&
-                   (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
+                   (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) {
+                       retval = -EINVAL;
                        goto err_fr;
+               }
        }
 
        brdp->nrpanels = panelnr;
@@ -2371,6 +2374,7 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
                dev_err(&pdev->dev, "too many boards found, "
                        "maximum supported %d\n", STL_MAXBRDS);
                mutex_unlock(&stl_brdslock);
+               retval = -ENODEV;
                goto err_fr;
        }
        brdp->brdnr = (unsigned int)brdnr;
@@ -4710,6 +4714,29 @@ static int __init stallion_module_init(void)
        spin_lock_init(&stallion_lock);
        spin_lock_init(&brd_lock);
 
+       stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
+       if (!stl_serial) {
+               retval = -ENOMEM;
+               goto err;
+       }
+
+       stl_serial->owner = THIS_MODULE;
+       stl_serial->driver_name = stl_drvname;
+       stl_serial->name = "ttyE";
+       stl_serial->major = STL_SERIALMAJOR;
+       stl_serial->minor_start = 0;
+       stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
+       stl_serial->subtype = SERIAL_TYPE_NORMAL;
+       stl_serial->init_termios = stl_deftermios;
+       stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       tty_set_operations(stl_serial, &stl_ops);
+
+       retval = tty_register_driver(stl_serial);
+       if (retval) {
+               printk("STALLION: failed to register serial driver\n");
+               goto err_frtty;
+       }
+
 /*
  *     Find any dynamically supported boards. That is via module load
  *     line options.
@@ -4739,13 +4766,9 @@ static int __init stallion_module_init(void)
 
        /* this has to be _after_ isa finding because of locking */
        retval = pci_register_driver(&stl_pcidriver);
-       if (retval && stl_nrbrds == 0)
-               goto err;
-
-       stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
-       if (!stl_serial) {
-               retval = -ENOMEM;
-               goto err_pcidr;
+       if (retval && stl_nrbrds == 0) {
+               printk(KERN_ERR "STALLION: can't register pci driver\n");
+               goto err_unrtty;
        }
 
 /*
@@ -4756,43 +4779,18 @@ static int __init stallion_module_init(void)
                printk("STALLION: failed to register serial board device\n");
 
        stallion_class = class_create(THIS_MODULE, "staliomem");
-       if (IS_ERR(stallion_class)) {
-               retval = PTR_ERR(stallion_class);
-               goto err_reg;
-       }
+       if (IS_ERR(stallion_class))
+               printk("STALLION: failed to create class\n");
        for (i = 0; i < 4; i++)
                class_device_create(stallion_class, NULL,
                                    MKDEV(STL_SIOMEMMAJOR, i), NULL,
                                    "staliomem%d", i);
 
-       stl_serial->owner = THIS_MODULE;
-       stl_serial->driver_name = stl_drvname;
-       stl_serial->name = "ttyE";
-       stl_serial->major = STL_SERIALMAJOR;
-       stl_serial->minor_start = 0;
-       stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
-       stl_serial->subtype = SERIAL_TYPE_NORMAL;
-       stl_serial->init_termios = stl_deftermios;
-       stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
-       tty_set_operations(stl_serial, &stl_ops);
-
-       retval = tty_register_driver(stl_serial);
-       if (retval) {
-               printk("STALLION: failed to register serial driver\n");
-               goto err_clsdev;
-       }
-
        return 0;
-err_clsdev:
-       for (i = 0; i < 4; i++)
-               class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-       class_destroy(stallion_class);
-err_reg:
-       unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
+err_unrtty:
+       tty_unregister_driver(stl_serial);
+err_frtty:
        put_tty_driver(stl_serial);
-err_pcidr:
-       pci_unregister_driver(&stl_pcidriver);
-       stl_free_isabrds();
 err:
        return retval;
 }
@@ -4821,8 +4819,6 @@ static void __exit stallion_module_exit(void)
                        tty_unregister_device(stl_serial,
                                brdp->brdnr * STL_MAXPORTS + j);
        }
-       tty_unregister_driver(stl_serial);
-       put_tty_driver(stl_serial);
 
        for (i = 0; i < 4; i++)
                class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
@@ -4834,6 +4830,9 @@ static void __exit stallion_module_exit(void)
        pci_unregister_driver(&stl_pcidriver);
 
        stl_free_isabrds();
+
+       tty_unregister_driver(stl_serial);
+       put_tty_driver(stl_serial);
 }
 
 module_init(stallion_module_init);
index 75d2a46e106fedf09630958ca24c1bf2909a25ad..3752edc30c366c7940812fb25c2569c7f88d3b79 100644 (file)
@@ -1148,7 +1148,8 @@ int tty_check_change(struct tty_struct * tty)
                return 0;
        if (is_current_pgrp_orphaned())
                return -EIO;
-       (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
+       kill_pgrp(task_pgrp(current), SIGTTOU, 1);
+       set_thread_flag(TIF_SIGPENDING);
        return -ERESTARTSYS;
 }
 
index 1cad32c62ed34493a220a703e0780400ad229f62..53f5538c0c05e69d056f7cbf8c48c57f1e821074 100644 (file)
@@ -115,6 +115,13 @@ config IXP4XX_WATCHDOG
 
          Say N if you are unsure.
 
+config KS8695_WATCHDOG
+       tristate "KS8695 watchdog"
+       depends on ARCH_KS8695
+       help
+         Watchdog timer embedded into KS8695 processor. This will reboot your
+         system when the timeout is reached.
+
 config S3C2410_WATCHDOG
        tristate "S3C2410 Watchdog"
        depends on ARCH_S3C2410
index 8bfc00cc7c2bc58a8b84ef9ac15ebb7c1df2dd60..d90f649038c2bc7d87626e274affb8942c740ce3 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
 obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
 obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
+obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
 obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
index fd955dbd588cb75b5be420e24a644ffcedb6040e..dc7548dcaf3539cb0ae656fc49009e6927908e9b 100644 (file)
@@ -205,7 +205,7 @@ static void __exit ixp2000_wdt_exit(void)
 module_init(ixp2000_wdt_init);
 module_exit(ixp2000_wdt_exit);
 
-MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net">);
+MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
 MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog");
 
 module_param(heartbeat, int, 0);
diff --git a/drivers/char/watchdog/ks8695_wdt.c b/drivers/char/watchdog/ks8695_wdt.c
new file mode 100644 (file)
index 0000000..7150fb9
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Watchdog driver for Kendin/Micrel KS8695.
+ *
+ * (C) 2007 Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/arch/regs-timer.h>
+
+
+#define WDT_DEFAULT_TIME       5       /* seconds */
+#define WDT_MAX_TIME           171     /* seconds */
+
+static int wdt_time = WDT_DEFAULT_TIME;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_time, int, 0);
+MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+#endif
+
+
+static unsigned long ks8695wdt_busy;
+
+/* ......................................................................... */
+
+/*
+ * Disable the watchdog.
+ */
+static void inline ks8695_wdt_stop(void)
+{
+       unsigned long tmcon;
+
+       /* disable timer0 */
+       tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+       __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Enable and reset the watchdog.
+ */
+static void inline ks8695_wdt_start(void)
+{
+       unsigned long tmcon;
+       unsigned long tval = wdt_time * CLOCK_TICK_RATE;
+
+       /* disable timer0 */
+       tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+       __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+
+       /* program timer0 */
+       __raw_writel(tval | T0TC_WATCHDOG, KS8695_TMR_VA + KS8695_T0TC);
+
+       /* re-enable timer0 */
+       tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+       __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Reload the watchdog timer.  (ie, pat the watchdog)
+ */
+static void inline ks8695_wdt_reload(void)
+{
+       unsigned long tmcon;
+
+       /* disable, then re-enable timer0 */
+       tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+       __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+       __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Change the watchdog time interval.
+ */
+static int ks8695_wdt_settimeout(int new_time)
+{
+       /*
+        * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
+        *
+        * Since WDV is a 16-bit counter, the maximum period is
+        * 65536 / 0.256 = 256 seconds.
+        */
+       if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
+               return -EINVAL;
+
+       /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */
+       wdt_time = new_time;
+       return 0;
+}
+
+/* ......................................................................... */
+
+/*
+ * Watchdog device is opened, and watchdog starts running.
+ */
+static int ks8695_wdt_open(struct inode *inode, struct file *file)
+{
+       if (test_and_set_bit(0, &ks8695wdt_busy))
+               return -EBUSY;
+
+       ks8695_wdt_start();
+       return nonseekable_open(inode, file);
+}
+
+/*
+ * Close the watchdog device.
+ * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also
+ *  disabled.
+ */
+static int ks8695_wdt_close(struct inode *inode, struct file *file)
+{
+       if (!nowayout)
+               ks8695_wdt_stop();      /* Disable the watchdog when file is closed */
+
+       clear_bit(0, &ks8695wdt_busy);
+       return 0;
+}
+
+static struct watchdog_info ks8695_wdt_info = {
+       .identity       = "ks8695 watchdog",
+       .options        = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+};
+
+/*
+ * Handle commands from user-space.
+ */
+static int ks8695_wdt_ioctl(struct inode *inode, struct file *file,
+               unsigned int cmd, unsigned long arg)
+{
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
+       int new_value;
+
+       switch(cmd) {
+               case WDIOC_KEEPALIVE:
+                       ks8695_wdt_reload();    /* pat the watchdog */
+                       return 0;
+
+               case WDIOC_GETSUPPORT:
+                       return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0;
+
+               case WDIOC_SETTIMEOUT:
+                       if (get_user(new_value, p))
+                               return -EFAULT;
+
+                       if (ks8695_wdt_settimeout(new_value))
+                               return -EINVAL;
+
+                       /* Enable new time value */
+                       ks8695_wdt_start();
+
+                       /* Return current value */
+                       return put_user(wdt_time, p);
+
+               case WDIOC_GETTIMEOUT:
+                       return put_user(wdt_time, p);
+
+               case WDIOC_GETSTATUS:
+               case WDIOC_GETBOOTSTATUS:
+                       return put_user(0, p);
+
+               case WDIOC_SETOPTIONS:
+                       if (get_user(new_value, p))
+                               return -EFAULT;
+
+                       if (new_value & WDIOS_DISABLECARD)
+                               ks8695_wdt_stop();
+                       if (new_value & WDIOS_ENABLECARD)
+                               ks8695_wdt_start();
+                       return 0;
+
+               default:
+                       return -ENOTTY;
+       }
+}
+
+/*
+ * Pat the watchdog whenever device is written to.
+ */
+static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+       ks8695_wdt_reload();            /* pat the watchdog */
+       return len;
+}
+
+/* ......................................................................... */
+
+static const struct file_operations ks8695wdt_fops = {
+       .owner          = THIS_MODULE,
+       .llseek         = no_llseek,
+       .ioctl          = ks8695_wdt_ioctl,
+       .open           = ks8695_wdt_open,
+       .release        = ks8695_wdt_close,
+       .write          = ks8695_wdt_write,
+};
+
+static struct miscdevice ks8695wdt_miscdev = {
+       .minor          = WATCHDOG_MINOR,
+       .name           = "watchdog",
+       .fops           = &ks8695wdt_fops,
+};
+
+static int __init ks8695wdt_probe(struct platform_device *pdev)
+{
+       int res;
+
+       if (ks8695wdt_miscdev.parent)
+               return -EBUSY;
+       ks8695wdt_miscdev.parent = &pdev->dev;
+
+       res = misc_register(&ks8695wdt_miscdev);
+       if (res)
+               return res;
+
+       printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : "");
+       return 0;
+}
+
+static int __exit ks8695wdt_remove(struct platform_device *pdev)
+{
+       int res;
+
+       res = misc_deregister(&ks8695wdt_miscdev);
+       if (!res)
+               ks8695wdt_miscdev.parent = NULL;
+
+       return res;
+}
+
+static void ks8695wdt_shutdown(struct platform_device *pdev)
+{
+       ks8695_wdt_stop();
+}
+
+#ifdef CONFIG_PM
+
+static int ks8695wdt_suspend(struct platform_device *pdev, pm_message_t message)
+{
+       ks8695_wdt_stop();
+       return 0;
+}
+
+static int ks8695wdt_resume(struct platform_device *pdev)
+{
+       if (ks8695wdt_busy)
+               ks8695_wdt_start();
+       return 0;
+}
+
+#else
+#define ks8695wdt_suspend NULL
+#define ks8695wdt_resume       NULL
+#endif
+
+static struct platform_driver ks8695wdt_driver = {
+       .probe          = ks8695wdt_probe,
+       .remove         = __exit_p(ks8695wdt_remove),
+       .shutdown       = ks8695wdt_shutdown,
+       .suspend        = ks8695wdt_suspend,
+       .resume         = ks8695wdt_resume,
+       .driver         = {
+               .name   = "ks8695_wdt",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init ks8695_wdt_init(void)
+{
+       /* Check that the heartbeat value is within range; if not reset to the default */
+       if (ks8695_wdt_settimeout(wdt_time)) {
+               ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
+               pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME);
+       }
+
+       return platform_driver_register(&ks8695wdt_driver);
+}
+
+static void __exit ks8695_wdt_exit(void)
+{
+       platform_driver_unregister(&ks8695wdt_driver);
+}
+
+module_init(ks8695_wdt_init);
+module_exit(ks8695_wdt_exit);
+
+MODULE_AUTHOR("Andrew Victor");
+MODULE_DESCRIPTION("Watchdog driver for KS8695");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index 6d3840e629de550c0b3de37a2090788cb6180351..6a86958b577f974bc423fbc22d48131c2ee79ecd 100644 (file)
@@ -102,10 +102,15 @@ geode_aes_crypt(struct geode_aes_op *op)
        u32 flags = 0;
        unsigned long iflags;
 
-       if (op->len == 0 || op->src == op->dst)
+       if (op->len == 0)
                return 0;
 
-       if (op->flags & AES_FLAGS_COHERENT)
+       /* If the source and destination is the same, then
+        * we need to turn on the coherent flags, otherwise
+        * we don't need to worry
+        */
+
+       if (op->src == op->dst)
                flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
 
        if (op->dir == AES_DIR_ENCRYPT)
@@ -120,7 +125,7 @@ geode_aes_crypt(struct geode_aes_op *op)
                _writefield(AES_WRITEIV0_REG, op->iv);
        }
 
-       if (op->flags & AES_FLAGS_USRKEY) {
+       if (!(op->flags & AES_FLAGS_HIDDENKEY)) {
                flags |= AES_CTRL_WRKEY;
                _writefield(AES_WRITEKEY0_REG, op->key);
        }
@@ -289,6 +294,7 @@ static struct crypto_alg geode_cbc_alg = {
                        .setkey                 =       geode_setkey,
                        .encrypt                =       geode_cbc_encrypt,
                        .decrypt                =       geode_cbc_decrypt,
+                       .ivsize                 =       AES_IV_LENGTH,
                }
        }
 };
index 8003a36f3a83de6a37e2d45d5b21dd059f992366..f47968671ae7cfede80dacbfbda8c1b236014d75 100644 (file)
@@ -20,8 +20,7 @@
 #define AES_DIR_DECRYPT 0
 #define AES_DIR_ENCRYPT 1
 
-#define AES_FLAGS_USRKEY   (1 << 0)
-#define AES_FLAGS_COHERENT (1 << 1)
+#define AES_FLAGS_HIDDENKEY (1 << 0)
 
 struct geode_aes_op {
 
index 5932c72f9e424a1ad76a4c6f56f15e10709af855..396dade731f9177b6354f1bfd6edcc2bff5e0642 100644 (file)
@@ -18,7 +18,7 @@ config FIREWIRE
          your IEEE 1394 adapter.
 
          To compile this driver as a module, say M here: the module will be
-         called fw-core.
+         called firewire-core.
 
          This is the "JUJU" FireWire stack, an alternative implementation
          designed for robustness and simplicity.  You can build either this
@@ -34,11 +34,11 @@ config FIREWIRE_OHCI
          is the only chipset in use, so say Y here.
 
          To compile this driver as a module, say M here:  The module will be
-         called fw-ohci.
+         called firewire-ohci.
 
          If you also build ohci1394 of the classic IEEE 1394 driver stack,
-         blacklist either ohci1394 or fw-ohci to let hotplug load the desired
-         driver.
+         blacklist either ohci1394 or firewire-ohci to let hotplug load the
+         desired driver.
 
 config FIREWIRE_SBP2
        tristate "Support for storage devices (SBP-2 protocol driver)"
@@ -50,12 +50,12 @@ config FIREWIRE_SBP2
          like scanners.
 
          To compile this driver as a module, say M here:  The module will be
-         called fw-sbp2.
+         called firewire-sbp2.
 
          You should also enable support for disks, CD-ROMs, etc. in the SCSI
          configuration section.
 
          If you also build sbp2 of the classic IEEE 1394 driver stack,
-         blacklist either sbp2 or fw-sbp2 to let hotplug load the desired
-         driver.
+         blacklist either sbp2 or firewire-sbp2 to let hotplug load the
+         desired driver.
 
index fc7d59d4bce049946a331e726395cc5283ae312b..a7c31e9039c14c0912554ed981c1fa390ce7606d 100644 (file)
@@ -2,9 +2,11 @@
 # Makefile for the Linux IEEE 1394 implementation
 #
 
-fw-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
-       fw-device.o fw-cdev.o
+firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
+                   fw-device.o fw-cdev.o
+firewire-ohci-y += fw-ohci.o
+firewire-sbp2-y += fw-sbp2.o
 
-obj-$(CONFIG_FIREWIRE) += fw-core.o
-obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o
-obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o
+obj-$(CONFIG_FIREWIRE) += firewire-core.o
+obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
+obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o
index 636151a64add8405d22fe05405d23cbd67c99780..9eb1edacd825d3d4c4e5d345bfb9c869bef98aaa 100644 (file)
@@ -407,11 +407,6 @@ fw_card_add(struct fw_card *card,
        card->link_speed = link_speed;
        card->guid = guid;
 
-       /* Activate link_on bit and contender bit in our self ID packets.*/
-       if (card->driver->update_phy_reg(card, 4, 0,
-                                        PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
-               return -EIO;
-
        /*
         * The subsystem grabs a reference when the card is added and
         * drops it when the driver calls fw_core_remove_card.
index 0fa5bd54c6a18a4e1fd612c23fd11942f669fdc0..5d402d63799f377f165a05482e31e3150308935c 100644 (file)
@@ -365,7 +365,7 @@ complete_transaction(struct fw_card *card, int rcode,
                    response->response.data, response->response.length);
 }
 
-static ssize_t ioctl_send_request(struct client *client, void *buffer)
+static int ioctl_send_request(struct client *client, void *buffer)
 {
        struct fw_device *device = client->device;
        struct fw_cdev_send_request *request = buffer;
@@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
        return 0;
 }
 
+/* Macros for decoding the iso packet control header. */
+#define GET_PAYLOAD_LENGTH(v)  ((v) & 0xffff)
+#define GET_INTERRUPT(v)       (((v) >> 16) & 0x01)
+#define GET_SKIP(v)            (((v) >> 17) & 0x01)
+#define GET_TAG(v)             (((v) >> 18) & 0x02)
+#define GET_SY(v)              (((v) >> 20) & 0x04)
+#define GET_HEADER_LENGTH(v)   (((v) >> 24) & 0xff)
+
 static int ioctl_queue_iso(struct client *client, void *buffer)
 {
        struct fw_cdev_queue_iso *request = buffer;
        struct fw_cdev_iso_packet __user *p, *end, *next;
        struct fw_iso_context *ctx = client->iso_context;
        unsigned long payload, buffer_end, header_length;
+       u32 control;
        int count;
        struct {
                struct fw_iso_packet packet;
@@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
        end = (void __user *)p + request->size;
        count = 0;
        while (p < end) {
-               if (__copy_from_user(&u.packet, p, sizeof(*p)))
+               if (get_user(control, &p->control))
                        return -EFAULT;
+               u.packet.payload_length = GET_PAYLOAD_LENGTH(control);
+               u.packet.interrupt = GET_INTERRUPT(control);
+               u.packet.skip = GET_SKIP(control);
+               u.packet.tag = GET_TAG(control);
+               u.packet.sy = GET_SY(control);
+               u.packet.header_length = GET_HEADER_LENGTH(control);
 
                if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
                        header_length = u.packet.header_length;
index 0ba9d64ccf4c64d4c48e658f33b724c3504d557e..af1723eae4ba6d7868d521fd340de08fdd993a9b 100644 (file)
@@ -99,6 +99,7 @@ fw_unit(struct device *dev)
 #define CSR_DEPENDENT_INFO     0x14
 #define CSR_MODEL              0x17
 #define CSR_INSTANCE           0x18
+#define CSR_DIRECTORY_ID       0x20
 
 #define SBP2_COMMAND_SET_SPECIFIER     0x38
 #define SBP2_COMMAND_SET               0x39
index c17342d3e6fd01089e2f058613a3167433926441..0d08bf9b78c21d8f1811a317e5145ae577e4cc98 100644 (file)
@@ -268,7 +268,7 @@ static int ar_context_add_page(struct ar_context *ctx)
 
        dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
 
-       ctx->last_buffer->descriptor.branch_address = ab_bus | 1;
+       ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
        ctx->last_buffer->next = ab;
        ctx->last_buffer = ab;
 
@@ -417,11 +417,21 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
        ctx->current_buffer = ab.next;
        ctx->pointer = ctx->current_buffer->data;
 
-       reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab.descriptor.branch_address);
+       return 0;
+}
+
+static void ar_context_run(struct ar_context *ctx)
+{
+       struct ar_buffer *ab = ctx->current_buffer;
+       dma_addr_t ab_bus;
+       size_t offset;
+
+       offset = offsetof(struct ar_buffer, data);
+       ab_bus = ab->descriptor.data_address - offset;
+
+       reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1);
        reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
        flush_writes(ctx->ohci);
-
-       return 0;
 }
 
 static void context_tasklet(unsigned long data)
@@ -1038,11 +1048,78 @@ static irqreturn_t irq_handler(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static int software_reset(struct fw_ohci *ohci)
+{
+       int i;
+
+       reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
+
+       for (i = 0; i < OHCI_LOOP_COUNT; i++) {
+               if ((reg_read(ohci, OHCI1394_HCControlSet) &
+                    OHCI1394_HCControl_softReset) == 0)
+                       return 0;
+               msleep(1);
+       }
+
+       return -EBUSY;
+}
+
 static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 {
        struct fw_ohci *ohci = fw_ohci(card);
        struct pci_dev *dev = to_pci_dev(card->device);
 
+       if (software_reset(ohci)) {
+               fw_error("Failed to reset ohci card.\n");
+               return -EBUSY;
+       }
+
+       /*
+        * Now enable LPS, which we need in order to start accessing
+        * most of the registers.  In fact, on some cards (ALI M5251),
+        * accessing registers in the SClk domain without LPS enabled
+        * will lock up the machine.  Wait 50msec to make sure we have
+        * full link enabled.
+        */
+       reg_write(ohci, OHCI1394_HCControlSet,
+                 OHCI1394_HCControl_LPS |
+                 OHCI1394_HCControl_postedWriteEnable);
+       flush_writes(ohci);
+       msleep(50);
+
+       reg_write(ohci, OHCI1394_HCControlClear,
+                 OHCI1394_HCControl_noByteSwapData);
+
+       reg_write(ohci, OHCI1394_LinkControlSet,
+                 OHCI1394_LinkControl_rcvSelfID |
+                 OHCI1394_LinkControl_cycleTimerEnable |
+                 OHCI1394_LinkControl_cycleMaster);
+
+       reg_write(ohci, OHCI1394_ATRetries,
+                 OHCI1394_MAX_AT_REQ_RETRIES |
+                 (OHCI1394_MAX_AT_RESP_RETRIES << 4) |
+                 (OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
+
+       ar_context_run(&ohci->ar_request_ctx);
+       ar_context_run(&ohci->ar_response_ctx);
+
+       reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
+       reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
+       reg_write(ohci, OHCI1394_IntEventClear, ~0);
+       reg_write(ohci, OHCI1394_IntMaskClear, ~0);
+       reg_write(ohci, OHCI1394_IntMaskSet,
+                 OHCI1394_selfIDComplete |
+                 OHCI1394_RQPkt | OHCI1394_RSPkt |
+                 OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
+                 OHCI1394_isochRx | OHCI1394_isochTx |
+                 OHCI1394_masterIntEnable |
+                 OHCI1394_cycle64Seconds);
+
+       /* Activate link_on bit and contender bit in our self ID packets.*/
+       if (ohci_update_phy_reg(card, 4, 0,
+                               PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
+               return -EIO;
+
        /*
         * When the link is not yet enabled, the atomic config rom
         * update mechanism described below in ohci_set_config_rom()
@@ -1700,22 +1777,6 @@ static const struct fw_card_driver ohci_driver = {
        .stop_iso               = ohci_stop_iso,
 };
 
-static int software_reset(struct fw_ohci *ohci)
-{
-       int i;
-
-       reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
-
-       for (i = 0; i < OHCI_LOOP_COUNT; i++) {
-               if ((reg_read(ohci, OHCI1394_HCControlSet) &
-                    OHCI1394_HCControl_softReset) == 0)
-                       return 0;
-               msleep(1);
-       }
-
-       return -EBUSY;
-}
-
 static int __devinit
 pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -1761,33 +1822,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
                goto fail_iomem;
        }
 
-       if (software_reset(ohci)) {
-               fw_error("Failed to reset ohci card.\n");
-               err = -EBUSY;
-               goto fail_registers;
-       }
-
-       /*
-        * Now enable LPS, which we need in order to start accessing
-        * most of the registers.  In fact, on some cards (ALI M5251),
-        * accessing registers in the SClk domain without LPS enabled
-        * will lock up the machine.  Wait 50msec to make sure we have
-        * full link enabled.
-        */
-       reg_write(ohci, OHCI1394_HCControlSet,
-                 OHCI1394_HCControl_LPS |
-                 OHCI1394_HCControl_postedWriteEnable);
-       flush_writes(ohci);
-       msleep(50);
-
-       reg_write(ohci, OHCI1394_HCControlClear,
-                 OHCI1394_HCControl_noByteSwapData);
-
-       reg_write(ohci, OHCI1394_LinkControlSet,
-                 OHCI1394_LinkControl_rcvSelfID |
-                 OHCI1394_LinkControl_cycleTimerEnable |
-                 OHCI1394_LinkControl_cycleMaster);
-
        ar_context_init(&ohci->ar_request_ctx, ohci,
                        OHCI1394_AsReqRcvContextControlSet);
 
@@ -1800,11 +1834,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
        context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE,
                     OHCI1394_AsRspTrContextControlSet, handle_at_packet);
 
-       reg_write(ohci, OHCI1394_ATRetries,
-                 OHCI1394_MAX_AT_REQ_RETRIES |
-                 (OHCI1394_MAX_AT_RESP_RETRIES << 4) |
-                 (OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
-
        reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
        ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
        reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
@@ -1834,18 +1863,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
                goto fail_registers;
        }
 
-       reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
-       reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
-       reg_write(ohci, OHCI1394_IntEventClear, ~0);
-       reg_write(ohci, OHCI1394_IntMaskClear, ~0);
-       reg_write(ohci, OHCI1394_IntMaskSet,
-                 OHCI1394_selfIDComplete |
-                 OHCI1394_RQPkt | OHCI1394_RSPkt |
-                 OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
-                 OHCI1394_isochRx | OHCI1394_isochTx |
-                 OHCI1394_masterIntEnable |
-                 OHCI1394_cycle64Seconds);
-
        bus_options = reg_read(ohci, OHCI1394_BusOptions);
        max_receive = (bus_options >> 12) & 0xf;
        link_speed = bus_options & 0x7;
@@ -1907,6 +1924,45 @@ static void pci_remove(struct pci_dev *dev)
        fw_notify("Removed fw-ohci device.\n");
 }
 
+#ifdef CONFIG_PM
+static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct fw_ohci *ohci = pci_get_drvdata(pdev);
+       int err;
+
+       software_reset(ohci);
+       free_irq(pdev->irq, ohci);
+       err = pci_save_state(pdev);
+       if (err) {
+               fw_error("pci_save_state failed with %d", err);
+               return err;
+       }
+       err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       if (err) {
+               fw_error("pci_set_power_state failed with %d", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int pci_resume(struct pci_dev *pdev)
+{
+       struct fw_ohci *ohci = pci_get_drvdata(pdev);
+       int err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       err = pci_enable_device(pdev);
+       if (err) {
+               fw_error("pci_enable_device failed with %d", err);
+               return err;
+       }
+
+       return ohci_enable(&ohci->card, ohci->config_rom, CONFIG_ROM_SIZE);
+}
+#endif
+
 static struct pci_device_id pci_table[] = {
        { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) },
        { }
@@ -1919,6 +1975,10 @@ static struct pci_driver fw_ohci_pci_driver = {
        .id_table       = pci_table,
        .probe          = pci_probe,
        .remove         = pci_remove,
+#ifdef CONFIG_PM
+       .resume         = pci_resume,
+       .suspend        = pci_suspend,
+#endif
 };
 
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
index 68300414e5f44060ec8be59d1d0cf79a6d491fdc..a98d3915e26f33f926d8e0c383842cb5330018db 100644 (file)
@@ -1108,6 +1108,58 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
        return SUCCESS;
 }
 
+/*
+ * Format of /sys/bus/scsi/devices/.../ieee1394_id:
+ * u64 EUI-64 : u24 directory_ID : u16 LUN  (all printed in hexadecimal)
+ *
+ * This is the concatenation of target port identifier and logical unit
+ * identifier as per SAM-2...SAM-4 annex A.
+ */
+static ssize_t
+sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct sbp2_device *sd;
+       struct fw_unit *unit;
+       struct fw_device *device;
+       u32 directory_id;
+       struct fw_csr_iterator ci;
+       int key, value, lun;
+
+       if (!sdev)
+               return 0;
+       sd = (struct sbp2_device *)sdev->host->hostdata;
+       unit = sd->unit;
+       device = fw_device(unit->device.parent);
+
+       /* implicit directory ID */
+       directory_id = ((unit->directory - device->config_rom) * 4
+                       + CSR_CONFIG_ROM) & 0xffffff;
+
+       /* explicit directory ID, overrides implicit ID if present */
+       fw_csr_iterator_init(&ci, unit->directory);
+       while (fw_csr_iterator_next(&ci, &key, &value))
+               if (key == CSR_DIRECTORY_ID) {
+                       directory_id = value;
+                       break;
+               }
+
+       /* FIXME: Make this work for multi-lun devices. */
+       lun = 0;
+
+       return sprintf(buf, "%08x%08x:%06x:%04x\n",
+                       device->config_rom[3], device->config_rom[4],
+                       directory_id, lun);
+}
+
+static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
+
+static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
+       &dev_attr_ieee1394_id,
+       NULL
+};
+
 static struct scsi_host_template scsi_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "SBP-2 IEEE-1394",
@@ -1121,6 +1173,7 @@ static struct scsi_host_template scsi_driver_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .cmd_per_lun            = 1,
        .can_queue              = 1,
+       .sdev_attrs             = sbp2_scsi_sysfs_attrs,
 };
 
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
index 4d1cb5b855d17e86285b7f3aeca698e80775fa57..13eea47dceb3562d687150d1a8d79dea3132056a 100644 (file)
@@ -620,7 +620,7 @@ config SENSORS_HDAPS
 
 config SENSORS_APPLESMC
        tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
-       depends on HWMON && INPUT && X86
+       depends on INPUT && X86
        select NEW_LEDS
        select LEDS_CLASS
        default n
index 0c160675b3acc54d70b2580dfbf507edff00a85d..fd1281f4220909e3f80d10aee1a3a6c501cf9fcc 100644 (file)
@@ -491,6 +491,12 @@ out:
 
 /* Sysfs Files */
 
+static ssize_t applesmc_name_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "applesmc\n");
+}
+
 static ssize_t applesmc_position_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
@@ -913,6 +919,8 @@ static struct led_classdev applesmc_backlight = {
        .brightness_set         = applesmc_brightness_set,
 };
 
+static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
+
 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
 static DEVICE_ATTR(calibrate, 0644,
                        applesmc_calibrate_show, applesmc_calibrate_store);
@@ -1197,10 +1205,14 @@ static int __init applesmc_init(void)
                goto out_driver;
        }
 
+       ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
+       if (ret)
+               goto out_device;
+
        /* Create key enumeration sysfs files */
        ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
        if (ret)
-               goto out_device;
+               goto out_name;
 
        /* create fan files */
        count = applesmc_get_fan_count();
@@ -1300,6 +1312,8 @@ out_fan_1:
        sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
 out_key_enumeration:
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+out_name:
+       sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
 out_device:
        platform_device_unregister(pdev);
 out_driver:
@@ -1325,6 +1339,7 @@ static void __exit applesmc_exit(void)
        sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
        sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+       sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
        platform_device_unregister(pdev);
        platform_driver_unregister(&applesmc_driver);
        release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
index 75e3911810a38af22deafc4f68cf1a4205ef5942..0328382df8fae74a3edf1e0560404cd8f6f3f18a 100644 (file)
@@ -176,6 +176,22 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
                goto exit_free;
        }
 
+       /* Check if we have problem with errata AE18 of Core processors:
+          Readings might stop update when processor visited too deep sleep,
+          fixed for stepping D0 (6EC).
+       */
+
+       if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
+               /* check for microcode update */
+               rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
+               if (edx < 0x39) {
+                       dev_err(&pdev->dev,
+                               "Errata AE18 not fixed, update BIOS or "
+                               "microcode of the CPU!\n");
+                       goto exit_free;
+               }
+       }
+
        /* Some processors have Tjmax 85 following magic should detect it
           Intel won't disclose the information without signed NDA, but
           individuals cannot sign it. Catch(ed) 22.
@@ -193,6 +209,19 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
                }
        }
 
+       /* Intel says that above should not work for desktop Core2 processors,
+          but it seems to work. There is no other way how get the absolute
+          readings. Warn the user about this. First check if are desktop,
+          bit 50 of MSR_IA32_PLATFORM_ID should be 0.
+       */
+
+       rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
+
+       if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
+               dev_warn(&pdev->dev, "Using undocumented features, absolute "
+                        "temperature might be wrong!\n");
+       }
+
        platform_set_drvdata(pdev, data);
 
        if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
@@ -330,9 +359,6 @@ static int __init coretemp_init(void)
        int i, err = -ENODEV;
        struct pdev_entry *p, *n;
 
-       printk(KERN_NOTICE DRVNAME ": This driver uses undocumented features "
-               "of Core CPU. Temperature might be wrong!\n");
-
        /* quick check if we run Intel */
        if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
                goto exit;
index c849c0c6ee9ce37edb2b86061aa595476946686c..d5ac422d73b2f9d076fa11135715be4ff4b7ae84 100644 (file)
@@ -53,8 +53,8 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low")
 
 /* The DS1621 registers */
 #define DS1621_REG_TEMP                        0xAA /* word, RO */
-#define DS1621_REG_TEMP_MIN            0xA1 /* word, RW */
-#define DS1621_REG_TEMP_MAX            0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MIN            0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MAX            0xA1 /* word, RW */
 #define DS1621_REG_CONF                        0xAC /* byte, RW */
 #define DS1621_COM_START               0xEE /* no data */
 #define DS1621_COM_STOP                        0x22 /* no data */
@@ -328,9 +328,9 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
 
                /* reset alarms if necessary */
                new_conf = data->conf;
-               if (data->temp < data->temp_min)
+               if (data->temp > data->temp_min)
                        new_conf &= ~DS1621_ALARM_TEMP_LOW;
-               if (data->temp > data->temp_max)
+               if (data->temp < data->temp_max)
                        new_conf &= ~DS1621_ALARM_TEMP_HIGH;
                if (data->conf != new_conf)
                        ds1621_write_value(client, DS1621_REG_CONF,
index 5aab23b93e246ffa685dc2d1e561c7c13dafd870..f17e771e42f8aa6c699a21e429b0a1d557fbb048 100644 (file)
@@ -132,7 +132,9 @@ int vid_from_reg(int val, u8 vrm)
                val &= 0x7f;
                return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
        default:                /* report 0 for unknown */
-               printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
+               if (vrm)
+                       printk(KERN_WARNING "hwmon-vid: Requested unsupported "
+                              "VRM version (%u)\n", (unsigned int)vrm);
                return 0;
        }
 }
index a5b774b07cbde457618d6885fd96d675193f8c11..12cb40a975de90cd61218fe04d146021f79e149a 100644 (file)
@@ -965,8 +965,10 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr,
        case W687THF_DEVID:
                sio_data->type = w83687thf;
                break;
+       case 0xff:      /* No device at all */
+               goto exit;
        default:
-               pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", val);
+               pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val);
                goto exit;
        }
 
index 8a0a99b93641d46b10efd56b09341e619cb15615..28e7b91a4553ff3d33f5e830fb881a0e7c8f6886 100644 (file)
@@ -837,20 +837,10 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
        .functionality  = i2c_pxa_functionality,
 };
 
-static struct pxa_i2c i2c_pxa = {
-       .lock   = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
-       .adap   = {
-               .owner          = THIS_MODULE,
-               .algo           = &i2c_pxa_algorithm,
-               .name           = "pxa2xx-i2c.0",
-               .retries        = 5,
-       },
-};
-
 #define res_len(r)             ((r)->end - (r)->start + 1)
 static int i2c_pxa_probe(struct platform_device *dev)
 {
-       struct pxa_i2c *i2c = &i2c_pxa;
+       struct pxa_i2c *i2c;
        struct resource *res;
        struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
        int ret;
@@ -864,15 +854,20 @@ static int i2c_pxa_probe(struct platform_device *dev)
        if (!request_mem_region(res->start, res_len(res), res->name))
                return -ENOMEM;
 
-       i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
+       i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
        if (!i2c) {
                ret = -ENOMEM;
                goto emalloc;
        }
 
-       memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
+       i2c->adap.owner   = THIS_MODULE;
+       i2c->adap.algo    = &i2c_pxa_algorithm;
+       i2c->adap.retries = 5;
+
+       spin_lock_init(&i2c->lock);
        init_waitqueue_head(&i2c->wait);
-       i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
+
+       sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
 
        i2c->reg_base = ioremap(res->start, res_len(res));
        if (!i2c->reg_base) {
index 7fff773f2df77ece16e19644346c771b6864516b..dc2175c81f5efe5c955729efd5b23b22c612d48e 100644 (file)
@@ -1037,6 +1037,17 @@ static void ide_disk_release(struct kref *kref)
 
 static int ide_disk_probe(ide_drive_t *drive);
 
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_disk_resume(ide_drive_t *drive)
+{
+       if (idedisk_supports_hpa(drive->id))
+               init_idedisk_capacity(drive);
+}
+
 static void ide_device_shutdown(ide_drive_t *drive)
 {
 #ifdef CONFIG_ALPHA
@@ -1071,6 +1082,7 @@ static ide_driver_t idedisk_driver = {
        },
        .probe                  = ide_disk_probe,
        .remove                 = ide_disk_remove,
+       .resume                 = ide_disk_resume,
        .shutdown               = ide_device_shutdown,
        .version                = IDEDISK_VERSION,
        .media                  = ide_disk,
index b77b7d138c497cb8c090802ea9216dc600e952f7..ead141e2db9e2d12213daaa5d746fe178a05724d 100644 (file)
@@ -119,15 +119,17 @@ static const struct drive_list_entry drive_blacklist [] = {
        { "HITACHI CDR-8335"    ,       "ALL"           },
        { "HITACHI CDR-8435"    ,       "ALL"           },
        { "Toshiba CD-ROM XM-6202B"     ,       "ALL"           },
+       { "TOSHIBA CD-ROM XM-1702BC",   "ALL"           },
        { "CD-532E-A"           ,       "ALL"           },
        { "E-IDE CD-ROM CR-840",        "ALL"           },
        { "CD-ROM Drive/F5A",   "ALL"           },
        { "WPI CDD-820",                "ALL"           },
        { "SAMSUNG CD-ROM SC-148C",     "ALL"           },
        { "SAMSUNG CD-ROM SC",  "ALL"           },
-       { "SanDisk SDP3B-64"    ,       "ALL"           },
        { "ATAPI CD-ROM DRIVE 40X MAXIMUM",     "ALL"           },
        { "_NEC DV5800A",               "ALL"           },  
+       { "SAMSUNG CD-ROM SN-124",      "N001" },
+       { "Seagate STT20000A",          "ALL" },
        { NULL                  ,       NULL            }
 
 };
index 3cebed77f55d27020b8be9b4331571cd80e00844..41bfa4d21ab65352afdf489782b0441a1fc40bfb 100644 (file)
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 {
        unsigned int unit;
        unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
                return;
        }
 
+       if (fixup)
+               fixup(hwif);
+
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
 
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
 
 int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 {
-       probe_hwif(hwif);
-
-       if (fixup)
-               fixup(hwif);
+       probe_hwif(hwif, fixup);
 
        if (!hwif_init(hwif)) {
                printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
 
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
-                       probe_hwif(&ide_hwifs[index]);
+                       probe_hwif(&ide_hwifs[index], NULL);
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
                        hwif_init(&ide_hwifs[index]);
index d50bd996ff22939a9613c6399cd9b4d932789bd4..ea94c9aa1220754b8cad352bff4cb8102e08075f 100644 (file)
@@ -67,6 +67,8 @@ static int proc_ide_read_imodel
                case ide_4drives:       name = "4drives";       break;
                case ide_pmac:          name = "mac-io";        break;
                case ide_au1xxx:        name = "au1xxx";        break;
+               case ide_etrax100:      name = "etrax100";      break;
+               case ide_acorn:         name = "acorn";         break;
                default:                name = "(unknown)";     break;
        }
        len = sprintf(page, "%s\n", name);
index 6002713a20a1bdfbcf9f7e2a3f000d491baa6802..0af0d1614f7553350a737edce67b0c931352fec1 100644 (file)
@@ -1010,9 +1010,11 @@ static int generic_ide_resume(struct device *dev)
 {
        ide_drive_t *drive = dev->driver_data;
        ide_hwif_t *hwif = HWIF(drive);
+       ide_driver_t *drv = to_ide_driver(dev->driver);
        struct request rq;
        struct request_pm_state rqpm;
        ide_task_t args;
+       int err;
 
        /* Call ACPI _STM only once */
        if (!(drive->dn % 2))
@@ -1029,7 +1031,12 @@ static int generic_ide_resume(struct device *dev)
        rqpm.pm_step = ide_pm_state_start_resume;
        rqpm.pm_state = PM_EVENT_ON;
 
-       return ide_do_drive_cmd(drive, &rq, ide_head_wait);
+       err = ide_do_drive_cmd(drive, &rq, ide_head_wait);
+
+       if (err == 0 && drv && drv->resume)
+               drv->resume(drive);
+
+       return err;
 }
 
 int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
index becb1a5648b0858643a8da7846cec022b82fd522..9db1be826e8018b70467ec59159bae927254e246 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Version 2.13
+ * Version 2.15
  *
  * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
  * IDE driver for Linux.
@@ -76,6 +76,8 @@ static struct amd_ide_chip {
        { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,        0x50, AMD_UDMA_133 },
        { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,        0x50, AMD_UDMA_133 },
        { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,        0x50, AMD_UDMA_133 },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE,        0x50, AMD_UDMA_133 },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE,        0x50, AMD_UDMA_133 },
        { PCI_DEVICE_ID_AMD_CS5536_IDE,                 0x40, AMD_UDMA_100 },
        { 0 }
 };
@@ -494,7 +496,9 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
        /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
        /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
        /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
-       /* 20 */ DECLARE_AMD_DEV("AMD5536"),
+       /* 20 */ DECLARE_NV_DEV("NFORCE-MCP73"),
+       /* 21 */ DECLARE_NV_DEV("NFORCE-MCP77"),
+       /* 22 */ DECLARE_AMD_DEV("AMD5536"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -534,7 +538,9 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_CS5536_IDE,           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21 },
+       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_CS5536_IDE,           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22 },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
index 0e52ad722a72ab23bf7e399a210fa87052f8dddb..8ab33faf6f76776d860d1b2db3ce72834937f369 100644 (file)
@@ -317,6 +317,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
index f2c5a141ca10ca1927a03abea7b8e4e01ce0a1ba..0d51a11e81da6edc8342ef33928a49b5740af8ec 100644 (file)
@@ -198,32 +198,41 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        ide_pci_device_t *d = &generic_chipsets[id->driver_data];
-       u16 command;
        int ret = -ENODEV;
 
        /* Don't use the generic entry unless instructed to do so */
        if (id->driver_data == 0 && ide_generic_all == 0)
                        goto out;
 
-       if (dev->vendor == PCI_VENDOR_ID_UMC &&
-           dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
-           (!(PCI_FUNC(dev->devfn) & 1)))
-               goto out; /* UM8886A/BF pair */
-
-       if (dev->vendor == PCI_VENDOR_ID_OPTI &&
-           dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
-           (!(PCI_FUNC(dev->devfn) & 1)))
-               goto out;
-
-       if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
-               if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+       switch (dev->vendor) {
+       case PCI_VENDOR_ID_UMC:
+               if (dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
+                               !(PCI_FUNC(dev->devfn) & 1))
+                       goto out; /* UM8886A/BF pair */
+               break;
+       case PCI_VENDOR_ID_OPTI:
+               if (dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
+                               !(PCI_FUNC(dev->devfn) & 1))
+                       goto out;
+               break;
+       case PCI_VENDOR_ID_JMICRON:
+               if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 &&
+                               PCI_FUNC(dev->devfn) != 1)
+                       goto out;
+               break;
+       case PCI_VENDOR_ID_NS:
+               if (dev->device == PCI_DEVICE_ID_NS_87410 &&
+                               (dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
                        goto out;
+               break;
        }
 
        if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+               u16 command;
                pci_read_config_word(dev, PCI_COMMAND, &command);
                if (!(command & PCI_COMMAND_IO)) {
-                       printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
+                       printk(KERN_INFO "Skipping disabled %s IDE "
+                                       "controller.\n", d->name);
                        goto out;
                }
        }
index fcbc5605b38ef28210d11bdf7f33051bad56312d..ce8a5449a5749d3ae99b6c6e04a263b808e0511e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/hpt366.c              Version 1.03    May 4, 2007
+ * linux/drivers/ide/pci/hpt366.c              Version 1.04    Jun 4, 2007
  *
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   frequency
  * - switch to using the  DPLL clock and enable UltraATA/133 mode by default on
- *   anything  newer than HPT370/A
+ *   anything  newer than HPT370/A (except HPT374 that is not capable of this
+ *   mode according to the manual)
  * - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
  *   also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
  *   unify HPT36x/37x timing setup code and the speedproc handlers by joining
@@ -365,7 +366,6 @@ static u32 sixty_six_base_hpt37x[] = {
 };
 
 #define HPT366_DEBUG_DRIVE_INFO                0
-#define HPT374_ALLOW_ATA133_6          1
 #define HPT371_ALLOW_ATA133_6          1
 #define HPT302_ALLOW_ATA133_6          1
 #define HPT372_ALLOW_ATA133_6          1
@@ -450,7 +450,7 @@ static struct hpt_info hpt370a __devinitdata = {
 
 static struct hpt_info hpt374 __devinitdata = {
        .chip_type      = HPT374,
-       .max_mode       = HPT374_ALLOW_ATA133_6 ? 4 : 3,
+       .max_mode       = 3,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
index 5faaff87d58077047bbcfad8b336a58a3d3f4385..4bd4bf02e917a8ca64a6a7b7f3c99d1c5797a9bf 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * linux/drivers/ide/pci/it821x.c              Version 0.10    Mar 10 2007
+ * linux/drivers/ide/pci/it821x.c              Version 0.15    Jun 2 2007
  *
  * Copyright (C) 2004          Red Hat <alan@redhat.com>
  * Copyright (C) 2007          Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
        }
 
        if (itdev->smart)
-               goto set_drive_speed;
+               return 0;
 
        /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
        itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
        it821x_clock_strategy(drive);
        it821x_program(drive, itdev->pio[unit]);
 
-set_drive_speed:
        return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
 }
 
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
                        default:
                                return 1;
                }
+
+               return ide_config_drive_speed(drive, speed);
        }
-       /*
-        *      In smart mode the clocking is done by the host controller
-        *      snooping the mode we picked. The rest of it is not our problem
-        */
-       return ide_config_drive_speed(drive, speed);
+
+       /* don't touch anything in the smart mode */
+       return 0;
 }
 
 /**
@@ -559,17 +558,10 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
                                if(idbits[129] != 1)
                                        printk("(%dK stripe)", idbits[146]);
                                printk(".\n");
-                       /* Now the core code will have wrongly decided no DMA
-                          so we need to fix this */
-                       hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
-                       if (drive->media == ide_disk)
-#endif
-                               ide_set_dma(drive);
                } else {
                        /* Non RAID volume. Fixups to stop the core code
                           doing unsupported things */
-                       id->field_valid &= 1;
+                       id->field_valid &= 3;
                        id->queue_depth = 0;
                        id->command_set_1 = 0;
                        id->command_set_2 &= 0xC400;
@@ -584,6 +576,16 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
                        printk(KERN_INFO "%s: Performing identify fixups.\n",
                                drive->name);
                }
+
+               /*
+                * Set MWDMA0 mode as enabled/support - just to tell
+                * IDE core that DMA is supported (it821x hardware
+                * takes care of DMA mode programming).
+                */
+               if (id->capability & 1) {
+                       id->dma_mword |= 0x0101;
+                       drive->current_speed = XFER_MW_DMA_0;
+               }
        }
 
 }
index 6234f806c6b5caa6d264d52371dbc69fa2405f8d..d9c4fd1ae9969784144f10d073c7d078b490bbc6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/serverworks.c         Version 0.9     Mar 4 2007
+ * linux/drivers/ide/pci/serverworks.c         Version 0.11    Jun 2 2007
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -158,48 +158,67 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
        pci_read_config_word(dev, 0x4A, &csb5_pio);
        pci_read_config_byte(dev, 0x54, &ultra_enable);
 
+       /* If we are in RAID mode (eg AMI MegaIDE) then we can't it
+          turns out trust the firmware configuration */
+
+       if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+               goto oem_setup_failed;
+
        /* Per Specified Design by OEM, and ASIC Architect */
        if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
            (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
                if (!drive->init_speed) {
                        u8 dma_stat = inb(hwif->dma_status);
 
-dma_pio:
                        if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
                            ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
                                drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
                                return 0;
                        } else if ((dma_timing) &&
                                   ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
-                               u8 dmaspeed = dma_timing;
+                               u8 dmaspeed;
 
-                               dma_timing &= ~0xFF;
-                               if ((dmaspeed & 0x20) == 0x20)
+                               switch (dma_timing & 0x77) {
+                               case 0x20:
                                        dmaspeed = XFER_MW_DMA_2;
-                               else if ((dmaspeed & 0x21) == 0x21)
+                                       break;
+                               case 0x21:
                                        dmaspeed = XFER_MW_DMA_1;
-                               else if ((dmaspeed & 0x77) == 0x77)
+                                       break;
+                               case 0x77:
                                        dmaspeed = XFER_MW_DMA_0;
-                               else
+                                       break;
+                               default:
                                        goto dma_pio;
+                               }
+
                                drive->current_speed = drive->init_speed = dmaspeed;
                                return 0;
-                       } else if (pio_timing) {
-                               u8 piospeed = pio_timing;
+                       }
+dma_pio:
+                       if (pio_timing) {
+                               u8 piospeed;
 
-                               pio_timing &= ~0xFF;
-                               if ((piospeed & 0x20) == 0x20)
+                               switch (pio_timing & 0x7f) {
+                               case 0x20:
                                        piospeed = XFER_PIO_4;
-                               else if ((piospeed & 0x22) == 0x22)
+                                       break;
+                               case 0x22:
                                        piospeed = XFER_PIO_3;
-                               else if ((piospeed & 0x34) == 0x34)
+                                       break;
+                               case 0x34:
                                        piospeed = XFER_PIO_2;
-                               else if ((piospeed & 0x47) == 0x47)
+                                       break;
+                               case 0x47:
                                        piospeed = XFER_PIO_1;
-                               else if ((piospeed & 0x5d) == 0x5d)
+                                       break;
+                               case 0x5d:
                                        piospeed = XFER_PIO_0;
-                               else
+                                       break;
+                               default:
                                        goto oem_setup_failed;
+                               }
+
                                drive->current_speed = drive->init_speed = piospeed;
                                return 0;
                        }
@@ -208,8 +227,8 @@ dma_pio:
 
 oem_setup_failed:
 
-       pio_timing      &= ~0xFF;
-       dma_timing      &= ~0xFF;
+       pio_timing      = 0;
+       dma_timing      = 0;
        ultra_timing    &= ~(0x0F << (4*unit));
        ultra_enable    &= ~(0x01 << drive->dn);
        csb5_pio        &= ~(0x0F << (4*drive->dn));
index 2296d43a24140ab121c3467313af3a5c4df2acb6..5f026b5d7857f034287483f96ec2f5b87d5e5910 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/workqueue.h>
 
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
@@ -235,6 +236,9 @@ static int ether1394_open(struct net_device *dev)
 /* This is called after an "ifdown" */
 static int ether1394_stop(struct net_device *dev)
 {
+       /* flush priv->wake */
+       flush_scheduled_work();
+
        netif_stop_queue(dev);
        return 0;
 }
@@ -530,6 +534,37 @@ static void ether1394_init_dev(struct net_device *dev)
        dev->tx_queue_len       = 1000;
 }
 
+/*
+ * Wake the queue up after commonly encountered transmit failure conditions are
+ * hopefully over.  Currently only tlabel exhaustion is accounted for.
+ */
+static void ether1394_wake_queue(struct work_struct *work)
+{
+       struct eth1394_priv *priv;
+       struct hpsb_packet *packet;
+
+       priv = container_of(work, struct eth1394_priv, wake);
+       packet = hpsb_alloc_packet(0);
+
+       /* This is really bad, but unjam the queue anyway. */
+       if (!packet)
+               goto out;
+
+       packet->host = priv->host;
+       packet->node_id = priv->wake_node;
+       /*
+        * A transaction label is all we really want.  If we get one, it almost
+        * always means we can get a lot more because the ieee1394 core recycled
+        * a whole batch of tlabels, at last.
+        */
+       if (hpsb_get_tlabel(packet) == 0)
+               hpsb_free_tlabel(packet);
+
+       hpsb_free_packet(packet);
+out:
+       netif_wake_queue(priv->wake_dev);
+}
+
 /*
  * This function is called every time a card is found. It is generally called
  * when the module is installed. This is where we add all of our ethernet
@@ -564,16 +599,17 @@ static void ether1394_add_host(struct hpsb_host *host)
        }
 
        SET_MODULE_OWNER(dev);
-#if 0
-       /* FIXME - Is this the correct parent device anyway? */
-       SET_NETDEV_DEV(dev, &host->device);
-#endif
+
+       /* This used to be &host->device in Linux 2.6.20 and before. */
+       SET_NETDEV_DEV(dev, host->device.parent);
 
        priv = netdev_priv(dev);
        INIT_LIST_HEAD(&priv->ip_node_list);
        spin_lock_init(&priv->lock);
        priv->host = host;
        priv->local_fifo = fifo_addr;
+       INIT_WORK(&priv->wake, ether1394_wake_queue);
+       priv->wake_dev = dev;
 
        hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
        if (hi == NULL) {
@@ -1390,22 +1426,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p,
                                       u64 addr, void *data, int tx_len)
 {
        p->node_id = node;
-       p->data = NULL;
 
-       p->tcode = TCODE_WRITEB;
-       p->header[1] = host->node_id << 16 | addr >> 32;
-       p->header[2] = addr & 0xffffffff;
+       if (hpsb_get_tlabel(p))
+               return -EAGAIN;
 
+       p->tcode = TCODE_WRITEB;
        p->header_size = 16;
        p->expect_response = 1;
-
-       if (hpsb_get_tlabel(p)) {
-               ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
-               return -1;
-       }
        p->header[0] =
                p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4;
-
+       p->header[1] = host->node_id << 16 | addr >> 32;
+       p->header[2] = addr & 0xffffffff;
        p->header[3] = tx_len << 16;
        p->data_size = (tx_len + 3) & ~3;
        p->data = data;
@@ -1451,7 +1482,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
 
        packet = ether1394_alloc_common_packet(priv->host);
        if (!packet)
-               return -1;
+               return -ENOMEM;
 
        if (ptask->tx_type == ETH1394_GASP) {
                int length = tx_len + 2 * sizeof(quadlet_t);
@@ -1462,7 +1493,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
                                               ptask->addr, ptask->skb->data,
                                               tx_len)) {
                hpsb_free_packet(packet);
-               return -1;
+               return -EAGAIN;
        }
 
        ptask->packet = packet;
@@ -1471,7 +1502,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
 
        if (hpsb_send_packet(packet) < 0) {
                ether1394_free_packet(packet);
-               return -1;
+               return -EIO;
        }
 
        return 0;
@@ -1514,13 +1545,18 @@ static void ether1394_complete_cb(void *__ptask)
 
        ptask->outstanding_pkts--;
        if (ptask->outstanding_pkts > 0 && !fail) {
-               int tx_len;
+               int tx_len, err;
 
                /* Add the encapsulation header to the fragment */
                tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
                                               &ptask->hdr);
-               if (ether1394_send_packet(ptask, tx_len))
+               err = ether1394_send_packet(ptask, tx_len);
+               if (err) {
+                       if (err == -EAGAIN)
+                               ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
+
                        ether1394_dg_complete(ptask, 1);
+               }
        } else {
                ether1394_dg_complete(ptask, fail);
        }
@@ -1633,10 +1669,18 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
        /* Add the encapsulation header to the fragment */
        tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
        dev->trans_start = jiffies;
-       if (ether1394_send_packet(ptask, tx_len))
-               goto fail;
+       if (ether1394_send_packet(ptask, tx_len)) {
+               if (dest_node == (LOCAL_BUS | ALL_NODES))
+                       goto fail;
+
+               /* Most failures of ether1394_send_packet are recoverable. */
+               netif_stop_queue(dev);
+               priv->wake_node = dest_node;
+               schedule_work(&priv->wake);
+               kmem_cache_free(packet_task_cache, ptask);
+               return NETDEV_TX_BUSY;
+       }
 
-       netif_wake_queue(dev);
        return NETDEV_TX_OK;
 fail:
        if (ptask)
@@ -1650,9 +1694,6 @@ fail:
        priv->stats.tx_errors++;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (netif_queue_stopped(dev))
-               netif_wake_queue(dev);
-
        /*
         * FIXME: According to a patch from 2003-02-26, "returning non-zero
         * causes serious problems" here, allegedly.  Before that patch,
index a3439ee7cb4ece87c1ecf8c0751ccd1f43f45f00..4f3e2dd46f0049c52211b589d2623a8053fcd9e7 100644 (file)
@@ -66,6 +66,10 @@ struct eth1394_priv {
        int bc_dgl;                     /* Outgoing broadcast datagram label */
        struct list_head ip_node_list;  /* List of IP capable nodes      */
        struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */
+
+       struct work_struct wake;        /* Wake up after xmit failure    */
+       struct net_device *wake_dev;    /* Stupid backlink for .wake     */
+       nodeid_t wake_node;             /* Destination of failed xmit    */
 };
 
 
index 835937e385292d648ba3d2b131e906d66bbb5f09..81b3864d2ba785b51b25d597965a608ff7879fcb 100644 (file)
@@ -976,7 +976,8 @@ static struct unit_directory *nodemgr_process_unit_directory
 
        ud->ne = ne;
        ud->ignore_driver = ignore_drivers;
-       ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE;
+       ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE;
+       ud->directory_id = ud->address & 0xffffff;
        ud->ud_kv = ud_kv;
        ud->id = (*id)++;
 
@@ -1085,6 +1086,10 @@ static struct unit_directory *nodemgr_process_unit_directory
 
                        break;
 
+               case CSR1212_KV_ID_DIRECTORY_ID:
+                       ud->directory_id = kv->value.immediate;
+                       break;
+
                default:
                        break;
                }
index e7ac683c72c7f26b5777425f56a94d927a3ba89d..4530b29d941c37c0bc74debaeab810920057b363 100644 (file)
@@ -75,6 +75,7 @@ struct unit_directory {
        struct csr1212_keyval *model_name_kv;
        quadlet_t specifier_id;
        quadlet_t version;
+       quadlet_t directory_id;
 
        unsigned int id;
 
index d382500f4210b89896a4d47607cc7d7c7fc8feac..f1d05eeb9f5190216b68504dc78fcc1fb7ef38fe 100644 (file)
@@ -936,6 +936,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
        struct hpsb_packet *packet;
        int header_length = req->req.misc & 0xffff;
        int expect_response = req->req.misc >> 16;
+       size_t data_size;
 
        if (header_length > req->req.length || header_length < 12 ||
            header_length > FIELD_SIZEOF(struct hpsb_packet, header)) {
@@ -945,7 +946,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                return sizeof(struct raw1394_request);
        }
 
-       packet = hpsb_alloc_packet(req->req.length - header_length);
+       data_size = req->req.length - header_length;
+       packet = hpsb_alloc_packet(data_size);
        req->packet = packet;
        if (!packet)
                return -ENOMEM;
@@ -960,7 +962,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
 
        if (copy_from_user
            (packet->data, int2ptr(req->req.sendb) + header_length,
-            packet->data_size)) {
+            data_size)) {
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
@@ -974,7 +976,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
        packet->host = fi->host;
        packet->expect_response = expect_response;
        packet->header_size = header_length;
-       packet->data_size = req->req.length - header_length;
+       packet->data_size = data_size;
 
        req->req.length = 0;
        hpsb_set_packet_complete_task(packet,
index 4cb6fa2bcfb7b0de3e331aaac42e8db4730572ae..3f873cc7e247a7944d4ac27359600daf378fb1f7 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/stringify.h>
 #include <linux/types.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <asm/byteorder.h>
 #include <asm/errno.h>
@@ -193,6 +194,27 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
        ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
        ", or a combination)");
 
+/*
+ * This influences the format of the sysfs attribute
+ * /sys/bus/scsi/devices/.../ieee1394_id.
+ *
+ * The default format is like in older kernels:  %016Lx:%d:%d
+ * It contains the target's EUI-64, a number given to the logical unit by
+ * the ieee1394 driver's nodemgr (starting at 0), and the LUN.
+ *
+ * The long format is:  %016Lx:%06x:%04x
+ * It contains the target's EUI-64, the unit directory's directory_ID as per
+ * IEEE 1212 clause 7.7.19, and the LUN.  This format comes closest to the
+ * format of SBP(-3) target port and logical unit identifier as per SAM (SCSI
+ * Architecture Model) rev.2 to 4 annex A.  Therefore and because it is
+ * independent of the implementation of the ieee1394 nodemgr, the longer format
+ * is recommended for future use.
+ */
+static int sbp2_long_sysfs_ieee1394_id;
+module_param_named(long_ieee1394_id, sbp2_long_sysfs_ieee1394_id, bool, 0644);
+MODULE_PARM_DESC(long_ieee1394_id, "8+3+2 bytes format of ieee1394_id in sysfs "
+                "(default = backwards-compatible = N, SAM-conforming = Y)");
+
 
 #define SBP2_INFO(fmt, args...)        HPSB_INFO("sbp2: "fmt, ## args)
 #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
@@ -2099,8 +2121,14 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
        if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0]))
                return 0;
 
-       return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)lu->ne->guid,
-                      lu->ud->id, ORB_SET_LUN(lu->lun));
+       if (sbp2_long_sysfs_ieee1394_id)
+               return sprintf(buf, "%016Lx:%06x:%04x\n",
+                               (unsigned long long)lu->ne->guid,
+                               lu->ud->directory_id, ORB_SET_LUN(lu->lun));
+       else
+               return sprintf(buf, "%016Lx:%d:%d\n",
+                               (unsigned long long)lu->ne->guid,
+                               lu->ud->id, ORB_SET_LUN(lu->lun));
 }
 
 MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
index e840434a96d8370071c2c554cab781ebc625c7df..40c004a2697e62281c17380f32cfea619f0a9f95 100644 (file)
@@ -1297,26 +1297,29 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
 
-       /* Check for duplicate REQ and stale connections. */
+       /* Check for possible duplicate REQ. */
        spin_lock_irqsave(&cm.lock, flags);
        timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
-       if (!timewait_info)
-               timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
-
        if (timewait_info) {
                cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
                                           timewait_info->work.remote_id);
-               cm_cleanup_timewait(cm_id_priv->timewait_info);
                spin_unlock_irqrestore(&cm.lock, flags);
                if (cur_cm_id_priv) {
                        cm_dup_req_handler(work, cur_cm_id_priv);
                        cm_deref_id(cur_cm_id_priv);
-               } else
-                       cm_issue_rej(work->port, work->mad_recv_wc,
-                                    IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
-                                    NULL, 0);
-               listen_cm_id_priv = NULL;
-               goto out;
+               }
+               return NULL;
+       }
+
+       /* Check for stale connections. */
+       timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
+       if (timewait_info) {
+               cm_cleanup_timewait(cm_id_priv->timewait_info);
+               spin_unlock_irqrestore(&cm.lock, flags);
+               cm_issue_rej(work->port, work->mad_recv_wc,
+                            IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
+                            NULL, 0);
+               return NULL;
        }
 
        /* Find matching listen request. */
index 58bc272bd407273d18416c00afb35a9e51c086d2..0aecea67f3e69cb6339dfe5d6f29679eb36285e7 100644 (file)
@@ -672,7 +672,7 @@ static int c2_up(struct net_device *netdev)
         * rdma interface.
         */
        in_dev = in_dev_get(netdev);
-       in_dev->cnf.arp_ignore = 1;
+       IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1);
        in_dev_put(in_dev);
 
        return 0;
index 7f0beec74f7006e76fff3e3ee07e81aecbfa9bc0..5766ae3a202995bebb306f4aae1f4580a888109a 100644 (file)
@@ -331,7 +331,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
                                0);
        qp->ipz_qp_handle.handle = outs[0];
        qp->real_qp_num = (u32)outs[1];
-       parms->act_nr_send_sges =
+       parms->act_nr_send_wqes =
                (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
        parms->act_nr_recv_wqes =
                (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
index a824bc5f79fdf5ee60ea4b580cef06819819ab28..dc137dec2308028c1341ce3de9c3892d0f06d172 100644 (file)
@@ -270,9 +270,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
 {
-       struct mlx4_wqe_ctrl_seg *ctrl;
        int err;
-       int i;
 
        mutex_init(&qp->mutex);
        spin_lock_init(&qp->sq.lock);
@@ -319,20 +317,24 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
-                                         ucmd.db_addr, &qp->db);
-               if (err)
-                       goto err_mtt;
+               if (!init_attr->srq) {
+                       err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
+                                                 ucmd.db_addr, &qp->db);
+                       if (err)
+                               goto err_mtt;
+               }
        } else {
                err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
                if (err)
                        goto err;
 
-               err = mlx4_ib_db_alloc(dev, &qp->db, 0);
-               if (err)
-                       goto err;
+               if (!init_attr->srq) {
+                       err = mlx4_ib_db_alloc(dev, &qp->db, 0);
+                       if (err)
+                               goto err;
 
-               *qp->db.db = 0;
+                       *qp->db.db = 0;
+               }
 
                if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf)) {
                        err = -ENOMEM;
@@ -348,11 +350,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               for (i = 0; i < qp->sq.max; ++i) {
-                       ctrl = get_send_wqe(qp, i);
-                       ctrl->owner_opcode = cpu_to_be32(1 << 31);
-               }
-
                qp->sq.wrid  = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL);
                qp->rq.wrid  = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL);
 
@@ -386,7 +383,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
        return 0;
 
 err_wrid:
-       if (pd->uobject)
+       if (pd->uobject && !init_attr->srq)
                mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
        else {
                kfree(qp->sq.wrid);
@@ -403,7 +400,7 @@ err_buf:
                mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
 
 err_db:
-       if (!pd->uobject)
+       if (!pd->uobject && !init_attr->srq)
                mlx4_ib_db_free(dev, &qp->db);
 
 err:
@@ -481,14 +478,16 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
        mlx4_mtt_cleanup(dev->dev, &qp->mtt);
 
        if (is_user) {
-               mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
-                                     &qp->db);
+               if (!qp->ibqp.srq)
+                       mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
+                                             &qp->db);
                ib_umem_release(qp->umem);
        } else {
                kfree(qp->sq.wrid);
                kfree(qp->rq.wrid);
                mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
-               mlx4_ib_db_free(dev, &qp->db);
+               if (!qp->ibqp.srq)
+                       mlx4_ib_db_free(dev, &qp->db);
        }
 }
 
@@ -852,7 +851,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
        if (ibqp->srq)
                context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn);
 
-       if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+       if (!ibqp->srq && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
                context->db_rec_addr = cpu_to_be64(qp->db.dma);
 
        if (cur_state == IB_QPS_INIT &&
@@ -872,6 +871,21 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
        else
                sqd_event = 0;
 
+       /*
+        * Before passing a kernel QP to the HW, make sure that the
+        * ownership bits of the send queue are set so that the
+        * hardware doesn't start processing stale work requests.
+        */
+       if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+               struct mlx4_wqe_ctrl_seg *ctrl;
+               int i;
+
+               for (i = 0; i < qp->sq.max; ++i) {
+                       ctrl = get_send_wqe(qp, i);
+                       ctrl->owner_opcode = cpu_to_be32(1 << 31);
+               }
+       }
+
        err = mlx4_qp_modify(dev->dev, &qp->mtt, to_mlx4_state(cur_state),
                             to_mlx4_state(new_state), context, optpar,
                             sqd_event, &qp->mqp);
@@ -919,7 +933,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                qp->rq.tail = 0;
                qp->sq.head = 0;
                qp->sq.tail = 0;
-               *qp->db.db  = 0;
+               if (!ibqp->srq)
+                       *qp->db.db  = 0;
        }
 
 out:
index 027664979fe2b1d5bff9e81539e6526a7fc71b86..eef415b12b2ebda3d60043bf4b7f9cf8fee72563 100644 (file)
@@ -2284,10 +2284,10 @@ void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
        struct mthca_next_seg *next;
 
        /*
-        * For SRQs, all WQEs generate a CQE, so we're always at the
-        * end of the doorbell chain.
+        * For SRQs, all receive WQEs generate a CQE, so we're always
+        * at the end of the doorbell chain.
         */
-       if (qp->ibqp.srq) {
+       if (qp->ibqp.srq && !is_send) {
                *new_wqe = 0;
                return;
        }
index a0b3782c762504d957e63d018214ec700ed89734..285c143115ccda751d8f544621eaad9ec2287bef 100644 (file)
@@ -156,7 +156,7 @@ struct ipoib_cm_data {
  * - and then invoke a Destroy QP or Reset QP.
  *
  * We use the second option and wait for a completion on the
- * rx_drain_qp before destroying QPs attached to our SRQ.
+ * same CQ before destroying QPs attached to our SRQ.
  */
 
 enum ipoib_cm_state {
@@ -199,7 +199,6 @@ struct ipoib_cm_dev_priv {
        struct ib_srq          *srq;
        struct ipoib_cm_rx_buf *srq_ring;
        struct ib_cm_id        *id;
-       struct ib_qp           *rx_drain_qp;   /* generates WR described in 10.3.1 */
        struct list_head        passive_ids;   /* state: LIVE */
        struct list_head        rx_error_list; /* state: ERROR */
        struct list_head        rx_flush_list; /* state: FLUSH, drain not started */
@@ -429,6 +428,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
 
 void ipoib_pkey_poll(struct work_struct *work);
 int ipoib_pkey_dev_delay_open(struct net_device *dev);
+void ipoib_drain_cq(struct net_device *dev);
 
 #ifdef CONFIG_INFINIBAND_IPOIB_CM
 
index ffec794b7913d6470bc2f3409a9fadd93c446cb2..076a0bbb63d7a2a1ad582ba5fc4450942c38ef08 100644 (file)
@@ -69,8 +69,9 @@ static struct ib_qp_attr ipoib_cm_err_attr = {
 
 #define IPOIB_CM_RX_DRAIN_WRID 0x7fffffff
 
-static struct ib_recv_wr ipoib_cm_rx_drain_wr = {
-       .wr_id = IPOIB_CM_RX_DRAIN_WRID
+static struct ib_send_wr ipoib_cm_rx_drain_wr = {
+       .wr_id = IPOIB_CM_RX_DRAIN_WRID,
+       .opcode = IB_WR_SEND,
 };
 
 static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
@@ -163,16 +164,22 @@ partial_error:
 
 static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv* priv)
 {
-       struct ib_recv_wr *bad_wr;
+       struct ib_send_wr *bad_wr;
+       struct ipoib_cm_rx *p;
 
-       /* rx_drain_qp send queue depth is 1, so
+       /* We only reserved 1 extra slot in CQ for drain WRs, so
         * make sure we have at most 1 outstanding WR. */
        if (list_empty(&priv->cm.rx_flush_list) ||
            !list_empty(&priv->cm.rx_drain_list))
                return;
 
-       if (ib_post_recv(priv->cm.rx_drain_qp, &ipoib_cm_rx_drain_wr, &bad_wr))
-               ipoib_warn(priv, "failed to post rx_drain wr\n");
+       /*
+        * QPs on flush list are error state.  This way, a "flush
+        * error" WC will be immediately generated for each WR we post.
+        */
+       p = list_entry(priv->cm.rx_flush_list.next, typeof(*p), list);
+       if (ib_post_send(p->qp, &ipoib_cm_rx_drain_wr, &bad_wr))
+               ipoib_warn(priv, "failed to post drain wr\n");
 
        list_splice_init(&priv->cm.rx_flush_list, &priv->cm.rx_drain_list);
 }
@@ -199,10 +206,10 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev,
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ib_qp_init_attr attr = {
                .event_handler = ipoib_cm_rx_event_handler,
-               .send_cq = priv->cq, /* does not matter, we never send anything */
+               .send_cq = priv->cq, /* For drain WR */
                .recv_cq = priv->cq,
                .srq = priv->cm.srq,
-               .cap.max_send_wr = 1, /* FIXME: 0 Seems not to work */
+               .cap.max_send_wr = 1, /* For drain WR */
                .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
                .sq_sig_type = IB_SIGNAL_ALL_WR,
                .qp_type = IB_QPT_RC,
@@ -242,6 +249,27 @@ static int ipoib_cm_modify_rx_qp(struct net_device *dev,
                ipoib_warn(priv, "failed to modify QP to RTR: %d\n", ret);
                return ret;
        }
+
+       /*
+        * Current Mellanox HCA firmware won't generate completions
+        * with error for drain WRs unless the QP has been moved to
+        * RTS first. This work-around leaves a window where a QP has
+        * moved to error asynchronously, but this will eventually get
+        * fixed in firmware, so let's not error out if modify QP
+        * fails.
+        */
+       qp_attr.qp_state = IB_QPS_RTS;
+       ret = ib_cm_init_qp_attr(cm_id, &qp_attr, &qp_attr_mask);
+       if (ret) {
+               ipoib_warn(priv, "failed to init QP attr for RTS: %d\n", ret);
+               return 0;
+       }
+       ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
+       if (ret) {
+               ipoib_warn(priv, "failed to modify QP to RTS: %d\n", ret);
+               return 0;
+       }
+
        return 0;
 }
 
@@ -623,38 +651,11 @@ static void ipoib_cm_tx_completion(struct ib_cq *cq, void *tx_ptr)
 int ipoib_cm_dev_open(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       struct ib_qp_init_attr qp_init_attr = {
-               .send_cq = priv->cq,   /* does not matter, we never send anything */
-               .recv_cq = priv->cq,
-               .cap.max_send_wr = 1,  /* FIXME: 0 Seems not to work */
-               .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
-               .cap.max_recv_wr = 1,
-               .cap.max_recv_sge = 1, /* FIXME: 0 Seems not to work */
-               .sq_sig_type = IB_SIGNAL_ALL_WR,
-               .qp_type = IB_QPT_UC,
-       };
        int ret;
 
        if (!IPOIB_CM_SUPPORTED(dev->dev_addr))
                return 0;
 
-       priv->cm.rx_drain_qp = ib_create_qp(priv->pd, &qp_init_attr);
-       if (IS_ERR(priv->cm.rx_drain_qp)) {
-               printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
-               ret = PTR_ERR(priv->cm.rx_drain_qp);
-               return ret;
-       }
-
-       /*
-        * We put the QP in error state directly.  This way, a "flush
-        * error" WC will be immediately generated for each WR we post.
-        */
-       ret = ib_modify_qp(priv->cm.rx_drain_qp, &ipoib_cm_err_attr, IB_QP_STATE);
-       if (ret) {
-               ipoib_warn(priv, "failed to modify drain QP to error: %d\n", ret);
-               goto err_qp;
-       }
-
        priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
        if (IS_ERR(priv->cm.id)) {
                printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
@@ -676,8 +677,6 @@ err_listen:
        ib_destroy_cm_id(priv->cm.id);
 err_cm:
        priv->cm.id = NULL;
-err_qp:
-       ib_destroy_qp(priv->cm.rx_drain_qp);
        return ret;
 }
 
@@ -713,7 +712,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
        while (!list_empty(&priv->cm.rx_error_list) ||
               !list_empty(&priv->cm.rx_flush_list) ||
               !list_empty(&priv->cm.rx_drain_list)) {
-               if (!time_after(jiffies, begin + 5 * HZ)) {
+               if (time_after(jiffies, begin + 5 * HZ)) {
                        ipoib_warn(priv, "RX drain timing out\n");
 
                        /*
@@ -726,6 +725,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
                }
                spin_unlock_irq(&priv->lock);
                msleep(1);
+               ipoib_drain_cq(dev);
                spin_lock_irq(&priv->lock);
        }
 
@@ -739,7 +739,6 @@ void ipoib_cm_dev_stop(struct net_device *dev)
                kfree(p);
        }
 
-       ib_destroy_qp(priv->cm.rx_drain_qp);
        cancel_delayed_work(&priv->cm.stale_task);
 }
 
index c1aad06eb4e9b0222457b5c7efc8fc146a39b839..8404f05b2b6eefd04a018b5da67698b65cfb09fd 100644 (file)
@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev)
        return pending;
 }
 
+void ipoib_drain_cq(struct net_device *dev)
+{
+       struct ipoib_dev_priv *priv = netdev_priv(dev);
+       int i, n;
+       do {
+               n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+               for (i = 0; i < n; ++i) {
+                       if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
+                               ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+                       else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+                               ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+                       else
+                               ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+               }
+       } while (n == IPOIB_NUM_WC);
+}
+
 int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ib_qp_attr qp_attr;
        unsigned long begin;
        struct ipoib_tx_buf *tx_req;
-       int i, n;
+       int i;
 
        clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
        netif_poll_disable(dev);
@@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
                        goto timeout;
                }
 
-               do {
-                       n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
-                       for (i = 0; i < n; ++i) {
-                               if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
-                                       ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
-                               else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
-                                       ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
-                               else
-                                       ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
-                       }
-               } while (n == IPOIB_NUM_WC);
+               ipoib_drain_cq(dev);
 
                msleep(1);
        }
index b234729706be800789dced2c155629e2bb448d03..be6b93c20f606b9e477746e81688d7abe25bcdda 100644 (file)
@@ -699,9 +699,9 @@ static void evdev_disconnect(struct input_handle *handle)
        if (evdev->open) {
                input_flush_device(handle, NULL);
                input_close_device(handle);
-               wake_up_interruptible(&evdev->wait);
                list_for_each_entry(client, &evdev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+               wake_up_interruptible(&evdev->wait);
        } else
                evdev_free(evdev);
 }
index 06f0541b24daaaed730d448d7f5f68bfa2b05c40..10e3b7bc925fd7b68ca8e7bb418d39471caa776c 100644 (file)
@@ -594,9 +594,9 @@ static void joydev_disconnect(struct input_handle *handle)
 
        if (joydev->open) {
                input_close_device(handle);
-               wake_up_interruptible(&joydev->wait);
                list_for_each_entry(client, &joydev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+               wake_up_interruptible(&joydev->wait);
        } else
                joydev_free(joydev);
 }
index 86ad1027e12a1ceabeedc5df8911fdfd30fdbc12..b069ee18e35312078ec3cff1d6910d102dd851a7 100644 (file)
@@ -54,7 +54,7 @@ static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata;
 
 module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
 MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
-module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[0].nargs, 0);
+module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[1].nargs, 0);
 MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
 module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
 MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
index fb129c479a666124670bfba0652f01ba66fb5ba2..682244b1c0422610e9475020d83f67cb7fff51e4 100644 (file)
@@ -370,10 +370,8 @@ int iforce_init_device(struct iforce *iforce)
 
 /*
  * Disable spring, enable force feedback.
- * FIXME: We should use iforce_set_autocenter() et al here.
  */
-
-       iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
+       iforce_set_autocenter(input_dev, 0);
 
 /*
  * Find appropriate device entry
index 21c4e13d3a508c15e17c50d2b6b453aed7fcf5f4..3154ccd7400098d1110fca740ed8156bb2a7eb32 100644 (file)
@@ -246,6 +246,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
 
 int iforce_get_id_packet(struct iforce *iforce, char *packet)
 {
+       int status;
+
        switch (iforce->bus) {
 
        case IFORCE_USB:
@@ -254,18 +256,22 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
                iforce->cr.bRequest = packet[0];
                iforce->ctrl->dev = iforce->usbdev;
 
-               if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC))
+               status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC);
+               if (status) {
+                       err("usb_submit_urb failed %d", status);
                        return -1;
+               }
 
                wait_event_interruptible_timeout(iforce->wait,
                        iforce->ctrl->status != -EINPROGRESS, HZ);
 
                if (iforce->ctrl->status) {
+                       dbg("iforce->ctrl->status = %d", iforce->ctrl->status);
                        usb_unlink_urb(iforce->ctrl);
                        return -1;
                }
 #else
-               err("iforce_get_id_packet: iforce->bus = USB!");
+               dbg("iforce_get_id_packet: iforce->bus = USB!");
 #endif
                break;
 
index 750099d8e3c62dd36499793de5473a4c18dfce7e..1457b73850e7dd03e41fdb8df932342a3857b281 100644 (file)
@@ -65,6 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce)
        XMIT_INC(iforce->xmit.tail, n);
 
        if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
+               clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
                warn("usb_submit_urb failed %d\n", n);
        }
 
@@ -163,8 +164,8 @@ static int iforce_usb_probe(struct usb_interface *intf,
        usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
                        iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
 
-       usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
-                       iforce + 1, 32, iforce_usb_out, iforce);
+       usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
+                       iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval);
 
        usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
                        (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
index 06eaf766d9d2fc2ff9026598bb15ccbc847520b7..f9e82c9ca42191142dcab70ed8493072bc049d39 100644 (file)
@@ -104,7 +104,7 @@ static int pxakbd_open(struct input_dev *dev)
        KPREC = 0x7F;
 
        /* Enable unit clock */
-       pxa_set_cken(CKEN19_KEYPAD, 1);
+       pxa_set_cken(CKEN_KEYPAD, 1);
 
        return 0;
 }
@@ -112,7 +112,7 @@ static int pxakbd_open(struct input_dev *dev)
 static void pxakbd_close(struct input_dev *dev)
 {
        /* Disable clock unit */
-       pxa_set_cken(CKEN19_KEYPAD, 0);
+       pxa_set_cken(CKEN_KEYPAD, 0);
 }
 
 #ifdef CONFIG_PM
@@ -185,7 +185,7 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
                            DRIVER_NAME, pdev);
        if (error) {
                printk(KERN_ERR "Cannot request keypad IRQ\n");
-               pxa_set_cken(CKEN19_KEYPAD, 0);
+               pxa_set_cken(CKEN_KEYPAD, 0);
                goto err_free_dev;
        }
 
index 1b2b9c9c5d88f405f3b1e2dca2303df9e723e22c..b773d4c756a61333d1e5d65ae5cc282cbe01815b 100644 (file)
 #include <linux/mutex.h>
 #include <linux/input-polldev.h>
 
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic implementation of a polled input device");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
 static DEFINE_MUTEX(polldev_mutex);
 static int polldev_users;
 static struct workqueue_struct *polldev_wq;
index eb0167e9f0cbe66a591ba65c90dffadb5103daff..50e06e8dd05d764a2af87fe7aa8d5c5e6f52db94 100644 (file)
@@ -48,7 +48,7 @@ config MOUSE_PS2_ALPS
          If unsure, say Y.
 
 config MOUSE_PS2_LOGIPS2PP
-       bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED
+       bool "Logitech PS/2++ mouse protocol extension" if EMBEDDED
        default y
        depends on MOUSE_PS2
        help
index cf3e4664e72bc59cf36ffb4a7987ae7fed3140f0..2c5f11a4f6b410f1c2fbff3f50b42ca0bcfc7b1e 100644 (file)
@@ -251,11 +251,15 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
 
        dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
 
-       for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
-       *version = (param[0] << 8) | (param[1] << 4) | i;
+       if (version) {
+               for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
+                       /* empty */;
+               *version = (param[0] << 8) | (param[1] << 4) | i;
+       }
 
        for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
-               if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
+               if (!memcmp(param, alps_model_data[i].signature,
+                           sizeof(alps_model_data[i].signature)))
                        return alps_model_data + i;
 
        return NULL;
@@ -380,32 +384,46 @@ static int alps_poll(struct psmouse *psmouse)
        return 0;
 }
 
-static int alps_reconnect(struct psmouse *psmouse)
+static int alps_hw_init(struct psmouse *psmouse, int *version)
 {
        struct alps_data *priv = psmouse->private;
-       int version;
-
-       psmouse_reset(psmouse);
 
-       if (!(priv->i = alps_get_model(psmouse, &version)))
+       priv->i = alps_get_model(psmouse, version);
+       if (!priv->i)
                return -1;
 
        if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
                return -1;
 
        if (alps_tap_mode(psmouse, 1)) {
-               printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n");
+               printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
                return -1;
        }
 
        if (alps_absolute_mode(psmouse)) {
-               printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n");
+               printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
                return -1;
        }
 
        if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
                return -1;
 
+       /* ALPS needs stream mode, otherwise it won't report any data */
+       if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
+               printk(KERN_ERR "alps.c: Failed to enable stream mode\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int alps_reconnect(struct psmouse *psmouse)
+{
+       psmouse_reset(psmouse);
+
+       if (alps_hw_init(psmouse, NULL))
+               return -1;
+
        return 0;
 }
 
@@ -430,23 +448,9 @@ int alps_init(struct psmouse *psmouse)
                goto init_fail;
 
        priv->dev2 = dev2;
+       psmouse->private = priv;
 
-       priv->i = alps_get_model(psmouse, &version);
-       if (!priv->i)
-               goto init_fail;
-
-       if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
-               goto init_fail;
-
-       if (alps_tap_mode(psmouse, 1))
-               printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
-
-       if (alps_absolute_mode(psmouse)) {
-               printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
-               goto init_fail;
-       }
-
-       if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+       if (alps_hw_init(psmouse, &version))
                goto init_fail;
 
        dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
@@ -493,13 +497,13 @@ int alps_init(struct psmouse *psmouse)
        /* We are having trouble resyncing ALPS touchpads so disable it for now */
        psmouse->resync_time = 0;
 
-       psmouse->private = priv;
        return 0;
 
 init_fail:
        psmouse_reset(psmouse);
        input_free_device(dev2);
        kfree(priv);
+       psmouse->private = NULL;
        return -1;
 }
 
index 9df74b72e6c4669c5d5ecd2863ae4f02aeff8437..0c5660d28caa18bafb5d3ab62a9219f3fc1c96ec 100644 (file)
@@ -221,6 +221,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
                { 66,   PS2PP_KIND_MX,                                  /* MX3100 reciver */
                                PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
                                PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
+               { 72,   PS2PP_KIND_TRACKMAN,    0 },                    /* T-CH11: TrackMan Marble */
                { 73,   0,                      PS2PP_SIDE_BTN },
                { 75,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 76,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
index 8675f95093935069718d6fe8cf49d8c80ac1fbd9..3f4866d8d18c85a8dae983273ba578e2e1df3d8f 100644 (file)
@@ -766,9 +766,9 @@ static void mousedev_disconnect(struct input_handle *handle)
 
        if (mousedev->open) {
                input_close_device(handle);
-               wake_up_interruptible(&mousedev->wait);
                list_for_each_entry(client, &mousedev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+               wake_up_interruptible(&mousedev->wait);
        } else
                mousedev_free(mousedev);
 }
index 559508795af1887df6ac98c028cd22ebd5eb5bed..d31ece8f68e93df7ea82f61c949f48a64326d28c 100644 (file)
@@ -170,7 +170,7 @@ static void ps2_close(struct serio *io)
 /*
  * Clear the input buffer.
  */
-static void __init ps2_clear_input(struct ps2if *ps2if)
+static void __devinit ps2_clear_input(struct ps2if *ps2if)
 {
        int maxread = 100;
 
@@ -228,7 +228,7 @@ static int __init ps2_test(struct ps2if *ps2if)
 /*
  * Add one device to this driver.
  */
-static int ps2_probe(struct sa1111_dev *dev)
+static int __devinit ps2_probe(struct sa1111_dev *dev)
 {
        struct ps2if *ps2if;
        struct serio *serio;
index 4f091800bfebd30daa41b00fb96a93c2b9911eb2..e5cca9bd040632bcbe7d7064a63ca4394c077e3d 100644 (file)
@@ -12,17 +12,17 @@ menuconfig INPUT_TOUCHSCREEN
 if INPUT_TOUCHSCREEN
 
 config TOUCHSCREEN_ADS7846
-       tristate "ADS 7846/7843 based touchscreens"
+       tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
        depends on SPI_MASTER
        depends on HWMON = n || HWMON
        help
          Say Y here if you have a touchscreen interface using the
-         ADS7846 or ADS7843 controller, and your board-specific setup
-         code includes that in its table of SPI devices.
+         ADS7846/TSC2046 or ADS7843 controller, and your board-specific
+         setup code includes that in its table of SPI devices.
 
          If HWMON is selected, and the driver is told the reference voltage
          on your board, you will also get hwmon interfaces for the voltage
-         (and on ads7846, temperature) sensors of this chip.
+         (and on ads7846/tsc2046, temperature) sensors of this chip.
 
          If unsure, say N (but it's safe to say "Y").
 
index 693e3b2a65a35e0a8c4c6f20ee93fa0018b6fa47..1c9069cd3bae4228fe1ed142c8c6543b4467ad11 100644 (file)
@@ -39,6 +39,7 @@
 /*
  * This code has been heavily tested on a Nokia 770, and lightly
  * tested on other ads7846 devices (OSK/Mistral, Lubbock).
+ * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
  *
@@ -847,7 +848,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
         * may not.  So we stick to very-portable 8 bit words, both RX and TX.
         */
        spi->bits_per_word = 8;
-       spi->mode = SPI_MODE_1;
+       spi->mode = SPI_MODE_0;
        err = spi_setup(spi);
        if (err < 0)
                return err;
index 6582816a04778806f773d53b16d64908cbd6d451..f0cbcdb008edd424b06a845c292e500c803058d2 100644 (file)
@@ -288,9 +288,9 @@ static int ucb1400_ts_thread(void *_ucb)
        struct ucb1400 *ucb = _ucb;
        struct task_struct *tsk = current;
        int valid = 0;
+       struct sched_param param = { .sched_priority = 1 };
 
-       tsk->policy = SCHED_FIFO;
-       tsk->rt_priority = 1;
+       sched_setscheduler(tsk, SCHED_FIFO, &param);
 
        while (!kthread_should_stop()) {
                unsigned int x, y, p;
index 8238b13874c200f33ee5ff7534dc7264e9d81919..2db364898e15f434e852c304bbcb855e271de00b 100644 (file)
@@ -476,9 +476,9 @@ static void tsdev_disconnect(struct input_handle *handle)
 
        if (tsdev->open) {
                input_close_device(handle);
-               wake_up_interruptible(&tsdev->wait);
                list_for_each_entry(client, &tsdev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+               wake_up_interruptible(&tsdev->wait);
        } else
                tsdev_free(tsdev);
 }
index d42fe89cddf6987648eddd2200c8c01f33eda709..3e088c42b2227befb07699a8e0ae38e4a5169f0a 100644 (file)
@@ -26,9 +26,9 @@ menu "Old ISDN4Linux"
        depends on NET && ISDN
 
 config ISDN_I4L
-       tristate "Old ISDN4Linux (obsolete)"
+       tristate "Old ISDN4Linux (deprecated)"
        ---help---
-         This driver allows you to use an ISDN-card for networking
+         This driver allows you to use an ISDN adapter for networking
          connections and as dialin/out device.  The isdn-tty's have a built
          in AT-compatible modem emulator.  Network devices support autodial,
          channel-bundling, callback and caller-authentication without having
@@ -39,8 +39,9 @@ config ISDN_I4L
 
          ISDN support in the linux kernel is moving towards a new API,
          called CAPI (Common ISDN Application Programming Interface).
-         Therefore the old ISDN4Linux layer is becoming obsolete. It is 
-         still usable, though, if you select this option.
+         Therefore the old ISDN4Linux layer will eventually become obsolete.
+         It is still available, though, for use with adapters that are not
+         supported by the new CAPI subsystem yet.
 
 if ISDN_I4L
 source "drivers/isdn/i4l/Kconfig"
index ff284aeb8fbb8ed6e843f96ce72beaef07acd78c..82edc1c1db7a685127498fcfecffc46db5e594dc 100644 (file)
@@ -189,21 +189,21 @@ void *TransmitBufferSet(APPL * appl, dword ref)
 {
        appl->xbuffer_used[ref] = true;
        DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
-           return (void *) ref;
+           return (void *)(long)ref;
 }
 
 void *TransmitBufferGet(APPL * appl, void *p)
 {
-       if (appl->xbuffer_internal[(dword) p])
-               return appl->xbuffer_internal[(dword) p];
+       if (appl->xbuffer_internal[(dword)(long)p])
+               return appl->xbuffer_internal[(dword)(long)p];
 
-       return appl->xbuffer_ptr[(dword) p];
+       return appl->xbuffer_ptr[(dword)(long)p];
 }
 
 void TransmitBufferFree(APPL * appl, void *p)
 {
-       appl->xbuffer_used[(dword) p] = false;
-       DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1))
+       appl->xbuffer_used[(dword)(long)p] = false;
+       DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
 }
 
 void *ReceiveBufferGet(APPL * appl, int Num)
@@ -301,7 +301,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
        /* if DATA_B3_IND, copy data too */
        if (command == _DATA_B3_I) {
                dword data = GET_DWORD(&msg.info.data_b3_ind.Data);
-               memcpy(write + length, (void *) data, dlength);
+               memcpy(write + length, (void *)(long)data, dlength);
        }
 
 #ifndef DIVA_NO_DEBUGLIB
@@ -318,7 +318,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
                        if (myDriverDebugHandle.dbgMask & DL_BLK) {
                                xlog("\x00\x02", &msg, 0x81, length);
                                for (i = 0; i < dlength; i += 256) {
-                                 DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
+                                 DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
                                        ((dlength - i) < 256) ? (dlength - i) : 256))
                                  if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
                                          break; /* not more if not explicitely requested */
index 14298b8c835fedc6ea3334a461e481d64735a94a..d755d904e62c693fec2d5444e09e4c677eb5ff40 100644 (file)
@@ -99,7 +99,7 @@ static int DIVA_INIT_FUNCTION create_proc(void)
        return (0);
 }
 
-static void DIVA_EXIT_FUNCTION remove_proc(void)
+static void remove_proc(void)
 {
        remove_proc_entry(DRIVERLNAME, proc_net_eicon);
        remove_proc_entry("net/eicon", NULL);
index df61e510a28be7ca4b71c091a330d06713b3b160..d36a4c09e25db2b5d8ee558ab2bf31664455e508 100644 (file)
@@ -195,7 +195,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
 /*
  * disconnect from didd
  */
-static void DIVA_EXIT_FUNCTION disconnect_didd(void)
+static void disconnect_didd(void)
 {
        IDI_SYNC_REQ req;
 
@@ -231,7 +231,7 @@ int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
 /*
  * exit
  */
-void DIVA_EXIT_FUNCTION divasfunc_exit(void)
+void divasfunc_exit(void)
 {
        divasa_xdi_driver_unload();
        disconnect_didd();
index 784232a144c8155d15cb4fa206c33a3ace9ebdaa..ccd35d047ec8c314dc337e827ca3ad58b45ae767 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  *
   Copyright (c) Eicon Networks, 2002.
@@ -533,7 +532,7 @@ word api_put(APPL   * appl, CAPI_MSG   * msg)
         if (m->header.command == _DATA_B3_R)
         {
 
-          m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
+          m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
 
         }
 
@@ -1032,7 +1031,7 @@ static void plci_free_msg_in_queue (PLCI   *plci)
       {
 
         TransmitBufferFree (plci->appl,
-          (byte   *)(((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
+          (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
 
       }
 
@@ -3118,7 +3117,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci,
        && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
       {
 
-        data->P = (byte   *)(*((dword   *)(parms[0].info)));
+        data->P = (byte *)(long)(*((dword *)(parms[0].info)));
 
       }
       else
@@ -3151,7 +3150,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci,
        && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
       {
 
-        TransmitBufferFree (appl, (byte   *)(*((dword   *)(parms[0].info))));
+        TransmitBufferFree (appl, (byte *)(long)(*((dword *)(parms[0].info))));
 
       }
     }
@@ -4057,7 +4056,7 @@ capi_callback_suffix:
     {
       if (m->header.command == _DATA_B3_R)
 
-        TransmitBufferFree (appl, (byte   *)(m->info.data_b3_req.Data));
+        TransmitBufferFree (appl, (byte *)(long)(m->info.data_b3_req.Data));
 
       dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
       break;
@@ -7134,7 +7133,7 @@ void nl_ind(PLCI   * plci)
   case N_UDATA:
     if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
     {
-      plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3);
+      plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
       plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
       plci->NL.R = plci->RData;
       plci->NL.RNum = 1;
index da4196f21e0fcc555398e110baa07ffa96830e6a..8d53a7fd2671f557cff40d6ebeb4bb724eda29b9 100644 (file)
@@ -1551,7 +1551,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
        if (retval == 0) { // yuck
                cards[i].typ = 0;
                nrcards--;
-               return retval;
+               return -EINVAL;
        }
        cs = cards[i].cs;
        hisax_d_if->cs = cs;
index 1f18f19933876d08ba94e2e4fde007cd7c52fa6a..b1a26e02df0263476c53a7de9faf9385ba94c26d 100644 (file)
@@ -485,7 +485,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
 {
        int k;
 
-       spin_lock_init(&urb->lock);
        urb->dev = dev;
        urb->pipe = pipe;
        urb->complete = complete;
@@ -578,16 +577,14 @@ stop_isoc_chain(usb_fifo * fifo)
                            "HFC-S USB: Stopping iso chain for fifo %i.%i",
                            fifo->fifonum, i);
 #endif
-                       usb_unlink_urb(fifo->iso[i].purb);
+                       usb_kill_urb(fifo->iso[i].purb);
                        usb_free_urb(fifo->iso[i].purb);
                        fifo->iso[i].purb = NULL;
                }
        }
-       if (fifo->urb) {
-               usb_unlink_urb(fifo->urb);
-               usb_free_urb(fifo->urb);
-               fifo->urb = NULL;
-       }
+       usb_kill_urb(fifo->urb);
+       usb_free_urb(fifo->urb);
+       fifo->urb = NULL;
        fifo->active = 0;
 }
 
@@ -1305,7 +1302,11 @@ usb_init(hfcusb_data * hfc)
        }
        /* default Prot: EURO ISDN, should be a module_param */
        hfc->protocol = 2;
-       hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+       i = hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+       if (i) {
+               printk(KERN_INFO "HFC-S USB: hisax_register -> %d\n", i);
+               return i;
+       }
 
 #ifdef CONFIG_HISAX_DEBUG
        hfc_debug = debug;
@@ -1626,11 +1627,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 #endif
                        /* init the chip and register the driver */
                        if (usb_init(context)) {
-                               if (context->ctrl_urb) {
-                                       usb_unlink_urb(context->ctrl_urb);
-                                       usb_free_urb(context->ctrl_urb);
-                                       context->ctrl_urb = NULL;
-                               }
+                               usb_kill_urb(context->ctrl_urb);
+                               usb_free_urb(context->ctrl_urb);
+                               context->ctrl_urb = NULL;
                                kfree(context);
                                return (-EIO);
                        }
@@ -1682,21 +1681,15 @@ hfc_usb_disconnect(struct usb_interface
                                    i);
 #endif
                        }
-                       if (context->fifos[i].urb) {
-                               usb_unlink_urb(context->fifos[i].urb);
-                               usb_free_urb(context->fifos[i].urb);
-                               context->fifos[i].urb = NULL;
-                       }
+                       usb_kill_urb(context->fifos[i].urb);
+                       usb_free_urb(context->fifos[i].urb);
+                       context->fifos[i].urb = NULL;
                }
                context->fifos[i].active = 0;
        }
-       /* wait for all URBS to terminate */
-       mdelay(10);
-       if (context->ctrl_urb) {
-               usb_unlink_urb(context->ctrl_urb);
-               usb_free_urb(context->ctrl_urb);
-               context->ctrl_urb = NULL;
-       }
+       usb_kill_urb(context->ctrl_urb);
+       usb_free_urb(context->ctrl_urb);
+       context->ctrl_urb = NULL;
        hisax_unregister(&context->d_if);
        kfree(context);         /* free our structure again */
 }                              /* hfc_usb_disconnect */
index 9e088fce8c3afb8d032a30e715ff08d6fec89066..7993e01f9fc5cd08e22e0caac469e7208b2e3930 100644 (file)
@@ -859,7 +859,11 @@ new_adapter(void)
        for (i = 0; i < 2; i++)
                b_if[i] = &adapter->bcs[i].b_if;
 
-       hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
+       if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
+                       protocol) != 0) {
+               kfree(adapter);
+               adapter = NULL;
+       }
 
        return adapter;
 }
index bb3a28a53ff4de2536b06095a54f2516832cef25..13751237bfcde6d861122cc84ca6c18605ea8dee 100644 (file)
@@ -107,12 +107,17 @@ static int probe_st5481(struct usb_interface *intf,
        for (i = 0; i < 2; i++)
                b_if[i] = &adapter->bcs[i].b_if;
 
-       hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol);
+       if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
+                       protocol) != 0)
+               goto err_b1;
+
        st5481_start(adapter);
 
        usb_set_intfdata(intf, adapter);
        return 0;
 
+ err_b1:
+       st5481_release_b(&adapter->bcs[1]);
  err_b:
        st5481_release_b(&adapter->bcs[0]);
  err_d:
index ff159512204880f35a90c8eee8a9c747191a4e68..4ada66b8b6792e2eb1025479a610fb6fb5d980c3 100644 (file)
@@ -407,7 +407,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
 {
        int k;
 
-       spin_lock_init(&urb->lock);
        urb->dev=dev;
        urb->pipe=pipe;
        urb->interval = 1;
index ea5f30d4a5a23377bd2527211081b6bd0ff3e278..4e5f87c1e71413bb3d15d65e5edf3ae011746b20 100644 (file)
@@ -2693,8 +2693,9 @@ isdn_tty_getdial(char *p, char *q,int cnt)
        int limit = ISDN_MSNLEN - 1;    /* MUST match the size of interface var to avoid
                                        buffer overflow */
 
-       while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) {
+       while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt>0) {
                if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) ||
+                   ((*p == 'R') && first) ||
                    (*p == '*') || (*p == '#')) {
                        *q++ = *p;
                        limit--;
index e6e4d240b2a6aa945ae2e2155bcba1901b10de77..184238e2ece4679ce04f68f455033d93b1710af5 100644 (file)
@@ -639,7 +639,7 @@ static void free_vmcs(struct vmcs *vmcs)
        free_pages((unsigned long)vmcs, vmcs_descriptor.order);
 }
 
-static __exit void free_kvm_area(void)
+static void free_kvm_area(void)
 {
        int cpu;
 
index 58926da0ae18c48a977b38fd6d9c67fe879ba805..ee699a7d62148ba05efe4bb3b11ca31524f9b462 100644 (file)
@@ -113,9 +113,8 @@ config PMAC_SMU
 
 config PMAC_APM_EMU
        tristate "APM emulation"
-       select SYS_SUPPORTS_APM_EMULATION
        select APM_EMULATION
-       depends on ADB_PMU && PM
+       depends on ADB_PMU && PM && PPC32
 
 config PMAC_MEDIABAY
        bool "Support PowerBook hotswap media bay"
index b77ef5187d6d0e6488217e9a38c9000ada5d8716..b46817f699f157899257907d0c77cbf113d61573 100644 (file)
@@ -628,16 +628,16 @@ static void real_leds(unsigned char leds, int device)
  */
 static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
-       struct adbhid *adbhid = dev->private;
+       struct adbhid *adbhid = input_get_drvdata(dev);
        unsigned char leds;
 
        switch (type) {
        case EV_LED:
-         leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0)
-              | (test_bit(LED_NUML,    dev->led) ? 1 : 0)
-              | (test_bit(LED_CAPSL,   dev->led) ? 2 : 0);
-         real_leds(leds, adbhid->id);
-         return 0;
+               leds =  (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) |
+                       (test_bit(LED_NUML,    dev->led) ? 1 : 0) |
+                       (test_bit(LED_CAPSL,   dev->led) ? 2 : 0);
+               real_leds(leds, adbhid->id);
+               return 0;
        }
 
        return -1;
@@ -649,7 +649,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
        switch (code) {
        case ADB_MSG_PRE_RESET:
        case ADB_MSG_POWERDOWN:
-               /* Stop the repeat timer. Autopoll is already off at this point */
+               /* Stop the repeat timer. Autopoll is already off at this point */
                {
                        int i;
                        for (i = 1; i < 16; i++) {
@@ -699,7 +699,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
        hid->current_handler_id = current_handler_id;
        hid->mouse_kind = mouse_kind;
        hid->flags = 0;
-       input_dev->private = hid;
+       input_set_drvdata(input_dev, hid);
        input_dev->name = hid->name;
        input_dev->phys = hid->phys;
        input_dev->id.bustype = BUS_ADB;
index 5a4a74c1097c6ce80eb38e726954304dbb25bc53..9620d452d030d1fdc413c10adaa20561b37d357b 100644 (file)
@@ -255,19 +255,25 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
 
 }
 
-static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
+static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
 {
        mdk_rdev_t *rdev;
        struct list_head *tmp;
+       mddev_t *mddev = bitmap->mddev;
 
        ITERATE_RDEV(mddev, rdev, tmp)
                if (test_bit(In_sync, &rdev->flags)
-                   && !test_bit(Faulty, &rdev->flags))
+                   && !test_bit(Faulty, &rdev->flags)) {
+                       int size = PAGE_SIZE;
+                       if (page->index == bitmap->file_pages-1)
+                               size = roundup(bitmap->last_page_size,
+                                              bdev_hardsect_size(rdev->bdev));
                        md_super_write(mddev, rdev,
-                                      (rdev->sb_offset<<1) + offset
+                                      (rdev->sb_offset<<1) + bitmap->offset
                                       + page->index * (PAGE_SIZE/512),
-                                      PAGE_SIZE,
+                                      size,
                                       page);
+               }
 
        if (wait)
                md_super_wait(mddev);
@@ -282,7 +288,7 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
        struct buffer_head *bh;
 
        if (bitmap->file == NULL)
-               return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
+               return write_sb_page(bitmap, page, wait);
 
        bh = page_buffers(page);
 
@@ -923,6 +929,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
                        }
 
                        bitmap->filemap[bitmap->file_pages++] = page;
+                       bitmap->last_page_size = count;
                }
                paddr = kmap_atomic(page, KM_USER0);
                if (bitmap->flags & BITMAP_HOSTENDIAN)
index d5ecd2d53046ab5510b520df48813debdc45d3c8..192741083196f25d7c75ab85bf2aaeb167a2e09d 100644 (file)
@@ -139,8 +139,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
        if (!conf)
                return NULL;
 
-       mddev->private = conf;
-
        cnt = 0;
        conf->array_size = 0;
 
@@ -232,7 +230,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
         * First calculate the device offsets.
         */
        conf->disks[0].offset = 0;
-       for (i=1; i<mddev->raid_disks; i++)
+       for (i = 1; i < raid_disks; i++)
                conf->disks[i].offset =
                        conf->disks[i-1].offset +
                        conf->disks[i-1].size;
@@ -244,7 +242,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
             curr_offset < conf->array_size;
             curr_offset += conf->hash_spacing) {
 
-               while (i < mddev->raid_disks-1 &&
+               while (i < raid_disks-1 &&
                       curr_offset >= conf->disks[i+1].offset)
                        i++;
 
@@ -299,9 +297,11 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
         */
        linear_conf_t *newconf;
 
-       if (rdev->raid_disk != mddev->raid_disks)
+       if (rdev->saved_raid_disk != mddev->raid_disks)
                return -EINVAL;
 
+       rdev->raid_disk = rdev->saved_raid_disk;
+
        newconf = linear_conf(mddev,mddev->raid_disks+1);
 
        if (!newconf)
index c10ce91b64e9b432cbe797df44b7d605aa7a4609..1c54f3c1cca74fca038b5b4452c9a0504e481e57 100644 (file)
@@ -1298,8 +1298,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        ITERATE_RDEV(mddev,rdev2,tmp)
                if (rdev2->desc_nr+1 > max_dev)
                        max_dev = rdev2->desc_nr+1;
-       
-       sb->max_dev = cpu_to_le32(max_dev);
+
+       if (max_dev > le32_to_cpu(sb->max_dev))
+               sb->max_dev = cpu_to_le32(max_dev);
        for (i=0; i<max_dev;i++)
                sb->dev_roles[i] = cpu_to_le16(0xfffe);
        
@@ -1365,10 +1366,14 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
        }
        /* make sure rdev->size exceeds mddev->size */
        if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
-               if (mddev->pers)
-                       /* Cannot change size, so fail */
-                       return -ENOSPC;
-               else
+               if (mddev->pers) {
+                       /* Cannot change size, so fail
+                        * If mddev->level <= 0, then we don't care
+                        * about aligning sizes (e.g. linear)
+                        */
+                       if (mddev->level > 0)
+                               return -ENOSPC;
+               } else
                        mddev->size = rdev->size;
        }
 
@@ -2142,6 +2147,9 @@ static void analyze_sbs(mddev_t * mddev)
                        rdev->desc_nr = i++;
                        rdev->raid_disk = rdev->desc_nr;
                        set_bit(In_sync, &rdev->flags);
+               } else if (rdev->raid_disk >= mddev->raid_disks) {
+                       rdev->raid_disk = -1;
+                       clear_bit(In_sync, &rdev->flags);
                }
        }
 
index dfe32149ad3ae1b0caf77fc39003d82cb640f3f7..2c404f73a377d4c73ea95ecaf98e2c1c44f823f6 100644 (file)
@@ -415,7 +415,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
        raid0_conf_t *conf = mddev_to_conf(mddev);
        struct strip_zone *zone;
        mdk_rdev_t *tmp_dev;
-       unsigned long chunk;
+       sector_t chunk;
        sector_t block, rsect;
        const int rw = bio_data_dir(bio);
 
@@ -470,7 +470,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
 
                sector_div(x, zone->nb_dev);
                chunk = x;
-               BUG_ON(x != (sector_t)chunk);
 
                x = block >> chunksize_bits;
                tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];
index c120114c241b327458af773e270d66efa6a17286..5c63c8e24ee74babe23ec1dcdd2434a8e45b30dd 100644 (file)
@@ -4,5 +4,6 @@ config VIDEO_SAA7146
 
 config VIDEO_SAA7146_VV
        tristate
+       depends on VIDEO_DEV
        select VIDEO_BUF
        select VIDEO_SAA7146
index 1a1c3bca55fa33a96bccbb9ab7879b17df71e0df..bff00b58bf65309ecec1b2cc723b6c885f59fcff 100644 (file)
@@ -1,8 +1,11 @@
 b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
-       flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
-       flexcop-dma.o
+       flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
 b2c2-flexcop-pci-objs = flexcop-pci.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
 
index 34d7abc900d7b6cd92994cc3a81af680fd1cb9d1..6aba5b39ed144c2e1476ad993fec4b0f1fb51157 100644 (file)
@@ -519,8 +519,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
-       if (mutex_lock_interruptible(&cinergyt2->sem))
-               return -ERESTARTSYS;
+       mutex_lock(&cinergyt2->sem);
 
        if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
                cancel_delayed_work(&cinergyt2->query_work);
index ccc429cbbad0421be88269d3fc30f0b258941485..0f2d4b415560f75fdc1132de3ae68c6f82e4628b 100644 (file)
@@ -41,6 +41,7 @@ struct tda10086_state {
        /* private demod data */
        u32 frequency;
        u32 symbol_rate;
+       bool has_lock;
 };
 
 static int debug = 0;
@@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
        // misc setup
        tda10086_write_byte(state, 0x01, 0x94);
        tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
-       tda10086_write_byte(state, 0x03, 0x64);
+       tda10086_write_byte(state, 0x03, 0xe4);
        tda10086_write_byte(state, 0x04, 0x43);
        tda10086_write_byte(state, 0x0c, 0x0c);
        tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
@@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
        // setup AGC
        tda10086_write_byte(state, 0x05, 0x0B);
        tda10086_write_byte(state, 0x37, 0x63);
-       tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
+       tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
        tda10086_write_byte(state, 0x40, 0x64);
        tda10086_write_byte(state, 0x41, 0x4f);
        tda10086_write_byte(state, 0x42, 0x43);
@@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
 
        dprintk ("%s\n", __FUNCTION__);
 
+       // modify parameters for tuning
+       tda10086_write_byte(state, 0x02, 0x35);
+       state->has_lock = false;
+
        // set params
        if (fe->ops.tuner_ops.set_params) {
                fe->ops.tuner_ops.set_params(fe, fe_params);
@@ -542,8 +547,14 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
                *fe_status |= FE_HAS_VITERBI;
        if (val & 0x08)
                *fe_status |= FE_HAS_SYNC;
-       if (val & 0x10)
+       if (val & 0x10) {
                *fe_status |= FE_HAS_LOCK;
+               if (!state->has_lock) {
+                       state->has_lock = true;
+                       // modify parameters for stable reception
+                       tda10086_write_byte(state, 0x02, 0x00);
+               }
+       }
 
        return 0;
 }
@@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
 
        dprintk ("%s\n", __FUNCTION__);
 
-       _str = tda10086_read_byte(state, 0x43);
+       _str = 0xff - tda10086_read_byte(state, 0x43);
        *signal = (_str << 8) | _str;
 
        return 0;
@@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
 
        dprintk ("%s\n", __FUNCTION__);
 
-       _snr = tda10086_read_byte(state, 0x1c);
+       _snr = 0xff - tda10086_read_byte(state, 0x1c);
        *snr = (_snr << 8) | _snr;
 
        return 0;
index 79f971dc52b6d3bbe4a65b67df3f87744a975135..bd3ebc2848352b75301f08d6bcafd771ec629564 100644 (file)
@@ -89,8 +89,8 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
        buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
        buf[3] = div >> 7;
        buf[4] = div << 1;
-       buf[5] = 0xff; // basedband filter to max
-       buf[6] = 0xfe; // gains at max + no RF attenuation
+       buf[5] = 0x77; // baseband cut-off 19 MHz
+       buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
        buf[7] = 0x83; // charge pumps at high, tests off
        buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
        buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
index 5cb3f54b548b1dc9f678d486cafa5b8026c58135..4cca55170e21f78f9425fff3d829cffe8d575bb1 100644 (file)
@@ -347,7 +347,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 && PCI && VIDEO_DEV
        select VIDEO_BUF
        default n
        ---help---
index 15012f88b802825b5b8bbf752b27aa7285d60d17..91e9e90c14a5eaebe90677f3aa165ced92d0c956 100644 (file)
@@ -86,7 +86,7 @@
                          V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
                          V4L2_CAP_SLICED_VBI_CAPTURE)
 #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
-                         V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
+                         V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
 
 struct ivtv_card_video_input {
        u8  video_type;         /* video input type */
index e29f949adf57d255a67b9967dc90d6ce01fa22e9..efc66355339ac7f8aa6d693c753c20afd006b594 100644 (file)
@@ -652,6 +652,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->dma_timer.data = (unsigned long)itv;
 
        itv->cur_dma_stream = -1;
+       itv->cur_pio_stream = -1;
        itv->audio_stereo_mode = AUDIO_STEREO;
        itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
 
index 552f04511eadf9ff11373d7640163c1cde0a9d64..e6e56f175f3fe1a1da7b2b96849795256d851ce5 100644 (file)
@@ -237,6 +237,7 @@ extern const u32 yuv_offset[4];
 #define IVTV_IRQ_ENC_VBI_CAP           (0x1 << 29)
 #define IVTV_IRQ_ENC_VIM_RST           (0x1 << 28)
 #define IVTV_IRQ_ENC_DMA_COMPLETE      (0x1 << 27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE      (0x1 << 25)
 #define IVTV_IRQ_DEC_AUD_MODE_CHG      (0x1 << 24)
 #define IVTV_IRQ_DEC_DATA_REQ          (0x1 << 22)
 #define IVTV_IRQ_DEC_DMA_COMPLETE      (0x1 << 20)
@@ -247,7 +248,8 @@ extern const u32 yuv_offset[4];
 #define IVTV_IRQ_DEC_VSYNC             (0x1 << 10)
 
 /* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
+#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
+               IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
 
 #define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
 #define IVTV_IRQ_MASK_DECODE  (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
@@ -374,6 +376,9 @@ struct ivtv_mailbox_data {
 #define IVTV_F_S_STREAMOFF     7       /* signal end of stream EOS */
 #define IVTV_F_S_APPL_IO        8      /* this stream is used read/written by an application */
 
+#define IVTV_F_S_PIO_PENDING   9       /* this stream has pending PIO */
+#define IVTV_F_S_PIO_HAS_VBI   1       /* the current PIO request also requests VBI data */
+
 /* per-ivtv, i_flags */
 #define IVTV_F_I_DMA              0    /* DMA in progress */
 #define IVTV_F_I_UDMA             1    /* UDMA in progress */
@@ -390,8 +395,11 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_DECODING_YUV     12   /* this stream is YUV frame decoding */
 #define IVTV_F_I_ENC_PAUSED       13   /* the encoder is paused */
 #define IVTV_F_I_VALID_DEC_TIMINGS 14  /* last_dec_timing is valid */
-#define IVTV_F_I_WORK_HANDLER_VBI  15  /* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV  16  /* there is work to be done for YUV */
+#define IVTV_F_I_HAVE_WORK        15   /* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_WORK_HANDLER_VBI  16  /* there is work to be done for VBI */
+#define IVTV_F_I_WORK_HANDLER_YUV  17  /* there is work to be done for YUV */
+#define IVTV_F_I_WORK_HANDLER_PIO  18  /* there is work to be done for PIO */
+#define IVTV_F_I_PIO              19   /* PIO in progress */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED           28   /* decoder stopped event */
@@ -484,6 +492,7 @@ struct ivtv_stream {
 
        /* Base Dev SG Array for cx23415/6 */
        struct ivtv_SG_element *SGarray;
+       struct ivtv_SG_element *PIOarray;
        dma_addr_t SG_handle;
        int SG_length;
 
@@ -706,6 +715,7 @@ struct ivtv {
        atomic_t decoding;      /* count number of active decoding streams */
        u32 irq_rr_idx; /* Round-robin stream index */
        int cur_dma_stream;     /* index of stream doing DMA */
+       int cur_pio_stream;     /* index of stream doing PIO */
        u32 dma_data_req_offset;
        u32 dma_data_req_size;
        int output_mode;        /* NONE, MPG, YUV, UDMA YUV, passthrough */
index 8976487a65f3c7994481a7657616b9acfaf75952..555d5e6369c319215ad7849f87dcf8b2ccd8a4d6 100644 (file)
@@ -32,6 +32,8 @@
 #include "ivtv-yuv.h"
 #include "ivtv-controls.h"
 #include "ivtv-ioctl.h"
+#include "ivtv-cards.h"
+#include <media/saa7115.h>
 
 /* This function tries to claim the stream for a specific file descriptor.
    If no one else is using this stream then the stream is claimed and
@@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
                ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
                /* Select correct audio input (i.e. TV tuner or Line in) */
                ivtv_audio_set_io(itv);
+               if (itv->hw_flags & IVTV_HW_SAA711X)
+               {
+                       struct v4l2_crystal_freq crystal_freq;
+                       crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+                       crystal_freq.flags = 0;
+                       ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+               }
                /* Done! Unmute and continue. */
                ivtv_unmute(itv);
                ivtv_release_stream(s);
@@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
                set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
                /* Select the correct audio input (i.e. radio tuner) */
                ivtv_audio_set_io(itv);
+               if (itv->hw_flags & IVTV_HW_SAA711X)
+               {
+                       struct v4l2_crystal_freq crystal_freq;
+                       crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+                       crystal_freq.flags = SAA7115_FREQ_FL_APLL;
+                       ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+               }
                /* Done! Unmute and continue. */
                ivtv_unmute(itv);
        }
index 1989ec1cb973614e02d3ebc0d052a47feb7787e6..57af1762de1f736ebcfe3f79c16322198796f75a 100644 (file)
@@ -532,11 +532,6 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
                                itv->yuv_info.yuv_forced_update = 1;
                                return 0;
                        }
-                       if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-                                r.width, r.height, r.left, r.top))
-                               itv->main_rect = r;
-                       else
-                               return -EINVAL;
                }
                return 0;
        }
@@ -799,9 +794,39 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                return ivtv_get_fmt(itv, id->type, fmt);
        }
 
+       case VIDIOC_CROPCAP: {
+               struct v4l2_cropcap *cropcap = arg;
+
+               if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+                   cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+                       return -EINVAL;
+               cropcap->bounds.top = cropcap->bounds.left = 0;
+               cropcap->bounds.width = 720;
+               if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+                       cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+                       cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+                       cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+               } else {
+                       cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+                       cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+                       cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+               }
+               cropcap->defrect = cropcap->bounds;
+               return 0;
+       }
+
        case VIDIOC_S_CROP: {
                struct v4l2_crop *crop = arg;
 
+               if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+                   (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+                       if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+                                crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+                               itv->main_rect = crop->c;
+                               return 0;
+                       }
+                       return -EINVAL;
+               }
                if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                        return -EINVAL;
                return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
@@ -810,6 +835,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
        case VIDIOC_G_CROP: {
                struct v4l2_crop *crop = arg;
 
+               if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+                   (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+                       crop->c = itv->main_rect;
+                       return 0;
+               }
                if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                        return -EINVAL;
                return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
@@ -977,7 +1007,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                if (itv->hw_flags & IVTV_HW_CX25840) {
                        itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
                }
-               IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
+               IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
 
                /* Tuner */
                ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
@@ -1207,7 +1237,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                                        (s->buffers - s->q_free.buffers) * 100 / s->buffers,
                                        (s->buffers * s->buf_size) / 1024, s->buffers);
                }
-               IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
+               IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
                IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
                break;
        }
@@ -1455,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
        case VIDIOC_S_FMT:
        case VIDIOC_TRY_FMT:
        case VIDIOC_ENUM_FMT:
+       case VIDIOC_CROPCAP:
        case VIDIOC_G_CROP:
        case VIDIOC_S_CROP:
        case VIDIOC_G_FREQUENCY:
index c3a047b381b3eb188707d241db033ccad43f33d2..ba98bf054f2e8371057d58f684d776bfc67dcea0 100644 (file)
@@ -31,8 +31,6 @@
 
 #define DMA_MAGIC_COOKIE 0x000001fe
 
-#define SLICED_VBI_PIO 1
-
 static void ivtv_dma_dec_start(struct ivtv_stream *s);
 
 static const int ivtv_stream_map[] = {
@@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
        IVTV_ENC_STREAM_TYPE_VBI,
 };
 
-static inline int ivtv_use_pio(struct ivtv_stream *s)
+
+static void ivtv_pio_work_handler(struct ivtv *itv)
 {
-       struct ivtv *itv = s->itv;
+       struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
+       struct ivtv_buffer *buf;
+       struct list_head *p;
+       int i = 0;
+
+       IVTV_DEBUG_DMA("ivtv_pio_work_handler\n");
+       if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
+                       s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+               itv->cur_pio_stream = -1;
+               /* trigger PIO complete user interrupt */
+               write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
+               return;
+       }
+       IVTV_DEBUG_DMA("Process PIO %s\n", s->name);
+       buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list);
+       list_for_each(p, &s->q_dma.list) {
+               struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
+               u32 size = s->PIOarray[i].size & 0x3ffff;
 
-       return s->dma == PCI_DMA_NONE ||
-           (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+               /* Copy the data from the card to the buffer */
+               if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
+                       memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
+               }
+               else {
+                       memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
+               }
+               if (s->PIOarray[i].size & 0x80000000)
+                       break;
+               i++;
+       }
+       write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
 }
 
 void ivtv_irq_work_handler(struct work_struct *work)
@@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
 
        DEFINE_WAIT(wait);
 
+       if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
+               ivtv_pio_work_handler(itv);
+
        if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
-               vbi_work_handler(itv);
+               ivtv_vbi_work_handler(itv);
 
        if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
                ivtv_yuv_work_handler(itv);
@@ -173,8 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
        }
        s->buffers_stolen = rc;
 
-       /* got the buffers, now fill in SGarray (DMA) or copy the data from the card
-          to the buffers (PIO). */
+       /* got the buffers, now fill in SGarray (DMA) */
        buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
        memset(buf->buf, 0, 128);
        list_for_each(p, &s->q_predma.list) {
@@ -182,21 +210,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
 
                if (skip_bufs-- > 0)
                        continue;
-               if (!ivtv_use_pio(s)) {
-                       s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
-                       s->SGarray[idx].src = cpu_to_le32(offset);
-                       s->SGarray[idx].size = cpu_to_le32(s->buf_size);
-               }
+               s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
+               s->SGarray[idx].src = cpu_to_le32(offset);
+               s->SGarray[idx].size = cpu_to_le32(s->buf_size);
                buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
 
-               /* If PIO, then copy the data from the card to the buffer */
-               if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-                       memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
-               }
-               else if (ivtv_use_pio(s)) {
-                       memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
-               }
-
                s->q_predma.bytesused += buf->bytesused;
                size -= buf->bytesused;
                offset += s->buf_size;
@@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
        u32 *u32buf;
        int x = 0;
 
-       if (ivtv_use_pio(s)) {
-               if (s->q_predma.bytesused)
-                       ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-               s->SG_length = 0;
-       }
        IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
                        s->name, s->dma_offset);
        list_for_each(p, &s->q_dma.list) {
@@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
        if (buf)
                buf->bytesused += s->dma_last_offset;
        if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-               /* Parse and Groom VBI Data */
-               s->q_dma.bytesused -= buf->bytesused;
-               ivtv_process_vbi_data(itv, buf, 0, s->type);
-               s->q_dma.bytesused += buf->bytesused;
+               list_for_each(p, &s->q_dma.list) {
+                       buf = list_entry(p, struct ivtv_buffer, list);
+
+                       /* Parse and Groom VBI Data */
+                       s->q_dma.bytesused -= buf->bytesused;
+                       ivtv_process_vbi_data(itv, buf, 0, s->type);
+                       s->q_dma.bytesused += buf->bytesused;
+               }
                if (s->id == -1) {
                        ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
                        return;
@@ -351,10 +368,14 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
        struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
        int i;
 
+       IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
+
        if (s->q_predma.bytesused)
                ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-       IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
-       s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
+
+       if (ivtv_use_dma(s))
+               s->SGarray[s->SG_length - 1].size =
+                       cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
 
        /* If this is an MPEG stream, and VBI data is also pending, then append the
           VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -368,7 +389,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
        if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
                        s->SG_length + s_vbi->SG_length <= s->buffers) {
                ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
-               s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
+               if (ivtv_use_dma(s_vbi))
+                       s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
                for (i = 0; i < s_vbi->SG_length; i++) {
                        s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
                }
@@ -381,14 +403,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
        /* Mark last buffer size for Interrupt flag */
        s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
-       /* Sync Hardware SG List of buffers */
-       ivtv_stream_sync_for_device(s);
-       write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
-       write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
-       set_bit(IVTV_F_I_DMA, &itv->i_flags);
-       itv->cur_dma_stream = s->type;
-       itv->dma_timer.expires = jiffies + HZ / 10;
-       add_timer(&itv->dma_timer);
+       if (ivtv_use_pio(s)) {
+               for (i = 0; i < s->SG_length; i++) {
+                       s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
+                       s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
+               }
+               set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
+               set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
+               set_bit(IVTV_F_I_PIO, &itv->i_flags);
+               itv->cur_pio_stream = s->type;
+       }
+       else {
+               /* Sync Hardware SG List of buffers */
+               ivtv_stream_sync_for_device(s);
+               write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
+               write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+               set_bit(IVTV_F_I_DMA, &itv->i_flags);
+               itv->cur_dma_stream = s->type;
+               itv->dma_timer.expires = jiffies + HZ / 10;
+               add_timer(&itv->dma_timer);
+       }
 }
 
 static void ivtv_dma_dec_start(struct ivtv_stream *s)
@@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
        wake_up(&itv->dma_waitq);
 }
 
+static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
+{
+       struct ivtv_stream *s;
+
+       if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
+               itv->cur_pio_stream = -1;
+               return;
+       }
+       s = &itv->streams[itv->cur_pio_stream];
+       IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name);
+       s->SG_length = 0;
+       clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+       clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+       itv->cur_pio_stream = -1;
+       dma_post(s);
+       if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
+               ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
+       else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
+               ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
+       else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
+               ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
+       clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+       if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
+               u32 tmp;
+
+               s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
+               tmp = s->dma_offset;
+               s->dma_offset = itv->vbi.dma_offset;
+               dma_post(s);
+               s->dma_offset = tmp;
+       }
+       wake_up(&itv->dma_waitq);
+}
+
 static void ivtv_irq_dma_err(struct ivtv *itv)
 {
        u32 data[CX2341X_MBOX_MAX_DATA];
@@ -532,13 +600,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
        clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
        s = &itv->streams[ivtv_stream_map[data[0]]];
        if (!stream_enc_dma_append(s, data)) {
-               if (ivtv_use_pio(s)) {
-                       dma_post(s);
-                       ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
-               }
-               else {
-                       set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
-               }
+               set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
        }
 }
 
@@ -551,15 +613,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
        IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
        s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 
-       if (ivtv_use_pio(s)) {
-               if (stream_enc_dma_append(s, data))
-                       return;
-               if (s->q_predma.bytesused)
-                       ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-               s->SG_length = 0;
-               dma_post(s);
-               return;
-       }
        /* If more than two VBI buffers are pending, then
           clear the old ones and start with this new one.
           This can happen during transition stages when MPEG capturing is
@@ -582,11 +635,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
        if (!stream_enc_dma_append(s, data) &&
                        !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
                set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
-               set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
+               set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
        }
 }
 
-static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
+static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
 {
        u32 data[CX2341X_MBOX_MAX_DATA];
        struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
@@ -594,7 +647,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
        IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
        if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
                        !stream_enc_dma_append(s, data)) {
-               dma_post(s);
+               set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
        }
 }
 
@@ -657,7 +710,6 @@ static void ivtv_irq_vsync(struct ivtv *itv)
        }
        if (frame != (itv->lastVsyncFrame & 1)) {
                struct ivtv_stream *s = ivtv_get_output_stream(itv);
-               int work = 0;
 
                itv->lastVsyncFrame += 1;
                if (frame == 0) {
@@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
                /* Send VBI to saa7127 */
                if (frame) {
                        set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
-                       work = 1;
+                       set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                }
 
                /* Check if we need to update the yuv registers */
@@ -691,11 +743,9 @@ static void ivtv_irq_vsync(struct ivtv *itv)
                                itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
                                itv->yuv_info.yuv_forced_update = 0;
                                set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
-                               work = 1;
+                               set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                        }
                }
-               if (work)
-                       queue_work(itv->irq_work_queues, &itv->irq_work_queue);
        }
 }
 
@@ -755,6 +805,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
                ivtv_irq_enc_dma_complete(itv);
        }
 
+       if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
+               ivtv_irq_enc_pio_complete(itv);
+       }
+
        if (combo & IVTV_IRQ_DMA_ERR) {
                ivtv_irq_dma_err(itv);
        }
@@ -768,7 +822,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
        }
 
        if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
-               ivtv_irq_dev_vbi_reinsert(itv);
+               ivtv_irq_dec_vbi_reinsert(itv);
        }
 
        if (combo & IVTV_IRQ_ENC_EOS) {
@@ -813,6 +867,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
                }
        }
 
+       if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
+               for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+                       int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+                       struct ivtv_stream *s = &itv->streams[idx];
+
+                       if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
+                               continue;
+                       if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
+                               ivtv_dma_enc_start(s);
+                       break;
+               }
+       }
+
+       if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
+               queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+
        spin_unlock(&itv->dma_reg_lock);
 
        /* If we've just handled a 'forced' vsync, it's safest to say it
index ccfcef1ad91a5225e73c50e39d41347794e7a8a2..a04f9387f63df4127668d42dfa9143154ce4e0c1 100644 (file)
@@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
                s->dma != PCI_DMA_NONE ? "DMA " : "",
                s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 
-       /* Allocate DMA SG Arrays */
-       if (s->dma != PCI_DMA_NONE) {
-               s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
-               if (s->SGarray == NULL) {
-                       IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+       if (ivtv_might_use_pio(s)) {
+               s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+               if (s->PIOarray == NULL) {
+                       IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
                        return -ENOMEM;
                }
-               s->SG_length = 0;
+       }
+
+       /* Allocate DMA SG Arrays */
+       s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+       if (s->SGarray == NULL) {
+               IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+               if (ivtv_might_use_pio(s)) {
+                       kfree(s->PIOarray);
+                       s->PIOarray = NULL;
+               }
+               return -ENOMEM;
+       }
+       s->SG_length = 0;
+       if (ivtv_might_use_dma(s)) {
                s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
                ivtv_stream_sync_for_cpu(s);
        }
@@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
                        break;
                }
                INIT_LIST_HEAD(&buf->list);
-               if (s->dma != PCI_DMA_NONE) {
+               if (ivtv_might_use_dma(s)) {
                        buf->dma_handle = pci_map_single(s->itv->dev,
                                buf->buf, s->buf_size + 256, s->dma);
                        ivtv_buf_sync_for_cpu(s, buf);
@@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
 
        /* empty q_free */
        while ((buf = ivtv_dequeue(s, &s->q_free))) {
-               if (s->dma != PCI_DMA_NONE)
+               if (ivtv_might_use_dma(s))
                        pci_unmap_single(s->itv->dev, buf->dma_handle,
                                s->buf_size + 256, s->dma);
                kfree(buf->buf);
@@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s)
                                 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
                        s->SG_handle = IVTV_DMA_UNMAPPED;
                }
+               kfree(s->SGarray);
+               kfree(s->PIOarray);
+               s->PIOarray = NULL;
                s->SGarray = NULL;
                s->SG_length = 0;
        }
index 903edd4b43814bd8848f81bd83039e4824dfb7de..2ed8d548255d95f58b31bdc38e8db9df63e1cc2b 100644 (file)
  */
 
 #define IVTV_DMA_UNMAPPED      ((u32) -1)
+#define SLICED_VBI_PIO 1
 
 /* ivtv_buffer utility functions */
+
+static inline int ivtv_might_use_pio(struct ivtv_stream *s)
+{
+       return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
+}
+
+static inline int ivtv_use_pio(struct ivtv_stream *s)
+{
+       struct ivtv *itv = s->itv;
+
+       return s->dma == PCI_DMA_NONE ||
+           (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+}
+
+static inline int ivtv_might_use_dma(struct ivtv_stream *s)
+{
+       return s->dma != PCI_DMA_NONE;
+}
+
+static inline int ivtv_use_dma(struct ivtv_stream *s)
+{
+       return !ivtv_use_pio(s);
+}
+
 static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
-       if (s->dma != PCI_DMA_NONE)
+       if (ivtv_use_dma(s))
                pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
                                s->buf_size + 256, s->dma);
 }
 
 static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
-       if (s->dma != PCI_DMA_NONE)
+       if (ivtv_use_dma(s))
                pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
                                s->buf_size + 256, s->dma);
 }
@@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
 
 static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
 {
-       pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
-               sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+       if (ivtv_use_dma(s))
+               pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
+                       sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 }
 
 static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
 {
-       pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
-               sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+       if (ivtv_use_dma(s))
+               pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
+                       sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 }
index 01a41a844a307c223d3c64e9f23eed84cb3c03a6..6af88ae9295f8f4096ef3b8b230fba06ce9a4d48 100644 (file)
@@ -868,7 +868,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
        if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
                return 0;
 
-       IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
+       IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
 
        /* Stop Decoder */
        if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
index 5efa5a867818a9879b9497cbd9972764b8fc449d..3ba46e07ea1f1b93e6c497f5ff76e4b6738b3eab 100644 (file)
@@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv)
 }
 
 
-void vbi_work_handler(struct ivtv *itv)
+void ivtv_vbi_work_handler(struct ivtv *itv)
 {
        struct v4l2_sliced_vbi_data data;
 
index cdaea697b3ec087e94cfe5828fb178026e28eb6f..ec211b49702cc975427fdbee35c7a5bea9d5abdb 100644 (file)
@@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
 int ivtv_used_line(struct ivtv *itv, int line, int field);
 void ivtv_disable_vbi(struct ivtv *itv);
 void ivtv_set_vbi(unsigned long arg);
-void vbi_work_handler(struct ivtv *itv);
+void ivtv_vbi_work_handler(struct ivtv *itv);
index 74839f98b7c45c2e8158f57a47a9cbb421dd9086..c1a392e47170b520d3b17c5c14463857b5b11e00 100644 (file)
@@ -75,10 +75,6 @@ struct saa7111 {
        int norm;
        int input;
        int enable;
-       int bright;
-       int contrast;
-       int hue;
-       int sat;
 };
 
 #define   I2C_SAA7111        0x48
@@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
        return i2c_smbus_write_byte_data(client, reg, value);
 }
 
+static inline void
+saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+{
+       struct saa7111 *decoder = i2c_get_clientdata(client);
+
+       if (decoder->reg[reg] != value) {
+               decoder->reg[reg] = value;
+               i2c_smbus_write_byte_data(client, reg, value);
+       }
+}
+
 static int
 saa7111_write_block (struct i2c_client *client,
                     const u8          *data,
@@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
        {
                struct video_picture *pic = arg;
 
-               if (decoder->bright != pic->brightness) {
-                       /* We want 0 to 255 we get 0-65535 */
-                       decoder->bright = pic->brightness;
-                       saa7111_write(client, 0x0a, decoder->bright >> 8);
-               }
-               if (decoder->contrast != pic->contrast) {
-                       /* We want 0 to 127 we get 0-65535 */
-                       decoder->contrast = pic->contrast;
-                       saa7111_write(client, 0x0b,
-                                     decoder->contrast >> 9);
-               }
-               if (decoder->sat != pic->colour) {
-                       /* We want 0 to 127 we get 0-65535 */
-                       decoder->sat = pic->colour;
-                       saa7111_write(client, 0x0c, decoder->sat >> 9);
-               }
-               if (decoder->hue != pic->hue) {
-                       /* We want -128 to 127 we get 0-65535 */
-                       decoder->hue = pic->hue;
-                       saa7111_write(client, 0x0d,
-                                     (decoder->hue - 32768) >> 8);
-               }
+               /* We want 0 to 255 we get 0-65535 */
+               saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
+               /* We want 0 to 127 we get 0-65535 */
+               saa7111_write(client, 0x0b, pic->contrast >> 9);
+               /* We want 0 to 127 we get 0-65535 */
+               saa7111_write(client, 0x0c, pic->colour >> 9);
+               /* We want -128 to 127 we get 0-65535 */
+               saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
        }
                break;
 
@@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
        decoder->norm = VIDEO_MODE_NTSC;
        decoder->input = 0;
        decoder->enable = 1;
-       decoder->bright = 32768;
-       decoder->contrast = 32768;
-       decoder->hue = 32768;
-       decoder->sat = 32768;
        i2c_set_clientdata(client, decoder);
 
        i = i2c_attach_client(client);
index 9118a6227ea63034d8d63469be9335c96993aa21..7df071eb0a3b2f2bc1317ca2cabe4b9a7ac443db 100644 (file)
@@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb)
        if (!USBVISION_IS_OPERATIONAL(usbvision))
                return;
 
+       /* any urb with wrong status is ignored without acknowledgement */
+       if (urb->status == -ENOENT) {
+               return;
+       }
+
        f = &usbvision->curFrame;
 
        /* Manage streaming interruption */
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
        if (usbvision->streaming == Stream_On) {
 
                /* If we collected enough data let's parse! */
-               if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */
-                       /*If we don't have a frame we're current working on, complain */
-                       if(!list_empty(&(usbvision->inqueue))) {
-                               if (!(*f)) {
-                                       (*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame);
-                               }
-                               usbvision_parse_data(usbvision);
-                       }
-                       else {
-                               PDEBUG(DBG_IRQ, "received data, but no one needs it");
-                               scratch_reset(usbvision);
+               if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
+                   (!list_empty(&(usbvision->inqueue))) ) {
+                       if (!(*f)) {
+                               (*f) = list_entry(usbvision->inqueue.next,
+                                                 struct usbvision_frame,
+                                                 frame);
                        }
+                       usbvision_parse_data(usbvision);
+               }
+               else {
+                       /*If we don't have a frame
+                         we're current working on, complain */
+                       PDEBUG(DBG_IRQ,
+                              "received data, but no one needs it");
+                       scratch_reset(usbvision);
                }
        }
        else {
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
        urb->dev = usbvision->dev;
        errCode = usb_submit_urb (urb, GFP_ATOMIC);
 
-       /* Disable this warning.  By design of the driver. */
-       //      if(errCode) {
-       //              err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode);
-       //      }
+       if(errCode) {
+               err("%s: usb_submit_urb failed: error %d",
+                   __FUNCTION__, errCode);
+       }
 
        return;
 }
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 {
        struct usb_device *dev = usbvision->dev;
        int bufIdx, errCode, regValue;
-       const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+       int sb_size;
 
        if (!USBVISION_IS_OPERATIONAL(usbvision))
                return -EFAULT;
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
                usbvision->last_error = errCode;
                return -EBUSY;
        }
+       sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
 
-       regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+       regValue = (16 - usbvision_read_reg(usbvision,
+                                           USBVISION_ALTER_REG)) & 0x0F;
 
        usbvision->usb_bandwidth = regValue >> 1;
-       PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+       PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+              usbvision->usb_bandwidth);
 
 
 
@@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
                        return -ENOMEM;
                }
                usbvision->sbuf[bufIdx].urb = urb;
-               usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+               usbvision->sbuf[bufIdx].data =
+                       usb_buffer_alloc(usbvision->dev,
+                                        sb_size,
+                                        GFP_KERNEL,
+                                        &urb->transfer_dma);
                urb->dev = dev;
                urb->context = usbvision;
                urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
                for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
                     k += usbvision->isocPacketSize) {
                        urb->iso_frame_desc[j].offset = k;
-                       urb->iso_frame_desc[j].length = usbvision->isocPacketSize;
+                       urb->iso_frame_desc[j].length =
+                               usbvision->isocPacketSize;
                }
        }
 
 
        /* Submit all URBs */
        for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
-                       errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL);
+                       errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
+                                                GFP_KERNEL);
                if (errCode) {
-                       err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode);
+                       err("%s: usb_submit_urb(%d) failed: error %d",
+                           __FUNCTION__, bufIdx, errCode);
                }
        }
 
        usbvision->streaming = Stream_Idle;
-       PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
+       PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
+              __FUNCTION__,
+              usbvision->video_endp);
        return 0;
 }
 
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 {
        int bufIdx, errCode, regValue;
-       const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+       int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
 
        if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
                return;
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
                errCode = usb_set_interface(usbvision->dev, usbvision->iface,
                                            usbvision->ifaceAlt);
                if (errCode < 0) {
-                       err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
+                       err("%s: usb_set_interface() failed: error %d",
+                           __FUNCTION__, errCode);
                        usbvision->last_error = errCode;
                }
-               regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
-               usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
-               PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
+               regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+               usbvision->isocPacketSize =
+                       (regValue == 0) ? 0 : (regValue * 64) - 1;
+               PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
+                      usbvision->isocPacketSize);
 
                usbvision->usb_bandwidth = regValue >> 1;
-               PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+               PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+                      usbvision->usb_bandwidth);
        }
 }
 
index bd6f6422ed5417053a61475ccab29e11bec02ea1..c759d00d701461272ee41552bfca254867ce2821 100644 (file)
 #define USBVISION_CLIPMASK_SIZE                (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
 
 #define USBVISION_URB_FRAMES           32
-#define USBVISION_MAX_ISOC_PACKET_SIZE         959                     // NT1003 Specs Document says 1023
 
 #define USBVISION_NUM_HEADERMARKER     20
 #define USBVISION_NUMFRAMES            3  /* Maximum number of frames an application can get */
index d25d3be8fcd2f0843732b1abd2839d9d00d6258a..165f81d16d00e98044bb73bc73dea3cffdaeb4ed 100644 (file)
@@ -436,7 +436,7 @@ typedef struct _MPT_SAS_MGMT {
 typedef struct _mpt_ioctl_events {
        u32     event;          /* Specified by define above */
        u32     eventContext;   /* Index or counter */
-       int     data[2];        /* First 8 bytes of Event Data */
+       u32     data[2];        /* First 8 bytes of Event Data */
 } MPT_IOCTL_EVENTS;
 
 /*
index fa0f7761652a47b0aff19b1ea420d0edf963fdf9..3bd94f11e7d6ef417244f48036e24a9b696aebc0 100644 (file)
@@ -2463,11 +2463,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                                ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
                                ioc->events[idx].eventContext = ioc->eventContext;
 
-                               ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
-                                       (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-                                       (sc->device->channel << 8) || sc->device->id;
+                               ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+                                       (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+                                       (sc->device->channel << 8) | sc->device->id;
 
-                               ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+                               ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
 
                                ioc->eventContext++;
                                if (hd->ioc->pcidev->vendor ==
index d3235f213c8933fe72bf77d464e64a69b8789b09..e0d474b174336ba20c7c714e356aabc09a715e07 100644 (file)
@@ -123,8 +123,12 @@ int i2o_driver_register(struct i2o_driver *drv)
        }
 
        rc = driver_register(&drv->driver);
-       if (rc)
-               destroy_workqueue(drv->event_queue);
+       if (rc) {
+               if (drv->event) {
+                       destroy_workqueue(drv->event_queue);
+                       drv->event_queue = NULL;
+               }
+       }
 
        return rc;
 };
@@ -256,7 +260,7 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c)
        int i;
        struct i2o_driver *drv;
 
-       for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+       for (i = 0; i < i2o_max_drivers; i++) {
                drv = i2o_drivers[i];
 
                if (drv)
@@ -276,7 +280,7 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c)
        int i;
        struct i2o_driver *drv;
 
-       for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+       for (i = 0; i < i2o_max_drivers; i++) {
                drv = i2o_drivers[i];
 
                if (drv)
@@ -295,7 +299,7 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev)
        int i;
        struct i2o_driver *drv;
 
-       for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+       for (i = 0; i < i2o_max_drivers; i++) {
                drv = i2o_drivers[i];
 
                if (drv)
@@ -314,7 +318,7 @@ void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev)
        int i;
        struct i2o_driver *drv;
 
-       for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+       for (i = 0; i < i2o_max_drivers; i++) {
                drv = i2o_drivers[i];
 
                if (drv)
@@ -335,17 +339,15 @@ int __init i2o_driver_init(void)
 
        spin_lock_init(&i2o_drivers_lock);
 
-       if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
-           ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
-            (2 * i2o_max_drivers - 1))) {
-               osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
-                        "a power of 2\n", i2o_max_drivers);
+       if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) {
+               osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n",
+                        i2o_max_drivers);
                i2o_max_drivers = I2O_MAX_DRIVERS;
        }
        osm_info("max drivers = %d\n", i2o_max_drivers);
 
        i2o_drivers =
-           kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
+           kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL);
        if (!i2o_drivers)
                return -ENOMEM;
 
index cb8c264eaff07e7ce93883e164910d60b909f191..38e815a2e87135227f16095607a2a588a38d6aab 100644 (file)
@@ -207,16 +207,7 @@ static int ucb1x00_thread(void *_ts)
        struct ucb1x00_ts *ts = _ts;
        struct task_struct *tsk = current;
        DECLARE_WAITQUEUE(wait, tsk);
-       int valid;
-
-       /*
-        * We could run as a real-time thread.  However, thus far
-        * this doesn't seem to be necessary.
-        */
-//     tsk->policy = SCHED_FIFO;
-//     tsk->rt_priority = 1;
-
-       valid = 0;
+       int valid = 0;
 
        add_wait_queue(&ts->irq_wait, &wait);
        while (!kthread_should_stop()) {
@@ -300,7 +291,7 @@ static void ucb1x00_ts_irq(int idx, void *id)
 
 static int ucb1x00_ts_open(struct input_dev *idev)
 {
-       struct ucb1x00_ts *ts = idev->private;
+       struct ucb1x00_ts *ts = input_get_drvdata(idev);
        int ret = 0;
 
        BUG_ON(ts->rtask);
@@ -337,7 +328,7 @@ static int ucb1x00_ts_open(struct input_dev *idev)
  */
 static void ucb1x00_ts_close(struct input_dev *idev)
 {
-       struct ucb1x00_ts *ts = idev->private;
+       struct ucb1x00_ts *ts = input_get_drvdata(idev);
 
        if (ts->rtask)
                kthread_stop(ts->rtask);
@@ -389,7 +380,6 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
        ts->idev = idev;
        ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
 
-       idev->private    = ts;
        idev->name       = "Touchscreen panel";
        idev->id.product = ts->ucb->id;
        idev->open       = ucb1x00_ts_open;
@@ -400,6 +390,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
        __set_bit(ABS_Y, idev->absbit);
        __set_bit(ABS_PRESSURE, idev->absbit);
 
+       input_set_drvdata(idev, ts);
+
        err = input_register_device(idev);
        if (err)
                goto fail;
index 35b139b0e5f2a01a97082d15514a0bd4fc6a93fc..5108b7c576dfba8fab2e5794188a04a0fdf7044e 100644 (file)
@@ -47,6 +47,7 @@ struct phantom_device {
        struct cdev cdev;
 
        struct mutex open_lock;
+       spinlock_t ioctl_lock;
 };
 
 static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -59,8 +60,11 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat)
                atomic_set(&dev->counter, 0);
                iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
                iowrite32(0x43, dev->caddr + PHN_IRQCTL);
-       } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
+               ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+       } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) {
                iowrite32(0, dev->caddr + PHN_IRQCTL);
+               ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+       }
 
        dev->status = newstat;
 
@@ -71,8 +75,8 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat)
  * File ops
  */
 
-static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
-       u_long arg)
+static long phantom_ioctl(struct file *file, unsigned int cmd,
+               unsigned long arg)
 {
        struct phantom_device *dev = file->private_data;
        struct phm_regs rs;
@@ -92,24 +96,32 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
                if (r.reg > 7)
                        return -EINVAL;
 
+               spin_lock(&dev->ioctl_lock);
                if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
-                               phantom_status(dev, dev->status | PHB_RUNNING))
+                               phantom_status(dev, dev->status | PHB_RUNNING)){
+                       spin_unlock(&dev->ioctl_lock);
                        return -ENODEV;
+               }
 
                pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
                iowrite32(r.value, dev->iaddr + r.reg);
+               ioread32(dev->iaddr); /* PCI posting */
 
                if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
                        phantom_status(dev, dev->status & ~PHB_RUNNING);
+               spin_unlock(&dev->ioctl_lock);
                break;
        case PHN_SET_REGS:
                if (copy_from_user(&rs, argp, sizeof(rs)))
                        return -EFAULT;
 
                pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
+               spin_lock(&dev->ioctl_lock);
                for (i = 0; i < min(rs.count, 8U); i++)
                        if ((1 << i) & rs.mask)
                                iowrite32(rs.values[i], dev->oaddr + i);
+               ioread32(dev->iaddr); /* PCI posting */
+               spin_unlock(&dev->ioctl_lock);
                break;
        case PHN_GET_REG:
                if (copy_from_user(&r, argp, sizeof(r)))
@@ -128,9 +140,11 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
                        return -EFAULT;
 
                pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
+               spin_lock(&dev->ioctl_lock);
                for (i = 0; i < min(rs.count, 8U); i++)
                        if ((1 << i) & rs.mask)
                                rs.values[i] = ioread32(dev->iaddr + i);
+               spin_unlock(&dev->ioctl_lock);
 
                if (copy_to_user(argp, &rs, sizeof(rs)))
                        return -EFAULT;
@@ -199,7 +213,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
 static struct file_operations phantom_file_ops = {
        .open = phantom_open,
        .release = phantom_release,
-       .ioctl = phantom_ioctl,
+       .unlocked_ioctl = phantom_ioctl,
        .poll = phantom_poll,
 };
 
@@ -212,6 +226,7 @@ static irqreturn_t phantom_isr(int irq, void *data)
 
        iowrite32(0, dev->iaddr);
        iowrite32(0xc0, dev->iaddr);
+       ioread32(dev->iaddr); /* PCI posting */
 
        atomic_inc(&dev->counter);
        wake_up_interruptible(&dev->wait);
@@ -282,11 +297,13 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
        }
 
        mutex_init(&pht->open_lock);
+       spin_lock_init(&pht->ioctl_lock);
        init_waitqueue_head(&pht->wait);
        cdev_init(&pht->cdev, &phantom_file_ops);
        pht->cdev.owner = THIS_MODULE;
 
        iowrite32(0, pht->caddr + PHN_IRQCTL);
+       ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
        retval = request_irq(pdev->irq, phantom_isr,
                        IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
        if (retval) {
@@ -337,6 +354,7 @@ static void __devexit phantom_remove(struct pci_dev *pdev)
        cdev_del(&pht->cdev);
 
        iowrite32(0, pht->caddr + PHN_IRQCTL);
+       ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
        free_irq(pdev->irq, pht);
 
        pci_iounmap(pdev, pht->oaddr);
@@ -358,6 +376,7 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
        struct phantom_device *dev = pci_get_drvdata(pdev);
 
        iowrite32(0, dev->caddr + PHN_IRQCTL);
+       ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
 
        return 0;
 }
index 6c36a55cb3d15101c509c1768abbe59ec4475ead..95c0b96e83f2110b751d775c2a53e66d718c6564 100644 (file)
@@ -740,7 +740,7 @@ static ssize_t hotkey_enable_store(struct device *dev,
 }
 
 static struct device_attribute dev_attr_hotkey_enable =
-       __ATTR(enable, S_IWUSR | S_IRUGO,
+       __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
                hotkey_enable_show, hotkey_enable_store);
 
 /* sysfs hotkey mask --------------------------------------------------- */
@@ -775,7 +775,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
 }
 
 static struct device_attribute dev_attr_hotkey_mask =
-       __ATTR(mask, S_IWUSR | S_IRUGO,
+       __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
                hotkey_mask_show, hotkey_mask_store);
 
 /* sysfs hotkey bios_enabled ------------------------------------------- */
@@ -787,7 +787,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
 }
 
 static struct device_attribute dev_attr_hotkey_bios_enabled =
-       __ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
+       __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
 
 /* sysfs hotkey bios_mask ---------------------------------------------- */
 static ssize_t hotkey_bios_mask_show(struct device *dev,
@@ -798,7 +798,7 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
 }
 
 static struct device_attribute dev_attr_hotkey_bios_mask =
-       __ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
+       __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
 
 /* --------------------------------------------------------------------- */
 
@@ -824,8 +824,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                str_supported(tp_features.hotkey));
 
        if (tp_features.hotkey) {
-               hotkey_dev_attributes = create_attr_set(4,
-                                               TPACPI_HOTKEY_SYSFS_GROUP);
+               hotkey_dev_attributes = create_attr_set(4, NULL);
                if (!hotkey_dev_attributes)
                        return -ENOMEM;
                res = add_to_attr_set(hotkey_dev_attributes,
@@ -1050,7 +1049,7 @@ static ssize_t bluetooth_enable_store(struct device *dev,
 }
 
 static struct device_attribute dev_attr_bluetooth_enable =
-       __ATTR(enable, S_IWUSR | S_IRUGO,
+       __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
                bluetooth_enable_show, bluetooth_enable_store);
 
 /* --------------------------------------------------------------------- */
@@ -1061,7 +1060,6 @@ static struct attribute *bluetooth_attributes[] = {
 };
 
 static const struct attribute_group bluetooth_attr_group = {
-       .name = TPACPI_BLUETH_SYSFS_GROUP,
        .attrs = bluetooth_attributes,
 };
 
@@ -1215,7 +1213,7 @@ static ssize_t wan_enable_store(struct device *dev,
 }
 
 static struct device_attribute dev_attr_wan_enable =
-       __ATTR(enable, S_IWUSR | S_IRUGO,
+       __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
                wan_enable_show, wan_enable_store);
 
 /* --------------------------------------------------------------------- */
@@ -1226,7 +1224,6 @@ static struct attribute *wan_attributes[] = {
 };
 
 static const struct attribute_group wan_attr_group = {
-       .name = TPACPI_WAN_SYSFS_GROUP,
        .attrs = wan_attributes,
 };
 
index 440145a026174c90bfcf85a05bc434d5504a3c21..72d62f2dabb976069ef26dabb4be6abad030be57 100644 (file)
@@ -278,8 +278,6 @@ static int beep_write(char *buf);
  * Bluetooth subdriver
  */
 
-#define TPACPI_BLUETH_SYSFS_GROUP "bluetooth"
-
 enum {
        /* ACPI GBDC/SBDC bits */
        TP_ACPI_BLUETOOTH_HWPRESENT     = 0x01, /* Bluetooth hw available */
@@ -416,8 +414,6 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
  * Hotkey subdriver
  */
 
-#define TPACPI_HOTKEY_SYSFS_GROUP "hotkey"
-
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
@@ -553,8 +549,6 @@ static int volume_write(char *buf);
  * Wan subdriver
  */
 
-#define TPACPI_WAN_SYSFS_GROUP "wwan"
-
 enum {
        /* ACPI GWAN/SWAN bits */
        TP_ACPI_WANCARD_HWPRESENT       = 0x01, /* Wan hw available */
index c08ad8f823d233657b9f076f8aee62b4135e0e3b..2d1b3df95c5bfbb138f5d0c509fe33345dc2a7b4 100644 (file)
@@ -343,7 +343,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
        if (!fm->addr)
                goto err_out_free;
 
-       rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm);
+       rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
        if (rc)
                goto err_out_unmap;
 
index a7562f7fc0b33b4a13725b0d630f67d21ba240a9..540ff4bea54c6f8eb3366b6066393dec6567ae8e 100644 (file)
@@ -135,23 +135,6 @@ struct mmc_blk_request {
        struct mmc_data         data;
 };
 
-static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
-{
-       struct mmc_blk_data *md = mq->data;
-       int stat = BLKPREP_OK;
-
-       /*
-        * If we have no device, we haven't finished initialising.
-        */
-       if (!md || !mq->card) {
-               printk(KERN_ERR "%s: killing request - no device/host\n",
-                      req->rq_disk->disk_name);
-               stat = BLKPREP_KILL;
-       }
-
-       return stat;
-}
-
 static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
 {
        int err;
@@ -460,7 +443,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
        if (ret)
                goto err_putdisk;
 
-       md->queue.prep_fn = mmc_blk_prep_rq;
        md->queue.issue_fn = mmc_blk_issue_rq;
        md->queue.data = md;
 
index 2e77963db334d1d7b9f513bf5dfdc587772743c6..dd97bc798409eb0bdec4d5a413c217c173a642e4 100644 (file)
 #define MMC_QUEUE_SUSPENDED    (1 << 0)
 
 /*
- * Prepare a MMC request.  Essentially, this means passing the
- * preparation off to the media driver.  The media driver will
- * create a mmc_io_request in req->special.
+ * Prepare a MMC request. This just filters out odd stuff.
  */
 static int mmc_prep_request(struct request_queue *q, struct request *req)
 {
-       struct mmc_queue *mq = q->queuedata;
-       int ret = BLKPREP_KILL;
-
-       if (blk_special_request(req)) {
-               /*
-                * Special commands already have the command
-                * blocks already setup in req->special.
-                */
-               BUG_ON(!req->special);
-
-               ret = BLKPREP_OK;
-       } else if (blk_fs_request(req) || blk_pc_request(req)) {
-               /*
-                * Block I/O requests need translating according
-                * to the protocol.
-                */
-               ret = mq->prep_fn(mq, req);
-       } else {
-               /*
-                * Everything else is invalid.
-                */
+       /*
+        * We only like normal block requests.
+        */
+       if (!blk_fs_request(req) && !blk_pc_request(req)) {
                blk_dump_rq_flags(req, "MMC bad request");
+               return BLKPREP_KILL;
        }
 
-       if (ret == BLKPREP_OK)
-               req->cmd_flags |= REQ_DONTPREP;
+       req->cmd_flags |= REQ_DONTPREP;
 
-       return ret;
+       return BLKPREP_OK;
 }
 
 static int mmc_queue_thread(void *d)
index c9f139e764f6cecdd3ac409160f077b79e73e74d..1590b3f3f1f7d8d54fbdf1eb1a27c6f25893205e 100644 (file)
@@ -10,20 +10,12 @@ struct mmc_queue {
        struct semaphore        thread_sem;
        unsigned int            flags;
        struct request          *req;
-       int                     (*prep_fn)(struct mmc_queue *, struct request *);
        int                     (*issue_fn)(struct mmc_queue *, struct request *);
        void                    *data;
        struct request_queue    *queue;
        struct scatterlist      *sg;
 };
 
-struct mmc_io_request {
-       struct request          *rq;
-       int                     num;
-       struct mmc_command      selcmd;         /* mmc_queue private */
-       struct mmc_command      cmd[4];         /* max 4 commands */
-};
-
 extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
 extern void mmc_cleanup_queue(struct mmc_queue *);
 extern void mmc_queue_suspend(struct mmc_queue *);
index c1dfd03d559ae27f0a246256ce4babbb3cffdc17..41bfb5dfe6ff1351d1c5845d753c6da3f4bd84e5 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 
 #include "core.h"
 #include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
        int err;
        u8 *status;
 
+       if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+               return MMC_ERR_NONE;
+
+       if (!(card->csd.cmdclass & CCC_SWITCH)) {
+               printk(KERN_WARNING "%s: card lacks mandatory switch "
+                       "function, performance might suffer.\n",
+                       mmc_hostname(card->host));
+               return MMC_ERR_NONE;
+       }
+
        err = MMC_ERR_FAILED;
 
        status = kmalloc(64, GFP_KERNEL);
@@ -204,10 +215,9 @@ static int mmc_read_switch(struct mmc_card *card)
 
        err = mmc_sd_switch(card, 0, 0, 1, status);
        if (err != MMC_ERR_NONE) {
-               /*
-                * Card not supporting high-speed will ignore the
-                * command.
-                */
+               printk(KERN_WARNING "%s: problem reading switch "
+                       "capabilities, performance might suffer.\n",
+                       mmc_hostname(card->host));
                err = MMC_ERR_NONE;
                goto out;
        }
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
        int err;
        u8 *status;
 
+       if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+               return MMC_ERR_NONE;
+
+       if (!(card->csd.cmdclass & CCC_SWITCH))
+               return MMC_ERR_NONE;
+
        if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
                return MMC_ERR_NONE;
 
@@ -402,7 +418,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        /*
         * Switch to wider bus (if supported).
         */
-       if ((host->caps && MMC_CAP_4_BIT_DATA) &&
+       if ((host->caps & MMC_CAP_4_BIT_DATA) &&
                (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
                err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
                if (err != MMC_ERR_NONE)
index e37943c314cbd7c954208130921349501db8cb18..5b00c194b6285a0bb76e7101765bf60bedceaf55 100644 (file)
@@ -417,7 +417,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
                blocks = 0;
        }
 
-       if (cmd->opcode == MMC_STOP_TRANSMISSION)
+       if (host->flags & FL_SENT_STOP)
                cmdr |= AT91_MCI_TRCMD_STOP;
 
        if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -563,8 +563,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
        if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
                        AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
                        AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
-               if ((status & AT91_MCI_RCRCE) &&
-                       ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
+               if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
                        cmd->error = MMC_ERR_NONE;
                }
                else {
index f967226d7505fcc5ac49961241e8116aca8acbee..52b63f11ddd6498000003049ce95f67306e80ab7 100644 (file)
@@ -76,8 +76,7 @@ const struct {
 #endif
 };
 
-#define AU1XMMC_CONTROLLER_COUNT \
-       (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
 
 /* This array stores pointers for the hosts (used by the IRQ handler) */
 struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
index 92055405cb3041cc699deb734637e9fffc6bdd30..451adcc52b3c5c281da118b50768ccd338a482a8 100644 (file)
@@ -1,10 +1,9 @@
 #
 # Makefile for the memory technology device drivers.
 #
-# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
 
 # Core functionality.
-mtd-y                          := mtdcore.o
+mtd-y                          := mtdcore.o mtdsuper.o
 mtd-$(CONFIG_MTD_PARTITIONS)   += mtdpart.o
 obj-$(CONFIG_MTD)              += $(mtd-y)
 
index a4873ab84e6bcc9fd73ef1cf8c17353e9b474b25..e8f686f7a357bd0e06a408dfb1b668d9a71c0317 100644 (file)
@@ -650,7 +650,7 @@ MODULE_DESCRIPTION(PMC551_VERSION);
  */
 static int msize = 0;
 #if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
-static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE
+static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
 #else
 static int asize = 0;
 #endif
index 389fea28b9a6da2e05de4a0bf6be59a4c0fdfe1f..14ffb1a9302a51e8dc2271f7311116b1f7b635f3 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/major.h>
-#include <linux/root_dev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
@@ -89,10 +88,6 @@ int __init uclinux_mtd_init(void)
        uclinux_ram_mtdinfo = mtd;
        add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
 
-       printk("uclinux[mtd]: set %s to be root filesystem\n",
-               uclinux_romfs[0].name);
-       ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
-
        return(0);
 }
 
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
new file mode 100644 (file)
index 0000000..aca3319
--- /dev/null
@@ -0,0 +1,232 @@
+/* MTD-based superblock management
+ *
+ * Copyright Â© 2001-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by:  David Howells <dhowells@redhat.com>
+ *              David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mtd/super.h>
+#include <linux/namei.h>
+#include <linux/ctype.h>
+
+/*
+ * compare superblocks to see if they're equivalent
+ * - they are if the underlying MTD device is the same
+ */
+static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
+{
+       struct mtd_info *mtd = _mtd;
+
+       if (sb->s_mtd == mtd) {
+               DEBUG(2, "MTDSB: Match on device %d (\"%s\")\n",
+                     mtd->index, mtd->name);
+               return 1;
+       }
+
+       DEBUG(2, "MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
+             sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
+       return 0;
+}
+
+/*
+ * mark the superblock by the MTD device it is using
+ * - set the device number to be the correct MTD block device for pesuperstence
+ *   of NFS exports
+ */
+static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
+{
+       struct mtd_info *mtd = _mtd;
+
+       sb->s_mtd = mtd;
+       sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+       return 0;
+}
+
+/*
+ * get a superblock on an MTD-backed filesystem
+ */
+static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
+                         const char *dev_name, void *data,
+                         struct mtd_info *mtd,
+                         int (*fill_super)(struct super_block *, void *, int),
+                         struct vfsmount *mnt)
+{
+       struct super_block *sb;
+       int ret;
+
+       sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, mtd);
+       if (IS_ERR(sb))
+               goto out_error;
+
+       if (sb->s_root)
+               goto already_mounted;
+
+       /* fresh new superblock */
+       DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n",
+             mtd->index, mtd->name);
+
+       ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
+       if (ret < 0) {
+               up_write(&sb->s_umount);
+               deactivate_super(sb);
+               return ret;
+       }
+
+       /* go */
+       sb->s_flags |= MS_ACTIVE;
+       return simple_set_mnt(mnt, sb);
+
+       /* new mountpoint for an already mounted superblock */
+already_mounted:
+       DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
+             mtd->index, mtd->name);
+       ret = simple_set_mnt(mnt, sb);
+       goto out_put;
+
+out_error:
+       ret = PTR_ERR(sb);
+out_put:
+       put_mtd_device(mtd);
+       return ret;
+}
+
+/*
+ * get a superblock on an MTD-backed filesystem by MTD device number
+ */
+static int get_sb_mtd_nr(struct file_system_type *fs_type, int flags,
+                        const char *dev_name, void *data, int mtdnr,
+                        int (*fill_super)(struct super_block *, void *, int),
+                        struct vfsmount *mnt)
+{
+       struct mtd_info *mtd;
+
+       mtd = get_mtd_device(NULL, mtdnr);
+       if (IS_ERR(mtd)) {
+               DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
+               return PTR_ERR(mtd);
+       }
+
+       return get_sb_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super,
+                             mnt);
+}
+
+/*
+ * set up an MTD-based superblock
+ */
+int get_sb_mtd(struct file_system_type *fs_type, int flags,
+              const char *dev_name, void *data,
+              int (*fill_super)(struct super_block *, void *, int),
+              struct vfsmount *mnt)
+{
+       struct nameidata nd;
+       int mtdnr, ret;
+
+       if (!dev_name)
+               return -EINVAL;
+
+       DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name);
+
+       /* the preferred way of mounting in future; especially when
+        * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
+        * by name, so that we don't require block device support to be present
+        * in the kernel. */
+       if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
+               if (dev_name[3] == ':') {
+                       struct mtd_info *mtd;
+
+                       /* mount by MTD device name */
+                       DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
+                             dev_name + 4);
+
+                       for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
+                               mtd = get_mtd_device(NULL, mtdnr);
+                               if (!IS_ERR(mtd)) {
+                                       if (!strcmp(mtd->name, dev_name + 4))
+                                               return get_sb_mtd_aux(
+                                                       fs_type, flags,
+                                                       dev_name, data, mtd,
+                                                       fill_super, mnt);
+
+                                       put_mtd_device(mtd);
+                               }
+                       }
+
+                       printk(KERN_NOTICE "MTD:"
+                              " MTD device with name \"%s\" not found.\n",
+                              dev_name + 4);
+
+               } else if (isdigit(dev_name[3])) {
+                       /* mount by MTD device number name */
+                       char *endptr;
+
+                       mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
+                       if (!*endptr) {
+                               /* It was a valid number */
+                               DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n",
+                                     mtdnr);
+                               return get_sb_mtd_nr(fs_type, flags,
+                                                    dev_name, data,
+                                                    mtdnr, fill_super, mnt);
+                       }
+               }
+       }
+
+       /* try the old way - the hack where we allowed users to mount
+        * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
+        */
+       ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+
+       DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
+             ret, nd.dentry ? nd.dentry->d_inode : NULL);
+
+       if (ret)
+               return ret;
+
+       ret = -EINVAL;
+
+       if (!S_ISBLK(nd.dentry->d_inode->i_mode))
+               goto out;
+
+       if (nd.mnt->mnt_flags & MNT_NODEV) {
+               ret = -EACCES;
+               goto out;
+       }
+
+       if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
+               goto not_an_MTD_device;
+
+       mtdnr = iminor(nd.dentry->d_inode);
+       path_release(&nd);
+
+       return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
+                            mnt);
+
+not_an_MTD_device:
+       if (!(flags & MS_SILENT))
+               printk(KERN_NOTICE
+                      "MTD: Attempt to mount non-MTD device \"%s\"\n",
+                      dev_name);
+out:
+       path_release(&nd);
+       return ret;
+
+}
+
+EXPORT_SYMBOL_GPL(get_sb_mtd);
+
+/*
+ * destroy an MTD-based superblock
+ */
+void kill_mtd_super(struct super_block *sb)
+{
+       generic_shutdown_super(sb);
+       put_mtd_device(sb->s_mtd);
+       sb->s_mtd = NULL;
+}
+
+EXPORT_SYMBOL_GPL(kill_mtd_super);
index fe94ae9ae1f22d4feb409100726a4d8dadca5cb7..e3744eb8eccba4a68f3780379911a1eff7df2ef5 100644 (file)
@@ -101,7 +101,7 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
        struct nand_chip *chip = mtd->priv;
 
        if (ctrl & NAND_CTRL_CHANGE) {
-               void __iomem *addr
+               void __iomem *addr;
                unsigned char bits;
 
                addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
index eb7d4d443deb1b7cdcc6480f9653db79a637e6dd..082073acf20fc51b6a252623bca2d7cc59ba456b 100644 (file)
@@ -81,7 +81,7 @@ __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
  */
 static struct mtd_partition partition_info_hi[] = {
       { .name = "PPChameleon HI Nand Flash",
-       offset = 0,
+       .offset = 0,
        .size = 128 * 1024 * 1024
       }
 };
@@ -424,9 +424,9 @@ static void __exit ppchameleonevb_cleanup(void)
 
        /* Release iomaps */
        this = (struct nand_chip *) &ppchameleon_mtd[1];
-       iounmap((void *) this->IO_ADDR_R;
+       iounmap((void *) this->IO_ADDR_R);
        this = (struct nand_chip *) &ppchameleonevb_mtd[1];
-       iounmap((void *) this->IO_ADDR_R;
+       iounmap((void *) this->IO_ADDR_R);
 
        /* Free the MTD device structure */
        kfree (ppchameleon_mtd);
index e8c9f27817b08f9d36c60d6abacf4b6c800e85a1..a804965e654259a3f136e02d0a4aa961b286eef2 100644 (file)
@@ -435,20 +435,12 @@ static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 
        spin_lock_irqsave(&cp->lock, flags);
        cp->vlgrp = grp;
-       cp->cpcmd |= RxVlanOn;
-       cpw16(CpCmd, cp->cpcmd);
-       spin_unlock_irqrestore(&cp->lock, flags);
-}
-
-static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct cp_private *cp = netdev_priv(dev);
-       unsigned long flags;
+       if (grp)
+               cp->cpcmd |= RxVlanOn;
+       else
+               cp->cpcmd &= ~RxVlanOn;
 
-       spin_lock_irqsave(&cp->lock, flags);
-       cp->cpcmd &= ~RxVlanOn;
        cpw16(CpCmd, cp->cpcmd);
-       vlan_group_set_device(cp->vlgrp, vid, NULL);
        spin_unlock_irqrestore(&cp->lock, flags);
 }
 #endif /* CP_VLAN_TAG_USED */
@@ -1944,7 +1936,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 #if CP_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = cp_vlan_rx_register;
-       dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid;
 #endif
 
        if (pci_using_dac)
index c5baa197bc08b6ce8dc5b0a0cbe71afd81333fc4..7d57f4a25dc178218d380adb2c265081b9d513c4 100644 (file)
@@ -2218,7 +2218,7 @@ config SK98LIN
 
 config VIA_VELOCITY
        tristate "VIA Velocity support"
-       depends on NET_PCI && PCI
+       depends on PCI
        select CRC32
        select CRC_CCITT
        select MII
@@ -2280,7 +2280,7 @@ config GFAR_NAPI
 config UCC_GETH
        tristate "Freescale QE Gigabit Ethernet"
        depends on QUICC_ENGINE
-       select UCC_FAST
+       select PHYLIB
        help
          This driver supports the Gigabit Ethernet mode of the QUICC Engine,
          which is available on some Freescale SOCs.
index 7122b7ba8d61f098e22bfb2fab4e6e527c1de629..04382f979c996ef9834061c21ffe25399ad879e8 100644 (file)
@@ -480,12 +480,10 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
 #if ACENIC_DO_VLAN
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = ace_vlan_rx_register;
-       dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid;
 #endif
-       if (1) {
-               dev->tx_timeout = &ace_watchdog;
-               dev->watchdog_timeo = 5*HZ;
-       }
+
+       dev->tx_timeout = &ace_watchdog;
+       dev->watchdog_timeo = 5*HZ;
 
        dev->open = &ace_open;
        dev->stop = &ace_close;
@@ -2283,19 +2281,6 @@ static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        ace_unmask_irq(dev);
        local_irq_restore(flags);
 }
-
-
-static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct ace_private *ap = netdev_priv(dev);
-       unsigned long flags;
-
-       local_irq_save(flags);
-       ace_mask_irq(dev);
-       vlan_group_set_device(ap->vlgrp, vid, NULL);
-       ace_unmask_irq(dev);
-       local_irq_restore(flags);
-}
 #endif /* ACENIC_DO_VLAN */
 
 
index 8ca8534d70bf33c56adac5130bd284808ab1a938..60ed1837fa8fd8435da2efa09c2c5c63dd619d28 100644 (file)
@@ -787,7 +787,6 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev);
 static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
 #if ACENIC_DO_VLAN
 static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
-static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
 #endif
 
 #endif /* _ACENIC_H_ */
index 675fe918421b69ca171964e9e0f41581d2601a8b..a61b2f89fc336c3f7bc75a9f2dece28c37124586 100644 (file)
@@ -155,7 +155,7 @@ This function will write into PHY registers.
 */
 static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val)
 {
-       unsigned int repeat = REPEAT_CNT
+       unsigned int repeat = REPEAT_CNT;
        void __iomem *mmio = lp->mmio;
        unsigned int reg_val;
 
@@ -1728,15 +1728,8 @@ static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group
        lp->vlgrp = grp;
        spin_unlock_irq(&lp->lock);
 }
-
-static void amd8111e_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct amd8111e_priv *lp = netdev_priv(dev);
-       spin_lock_irq(&lp->lock);
-       vlan_group_set_device(lp->vlgrp, vid, NULL);
-       spin_unlock_irq(&lp->lock);
-}
 #endif
+
 static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp)
 {
        writel( VAL1|MPPLBA, lp->mmio + CMD3);
@@ -1996,7 +1989,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 #if AMD8111E_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ;
        dev->vlan_rx_register =amd8111e_vlan_rx_register;
-       dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid;
 #endif
 
        lp = netdev_priv(dev);
@@ -2049,7 +2041,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 #if AMD8111E_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register =amd8111e_vlan_rx_register;
-       dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid;
 #endif
        /* Probe the external PHY */
        amd8111e_probe_ext_phy(dev);
index 2007510c4eb6b97dd744a4487c8c3516997cefaf..e65080a5994a62010ec66fa79075997bb507e104 100644 (file)
@@ -615,7 +615,7 @@ typedef enum {
 #define SSTATE  2
 
 /* Assume contoller gets data 10 times the maximum processing time */
-#define  REPEAT_CNT                    10;
+#define  REPEAT_CNT                    10
 
 /* amd8111e decriptor flag definitions */
 typedef enum {
index 7284ccad0b919383a72ef6da0589c1d256cc6a8e..4030274fe788d1bf3f1e7f0fdc3f589965856bb0 100644 (file)
@@ -2,10 +2,8 @@
 # Arcnet configuration
 #
 
-menu "ARCnet devices"
+menuconfig ARCNET
        depends on NETDEVICES && (ISA || PCI)
-
-config ARCNET
        tristate "ARCnet support"
        ---help---
          If you have a network card of this type, say Y and check out the
@@ -25,9 +23,10 @@ config ARCNET
          <file:Documentation/networking/net-modules.txt>.  The module will
          be called arcnet.
 
+if ARCNET
+
 config ARCNET_1201
        tristate "Enable standard ARCNet packet format (RFC 1201)"
-       depends on ARCNET
        help
          This allows you to use RFC1201 with your ARCnet card via the virtual
          arc0 device.  You need to say Y here to communicate with
@@ -38,7 +37,6 @@ config ARCNET_1201
 
 config ARCNET_1051
        tristate "Enable old ARCNet packet format (RFC 1051)"
-       depends on ARCNET
        ---help---
          This allows you to use RFC1051 with your ARCnet card via the virtual
          arc0s device. You only need arc0s if you want to talk to ARCnet
@@ -53,7 +51,6 @@ config ARCNET_1051
 
 config ARCNET_RAW
        tristate "Enable raw mode packet interface"
-       depends on ARCNET
        help
          ARCnet "raw mode" packet encapsulation, no soft headers.  Unlikely
          to work unless talking to a copy of the same Linux arcnet driver,
@@ -61,7 +58,6 @@ config ARCNET_RAW
 
 config ARCNET_CAP
        tristate "Enable CAP mode packet interface"
-       depends on ARCNET
        help
          ARCnet "cap mode" packet encapsulation. Used to get the hardware
           acknowledge back to userspace. After the initial protocol byte every
@@ -80,7 +76,6 @@ config ARCNET_CAP
 
 config ARCNET_COM90xx
        tristate "ARCnet COM90xx (normal) chipset driver"
-       depends on ARCNET
        help
          This is the chipset driver for the standard COM90xx cards. If you
          have always used the old ARCnet driver without knowing what type of
@@ -92,7 +87,6 @@ config ARCNET_COM90xx
 
 config ARCNET_COM90xxIO
        tristate "ARCnet COM90xx (IO mapped) chipset driver"
-       depends on ARCNET
        ---help---
          This is the chipset driver for the COM90xx cards, using them in
          IO-mapped mode instead of memory-mapped mode. This is slower than
@@ -105,7 +99,6 @@ config ARCNET_COM90xxIO
 
 config ARCNET_RIM_I
        tristate "ARCnet COM90xx (RIM I) chipset driver"
-       depends on ARCNET
        ---help---
          This is yet another chipset driver for the COM90xx cards, but this
          time only using memory-mapped mode, and no IO ports at all. This
@@ -118,7 +111,6 @@ config ARCNET_RIM_I
 
 config ARCNET_COM20020
        tristate "ARCnet COM20020 chipset driver"
-       depends on ARCNET
        help
          This is the driver for the new COM20020 chipset. It supports such
          things as promiscuous mode, so packet sniffing is possible, and
@@ -136,5 +128,4 @@ config ARCNET_COM20020_PCI
        tristate "Support for COM20020 on PCI"
        depends on ARCNET_COM20020 && PCI
 
-endmenu
-
+endif # ARCNET
index 78cf00ff3d388d9f3eb899b69846de27daa04181..6862c11ff86408972ca124ab6813ee52fe497c0b 100644 (file)
@@ -1229,39 +1229,9 @@ static void atl1_vlan_rx_register(struct net_device *netdev,
        spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
-/* FIXME: justify or remove -- CHS */
-static void atl1_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
-       /* We don't do Vlan filtering */
-       return;
-}
-
-/* FIXME: this looks wrong too -- CHS */
-static void atl1_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->lock, flags);
-       /* atl1_irq_disable(adapter); */
-       vlan_group_set_device(adapter->vlgrp, vid, NULL);
-       /* atl1_irq_enable(adapter); */
-       spin_unlock_irqrestore(&adapter->lock, flags);
-       /* We don't do Vlan filtering */
-       return;
-}
-
 static void atl1_restore_vlan(struct atl1_adapter *adapter)
 {
        atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-       if (adapter->vlgrp) {
-               u16 vid;
-               for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-                       if (!vlan_group_get_device(adapter->vlgrp, vid))
-                               continue;
-                       atl1_vlan_rx_add_vid(adapter->netdev, vid);
-               }
-       }
 }
 
 static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring)
@@ -2203,8 +2173,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
        netdev->poll_controller = atl1_poll_controller;
 #endif
        netdev->vlan_rx_register = atl1_vlan_rx_register;
-       netdev->vlan_rx_add_vid = atl1_vlan_rx_add_vid;
-       netdev->vlan_rx_kill_vid = atl1_vlan_rx_kill_vid;
+
        netdev->ethtool_ops = &atl1_ethtool_ops;
        adapter->bd_number = cards_found;
        adapter->pci_using_64 = pci_using_64;
index 88b33c6ddda8d0aaef1306251b63d7c0211c5e16..ce3ed67a878e39af77ab5a95453406091b7c6e15 100644 (file)
@@ -54,8 +54,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.5.10"
-#define DRV_MODULE_RELDATE     "May 1, 2007"
+#define DRV_MODULE_VERSION     "1.5.11"
+#define DRV_MODULE_RELDATE     "June 4, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -1778,6 +1778,15 @@ bnx2_init_5709_context(struct bnx2 *bp)
        val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
        val |= (BCM_PAGE_BITS - 8) << 16;
        REG_WR(bp, BNX2_CTX_COMMAND, val);
+       for (i = 0; i < 10; i++) {
+               val = REG_RD(bp, BNX2_CTX_COMMAND);
+               if (!(val & BNX2_CTX_COMMAND_MEM_INIT))
+                       break;
+               udelay(2);
+       }
+       if (val & BNX2_CTX_COMMAND_MEM_INIT)
+               return -EBUSY;
+
        for (i = 0; i < bp->ctx_pages; i++) {
                int j;
 
@@ -1811,6 +1820,7 @@ bnx2_init_context(struct bnx2 *bp)
        vcid = 96;
        while (vcid) {
                u32 vcid_addr, pcid_addr, offset;
+               int i;
 
                vcid--;
 
@@ -1831,16 +1841,20 @@ bnx2_init_context(struct bnx2 *bp)
                        pcid_addr = vcid_addr;
                }
 
-               REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
-               REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+               for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) {
+                       vcid_addr += (i << PHY_CTX_SHIFT);
+                       pcid_addr += (i << PHY_CTX_SHIFT);
 
-               /* Zero out the context. */
-               for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
-                       CTX_WR(bp, 0x00, offset, 0);
-               }
+                       REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
+                       REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+
+                       /* Zero out the context. */
+                       for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
+                               CTX_WR(bp, 0x00, offset, 0);
 
-               REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
-               REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+                       REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
+                       REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+               }
        }
 }
 
@@ -3691,9 +3705,11 @@ bnx2_init_chip(struct bnx2 *bp)
 
        /* Initialize context mapping and zero out the quick contexts.  The
         * context block must have already been enabled. */
-       if (CHIP_NUM(bp) == CHIP_NUM_5709)
-               bnx2_init_5709_context(bp);
-       else
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               rc = bnx2_init_5709_context(bp);
+               if (rc)
+                       return rc;
+       } else
                bnx2_init_context(bp);
 
        if ((rc = bnx2_init_cpus(bp)) != 0)
@@ -3772,7 +3788,10 @@ bnx2_init_chip(struct bnx2 *bp)
        REG_WR(bp, BNX2_HC_CMD_TICKS,
               (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
 
-       REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
+       if (CHIP_NUM(bp) == CHIP_NUM_5708)
+               REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
+       else
+               REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
        REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
 
        if (CHIP_ID(bp) == CHIP_ID_5706_A1)
@@ -3799,6 +3818,11 @@ bnx2_init_chip(struct bnx2 *bp)
        /* Initialize the receive filter. */
        bnx2_set_rx_mode(bp->dev);
 
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+               val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+               REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+       }
        rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
                          0);
 
@@ -4620,6 +4644,11 @@ bnx2_timer(unsigned long data)
 
        bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
 
+       /* workaround occasional corrupted counters */
+       if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
+               REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
+                                           BNX2_HC_COMMAND_STATS_NOW);
+
        if (bp->phy_flags & PHY_SERDES_FLAG) {
                if (CHIP_NUM(bp) == CHIP_NUM_5706)
                        bnx2_5706_serdes_timer(bp);
@@ -4786,19 +4815,6 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
 
        bnx2_netif_start(bp);
 }
-
-/* Called with rtnl_lock */
-static void
-bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
-{
-       struct bnx2 *bp = netdev_priv(dev);
-
-       bnx2_netif_stop(bp);
-       vlan_group_set_device(bp->vlgrp, vid, NULL);
-       bnx2_set_rx_mode(dev);
-
-       bnx2_netif_start(bp);
-}
 #endif
 
 /* Called with netif_tx_lock.
@@ -5430,6 +5446,10 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
                0xff;
 
        bp->stats_ticks = coal->stats_block_coalesce_usecs;
+       if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+               if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
+                       bp->stats_ticks = USEC_PER_SEC;
+       }
        if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00;
        bp->stats_ticks &= 0xffff00;
 
@@ -6453,7 +6473,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->watchdog_timeo = TX_TIMEOUT;
 #ifdef BCM_VLAN
        dev->vlan_rx_register = bnx2_vlan_rx_register;
-       dev->vlan_rx_kill_vid = bnx2_vlan_rx_kill_vid;
 #endif
        dev->poll = bnx2_poll;
        dev->ethtool_ops = &bnx2_ethtool_ops;
index bd6288d6350f87d505df811c0a9ee7e372799cec..49a5de253b17ff1af7f18fcfc7c92cacc0e7a2cb 100644 (file)
@@ -1373,6 +1373,7 @@ struct l2_fhdr {
 #define BNX2_MISC_NEW_CORE_CTL                         0x000008c8
 #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS     (1L<<0)
 #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ                 (1L<<1)
+#define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE               (1L<<16)
 #define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN             (0x3fffL<<2)
 #define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC              (0xffffL<<16)
 
index 4aec747d9e437a819f6e0127598a35a4f373a88d..59b9943b077d4225c236a1a702fc5d9fbaa82f4b 100644 (file)
@@ -4919,7 +4919,10 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
        pci_cmd &= ~PCI_COMMAND_SERR;
        pci_cmd |= PCI_COMMAND_PARITY;
        pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
-       pci_set_mwi(pdev);
+       if (pci_set_mwi(pdev))
+               printk(KERN_WARNING PFX "Could not enable MWI for %s\n",
+                      pci_name(pdev));
+
        /*
         * On some architectures, the default cache line size set
         * by pci_set_mwi reduces perforamnce.  We have to increase
index 125c9b10586920bb244970606c85cfe21025277f..231ce43b97cfeb68817eabce4148feeaf8285449 100644 (file)
@@ -883,15 +883,6 @@ static void vlan_rx_register(struct net_device *dev,
        t1_set_vlan_accel(adapter, grp != NULL);
        spin_unlock_irq(&adapter->async_lock);
 }
-
-static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct adapter *adapter = dev->priv;
-
-       spin_lock_irq(&adapter->async_lock);
-       vlan_group_set_device(adapter->vlan_grp, vid, NULL);
-       spin_unlock_irq(&adapter->async_lock);
-}
 #endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1099,7 +1090,6 @@ static int __devinit init_one(struct pci_dev *pdev,
                        netdev->features |=
                                NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
                        netdev->vlan_rx_register = vlan_rx_register;
-                       netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
 #endif
 
                        /* T204: disable TSO */
index 269d097dd927663a8e0172b282f0e24e4dfcd6f8..d0f87d82566aa46cf1135d5918cfdfd37690cee6 100644 (file)
 #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_LOW(filterId) (0x204A + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
 #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_MID(filterId) (0x204B + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
 #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_HIGH(filterId)(0x204C + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
-#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId)      (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId)
+#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId)      (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId))
 #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_LOW                     0x204A
 #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_MID                     0x204B
 #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_HIGH                    0x204C
index 67b4b219d927884395857446ce1550548a53b6fd..1b20f4060e2d7a1fbdb00b9154d88103a4127625 100644 (file)
@@ -2067,11 +2067,6 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        t3_synchronize_rx(adapter, pi);
 }
 
-static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       /* nothing */
-}
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void cxgb_netpoll(struct net_device *dev)
 {
@@ -2409,7 +2404,6 @@ static int __devinit init_one(struct pci_dev *pdev,
 
                netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
                netdev->vlan_rx_register = vlan_rx_register;
-               netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
 
                netdev->open = cxgb_open;
                netdev->stop = cxgb_close;
index 571d82f8008c4e9fff3d0b7cff680143b5a9d31c..7df23dc28190c37fd5014480aade885053021ef4 100644 (file)
@@ -566,6 +566,7 @@ static int __devinit dfx_register(struct device *bdev)
                bp->base.mem = ioremap_nocache(bar_start, bar_len);
                if (!bp->base.mem) {
                        printk(KERN_ERR "%s: Cannot map MMIO\n", print_name);
+                       err = -ENOMEM;
                        goto err_out_region;
                }
        } else {
index cbc7febe9cdcdc1c1692aa1f857276e865549953..cf8af928a69cd4b9d157fb97cb6f6071dc421ba8 100644 (file)
@@ -1142,13 +1142,16 @@ e1000_probe(struct pci_dev *pdev,
            !e1000_check_mng_mode(&adapter->hw))
                e1000_get_hw_control(adapter);
 
-       strcpy(netdev->name, "eth%d");
-       if ((err = register_netdev(netdev)))
-               goto err_register;
-
        /* tell the stack to leave us alone until e1000_open() is called */
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
+#ifdef CONFIG_E1000_NAPI
+       netif_poll_disable(netdev);
+#endif
+
+       strcpy(netdev->name, "eth%d");
+       if ((err = register_netdev(netdev)))
+               goto err_register;
 
        DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
 
@@ -1325,7 +1328,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
        spin_lock_init(&adapter->tx_queue_lock);
 #endif
 
-       atomic_set(&adapter->irq_sem, 1);
+       /* Explicitly disable IRQ since the NIC can be in any state. */
+       atomic_set(&adapter->irq_sem, 0);
+       e1000_irq_disable(adapter);
+
        spin_lock_init(&adapter->stats_lock);
 
        set_bit(__E1000_DOWN, &adapter->flags);
@@ -1431,6 +1437,10 @@ e1000_open(struct net_device *netdev)
        /* From here on the code is the same as e1000_up() */
        clear_bit(__E1000_DOWN, &adapter->flags);
 
+#ifdef CONFIG_E1000_NAPI
+       netif_poll_enable(netdev);
+#endif
+
        e1000_irq_enable(adapter);
 
        /* fire a link status change interrupt to start the watchdog */
index 602872dbe15fa4be022b2effd872a0deb447c6b3..e85a933a47625e68bee0704b17d2a5675ac7d492 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0058"
+#define DRV_VERSION    "EHEA_0061"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
        | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
index f6e0cb1ada1ff6a0b14fa07b0e574f18316bf0dc..152bb2016a2c94998e68c0094ab64d9425582dc7 100644 (file)
@@ -428,7 +428,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
                                }
                                skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
                                               cqe->num_bytes_transfered - 4);
-                               ehea_fill_skb(dev, skb, cqe);
+                               ehea_fill_skb(port->netdev, skb, cqe);
                        } else if (rq == 2) {  /* RQ2 */
                                skb = get_skb_by_index(skb_arr_rq2,
                                                       skb_arr_rq2_len, cqe);
index 88efe9731babe983d6cc76983c3a93a5173498d5..e5502af5b8e21a2bf7e3cef3aa13b6e1f1f9c69b 100644 (file)
@@ -550,7 +550,7 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
                                skbn = dev_alloc_skb(pkt_len + 2);
                                if (skbn != NULL) {
                                        skb_reserve(skbn, 2);   /* align IP header */
-                                       skb_copy_from_linear_data(skb
+                                       skb_copy_from_linear_data(skb,
                                                                  skbn->data,
                                                                  pkt_len);
                                        /* swap */
index 7a018027fcc00a39d4e4c362fb00ed40945aa070..32788ca40d25c4cbc726d96451d181038128c003 100644 (file)
@@ -195,7 +195,7 @@ enum {
 #define NVREG_IRQ_TX_FORCED            0x0100
 #define NVREG_IRQ_RECOVER_ERROR                0x8000
 #define NVREG_IRQMASK_THROUGHPUT       0x00df
-#define NVREG_IRQMASK_CPU              0x0040
+#define NVREG_IRQMASK_CPU              0x0060
 #define NVREG_IRQ_TX_ALL               (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
 #define NVREG_IRQ_RX_ALL               (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
 #define NVREG_IRQ_OTHER                        (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
@@ -4605,12 +4605,7 @@ static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
 
        spin_unlock_irq(&np->lock);
-};
-
-static void nv_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       /* nothing to do */
-};
+}
 
 /* The mgmt unit and driver use a semaphore to access the phy during init */
 static int nv_mgmt_acquire_sema(struct net_device *dev)
@@ -4956,7 +4951,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE;
                dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
                dev->vlan_rx_register = nv_vlan_rx_register;
-               dev->vlan_rx_kill_vid = nv_vlan_rx_kill_vid;
        }
 
        np->msi_flags = 0;
index f5b3cba23fc5e402068c2be8d3511fc9dac73147..6822bf14267b265ca8c3b0adc0801074b1f37728 100644 (file)
@@ -140,7 +140,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
 static void gfar_vlan_rx_register(struct net_device *netdev,
                                struct vlan_group *grp);
-static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 void gfar_halt(struct net_device *dev);
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
@@ -284,7 +283,6 @@ static int gfar_probe(struct platform_device *pdev)
 
        if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
                dev->vlan_rx_register = gfar_vlan_rx_register;
-               dev->vlan_rx_kill_vid = gfar_vlan_rx_kill_vid;
 
                dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 
@@ -1133,20 +1131,6 @@ static void gfar_vlan_rx_register(struct net_device *dev,
        spin_unlock_irqrestore(&priv->rxlock, flags);
 }
 
-
-static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
-{
-       struct gfar_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->rxlock, flags);
-
-       vlan_group_set_device(priv->vlgrp, vid, NULL);
-
-       spin_unlock_irqrestore(&priv->rxlock, flags);
-}
-
-
 static int gfar_change_mtu(struct net_device *dev, int new_mtu)
 {
        int tempsize, tempval;
index 8118a6750b614ded8ca7ca0365014d7776022406..8caa591c56494f486461dd831a152bf09d229bb1 100644 (file)
@@ -3005,7 +3005,7 @@ static int __init hp100_isa_init(void)
        return cards > 0 ? 0 : -ENODEV;
 }
 
-static void __exit hp100_isa_cleanup(void)
+static void hp100_isa_cleanup(void)
 {
        int i;
 
index 0343ea12b299638770b46d0af70658f7b17b3f0b..92b403bf38b0f438598c71faa9622ef9ae4cbd06 100644 (file)
@@ -8,15 +8,16 @@
  *     as published by the Free Software Foundation; either version
  *     2 of the License, or (at your option) any later version.
  */
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h> /* printk() */
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/errno.h>  /* error codes */
-#include <linux/types.h>  /* size_t */
-#include <linux/interrupt.h> /* mark_bh */
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
 
 #include <linux/in.h>
 #include <linux/in6.h>
@@ -33,7 +34,6 @@
 
 #include <asm/io.h>
 #include <asm/scatterlist.h>
-#include <linux/dma-mapping.h>
 
 #include "meth.h"
 
@@ -51,8 +51,6 @@
 
 
 static const char *meth_str="SGI O2 Fast Ethernet";
-MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
-MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
 
 #define HAVE_TX_TIMEOUT
 /* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
@@ -784,15 +782,15 @@ static struct net_device_stats *meth_stats(struct net_device *dev)
 /*
  * The init function.
  */
-static struct net_device *meth_init(void)
+static int __init meth_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
        struct meth_private *priv;
-       int ret;
+       int err;
 
        dev = alloc_etherdev(sizeof(struct meth_private));
        if (!dev)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        dev->open            = meth_open;
        dev->stop            = meth_release;
@@ -808,11 +806,12 @@ static struct net_device *meth_init(void)
 
        priv = netdev_priv(dev);
        spin_lock_init(&priv->meth_lock);
+       SET_NETDEV_DEV(dev, &pdev->dev);
 
-       ret = register_netdev(dev);
-       if (ret) {
+       err = register_netdev(dev);
+       if (err) {
                free_netdev(dev);
-               return ERR_PTR(ret);
+               return err;
        }
 
        printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n",
@@ -820,21 +819,44 @@ static struct net_device *meth_init(void)
        return 0;
 }
 
-static struct net_device *meth_dev;
+static int __exit meth_remove(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+
+       unregister_netdev(dev);
+       free_netdev(dev);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver meth_driver = {
+       .probe  = meth_probe,
+       .remove = __devexit_p(meth_remove),
+       .driver = {
+               .name   = "meth",
+       }
+};
 
 static int __init meth_init_module(void)
 {
-       meth_dev = meth_init();
-       if (IS_ERR(meth_dev))
-               return PTR_ERR(meth_dev);
-       return 0;
+       int err;
+
+       err = platform_driver_register(&meth_driver);
+       if (err)
+               printk(KERN_ERR "Driver registration failed\n");
+
+       return err;
 }
 
 static void __exit meth_exit_module(void)
 {
-       unregister_netdev(meth_dev);
-       free_netdev(meth_dev);
+       platform_driver_unregister(&meth_driver);
 }
 
 module_init(meth_init_module);
 module_exit(meth_exit_module);
+
+MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
+MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
+MODULE_LICENSE("GPL");
index dfbd5809d7444a2c7e84403c5eca2dc05518f228..f8d63d39f59246bc80da046ee72963e2303c8644 100644 (file)
@@ -51,8 +51,8 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
 
        if (obj < bitmap->max) {
                set_bit(obj, bitmap->table);
+               bitmap->last = (obj + 1) & (bitmap->max - 1);
                obj |= bitmap->top;
-               bitmap->last = obj + 1;
        } else
                obj = -1;
 
index 5d14be7405a37e29c6a75ee73d9409f25f0d9aa3..b53b7ad999bcb58290b5f790b3afcb15b7eddbb0 100644 (file)
@@ -1472,6 +1472,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
        .set_sg = ethtool_op_set_sg,
        .get_tso = ethtool_op_get_tso,
        .set_tso = ethtool_op_set_tso,
+       .get_link = ethtool_op_get_link,
        .get_strings = myri10ge_get_strings,
        .get_stats_count = myri10ge_get_stats_count,
        .get_ethtool_stats = myri10ge_get_ethtool_stats,
index 2c5c6d20e6e91c8ca8609e67e2ec474e9b53e797..c61181f23bd58dce16d347240b39da5f04f3fb40 100644 (file)
@@ -654,8 +654,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
        if (adapter->portnum == 0)
                netxen_free_adapter_offload(adapter);
 
-       if (adapter->irq)
-               free_irq(adapter->irq, adapter);
        if(adapter->portnum == 0) {
                /* leave the hw in the same state as reboot */
                writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
index 3439f8c649f93e5281aed53ceb2a8b9067ff38c3..717d8e9b98332ab4a59256079005c3560cedb141 100644 (file)
@@ -506,17 +506,6 @@ static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group
        spin_unlock(&dev->tx_lock);
        spin_unlock_irq(&dev->misc_lock);
 }
-
-static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid)
-{
-       struct ns83820 *dev = PRIV(ndev);
-
-       spin_lock_irq(&dev->misc_lock);
-       spin_lock(&dev->tx_lock);
-       vlan_group_set_device(dev->vlgrp, vid, NULL);
-       spin_unlock(&dev->tx_lock);
-       spin_unlock_irq(&dev->misc_lock);
-}
 #endif
 
 /* Packet Receiver
@@ -2083,7 +2072,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        /* We also support hardware vlan acceleration */
        ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        ndev->vlan_rx_register = ns83820_vlan_rx_register;
-       ndev->vlan_rx_kill_vid = ns83820_vlan_rx_kill_vid;
 #endif
 
        if (using_dac) {
index 68c99b4c5255531d11d952fd251e14adc8cf0f55..bb966911a137a051593b1b4ff7f32cf2263cd65f 100644 (file)
@@ -89,6 +89,7 @@ EXPORT_SYMBOL(fixed_mdio_set_link_update);
 /*-----------------------------------------------------------------------------
  *  This is used for updating internal mii regs from the status
  *-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
 static int fixed_mdio_update_regs(struct fixed_info *fixed)
 {
        u16 *regs = fixed->regs;
@@ -165,6 +166,7 @@ static int fixed_mii_reset(struct mii_bus *bus)
        /*nothing here - no way/need to reset it*/
        return 0;
 }
+#endif
 
 static int fixed_config_aneg(struct phy_device *phydev)
 {
@@ -194,6 +196,7 @@ static struct phy_driver fixed_mdio_driver = {
  * number is used to create multiple fixed PHYs, so that several devices can
  * utilize them simultaneously.
  *-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
 static int fixed_mdio_register_device(int number, int speed, int duplex)
 {
        struct mii_bus *new_bus;
@@ -301,6 +304,7 @@ device_create_fail:
 
        return err;
 }
+#endif
 
 
 MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
index d8766c0e825585c230171dcb57cc0a627a791c5f..585be044ebbbdac47d88b0bb76eeb7e932ea027a 100755 (executable)
@@ -4044,7 +4044,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
        if (pci_using_dac)
                ndev->features |= NETIF_F_HIGHDMA;
        if (qdev->device_id == QL3032_DEVICE_ID)
-               ndev->features |= (NETIF_F_HW_CSUM | NETIF_F_SG);
+               ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 
        qdev->mem_map_registers =
            ioremap_nocache(pci_resource_start(pdev, 1),
index 45876a854f002975893d95265798797bb4bc7f1d..5ec7752caa4806c7a2adb10d898c11e04a39583f 100644 (file)
@@ -886,16 +886,6 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
-static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct rtl8169_private *tp = netdev_priv(dev);
-       unsigned long flags;
-
-       spin_lock_irqsave(&tp->lock, flags);
-       vlan_group_set_device(tp->vlgrp, vid, NULL);
-       spin_unlock_irqrestore(&tp->lock, flags);
-}
-
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
                               struct sk_buff *skb)
 {
@@ -1671,7 +1661,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 #ifdef CONFIG_R8169_VLAN
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = rtl8169_vlan_rx_register;
-       dev->vlan_rx_kill_vid = rtl8169_vlan_rx_kill_vid;
 #endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
index e3e6d410d72cdeef0d27bf10de6dce155bb6f201..c6ba3dee8ae0f4a2a84a09018411360b5022eeee 100644 (file)
@@ -340,17 +340,6 @@ static void s2io_vlan_rx_register(struct net_device *dev,
 /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
 static int vlan_strip_flag;
 
-/* Unregister the vlan */
-static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
-{
-       struct s2io_nic *nic = dev->priv;
-       unsigned long flags;
-
-       spin_lock_irqsave(&nic->tx_lock, flags);
-       vlan_group_set_device(nic->vlgrp, vid, NULL);
-       spin_unlock_irqrestore(&nic->tx_lock, flags);
-}
-
 /*
  * Constants to be programmed into the Xena's registers, to configure
  * the XAUI.
@@ -7412,7 +7401,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = s2io_vlan_rx_register;
-       dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
 
        /*
         * will use eth_mac_addr() for  dev->set_mac_address
index fe847800acdcd85ac2a962668d6a0b19eadd7415..75afc1f07ba0ab2b70d263738759cb30c9b52fa9 100644 (file)
@@ -1748,7 +1748,7 @@ char *addr_to_string(struct fddi_addr *addr)
 #endif
 
 #ifdef AM29K
-smt_ifconfig(int argc, char *argv[])
+int smt_ifconfig(int argc, char *argv[])
 {
        if (argc >= 2 && !strcmp(argv[0],"opt_bypass") &&
            !strcmp(argv[1],"yes")) {
index 832fd69a0e59b155f4b28fbf5d502ce363d087b8..fe01b961b597263dc20aad6b331b384c3830d549 100644 (file)
@@ -364,7 +364,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                        /* for SFP-module set SIGDET polarity to low */
                        ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                        ctrl |= PHY_M_FIB_SIGD_POL;
-                       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
                }
 
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
@@ -658,7 +658,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
        const u8 *addr = hw->dev[port]->dev_addr;
 
        sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-       sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+       sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
 
        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
 
@@ -1049,26 +1049,22 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
        u16 port = sky2->port;
 
        netif_tx_lock_bh(dev);
+       netif_poll_disable(sky2->hw->dev[0]);
 
-       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
-       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
        sky2->vlgrp = grp;
+       if (grp) {
+               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+                            RX_VLAN_STRIP_ON);
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            TX_VLAN_TAG_ON);
+       } else {
+               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+                            RX_VLAN_STRIP_OFF);
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            TX_VLAN_TAG_OFF);
+       }
 
-       netif_tx_unlock_bh(dev);
-}
-
-static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct sky2_port *sky2 = netdev_priv(dev);
-       struct sky2_hw *hw = sky2->hw;
-       u16 port = sky2->port;
-
-       netif_tx_lock_bh(dev);
-
-       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
-       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
-       vlan_group_set_device(sky2->vlgrp, vid, NULL);
-
+       netif_poll_enable(sky2->hw->dev[0]);
        netif_tx_unlock_bh(dev);
 }
 #endif
@@ -1432,7 +1428,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                tcpsum = offset << 16;          /* sum start */
                tcpsum |= offset + skb->csum_offset;    /* sum write */
 
-               ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+               ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
                if (ip_hdr(skb)->protocol == IPPROTO_UDP)
                        ctrl |= UDPTCP;
 
@@ -3484,7 +3480,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 #ifdef SKY2_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = sky2_vlan_rx_register;
-       dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
 #endif
 
        /* read the mac address */
index 5efb5afc45baa091eee09138cdf1593cb3d4341c..b8c4a3b5eadf9812f7bede24ebeeb20f76a41e6b 100644 (file)
@@ -1149,7 +1149,7 @@ enum {
        PHY_M_IS_JABBER         = 1<<0, /* Jabber */
 
        PHY_M_DEF_MSK           = PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
-                                | PHY_M_IS_FIFO_ERROR,
+                                | PHY_M_IS_DUP_CHANGE,
        PHY_M_AN_MSK           = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
 };
 
@@ -1732,28 +1732,6 @@ enum {
 
 /*     GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
 enum {
-       GPC_SEL_BDT     = 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
-       GPC_INT_POL_HI  = 1<<27, /* IRQ Polarity is Active HIGH */
-       GPC_75_OHM      = 1<<26, /* Use 75 Ohm Termination instead of 50 */
-       GPC_DIS_FC      = 1<<25, /* Disable Automatic Fiber/Copper Detection */
-       GPC_DIS_SLEEP   = 1<<24, /* Disable Energy Detect */
-       GPC_HWCFG_M_3   = 1<<23, /* HWCFG_MODE[3] */
-       GPC_HWCFG_M_2   = 1<<22, /* HWCFG_MODE[2] */
-       GPC_HWCFG_M_1   = 1<<21, /* HWCFG_MODE[1] */
-       GPC_HWCFG_M_0   = 1<<20, /* HWCFG_MODE[0] */
-       GPC_ANEG_0      = 1<<19, /* ANEG[0] */
-       GPC_ENA_XC      = 1<<18, /* Enable MDI crossover */
-       GPC_DIS_125     = 1<<17, /* Disable 125 MHz clock */
-       GPC_ANEG_3      = 1<<16, /* ANEG[3] */
-       GPC_ANEG_2      = 1<<15, /* ANEG[2] */
-       GPC_ANEG_1      = 1<<14, /* ANEG[1] */
-       GPC_ENA_PAUSE   = 1<<13, /* Enable Pause (SYM_OR_REM) */
-       GPC_PHYADDR_4   = 1<<12, /* Bit 4 of Phy Addr */
-       GPC_PHYADDR_3   = 1<<11, /* Bit 3 of Phy Addr */
-       GPC_PHYADDR_2   = 1<<10, /* Bit 2 of Phy Addr */
-       GPC_PHYADDR_1   = 1<<9,  /* Bit 1 of Phy Addr */
-       GPC_PHYADDR_0   = 1<<8,  /* Bit 0 of Phy Addr */
-                                               /* Bits  7..2:  reserved */
        GPC_RST_CLR     = 1<<1, /* Clear GPHY Reset */
        GPC_RST_SET     = 1<<0, /* Set   GPHY Reset */
 };
index 111f23d05764b1544ee06f6f0e9d95a3bafee31f..506bffcbc6dc9f319eafc8d2804ae123ed1181d3 100644 (file)
@@ -281,17 +281,14 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 
 #elif   defined(CONFIG_SUPERH)
 
-#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#ifdef CONFIG_SOLUTION_ENGINE
 #define SMC_CAN_USE_8BIT       0
 #define SMC_CAN_USE_16BIT      1
 #define SMC_CAN_USE_32BIT      0
 #define SMC_IO_SHIFT           0
 #define SMC_NOWAIT             1
 
-#define SMC_inb(a, r)          (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff
 #define SMC_inw(a, r)          inw((a) + (r))
-#define SMC_outb(v, a, r)      outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
-
 #define SMC_outw(v, a, r)      outw(v, (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)
index c3964c3d89d93e8f6e65b23a16e6d2ef1a1935dd..b47ad1df2e0cd8c6cafe7d4e51a00cfa27945013 100644 (file)
@@ -1014,12 +1014,12 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
                 */
        }
 
-       /* pass skb up to stack */
-       netif_receive_skb(skb);
-
        /* update netdevice statistics */
        card->netdev_stats.rx_packets++;
        card->netdev_stats.rx_bytes += skb->len;
+
+       /* pass skb up to stack */
+       netif_receive_skb(skb);
 }
 
 #ifdef DEBUG
@@ -1190,43 +1190,6 @@ spider_net_poll(struct net_device *netdev, int *budget)
        return 1;
 }
 
-/**
- * spider_net_vlan_rx_reg - initializes VLAN structures in the driver and card
- * @netdev: interface device structure
- * @grp: vlan_group structure that is registered (NULL on destroying interface)
- */
-static void
-spider_net_vlan_rx_reg(struct net_device *netdev, struct vlan_group *grp)
-{
-       /* further enhancement... yet to do */
-       return;
-}
-
-/**
- * spider_net_vlan_rx_add - adds VLAN id to the card filter
- * @netdev: interface device structure
- * @vid: VLAN id to add
- */
-static void
-spider_net_vlan_rx_add(struct net_device *netdev, uint16_t vid)
-{
-       /* further enhancement... yet to do */
-       /* add vid to card's VLAN filter table */
-       return;
-}
-
-/**
- * spider_net_vlan_rx_kill - removes VLAN id to the card filter
- * @netdev: interface device structure
- * @vid: VLAN id to remove
- */
-static void
-spider_net_vlan_rx_kill(struct net_device *netdev, uint16_t vid)
-{
-       /* further enhancement... yet to do */
-       /* remove vid from card's VLAN filter table */
-}
-
 /**
  * spider_net_get_stats - get interface statistics
  * @netdev: interface device structure
@@ -2177,9 +2140,6 @@ spider_net_setup_netdev_ops(struct net_device *netdev)
        netdev->poll = &spider_net_poll;
        netdev->weight = SPIDER_NET_NAPI_WEIGHT;
        /* HW VLAN */
-       netdev->vlan_rx_register = &spider_net_vlan_rx_reg;
-       netdev->vlan_rx_add_vid = &spider_net_vlan_rx_add;
-       netdev->vlan_rx_kill_vid = &spider_net_vlan_rx_kill;
 #ifdef CONFIG_NET_POLL_CONTROLLER
        /* poll controller */
        netdev->poll_controller = &spider_net_poll_controller;
index 923b9c725cc3f4e5cd75434914dbb4ce466c151f..2f3184184ad9b201c82d5c38260de72d4a5f2d6a 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.76"
-#define DRV_MODULE_RELDATE     "May 5, 2007"
+#define DRV_MODULE_VERSION     "3.77"
+#define DRV_MODULE_RELDATE     "May 31, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -9121,21 +9121,6 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        if (netif_running(dev))
                tg3_netif_start(tp);
 }
-
-static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct tg3 *tp = netdev_priv(dev);
-
-       if (netif_running(dev))
-               tg3_netif_stop(tp);
-
-       tg3_full_lock(tp, 0);
-       vlan_group_set_device(tp->vlgrp, vid, NULL);
-       tg3_full_unlock(tp);
-
-       if (netif_running(dev))
-               tg3_netif_start(tp);
-}
 #endif
 
 static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
@@ -10976,6 +10961,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
         * upon subsystem IDs.
         */
        if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
            !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
                tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT |
                                  TG3_FLAG_USE_LINKCHG_REG);
@@ -11778,7 +11764,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 #if TG3_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->vlan_rx_register = tg3_vlan_rx_register;
-       dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid;
 #endif
 
        tp = netdev_priv(dev);
index 99c4c1922f190f2bd9d81025ad0697c3dc939347..e6b2e06493e79b4c0fe05dbd5397bf48224b36d8 100644 (file)
@@ -2,12 +2,10 @@
 # Token Ring driver configuration
 #
 
-menu "Token Ring devices"
-       depends on NETDEVICES && !UML
-
 # So far, we only have PCI, ISA, and MCA token ring devices
-config TR
+menuconfig TR
        bool "Token Ring driver support"
+       depends on NETDEVICES && !UML
        depends on (PCI || ISA || MCA || CCW)
        select LLC
        help
@@ -20,9 +18,11 @@ config TR
          from <http://www.tldp.org/docs.html#howto>. Most people can
          say N here.
 
+if TR
+
 config IBMTR
        tristate "IBM Tropic chipset based adapter support"
-       depends on TR && (ISA || MCA)
+       depends on ISA || MCA
        ---help---
          This is support for all IBM Token Ring cards that don't use DMA. If
          you have such a beast, say Y and read the Token-Ring mini-HOWTO,
@@ -36,7 +36,7 @@ config IBMTR
 
 config IBMOL
        tristate "IBM Olympic chipset PCI adapter support"
-       depends on TR && PCI
+       depends on PCI
        ---help---
          This is support for all non-Lanstreamer IBM PCI Token Ring Cards.
          Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II
@@ -54,7 +54,7 @@ config IBMOL
 
 config IBMLS
        tristate "IBM Lanstreamer chipset PCI adapter support"
-       depends on TR && PCI && !64BIT
+       depends on PCI && !64BIT
        help
          This is support for IBM Lanstreamer PCI Token Ring Cards.
 
@@ -66,7 +66,7 @@ config IBMLS
 
 config 3C359
        tristate "3Com 3C359 Token Link Velocity XL adapter support"
-       depends on TR && PCI
+       depends on PCI
        ---help---
          This is support for the 3Com PCI Velocity XL cards, specifically
          the 3Com 3C359, please note this is not for the 3C339 cards, you
@@ -84,7 +84,7 @@ config 3C359
 
 config TMS380TR
        tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
-       depends on TR && (PCI || ISA && ISA_DMA_API || MCA)
+       depends on PCI || ISA && ISA_DMA_API || MCA
        select FW_LOADER
        ---help---
          This driver provides generic support for token ring adapters
@@ -108,7 +108,7 @@ config TMS380TR
 
 config TMSPCI
        tristate "Generic TMS380 PCI support"
-       depends on TR && TMS380TR && PCI
+       depends on TMS380TR && PCI
        ---help---
          This tms380 module supports generic TMS380-based PCI cards.
 
@@ -123,7 +123,7 @@ config TMSPCI
 
 config SKISA
        tristate "SysKonnect TR4/16 ISA support"
-       depends on TR && TMS380TR && ISA
+       depends on TMS380TR && ISA
        help
          This tms380 module supports SysKonnect TR4/16 ISA cards.
 
@@ -135,7 +135,7 @@ config SKISA
 
 config PROTEON
        tristate "Proteon ISA support"
-       depends on TR && TMS380TR && ISA
+       depends on TMS380TR && ISA
        help
          This tms380 module supports Proteon ISA cards.
 
@@ -148,7 +148,7 @@ config PROTEON
 
 config ABYSS
        tristate "Madge Smart 16/4 PCI Mk2 support"
-       depends on TR && TMS380TR && PCI
+       depends on TMS380TR && PCI
        help
          This tms380 module supports the Madge Smart 16/4 PCI Mk2
          cards (51-02).
@@ -158,7 +158,7 @@ config ABYSS
 
 config MADGEMC
        tristate "Madge Smart 16/4 Ringnode MicroChannel"
-       depends on TR && TMS380TR && MCA
+       depends on TMS380TR && MCA
        help
          This tms380 module supports the Madge Smart 16/4 MC16 and MC32
          MicroChannel adapters.
@@ -168,7 +168,7 @@ config MADGEMC
 
 config SMCTR
        tristate "SMC ISA/MCA adapter support"
-       depends on TR && (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
+       depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
        ---help---
          This is support for the ISA and MCA SMC Token Ring cards,
          specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A
@@ -182,5 +182,4 @@ config SMCTR
          To compile this driver as a module, choose M here: the module will be
          called smctr.
 
-endmenu
-
+endif # TR
index f72573594121340f217336024e9a1aff192c30db..15b2fb8aa49280008f1b38925340df4495c19cdd 100644 (file)
@@ -741,15 +741,6 @@ typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        spin_unlock_bh(&tp->state_lock);
 }
 
-static void
-typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct typhoon *tp = netdev_priv(dev);
-       spin_lock_bh(&tp->state_lock);
-       vlan_group_set_device(tp->vlgrp, vid, NULL);
-       spin_unlock_bh(&tp->state_lock);
-}
-
 static inline void
 typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
                        u32 ring_dma)
@@ -2542,7 +2533,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->get_stats          = typhoon_get_stats;
        dev->set_mac_address    = typhoon_set_mac_address;
        dev->vlan_rx_register   = typhoon_vlan_rx_register;
-       dev->vlan_rx_kill_vid   = typhoon_vlan_rx_kill_vid;
+
        SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
 
        /* We can handle scatter gather, up to 16 entries, and
index c2ccbd098f538778ac0cb4e0b280a61974c9e3a0..18b731bb4da1a6cfe881b1c8485e9b92268fc1e4 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
-#include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/workqueue.h>
index f96966d4bcc2b55a1eb3d239c209ec5a6ebd7d65..7bcb82f50cf73b85514df409ea0cc5afc5938809 100644 (file)
@@ -260,8 +260,6 @@ static struct of_device_id uec_mdio_match[] = {
        {},
 };
 
-MODULE_DEVICE_TABLE(of, uec_mdio_match);
-
 static struct of_platform_driver uec_mdio_driver = {
        .name   = DRV_NAME,
        .probe  = uec_mdio_probe,
index d5ef97bc4d0169ba2dfe855d92f17c53abbc2eed..6d95cacd5284dec9642d41d2e4dfce146eb65189 100644 (file)
@@ -1458,6 +1458,10 @@ static const struct usb_device_id        products [] = {
        // IO-DATA ETG-US2
        USB_DEVICE (0x04bb, 0x0930),
        .driver_info = (unsigned long) &ax88178_info,
+}, {
+       // Belkin F5D5055
+       USB_DEVICE(0x050d, 0x5055),
+       .driver_info = (unsigned long) &ax88178_info,
 },
        { },            // END
 };
index 5a21f06bf8a54fab20e2bb70dd0f599b4be910c2..675ac99a79c6174bfd3f87f8b2b27f23e29417bf 100644 (file)
@@ -91,6 +91,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
                                "CDC descriptors on config\n");
        }
 
+       /* Maybe CDC descriptors are after the endpoint?  This bug has
+        * been seen on some 2Wire Inc RNDIS-ish products.
+        */
+       if (len == 0) {
+               struct usb_host_endpoint        *hep;
+
+               hep = intf->cur_altsetting->endpoint;
+               if (hep) {
+                       buf = hep->extra;
+                       len = hep->extralen;
+               }
+               if (len)
+                       dev_dbg(&intf->dev,
+                               "CDC descriptors on endpoint\n");
+       }
+
        /* this assumes that if there's a non-RNDIS vendor variant
         * of cdc-acm, it'll fail RNDIS requests cleanly.
         */
index 980e4aaa97aaa9ed4a8e77e32e2b973ceded9b38..cd991a0f75bb3ef919d8ba9f513b982eba884163 100644 (file)
@@ -515,6 +515,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                dev_err(&intf->dev,
                        "dev can't take %u byte packets (max %u)\n",
                        dev->hard_mtu, tmp);
+               retval = -EINVAL;
                goto fail_and_release;
        }
 
index f9cd42d058b042c7d68949fa1cfe985444189f1f..5b16d9a1269a2851e3f8982b23f835c256044ba7 100644 (file)
@@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
 
 /*-------------------------------------------------------------------------*/
 
-/* FIXME these suspend/resume methods assume non-CDC style
- * devices, with only one interface.
+/*
+ * suspend the whole driver as soon as the first interface is suspended
+ * resume only when the last interface is resumed
  */
 
 int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
 
-       /* accelerate emptying of the rx and queues, to avoid
-        * having everything error out.
-        */
-       netif_device_detach (dev->net);
-       (void) unlink_urbs (dev, &dev->rxq);
-       (void) unlink_urbs (dev, &dev->txq);
+       if (!dev->suspend_count++) {
+               /* accelerate emptying of the rx and queues, to avoid
+                * having everything error out.
+                */
+               netif_device_detach (dev->net);
+               (void) unlink_urbs (dev, &dev->rxq);
+               (void) unlink_urbs (dev, &dev->txq);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(usbnet_suspend);
@@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
 
-       netif_device_attach (dev->net);
-       tasklet_schedule (&dev->bh);
+       if (!--dev->suspend_count) {
+               netif_device_attach (dev->net);
+               tasklet_schedule (&dev->bh);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(usbnet_resume);
index 82db5a8e528e57b95ad40c369afb31b7298c2aa6..a3f8b9e7bc00551d12690555d412ed28a9c9d55c 100644 (file)
@@ -32,6 +32,7 @@ struct usbnet {
        const char              *driver_name;
        wait_queue_head_t       *wait;
        struct mutex            phy_mutex;
+       unsigned char           suspend_count;
 
        /* i/o info: pipes etc */
        unsigned                in, out;
index 246fac0e80010bf4537417f0093b6a8d682bffdd..3df3c60263d4ac07e50e4aa4029a0f03affdc101 100644 (file)
@@ -311,7 +311,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
        local_info_t *local;
        struct ieee80211_hdr_4addr *hdr;
        u16 fc;
-       int hdr_len, res;
+       int prefix_len, postfix_len, hdr_len, res;
 
        iface = netdev_priv(skb->dev);
        local = iface->local;
@@ -337,10 +337,13 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
        if (skb == NULL)
                return NULL;
 
-       if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
-            skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
-           pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
-                            crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
+       prefix_len = crypt->ops->extra_mpdu_prefix_len +
+               crypt->ops->extra_msdu_prefix_len;
+       postfix_len = crypt->ops->extra_mpdu_postfix_len +
+               crypt->ops->extra_msdu_postfix_len;
+       if ((skb_headroom(skb) < prefix_len ||
+            skb_tailroom(skb) < postfix_len) &&
+           pskb_expand_head(skb, prefix_len, postfix_len, GFP_ATOMIC)) {
                kfree_skb(skb);
                return NULL;
        }
index 606bdd002be748f288ecd3006dd97f0795ffc579..dfe27642322c9d49f264fe277f940cc338ff9987 100644 (file)
@@ -46,7 +46,7 @@ u32 libertas_index_to_data_rate(u8 index);
 u8 libertas_data_rate_to_index(u32 rate);
 void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
 
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
 
 /** The proc fs interface */
 int libertas_process_rx_command(wlan_private * priv);
index 441123c85e62ce0a3d68ec0f0db26414966683a3..5c63c9b1659c1e45e1054bb01fd0969a82dfa563 100644 (file)
@@ -333,18 +333,22 @@ static void command_timer_fn(unsigned long data)
        unsigned long flags;
 
        ptempnode = adapter->cur_cmd;
+       if (ptempnode == NULL) {
+               lbs_pr_debug(1, "PTempnode Empty\n");
+               return;
+       }
+
        cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
+       if (!cmd) {
+               lbs_pr_debug(1, "cmd is NULL\n");
+               return;
+       }
 
        lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command);
 
        if (!adapter->fw_ready)
                return;
 
-       if (ptempnode == NULL) {
-               lbs_pr_debug(1, "PTempnode Empty\n");
-               return;
-       }
-
        spin_lock_irqsave(&adapter->driver_lock, flags);
        adapter->cur_cmd = NULL;
        spin_unlock_irqrestore(&adapter->driver_lock, flags);
index d17924f764e573d5edd537aefac261c817e28f6e..96619a32951bc9dc14904dd3267c13c25d5f7189 100644 (file)
@@ -136,7 +136,7 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
        LEAVE();
 }
 
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
 {
        lbs_pr_debug(1, "skb->data=%p\n", skb->data);
 
@@ -148,8 +148,6 @@ int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        netif_rx(skb);
-
-       return 0;
 }
 
 /**
@@ -269,15 +267,11 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
        wlan_compute_rssi(priv, p_rx_pd);
 
        lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
-       if (libertas_upload_rx_packet(priv, skb)) {
-               lbs_pr_debug(1, "RX error: libertas_upload_rx_packet"
-                      " returns failure\n");
-               ret = -1;
-               goto done;
-       }
        priv->stats.rx_bytes += skb->len;
        priv->stats.rx_packets++;
 
+       libertas_upload_rx_packet(priv, skb);
+
        ret = 0;
 done:
        LEAVE();
@@ -438,22 +432,14 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
        wlan_compute_rssi(priv, prxpd);
 
        lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
-
-       if (libertas_upload_rx_packet(priv, skb)) {
-               lbs_pr_debug(1, "RX error: libertas_upload_rx_packet "
-                       "returns failure\n");
-               ret = -1;
-               goto done;
-       }
-
        priv->stats.rx_bytes += skb->len;
        priv->stats.rx_packets++;
 
+       libertas_upload_rx_packet(priv, skb);
+
        ret = 0;
 done:
        LEAVE();
 
-       skb->protocol = __constant_htons(0x0019);       /* ETH_P_80211_RAW */
-
        return (ret);
 }
index dd070cccf324a8effd3f1db02aca58a7f1d5ceb8..f49eb068c7d0ce232b9535d6d036bf64ae11222c 100644 (file)
@@ -378,9 +378,10 @@ islpci_eth_receive(islpci_private *priv)
        display_buffer((char *) skb->data, skb->len);
 #endif
        /* take care of monitor mode and spy monitoring. */
-       if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
+       if (unlikely(priv->iw_mode == IW_MODE_MONITOR)) {
+               skb->dev = ndev;
                discard = islpci_monitor_rx(priv, &skb);
-       else {
+       else {
                if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
                        /* The packet has a rx_annex. Read it for spy monitoring, Then
                         * remove it, while keeping the 2 leading MAC addr.
index d9cbd586ae4bc282815a6b7aad16ddb3ecb523df..be1df85e5e2d5ae08b5a3f562cb462589495f409 100644 (file)
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/msi.h>
+#include <linux/smp.h>
 
 #include <asm/errno.h>
 #include <asm/io.h>
-#include <asm/smp.h>
 
 #include "pci.h"
 #include "msi.h"
@@ -333,7 +333,7 @@ static int msi_capability_init(struct pci_dev *dev)
                        msi_mask_bits_reg(pos, is_64bit_address(control)),
                        maskbits);
        }
-       list_add(&entry->list, &dev->msi_list);
+       list_add_tail(&entry->list, &dev->msi_list);
 
        /* Configure MSI capability structure */
        ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI);
@@ -404,7 +404,7 @@ static int msix_capability_init(struct pci_dev *dev,
                entry->dev = dev;
                entry->mask_base = base;
 
-               list_add(&entry->list, &dev->msi_list);
+               list_add_tail(&entry->list, &dev->msi_list);
        }
 
        ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
@@ -558,12 +558,12 @@ static int msi_free_irqs(struct pci_dev* dev)
 
        list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
                if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) {
-                       if (list_is_last(&entry->list, &dev->msi_list))
-                               iounmap(entry->mask_base);
-
                        writel(1, entry->mask_base + entry->msi_attrib.entry_nr
                                  * PCI_MSIX_ENTRY_SIZE
                                  + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+
+                       if (list_is_last(&entry->list, &dev->msi_list))
+                               iounmap(entry->mask_base);
                }
                list_del(&entry->list);
                kfree(entry);
index 6ccc2e95930a299074550ef9c050a42011c80c98..01d8f8a8843c5c064250f09af7396a1e3aa7cdd0 100644 (file)
@@ -1625,18 +1625,22 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
- * some other busses controlled by the chipset even if Linux is not aware of it.
- * Instead of setting the flag on all busses in the machine, simply disable MSI
- * globally.
+/* Some chipsets do not support MSI. We cannot easily rely on setting
+ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
+ * some other busses controlled by the chipset even if Linux is not
+ * aware of it.  Instead of setting the flag on all busses in the
+ * machine, simply disable MSI globally.
  */
-static void __init quirk_svw_msi(struct pci_dev *dev)
+static void __init quirk_disable_all_msi(struct pci_dev *dev)
 {
        pci_no_msi();
        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_svw_msi);
+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_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
 static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -1649,8 +1653,6 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_msi);
 
 /* Go through the list of Hypertransport capabilities and
  * return 1 if a HT MSI capability is found and enabled */
index b137a27472c7feefef492da45e7058cc3356c8bb..c13232435dc06322f824b1f4fd07d34bdce112bb 100644 (file)
@@ -403,10 +403,11 @@ const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
        while (ids->vendor || ids->subvendor || ids->class_mask) {
                list_for_each_entry(dev, &pci_devices, global_list) {
                        if ((found = pci_match_one_device(ids, dev)) != NULL)
-                               break;
+                               goto exit;
                }
                ids++;
        }
+exit:
        up_read(&pci_bus_sem);
        return found;
 }
index 948efc775a78355a44408f2c2e0f625b35efc625..eb6abd3f9221a896f1375ff855c2ac419491e630 100644 (file)
@@ -336,16 +336,21 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
                enable_irq_wake(board->det_pin);
                if (board->irq_pin)
                        enable_irq_wake(board->irq_pin);
-       } else {
-               disable_irq_wake(board->det_pin);
-               if (board->irq_pin)
-                       disable_irq_wake(board->irq_pin);
        }
        return 0;
 }
 
 static int at91_cf_resume(struct platform_device *pdev)
 {
+       struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
+       struct at91_cf_data     *board = cf->board;
+
+       if (device_may_wakeup(&pdev->dev)) {
+               disable_irq_wake(board->det_pin);
+               if (board->irq_pin)
+                       disable_irq_wake(board->irq_pin);
+       }
+
        pcmcia_socket_dev_resume(&pdev->dev);
        return 0;
 }
index 6085261aa2c15b581a8c7dba2a7b2830a945db86..e24ea82dc35b83b1036a2b5cf15d9e54afd2ee96 100644 (file)
@@ -641,9 +641,16 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
         * drivers can't provide shutdown() methods to disable IRQs.
         * Or better yet, fix PNP to allow those methods...
         */
-       return cmos_do_probe(&pnp->dev,
-                       &pnp->res.port_resource[0],
-                       pnp->res.irq_resource[0].start);
+       if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
+               /* Some machines contain a PNP entry for the RTC, but
+                * don't define the IRQ. It should always be safe to
+                * hardcode it in these cases
+                */
+               return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8);
+       else
+               return cmos_do_probe(&pnp->dev,
+                                    &pnp->res.port_resource[0],
+                                    pnp->res.irq_resource[0].start);
 }
 
 static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
index a1dc8c466ec9ba895c6470bea0044c8937452f76..0c081a664ee8561d84048c50065c0fa654d91cb4 100644 (file)
@@ -14,9 +14,9 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/poll.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <asm/atomic.h>
 #include <asm/ebcdic.h>
 
@@ -514,7 +514,7 @@ void dasd_eer_disable(struct dasd_device *device)
  * to transfer in a readbuffer, which is protected by the readbuffer_mutex.
  */
 static char readbuffer[PAGE_SIZE];
-static DECLARE_MUTEX(readbuffer_mutex);
+static DEFINE_MUTEX(readbuffer_mutex);
 
 static int dasd_eer_open(struct inode *inp, struct file *filp)
 {
@@ -579,7 +579,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
        struct eerbuffer *eerb;
 
        eerb = (struct eerbuffer *) filp->private_data;
-       if (down_interruptible(&readbuffer_mutex))
+       if (mutex_lock_interruptible(&readbuffer_mutex))
                return -ERESTARTSYS;
 
        spin_lock_irqsave(&bufferlock, flags);
@@ -588,7 +588,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
                                  /* has been deleted             */
                eerb->residual = 0;
                spin_unlock_irqrestore(&bufferlock, flags);
-               up(&readbuffer_mutex);
+               mutex_unlock(&readbuffer_mutex);
                return -EIO;
        } else if (eerb->residual > 0) {
                /* OK we still have a second half of a record to deliver */
@@ -602,7 +602,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
                        if (!tc) {
                                /* no data available */
                                spin_unlock_irqrestore(&bufferlock, flags);
-                               up(&readbuffer_mutex);
+                               mutex_unlock(&readbuffer_mutex);
                                if (filp->f_flags & O_NONBLOCK)
                                        return -EAGAIN;
                                rc = wait_event_interruptible(
@@ -610,7 +610,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
                                        eerb->head != eerb->tail);
                                if (rc)
                                        return rc;
-                               if (down_interruptible(&readbuffer_mutex))
+                               if (mutex_lock_interruptible(&readbuffer_mutex))
                                        return -ERESTARTSYS;
                                spin_lock_irqsave(&bufferlock, flags);
                        }
@@ -626,11 +626,11 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
        spin_unlock_irqrestore(&bufferlock, flags);
 
        if (copy_to_user(buf, readbuffer, effective_count)) {
-               up(&readbuffer_mutex);
+               mutex_unlock(&readbuffer_mutex);
                return -EFAULT;
        }
 
-       up(&readbuffer_mutex);
+       mutex_unlock(&readbuffer_mutex);
        return effective_count;
 }
 
index f6ef90ee3e7d83d06090ff594818d2f40fdd6c85..743944ad61ecb44be0ba47a9f60ebad97e159730 100644 (file)
@@ -487,7 +487,7 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */
 } __attribute__ ((packed));
 
 static struct diag210 raw3270_init_diag210;
-static DECLARE_MUTEX(raw3270_init_sem);
+static DEFINE_MUTEX(raw3270_init_mutex);
 
 static int
 raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
@@ -713,7 +713,7 @@ raw3270_size_device(struct raw3270 *rp)
 {
        int rc;
 
-       down(&raw3270_init_sem);
+       mutex_lock(&raw3270_init_mutex);
        rp->view = &raw3270_init_view;
        raw3270_init_view.dev = rp;
        if (MACHINE_IS_VM)
@@ -722,7 +722,7 @@ raw3270_size_device(struct raw3270 *rp)
                rc = __raw3270_size_device(rp);
        raw3270_init_view.dev = NULL;
        rp->view = NULL;
-       up(&raw3270_init_sem);
+       mutex_unlock(&raw3270_init_mutex);
        if (rc == 0) {  /* Found something. */
                /* Try to find a model. */
                rp->model = 0;
@@ -749,7 +749,7 @@ raw3270_reset_device(struct raw3270 *rp)
 {
        int rc;
 
-       down(&raw3270_init_sem);
+       mutex_lock(&raw3270_init_mutex);
        memset(&rp->init_request, 0, sizeof(rp->init_request));
        memset(&rp->init_data, 0, sizeof(rp->init_data));
        /* Store reset data stream to init_data/init_request */
@@ -764,7 +764,7 @@ raw3270_reset_device(struct raw3270 *rp)
        rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
        raw3270_init_view.dev = NULL;
        rp->view = NULL;
-       up(&raw3270_init_sem);
+       mutex_unlock(&raw3270_init_mutex);
        return rc;
 }
 
index a8b373f69cf0ef2d61ab1315b3b191f4276e39e9..6b264bdb5bfb1c09097f5133a44becedda7c3865 100644 (file)
@@ -296,30 +296,57 @@ static void ccw_device_unregister(struct ccw_device *cdev)
                device_del(&cdev->dev);
 }
 
+static void ccw_device_remove_orphan_cb(struct device *dev)
+{
+       struct ccw_device *cdev = to_ccwdev(dev);
+
+       ccw_device_unregister(cdev);
+       put_device(&cdev->dev);
+}
+
+static void ccw_device_remove_sch_cb(struct device *dev)
+{
+       struct subchannel *sch;
+
+       sch = to_subchannel(dev);
+       css_sch_device_unregister(sch);
+       /* Reset intparm to zeroes. */
+       sch->schib.pmcw.intparm = 0;
+       cio_modify(sch);
+       put_device(&sch->dev);
+}
+
 static void
 ccw_device_remove_disconnected(struct ccw_device *cdev)
 {
-       struct subchannel *sch;
        unsigned long flags;
+       int rc;
+
        /*
         * Forced offline in disconnected state means
         * 'throw away device'.
         */
        if (ccw_device_is_orphan(cdev)) {
-               /* Deregister ccw device. */
+               /*
+                * Deregister ccw device.
+                * Unfortunately, we cannot do this directly from the
+                * attribute method.
+                */
                spin_lock_irqsave(cdev->ccwlock, flags);
                cdev->private->state = DEV_STATE_NOT_OPER;
                spin_unlock_irqrestore(cdev->ccwlock, flags);
-               ccw_device_unregister(cdev);
-               put_device(&cdev->dev);
-               return ;
+               rc = device_schedule_callback(&cdev->dev,
+                                             ccw_device_remove_orphan_cb);
+               if (rc)
+                       dev_info(&cdev->dev, "Couldn't unregister orphan\n");
+               return;
        }
-       sch = to_subchannel(cdev->dev.parent);
-       css_sch_device_unregister(sch);
-       /* Reset intparm to zeroes. */
-       sch->schib.pmcw.intparm = 0;
-       cio_modify(sch);
-       put_device(&sch->dev);
+       /* Deregister subchannel, which will kill the ccw device. */
+       rc = device_schedule_callback(cdev->dev.parent,
+                                     ccw_device_remove_sch_cb);
+       if (rc)
+               dev_info(&cdev->dev,
+                        "Couldn't unregister disconnected device\n");
 }
 
 int
index 898ec3b2bebb5092c123030504c69aae89b89886..6bba809295772702bf3637bd6b263cb2a415a22b 100644 (file)
@@ -688,6 +688,12 @@ ccw_device_disband_done(struct ccw_device *cdev, int err)
                ccw_device_done(cdev, DEV_STATE_BOXED);
                break;
        default:
+               cdev->private->flags.donotify = 0;
+               if (get_device(&cdev->dev)) {
+                       PREPARE_WORK(&cdev->private->kick_work,
+                                    ccw_device_call_sch_unregister);
+                       queue_work(ccw_device_work, &cdev->private->kick_work);
+               }
                ccw_device_done(cdev, DEV_STATE_NOT_OPER);
                break;
        }
index ddff40c4212c28068dcb3b58e501ba1398d4e336..821cde65e3694ecc3ab6f68cb30c168c276581cf 100644 (file)
@@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
        int retval = 0;
        unsigned long flags;
 
+       zfcp_adapter_scsi_unregister(adapter);
        device_unregister(&adapter->generic_services);
        zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
        dev_set_drvdata(&adapter->ccw_device->dev, NULL);
index 81680efa172138499311cab2789070a115f0c730..1c8f71a59855b26b2123e611b3ce3978ee6d5dd2 100644 (file)
@@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
  * @ccw_device: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an adapter
- * into state offline. Setting an fcp device offline means that it will be
- * unregistered from the SCSI stack and that the adapter will be shut down
- * asynchronously.
+ * into state offline.
  */
 static int
 zfcp_ccw_set_offline(struct ccw_device *ccw_device)
@@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
        adapter = dev_get_drvdata(&ccw_device->dev);
        zfcp_erp_adapter_shutdown(adapter, 0);
        zfcp_erp_wait(adapter);
-       zfcp_adapter_scsi_unregister(adapter);
        zfcp_erp_thread_kill(adapter);
        zfcp_adapter_debug_unregister(adapter);
        up(&zfcp_data.config_sema);
index a8b02542ac2da30aaaf9a953153d41e419c18da0..0eb31e162b159604b5e6d7cfca9c4e646486b062 100644 (file)
@@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
        kfree(fsf_req);
 }
 
-/**
- * zfcp_fsf_req_dismiss - dismiss a single fsf request
- */
-static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
-                                struct zfcp_fsf_req *fsf_req,
-                                unsigned int counter)
-{
-       u64 dbg_tmp[2];
-
-       dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
-       dbg_tmp[1] = (u64) counter;
-       debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
-       list_del(&fsf_req->list);
-       fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-       zfcp_fsf_req_complete(fsf_req);
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+/*
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
  */
 void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 {
-       struct zfcp_fsf_req *request, *tmp;
+       struct zfcp_fsf_req *fsf_req, *tmp;
        unsigned long flags;
        LIST_HEAD(remove_queue);
-       unsigned int i, counter;
+       unsigned int i;
 
+       BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
        spin_lock_irqsave(&adapter->req_list_lock, flags);
        atomic_set(&adapter->reqs_active, 0);
-       for (i=0; i<REQUEST_LIST_SIZE; i++)
+       for (i = 0; i < REQUEST_LIST_SIZE; i++)
                list_splice_init(&adapter->req_list[i], &remove_queue);
-
        spin_unlock_irqrestore(&adapter->req_list_lock, flags);
 
-       counter = 0;
-       list_for_each_entry_safe(request, tmp, &remove_queue, list) {
-               zfcp_fsf_req_dismiss(adapter, request, counter);
-               counter++;
+       list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+               list_del(&fsf_req->list);
+               fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+               zfcp_fsf_req_complete(fsf_req);
        }
 }
 
index 16e2d64658afea075143230bdcc08d9a492a58a8..0acf6db0a08d7ff3a60d13dc4cccec0e189ae0da 100644 (file)
@@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
        int retval = 0;
        static unsigned int unique_id = 0;
 
+       if (adapter->scsi_host)
+               goto out;
+
        /* register adapter as SCSI host with mid layer of SCSI stack */
        adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
                                             sizeof (struct zfcp_adapter *));
index 262f01e68592f4b359cef0d7c0743673cb237049..44e039865aa99714d4184e033a2d5bce65d94532 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/mm.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index d28c14e23c32a3cf270545258173ae36e358116f..2b2f5c12019b82b94f7115088f8de140d10d271a 100644 (file)
@@ -1532,6 +1532,7 @@ source "drivers/scsi/arm/Kconfig"
 config JAZZ_ESP
        bool "MIPS JAZZ FAS216 SCSI support"
        depends on MACH_JAZZ && SCSI
+       select SCSI_SPI_ATTRS
        help
          This is the driver for the onboard SCSI host adapter of MIPS Magnum
          4000, Acer PICA, Olivetti M700-10 and a few other identical OEM
@@ -1753,23 +1754,10 @@ config SUN3X_ESP
          The ESP was an on-board SCSI controller used on Sun 3/80
          machines.  Say Y here to compile in support for it.
 
-config SCSI_ESP_CORE
-       tristate "ESP Scsi Driver Core"
-       depends on SCSI
-       select SCSI_SPI_ATTRS
-       help
-         This is a core driver for NCR53c9x based scsi chipsets,
-         also known as "ESP" for Emulex Scsi Processor or
-         Enhanced Scsi Processor.  This driver does not exist by
-         itself, there are front-end drivers which, when enabled,
-         select and enable this driver.  One example is SCSI_SUNESP.
-         These front-end drivers provide probing, DMA, and register
-         access support for the core driver.
-
 config SCSI_SUNESP
        tristate "Sparc ESP Scsi Driver"
        depends on SBUS && SCSI
-       select SCSI_ESP_CORE
+       select SCSI_SPI_ATTRS
        help
          This is the driver for the Sun ESP SCSI host adapter. The ESP
          chipset is present in most SPARC SBUS-based computers.
index 51e884fa10b05a0e4e919e6bbc86fa641f455c1b..b1b632791580517d215d3280e2f64b3dd5ed7889 100644 (file)
@@ -106,8 +106,7 @@ obj-$(CONFIG_MEGARAID_LEGACY)       += megaraid.o
 obj-$(CONFIG_MEGARAID_NEWGEN)  += megaraid/
 obj-$(CONFIG_MEGARAID_SAS)     += megaraid/
 obj-$(CONFIG_SCSI_ACARD)       += atp870u.o
-obj-$(CONFIG_SCSI_ESP_CORE)    += esp_scsi.o
-obj-$(CONFIG_SCSI_SUNESP)      += sun_esp.o
+obj-$(CONFIG_SCSI_SUNESP)      += esp_scsi.o   sun_esp.o
 obj-$(CONFIG_SCSI_GDTH)                += gdth.o
 obj-$(CONFIG_SCSI_INITIO)      += initio.o
 obj-$(CONFIG_SCSI_INIA100)     += a100u2w.o
@@ -121,7 +120,7 @@ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
 obj-$(CONFIG_SCSI_3W_9XXX)     += 3w-9xxx.o
 obj-$(CONFIG_SCSI_PPA)         += ppa.o
 obj-$(CONFIG_SCSI_IMM)         += imm.o
-obj-$(CONFIG_JAZZ_ESP)         += NCR53C9x.o   jazz_esp.o
+obj-$(CONFIG_JAZZ_ESP)         += esp_scsi.o   jazz_esp.o
 obj-$(CONFIG_SUN3X_ESP)                += NCR53C9x.o   sun3x_esp.o
 obj-$(CONFIG_SCSI_FCAL)                += fcal.o
 obj-$(CONFIG_SCSI_LASI700)     += 53c700.o lasi700.o
index bb3cb33605417aa3f4b23dd4dc6216b744ebc2ad..88ea5a1fb606d8b8bb7c91c7c9bb2a4721e43bd9 100644 (file)
@@ -2625,7 +2625,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
        NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata * instance->hostdata);
+       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
        int transferred;
        NCR5380_setup(instance);
 
index 1e82c69b36b023b57d1c5ad4911c7349a9d561c4..8dcfe4ec35c224d2b296df65455817d608d3b9e8 100644 (file)
@@ -146,7 +146,7 @@ static char *aac_get_status_string(u32 status);
 static int nondasd = -1;
 static int dacmode = -1;
 
-static int commit = -1;
+int aac_commit = -1;
 int startup_timeout = 180;
 int aif_timeout = 120;
 
@@ -154,7 +154,7 @@ module_param(nondasd, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
 module_param(dacmode, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-module_param(commit, int, S_IRUGO|S_IWUSR);
+module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
 module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
@@ -173,6 +173,9 @@ int expose_physicals = -1;
 module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
 
+int aac_reset_devices = 0;
+module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
 
 static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
                struct fib *fibptr) {
@@ -246,7 +249,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
        aac_fib_complete(fibptr);
        /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
        if (status >= 0) {
-               if ((commit == 1) || commit_flag) {
+               if ((aac_commit == 1) || commit_flag) {
                        struct aac_commit_config * dinfo;
                        aac_fib_init(fibptr);
                        dinfo = (struct aac_commit_config *) fib_data(fibptr);
@@ -261,7 +264,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
                                    1, 1,
                                    NULL, NULL);
                        aac_fib_complete(fibptr);
-               } else if (commit == 0) {
+               } else if (aac_commit == 0) {
                        printk(KERN_WARNING
                          "aac_get_config_status: Foreign device configurations are being ignored\n");
                }
@@ -340,7 +343,7 @@ int aac_get_containers(struct aac_dev *dev)
 static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
 {
        void *buf;
-       unsigned int transfer_len;
+       int transfer_len;
        struct scatterlist *sg = scsicmd->request_buffer;
 
        if (scsicmd->use_sg) {
@@ -351,7 +354,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
                transfer_len = min(scsicmd->request_bufflen, len + offset);
        }
        transfer_len -= offset;
-       if (buf && transfer_len)
+       if (buf && transfer_len > 0)
                memcpy(buf + offset, data, transfer_len);
 
        if (scsicmd->use_sg) 
index 45ca3e801619bea0738cafc482f24a1108cd0e3c..c81edf36913f89025c2f6095589a3040aaffeea9 100644 (file)
@@ -1823,9 +1823,12 @@ int aac_send_shutdown(struct aac_dev *dev);
 int aac_probe_container(struct aac_dev *dev, int cid);
 int _aac_rx_init(struct aac_dev *dev);
 int aac_rx_select_comm(struct aac_dev *dev, int comm);
+int aac_rx_deliver_producer(struct fib * fib);
 extern int numacb;
 extern int acbsize;
 extern char aac_driver_version[];
 extern int startup_timeout;
 extern int aif_timeout;
 extern int expose_physicals;
+extern int aac_reset_devices;
+extern int aac_commit;
index 350ea7feb61d635a50c5cb09d2674a73b1f2bdcf..5c487ff096c7dca723374944c7751ebdf03d7629 100644 (file)
@@ -863,6 +863,14 @@ static struct scsi_host_template aac_driver_template = {
        .emulated                       = 1,
 };
 
+static void __aac_shutdown(struct aac_dev * aac)
+{
+       kthread_stop(aac->thread);
+       aac_send_shutdown(aac);
+       aac_adapter_disable_int(aac);
+       free_irq(aac->pdev->irq, aac);
+}
+
 static int __devinit aac_probe_one(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
@@ -1015,10 +1023,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        return 0;
 
  out_deinit:
-       kthread_stop(aac->thread);
-       aac_send_shutdown(aac);
-       aac_adapter_disable_int(aac);
-       free_irq(pdev->irq, aac);
+       __aac_shutdown(aac);
  out_unmap:
        aac_fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
@@ -1038,7 +1043,8 @@ static void aac_shutdown(struct pci_dev *dev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(dev);
        struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
-       aac_send_shutdown(aac);
+       scsi_block_requests(shost);
+       __aac_shutdown(aac);
 }
 
 static void __devexit aac_remove_one(struct pci_dev *pdev)
@@ -1048,16 +1054,12 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
 
        scsi_remove_host(shost);
 
-       kthread_stop(aac->thread);
-
-       aac_send_shutdown(aac);
-       aac_adapter_disable_int(aac);
+       __aac_shutdown(aac);
        aac_fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
                        aac->comm_phys);
        kfree(aac->queues);
 
-       free_irq(pdev->irq, aac);
        aac_adapter_ioremap(aac, 0);
        
        kfree(aac->fibs);
index 291cd14f4e989737b0f54c289250a6cb006a67e0..ae978a373c5642134f146ccdfeb7046db2167f20 100644 (file)
@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev)
  *
  *     Will send a fib, returning 0 if successful.
  */
-static int aac_rx_deliver_producer(struct fib * fib)
+int aac_rx_deliver_producer(struct fib * fib)
 {
        struct aac_dev *dev = fib->dev;
        struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
@@ -488,6 +488,8 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
                return -EINVAL;
        if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
                return -ENODEV;
+       if (startup_timeout < 300)
+               startup_timeout = 300;
        return 0;
 }
 
@@ -542,7 +544,7 @@ int _aac_rx_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
        dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
        dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
-       if ((((status & 0x0c) != 0x0c) || reset_devices) &&
+       if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
          !aac_rx_restart_adapter(dev, 0))
                ++restart;
        /*
@@ -594,6 +596,8 @@ int _aac_rx_init(struct aac_dev *dev)
                }
                msleep(1);
        }
+       if (restart)
+               aac_commit = 1;
        /*
         *      Fill in the common function dispatch table.
         */
index f4b5e9742ab0de4673c0e94b14b5bc84522bdc83..85b91bc578c9f2a1a131a6208b8b6483e5afe6e7 100644 (file)
@@ -5,7 +5,7 @@
  * based on the old aacraid driver that is..
  * Adaptec aacraid device driver for Linux.
  *
- * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
+ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.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
@@ -257,6 +257,11 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
                        NULL, NULL, NULL, NULL, NULL);
 }
 
+static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
+{
+       return -EINVAL;
+}
+
 /**
  *     aac_sa_check_health
  *     @dev: device to check if healthy
@@ -366,7 +371,9 @@ int aac_sa_init(struct aac_dev *dev)
        dev->a_ops.adapter_notify = aac_sa_notify_adapter;
        dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
        dev->a_ops.adapter_check_health = aac_sa_check_health;
+       dev->a_ops.adapter_restart = aac_sa_restart_adapter;
        dev->a_ops.adapter_intr = aac_sa_intr;
+       dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
        dev->a_ops.adapter_ioremap = aac_sa_ioremap;
 
        /*
index 9ddc6e4a74b040d497620675f0cd5dfcf7256078..05f692bd0adc5543c236079d428bb0e48a503772 100644 (file)
@@ -5180,7 +5180,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                        cur_lun = lun;
                        max_lun = lun;
                }
-               for (cur_lun <= max_lun; cur_lun++) {
+               for (;cur_lun <= max_lun; cur_lun++) {
                        struct ahd_tmode_lstate* lstate;
 
                        lstate = tstate->enabled_luns[cur_lun];
index c328596def3c557f25c4b6bc88ec3bba94bfa3d8..6066998ed5624388ccb2f5802094a0cb848a9c5f 100644 (file)
@@ -106,6 +106,7 @@ static void make_expression(expression_t *immed, int value);
 static void add_conditional(symbol_t *symbol);
 static void add_version(const char *verstring);
 static int  is_download_const(expression_t *immed);
+void yyerror(const char *string);
 
 #define SRAM_SYMNAME "SRAM_BASE"
 #define SCB_SYMNAME "SCB_BASE"
index 439f760b34b5423784f1c38858d85122aea11892..ff46aa6801bfc6cbd2558c3e3fe26df5c2b84c43 100644 (file)
@@ -65,6 +65,7 @@
 static symbol_t *macro_symbol;
 
 static void add_macro_arg(const char *argtext, int position);
+void mmerror(const char *string);
 
 %}
 
index 9a14a6d9727548039051e3999f0a8817e076cfce..c0d0b7d7a8ce0d34b33dc7b4a8ea3990e6212155 100644 (file)
@@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
 static inline int asd_clear_nexus(struct sas_task *task)
 {
        int res = TMF_RESP_FUNC_FAILED;
+       int leftover;
        struct asd_ascb *tascb = task->lldd_task;
        unsigned long flags;
 
@@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task)
                res = asd_clear_nexus_tag(task);
        else
                res = asd_clear_nexus_index(task);
-       wait_for_completion_timeout(&tascb->completion,
-                                   AIC94XX_SCB_TIMEOUT);
+       leftover = wait_for_completion_timeout(&tascb->completion,
+                                              AIC94XX_SCB_TIMEOUT);
        ASD_DPRINTK("came back from clear nexus\n");
        spin_lock_irqsave(&task->task_state_lock, flags);
+       if (leftover < 1)
+               res = TMF_RESP_FUNC_FAILED;
        if (task->task_state_flags & SAS_TASK_STATE_DONE)
                res = TMF_RESP_FUNC_COMPLETE;
        spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task)
        unsigned long flags;
        struct asd_ascb *ascb = NULL;
        struct scb *scb;
+       int leftover;
 
        spin_lock_irqsave(&task->task_state_lock, flags);
        if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task)
                break;
        case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
                res = TMF_RESP_FUNC_FAILED;
-               wait_for_completion_timeout(&tascb->completion,
-                                           AIC94XX_SCB_TIMEOUT);
+               leftover = wait_for_completion_timeout(&tascb->completion,
+                                                      AIC94XX_SCB_TIMEOUT);
                spin_lock_irqsave(&task->task_state_lock, flags);
+               if (leftover < 1)
+                       res = TMF_RESP_FUNC_FAILED;
                if (task->task_state_flags & SAS_TASK_STATE_DONE)
                        res = TMF_RESP_FUNC_COMPLETE;
                spin_unlock_irqrestore(&task->task_state_lock, flags);
index eff846ae0aff62ffd15394f0b35de6ba8cad8728..03dbe60c264aa5c4490654a9c528f59766b5faab 100644 (file)
@@ -893,45 +893,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
        return 0;
 }
 
-/*
- * our own old-style timeout update
- */
-/*
- * The strategy is to cause the timer code to call scsi_times_out()
- * when the soonest timeout is pending.
- * The arguments are used when we are queueing a new command, because
- * we do not want to subtract the time used from this time, but when we
- * set the timer, we want to take this value into account.
- */
-
-int atari_scsi_update_timeout(Scsi_Cmnd * SCset, int timeout)
-{
-       int rtn;
-
-       /*
-        * We are using the new error handling code to actually register/deregister
-        * timers for timeout.
-        */
-
-       if (!timer_pending(&SCset->eh_timeout))
-               rtn = 0;
-       else
-               rtn = SCset->eh_timeout.expires - jiffies;
-
-       if (timeout == 0) {
-               del_timer(&SCset->eh_timeout);
-               SCset->eh_timeout.data = (unsigned long)NULL;
-               SCset->eh_timeout.expires = 0;
-       } else {
-               if (SCset->eh_timeout.data != (unsigned long)NULL)
-                       del_timer(&SCset->eh_timeout);
-               SCset->eh_timeout.data = (unsigned long)SCset;
-               SCset->eh_timeout.expires = jiffies + timeout;
-               add_timer(&SCset->eh_timeout);
-       }
-       return rtn;
-}
-
 /*
  * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd,
  *     void (*done)(Scsi_Cmnd *))
@@ -956,7 +917,6 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
        Scsi_Cmnd *tmp;
        int oldto;
        unsigned long flags;
-       // extern int update_timeout(Scsi_Cmnd * SCset, int timeout);
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
        switch (cmd->cmnd[0]) {
@@ -1029,9 +989,9 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
         * alter queues and touch the lock.
         */
        if (!IS_A_TT()) {
-               oldto = atari_scsi_update_timeout(cmd, 0);
+               /* perhaps stop command timer here */
                falcon_get_lock();
-               atari_scsi_update_timeout(cmd, oldto);
+               /* perhaps restart command timer here */
        }
        if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
                LIST(cmd, hostdata->issue_queue);
index 4baa79e686794ba5915717c2998860b6031fd91b..fa6ff295e5683b544ceea30250de287fbdb362d6 100644 (file)
@@ -3954,6 +3954,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
                spin_unlock_irq(scsi_cmd->device->host->host_lock);
                ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
                spin_lock_irq(scsi_cmd->device->host->host_lock);
+
+               list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+                       if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+                               rc = -EIO;
+                               break;
+                       }
+               }
        } else
                rc = ipr_device_reset(ioa_cfg, res);
        res->resetting_device = 0;
index 19dd4b962e18c140d78511b0b516a07db696b1b7..81e497d9eae022e496cdab7a6582291e750cc96d 100644 (file)
-/*
- * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
+/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
  *
- * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
- *
- * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
+ * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/delay.h>
 #include <linux/types.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/blkdev.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "NCR53C9x.h"
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
-#include <asm/dma.h>
 
-#include <asm/pgtable.h>
-
-static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
-static int  dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_dump_state(struct NCR_ESP *esp);
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_ints_off(struct NCR_ESP *esp);
-static void dma_ints_on(struct NCR_ESP *esp);
-static int  dma_irq_p(struct NCR_ESP *esp);
-static int  dma_ports_p(struct NCR_ESP *esp);
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_advance_sg (struct scsi_cmnd *sp);
-static void dma_led_off(struct NCR_ESP *);
-static void dma_led_on(struct NCR_ESP *);
-
-
-static volatile unsigned char cmd_buffer[16];
-                               /* This is where all commands are put
-                                * before they are trasfered to the ESP chip
-                                * via PIO.
-                                */
-
-static int jazz_esp_release(struct Scsi_Host *shost)
-{
-       if (shost->irq)
-               free_irq(shost->irq, NULL);
-       if (shost->dma_channel != 0xff)
-               free_dma(shost->dma_channel);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
-       scsi_unregister(shost);
-       return 0;
-}
+#include <scsi/scsi_host.h>
 
-/***************************************************************** Detection */
-static int jazz_esp_detect(struct scsi_host_template *tpnt)
-{
-    struct NCR_ESP *esp;
-    struct ConfigDev *esp_dev;
-
-    /*
-     * first assumption it is there:-)
-     */
-    if (1) {
-       esp_dev = NULL;
-       esp = esp_allocate(tpnt, esp_dev, 0);
-       
-       /* Do command transfer with programmed I/O */
-       esp->do_pio_cmds = 1;
-       
-       /* Required functions */
-       esp->dma_bytes_sent = &dma_bytes_sent;
-       esp->dma_can_transfer = &dma_can_transfer;
-       esp->dma_dump_state = &dma_dump_state;
-       esp->dma_init_read = &dma_init_read;
-       esp->dma_init_write = &dma_init_write;
-       esp->dma_ints_off = &dma_ints_off;
-       esp->dma_ints_on = &dma_ints_on;
-       esp->dma_irq_p = &dma_irq_p;
-       esp->dma_ports_p = &dma_ports_p;
-       esp->dma_setup = &dma_setup;
-
-       /* Optional functions */
-       esp->dma_barrier = NULL;
-       esp->dma_drain = NULL;
-       esp->dma_invalidate = NULL;
-       esp->dma_irq_entry = NULL;
-       esp->dma_irq_exit = NULL;
-       esp->dma_poll = NULL;
-       esp->dma_reset = NULL;
-       esp->dma_led_off = &dma_led_off;
-       esp->dma_led_on = &dma_led_on;
-       
-       /* virtual DMA functions */
-       esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
-       esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
-       esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
-       esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
-       esp->dma_advance_sg = &dma_advance_sg;
-
-
-       /* SCSI chip speed */
-       esp->cfreq = 40000000;
+#include "esp_scsi.h"
 
-       /* 
-        * we don't give the address of DMA channel, but the number
-        * of DMA channel, so we can use the jazz DMA functions
-        * 
-        */
-       esp->dregs = (void *) JAZZ_SCSI_DMA;
-       
-       /* ESP register base */
-       esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
-       
-       /* Set the command buffer */
-       esp->esp_command = (volatile unsigned char *)cmd_buffer;
-       
-       /* get virtual dma address for command buffer */
-       esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
-       
-       esp->irq = JAZZ_SCSI_IRQ;
-       request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI",
-                   esp->ehost);
-
-       /*
-        * FIXME, look if the scsi id is available from NVRAM
-        */
-       esp->scsi_id = 7;
-               
-       /* Check for differential SCSI-bus */
-       /* What is this stuff? */
-       esp->diff = 0;
-
-       esp_initialize(esp);
-       
-       printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
-       esps_running = esps_in_use;
-       return esps_in_use;
-    }
-    return 0;
-}
+#define DRV_MODULE_NAME                "jazz_esp"
+#define PFX DRV_MODULE_NAME    ": "
+#define DRV_VERSION            "1.000"
+#define DRV_MODULE_RELDATE     "May 19, 2007"
 
-/************************************************************* DMA Functions */
-static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
+static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
 {
-    return fifo_count;
+       *(volatile u8 *)(esp->regs + reg) = val;
 }
 
-static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
 {
-    /*
-     * maximum DMA size is 1MB
-     */
-    unsigned long sz = sp->SCp.this_residual;
-    if(sz > 0x100000)
-       sz = 0x100000;
-    return sz;
+       return *(volatile u8 *)(esp->regs + reg);
 }
 
-static void dma_dump_state(struct NCR_ESP *esp)
+static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
+                                     size_t sz, int dir)
 {
-    
-    ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
-           esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
+       return dma_map_single(esp->dev, buf, sz, dir);
 }
 
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
+static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
+                                 int num_sg, int dir)
 {
-    dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
-    vdma_disable ((int)esp->dregs);
-    vdma_set_mode ((int)esp->dregs, DMA_MODE_READ);
-    vdma_set_addr ((int)esp->dregs, vaddress);
-    vdma_set_count ((int)esp->dregs, length);
-    vdma_enable ((int)esp->dregs);
+       return dma_map_sg(esp->dev, sg, num_sg, dir);
 }
 
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
+                                 size_t sz, int dir)
 {
-    dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);    
-    vdma_disable ((int)esp->dregs);    
-    vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE);
-    vdma_set_addr ((int)esp->dregs, vaddress);
-    vdma_set_count ((int)esp->dregs, length);
-    vdma_enable ((int)esp->dregs);    
+       dma_unmap_single(esp->dev, addr, sz, dir);
 }
 
-static void dma_ints_off(struct NCR_ESP *esp)
+static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
+                             int num_sg, int dir)
 {
-    disable_irq(esp->irq);
+       dma_unmap_sg(esp->dev, sg, num_sg, dir);
 }
 
-static void dma_ints_on(struct NCR_ESP *esp)
+static int jazz_esp_irq_pending(struct esp *esp)
 {
-    enable_irq(esp->irq);
+       if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
+               return 1;
+       return 0;
 }
 
-static int dma_irq_p(struct NCR_ESP *esp)
+static void jazz_esp_reset_dma(struct esp *esp)
 {
-    return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR);
+       vdma_disable ((int)esp->dma_regs);
 }
 
-static int dma_ports_p(struct NCR_ESP *esp)
+static void jazz_esp_dma_drain(struct esp *esp)
 {
-    int enable = vdma_get_enable((int)esp->dregs);
-    
-    return (enable & R4030_CHNL_ENABLE);
+       /* nothing to do */
 }
 
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
+static void jazz_esp_dma_invalidate(struct esp *esp)
 {
-    /* 
-     * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
-     * so when (write) is true, it actually means READ!
-     */
-    if(write){
-       dma_init_read(esp, addr, count);
-    } else {
-       dma_init_write(esp, addr, count);
-    }
+       vdma_disable ((int)esp->dma_regs);
 }
 
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
+                                 u32 dma_count, int write, u8 cmd)
 {
-    sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
-    sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
+       BUG_ON(!(cmd & ESP_CMD_DMA));
+
+       jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+       jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+       vdma_disable ((int)esp->dma_regs);
+       if (write)
+               vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
+       else
+               vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);
+
+       vdma_set_addr ((int)esp->dma_regs, addr);
+       vdma_set_count ((int)esp->dma_regs, dma_count);
+       vdma_enable ((int)esp->dma_regs);
+
+       scsi_esp_cmd(esp, cmd);
 }
 
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    int sz = sp->SCp.buffers_residual;
-    struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
-    
-    while (sz >= 0) {
-       sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
-       sz--;
-    }
-    sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
-}    
-
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static int jazz_esp_dma_error(struct esp *esp)
 {
-    vdma_free(sp->SCp.have_data_in);
+       u32 enable = vdma_get_enable((int)esp->dma_regs);
+
+       if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
+               return 1;
+
+       return 0;
 }
 
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static const struct esp_driver_ops jazz_esp_ops = {
+       .esp_write8     =       jazz_esp_write8,
+       .esp_read8      =       jazz_esp_read8,
+       .map_single     =       jazz_esp_map_single,
+       .map_sg         =       jazz_esp_map_sg,
+       .unmap_single   =       jazz_esp_unmap_single,
+       .unmap_sg       =       jazz_esp_unmap_sg,
+       .irq_pending    =       jazz_esp_irq_pending,
+       .reset_dma      =       jazz_esp_reset_dma,
+       .dma_drain      =       jazz_esp_dma_drain,
+       .dma_invalidate =       jazz_esp_dma_invalidate,
+       .send_dma_cmd   =       jazz_esp_send_dma_cmd,
+       .dma_error      =       jazz_esp_dma_error,
+};
+
+static int __devinit esp_jazz_probe(struct platform_device *dev)
 {
-    int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
-                       
-    while(sz >= 0) {
-       vdma_free(sg[sz].dma_address);
-       sz--;
-    }
+       struct scsi_host_template *tpnt = &scsi_esp_template;
+       struct Scsi_Host *host;
+       struct esp *esp;
+       struct resource *res;
+       int err;
+
+       host = scsi_host_alloc(tpnt, sizeof(struct esp));
+
+       err = -ENOMEM;
+       if (!host)
+               goto fail;
+
+       host->max_id = 8;
+       esp = host_to_esp(host);
+
+       esp->host = host;
+       esp->dev = dev;
+       esp->ops = &jazz_esp_ops;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!res)
+               goto fail_unlink;
+
+       esp->regs = (void __iomem *)res->start;
+       if (!esp->regs)
+               goto fail_unlink;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       if (!res)
+               goto fail_unlink;
+
+       esp->dma_regs = (void __iomem *)res->start;
+
+       esp->command_block = dma_alloc_coherent(esp->dev, 16,
+                                               &esp->command_block_dma,
+                                               GFP_KERNEL);
+       if (!esp->command_block)
+               goto fail_unmap_regs;
+
+       host->irq = platform_get_irq(dev, 0);
+       err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
+       if (err < 0)
+               goto fail_unmap_command_block;
+
+       esp->scsi_id = 7;
+       esp->host->this_id = esp->scsi_id;
+       esp->scsi_id_mask = (1 << esp->scsi_id);
+       esp->cfreq = 40000000;
+
+       dev_set_drvdata(&dev->dev, esp);
+
+       err = scsi_esp_register(esp, &dev->dev);
+       if (err)
+               goto fail_free_irq;
+
+       return 0;
+
+fail_free_irq:
+       free_irq(host->irq, esp);
+fail_unmap_command_block:
+       dma_free_coherent(esp->dev, 16,
+                         esp->command_block,
+                         esp->command_block_dma);
+fail_unmap_regs:
+fail_unlink:
+       scsi_host_put(host);
+fail:
+       return err;
 }
 
-static void dma_advance_sg (struct scsi_cmnd *sp)
+static int __devexit esp_jazz_remove(struct platform_device *dev)
 {
-    sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
+       struct esp *esp = dev_get_drvdata(&dev->dev);
+       unsigned int irq = esp->host->irq;
+
+       scsi_esp_unregister(esp);
+
+       free_irq(irq, esp);
+       dma_free_coherent(esp->dev, 16,
+                         esp->command_block,
+                         esp->command_block_dma);
+
+       scsi_host_put(esp->host);
+
+       return 0;
 }
 
-#define JAZZ_HDC_LED   0xe000d100 /* FIXME, find correct address */
+static struct platform_driver esp_jazz_driver = {
+       .probe          = esp_jazz_probe,
+       .remove         = __devexit_p(esp_jazz_remove),
+       .driver = {
+               .name   = "jazz_esp",
+       },
+};
 
-static void dma_led_off(struct NCR_ESP *esp)
+static int __init jazz_esp_init(void)
 {
-#if 0    
-    *(unsigned char *)JAZZ_HDC_LED = 0;
-#endif    
+       return platform_driver_register(&esp_jazz_driver);
 }
 
-static void dma_led_on(struct NCR_ESP *esp)
-{    
-#if 0    
-    *(unsigned char *)JAZZ_HDC_LED = 1;
-#endif    
+static void __exit jazz_esp_exit(void)
+{
+       platform_driver_unregister(&esp_jazz_driver);
 }
 
-static struct scsi_host_template driver_template = {
-       .proc_name              = "jazz_esp",
-       .proc_info              = esp_proc_info,
-       .name                   = "ESP 100/100a/200",
-       .detect                 = jazz_esp_detect,
-       .slave_alloc            = esp_slave_alloc,
-       .slave_destroy          = esp_slave_destroy,
-       .release                = jazz_esp_release,
-       .info                   = esp_info,
-       .queuecommand           = esp_queue,
-       .eh_abort_handler       = esp_abort,
-       .eh_bus_reset_handler   = esp_reset,
-       .can_queue              = 7,
-       .this_id                = 7,
-       .sg_tablesize           = SG_ALL,
-       .cmd_per_lun            = 1,
-       .use_clustering         = DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
+MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
+MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(jazz_esp_init);
+module_exit(jazz_esp_exit);
index 5631c199a8ebd0bafaa03a814e3c9ce817224cdc..732446e63963557dab5136c10c361acbc1a18a9a 100644 (file)
@@ -254,6 +254,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
 
                sg_init_one(&dummy, md, id->table_desc.len);
                sg_dma_address(&dummy) = token;
+               sg_dma_len(&dummy) = id->table_desc.len;
                err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
                              id->table_desc.len);
                if (err) {
index 7a812677ff8a4de0f2e3dbb8c8a9e00a2d9af409..e2cf12ef3688d326d6959bc64d2d9a3dd19bbf20 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.10-rc1
+ * Version     : v00.00.03.10-rc5
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
@@ -886,6 +886,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
                goto out_return_cmd;
 
        cmd->scmd = scmd;
+       scmd->SCp.ptr = (char *)cmd;
 
        /*
         * Issue the command to the FW
@@ -919,7 +920,7 @@ static int megasas_slave_configure(struct scsi_device *sdev)
         * The RAID firmware may require extended timeouts.
         */
        if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-               sdev->timeout = 90 * HZ;
+               sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
        return 0;
 }
 
@@ -981,8 +982,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
 
        instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-       scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n",
-              scmd->serial_number, scmd->cmnd[0]);
+       scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
+                scmd->serial_number, scmd->cmnd[0], scmd->retries);
 
        if (instance->hw_crit_error) {
                printk(KERN_ERR "megasas: cannot recover from previous reset "
@@ -999,6 +1000,39 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
        return ret_val;
 }
 
+/**
+ * megasas_reset_timer - quiesce the adapter if required
+ * @scmd:              scsi cmnd
+ *
+ * Sets the FW busy flag and reduces the host->can_queue if the
+ * cmd has not been completed within the timeout period.
+ */
+static enum
+scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+{
+       struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
+       struct megasas_instance *instance;
+       unsigned long flags;
+
+       if (time_after(jiffies, scmd->jiffies_at_alloc +
+                               (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
+               return EH_NOT_HANDLED;
+       }
+
+       instance = cmd->instance;
+       if (!(instance->flag & MEGASAS_FW_BUSY)) {
+               /* FW is busy, throttle IO */
+               spin_lock_irqsave(instance->host->host_lock, flags);
+
+               instance->host->can_queue = 16;
+               instance->last_time = jiffies;
+               instance->flag |= MEGASAS_FW_BUSY;
+
+               spin_unlock_irqrestore(instance->host->host_lock, flags);
+       }
+       return EH_RESET_TIMER;
+}
+
 /**
  * megasas_reset_device -      Device reset handler entry point
  */
@@ -1112,6 +1146,7 @@ static struct scsi_host_template megasas_template = {
        .eh_device_reset_handler = megasas_reset_device,
        .eh_bus_reset_handler = megasas_reset_bus_host,
        .eh_host_reset_handler = megasas_reset_bus_host,
+       .eh_timed_out = megasas_reset_timer,
        .bios_param = megasas_bios_param,
        .use_clustering = ENABLE_CLUSTERING,
 };
@@ -1215,9 +1250,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
        int exception = 0;
        struct megasas_header *hdr = &cmd->frame->hdr;
 
-       if (cmd->scmd) {
-               cmd->scmd->SCp.ptr = (char *)0;
-       }
+       if (cmd->scmd)
+               cmd->scmd->SCp.ptr = NULL;
 
        switch (hdr->cmd) {
 
@@ -1806,6 +1840,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
        u32 context;
        struct megasas_cmd *cmd;
        struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+       unsigned long flags;
 
        /* If we have already declared adapter dead, donot complete cmds */
        if (instance->hw_crit_error)
@@ -1828,6 +1863,22 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
        }
 
        *instance->consumer = producer;
+
+       /*
+        * Check if we can restore can_queue
+        */
+       if (instance->flag & MEGASAS_FW_BUSY
+               && time_after(jiffies, instance->last_time + 5 * HZ)
+               && atomic_read(&instance->fw_outstanding) < 17) {
+
+               spin_lock_irqsave(instance->host->host_lock, flags);
+               instance->flag &= ~MEGASAS_FW_BUSY;
+               instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+               spin_unlock_irqrestore(instance->host->host_lock, flags);
+       }
+
 }
 
 /**
@@ -2398,6 +2449,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
        megasas_dbg_lvl = 0;
+       instance->flag = 0;
+       instance->last_time = 0;
 
        /*
         * Initialize MFI Firmware
index e862992ee37783c8d09b615cd5c95be4363fe68d..4dffc918a414c3bf5c4254f0ceea06998127cc15 100644 (file)
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.03.10-rc1"
-#define MEGASAS_RELDATE                                "Feb 14, 2007"
-#define MEGASAS_EXT_VERSION                    "Wed Feb 14 10:14:25 PST 2007"
+#define MEGASAS_VERSION                                "00.00.03.10-rc5"
+#define MEGASAS_RELDATE                                "May 17, 2007"
+#define MEGASAS_EXT_VERSION                    "Thu May 17 10:09:32 PDT 2007"
 
 /*
  * Device IDs
@@ -539,6 +539,8 @@ struct megasas_ctrl_info {
 
 #define MEGASAS_DBG_LVL                                1
 
+#define MEGASAS_FW_BUSY                                1
+
 /*
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -549,8 +551,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_RESET_WAIT_TIME                        180
 #define MEGASAS_INTERNAL_CMD_WAIT_TIME         180
 #define        MEGASAS_RESET_NOTICE_INTERVAL           5
-
 #define MEGASAS_IOCTL_CMD                      0
+#define MEGASAS_DEFAULT_CMD_TIMEOUT            90
 
 /*
  * FW reports the maximum of number of commands that it can accept (maximum
@@ -1073,7 +1075,6 @@ struct megasas_instance {
        struct megasas_register_set __iomem *reg_set;
 
        s8 init_id;
-       u8 reserved[3];
 
        u16 max_num_sge;
        u16 max_fw_cmds;
@@ -1104,6 +1105,9 @@ struct megasas_instance {
 
        struct megasas_instance_template *instancet;
        struct tasklet_struct isr_tasklet;
+
+       u8 flag;
+       unsigned long last_time;
 };
 
 #define MEGASAS_IS_LOGICAL(scp)                                                \
index 3b2e1a53e6e2df3e63dbf153e42ae516e33be652..d953d43fe2e6146e62ab43ee392d3a3c0df0c2af 100644 (file)
@@ -4,6 +4,7 @@
  *
  */
 
+#include <linux/completion.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -50,16 +51,10 @@ static struct ctrl_inquiry {
 } *fcs __initdata;
 static int fcscount __initdata = 0;
 static atomic_t fcss __initdata = ATOMIC_INIT(0);
-DECLARE_MUTEX_LOCKED(fc_sem);
+static DECLARE_COMPLETION(fc_detect_complete);
 
 static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
 
-static void __init pluto_detect_timeout(unsigned long data)
-{
-       PLND(("Timeout\n"))
-       up(&fc_sem);
-}
-
 static void __init pluto_detect_done(Scsi_Cmnd *SCpnt)
 {
        /* Do nothing */
@@ -69,7 +64,7 @@ static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt)
 {
        PLND(("Detect done %08lx\n", (long)SCpnt))
        if (atomic_dec_and_test (&fcss))
-               up(&fc_sem);
+               complete(&fc_detect_complete);
 }
 
 int pluto_slave_configure(struct scsi_device *device)
@@ -96,7 +91,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
        int i, retry, nplutos;
        fc_channel *fc;
        struct scsi_device dev;
-       DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
 
        tpnt->proc_name = "pluto";
        fcscount = 0;
@@ -187,15 +181,11 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
                        }
                }
            
-               fc_timer.expires = jiffies + 10 * HZ;
-               add_timer(&fc_timer);
-               
-               down(&fc_sem);
+               wait_for_completion_timeout(&fc_detect_complete, 10 * HZ);
                PLND(("Woken up\n"))
                if (!atomic_read(&fcss))
                        break; /* All fc channels have answered us */
        }
-       del_timer_sync(&fc_timer);
 
        PLND(("Finished search\n"))
        for (i = 0, nplutos = 0; i < fcscount; i++) {
index dd076da86a465d668d6b251512492176a65e81be..b98136adaaaebe4784040a05eebcdbd92a490b63 100644 (file)
@@ -2590,7 +2590,7 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
                        return 0;
                if (msleep_interruptible(step))
                        break;
-       } while (--iterations >= 0);
+       } while (--iterations > 0);
 
        return -ETIMEDOUT;
 }
index ce63044b1ec8a630711120ea287d73617a922b61..18dd5cc4d7c6f5e32bb28b24a1b249b28661babf 100644 (file)
@@ -209,6 +209,7 @@ static struct {
        {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+       {"Promise", "", NULL, BLIST_SPARSELUN},
        {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
        {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
        {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ},    /* Chokes on tagged INQUIRY */
index a67f315244d7c17de1d3acd2697c2b78463e07ea..662577fbe7a87ddd93a66e37e66bbedbeb64e73d 100644 (file)
@@ -184,6 +184,15 @@ int scsi_complete_async_scans(void)
 /* Only exported for the benefit of scsi_wait_scan */
 EXPORT_SYMBOL_GPL(scsi_complete_async_scans);
 
+#ifndef MODULE
+/*
+ * For async scanning we need to wait for all the scans to complete before
+ * trying to mount the root fs.  Otherwise non-modular drivers may not be ready
+ * yet.
+ */
+late_initcall(scsi_complete_async_scans);
+#endif
+
 /**
  * scsi_unlock_floptical - unlock device via a special MODE SENSE command
  * @sdev:      scsi device to send command to
index 00e46662296f89ebdfe1def87804f10fcd5e390c..3d8c9cb24f9187d6f0e4f487c4eae7878036b332 100644 (file)
@@ -1789,7 +1789,7 @@ static void sd_shutdown(struct device *dev)
 static int sd_suspend(struct device *dev, pm_message_t mesg)
 {
        struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
-       int ret;
+       int ret = 0;
 
        if (!sdkp)
                return 0;       /* this can happen */
@@ -1798,30 +1798,34 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
                sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
                ret = sd_sync_cache(sdkp);
                if (ret)
-                       return ret;
+                       goto done;
        }
 
        if (mesg.event == PM_EVENT_SUSPEND &&
            sdkp->device->manage_start_stop) {
                sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
                ret = sd_start_stop_device(sdkp, 0);
-               if (ret)
-                       return ret;
        }
 
-       return 0;
+done:
+       scsi_disk_put(sdkp);
+       return ret;
 }
 
 static int sd_resume(struct device *dev)
 {
        struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+       int ret = 0;
 
        if (!sdkp->device->manage_start_stop)
-               return 0;
+               goto done;
 
        sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+       ret = sd_start_stop_device(sdkp, 1);
 
-       return sd_start_stop_device(sdkp, 1);
+done:
+       scsi_disk_put(sdkp);
+       return ret;
 }
 
 /**
index 69be1324b114ffc274cadd4e805b8e89c4ea1bd3..9ac83abc4028c2ec33cd80941e0bda1050003d0c 100644 (file)
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
 
 #define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "3.1.0.1"
+#define ST_DRIVER_VERSION "3.6.0000.1"
 #define ST_VER_MAJOR           3
-#define ST_VER_MINOR           1
+#define ST_VER_MINOR           6
 #define ST_OEM                         0
 #define ST_BUILD_VER           1
 
@@ -113,10 +114,6 @@ enum {
        SG_CF_64B                               = 0x40, /* 64 bit item */
        SG_CF_HOST                              = 0x20, /* sg in host memory */
 
-       ST_MAX_ARRAY_SUPPORTED                  = 16,
-       ST_MAX_TARGET_NUM                       = (ST_MAX_ARRAY_SUPPORTED+1),
-       ST_MAX_LUN_PER_TARGET                   = 16,
-
        st_shasta                               = 0,
        st_vsc                                  = 1,
        st_vsc1                                 = 2,
@@ -586,7 +583,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
        u16 tag;
        host = cmd->device->host;
        id = cmd->device->id;
-       lun = cmd->device->channel; /* firmware lun issue work around */
+       lun = cmd->device->lun;
        hba = (struct st_hba *) &host->hostdata[0];
 
        switch (cmd->cmnd[0]) {
@@ -605,8 +602,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
                        stex_invalid_field(cmd, done);
                return 0;
        }
+       case REPORT_LUNS:
+               /*
+                * The shasta firmware does not report actual luns in the
+                * target, so fail the command to force sequential lun scan.
+                * Also, the console device does not support this command.
+                */
+               if (hba->cardtype == st_shasta || id == host->max_id - 1) {
+                       stex_invalid_field(cmd, done);
+                       return 0;
+               }
+               break;
+       case TEST_UNIT_READY:
+               if (id == host->max_id - 1) {
+                       cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+                       done(cmd);
+                       return 0;
+               }
+               break;
        case INQUIRY:
-               if (id != ST_MAX_ARRAY_SUPPORTED)
+               if (id != host->max_id - 1)
                        break;
                if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
                        stex_direct_copy(cmd, console_inq_page,
@@ -624,7 +639,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
                        ver.oem = ST_OEM;
                        ver.build = ST_BUILD_VER;
                        ver.signature[0] = PASSTHRU_SIGNATURE;
-                       ver.console_id = ST_MAX_ARRAY_SUPPORTED;
+                       ver.console_id = host->max_id - 1;
                        ver.host_no = hba->host->host_no;
                        cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
                                DID_OK << 16 | COMMAND_COMPLETE << 8 :
@@ -645,13 +660,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 
        req = stex_alloc_req(hba);
 
-       if (hba->cardtype == st_yosemite) {
-               req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
-               req->target = 0;
-       } else {
-               req->lun = lun;
-               req->target = id;
-       }
+       req->lun = lun;
+       req->target = id;
 
        /* cdb */
        memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -767,18 +777,6 @@ static void stex_ys_commands(struct st_hba *hba,
                        ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
                else
                        ccb->srb_status = SRB_STATUS_SUCCESS;
-       } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
-               u8 *report_lun_data = (u8 *)hba->copy_buffer;
-
-               count = STEX_EXTRA_SIZE;
-               stex_internal_copy(ccb->cmd, report_lun_data,
-                       &count, ccb->sg_count, ST_FROM_CMD);
-               if (report_lun_data[2] || report_lun_data[3]) {
-                       report_lun_data[2] = 0x00;
-                       report_lun_data[3] = 0x08;
-                       stex_internal_copy(ccb->cmd, report_lun_data,
-                               &count, ccb->sg_count, ST_TO_CMD);
-               }
        }
 }
 
@@ -995,6 +993,11 @@ static int stex_abort(struct scsi_cmnd *cmd)
        u32 data;
        int result = SUCCESS;
        unsigned long flags;
+
+       printk(KERN_INFO DRV_NAME
+               "(%s): aborting command\n", pci_name(hba->pdev));
+       scsi_print_command(cmd);
+
        base = hba->mmio_base;
        spin_lock_irqsave(host->host_lock, flags);
        if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
@@ -1051,7 +1054,12 @@ static void stex_hard_reset(struct st_hba *hba)
        pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
        pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
-       msleep(1);
+
+       /*
+        * 1 ms may be enough for 8-port controllers. But 16-port controllers
+        * require more time to finish bus reset. Use 100 ms here for safety
+        */
+       msleep(100);
        pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
 
@@ -1075,6 +1083,10 @@ static int stex_reset(struct scsi_cmnd *cmd)
        unsigned long before;
        hba = (struct st_hba *) &cmd->device->host->hostdata[0];
 
+       printk(KERN_INFO DRV_NAME
+               "(%s): resetting host\n", pci_name(hba->pdev));
+       scsi_print_command(cmd);
+
        hba->mu_status = MU_STATE_RESETTING;
 
        if (hba->cardtype == st_shasta)
@@ -1194,7 +1206,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto out_scsi_host_put;
        }
 
-       hba->mmio_base = ioremap(pci_resource_start(pdev, 0),
+       hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
                pci_resource_len(pdev, 0));
        if ( !hba->mmio_base) {
                printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
@@ -1229,12 +1241,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
        hba->mu_status = MU_STATE_STARTING;
 
-       /* firmware uses id/lun pair for a logical drive, but lun would be
-          always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
-          channel to map lun here */
-       host->max_channel = ST_MAX_LUN_PER_TARGET - 1;
-       host->max_id = ST_MAX_TARGET_NUM;
-       host->max_lun = 1;
+       if (hba->cardtype == st_shasta) {
+               host->max_lun = 8;
+               host->max_id = 16 + 1;
+       } else if (hba->cardtype == st_yosemite) {
+               host->max_lun = 128;
+               host->max_id = 1 + 1;
+       } else {
+               /* st_vsc and st_vsc1 */
+               host->max_lun = 1;
+               host->max_id = 128 + 1;
+       }
+       host->max_channel = 0;
        host->unique_id = host->host_no;
        host->max_cmd_len = STEX_CDB_LENGTH;
 
index 1a9a24b82636e42704ae910f97e46d212800ebd4..e88da72f8304e9a6abc00daa73590e409e76e88b 100644 (file)
@@ -167,8 +167,9 @@ static void pl010_rx_chars(struct uart_amba_port *uap)
        ignore_char:
                status = readb(uap->port.membase + UART01x_FR);
        }
+       spin_unlock(&uap->port.lock);
        tty_flip_buffer_push(tty);
-       return;
+       spin_lock(&uap->port.lock);
 }
 
 static void pl010_tx_chars(struct uart_amba_port *uap)
index 44639e71372a7eb08c209562e95374fe5d0fb22e..954073c6ce3a4e5cccb7df1806575fc1778cbc2c 100644 (file)
@@ -153,8 +153,9 @@ static void pl011_rx_chars(struct uart_amba_port *uap)
        ignore_char:
                status = readw(uap->port.membase + UART01x_FR);
        }
+       spin_unlock(&uap->port.lock);
        tty_flip_buffer_push(tty);
-       return;
+       spin_lock(&uap->port.lock);
 }
 
 static void pl011_tx_chars(struct uart_amba_port *uap)
index 698763b28dddb10c56bae0cdfd540d2555f4d929..8721afe1ae4fa2906666e3857840fdb3709eabd7 100644 (file)
@@ -589,7 +589,7 @@ static int __init ks8695_console_setup(struct console *co, char *options)
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-extern struct uart_driver ks8695_reg;
+static struct uart_driver ks8695_reg;
 
 static struct console ks8695_console = {
        .name           = SERIAL_KS8695_DEVNAME,
index e35d9ab359f156313f37b4d728b72cbe78fd7a24..b45ba5392dd362941e12770edcf12c5671e590b2 100644 (file)
@@ -30,9 +30,9 @@ void
 sunserial_console_termios(struct console *con)
 {
        char mode[16], buf[16], *s;
-       char *mode_prop = "ttyX-mode";
-       char *cd_prop = "ttyX-ignore-cd";
-       char *dtr_prop = "ttyX-rts-dtr-off";
+       char mode_prop[] = "ttyX-mode";
+       char cd_prop[]   = "ttyX-ignore-cd";
+       char dtr_prop[]  = "ttyX-rts-dtr-off";
        char *ssp_console_modes_prop = "ssp-console-modes";
        int baud, bits, stop, cflag;
        char parity;
index 0985193dc57d1ce9aefbb548b0fb527d88343485..15b6e1cb040be54994ea9cbeea68bce51a61e2bf 100644 (file)
@@ -1239,7 +1239,7 @@ static inline struct console *SUNZILOG_CONSOLE(void)
 #define SUNZILOG_CONSOLE()     (NULL)
 #endif
 
-static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
+static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
 {
        int baud, brg;
 
@@ -1259,7 +1259,7 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 }
 
 #ifdef CONFIG_SERIO
-static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
+static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up)
 {
        struct serio *serio = &up->serio;
 
index 1d8a2f6bb8ebada212ad8d9617825bd9b96958ab..8b2601de36306e085d9a55481b0b777248db4946 100644 (file)
@@ -113,16 +113,16 @@ static void atmel_spi_next_xfer(struct spi_master *master,
 
        len = as->remaining_bytes;
 
-       tx_dma = xfer->tx_dma;
-       rx_dma = xfer->rx_dma;
+       tx_dma = xfer->tx_dma + xfer->len - len;
+       rx_dma = xfer->rx_dma + xfer->len - len;
 
        /* use scratch buffer only when rx or tx data is unspecified */
-       if (rx_dma == INVALID_DMA_ADDRESS) {
+       if (!xfer->rx_buf) {
                rx_dma = as->buffer_dma;
                if (len > BUFFER_SIZE)
                        len = BUFFER_SIZE;
        }
-       if (tx_dma == INVALID_DMA_ADDRESS) {
+       if (!xfer->tx_buf) {
                tx_dma = as->buffer_dma;
                if (len > BUFFER_SIZE)
                        len = BUFFER_SIZE;
index 052359fc41ee61c3324c925482baf7defa4b976a..11f36bef3057493a6c7b0c3e79e5f270f220a601 100644 (file)
@@ -329,8 +329,8 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
        int ret = 0;
 
 #if defined(CONFIG_PPC_MERGE)
-       cdm = mpc52xx_find_and_map("mpc52xx-cdm");
-       gpio = mpc52xx_find_and_map("mpc52xx-gpio");
+       cdm = mpc52xx_find_and_map("mpc5200-cdm");
+       gpio = mpc52xx_find_and_map("mpc5200-gpio");
 #else
        cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
        gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
@@ -445,9 +445,6 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
        struct spi_master *master;
        int ret;
 
-       if (pdata == NULL)
-               return -ENODEV;
-
        master = spi_alloc_master(dev, sizeof *mps);
        if (master == NULL)
                return -ENOMEM;
@@ -594,17 +591,17 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
        }
        regaddr64 = of_translate_address(op->node, regaddr_p);
 
+       /* get PSC id (1..6, used by port_config) */
        if (op->dev.platform_data == NULL) {
-               struct device_node *np;
-               int i = 0;
+               const u32 *psc_nump;
 
-               for_each_node_by_type(np, "spi") {
-                       if (of_find_device_by_node(np) == op) {
-                               id = i;
-                               break;
-                       }
-                       i++;
+               psc_nump = of_get_property(op->node, "cell-index", NULL);
+               if (!psc_nump || *psc_nump > 5) {
+                       printk(KERN_ERR "mpc52xx_psc_spi: Device node %s has invalid "
+                                       "cell-index property\n", op->node->full_name);
+                       return -EINVAL;
                }
+               id = *psc_nump + 1;
        }
 
        return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
@@ -617,7 +614,7 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
 }
 
 static struct of_device_id mpc52xx_psc_spi_of_match[] = {
-       { .type = "spi", .compatible = "mpc52xx-psc-spi", },
+       { .type = "spi", .compatible = "mpc5200-psc-spi", },
        {},
 };
 
index 96f62b2df300d26fce75823fa257e01a5e03f42b..95183e1df525c6a1a14ac6244d0f94f5fc3d05ea 100644 (file)
@@ -358,11 +358,11 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
        case SPI_MODE_0:
        case SPI_MODE_3:
-               flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
+               flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
                break;
        case SPI_MODE_1:
        case SPI_MODE_2:
-               flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
+               flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
                break;
        }
 
index c3219b29b5ac70b87190c36b195c4a6139dc385b..4831edbae2d589a0442021df9ee78aeaec10430f 100644 (file)
@@ -411,7 +411,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
  */
 int spi_register_master(struct spi_master *master)
 {
-       static atomic_t         dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
+       static atomic_t         dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
        struct device           *dev = master->cdev.dev;
        int                     status = -ENODEV;
        int                     dynamic = 0;
index 51daa212c6b799fd769ca82ef6f57bef96a933e3..656be4a5094a68cfd1d6d10b5fb936e2dbf7a1e0 100644 (file)
                                                        32.768 KHz Clock */
 
 /* SPI DMA Register Bit Fields & Masks */
-#define SPI_DMA_RHDMA  (0xF << 4)      /* RXFIFO Half Status */
+#define SPI_DMA_RHDMA  (0x1 << 4)      /* RXFIFO Half Status */
 #define SPI_DMA_RFDMA  (0x1 << 5)      /* RXFIFO Full Status */
 #define SPI_DMA_TEDMA  (0x1 << 6)      /* TXFIFO Empty Status */
 #define SPI_DMA_THDMA  (0x1 << 7)      /* TXFIFO Half Status */
@@ -1355,6 +1355,7 @@ static int setup(struct spi_device *spi)
                spi->bits_per_word,
                spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
                spi->max_speed_hz);
+       return status;
 
 err_first_setup:
        kfree(chip);
index 225d6b2f82ddcbc4a4e9031d072e23b2fada88a3..d04242aee40dd613eaa903c99fe9349a8bf418f8 100644 (file)
@@ -168,6 +168,12 @@ static int spidev_message(struct spidev_data *spidev,
                        n--, k_tmp++, u_tmp++) {
                k_tmp->len = u_tmp->len;
 
+               total += k_tmp->len;
+               if (total > bufsiz) {
+                       status = -EMSGSIZE;
+                       goto done;
+               }
+
                if (u_tmp->rx_buf) {
                        k_tmp->rx_buf = buf;
                        if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
@@ -179,12 +185,6 @@ static int spidev_message(struct spidev_data *spidev,
                                        u_tmp->len))
                                goto done;
                }
-
-               total += k_tmp->len;
-               if (total > bufsiz) {
-                       status = -EMSGSIZE;
-                       goto done;
-               }
                buf += k_tmp->len;
 
                k_tmp->cs_change = !!u_tmp->cs_change;
@@ -364,6 +364,7 @@ spidev_ioctl(struct inode *inode, struct file *filp,
                        break;
                }
                if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
+                       kfree(ioc);
                        retval = -EFAULT;
                        break;
                }
index 3524e3fc08b91ed27316748dc5ea528e3f7d61a0..61de78a9f6ee76156523e7041b04fd8b3b8434dd 100644 (file)
@@ -2182,7 +2182,7 @@ struct dec_serial_hook zs_kgdbhook = {
        .init_info      = kgdbhook_init_info,
        .rx_char        = kgdbhook_rx_char,
        .cflags         = B38400 | CS8 | CLOCAL,
-}
+};
 
 void __init zs_kgdb_hook(int tty_num)
 {
index 30b7bfbc985a752065b62770c9e52aa0f5cde8f8..8bcf7fe1dd80c7b531c417f5c58e565b8fd8653f 100644 (file)
@@ -476,8 +476,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
        add_timer(&timer);
        wait_for_completion(done);
        status = urb->status;
-       if (status == -ECONNRESET)
-               status = -ETIMEDOUT;
        del_timer_sync(&timer);
 
        if (actual_length)
@@ -629,10 +627,22 @@ static int cxacru_card_status(struct cxacru_data *instance)
        return 0;
 }
 
+static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance,
+               struct atm_dev *atm_dev)
+{
+       struct usb_interface *intf = usbatm_instance->usb_intf;
+
+       #define CXACRU_DEVICE_REMOVE_FILE(_name) \
+               device_remove_file(&intf->dev, &dev_attr_##_name);
+       CXACRU_ALL_FILES(REMOVE);
+       #undef CXACRU_DEVICE_REMOVE_FILE
+}
+
 static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
                struct atm_dev *atm_dev)
 {
        struct cxacru_data *instance = usbatm_instance->driver_data;
+       struct usb_interface *intf = usbatm_instance->usb_intf;
        /*
        struct atm_dev *atm_dev = usbatm_instance->atm_dev;
        */
@@ -649,14 +659,18 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
                return ret;
        }
 
+       #define CXACRU_DEVICE_CREATE_FILE(_name) \
+               ret = device_create_file(&intf->dev, &dev_attr_##_name); \
+               if (unlikely(ret)) \
+                       goto fail_sysfs;
+       CXACRU_ALL_FILES(CREATE);
+       #undef CXACRU_DEVICE_CREATE_FILE
+
        /* start ADSL */
        mutex_lock(&instance->adsl_state_serialize);
        ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
-       if (ret < 0) {
+       if (ret < 0)
                atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
-               mutex_unlock(&instance->adsl_state_serialize);
-               return ret;
-       }
 
        /* Start status polling */
        mutex_lock(&instance->poll_state_serialize);
@@ -680,6 +694,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
        if (start_polling)
                cxacru_poll_status(&instance->poll_work.work);
        return 0;
+
+fail_sysfs:
+       usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret);
+       cxacru_remove_device_files(usbatm_instance, atm_dev);
+       return ret;
 }
 
 static void cxacru_poll_status(struct work_struct *work)
@@ -1065,13 +1084,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
                goto fail;
        }
 
-       #define CXACRU_DEVICE_CREATE_FILE(_name) \
-               ret = device_create_file(&intf->dev, &dev_attr_##_name); \
-               if (unlikely(ret)) \
-                       goto fail_sysfs;
-       CXACRU_ALL_FILES(CREATE);
-       #undef CXACRU_DEVICE_CREATE_FILE
-
        usb_fill_int_urb(instance->rcv_urb,
                        usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
                        instance->rcv_buf, PAGE_SIZE,
@@ -1092,14 +1104,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
 
        return 0;
 
- fail_sysfs:
-       dbg("cxacru_bind: device_create_file failed (%d)\n", ret);
-
-       #define CXACRU_DEVICE_REMOVE_FILE(_name) \
-               device_remove_file(&intf->dev, &dev_attr_##_name);
-       CXACRU_ALL_FILES(REMOVE);
-       #undef CXACRU_DEVICE_REVOVE_FILE
-
  fail:
        free_page((unsigned long) instance->snd_buf);
        free_page((unsigned long) instance->rcv_buf);
@@ -1146,11 +1150,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
        free_page((unsigned long) instance->snd_buf);
        free_page((unsigned long) instance->rcv_buf);
 
-       #define CXACRU_DEVICE_REMOVE_FILE(_name) \
-               device_remove_file(&intf->dev, &dev_attr_##_name);
-       CXACRU_ALL_FILES(REMOVE);
-       #undef CXACRU_DEVICE_REVOVE_FILE
-
        kfree(instance);
 
        usbatm_instance->driver_data = NULL;
@@ -1231,6 +1230,7 @@ static struct usbatm_driver cxacru_driver = {
        .heavy_init     = cxacru_heavy_init,
        .unbind         = cxacru_unbind,
        .atm_start      = cxacru_atm_start,
+       .atm_stop       = cxacru_remove_device_files,
        .bulk_in        = CXACRU_EP_DATA,
        .bulk_out       = CXACRU_EP_DATA,
        .rx_padding     = 3,
index 15e740e3a5c47c41bb09340aac5811be1241e09f..6778f9af794381ec0ae40df7253aa26f0bbddfbc 100644 (file)
@@ -347,10 +347,8 @@ static int handle_bidir (struct usblp *usblp)
        if (usblp->bidir && usblp->used && !usblp->sleeping) {
                usblp->readcount = 0;
                usblp->readurb->dev = usblp->dev;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
-                       usblp->used = 0;
+               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
                        return -EIO;
-               }
        }
 
        return 0;
@@ -412,6 +410,7 @@ static int usblp_open(struct inode *inode, struct file *file)
        usblp->readurb->status = 0;
 
        if (handle_bidir(usblp) < 0) {
+               usblp->used = 0;
                file->private_data = NULL;
                retval = -EIO;
        }
@@ -1003,7 +1002,7 @@ abort:
                                usblp->writebuf, usblp->writeurb->transfer_dma);
                if (usblp->readbuf)
                        usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
-                               usblp->readbuf, usblp->writeurb->transfer_dma);
+                               usblp->readbuf, usblp->readurb->transfer_dma);
                kfree(usblp->statusbuf);
                kfree(usblp->device_id_string);
                usb_free_urb(usblp->writeurb);
index f493fb1eaa274fccef4266ae6784e91c165c3935..346fc030c929ae172b6658df8f1a2b54113e1ac3 100644 (file)
@@ -40,21 +40,25 @@ config USB_DEVICEFS
 config USB_DEVICE_CLASS
        bool "USB device class-devices (DEPRECATED)"
        depends on USB
-       default n
+       default y
        ---help---
          Userspace access to USB devices is granted by device-nodes exported
          directly from the usbdev in sysfs. Old versions of the driver
          core and udev needed additional class devices to export device nodes.
 
          These additional devices are difficult to handle in userspace, if
-         information about USB interfaces must be available. One device contains
-         the device node, the other device contains the interface data. Both
-         devices are at the same level in sysfs (siblings) and one can't access
-         the other. The device node created directly by the usbdev is the parent
-         device of the interface and therefore easily accessible from the interface
-         event.
-
-         This option provides backward compatibility if needed.
+         information about USB interfaces must be available. One device
+         contains the device node, the other device contains the interface
+         data. Both devices are at the same level in sysfs (siblings) and one
+         can't access the other. The device node created directly by the
+         usb device is the parent device of the interface and therefore
+         easily accessible from the interface event.
+
+         This option provides backward compatibility for libusb device
+         nodes (lsusb) when usbfs is not used, and the following udev rule
+         doesn't exist:
+           SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
+           NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
 
 config USB_DYNAMIC_MINORS
        bool "Dynamic USB minor allocation (EXPERIMENTAL)"
index bfb3731d42db816531a4cacd69d692ff04727827..dd3482328ad2603e7726e10d07dd4f2dc09ffc58 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/usb.h>
+#include <linux/usb/ch9.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
        unsigned char *buffer0 = buffer;
        struct usb_endpoint_descriptor *d;
        struct usb_host_endpoint *endpoint;
-       int n, i;
+       int n, i, j;
 
        d = (struct usb_endpoint_descriptor *) buffer;
        buffer += d->bLength;
@@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
        memcpy(&endpoint->desc, d, n);
        INIT_LIST_HEAD(&endpoint->urb_list);
 
+       /* If the bInterval value is outside the legal range,
+        * set it to a default value: 32 ms */
+       i = 0;          /* i = min, j = max, n = default */
+       j = 255;
+       if (usb_endpoint_xfer_int(d)) {
+               i = 1;
+               switch (to_usb_device(ddev)->speed) {
+               case USB_SPEED_HIGH:
+                       n = 9;          /* 32 ms = 2^(9-1) uframes */
+                       j = 16;
+                       break;
+               default:                /* USB_SPEED_FULL or _LOW */
+                       /* For low-speed, 10 ms is the official minimum.
+                        * But some "overclocked" devices might want faster
+                        * polling so we'll allow it. */
+                       n = 32;
+                       break;
+               }
+       } else if (usb_endpoint_xfer_isoc(d)) {
+               i = 1;
+               j = 16;
+               switch (to_usb_device(ddev)->speed) {
+               case USB_SPEED_HIGH:
+                       n = 9;          /* 32 ms = 2^(9-1) uframes */
+                       break;
+               default:                /* USB_SPEED_FULL */
+                       n = 6;          /* 32 ms = 2^(6-1) frames */
+                       break;
+               }
+       }
+       if (d->bInterval < i || d->bInterval > j) {
+               dev_warn(ddev, "config %d interface %d altsetting %d "
+                   "endpoint 0x%X has an invalid bInterval %d, "
+                   "changing to %d\n",
+                   cfgno, inum, asnum,
+                   d->bEndpointAddress, d->bInterval, n);
+               endpoint->desc.bInterval = n;
+       }
+
        /* Skip over any Class Specific or Vendor Specific descriptors;
         * find the next endpoint or interface descriptor */
        endpoint->extra = buffer;
@@ -185,10 +225,12 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
                num_ep = USB_MAXENDPOINTS;
        }
 
-       len = sizeof(struct usb_host_endpoint) * num_ep;
-       alt->endpoint = kzalloc(len, GFP_KERNEL);
-       if (!alt->endpoint)
-               return -ENOMEM;
+       if (num_ep > 0) {       /* Can't allocate 0 bytes */
+               len = sizeof(struct usb_host_endpoint) * num_ep;
+               alt->endpoint = kzalloc(len, GFP_KERNEL);
+               if (!alt->endpoint)
+                       return -ENOMEM;
+       }
 
        /* Parse all the endpoint descriptors */
        n = 0;
index b9f7f90aef827043ea096bd862d985ddb018bf79..2619986e53000f95667365157193dd1dec0d3453 100644 (file)
@@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev)
 
 #else
 
-#define autosuspend_check(udev)                0
+static inline int autosuspend_check(struct usb_device *udev)
+{
+       return 0;
+}
 
 #endif /* CONFIG_USB_SUSPEND */
 
@@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                if (status < 0)
                        goto done;
        }
-       cancel_delayed_work(&udev->autosuspend);
 
        /* Suspend all the interfaces and then udev itself */
        if (udev->actconfig) {
@@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                        usb_resume_interface(intf);
                }
 
+               /* Try another autosuspend when the interfaces aren't busy */
+               if (udev->auto_pm)
+                       autosuspend_check(udev);
+
        /* If the suspend succeeded, propagate it up the tree */
-       } else if (parent)
-               usb_autosuspend_device(parent);
+       } else {
+               cancel_delayed_work(&udev->autosuspend);
+               if (parent)
+                       usb_autosuspend_device(parent);
+       }
 
  done:
        // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
@@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev)
        usb_pm_lock(udev);
        udev->auto_pm = 0;
        status = usb_resume_both(udev);
+       udev->last_busy = jiffies;
        usb_pm_unlock(udev);
 
        /* Now that the device is awake, we can start trying to autosuspend
index 40cf882293e64dc57e54efbf3908cd725bd316b6..8969e42434b9ca2a2b2a54ea9c7aab0bcccd642a 100644 (file)
@@ -1018,8 +1018,8 @@ done:
                atomic_dec (&urb->use_count);
                if (urb->reject)
                        wake_up (&usb_kill_urb_queue);
-               usb_put_urb (urb);
                usbmon_urb_submit_error(&hcd->self, urb, status);
+               usb_put_urb (urb);
        }
        return status;
 }
@@ -1175,10 +1175,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev,
        struct urb              *urb;
 
        hcd = bus_to_hcd(udev->bus);
-
-       WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
-                       udev->state != USB_STATE_NOTATTACHED);
-
        local_irq_disable ();
 
        /* ep is already gone from udev->ep_{in,out}[]; no more submits */
@@ -1685,7 +1681,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        spin_unlock_irq (&hcd_root_hub_lock);
 
 #ifdef CONFIG_PM
-       flush_workqueue(ksuspend_usb_wq);
+       cancel_work_sync(&hcd->wakeup_work);
 #endif
 
        mutex_lock(&usb_bus_list_lock);
index f6b74a678de51f853e639c3fa7bcca80146021fd..24f10a19dbdbc1bbbf6befd31da7018078cfa186 100644 (file)
@@ -1158,6 +1158,30 @@ static void release_address(struct usb_device *udev)
        }
 }
 
+#ifdef CONFIG_USB_SUSPEND
+
+static void usb_stop_pm(struct usb_device *udev)
+{
+       /* Synchronize with the ksuspend thread to prevent any more
+        * autosuspend requests from being submitted, and decrement
+        * the parent's count of unsuspended children.
+        */
+       usb_pm_lock(udev);
+       if (udev->parent && !udev->discon_suspended)
+               usb_autosuspend_device(udev->parent);
+       usb_pm_unlock(udev);
+
+       /* Stop any autosuspend requests already submitted */
+       cancel_rearming_delayed_work(&udev->autosuspend);
+}
+
+#else
+
+static inline void usb_stop_pm(struct usb_device *udev)
+{ }
+
+#endif
+
 /**
  * usb_disconnect - disconnect a device (usbcore-internal)
  * @pdev: pointer to device being disconnected
@@ -1224,13 +1248,7 @@ void usb_disconnect(struct usb_device **pdev)
        *pdev = NULL;
        spin_unlock_irq(&device_state_lock);
 
-       /* Decrement the parent's count of unsuspended children */
-       if (udev->parent) {
-               usb_pm_lock(udev);
-               if (!udev->discon_suspended)
-                       usb_autosuspend_device(udev->parent);
-               usb_pm_unlock(udev);
-       }
+       usb_stop_pm(udev);
 
        put_device(&udev->dev);
 }
@@ -2201,14 +2219,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                continue;
                        }
 
-                       /* Use a short timeout the first time through,
-                        * so that recalcitrant full-speed devices with
-                        * 8- or 16-byte ep0-maxpackets won't slow things
-                        * down tremendously by NAKing the unexpectedly
-                        * early status stage.  Also, retry on all errors;
-                        * some devices are flakey.
-                        * 255 is for WUSB devices, we actually need to use 512.
-                        * WUSB1.0[4.8.1].
+                       /* Retry on all errors; some devices are flakey.
+                        * 255 is for WUSB devices, we actually need to use
+                        * 512 (WUSB1.0[4.8.1]).
                         */
                        for (j = 0; j < 3; ++j) {
                                buf->bMaxPacketSize0 = 0;
@@ -2216,7 +2229,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
                                        USB_DT_DEVICE << 8, 0,
                                        buf, GET_DESCRIPTOR_BUFSIZE,
-                                       (i ? USB_CTRL_GET_TIMEOUT : 1000));
+                                       USB_CTRL_GET_TIMEOUT);
                                switch (buf->bMaxPacketSize0) {
                                case 8: case 16: case 32: case 64: case 255:
                                        if (buf->bDescriptorType ==
@@ -2426,10 +2439,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 
        if (portchange & USB_PORT_STAT_C_CONNECTION) {
                status = hub_port_debounce(hub, port1);
-               if (status < 0 && printk_ratelimit()) {
-                       dev_err (hub_dev,
-                               "connect-debounce failed, port %d disabled\n",
-                               port1);
+               if (status < 0) {
+                       if (printk_ratelimit())
+                               dev_err (hub_dev, "connect-debounce failed, "
+                                               "port %d disabled\n", port1);
                        goto done;
                }
                portstatus = status;
index b7434787db5fb312cb705545fbc4fa64ab9dfc0e..f9fed34bf7d8b307491aee6d91c84edd686f28ed 100644 (file)
@@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
 
        if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                        USB_ENDPOINT_XFER_INT) {
-               int interval;
-
-               if (usb_dev->speed == USB_SPEED_HIGH)
-                       interval = 1 << min(15, ep->desc.bInterval - 1);
-               else
-                       interval = ep->desc.bInterval;
                pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
                usb_fill_int_urb(urb, usb_dev, pipe, data, len,
-                               usb_api_blocking_completion, NULL, interval);
+                               usb_api_blocking_completion, NULL,
+                               ep->desc.bInterval);
        } else
                usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
                                usb_api_blocking_completion, NULL);
index e7c982377488fca4b727d9d2edd7084269298b1b..be37c863fdfb18e872e553af1b8c5778a67e67a6 100644 (file)
@@ -232,12 +232,15 @@ set_level(struct device *dev, struct device_attribute *attr,
        int len = count;
        char *cp;
        int rc = 0;
+       int old_autosuspend_disabled, old_autoresume_disabled;
 
        cp = memchr(buf, '\n', count);
        if (cp)
                len = cp - buf;
 
        usb_lock_device(udev);
+       old_autosuspend_disabled = udev->autosuspend_disabled;
+       old_autoresume_disabled = udev->autoresume_disabled;
 
        /* Setting the flags without calling usb_pm_lock is a subject to
         * races, but who cares...
@@ -263,6 +266,10 @@ set_level(struct device *dev, struct device_attribute *attr,
        } else
                rc = -EINVAL;
 
+       if (rc) {
+               udev->autosuspend_disabled = old_autosuspend_disabled;
+               udev->autoresume_disabled = old_autoresume_disabled;
+       }
        usb_unlock_device(udev);
        return (rc < 0 ? rc : count);
 }
index 18ddc5e67e39099bc9634e9e4def4232cfc4fdef..4a6299bd00478156417a7ed757ffc0d261bdc736 100644 (file)
@@ -184,10 +184,6 @@ static void usb_release_dev(struct device *dev)
 
        udev = to_usb_device(dev);
 
-#ifdef CONFIG_USB_SUSPEND
-       cancel_delayed_work(&udev->autosuspend);
-       flush_workqueue(ksuspend_usb_wq);
-#endif
        usb_destroy_configuration(udev);
        usb_put_hcd(bus_to_hcd(udev->bus));
        kfree(udev->product);
@@ -205,7 +201,11 @@ struct device_type usb_device_type = {
 
 static int ksuspend_usb_init(void)
 {
-       ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
+       /* This workqueue is supposed to be both freezable and
+        * singlethreaded.  Its job doesn't justify running on more
+        * than one CPU.
+        */
+       ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
        if (!ksuspend_usb_wq)
                return -ENOMEM;
        return 0;
index f28af06905a5caaee0245e5a85f78176ca015b0d..6042364402b8fb0b4fe1551fe8b5c57b8ae190c5 100644 (file)
@@ -132,7 +132,7 @@ ep_matches (
         * where it's an output parameter representing the full speed limit.
         * the usb spec fixes high speed bulk maxpacket at 512 bytes.
         */
-       max = 0x7ff & le16_to_cpup (&desc->wMaxPacketSize);
+       max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
        switch (type) {
        case USB_ENDPOINT_XFER_INT:
                /* INT:  limit 64 bytes full speed, 1024 high speed */
index 157054ea39786936ff3f269bc58bf705ba4d7c83..3ca2b3159f00d8947a712ea45d96c09a6c72f72c 100644 (file)
@@ -228,13 +228,15 @@ static int dr_controller_setup(struct fsl_udc *udc)
 
        /* Config PHY interface */
        portctrl = fsl_readl(&dr_regs->portsc1);
-       portctrl &= ~PORTSCX_PHY_TYPE_SEL;
+       portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH);
        switch (udc->phy_mode) {
        case FSL_USB2_PHY_ULPI:
                portctrl |= PORTSCX_PTS_ULPI;
                break;
-       case FSL_USB2_PHY_UTMI:
        case FSL_USB2_PHY_UTMI_WIDE:
+               portctrl |= PORTSCX_PTW_16BIT;
+               /* fall through */
+       case FSL_USB2_PHY_UTMI:
                portctrl |= PORTSCX_PTS_UTMI;
                break;
        case FSL_USB2_PHY_SERIAL:
@@ -625,7 +627,7 @@ static void fsl_free_buffer(struct usb_ep *_ep, void *buf,
        struct fsl_ep *ep;
 
        if (!_ep)
-               return NULL;
+               return;
 
        ep = container_of(_ep, struct fsl_ep, ep);
 
index 188c74a95216860cb1740243211b94ef013cbddd..46d0e52527447aea5d9f63073d964317dd0bd0a9 100644 (file)
@@ -1369,12 +1369,12 @@ config_buf (struct dev_data *dev, u8 type, unsigned index)
                hs = !hs;
        if (hs) {
                dev->req->buf = dev->hs_config;
-               len = le16_to_cpup (&dev->hs_config->wTotalLength);
+               len = le16_to_cpu(dev->hs_config->wTotalLength);
        } else
 #endif
        {
                dev->req->buf = dev->config;
-               len = le16_to_cpup (&dev->config->wTotalLength);
+               len = le16_to_cpu(dev->config->wTotalLength);
        }
        ((u8 *)dev->req->buf) [1] = type;
        return len;
@@ -1885,7 +1885,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 
        /* full or low speed config */
        dev->config = (void *) kbuf;
-       total = le16_to_cpup (&dev->config->wTotalLength);
+       total = le16_to_cpu(dev->config->wTotalLength);
        if (!is_valid_config (dev->config) || total >= length)
                goto fail;
        kbuf += total;
@@ -1894,7 +1894,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
        /* optional high speed config */
        if (kbuf [1] == USB_DT_CONFIG) {
                dev->hs_config = (void *) kbuf;
-               total = le16_to_cpup (&dev->hs_config->wTotalLength);
+               total = le16_to_cpu(dev->hs_config->wTotalLength);
                if (!is_valid_config (dev->hs_config) || total >= length)
                        goto fail;
                kbuf += total;
index 52779c52b56d97231aecfc5703e062ff68c8c64e..d975ecf18e00537bb6a67895f04f4a5bd00b6ee5 100644 (file)
@@ -2440,9 +2440,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 
                tmp = 0;
 
-#define        w_value         le16_to_cpup (&u.r.wValue)
-#define        w_index         le16_to_cpup (&u.r.wIndex)
-#define        w_length        le16_to_cpup (&u.r.wLength)
+#define        w_value         le16_to_cpu(u.r.wValue)
+#define        w_index         le16_to_cpu(u.r.wIndex)
+#define        w_length        le16_to_cpu(u.r.wLength)
 
                /* ack the irq */
                writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0);
index b394e63894d2e21c50ba15265fd7433838c1c91d..c4975a6cf7774cc32fcd0ff3500462694b2c0f7b 100644 (file)
@@ -1651,9 +1651,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
                        UDC_EP_NUM_REG = 0;
                } while (UDC_IRQ_SRC_REG & UDC_SETUP);
 
-#define        w_value         le16_to_cpup (&u.r.wValue)
-#define        w_index         le16_to_cpup (&u.r.wIndex)
-#define        w_length        le16_to_cpup (&u.r.wLength)
+#define        w_value         le16_to_cpu(u.r.wValue)
+#define        w_index         le16_to_cpu(u.r.wIndex)
+#define        w_length        le16_to_cpu(u.r.wLength)
 
                /* Delegate almost all control requests to the gadget driver,
                 * except for a handful of ch9 status/feature requests that
index 6ec8cf1a3ccb1cd14d39667231da28b36abdecdf..708657c89132068f2bfdbb8cc7f3552cbc182cbe 100644 (file)
@@ -186,10 +186,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                DEBUG("query OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
                        DEBUG ("%03d: %08x %08x %08x %08x\n", i,
-                               le32_to_cpup((__le32 *)&buf[i]),
-                               le32_to_cpup((__le32 *)&buf[i + 4]),
-                               le32_to_cpup((__le32 *)&buf[i + 8]),
-                               le32_to_cpup((__le32 *)&buf[i + 12]));
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 4])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 8])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 12])));
                }
        }
 
@@ -665,7 +669,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
        case OID_PNP_QUERY_POWER:
                DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
-                               le32_to_cpup((__le32 *) buf) - 1);
+                               le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
                /* only suspend is a real power state, and
                 * it can't be entered by OID_PNP_SET_POWER...
                 */
@@ -704,10 +708,14 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
                        DEBUG ("%03d: %08x %08x %08x %08x\n", i,
-                               le32_to_cpup((__le32 *)&buf[i]),
-                               le32_to_cpup((__le32 *)&buf[i + 4]),
-                               le32_to_cpup((__le32 *)&buf[i + 8]),
-                               le32_to_cpup((__le32 *)&buf[i + 12]));
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 4])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 8])),
+                               le32_to_cpu(get_unaligned((__le32 *)
+                                       &buf[i + 12])));
                }
        }
 
@@ -721,7 +729,8 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                 *      PROMISCUOUS, DIRECTED,
                 *      MULTICAST, ALL_MULTICAST, BROADCAST
                 */
-               *params->filter = (u16) le32_to_cpup((__le32 *)buf);
+               *params->filter = (u16) le32_to_cpu(get_unaligned(
+                               (__le32 *)buf));
                DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
                        __FUNCTION__, *params->filter);
 
@@ -771,7 +780,7 @@ update_linkstate:
                 * resuming, Windows forces a reset, and then SET_POWER D0.
                 * FIXME ... then things go batty; Windows wedges itself.
                 */
-               i = le32_to_cpup((__force __le32 *)buf);
+               i = le32_to_cpu(get_unaligned((__le32 *)buf));
                DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
                switch (i) {
                case NdisDeviceStateD0:
@@ -1058,8 +1067,8 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                return -ENOMEM;
 
        tmp = (__le32 *) buf;
-       MsgType   = le32_to_cpup(tmp++);
-       MsgLength = le32_to_cpup(tmp++);
+       MsgType   = le32_to_cpu(get_unaligned(tmp++));
+       MsgLength = le32_to_cpu(get_unaligned(tmp++));
 
        if (configNr >= RNDIS_MAX_CONFIGS)
                return -ENOTSUPP;
index a52480505f78fa2495787ad3db8d090a2779e74e..c7a7c590426fd2d54812a46f45a6a495a22b0ca2 100644 (file)
@@ -193,6 +193,19 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
        out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
        out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
 
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+       /*
+        * Turn on cache snooping hardware, since some PowerPC platforms
+        * wholly rely on hardware to deal with cache coherent
+        */
+
+       /* Setup Snooping for all the 4GB space */
+       /* SNOOP1 starts from 0x0, size 2G */
+       out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0 | SNOOP_SIZE_2GB);
+       /* SNOOP2 starts from 0x80000000, size 2G */
+       out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
+#endif
+
        if (pdata->operating_mode == FSL_USB2_DR_HOST)
                mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
 
index f28736a917e46127d8568b124c1f1e8657ba1a2c..b5e59db53347fa37df58456252e50876608b6c35 100644 (file)
@@ -34,4 +34,5 @@
 #define FSL_SOC_USB_PRICTRL    0x40c   /* NOTE: big-endian */
 #define FSL_SOC_USB_SICTRL     0x410   /* NOTE: big-endian */
 #define FSL_SOC_USB_CTRL       0x500   /* NOTE: big-endian */
+#define SNOOP_SIZE_2GB         0x1e
 #endif                         /* _EHCI_FSL_H */
index 216c9c9d4d6d58b07b0ed39d86ce77e080367740..bb9cc595219e84cb0582250dc857d9892a503c0a 100644 (file)
@@ -417,6 +417,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
        unsigned long   flags;
 
        spin_lock_irqsave (&ohci->lock, flags);
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+               goto done;
 
        /* undocumented erratum seen on at least rev D */
        if ((ohci->flags & OHCI_QUIRK_AMD756)
index 79705609fd0c4cb248b6f9a7a195dce886d65776..ca62cb583221a877e0f819b27de91a6d7e62d066 100644 (file)
@@ -137,7 +137,7 @@ static const struct pci_device_id ohci_pci_quirks[] = {
                /* Toshiba portege 4000 */
                .vendor         = PCI_VENDOR_ID_AL,
                .device         = 0x5237,
-               .subvendor      = PCI_VENDOR_ID_TOSHIBA_2,
+               .subvendor      = PCI_VENDOR_ID_TOSHIBA,
                .subdevice      = 0x0004,
                .driver_data    = (unsigned long) broken_suspend,
        },
index 20861650905e63606955056b5169581a0b92463c..c225159ca3d346759a33b73b49743d64914ba778 100644 (file)
@@ -44,6 +44,7 @@
 #define EHCI_USBSTS            4               /* status register */
 #define EHCI_USBSTS_HALTED     (1 << 12)       /* HCHalted bit */
 #define EHCI_USBINTR           8               /* interrupt register */
+#define EHCI_CONFIGFLAG                0x40            /* configured flag register */
 #define EHCI_USBLEGSUP         0               /* legacy support register */
 #define EHCI_USBLEGSUP_BIOS    (1 << 16)       /* BIOS semaphore */
 #define EHCI_USBLEGSUP_OS      (1 << 24)       /* OS semaphore */
@@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
        u32     hcc_params, val;
        u8      offset, cap_length;
        int     count = 256/4;
+       int     tried_handoff = 0;
 
        if (!mmio_resource_enabled(pdev, 0))
                return;
@@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
                         */
                        msec = 5000;
                        while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+                               tried_handoff = 1;
                                msleep(10);
                                msec -= 10;
                                pci_read_config_dword(pdev, offset, &cap);
@@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
                        pci_write_config_dword(pdev,
                                        offset + EHCI_USBLEGCTLSTS,
                                        0);
+
+                       /* If the BIOS ever owned the controller then we
+                        * can't expect any power sessions to remain intact.
+                        */
+                       if (tried_handoff)
+                               writel(0, op_reg_base + EHCI_CONFIGFLAG);
                        break;
                case 0:                 /* illegal reserved capability */
                        cap = 0;
index ff0dba01f1c7d2129a9830cae777fa3e1f85b938..e98df2ee990131643d6e162c67b82145bab018bf 100644 (file)
 #include <asm/system.h>
 #include <asm/byteorder.h>
 #include "../core/hcd.h"
+
+       /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+        * If you're going to try stuff like this, you need to split
+        * out shareable stuff (register declarations?) into its own
+        * file, maybe name <linux/usb/ohci.h>
+        */
+
 #include "ohci.h"
 #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
 #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
@@ -173,11 +180,6 @@ struct u132_ring {
         struct u132_endp *curr_endp;
         struct delayed_work scheduler;
 };
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
-#define OHCI_QUIRK_ZFMICRO 0x10
 struct u132 {
         struct kref kref;
         struct list_head u132_list;
index 88fb56d5db8f8c2b22a21ceaa51602d72b86827f..cac1500cba62b8528faca6e1a370f8c769e2b1af 100644 (file)
@@ -1822,16 +1822,10 @@ static int auerchar_release (struct inode *inode, struct file *file)
        pauerswald_t cp;
        dbg("release");
 
-       /* get the mutexes */
-       if (down_interruptible (&ccp->mutex)) {
-               return -ERESTARTSYS;
-       }
+       down(&ccp->mutex);
        cp = ccp->auerdev;
        if (cp) {
-               if (down_interruptible (&cp->mutex)) {
-                       up (&ccp->mutex);
-                       return -ERESTARTSYS;
-               }
+               down(&cp->mutex);
                /* remove an open service */
                auerswald_removeservice (cp, &ccp->scontext);
                /* detach from device */
index e2172e5cf1528da7f6739450b8556023f1d23b54..e0f122e131d720e0580382f88845c2bf47cde5a7 100644 (file)
@@ -73,6 +73,13 @@ static struct list_head ftdi_static_list;
 #include "usb_u132.h"
 #include <asm/io.h>
 #include "../core/hcd.h"
+
+       /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+        * If you're going to try stuff like this, you need to split
+        * out shareable stuff (register declarations?) into its own
+        * file, maybe name <linux/usb/ohci.h>
+        */
+
 #include "../host/ohci.h"
 /* Define these values to match your devices*/
 #define USB_FTDI_ELAN_VENDOR_ID 0x0403
@@ -2300,10 +2307,7 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi)
         offsetof(struct ohci_regs, member), 0, data);
 #define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
         offsetof(struct ohci_regs, member), 0, data);
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
+
 #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
 #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
         OHCI_INTR_WDH)
index 11555bde655bf16c6fc2b049aea6910b1a808fba..7bad494047621a38f61bd8cf90057f2d40870ea7 100644 (file)
@@ -165,6 +165,8 @@ struct ld_usb {
        size_t                  interrupt_in_endpoint_size;
        int                     interrupt_in_running;
        int                     interrupt_in_done;
+       int                     buffer_overflow;
+       spinlock_t              rbsl;
 
        char*                   interrupt_out_buffer;
        struct usb_endpoint_descriptor* interrupt_out_endpoint;
@@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
                } else {
                        dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
                                 __FUNCTION__, urb->status);
+                       spin_lock(&dev->rbsl);
                        goto resubmit; /* maybe we can recover */
                }
        }
 
+       spin_lock(&dev->rbsl);
        if (urb->actual_length > 0) {
                next_ring_head = (dev->ring_head+1) % ring_buffer_size;
                if (next_ring_head != dev->ring_tail) {
@@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
                        dev->ring_head = next_ring_head;
                        dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
                                 __FUNCTION__, urb->actual_length);
-               } else
+               } else {
                        dev_warn(&dev->intf->dev,
                                 "Ring buffer overflow, %d bytes dropped\n",
                                 urb->actual_length);
+                       dev->buffer_overflow = 1;
+               }
        }
 
 resubmit:
        /* resubmit if we're still running */
-       if (dev->interrupt_in_running && dev->intf) {
+       if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
                retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
-               if (retval)
+               if (retval) {
                        dev_err(&dev->intf->dev,
                                "usb_submit_urb failed (%d)\n", retval);
+                       dev->buffer_overflow = 1;
+               }
        }
-
+       spin_unlock(&dev->rbsl);
 exit:
        dev->interrupt_in_done = 1;
        wake_up_interruptible(&dev->read_wait);
@@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
        /* initialize in direction */
        dev->ring_head = 0;
        dev->ring_tail = 0;
+       dev->buffer_overflow = 0;
        usb_fill_int_urb(dev->interrupt_in_urb,
                         interface_to_usbdev(interface),
                         usb_rcvintpipe(interface_to_usbdev(interface),
@@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
        size_t *actual_buffer;
        size_t bytes_to_read;
        int retval = 0;
+       int rv;
 
        dev = file->private_data;
 
@@ -460,7 +470,10 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
        }
 
        /* wait for data */
+       spin_lock_irq(&dev->rbsl);
        if (dev->ring_head == dev->ring_tail) {
+               dev->interrupt_in_done = 0;
+               spin_unlock_irq(&dev->rbsl);
                if (file->f_flags & O_NONBLOCK) {
                        retval = -EAGAIN;
                        goto unlock_exit;
@@ -468,6 +481,8 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
                retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
                if (retval < 0)
                        goto unlock_exit;
+       } else {
+               spin_unlock_irq(&dev->rbsl);
        }
 
        /* actual_buffer contains actual_length + interrupt_in_buffer */
@@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
 
        retval = bytes_to_read;
 
+       spin_lock_irq(&dev->rbsl);
+       if (dev->buffer_overflow) {
+               dev->buffer_overflow = 0;
+               spin_unlock_irq(&dev->rbsl);
+               rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+               if (rv < 0)
+                       dev->buffer_overflow = 1;
+       } else {
+               spin_unlock_irq(&dev->rbsl);
+       }
+
 unlock_exit:
        /* unlock the device */
        up(&dev->sem);
@@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
                goto exit;
        }
        init_MUTEX(&dev->sem);
+       spin_lock_init(&dev->rbsl);
        dev->intf = intf;
        init_waitqueue_head(&dev->read_wait);
        init_waitqueue_head(&dev->write_wait);
index ea2175bb227460079cda3c8ca994ca35a6dccdb6..fe437125f14bc9f86cdb2b4352c04c2c2528aca6 100644 (file)
@@ -63,7 +63,8 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
                                 request, requesttype, value, index,
                                 buf, 0x0000001, 1000);
        if (result)
-               dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]);
+               dbg("%03d < %d bytes [0x%02X]", seq, result,
+                   ((unsigned char *)buf)[0]);
        else
                dbg("%03d < 0 bytes", seq);
 }
index 95a1805b064ff65cc0f7779f8643a5ece4593953..2353679f601ebbc618b1d4647f792cf410dc2d23 100644 (file)
@@ -273,12 +273,18 @@ static __u16 product;
 
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
 struct ftdi_sio_quirk {
+       int (*probe)(struct usb_serial *);
        void (*setup)(struct usb_serial *); /* Special settings during startup. */
 };
 
+static int   ftdi_olimex_probe         (struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup       (struct usb_serial *serial);
 static void  ftdi_HE_TIRA1_setup       (struct usb_serial *serial);
 
+static struct ftdi_sio_quirk ftdi_olimex_quirk = {
+       .probe  = ftdi_olimex_probe,
+};
+
 static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
        .setup = ftdi_USB_UIRT_setup,
 };
@@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
@@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
        { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+       { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = {
 
 /*
  * ***************************************************************************
- * Utlity functions
+ * Utility functions
  * ***************************************************************************
  */
 
@@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
 /* Probe function to check for special devices */
 static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
 {
+       struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+
+       if (quirk && quirk->probe) {
+               int ret = quirk->probe(serial);
+               if (ret != 0)
+                       return ret;
+       }
+
        usb_set_serial_data(serial, (void *)id->driver_info);
 
-       return (0);
+       return 0;
 }
 
 static int ftdi_sio_port_probe(struct usb_serial_port *port)
@@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
        priv->force_rtscts = 1;
 } /* ftdi_HE_TIRA1_setup */
 
+/*
+ * First port on Olimex arm-usb-ocd is reserved for JTAG interface
+ * and can be accessed from userspace using openocd.
+ */
+static int ftdi_olimex_probe(struct usb_serial *serial)
+{
+       struct usb_device *udev = serial->dev;
+       struct usb_interface *interface = serial->interface;
+
+       dbg("%s",__FUNCTION__);
+
+       if (interface == udev->actconfig->interface[0]) {
+               info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
 
 /* ftdi_shutdown is called from usbserial:usb_serial_disconnect
  *   it is called when the usb device is disconnected
index 77ad0a09b3849dd675ea48c6dbf776a53094dbfe..33aee9047242889b6f1f44171c2cbd9a458a0020 100644 (file)
@@ -60,6 +60,9 @@
 /* DMX4ALL DMX Interfaces */
 #define FTDI_DMX4ALL 0xC850
 
+/* OpenDCC (www.opendcc.de) product id */
+#define FTDI_OPENDCC_PID       0xBFD8
+
 /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
 /* they use the ftdi chipset for the USB interface and the vendor id is the same */
 #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
 #define FTDI_IBS_PEDO_PID      0xff3e  /* IBS PEDO-Modem (RF modem 868.35 MHz) */
 #define FTDI_IBS_PROD_PID      0xff3f  /* future device */
 
+/*
+ *  MaxStream devices  www.maxstream.net
+ */
+#define FTDI_MAXSTREAM_PID     0xEE18  /* Xbee PKG-U Module */
+
+/* Olimex */
+#define OLIMEX_VID                     0x15BA
+#define OLIMEX_ARM_USB_OCD_PID         0x0003
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 2366e7b63ece5679c0a00f80446ff5577d70bd76..36620c651079ccb4b20e8bde21e0f2df6581c226 100644 (file)
@@ -769,11 +769,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
                return;
        }
 
-       if (!mos7840_port) {
-               dbg("%s", "NULL mos7840_port pointer \n");
-               return;
-       }
-
        if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {
                dbg("%s", "Port Paranoia failed \n");
                return;
index 4adfab988e86630089c57d6ff4001d7986166c94..00afc1712c391336163f4f0b72b83a115cb5aeb5 100644 (file)
@@ -165,12 +165,10 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial       *serial = port->serial;
        struct usb_serial_port  *wport;
-       struct omninet_data     *od = usb_get_serial_port_data(port);
        int                     result = 0;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
        wport = serial->port[1];
        wport->tty = port->tty;
 
index 8c3f55b080b4e147cd56e0c70fe7d07ecd7849ff..89f067d9507690dade260c0e38089b93e00b8619 100644 (file)
@@ -165,7 +165,6 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
index 644607de4c11a69f3e0e4a8d22b97e5f9fbcf473..ac1829c6e8f02da29aecc3a5383a0c1dfa7a2b2e 100644 (file)
@@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+       { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
        { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -60,6 +61,7 @@ static struct usb_device_id id_table_3port [] = {
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+       { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
        { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
index 6d3dad3d1daeb2c84d5531a934e9dae7f5f1b9dc..d35369392feda4b8939e5a47f91da758b95f2743 100644 (file)
@@ -84,7 +84,7 @@ resubmit:
 
 static int usb_onetouch_open(struct input_dev *dev)
 {
-       struct usb_onetouch *onetouch = dev->private;
+       struct usb_onetouch *onetouch = input_get_drvdata(dev);
 
        onetouch->is_open = 1;
        onetouch->irq->dev = onetouch->udev;
@@ -98,7 +98,7 @@ static int usb_onetouch_open(struct input_dev *dev)
 
 static void usb_onetouch_close(struct input_dev *dev)
 {
-       struct usb_onetouch *onetouch = dev->private;
+       struct usb_onetouch *onetouch = input_get_drvdata(dev);
 
        usb_kill_urb(onetouch->irq);
        onetouch->is_open = 0;
@@ -185,13 +185,14 @@ int onetouch_connect_input(struct us_data *ss)
        input_dev->name = onetouch->name;
        input_dev->phys = onetouch->phys;
        usb_to_input_id(udev, &input_dev->id);
-       input_dev->cdev.dev = &udev->dev;
+       input_dev->dev.parent = &udev->dev;
 
        set_bit(EV_KEY, input_dev->evbit);
        set_bit(ONETOUCH_BUTTON, input_dev->keybit);
        clear_bit(0, input_dev->keybit);
 
-       input_dev->private = onetouch;
+       input_set_drvdata(input_dev, onetouch);
+
        input_dev->open = usb_onetouch_open;
        input_dev->close = usb_onetouch_close;
 
index 8b3145ab775752c60797be1c62fbcd8b9123dcac..54979c239c6329d7382176e7996a5384c371b160 100644 (file)
@@ -1179,14 +1179,28 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
                 US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_FIX_INQUIRY ),
 
-/* This is a virtual windows driver CD, which the zd1211rw driver automatically
- * converts into a WLAN device. */
+/* These are virtual windows driver CDs, which the zd1211rw driver
+ * automatically converts into WLAN devices. */
 UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
                 "ZyXEL",
                 "G-220F USB-WLAN Install",
                 US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_IGNORE_DEVICE ),
 
+UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
+               "SiteCom",
+               "WL-117 USB-WLAN Install",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_DEVICE ),
+
+/* SanDisk that has a second LUN for a driver ISO, reported by
+ * Ben Collins <bcollins@ubuntu.com> */
+UNUSUAL_DEV( 0x0781, 0x5406, 0x0000, 0xffff,
+               "SanDisk",
+               "U3 Cruzer Micro driver ISO",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_SINGLE_LUN ),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
                "ATI",
@@ -1265,6 +1279,15 @@ UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
+/* Reported by Edward Chapman (taken from linux-usb mailing list)
+   Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */
+UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999,
+               "Netac",
+               "USB Flash Disk",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE ),
+
+
 /* Patch by Stephan Walter <stephan.walter@epfl.ch>
  * I don't know why, but it works... */
 UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012,
index 4d7485fa553ff3f7732bbe76953e6b74f6310319..403dac787ebf0f98975802648455470b9d8edcac 100644 (file)
@@ -704,6 +704,91 @@ config FB_CG6
          This is the frame buffer device driver for the CGsix (GX, TurboGX)
          frame buffer.
 
+config FB_FFB
+       bool "Creator/Creator3D/Elite3D support"
+       depends on FB_SBUS && SPARC64
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the frame buffer device driver for the Creator, Creator3D,
+         and Elite3D graphics boards.
+
+config FB_TCX
+       bool "TCX (SS4/SS5 only) support"
+       depends on FB_SBUS
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the frame buffer device driver for the TCX 24/8bit frame
+         buffer.
+
+config FB_CG14
+       bool "CGfourteen (SX) support"
+       depends on FB_SBUS
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the frame buffer device driver for the CGfourteen frame
+         buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+       bool "P9100 (Sparcbook 3 only) support"
+       depends on FB_SBUS
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the frame buffer device driver for the P9100 card
+         supported on Sparcbook 3 machines.
+
+config FB_LEO
+       bool "Leo (ZX) support"
+       depends on FB_SBUS
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the frame buffer device driver for the SBUS-based Sun ZX
+         (leo) frame buffer cards.
+
+config FB_IGA
+       bool "IGA 168x display support"
+       depends on (FB = y) && SPARC32
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the framebuffer device for the INTERGRAPHICS 1680 and
+         successor frame buffer cards.
+
+config FB_XVR500
+       bool "Sun XVR-500 3DLABS Wildcat support"
+       depends on (FB = y) && PCI && SPARC64
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the framebuffer device for the Sun XVR-500 and similar
+         graphics cards based upon the 3DLABS Wildcat chipset.  The driver
+         only works on sparc64 systems where the system firwmare has
+         mostly initialized the card already.  It is treated as a
+         completely dumb framebuffer device.
+
+config FB_XVR2500
+       bool "Sun XVR-2500 3DLABS Wildcat support"
+       depends on (FB = y) && PCI && SPARC64
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         This is the framebuffer device for the Sun XVR-2500 and similar
+         graphics cards based upon the 3DLABS Wildcat chipset.  The driver
+         only works on sparc64 systems where the system firwmare has
+         mostly initialized the card already.  It is treated as a
+         completely dumb framebuffer device.
+
 config FB_PVR2
        tristate "NEC PowerVR 2 display support"
        depends on FB && SH_DREAMCAST
@@ -1195,7 +1280,7 @@ config FB_ATY
 config FB_ATY_CT
        bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
        depends on PCI && FB_ATY
-       default y if SPARC64 && FB_PCI
+       default y if SPARC64 && PCI
        help
          Say Y here to support use of ATI's 64-bit Rage boards (or other
          boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
@@ -1484,95 +1569,6 @@ config FB_AU1200
 
 source "drivers/video/geode/Kconfig"
 
-config FB_FFB
-       bool "Creator/Creator3D/Elite3D support"
-       depends on FB_SBUS && SPARC64
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the frame buffer device driver for the Creator, Creator3D,
-         and Elite3D graphics boards.
-
-config FB_TCX
-       bool "TCX (SS4/SS5 only) support"
-       depends on FB_SBUS
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the frame buffer device driver for the TCX 24/8bit frame
-         buffer.
-
-config FB_CG14
-       bool "CGfourteen (SX) support"
-       depends on FB_SBUS
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the frame buffer device driver for the CGfourteen frame
-         buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
-       bool "P9100 (Sparcbook 3 only) support"
-       depends on FB_SBUS
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the frame buffer device driver for the P9100 card
-         supported on Sparcbook 3 machines.
-
-config FB_LEO
-       bool "Leo (ZX) support"
-       depends on FB_SBUS
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the frame buffer device driver for the SBUS-based Sun ZX
-         (leo) frame buffer cards.
-
-config FB_XVR500
-       bool "Sun XVR-500 3DLABS Wildcat support"
-       depends on (FB = y) && PCI && SPARC64
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the framebuffer device for the Sun XVR-500 and similar
-         graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-         only works on sparc64 systems where the system firwmare has
-         mostly initialized the card already.  It is treated as a
-         completely dumb framebuffer device.
-
-config FB_XVR2500
-       bool "Sun XVR-2500 3DLABS Wildcat support"
-       depends on (FB = y) && PCI && SPARC64
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the framebuffer device for the Sun XVR-2500 and similar
-         graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-         only works on sparc64 systems where the system firwmare has
-         mostly initialized the card already.  It is treated as a
-         completely dumb framebuffer device.
-
-config FB_PCI
-       bool "PCI framebuffers"
-       depends on (FB = y) && PCI && SPARC
-
-config FB_IGA
-       bool "IGA 168x display support"
-       depends on SPARC32 && FB_PCI
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the framebuffer device for the INTERGRAPHICS 1680 and
-         successor frame buffer cards.
-
 config FB_HIT
        tristate "HD64461 Frame Buffer support"
        depends on FB && HD64461
@@ -1796,9 +1792,10 @@ config FB_IBM_GXT4500
 config FB_PS3
        bool "PS3 GPU framebuffer driver"
        depends on (FB = y) && PS3_PS3AV
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
        ---help---
          Include support for the virtual frame buffer in the PS3 platform.
 
index ba6fede5c466f3c6eaa5742ac35ae0ebe99f8232..8a1b07c74394d35f12c62ab25129ca762c23e045 100644 (file)
@@ -1055,9 +1055,10 @@ err_enable_device:
 static void __devexit ark_pci_remove(struct pci_dev *dev)
 {
        struct fb_info *info = pci_get_drvdata(dev);
-       struct arkfb_info *par = info->par;
 
        if (info) {
+               struct arkfb_info *par = info->par;
+
 #ifdef CONFIG_MTRR
                if (par->mtrr_reg >= 0) {
                        mtrr_del(par->mtrr_reg, 0, 0);
index 9b26dda18a38c1e13fde4b3b92610a36d840d7ef..ac46cc3f6a2a1286586d51cc3bec3dce23ff0d19 100644 (file)
@@ -47,7 +47,7 @@ targets := promcon_tbl.c
 quiet_cmd_conmakehash = CNMKHSH $@
       cmd_conmakehash = scripts/conmakehash $< | \
                sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
-               -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+               -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
 
 $(obj)/promcon_tbl.c: $(src)/prom.uni
        $(call cmd,conmakehash)
index 71f24e00fcd041c54212166f30db1c9e23283aa6..8e6ef4bc7a5c75027ae59c8b35b4c5c5acdaead0 100644 (file)
@@ -176,7 +176,6 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
 extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
-extern struct class *fb_class;
 
 #define FBCON_ATTRIBUTE_UNDERLINE 1
 #define FBCON_ATTRIBUTE_REVERSE   2
index 1d4e8354b56159b407783eb073a70a4c464fcbf2..3f6c98fad437fca8f542dbd11a29a19e55d52bce 100644 (file)
@@ -656,7 +656,7 @@ static int ffb_setcolreg(unsigned regno,
 {
        u32 value;
 
-       if (regno >= 256)
+       if (regno >= 16)
                return 1;
 
        red >>= 8;
@@ -903,7 +903,7 @@ ffb_init_fix(struct fb_info *info)
 struct all_info {
        struct fb_info info;
        struct ffb_par par;
-       u32 pseudo_palette[256];
+       u32 pseudo_palette[16];
 };
 
 static int ffb_init_one(struct of_device *op)
index 267c1ff9ebd9b8b841bc448cbf8b0005c9df1710..a1258989859767106811fa7f50dae4498b75db50 100644 (file)
@@ -394,26 +394,18 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
 
        /* initialize GPIOs */
        imx_gpio_mode(PD6_PF_LSCLK);
-       imx_gpio_mode(PD10_PF_SPL_SPR);
        imx_gpio_mode(PD11_PF_CONTRAST);
        imx_gpio_mode(PD14_PF_FLM_VSYNC);
        imx_gpio_mode(PD13_PF_LP_HSYNC);
-       imx_gpio_mode(PD7_PF_REV);
-       imx_gpio_mode(PD8_PF_CLS);
-
-#ifndef CONFIG_MACH_PIMX1
-       /* on PiMX1 used as buffers enable signal
-        */
-       imx_gpio_mode(PD9_PF_PS);
-#endif
-
-#ifndef CONFIG_MACH_MX1FS2
-       /* on mx1fs2 this pin is used to (de)activate the display, so we need
-        * it as a normal gpio
-        */
        imx_gpio_mode(PD12_PF_ACD_OE);
-#endif
 
+       /* These are only needed for Sharp HR TFT displays */
+       if (fbi->pcr & PCR_SHARP) {
+               imx_gpio_mode(PD7_PF_REV);
+               imx_gpio_mode(PD8_PF_CLS);
+               imx_gpio_mode(PD9_PF_PS);
+               imx_gpio_mode(PD10_PF_SPL_SPR);
+       }
 }
 
 #ifdef CONFIG_PM
@@ -476,7 +468,6 @@ static int __init imxfb_init_fbinfo(struct device *dev)
 
        info->fbops                     = &imxfb_ops;
        info->flags                     = FBINFO_FLAG_DEFAULT;
-       info->pseudo_palette            = (fbi + 1);
 
        fbi->rgb[RGB_16]                = &def_rgb_16;
        fbi->rgb[RGB_8]                 = &def_rgb_8;
@@ -499,6 +490,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
        info->var.sync                  = inf->sync;
        info->var.grayscale             = inf->cmap_greyscale;
        fbi->cmap_inverse               = inf->cmap_inverse;
+       fbi->cmap_static                = inf->cmap_static;
        fbi->pcr                        = inf->pcr;
        fbi->lscr1                      = inf->lscr1;
        fbi->dmacr                      = inf->dmacr;
index bd30aba242d07643722ef8d58aa1870128a3bec3..731d7a5c5aa2abf960f1ae4e8534a06d703e7d58 100644 (file)
@@ -1286,34 +1286,36 @@ static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        if (regno >= fb->cmap.len || regno > 255)
                return -EINVAL;
 
-       switch (fb->var.bits_per_pixel) {
-       case 8:
+       if (fb->var.bits_per_pixel <= 8) {
                outb(regno, 0x3c8);
 
                outb(red >> 10, 0x3c9);
                outb(green >> 10, 0x3c9);
                outb(blue >> 10, 0x3c9);
-               break;
-       case 16:
-               ((u32 *) fb->pseudo_palette)[regno] =
+       } else if (regno < 16) {
+               switch (fb->var.bits_per_pixel) {
+               case 16:
+                       ((u32 *) fb->pseudo_palette)[regno] =
                                ((red & 0xf800)) | ((green & 0xfc00) >> 5) |
                                ((blue & 0xf800) >> 11);
-               break;
-       case 24:
-               ((u32 *) fb->pseudo_palette)[regno] =
+                       break;
+               case 24:
+                       ((u32 *) fb->pseudo_palette)[regno] =
                                ((red & 0xff00) << 8) | ((green & 0xff00)) |
                                ((blue & 0xff00) >> 8);
-               break;
+                       break;
 #ifdef NO_32BIT_SUPPORT_YET
-       case 32:
-               ((u32 *) fb->pseudo_palette)[regno] =
+               case 32:
+                       ((u32 *) fb->pseudo_palette)[regno] =
                                ((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
                                ((green & 0xff00)) | ((blue & 0xff00) >> 8);
-               break;
+                       break;
 #endif
-       default:
-               return 1;
+               default:
+                       return 1;
+               }
        }
+
        return 0;
 }
 
index ab5e66890e4e7f3f60a04e0cfda7acd841c828f8..0a04483aa3e0272c59b9ad86165a668a0d2e28f5 100644 (file)
@@ -183,15 +183,17 @@ static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
                index = PM2VR_RD_INDEXED_DATA;
                break;
        }       
-       mb();
+       wmb();
        pm2_WR(p, index, v);
+       wmb();
 }
 
 static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
 {
        pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
-       mb();
+       wmb();
        pm2_WR(p, PM2VR_RD_INDEXED_DATA, v);
+       wmb();
 }
 
 #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
@@ -466,11 +468,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
                WAIT_FIFO(par, 8);
                pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
                pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
-               wmb();
                pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
                pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
                pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
-               wmb();
                pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
                rmb();
                for (i = 256;
@@ -483,12 +483,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
                pm2_mnp(clk, &m, &n, &p);
                WAIT_FIFO(par, 10);
                pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
-               wmb();
                pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
                pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
-               wmb();
                pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
-               wmb();
                pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
                rmb();
                for (i = 256;
@@ -509,12 +506,9 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
                pm2_mnp(clk, &m, &n, &p);
                WAIT_FIFO(par, 8);
                pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
-               wmb();
                pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
                pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
-               wmb();
                pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
-               wmb();
                pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
                rmb();
                for (i = 256;
@@ -1066,10 +1060,9 @@ static void pm2fb_block_op(struct fb_info* info, int copy,
 
        if (!w || !h)
                return;
-       WAIT_FIFO(par, 6);
+       WAIT_FIFO(par, 5);
        pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
                PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
-       pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
        if (copy)
                pm2_WR(par, PM2R_FB_SOURCE_DELTA,
                        ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
index c77a1a1fd46bcf2aaf4870693dca3f4a15c5a207..b52e883f0a52823f9c258c4906f33a131b5ce0b3 100644 (file)
  */
 static char *mode_option __devinitdata;
 
-/*
- *  If your driver supports multiple boards, you should make the
- *  below data types arrays, or allocate them dynamically (using kmalloc()).
- */
-
 /*
  * This structure defines the hardware state of the graphics card. Normally
  * you place this in a header file in linux/include/video. This file usually
@@ -67,7 +62,7 @@ struct pm3_par {
        unsigned char   __iomem *v_regs;/* virtual address of p_regs */
        u32             video;          /* video flags before blanking */
        u32             base;           /* screen base (xoffset+yoffset) in 128 bits unit */
-       u32             palette[16];
+       u32             palette[16];
 };
 
 /*
@@ -104,36 +99,28 @@ static inline void PM3_WAIT(struct pm3_par *par, u32 n)
        while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
 }
 
-static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
-{
-       if (par->v_regs) {
-               mb();
-               PM3_WAIT(par, 1);
-               wmb();
-               PM3_WRITE_REG(par, off, v);
-       }
-}
-
-static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
-{
-       PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
-       PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
-}
-
 static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
 {
-       PM3_SET_INDEX(par, r);
+       PM3_WAIT(par, 3);
+       PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff);
+       PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff);
        wmb();
        PM3_WRITE_REG(par, PM3RD_IndexedData, v);
+       wmb();
 }
 
 static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
                        unsigned char r, unsigned char g, unsigned char b)
 {
-       PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
-       PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r);
-       PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g);
-       PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b);
+       PM3_WAIT(par, 4);
+       PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
+       wmb();
+       PM3_WRITE_REG(par, PM3RD_PaletteData, r);
+       wmb();
+       PM3_WRITE_REG(par, PM3RD_PaletteData, g);
+       wmb();
+       PM3_WRITE_REG(par, PM3RD_PaletteData, b);
+       wmb();
 }
 
 static void pm3fb_clear_colormap(struct pm3_par *par,
@@ -141,7 +128,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
 {
        int i;
 
-       for (i = 0; i < 256 ; i++) /* fill color map with white */
+       for (i = 0; i < 256 ; i++)
                pm3fb_set_color(par, i, r, g, b);
 
 }
@@ -175,19 +162,26 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
        }
 }
 
-static inline int pm3fb_shift_bpp(unsigned long depth, int v)
+static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
 {
-       switch (depth) {
+       if ( var->bits_per_pixel == 16 )
+               return var->red.length + var->green.length
+                       + var->blue.length;
+
+       return var->bits_per_pixel;
+}
+
+static inline int pm3fb_shift_bpp(unsigned bpp, int v)
+{
+       switch (bpp) {
        case 8:
                return (v >> 4);
-       case 12:
-       case 15:
        case 16:
                return (v >> 3);
        case 32:
                return (v >> 2);
        }
-       DPRINTK("Unsupported depth %ld\n", depth);
+       DPRINTK("Unsupported depth %u\n", bpp);
        return 0;
 }
 
@@ -206,56 +200,50 @@ static void pm3fb_write_mode(struct fb_info *info)
        const u32 vbend = vsend + info->var.upper_margin;
        const u32 vtotal = info->var.yres + vbend;
        const u32 width = (info->var.xres_virtual + 7) & ~7;
-
-       PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
-       PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000);
-       PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000);
-       PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007);
-
-       PM3_SLOW_WRITE_REG(par, PM3HTotal,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         htotal - 1));
-       PM3_SLOW_WRITE_REG(par, PM3HsEnd,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         hsend));
-       PM3_SLOW_WRITE_REG(par, PM3HsStart,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         hsstart));
-       PM3_SLOW_WRITE_REG(par, PM3HbEnd,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         hbend));
-       PM3_SLOW_WRITE_REG(par, PM3HgEnd,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         hbend));
-       PM3_SLOW_WRITE_REG(par, PM3ScreenStride,
-                          pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                         width));
-       PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1);
-       PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1);
-       PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
-       PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);
-
-       switch (info->var.bits_per_pixel) {
+       const unsigned bpp = info->var.bits_per_pixel;
+
+       PM3_WAIT(par, 20);
+       PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
+       PM3_WRITE_REG(par, PM3Aperture0, 0x00000000);
+       PM3_WRITE_REG(par, PM3Aperture1, 0x00000000);
+       PM3_WRITE_REG(par, PM3FIFODis, 0x00000007);
+
+       PM3_WRITE_REG(par, PM3HTotal,
+                          pm3fb_shift_bpp(bpp, htotal - 1));
+       PM3_WRITE_REG(par, PM3HsEnd,
+                          pm3fb_shift_bpp(bpp, hsend));
+       PM3_WRITE_REG(par, PM3HsStart,
+                          pm3fb_shift_bpp(bpp, hsstart));
+       PM3_WRITE_REG(par, PM3HbEnd,
+                          pm3fb_shift_bpp(bpp, hbend));
+       PM3_WRITE_REG(par, PM3HgEnd,
+                          pm3fb_shift_bpp(bpp, hbend));
+       PM3_WRITE_REG(par, PM3ScreenStride,
+                          pm3fb_shift_bpp(bpp, width));
+       PM3_WRITE_REG(par, PM3VTotal, vtotal - 1);
+       PM3_WRITE_REG(par, PM3VsEnd, vsend - 1);
+       PM3_WRITE_REG(par, PM3VsStart, vsstart - 1);
+       PM3_WRITE_REG(par, PM3VbEnd, vbend);
+
+       switch (bpp) {
        case 8:
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+               PM3_WRITE_REG(par, PM3ByAperture1Mode,
                                   PM3ByApertureMode_PIXELSIZE_8BIT);
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+               PM3_WRITE_REG(par, PM3ByAperture2Mode,
                                   PM3ByApertureMode_PIXELSIZE_8BIT);
                break;
 
-       case 12:
-       case 15:
        case 16:
 #ifndef __BIG_ENDIAN
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+               PM3_WRITE_REG(par, PM3ByAperture1Mode,
                                   PM3ByApertureMode_PIXELSIZE_16BIT);
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+               PM3_WRITE_REG(par, PM3ByAperture2Mode,
                                   PM3ByApertureMode_PIXELSIZE_16BIT);
 #else
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+               PM3_WRITE_REG(par, PM3ByAperture1Mode,
                                   PM3ByApertureMode_PIXELSIZE_16BIT |
                                   PM3ByApertureMode_BYTESWAP_BADC);
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+               PM3_WRITE_REG(par, PM3ByAperture2Mode,
                                   PM3ByApertureMode_PIXELSIZE_16BIT |
                                   PM3ByApertureMode_BYTESWAP_BADC);
 #endif /* ! __BIG_ENDIAN */
@@ -263,23 +251,22 @@ static void pm3fb_write_mode(struct fb_info *info)
 
        case 32:
 #ifndef __BIG_ENDIAN
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+               PM3_WRITE_REG(par, PM3ByAperture1Mode,
                                   PM3ByApertureMode_PIXELSIZE_32BIT);
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+               PM3_WRITE_REG(par, PM3ByAperture2Mode,
                                   PM3ByApertureMode_PIXELSIZE_32BIT);
 #else
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+               PM3_WRITE_REG(par, PM3ByAperture1Mode,
                                   PM3ByApertureMode_PIXELSIZE_32BIT |
                                   PM3ByApertureMode_BYTESWAP_DCBA);
-               PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+               PM3_WRITE_REG(par, PM3ByAperture2Mode,
                                   PM3ByApertureMode_PIXELSIZE_32BIT |
                                   PM3ByApertureMode_BYTESWAP_DCBA);
 #endif /* ! __BIG_ENDIAN */
                break;
 
        default:
-               DPRINTK("Unsupported depth %d\n",
-                       info->var.bits_per_pixel);
+               DPRINTK("Unsupported depth %d\n", bpp);
                break;
        }
 
@@ -296,14 +283,15 @@ static void pm3fb_write_mode(struct fb_info *info)
                           PM3VideoControl_VSYNC_MASK);
                video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
                         PM3VideoControl_VSYNC_ACTIVE_HIGH;
-               PM3_SLOW_WRITE_REG(par, PM3VideoControl, video);
+               PM3_WRITE_REG(par, PM3VideoControl, video);
        }
-       PM3_SLOW_WRITE_REG(par, PM3VClkCtl,
+       PM3_WRITE_REG(par, PM3VClkCtl,
                           (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
-       PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
-       PM3_SLOW_WRITE_REG(par, PM3ChipConfig,
+       PM3_WRITE_REG(par, PM3ScreenBase, par->base);
+       PM3_WRITE_REG(par, PM3ChipConfig,
                           (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
 
+       wmb();
        {
                unsigned char uninitialized_var(m);     /* ClkPreScale */
                unsigned char uninitialized_var(n);     /* ClkFeedBackScale */
@@ -337,7 +325,7 @@ static void pm3fb_write_mode(struct fb_info *info)
 
        PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
 
-       switch (info->var.bits_per_pixel) {
+       switch (pm3fb_depth(&info->var)) {
        case 8:
                PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
                                  PM3RD_PixelSize_8_BIT_PIXELS);
@@ -393,57 +381,44 @@ static void pm3fb_write_mode(struct fb_info *info)
  * hardware independent functions
  */
 int pm3fb_init(void);
-int pm3fb_setup(char*);
 
 static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        u32 lpitch;
+       unsigned bpp = var->red.length + var->green.length
+                       + var->blue.length + var->transp.length;
 
-       var->transp.offset = 0;
-       var->transp.length = 0;
-       switch(var->bits_per_pixel) {
-       case 8:
-               var->red.length = var->green.length = var->blue.length = 8;
-               var->red.offset = var->green.offset = var->blue.offset = 0;
-               break;
-       case 12:
-               var->red.offset   = 8;
-               var->red.length   = 4;
-               var->green.offset = 4;
-               var->green.length = 4;
-               var->blue.offset  = 0;
-               var->blue.length  = 4;
-               var->transp.offset = 12;
-               var->transp.length = 4;
-       case 15:
-               var->red.offset   = 10;
-               var->red.length   = 5;
-               var->green.offset = 5;
-               var->green.length = 5;
-               var->blue.offset  = 0;
-               var->blue.length  = 5;
-               var->transp.offset = 15;
-               var->transp.length = 1;
-               break;
-       case 16:
-               var->red.offset   = 11;
-               var->red.length   = 5;
-               var->green.offset = 5;
-               var->green.length = 6;
-               var->blue.offset  = 0;
-               var->blue.length  = 5;
-               break;
-       case 32:
-               var->transp.offset = 24;
-               var->transp.length = 8;
-               var->red.offset   = 16;
-               var->green.offset = 8;
-               var->blue.offset  = 0;
-               var->red.length = var->green.length = var->blue.length = 8;
-               break;
-       default:
-               DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
-               return -EINVAL;
+       if ( bpp != var->bits_per_pixel ) {
+               /* set predefined mode for bits_per_pixel settings */
+
+               switch(var->bits_per_pixel) {
+               case 8:
+                       var->red.length = var->green.length = var->blue.length = 8;
+                       var->red.offset = var->green.offset = var->blue.offset = 0;
+                       var->transp.offset = 0;
+                       var->transp.length = 0;
+                       break;
+               case 16:
+                       var->red.length = var->blue.length = 5;
+                       var->green.length = 6;
+                       var->transp.length = 0;
+                       break;
+               case 32:
+                       var->red.length = var->green.length = var->blue.length = 8;
+                       var->transp.length = 8;
+                       break;
+               default:
+                       DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+                       return -EINVAL;
+               }
+       }
+       /* it is assumed BGRA order */
+       if (var->bits_per_pixel > 8 )
+       {
+               var->blue.offset = 0;
+               var->green.offset = var->blue.length;
+               var->red.offset = var->green.offset + var->green.length;
+               var->transp.offset = var->red.offset + var->red.length;
        }
        var->height = var->width = -1;
 
@@ -502,10 +477,9 @@ static int pm3fb_set_par(struct fb_info *info)
 {
        struct pm3_par *par = info->par;
        const u32 xres = (info->var.xres + 31) & ~31;
-       const int depth = (info->var.bits_per_pixel + 7) & ~7;
+       const unsigned bpp = info->var.bits_per_pixel;
 
-       par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
-                                       (info->var.yoffset * xres)
+       par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
                                        + info->var.xoffset);
        par->video = 0;
 
@@ -524,18 +498,16 @@ static int pm3fb_set_par(struct fb_info *info)
        else
                par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
 
-       if (info->var.activate == FB_ACTIVATE_NOW)
+       if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
                par->video |= PM3VideoControl_ENABLE;
        else {
                par->video |= PM3VideoControl_DISABLE;
                DPRINTK("PM3Video disabled\n");
        }
-       switch (depth) {
+       switch (bpp) {
        case 8:
                par->video |= PM3VideoControl_PIXELSIZE_8BIT;
                break;
-       case 12:
-       case 15:
        case 16:
                par->video |= PM3VideoControl_PIXELSIZE_16BIT;
                break;
@@ -548,9 +520,9 @@ static int pm3fb_set_par(struct fb_info *info)
        }
 
        info->fix.visual =
-               (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+               (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
        info->fix.line_length = ((info->var.xres_virtual + 7)  & ~7)
-                                       * depth / 8;
+                                       * bpp / 8;
 
 /*     pm3fb_clear_memory(info, 0);*/
        pm3fb_clear_colormap(par, 0, 0, 0);
@@ -580,8 +552,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
         *   var->{color}.length contains length of bitfield
         *   {hardwarespecific} contains width of DAC
         *   pseudo_palette[X] is programmed to (X << red.offset) |
-        *                                    (X << green.offset) |
-        *                                    (X << blue.offset)
+        *                                      (X << green.offset) |
+        *                                      (X << blue.offset)
         *   RAMDAC[X] is programmed to (red, green, blue)
         *   color depth = SUM(var->{color}.length)
         *
@@ -621,7 +593,6 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
                case 8:
                        break;
                case 16:
-               case 24:
                case 32:
                        ((u32*)(info->pseudo_palette))[regno] = v;
                        break;
@@ -643,7 +614,8 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
        par->base = pm3fb_shift_bpp(var->bits_per_pixel,
                                        (var->yoffset * xres)
                                        + var->xoffset);
-       PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
+       PM3_WAIT(par, 1);
+       PM3_WRITE_REG(par, PM3ScreenBase, par->base);
        return 0;
 }
 
@@ -665,31 +637,31 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
 
        switch (blank_mode) {
        case FB_BLANK_UNBLANK:
-               video = video | PM3VideoControl_ENABLE;
+               video |= PM3VideoControl_ENABLE;
                break;
-       case FB_BLANK_NORMAL:   /* FIXME */
-               video = video & ~(PM3VideoControl_ENABLE);
+       case FB_BLANK_NORMAL:
+               video &= ~(PM3VideoControl_ENABLE);
                break;
        case FB_BLANK_HSYNC_SUSPEND:
-               video = video & ~(PM3VideoControl_HSYNC_MASK |
-                                 PM3VideoControl_BLANK_ACTIVE_LOW);
+               video &= ~(PM3VideoControl_HSYNC_MASK |
+                         PM3VideoControl_BLANK_ACTIVE_LOW);
                break;
        case FB_BLANK_VSYNC_SUSPEND:
-               video = video & ~(PM3VideoControl_VSYNC_MASK |
-                                 PM3VideoControl_BLANK_ACTIVE_LOW);
+               video &= ~(PM3VideoControl_VSYNC_MASK |
+                         PM3VideoControl_BLANK_ACTIVE_LOW);
                break;
        case FB_BLANK_POWERDOWN:
-               video = video & ~(PM3VideoControl_HSYNC_MASK |
-                                 PM3VideoControl_VSYNC_MASK |
-                                 PM3VideoControl_BLANK_ACTIVE_LOW);
+               video &= ~(PM3VideoControl_HSYNC_MASK |
+                         PM3VideoControl_VSYNC_MASK |
+                         PM3VideoControl_BLANK_ACTIVE_LOW);
                break;
        default:
                DPRINTK("Unsupported blanking %d\n", blank_mode);
                return 1;
        }
 
-       PM3_SLOW_WRITE_REG(par,PM3VideoControl, video);
-
+       PM3_WAIT(par, 1);
+       PM3_WRITE_REG(par,PM3VideoControl, video);
        return 0;
 }
 
@@ -703,9 +675,9 @@ static struct fb_ops pm3fb_ops = {
        .fb_set_par     = pm3fb_set_par,
        .fb_setcolreg   = pm3fb_setcolreg,
        .fb_pan_display = pm3fb_pan_display,
-       .fb_fillrect    = cfb_fillrect,         /* Needed !!! */
-       .fb_copyarea    = cfb_copyarea,         /* Needed !!! */
-       .fb_imageblit   = cfb_imageblit,        /* Needed !!! */
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
        .fb_blank       = pm3fb_blank,
 };
 
@@ -722,7 +694,7 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
        unsigned long   memsize = 0, tempBypass, i, temp1, temp2;
        unsigned char   __iomem *screen_mem;
 
-       pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */
+       pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
        /* Linear frame buffer - request region and map it. */
        if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
                                 "pm3fb smem")) {
@@ -744,7 +716,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
 
        DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
 
-       PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
+       PM3_WAIT(par, 1);
+       PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
 
        /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
        for (i = 0; i < 32; i++) {
@@ -765,10 +738,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
        if (memsize + 1 == i) {
                for (i = 0; i < 32; i++) {
                        /* Clear first 32MB ; 0 is 0, no need to byteswap */
-                       writel(0x0000000,
-                              (screen_mem + (i * 1048576)));
-                       mb();
+                       writel(0x0000000, (screen_mem + (i * 1048576)));
                }
+               wmb();
 
                for (i = 32; i < 64; i++) {
                        fb_writel(i * 0x00345678,
@@ -787,7 +759,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
        }
        DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
 
-       PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
+       PM3_WAIT(par, 1);
+       PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
 
        iounmap(screen_mem);
        release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@@ -890,7 +863,6 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
                goto err_exit_both;
        }
 
-       /* This has to been done !!! */
        if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
                retval = -ENOMEM;
                goto err_exit_both;
@@ -907,7 +879,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
        }
        printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
           info->fix.id);
-       pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
+       pci_set_drvdata(dev, info);
        return 0;
 
  err_exit_all:
@@ -949,8 +921,7 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
 
 static struct pci_device_id pm3fb_id_table[] = {
        { PCI_VENDOR_ID_3DLABS, 0x0a,
-         PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
-         0xff0000, 0 },
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
        { 0, }
 };
 
@@ -964,6 +935,22 @@ static struct pci_driver pm3fb_driver = {
 
 MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
 
+#ifndef MODULE
+       /*
+        *  Setup
+        */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+static int __init pm3fb_setup(char *options)
+{
+       /* Parse user speficied options (`video=pm3fb:') */
+       return 0;
+}
+#endif /* MODULE */
+
 int __init pm3fb_init(void)
 {
        /*
@@ -985,22 +972,6 @@ static void __exit pm3fb_exit(void)
        pci_unregister_driver(&pm3fb_driver);
 }
 
-#ifndef MODULE
-       /*
-        *  Setup
-        */
-
-/*
- * Only necessary if your driver takes special options,
- * otherwise we fall back on the generic fb_setup().
- */
-int __init pm3fb_setup(char *options)
-{
-       /* Parse user speficied options (`video=pm3fb:') */
-       return 0;
-}
-#endif /* MODULE */
-
 module_init(pm3fb_init);
 module_exit(pm3fb_exit);
 
index 9756a728b74f3e2dbb58d5ca0709b3b298266c06..9cf92ba5d6e309a16676ef6816271722f0eb09b3 100644 (file)
@@ -951,12 +951,14 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
 static struct fb_ops ps3fb_ops = {
        .fb_open        = ps3fb_open,
        .fb_release     = ps3fb_release,
+       .fb_read        = fb_sys_read,
+       .fb_write       = fb_sys_write,
        .fb_check_var   = ps3fb_check_var,
        .fb_set_par     = ps3fb_set_par,
        .fb_setcolreg   = ps3fb_setcolreg,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
+       .fb_fillrect    = sys_fillrect,
+       .fb_copyarea    = sys_copyarea,
+       .fb_imageblit   = sys_imageblit,
        .fb_mmap        = ps3fb_mmap,
        .fb_blank       = ps3fb_blank,
        .fb_ioctl       = ps3fb_ioctl,
index 836a612af977f167e67ff1a0f92fe4708bc6788d..64779e70408f9e8a0d25c0973a5f39558b70471d 100644 (file)
@@ -132,7 +132,6 @@ static struct fb_info info;
 static struct xxx_par __initdata current_par;
 
 int xxxfb_init(void);
-int xxxfb_setup(char*);
 
 /**
  *     xxxfb_open - Optional function. Called when the framebuffer is
@@ -975,6 +974,21 @@ static struct platform_device xxxfb_device = {
        .name = "xxxfb",
 };
 
+#ifndef MODULE
+    /*
+     *  Setup
+     */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+int __init xxxfb_setup(char *options)
+{
+    /* Parse user speficied options (`video=xxxfb:') */
+}
+#endif /* MODULE */
+
 static int __init xxxfb_init(void)
 {
        int ret;
@@ -1006,21 +1020,6 @@ static void __exit xxxfb_exit(void)
 }
 #endif /* CONFIG_PCI */
 
-#ifdef MODULE
-    /*
-     *  Setup
-     */
-
-/* 
- * Only necessary if your driver takes special options,
- * otherwise we fall back on the generic fb_setup().
- */
-int __init xxxfb_setup(char *options)
-{
-    /* Parse user speficied options (`video=xxxfb:') */
-}
-#endif /* MODULE */
-
 /* ------------------------------------------------------------------------- */
 
 
index 4316c7fe8e21c52d92fa4cca203bb796d7594a54..c3869a96ab5877162ea6e72960f7d0fdf73e9cd1 100644 (file)
@@ -28,7 +28,7 @@ struct s3d_info {
        unsigned int            depth;
        unsigned int            fb_size;
 
-       u32                     pseudo_palette[256];
+       u32                     pseudo_palette[16];
 };
 
 static int __devinit s3d_get_props(struct s3d_info *sp)
@@ -52,15 +52,14 @@ static int s3d_setcolreg(unsigned regno,
 {
        u32 value;
 
-       if (regno >= 256)
-               return 1;
+       if (regno < 16) {
+               red >>= 8;
+               green >>= 8;
+               blue >>= 8;
 
-       red >>= 8;
-       green >>= 8;
-       blue >>= 8;
-
-       value = (blue << 24) | (green << 16) | (red << 8);
-       ((u32 *)info->pseudo_palette)[regno] = value;
+               value = (blue << 24) | (green << 16) | (red << 8);
+               ((u32 *)info->pseudo_palette)[regno] = value;
+       }
 
        return 0;
 }
index 08880a62bfa3302e3983169b73dd461f6c50913d..71bf3f1f00bcf1b9f2aa018281494a9a2a6b0e72 100644 (file)
@@ -50,7 +50,7 @@ struct e3d_info {
        u32                     fb8_0_off;
        u32                     fb8_1_off;
 
-       u32                     pseudo_palette[256];
+       u32                     pseudo_palette[16];
 };
 
 static int __devinit e3d_get_props(struct e3d_info *ep)
@@ -126,7 +126,9 @@ static int e3d_setcolreg(unsigned regno,
        blue_8 = blue >> 8;
 
        value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8);
-       ((u32 *)info->pseudo_palette)[regno] = value;
+
+       if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16)
+               ((u32 *)info->pseudo_palette)[regno] = value;
 
 
        red_10 = red >> 6;
index 5e9755e464a15fcacde5393247a01740d54cd4b7..30c0b948852b06b473a8e87705bcbd87f726fb70 100644 (file)
@@ -778,9 +778,10 @@ err_enable_device:
 static void __devexit vt8623_pci_remove(struct pci_dev *dev)
 {
        struct fb_info *info = pci_get_drvdata(dev);
-       struct vt8623fb_info *par = info->par;
 
        if (info) {
+               struct vt8623fb_info *par = info->par;
+
 #ifdef CONFIG_MTRR
                if (par->mtrr_reg >= 0) {
                        mtrr_del(par->mtrr_reg, 0, 0);
index 5fc86ea20692ff0e12309c9bd459b80282a89a0c..003c49a490eb9034f21bb8b8f49d8d91b0eddee6 100644 (file)
@@ -660,7 +660,7 @@ int __init w100fb_probe(struct platform_device *pdev)
                        err = -ENODEV;
                        goto out;
        }
-       printk(" at 0x%08lx.\n", mem->start+W100_CFG_BASE);
+       printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE);
 
        /* Remap the framebuffer */
        remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE);
@@ -753,10 +753,14 @@ int __init w100fb_probe(struct platform_device *pdev)
                goto out;
        }
 
-       device_create_file(&pdev->dev, &dev_attr_fastpllclk);
-       device_create_file(&pdev->dev, &dev_attr_reg_read);
-       device_create_file(&pdev->dev, &dev_attr_reg_write);
-       device_create_file(&pdev->dev, &dev_attr_flip);
+       err = device_create_file(&pdev->dev, &dev_attr_fastpllclk);
+       err |= device_create_file(&pdev->dev, &dev_attr_reg_read);
+       err |= device_create_file(&pdev->dev, &dev_attr_reg_write);
+       err |= device_create_file(&pdev->dev, &dev_attr_flip);
+
+       if (err != 0)
+               printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n",
+                               info->node, err);
 
        printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
        return 0;
index 2dac3ad2c44b6c1110452208826dfac0186b901b..2c55dd94a1de573c9e4169a3cbb3c993dc6422b9 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/rxrpc.h>
 #include <linux/key.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
+
 #include "afs.h"
 #include "afs_vl.h"
 
index 7b0265d7f3a84a88f537b8e9174a27e4c3e650b6..861141b4f6d6f4cbbfcd96366074db8e4adbeaf3 100644 (file)
@@ -558,7 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                        if (!realdatastart)
                                realdatastart = (unsigned long) -ENOMEM;
                        printk("Unable to allocate RAM for process data, errno %d\n",
-                                       (int)-datapos);
+                                       (int)-realdatastart);
                        do_munmap(current->mm, textpos, text_len);
                        ret = realdatastart;
                        goto err;
index 1de2331db8445d0923dfd17e6608d1357f466b3c..4db6216e5266a590b0330ff4c8c2868eb84c1013 100644 (file)
@@ -1544,9 +1544,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
        compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
 {
        fd_set_bits fds;
-       char *bits;
+       void *bits;
        int size, max_fds, ret = -EINVAL;
        struct fdtable *fdt;
+       long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
 
        if (n < 0)
                goto out_nofds;
@@ -1564,11 +1565,14 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
         * since we used fdset we need to allocate memory in units of
         * long-words.
         */
-       ret = -ENOMEM;
        size = FDS_BYTES(n);
-       bits = kmalloc(6 * size, GFP_KERNEL);
-       if (!bits)
-               goto out_nofds;
+       bits = stack_fds;
+       if (size > sizeof(stack_fds) / 6) {
+               bits = kmalloc(6 * size, GFP_KERNEL);
+               ret = -ENOMEM;
+               if (!bits)
+                       goto out_nofds;
+       }
        fds.in      = (unsigned long *)  bits;
        fds.out     = (unsigned long *) (bits +   size);
        fds.ex      = (unsigned long *) (bits + 2*size);
@@ -1600,7 +1604,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
            compat_set_fd_set(n, exp, fds.res_ex))
                ret = -EFAULT;
 out:
-       kfree(bits);
+       if (bits != stack_fds)
+               kfree(bits);
 out_nofds:
        return ret;
 }
index 65643def31825d99fa7df8399871fd4e2d8b4144..6b44cdc96facd51030d8798f68e3cf68aecc0d4e 100644 (file)
@@ -1194,6 +1194,7 @@ static int vt_check(struct file *file)
 {
        struct tty_struct *tty;
        struct inode *inode = file->f_path.dentry->d_inode;
+       struct vc_data *vc;
        
        if (file->f_op->ioctl != tty_ioctl)
                return -EINVAL;
@@ -1204,12 +1205,16 @@ static int vt_check(struct file *file)
                                                        
        if (tty->driver->ioctl != vt_ioctl)
                return -EINVAL;
-       
+
+       vc = (struct vc_data *)tty->driver_data;
+       if (!vc_cons_allocated(vc->vc_num))     /* impossible? */
+               return -ENOIOCTLCMD;
+
        /*
         * To have permissions to do most of the vt ioctls, we either have
-        * to be the owner of the tty, or super-user.
+        * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
         */
-       if (current->signal->tty == tty || capable(CAP_SYS_ADMIN))
+       if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
                return 1;
        return 0;                                                    
 }
@@ -1310,16 +1315,28 @@ static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
        struct unimapdesc32 tmp;
        struct unimapdesc32 __user *user_ud = compat_ptr(arg);
        int perm = vt_check(file);
-       
-       if (perm < 0) return perm;
+       struct vc_data *vc;
+
+       if (perm < 0)
+               return perm;
        if (copy_from_user(&tmp, user_ud, sizeof tmp))
                return -EFAULT;
+       if (tmp.entries)
+               if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries),
+                               tmp.entry_ct*sizeof(struct unipair)))
+                       return -EFAULT;
+       vc = ((struct tty_struct *)file->private_data)->driver_data;
        switch (cmd) {
        case PIO_UNIMAP:
-               if (!perm) return -EPERM;
-               return con_set_unimap(vc_cons[fg_console].d, tmp.entry_ct, compat_ptr(tmp.entries));
+               if (!perm)
+                       return -EPERM;
+               return con_set_unimap(vc, tmp.entry_ct,
+                                               compat_ptr(tmp.entries));
        case GIO_UNIMAP:
-               return con_get_unimap(vc_cons[fg_console].d, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries));
+               if (!perm && fg_console != vc->vc_num)
+                       return -EPERM;
+               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
+                                               compat_ptr(tmp.entries));
        }
        return 0;
 }
index 9881b5c5de59b6f564435cc26dc17f5a638e32bc..59288d817078879ad36c1ece17a51208488d571e 100644 (file)
 #include <linux/fs_stack.h>
 #include "ecryptfs_kernel.h"
 
-/**
- * ecryptfs_llseek
- * @file: File we are seeking in
- * @offset: The offset to seek to
- * @origin: 2 - offset from i_size; 1 - offset from f_pos
- *
- * Returns the position we have seeked to, or negative on error
- */
-static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin)
-{
-       loff_t rv;
-       loff_t new_end_pos;
-       int rc;
-       int expanding_file = 0;
-       struct inode *inode = file->f_mapping->host;
-
-       /* If our offset is past the end of our file, we're going to
-        * need to grow it so we have a valid length of 0's */
-       new_end_pos = offset;
-       switch (origin) {
-       case 2:
-               new_end_pos += i_size_read(inode);
-               expanding_file = 1;
-               break;
-       case 1:
-               new_end_pos += file->f_pos;
-               if (new_end_pos > i_size_read(inode)) {
-                       ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
-                                       "> i_size_read(inode)(=[0x%.16x])\n",
-                                       new_end_pos, i_size_read(inode));
-                       expanding_file = 1;
-               }
-               break;
-       default:
-               if (new_end_pos > i_size_read(inode)) {
-                       ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
-                                       "> i_size_read(inode)(=[0x%.16x])\n",
-                                       new_end_pos, i_size_read(inode));
-                       expanding_file = 1;
-               }
-       }
-       ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos);
-       if (expanding_file) {
-               rc = ecryptfs_truncate(file->f_path.dentry, new_end_pos);
-               if (rc) {
-                       rv = rc;
-                       ecryptfs_printk(KERN_ERR, "Error on attempt to "
-                                       "truncate to (higher) offset [0x%.16x];"
-                                       " rc = [%d]\n", new_end_pos, rc);
-                       goto out;
-               }
-       }
-       rv = generic_file_llseek(file, offset, origin);
-out:
-       return rv;
-}
-
 /**
  * ecryptfs_read_update_atime
  *
@@ -425,7 +368,7 @@ const struct file_operations ecryptfs_dir_fops = {
 };
 
 const struct file_operations ecryptfs_main_fops = {
-       .llseek = ecryptfs_llseek,
+       .llseek = generic_file_llseek,
        .read = do_sync_read,
        .aio_read = ecryptfs_read_update_atime,
        .write = do_sync_write,
index 88ea6697908f511a1eadeffc4ee04ce3f9f93cf4..55cec98a84e75cf490143af46302a9495993f158 100644 (file)
@@ -376,9 +376,31 @@ out:
        return 0;
 }
 
+/**
+ * eCryptfs does not currently support holes. When writing after a
+ * seek past the end of the file, eCryptfs fills in 0's through to the
+ * current location. The code to fill in the 0's to all the
+ * intermediate pages calls ecryptfs_prepare_write_no_truncate().
+ */
+static int
+ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page,
+                                  unsigned from, unsigned to)
+{
+       int rc = 0;
+
+       if (from == 0 && to == PAGE_CACHE_SIZE)
+               goto out;       /* If we are writing a full page, it will be
+                                  up to date. */
+       if (!PageUptodate(page))
+               rc = ecryptfs_do_readpage(file, page, page->index);
+out:
+       return rc;
+}
+
 static int ecryptfs_prepare_write(struct file *file, struct page *page,
                                  unsigned from, unsigned to)
 {
+       loff_t pos;
        int rc = 0;
 
        if (from == 0 && to == PAGE_CACHE_SIZE)
@@ -386,6 +408,16 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
                                   up to date. */
        if (!PageUptodate(page))
                rc = ecryptfs_do_readpage(file, page, page->index);
+       pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+       if (pos > i_size_read(page->mapping->host)) {
+               rc = ecryptfs_truncate(file->f_path.dentry, pos);
+               if (rc) {
+                       printk(KERN_ERR "Error on attempt to "
+                              "truncate to (higher) offset [%lld];"
+                              " rc = [%d]\n", pos, rc);
+                       goto out;
+               }
+       }
 out:
        return rc;
 }
@@ -744,10 +776,10 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
                rc = PTR_ERR(tmp_page);
                goto out;
        }
-       rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros);
-       if (rc) {
+       if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start,
+                                                    (start + num_zeros)))) {
                ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
-                               "to remainder of page at index [0x%.16x]\n",
+                               "to page at index [0x%.16x]\n",
                                index);
                page_cache_release(tmp_page);
                goto out;
index 0b685888ff6f9b1c51c860191828adbde4950fe6..f20561ff4528f21ad7a36d35d56513346c5f740b 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -134,6 +134,9 @@ asmlinkage long sys_uselib(const char __user * library)
        if (error)
                goto out;
 
+       error = -EACCES;
+       if (nd.mnt->mnt_flags & MNT_NOEXEC)
+               goto exit;
        error = -EINVAL;
        if (!S_ISREG(nd.dentry->d_inode->i_mode))
                goto exit;
index 8a23483ca8d0c3668e171bbc53c7a629a2403876..3b64bb16c727784d0a5f6b6f7c12e0ac30aa4cd2 100644 (file)
 void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
                unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
 {
-        struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+       struct ext4_super_block *es = EXT4_SB(sb)->s_es;
        ext4_grpblk_t offset;
 
-        blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+       blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
        offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
        if (offsetp)
                *offsetp = offset;
        if (blockgrpp)
-               *blockgrpp = blocknr;
+               *blockgrpp = blocknr;
 
 }
 
index a0f0c04e79b2bb47ca670fe7edd9875afb937d97..b9ce24129070bff5cee547a333139d9a4645d2c7 100644 (file)
@@ -374,7 +374,7 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc
                                       le32_to_cpu(ix[-1].ei_block));
                        }
                        BUG_ON(k && le32_to_cpu(ix->ei_block)
-                                          <= le32_to_cpu(ix[-1].ei_block));
+                                          <= le32_to_cpu(ix[-1].ei_block));
                        if (block < le32_to_cpu(ix->ei_block))
                                break;
                        chix = ix;
@@ -423,8 +423,8 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
 
        path->p_ext = l - 1;
        ext_debug("  -> %d:%llu:%d ",
-                       le32_to_cpu(path->p_ext->ee_block),
-                       ext_pblock(path->p_ext),
+                       le32_to_cpu(path->p_ext->ee_block),
+                       ext_pblock(path->p_ext),
                        le16_to_cpu(path->p_ext->ee_len));
 
 #ifdef CHECK_BINSEARCH
@@ -435,7 +435,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
                chex = ex = EXT_FIRST_EXTENT(eh);
                for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ex++) {
                        BUG_ON(k && le32_to_cpu(ex->ee_block)
-                                         <= le32_to_cpu(ex[-1].ee_block));
+                                         <= le32_to_cpu(ex[-1].ee_block));
                        if (block < le32_to_cpu(ex->ee_block))
                                break;
                        chex = ex;
@@ -577,7 +577,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
        curp->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(curp->p_hdr->eh_entries)+1);
 
        BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries)
-                            > le16_to_cpu(curp->p_hdr->eh_max));
+                            > le16_to_cpu(curp->p_hdr->eh_max));
        BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr));
 
        err = ext4_ext_dirty(handle, inode, curp);
@@ -621,12 +621,12 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                border = path[depth].p_ext[1].ee_block;
                ext_debug("leaf will be split."
                                " next leaf starts at %d\n",
-                                 le32_to_cpu(border));
+                                 le32_to_cpu(border));
        } else {
                border = newext->ee_block;
                ext_debug("leaf will be added."
                                " next leaf starts at %d\n",
-                               le32_to_cpu(border));
+                               le32_to_cpu(border));
        }
 
        /*
@@ -684,9 +684,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
        while (path[depth].p_ext <=
                        EXT_MAX_EXTENT(path[depth].p_hdr)) {
                ext_debug("move %d:%llu:%d in new leaf %llu\n",
-                               le32_to_cpu(path[depth].p_ext->ee_block),
-                               ext_pblock(path[depth].p_ext),
-                               le16_to_cpu(path[depth].p_ext->ee_len),
+                               le32_to_cpu(path[depth].p_ext->ee_block),
+                               ext_pblock(path[depth].p_ext),
+                               le16_to_cpu(path[depth].p_ext->ee_len),
                                newblock);
                /*memmove(ex++, path[depth].p_ext++,
                                sizeof(struct ext4_extent));
@@ -765,9 +765,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                                EXT_LAST_INDEX(path[i].p_hdr));
                while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
                        ext_debug("%d: move %d:%d in new index %llu\n", i,
-                                       le32_to_cpu(path[i].p_idx->ei_block),
-                                       idx_pblock(path[i].p_idx),
-                                       newblock);
+                                       le32_to_cpu(path[i].p_idx->ei_block),
+                                       idx_pblock(path[i].p_idx),
+                                       newblock);
                        /*memmove(++fidx, path[i].p_idx++,
                                        sizeof(struct ext4_extent_idx));
                        neh->eh_entries++;
@@ -1127,6 +1127,55 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
        return 0;
 }
 
+/*
+ * check if a portion of the "newext" extent overlaps with an
+ * existing extent.
+ *
+ * If there is an overlap discovered, it updates the length of the newext
+ * such that there will be no overlap, and then returns 1.
+ * If there is no overlap found, it returns 0.
+ */
+unsigned int ext4_ext_check_overlap(struct inode *inode,
+                                   struct ext4_extent *newext,
+                                   struct ext4_ext_path *path)
+{
+       unsigned long b1, b2;
+       unsigned int depth, len1;
+       unsigned int ret = 0;
+
+       b1 = le32_to_cpu(newext->ee_block);
+       len1 = le16_to_cpu(newext->ee_len);
+       depth = ext_depth(inode);
+       if (!path[depth].p_ext)
+               goto out;
+       b2 = le32_to_cpu(path[depth].p_ext->ee_block);
+
+       /*
+        * get the next allocated block if the extent in the path
+        * is before the requested block(s) 
+        */
+       if (b2 < b1) {
+               b2 = ext4_ext_next_allocated_block(path);
+               if (b2 == EXT_MAX_BLOCK)
+                       goto out;
+       }
+
+       /* check for wrap through zero */
+       if (b1 + len1 < b1) {
+               len1 = EXT_MAX_BLOCK - b1;
+               newext->ee_len = cpu_to_le16(len1);
+               ret = 1;
+       }
+
+       /* check for overlap */
+       if (b1 + len1 > b2) {
+               newext->ee_len = cpu_to_le16(b2 - b1);
+               ret = 1;
+       }
+out:
+       return ret;
+}
+
 /*
  * ext4_ext_insert_extent:
  * tries to merge requsted extent into the existing extent or
@@ -1212,12 +1261,12 @@ has_space:
        if (!nearex) {
                /* there is no extent in this leaf, create first one */
                ext_debug("first extent in the leaf: %d:%llu:%d\n",
-                               le32_to_cpu(newext->ee_block),
-                               ext_pblock(newext),
-                               le16_to_cpu(newext->ee_len));
+                               le32_to_cpu(newext->ee_block),
+                               ext_pblock(newext),
+                               le16_to_cpu(newext->ee_len));
                path[depth].p_ext = EXT_FIRST_EXTENT(eh);
        } else if (le32_to_cpu(newext->ee_block)
-                          > le32_to_cpu(nearex->ee_block)) {
+                          > le32_to_cpu(nearex->ee_block)) {
 /*             BUG_ON(newext->ee_block == nearex->ee_block); */
                if (nearex != EXT_LAST_EXTENT(eh)) {
                        len = EXT_MAX_EXTENT(eh) - nearex;
@@ -1225,9 +1274,9 @@ has_space:
                        len = len < 0 ? 0 : len;
                        ext_debug("insert %d:%llu:%d after: nearest 0x%p, "
                                        "move %d from 0x%p to 0x%p\n",
-                                       le32_to_cpu(newext->ee_block),
-                                       ext_pblock(newext),
-                                       le16_to_cpu(newext->ee_len),
+                                       le32_to_cpu(newext->ee_block),
+                                       ext_pblock(newext),
+                                       le16_to_cpu(newext->ee_len),
                                        nearex, len, nearex + 1, nearex + 2);
                        memmove(nearex + 2, nearex + 1, len);
                }
@@ -1358,9 +1407,9 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block,
                        cbex.ec_start = 0;
                        cbex.ec_type = EXT4_EXT_CACHE_GAP;
                } else {
-                       cbex.ec_block = le32_to_cpu(ex->ee_block);
-                       cbex.ec_len = le16_to_cpu(ex->ee_len);
-                       cbex.ec_start = ext_pblock(ex);
+                       cbex.ec_block = le32_to_cpu(ex->ee_block);
+                       cbex.ec_len = le16_to_cpu(ex->ee_len);
+                       cbex.ec_start = ext_pblock(ex);
                        cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
                }
 
@@ -1431,16 +1480,16 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
                len = le32_to_cpu(ex->ee_block) - block;
                ext_debug("cache gap(before): %lu [%lu:%lu]",
                                (unsigned long) block,
-                               (unsigned long) le32_to_cpu(ex->ee_block),
-                               (unsigned long) le16_to_cpu(ex->ee_len));
+                               (unsigned long) le32_to_cpu(ex->ee_block),
+                               (unsigned long) le16_to_cpu(ex->ee_len));
        } else if (block >= le32_to_cpu(ex->ee_block)
-                           + le16_to_cpu(ex->ee_len)) {
-               lblock = le32_to_cpu(ex->ee_block)
-                        + le16_to_cpu(ex->ee_len);
+                           + le16_to_cpu(ex->ee_len)) {
+               lblock = le32_to_cpu(ex->ee_block)
+                        + le16_to_cpu(ex->ee_len);
                len = ext4_ext_next_allocated_block(path);
                ext_debug("cache gap(after): [%lu:%lu] %lu",
-                               (unsigned long) le32_to_cpu(ex->ee_block),
-                               (unsigned long) le16_to_cpu(ex->ee_len),
+                               (unsigned long) le32_to_cpu(ex->ee_block),
+                               (unsigned long) le16_to_cpu(ex->ee_len),
                                (unsigned long) block);
                BUG_ON(len == lblock);
                len = len - lblock;
@@ -1468,9 +1517,9 @@ ext4_ext_in_cache(struct inode *inode, unsigned long block,
        BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
                        cex->ec_type != EXT4_EXT_CACHE_EXTENT);
        if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) {
-               ex->ee_block = cpu_to_le32(cex->ec_block);
+               ex->ee_block = cpu_to_le32(cex->ec_block);
                ext4_ext_store_pblock(ex, cex->ec_start);
-               ex->ee_len = cpu_to_le16(cex->ec_len);
+               ex->ee_len = cpu_to_le16(cex->ec_len);
                ext_debug("%lu cached by %lu:%lu:%llu\n",
                                (unsigned long) block,
                                (unsigned long) cex->ec_block,
@@ -1956,9 +2005,9 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                        /* we should allocate requested block */
                } else if (goal == EXT4_EXT_CACHE_EXTENT) {
                        /* block is already allocated */
-                       newblock = iblock
-                                  - le32_to_cpu(newex.ee_block)
-                                  + ext_pblock(&newex);
+                       newblock = iblock
+                                  - le32_to_cpu(newex.ee_block)
+                                  + ext_pblock(&newex);
                        /* number of remaining blocks in the extent */
                        allocated = le16_to_cpu(newex.ee_len) -
                                        (iblock - le32_to_cpu(newex.ee_block));
@@ -1987,7 +2036,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 
        ex = path[depth].p_ext;
        if (ex) {
-               unsigned long ee_block = le32_to_cpu(ex->ee_block);
+               unsigned long ee_block = le32_to_cpu(ex->ee_block);
                ext4_fsblk_t ee_start = ext_pblock(ex);
                unsigned short ee_len  = le16_to_cpu(ex->ee_len);
 
@@ -2000,7 +2049,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                if (ee_len > EXT_MAX_LEN)
                        goto out2;
                /* if found extent covers block, simply return it */
-               if (iblock >= ee_block && iblock < ee_block + ee_len) {
+               if (iblock >= ee_block && iblock < ee_block + ee_len) {
                        newblock = iblock - ee_block + ee_start;
                        /* number of remaining blocks in the extent */
                        allocated = ee_len - (iblock - ee_block);
@@ -2031,7 +2080,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 
        /* allocate new block */
        goal = ext4_ext_find_goal(inode, path, iblock);
-       allocated = max_blocks;
+
+       /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */
+       newex.ee_block = cpu_to_le32(iblock);
+       newex.ee_len = cpu_to_le16(max_blocks);
+       err = ext4_ext_check_overlap(inode, &newex, path);
+       if (err)
+               allocated = le16_to_cpu(newex.ee_len);
+       else
+               allocated = max_blocks;
        newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err);
        if (!newblock)
                goto out2;
@@ -2039,12 +2096,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                        goal, newblock, allocated);
 
        /* try to insert new extent into found leaf and return */
-       newex.ee_block = cpu_to_le32(iblock);
        ext4_ext_store_pblock(&newex, newblock);
        newex.ee_len = cpu_to_le16(allocated);
        err = ext4_ext_insert_extent(handle, inode, path, &newex);
-       if (err)
+       if (err) {
+               /* free data blocks we just allocated */
+               ext4_free_blocks(handle, inode, ext_pblock(&newex),
+                                       le16_to_cpu(newex.ee_len));
                goto out2;
+       }
 
        if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize)
                EXT4_I(inode)->i_disksize = inode->i_size;
@@ -2157,11 +2217,3 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
 
        return needed;
 }
-
-EXPORT_SYMBOL(ext4_mark_inode_dirty);
-EXPORT_SYMBOL(ext4_ext_invalidate_cache);
-EXPORT_SYMBOL(ext4_ext_insert_extent);
-EXPORT_SYMBOL(ext4_ext_walk_space);
-EXPORT_SYMBOL(ext4_ext_find_goal);
-EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert);
-
index b34182b6ee4d1ea9cba530ea5dac87a787a8b7c1..0bcf62a750ffe29f788b5eb9d1c9b209ec8d3f54 100644 (file)
@@ -255,8 +255,8 @@ static int verify_chain(Indirect *from, Indirect *to)
  *     @inode: inode in question (we are only interested in its superblock)
  *     @i_block: block number to be parsed
  *     @offsets: array to store the offsets in
- *      @boundary: set this non-zero if the referred-to block is likely to be
- *             followed (on disk) by an indirect block.
+ *     @boundary: set this non-zero if the referred-to block is likely to be
+ *            followed (on disk) by an indirect block.
  *
  *     To store the locations of file's data ext4 uses a data structure common
  *     for UNIX filesystems - tree of pointers anchored in the inode, with
index 4ec57be5baf5df659a4f9c2d9330c8bfbe10c796..2811e5720ad019d18e9976ac8afc21e3c885768b 100644 (file)
@@ -46,7 +46,7 @@
  */
 #define NAMEI_RA_CHUNKS  2
 #define NAMEI_RA_BLOCKS  4
-#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_SIZE       (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
 #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
 static struct buffer_head *ext4_append(handle_t *handle,
@@ -241,7 +241,7 @@ static inline unsigned dx_node_limit (struct inode *dir)
 static void dx_show_index (char * label, struct dx_entry *entries)
 {
        int i, n = dx_get_count (entries);
-        printk("%s index ", label);
+       printk("%s index ", label);
        for (i = 0; i < n; i++) {
                printk("%x->%u ", i? dx_get_hash(entries + i) :
                                0, dx_get_block(entries + i));
index cb9afdd0e26e5f8f458329aaab3e04be6daf9a5c..175b68c609685fb06742caf6bed160ca7a98d68b 100644 (file)
@@ -1985,7 +1985,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
 
        if (bd_claim(bdev, sb)) {
                printk(KERN_ERR
-                       "EXT4: failed to claim external journal device.\n");
+                       "EXT4: failed to claim external journal device.\n");
                blkdev_put(bdev);
                return NULL;
        }
index 8890eba1db524dbd020a5f32554c645f3efab809..bd5a772d8ccf09f09eee4310c4ce2174095f1314 100644 (file)
@@ -485,7 +485,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
                       struct nameidata *nd)
 {
-       if (nd && (nd->flags & LOOKUP_CREATE)) {
+       if (nd && (nd->flags & LOOKUP_OPEN)) {
                int err = fuse_create_open(dir, entry, mode, nd);
                if (err != -ENOSYS)
                        return err;
index d0ed60bc318842393e2af04a9b09a49c16afe622..adf7995232b8b851250ed83839fdd5436c85c143 100644 (file)
@@ -610,7 +610,9 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
        ssize_t res;
        /* Don't allow parallel writes to the same file */
        mutex_lock(&inode->i_mutex);
-       res = fuse_direct_io(file, buf, count, ppos, 1);
+       res = generic_write_checks(file, ppos, &count, 0);
+       if (!res)
+               res = fuse_direct_io(file, buf, count, ppos, 1);
        mutex_unlock(&inode->i_mutex);
        return res;
 }
index 78f7a1dc90ddbd7f52125662cd1f60c0b56139c3..9804c0cdcb4200020398a1e87efb715cec697bec 100644 (file)
@@ -454,6 +454,7 @@ static const struct super_operations fuse_super_operations = {
        .destroy_inode  = fuse_destroy_inode,
        .read_inode     = fuse_read_inode,
        .clear_inode    = fuse_clear_inode,
+       .drop_inode     = generic_delete_inode,
        .remount_fs     = fuse_remount_fs,
        .put_super      = fuse_put_super,
        .umount_begin   = fuse_umount_begin,
index 479c1038ed4a4f7d3354e5939f6eae6a910e1d4f..8c90cbc903fa812e562984dab11ccc4e9212f2d2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/kallsyms.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -20,6 +21,7 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
                unsigned long arg)
 {
        int error = -ENOTTY;
+       void *f;
 
        if (!filp->f_op)
                goto out;
@@ -29,10 +31,16 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
                if (error == -ENOIOCTLCMD)
                        error = -EINVAL;
                goto out;
-       } else if (filp->f_op->ioctl) {
+       } else if ((f = filp->f_op->ioctl)) {
                lock_kernel();
-               error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
-                                         filp, cmd, arg);
+               if (!filp->f_op->ioctl) {
+                       printk("%s: ioctl %p disappeared\n", __FUNCTION__, f);
+                       print_symbol("symbol: %s\n", (unsigned long)f);
+                       dump_stack();
+               } else {
+                       error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
+                                                 filp, cmd, arg);
+               }
                unlock_kernel();
        }
 
index 4884d5edfe658282d626c6674497231a9ff4d20a..12e83f67eee493cfe625430e14e1e7a938d09395 100644 (file)
@@ -229,9 +229,16 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
           check anyway. */
        if (!tn->fn->size) {
                if (rii->mdata_tn) {
-                       /* We had a candidate mdata node already */
-                       dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version);
-                       jffs2_kill_tn(c, rii->mdata_tn);
+                       if (rii->mdata_tn->version < tn->version) {
+                               /* We had a candidate mdata node already */
+                               dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version);
+                               jffs2_kill_tn(c, rii->mdata_tn);
+                       } else {
+                               dbg_readinode("kill new mdata with ver %d (older than existing %d\n",
+                                             tn->version, rii->mdata_tn->version);
+                               jffs2_kill_tn(c, tn);
+                               return 0;
+                       }
                }
                rii->mdata_tn = tn;
                dbg_readinode("keep new mdata with ver %d\n", tn->version);
@@ -1044,7 +1051,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
 
                case JFFS2_NODETYPE_DIRENT:
 
-                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
+                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent) &&
+                           len < sizeof(struct jffs2_raw_dirent)) {
                                err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf);
                                if (unlikely(err))
                                        goto free_out;
@@ -1058,7 +1066,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
 
                case JFFS2_NODETYPE_INODE:
 
-                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
+                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode) &&
+                           len < sizeof(struct jffs2_raw_inode)) {
                                err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf);
                                if (unlikely(err))
                                        goto free_out;
@@ -1071,7 +1080,8 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
                        break;
 
                default:
-                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {
+                       if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node) &&
+                           len < sizeof(struct jffs2_unknown_node)) {
                                err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf);
                                if (unlikely(err))
                                        goto free_out;
index 6488af43bc9b757e5de859184aacd987404d866f..e220d3bd610de5ae2bc3eb96441d0c9c3c1c8d28 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mount.h>
 #include <linux/jffs2.h>
 #include <linux/pagemap.h>
-#include <linux/mtd/mtd.h>
+#include <linux/mtd/super.h>
 #include <linux/ctype.h>
 #include <linux/namei.h>
 #include "compr.h"
@@ -75,69 +75,27 @@ static const struct super_operations jffs2_super_operations =
        .sync_fs =      jffs2_sync_fs,
 };
 
-static int jffs2_sb_compare(struct super_block *sb, void *data)
-{
-       struct jffs2_sb_info *p = data;
-       struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-
-       /* The superblocks are considered to be equivalent if the underlying MTD
-          device is the same one */
-       if (c->mtd == p->mtd) {
-               D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name));
-               return 1;
-       } else {
-               D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n",
-                         c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name));
-               return 0;
-       }
-}
-
-static int jffs2_sb_set(struct super_block *sb, void *data)
-{
-       struct jffs2_sb_info *p = data;
-
-       /* For persistence of NFS exports etc. we use the same s_dev
-          each time we mount the device, don't just use an anonymous
-          device */
-       sb->s_fs_info = p;
-       p->os_priv = sb;
-       sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
-
-       return 0;
-}
-
-static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
-                           int flags, const char *dev_name,
-                           void *data, struct mtd_info *mtd,
-                           struct vfsmount *mnt)
+/*
+ * fill in the superblock
+ */
+static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
 {
-       struct super_block *sb;
        struct jffs2_sb_info *c;
-       int ret;
+
+       D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
+                 " New superblock for device %d (\"%s\")\n",
+                 sb->s_mtd->index, sb->s_mtd->name));
 
        c = kzalloc(sizeof(*c), GFP_KERNEL);
        if (!c)
                return -ENOMEM;
-       c->mtd = mtd;
-
-       sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
-
-       if (IS_ERR(sb))
-               goto out_error;
-
-       if (sb->s_root) {
-               /* New mountpoint for JFFS2 which is already mounted */
-               D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
-                         mtd->index, mtd->name));
-               ret = simple_set_mnt(mnt, sb);
-               goto out_put;
-       }
 
-       D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
-                 mtd->index, mtd->name));
+       c->mtd = sb->s_mtd;
+       c->os_priv = sb;
+       sb->s_fs_info = c;
 
-       /* Initialize JFFS2 superblock locks, the further initialization will be
-        * done later */
+       /* Initialize JFFS2 superblock locks, the further initialization will
+        * be done later */
        init_MUTEX(&c->alloc_sem);
        init_MUTEX(&c->erase_free_sem);
        init_waitqueue_head(&c->erase_wait);
@@ -146,133 +104,20 @@ static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
        spin_lock_init(&c->inocache_lock);
 
        sb->s_op = &jffs2_super_operations;
-       sb->s_flags = flags | MS_NOATIME;
+       sb->s_flags = sb->s_flags | MS_NOATIME;
        sb->s_xattr = jffs2_xattr_handlers;
 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
 #endif
-       ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
-
-       if (ret) {
-               /* Failure case... */
-               up_write(&sb->s_umount);
-               deactivate_super(sb);
-               return ret;
-       }
-
-       sb->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, sb);
-
-out_error:
-       ret = PTR_ERR(sb);
- out_put:
-       kfree(c);
-       put_mtd_device(mtd);
-
-       return ret;
-}
-
-static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
-                             int flags, const char *dev_name,
-                             void *data, int mtdnr,
-                             struct vfsmount *mnt)
-{
-       struct mtd_info *mtd;
-
-       mtd = get_mtd_device(NULL, mtdnr);
-       if (IS_ERR(mtd)) {
-               D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
-               return PTR_ERR(mtd);
-       }
-
-       return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
+       return jffs2_do_fill_super(sb, data, silent);
 }
 
 static int jffs2_get_sb(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
                        void *data, struct vfsmount *mnt)
 {
-       int err;
-       struct nameidata nd;
-       int mtdnr;
-
-       if (!dev_name)
-               return -EINVAL;
-
-       D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
-
-       /* The preferred way of mounting in future; especially when
-          CONFIG_BLK_DEV is implemented - we specify the underlying
-          MTD device by number or by name, so that we don't require
-          block device support to be present in the kernel. */
-
-       /* FIXME: How to do the root fs this way? */
-
-       if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
-               /* Probably mounting without the blkdev crap */
-               if (dev_name[3] == ':') {
-                       struct mtd_info *mtd;
-
-                       /* Mount by MTD device name */
-                       D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4));
-                       for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
-                               mtd = get_mtd_device(NULL, mtdnr);
-                               if (!IS_ERR(mtd)) {
-                                       if (!strcmp(mtd->name, dev_name+4))
-                                               return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
-                                       put_mtd_device(mtd);
-                               }
-                       }
-                       printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4);
-               } else if (isdigit(dev_name[3])) {
-                       /* Mount by MTD device number name */
-                       char *endptr;
-
-                       mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
-                       if (!*endptr) {
-                               /* It was a valid number */
-                               D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
-                               return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
-                       }
-               }
-       }
-
-       /* Try the old way - the hack where we allowed users to mount
-          /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
-
-       err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-
-       D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n",
-                 err, nd.dentry->d_inode));
-
-       if (err)
-               return err;
-
-       err = -EINVAL;
-
-       if (!S_ISBLK(nd.dentry->d_inode->i_mode))
-               goto out;
-
-       if (nd.mnt->mnt_flags & MNT_NODEV) {
-               err = -EACCES;
-               goto out;
-       }
-
-       if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
-               if (!(flags & MS_SILENT))
-                       printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
-                              dev_name);
-               goto out;
-       }
-
-       mtdnr = iminor(nd.dentry->d_inode);
-       path_release(&nd);
-
-       return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
-
-out:
-       path_release(&nd);
-       return err;
+       return get_sb_mtd(fs_type, flags, dev_name, data, jffs2_fill_super,
+                         mnt);
 }
 
 static void jffs2_put_super (struct super_block *sb)
@@ -307,8 +152,7 @@ static void jffs2_kill_sb(struct super_block *sb)
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
        if (!(sb->s_flags & MS_RDONLY))
                jffs2_stop_garbage_collect_thread(c);
-       generic_shutdown_super(sb);
-       put_mtd_device(c->mtd);
+       kill_mtd_super(sb);
        kfree(c);
 }
 
index 78fc08893a6c781ed94594e96f0408d4be21cbb7..e48665984cb3393d1f859e27db42ba29a6937345 100644 (file)
@@ -754,6 +754,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
                list_del(&xd->xindex);
                jffs2_free_xattr_datum(xd);
        }
+       list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
+               list_del(&xd->xindex);
+               jffs2_free_xattr_datum(xd);
+       }
 }
 
 #define XREF_TMPHASH_SIZE      (128)
@@ -825,7 +829,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
                           ref->xd and ref->ic are not valid yet. */
                        xd = jffs2_find_xattr_datum(c, ref->xid);
                        ic = jffs2_get_ino_cache(c, ref->ino);
-                       if (!xd || !ic) {
+                       if (!xd || !ic || !ic->nlink) {
                                dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
                                          ref->ino, ref->xid, ref->xseqno);
                                ref->xseqno |= XREF_DELETE_MARKER;
index 345aa5c0f3824cb78255b50a48d84be61eb17517..00eee87510fe5b5438aa21556298cdebfc294804 100644 (file)
@@ -122,19 +122,25 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_
        return -EINVAL;
 }
 
-static void nfs_direct_dirty_pages(struct page **pages, int npages)
+static void nfs_direct_dirty_pages(struct page **pages, unsigned int pgbase, size_t count)
 {
-       int i;
+       unsigned int npages;
+       unsigned int i;
+
+       if (count == 0)
+               return;
+       pages += (pgbase >> PAGE_SHIFT);
+       npages = (count + (pgbase & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
        for (i = 0; i < npages; i++) {
                struct page *page = pages[i];
                if (!PageCompound(page))
-                       set_page_dirty_lock(page);
+                       set_page_dirty(page);
        }
 }
 
-static void nfs_direct_release_pages(struct page **pages, int npages)
+static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
 {
-       int i;
+       unsigned int i;
        for (i = 0; i < npages; i++)
                page_cache_release(pages[i]);
 }
@@ -162,7 +168,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
        return dreq;
 }
 
-static void nfs_direct_req_release(struct kref *kref)
+static void nfs_direct_req_free(struct kref *kref)
 {
        struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
 
@@ -171,6 +177,11 @@ static void nfs_direct_req_release(struct kref *kref)
        kmem_cache_free(nfs_direct_cachep, dreq);
 }
 
+static void nfs_direct_req_release(struct nfs_direct_req *dreq)
+{
+       kref_put(&dreq->kref, nfs_direct_req_free);
+}
+
 /*
  * Collects and returns the final error value/byte-count.
  */
@@ -190,7 +201,6 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
                result = dreq->count;
 
 out:
-       kref_put(&dreq->kref, nfs_direct_req_release);
        return (ssize_t) result;
 }
 
@@ -208,7 +218,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)
        }
        complete_all(&dreq->completion);
 
-       kref_put(&dreq->kref, nfs_direct_req_release);
+       nfs_direct_req_release(dreq);
 }
 
 /*
@@ -224,17 +234,18 @@ static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
        if (nfs_readpage_result(task, data) != 0)
                return;
 
-       nfs_direct_dirty_pages(data->pagevec, data->npages);
-       nfs_direct_release_pages(data->pagevec, data->npages);
-
        spin_lock(&dreq->lock);
-
-       if (likely(task->tk_status >= 0))
-               dreq->count += data->res.count;
-       else
+       if (unlikely(task->tk_status < 0)) {
                dreq->error = task->tk_status;
-
-       spin_unlock(&dreq->lock);
+               spin_unlock(&dreq->lock);
+       } else {
+               dreq->count += data->res.count;
+               spin_unlock(&dreq->lock);
+               nfs_direct_dirty_pages(data->pagevec,
+                               data->args.pgbase,
+                               data->res.count);
+       }
+       nfs_direct_release_pages(data->pagevec, data->npages);
 
        if (put_dreq(dreq))
                nfs_direct_complete(dreq);
@@ -279,9 +290,12 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
                result = get_user_pages(current, current->mm, user_addr,
                                        data->npages, 1, 0, data->pagevec, NULL);
                up_read(&current->mm->mmap_sem);
-               if (unlikely(result < data->npages)) {
-                       if (result > 0)
-                               nfs_direct_release_pages(data->pagevec, result);
+               if (result < 0) {
+                       nfs_readdata_release(data);
+                       break;
+               }
+               if ((unsigned)result < data->npages) {
+                       nfs_direct_release_pages(data->pagevec, result);
                        nfs_readdata_release(data);
                        break;
                }
@@ -359,6 +373,7 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size
        if (!result)
                result = nfs_direct_wait(dreq);
        rpc_clnt_sigunmask(clnt, &oldset);
+       nfs_direct_req_release(dreq);
 
        return result;
 }
@@ -610,9 +625,12 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
                result = get_user_pages(current, current->mm, user_addr,
                                        data->npages, 0, 0, data->pagevec, NULL);
                up_read(&current->mm->mmap_sem);
-               if (unlikely(result < data->npages)) {
-                       if (result > 0)
-                               nfs_direct_release_pages(data->pagevec, result);
+               if (result < 0) {
+                       nfs_writedata_release(data);
+                       break;
+               }
+               if ((unsigned)result < data->npages) {
+                       nfs_direct_release_pages(data->pagevec, result);
                        nfs_writedata_release(data);
                        break;
                }
@@ -703,6 +721,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
        if (!result)
                result = nfs_direct_wait(dreq);
        rpc_clnt_sigunmask(clnt, &oldset);
+       nfs_direct_req_release(dreq);
 
        return result;
 }
index cbdd1c6aaa94ceff27a1aa187c757670b5bcab2a..c5bb51a29e8072198c57963f5c3c9dbf86ebc6ab 100644 (file)
@@ -355,6 +355,26 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
        nfs_pageio_doio(desc);
 }
 
+/**
+ * nfs_pageio_cond_complete - Conditional I/O completion
+ * @desc: pointer to io descriptor
+ * @index: page index
+ *
+ * It is important to ensure that processes don't try to take locks
+ * on non-contiguous ranges of pages as that might deadlock. This
+ * function should be called before attempting to wait on a locked
+ * nfs_page. It will complete the I/O if the page index 'index'
+ * is not contiguous with the existing list of pages in 'desc'.
+ */
+void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
+{
+       if (!list_empty(&desc->pg_list)) {
+               struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev);
+               if (index != prev->wb_index + 1)
+                       nfs_pageio_doio(desc);
+       }
+}
+
 #define NFS_SCAN_MAXENTRIES 16
 /**
  * nfs_scan_list - Scan a list for matching requests
index b084c03ce493f09de40612a0ed22abc1ad84ea22..af344a158e0103465ab632274e88b9583b69c5aa 100644 (file)
@@ -273,8 +273,6 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
                 *       request as dirty (in which case we don't care).
                 */
                spin_unlock(req_lock);
-               /* Prevent deadlock! */
-               nfs_pageio_complete(pgio);
                ret = nfs_wait_on_request(req);
                nfs_release_request(req);
                if (ret != 0)
@@ -321,6 +319,8 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc
                pgio = &mypgio;
        }
 
+       nfs_pageio_cond_complete(pgio, page->index);
+
        err = nfs_page_async_flush(pgio, page);
        if (err <= 0)
                goto out;
@@ -329,6 +329,8 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc
        if (!offset)
                goto out;
 
+       nfs_pageio_cond_complete(pgio, page->index);
+
        ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
        if (ctx == NULL) {
                err = -EBADF;
index 074791ce4ab27fda0ae007f491662ac5ec95b2a7..b532a730cec2378072a20304fb85d07ed0d529f3 100644 (file)
@@ -140,7 +140,7 @@ static int ntfs_init_locked_inode(struct inode *vi, ntfs_attr *na)
                if (!ni->name)
                        return -ENOMEM;
                memcpy(ni->name, na->name, i);
-               ni->name[i] = 0;
+               ni->name[na->name_len] = 0;
        }
        return 0;
 }
index 8e7cafb5fc6c638cded86d0a04c369f62daa5b25..a480b09c79b916de88252129919bedbbfb10850a 100644 (file)
@@ -222,7 +222,10 @@ static int ocfs2_readpage(struct file *file, struct page *page)
                goto out;
        }
 
-       down_read(&OCFS2_I(inode)->ip_alloc_sem);
+       if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) {
+               ret = AOP_TRUNCATED_PAGE;
+               goto out_meta_unlock;
+       }
 
        /*
         * i_size might have just been updated as we grabed the meta lock.  We
@@ -235,10 +238,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
         * XXX sys_readahead() seems to get that wrong?
         */
        if (start >= i_size_read(inode)) {
-               char *addr = kmap(page);
-               memset(addr, 0, PAGE_SIZE);
-               flush_dcache_page(page);
-               kunmap(page);
+               zero_user_page(page, 0, PAGE_SIZE, KM_USER0);
                SetPageUptodate(page);
                ret = 0;
                goto out_alloc;
@@ -258,6 +258,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
        ocfs2_data_unlock(inode, 0);
 out_alloc:
        up_read(&OCFS2_I(inode)->ip_alloc_sem);
+out_meta_unlock:
        ocfs2_meta_unlock(inode, 0);
 out:
        if (unlock)
@@ -797,6 +798,11 @@ int ocfs2_map_and_write_splice_data(struct inode *inode,
        }
        to = from + bytes;
 
+       BUG_ON(from > PAGE_CACHE_SIZE);
+       BUG_ON(to > PAGE_CACHE_SIZE);
+       BUG_ON(from < cluster_start);
+       BUG_ON(to > cluster_end);
+
        if (wc->w_this_page_new)
                ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode,
                                            cluster_start, cluster_end, 1);
@@ -808,11 +814,6 @@ int ocfs2_map_and_write_splice_data(struct inode *inode,
                goto out;
        }
 
-       BUG_ON(from > PAGE_CACHE_SIZE);
-       BUG_ON(to > PAGE_CACHE_SIZE);
-       BUG_ON(from > osb->s_clustersize);
-       BUG_ON(to > osb->s_clustersize);
-
        src = buf->ops->map(sp->s_pipe, buf, 1);
        dst = kmap_atomic(wc->w_this_page, KM_USER1);
        memcpy(dst + from, src + src_from, bytes);
@@ -889,6 +890,11 @@ int ocfs2_map_and_write_user_data(struct inode *inode,
 
        to = from + bytes;
 
+       BUG_ON(from > PAGE_CACHE_SIZE);
+       BUG_ON(to > PAGE_CACHE_SIZE);
+       BUG_ON(from < cluster_start);
+       BUG_ON(to > cluster_end);
+
        if (wc->w_this_page_new)
                ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode,
                                            cluster_start, cluster_end, 1);
@@ -900,11 +906,6 @@ int ocfs2_map_and_write_user_data(struct inode *inode,
                goto out;
        }
 
-       BUG_ON(from > PAGE_CACHE_SIZE);
-       BUG_ON(to > PAGE_CACHE_SIZE);
-       BUG_ON(from > osb->s_clustersize);
-       BUG_ON(to > osb->s_clustersize);
-
        dst = kmap(wc->w_this_page);
        memcpy(dst + from, bp->b_src_buf + src_from, bytes);
        kunmap(wc->w_this_page);
index a93620ce4aca80e7444ca01cffd24ee45b16b359..2b205f5d5790e73d281f6fbf7e298d2f7dc3b782 100644 (file)
@@ -144,8 +144,7 @@ static struct kobj_type mlog_ktype = {
 };
 
 static struct kset mlog_kset = {
-       .kobj  = {.name = "logmask"},
-       .ktype = &mlog_ktype
+       .kobj   = {.name = "logmask", .ktype = &mlog_ktype},
 };
 
 int mlog_sys_init(struct kset *o2cb_subsys)
index 9395b4fa547df54a5dcce659d779ac718377b053..ac6c96431bbcb3a7687b522465e456d68246c002 100644 (file)
@@ -326,6 +326,7 @@ static int ocfs2_truncate_file(struct inode *inode,
                   (unsigned long long)OCFS2_I(inode)->ip_blkno,
                   (unsigned long long)new_i_size);
 
+       unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1);
        truncate_inode_pages(inode->i_mapping, new_i_size);
 
        fe = (struct ocfs2_dinode *) di_bh->b_data;
@@ -1418,36 +1419,6 @@ out:
        return total ? total : ret;
 }
 
-static int ocfs2_check_iovec(const struct iovec *iov, size_t *counted,
-                            unsigned long *nr_segs)
-{
-       size_t ocount;          /* original count */
-       unsigned long seg;
-
-       ocount = 0;
-       for (seg = 0; seg < *nr_segs; seg++) {
-               const struct iovec *iv = &iov[seg];
-
-               /*
-                * If any segment has a negative length, or the cumulative
-                * length ever wraps negative then return -EINVAL.
-                */
-               ocount += iv->iov_len;
-               if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
-                       return -EINVAL;
-               if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
-                       continue;
-               if (seg == 0)
-                       return -EFAULT;
-               *nr_segs = seg;
-               ocount -= iv->iov_len;  /* This segment is no good */
-               break;
-       }
-
-       *counted = ocount;
-       return 0;
-}
-
 static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
                                    const struct iovec *iov,
                                    unsigned long nr_segs,
@@ -1470,7 +1441,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        if (iocb->ki_left == 0)
                return 0;
 
-       ret = ocfs2_check_iovec(iov, &ocount, &nr_segs);
+       ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
        if (ret)
                return ret;
 
index 4dedd9789108193eee3b107c84053270255e5a9b..545f7892cdf39b645888e12fa8614598dbb86bfb 100644 (file)
@@ -471,9 +471,6 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
 
        mutex_lock(&local_alloc_inode->i_mutex);
 
-       ac->ac_inode = local_alloc_inode;
-       ac->ac_which = OCFS2_AC_USE_LOCAL;
-
        if (osb->local_alloc_state != OCFS2_LA_ENABLED) {
                status = -ENOSPC;
                goto bail;
@@ -511,10 +508,14 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
                }
        }
 
+       ac->ac_inode = local_alloc_inode;
+       ac->ac_which = OCFS2_AC_USE_LOCAL;
        get_bh(osb->local_alloc_bh);
        ac->ac_bh = osb->local_alloc_bh;
        status = 0;
 bail:
+       if (status < 0 && local_alloc_inode)
+               iput(local_alloc_inode);
 
        mlog_exit(status);
        return status;
index 3b481d557edbd01df82c18d5cbef6386fa862bf1..5d258c40a2fd9c59fead95c4d3d84d7a4092bce3 100644 (file)
@@ -179,7 +179,7 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size)
                        return ret;
        }
 
-       ret = vmtruncate(inode, size);
+       ret = vmtruncate(inode, newsize);
 
        return ret;
 }
@@ -195,6 +195,11 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
        unsigned int old_ia_valid = ia->ia_valid;
        int ret = 0;
 
+       /* POSIX UID/GID verification for setting inode attributes */
+       ret = inode_change_ok(inode, ia);
+       if (ret)
+               return ret;
+
        /* by providing our own setattr() method, we skip this quotaism */
        if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) ||
            (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid))
index 9c23fee3bae9b678d4d3cd6bbca538e07aa3599d..ffbfc2caaf2050990de21e5a4348a789fbd65c99 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/buffer_head.h>
 #include <asm/uaccess.h>
 
-extern struct reiserfs_key MIN_KEY;
+extern const struct reiserfs_key MIN_KEY;
 
 static int reiserfs_readdir(struct file *, void *, filldir_t);
 static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
index 7cfeab412b45ec4ef381caef24a721e966a4f3ad..f1da89203a9aeea3108fe9270169c501df821129 100644 (file)
@@ -11,6 +11,8 @@
  *      Now using anonymous inode source.
  *      Thanks to Oleg Nesterov for useful code review and suggestions.
  *      More comments and suggestions from Arnd Bergmann.
+ * Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br>
+ *      Retrieve multiple signals with one read() call
  */
 
 #include <linux/file.h>
@@ -206,6 +208,59 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
        return err ? -EFAULT: sizeof(*uinfo);
 }
 
+static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info,
+                               int nonblock)
+{
+       ssize_t ret;
+       struct signalfd_lockctx lk;
+       DECLARE_WAITQUEUE(wait, current);
+
+       if (!signalfd_lock(ctx, &lk))
+               return 0;
+
+       ret = dequeue_signal(lk.tsk, &ctx->sigmask, info);
+       switch (ret) {
+       case 0:
+               if (!nonblock)
+                       break;
+               ret = -EAGAIN;
+       default:
+               signalfd_unlock(&lk);
+               return ret;
+       }
+
+       add_wait_queue(&ctx->wqh, &wait);
+       for (;;) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               ret = dequeue_signal(lk.tsk, &ctx->sigmask, info);
+               signalfd_unlock(&lk);
+               if (ret != 0)
+                       break;
+               if (signal_pending(current)) {
+                       ret = -ERESTARTSYS;
+                       break;
+               }
+               schedule();
+               ret = signalfd_lock(ctx, &lk);
+               if (unlikely(!ret)) {
+                       /*
+                        * Let the caller read zero byte, ala socket
+                        * recv() when the peer disconnect. This test
+                        * must be done before doing a dequeue_signal(),
+                        * because if the sighand has been orphaned,
+                        * the dequeue_signal() call is going to crash
+                        * because ->sighand will be long gone.
+                        */
+                        break;
+               }
+       }
+
+       remove_wait_queue(&ctx->wqh, &wait);
+       __set_current_state(TASK_RUNNING);
+
+       return ret;
+}
+
 /*
  * Returns either the size of a "struct signalfd_siginfo", or zero if the
  * sighand we are attached to, has been orphaned. The "count" parameter
@@ -215,55 +270,30 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
                             loff_t *ppos)
 {
        struct signalfd_ctx *ctx = file->private_data;
-       ssize_t res = 0;
-       int locked, signo;
+       struct signalfd_siginfo __user *siginfo;
+       int nonblock = file->f_flags & O_NONBLOCK;
+       ssize_t ret, total = 0;
        siginfo_t info;
-       struct signalfd_lockctx lk;
-       DECLARE_WAITQUEUE(wait, current);
 
-       if (count < sizeof(struct signalfd_siginfo))
+       count /= sizeof(struct signalfd_siginfo);
+       if (!count)
                return -EINVAL;
-       locked = signalfd_lock(ctx, &lk);
-       if (!locked)
-               return 0;
-       res = -EAGAIN;
-       signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
-       if (signo == 0 && !(file->f_flags & O_NONBLOCK)) {
-               add_wait_queue(&ctx->wqh, &wait);
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
-                       if (signo != 0)
-                               break;
-                       if (signal_pending(current)) {
-                               res = -ERESTARTSYS;
-                               break;
-                       }
-                       signalfd_unlock(&lk);
-                       schedule();
-                       locked = signalfd_lock(ctx, &lk);
-                       if (unlikely(!locked)) {
-                               /*
-                                * Let the caller read zero byte, ala socket
-                                * recv() when the peer disconnect. This test
-                                * must be done before doing a dequeue_signal(),
-                                * because if the sighand has been orphaned,
-                                * the dequeue_signal() call is going to crash.
-                                */
-                               res = 0;
-                               break;
-                       }
-               }
-               remove_wait_queue(&ctx->wqh, &wait);
-               __set_current_state(TASK_RUNNING);
-       }
-       if (likely(locked))
-               signalfd_unlock(&lk);
-       if (likely(signo))
-               res = signalfd_copyinfo((struct signalfd_siginfo __user *) buf,
-                                       &info);
 
-       return res;
+       siginfo = (struct signalfd_siginfo __user *) buf;
+
+       do {
+               ret = signalfd_dequeue(ctx, &info, nonblock);
+               if (unlikely(ret <= 0))
+                       break;
+               ret = signalfd_copyinfo(siginfo, &info);
+               if (ret < 0)
+                       break;
+               siginfo++;
+               total += ret;
+               nonblock = 1;
+       } while (--count);
+
+       return total ? total : ret;
 }
 
 static const struct file_operations signalfd_fops = {
index 12f28281d2b1e1f8d1627995f03efcfeb25a4945..cb211360273ac77e21a7b4a5f44f4a401385d1a2 100644 (file)
@@ -272,7 +272,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
        struct page *page;
        pgoff_t index, end_index;
        loff_t isize;
-       size_t total_len;
        int error, page_nr;
        struct splice_pipe_desc spd = {
                .pages = pages,
@@ -298,7 +297,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
         * Now fill in the holes:
         */
        error = 0;
-       total_len = 0;
 
        /*
         * Lookup the (hopefully) full range of pages we need.
@@ -415,43 +413,47 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 
                                break;
                        }
+               }
+fill_it:
+               /*
+                * i_size must be checked after PageUptodate.
+                */
+               isize = i_size_read(mapping->host);
+               end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
+               if (unlikely(!isize || index > end_index))
+                       break;
+
+               /*
+                * if this is the last page, see if we need to shrink
+                * the length and stop
+                */
+               if (end_index == index) {
+                       unsigned int plen;
 
                        /*
-                        * i_size must be checked after ->readpage().
+                        * max good bytes in this page
                         */
-                       isize = i_size_read(mapping->host);
-                       end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
-                       if (unlikely(!isize || index > end_index))
+                       plen = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
+                       if (plen <= loff)
                                break;
 
                        /*
-                        * if this is the last page, see if we need to shrink
-                        * the length and stop
+                        * force quit after adding this page
                         */
-                       if (end_index == index) {
-                               loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK);
-                               if (total_len + loff > isize)
-                                       break;
-                               /*
-                                * force quit after adding this page
-                                */
-                               len = this_len;
-                               this_len = min(this_len, loff);
-                               loff = 0;
-                       }
+                       this_len = min(this_len, plen - loff);
+                       len = this_len;
                }
-fill_it:
+
                partial[page_nr].offset = loff;
                partial[page_nr].len = this_len;
                len -= this_len;
-               total_len += this_len;
                loff = 0;
                spd.nr_pages++;
                index++;
        }
 
        /*
-        * Release any pages at the end, if we quit early. 'i' is how far
+        * Release any pages at the end, if we quit early. 'page_nr' is how far
         * we got, 'nr_pages' is how many pages are in the map.
         */
        while (page_nr < nr_pages)
@@ -478,10 +480,18 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
 {
        ssize_t spliced;
        int ret;
+       loff_t isize, left;
+
+       isize = i_size_read(in->f_mapping->host);
+       if (unlikely(*ppos >= isize))
+               return 0;
+
+       left = isize - *ppos;
+       if (unlikely(left < len))
+               len = left;
 
        ret = 0;
        spliced = 0;
-
        while (len) {
                ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 
@@ -644,7 +654,6 @@ find_page:
         * accessed, we are now done!
         */
        mark_page_accessed(page);
-       balance_dirty_pages_ratelimited(mapping);
 out:
        page_cache_release(page);
        unlock_page(page);
@@ -815,6 +824,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
                        if (err)
                                ret = err;
                }
+               balance_dirty_pages_ratelimited(mapping);
        }
 
        return ret;
@@ -868,6 +878,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                        if (err)
                                ret = err;
                }
+               balance_dirty_pages_ratelimited(mapping);
        }
 
        return ret;
@@ -922,7 +933,6 @@ static long do_splice_to(struct file *in, loff_t *ppos,
                         struct pipe_inode_info *pipe, size_t len,
                         unsigned int flags)
 {
-       loff_t isize, left;
        int ret;
 
        if (unlikely(!in->f_op || !in->f_op->splice_read))
@@ -935,14 +945,6 @@ static long do_splice_to(struct file *in, loff_t *ppos,
        if (unlikely(ret < 0))
                return ret;
 
-       isize = i_size_read(in->f_mapping->host);
-       if (unlikely(*ppos >= isize))
-               return 0;
-       
-       left = isize - *ppos;
-       if (unlikely(left < len))
-               len = left;
-
        return in->f_op->splice_read(in, ppos, pipe, len, flags);
 }
 
@@ -1058,8 +1060,6 @@ out_release:
        return ret;
 }
 
-EXPORT_SYMBOL(do_splice_direct);
-
 /*
  * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
  * location, so checking ->i_pipe is not enough to verify that this is a
index c8461551e108bda5a48448ae5b0945286842a1ab..1f0129405cf47e636220a59ccd1e4f040940057d 100644 (file)
@@ -460,8 +460,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
        kernel_long_ad laarr[EXTENT_MERGE_SIZE];
        struct extent_position prev_epos, cur_epos, next_epos;
        int count = 0, startnum = 0, endnum = 0;
-       uint32_t elen = 0;
-       kernel_lb_addr eloc;
+       uint32_t elen = 0, tmpelen;
+       kernel_lb_addr eloc, tmpeloc;
        int c = 1;
        loff_t lbcount = 0, b_off = 0;
        uint32_t newblocknum, newblock;
@@ -520,8 +520,12 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
 
        b_off -= lbcount;
        offset = b_off >> inode->i_sb->s_blocksize_bits;
-       /* Move into indirect extent if we are at a pointer to it */
-       udf_next_aext(inode, &prev_epos, &eloc, &elen, 0);
+       /*
+        * Move prev_epos and cur_epos into indirect extent if we are at
+        * the pointer to it
+        */
+       udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
+       udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
 
        /* if the extent is allocated and recorded, return the block
        if the extent is not a multiple of the blocksize, round up */
index 3a743d854c17bf9408b8114d0b44ead19fe18b1e..6658afb41cc7564ffeced0d42e0b35b0421baf0e 100644 (file)
@@ -1351,7 +1351,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
 
        for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
        {
-               switch UDF_SB_PARTTYPE(sb, i)
+               switch (UDF_SB_PARTTYPE(sb, i))
                {
                        case UDF_VIRTUAL_MAP15:
                        case UDF_VIRTUAL_MAP20:
index 4475588e973a4aa922144c80b39df5948b5199ef..7361861e3aacde605a400771af549b77e9b457e5 100644 (file)
@@ -701,7 +701,7 @@ xfs_is_delayed_page(
                        else if (buffer_delay(bh))
                                acceptable = (type == IOMAP_DELAY);
                        else if (buffer_dirty(bh) && buffer_mapped(bh))
-                               acceptable = (type == 0);
+                               acceptable = (type == IOMAP_NEW);
                        else
                                break;
                } while ((bh = bh->b_this_page) != head);
@@ -810,7 +810,7 @@ xfs_convert_page(
                        page_dirty--;
                        count++;
                } else {
-                       type = 0;
+                       type = IOMAP_NEW;
                        if (buffer_mapped(bh) && all_bh && startio) {
                                lock_buffer(bh);
                                xfs_add_to_ioend(inode, bh, offset,
@@ -968,8 +968,8 @@ xfs_page_state_convert(
 
        bh = head = page_buffers(page);
        offset = page_offset(page);
-       flags = -1;
-       type = IOMAP_READ;
+       flags = BMAPI_READ;
+       type = IOMAP_NEW;
 
        /* TODO: cleanup count and page_dirty */
 
@@ -999,14 +999,14 @@ xfs_page_state_convert(
                 *
                 * Third case, an unmapped buffer was found, and we are
                 * in a path where we need to write the whole page out.
-                */
+                */
                if (buffer_unwritten(bh) || buffer_delay(bh) ||
                    ((buffer_uptodate(bh) || PageUptodate(page)) &&
                     !buffer_mapped(bh) && (unmapped || startio))) {
-                       /*
+                       /*
                         * Make sure we don't use a read-only iomap
                         */
-                       if (flags == BMAPI_READ)
+                       if (flags == BMAPI_READ)
                                iomap_valid = 0;
 
                        if (buffer_unwritten(bh)) {
@@ -1055,7 +1055,7 @@ xfs_page_state_convert(
                         * That means it must already have extents allocated
                         * underneath it. Map the extent by reading it.
                         */
-                       if (!iomap_valid || type != IOMAP_READ) {
+                       if (!iomap_valid || flags != BMAPI_READ) {
                                flags = BMAPI_READ;
                                size = xfs_probe_cluster(inode, page, bh,
                                                                head, 1);
@@ -1066,7 +1066,15 @@ xfs_page_state_convert(
                                iomap_valid = xfs_iomap_valid(&iomap, offset);
                        }
 
-                       type = IOMAP_READ;
+                       /*
+                        * We set the type to IOMAP_NEW in case we are doing a
+                        * small write at EOF that is extending the file but
+                        * without needing an allocation. We need to update the
+                        * file size on I/O completion in this case so it is
+                        * the same case as having just allocated a new extent
+                        * that we are writing into for the first time.
+                        */
+                       type = IOMAP_NEW;
                        if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
                                ASSERT(buffer_mapped(bh));
                                if (iomap_valid)
index b62cd36ff324777ec675173055db9eafbbaae019..e2fcee2b340d8e4134a7320c80eb92aaef4f611b 100644 (file)
@@ -13,7 +13,7 @@
 
 extern int pxm_to_node(int);
 extern int node_to_pxm(int);
-extern int __cpuinit acpi_map_pxm_to_node(int);
+extern int acpi_map_pxm_to_node(int);
 extern void __cpuinit acpi_unmap_pxm_to_node(int);
 
 #endif                         /* CONFIG_ACPI_NUMA */
index 5e07db0d46e9997752161028ed0e4e4dc26e2219..ca882b8e7d108e9d069ae053dd384e459bcec9a4 100644 (file)
@@ -78,7 +78,7 @@ struct acpi_signal_fatal_info {
 /*
  * OSL Initialization and shutdown primitives
  */
-acpi_status acpi_os_initialize(void);
+acpi_status __initdata acpi_os_initialize(void);
 
 acpi_status acpi_os_terminate(void);
 
@@ -236,6 +236,7 @@ acpi_os_derive_pci_id(acpi_handle rhandle,
  * Miscellaneous
  */
 acpi_status acpi_os_validate_interface(char *interface);
+acpi_status acpi_osi_invalidate(char* interface);
 
 acpi_status
 acpi_os_validate_address(u8 space_id,
index e08f7df85a4fdc2974e2c7e8ff7ba777e032f4dc..b5cca5daa348802e25426990f9e290db9d3621f9 100644 (file)
@@ -55,7 +55,7 @@ acpi_status
 acpi_initialize_tables(struct acpi_table_desc *initial_storage,
                       u32 initial_table_count, u8 allow_resize);
 
-acpi_status acpi_initialize_subsystem(void);
+acpi_status __init acpi_initialize_subsystem(void);
 
 acpi_status acpi_enable_subsystem(u32 flags);
 
index 15a838862cd4c33a6646f5dd6e1ef6ae1e34aa4f..a87ef1c8d46bbaacf43b75361b9062e048a3c47a 100644 (file)
@@ -390,6 +390,8 @@ void acpi_ut_delete_object_desc(union acpi_operand_object *object);
 
 u8 acpi_ut_valid_internal_object(void *object);
 
+union acpi_operand_object *acpi_ut_create_package_object(u32 count);
+
 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size);
 
 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
index 4b6ef7f21b9396e779e3cb86400d578ad3590e9e..3a0cbeb03fa17e01698796ab5edf48fe3af62ab7 100644 (file)
@@ -313,32 +313,29 @@ static inline int ffs(int word)
  * fls: find last bit set.
  */
 #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
-static inline int fls(int word)
+static inline int fls64(unsigned long word)
 {
-       return 64 - __kernel_ctlz(word & 0xffffffff);
+       return 64 - __kernel_ctlz(word);
 }
 #else
-#include <asm-generic/bitops/fls.h>
-#endif
-#include <asm-generic/bitops/fls64.h>
+extern const unsigned char __flsm1_tab[256];
 
-/* Compute powers of two for the given integer.  */
-static inline long floor_log2(unsigned long word)
+static inline int fls64(unsigned long x)
 {
-#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
-       return 63 - __kernel_ctlz(word);
-#else
-       long bit;
-       for (bit = -1; word ; bit++)
-               word >>= 1;
-       return bit;
-#endif
+       unsigned long t, a, r;
+
+       t = __kernel_cmpbge (x, 0x0101010101010101);
+       a = __flsm1_tab[t];
+       t = __kernel_extbl (x, a);
+       r = a*8 + __flsm1_tab[t] + (x != 0);
+
+       return r;
 }
+#endif
 
-static inline long ceil_log2(unsigned long word)
+static inline int fls(int x)
 {
-       long bit = floor_log2(word);
-       return bit + (word > (1UL << bit));
+       return fls64((unsigned int) x);
 }
 
 /*
@@ -353,9 +350,20 @@ static inline unsigned long hweight64(unsigned long w)
        return __kernel_ctpop(w);
 }
 
-#define hweight32(x)   (unsigned int) hweight64((x) & 0xfffffffful)
-#define hweight16(x)   (unsigned int) hweight64((x) & 0xfffful)
-#define hweight8(x)    (unsigned int) hweight64((x) & 0xfful)
+static inline unsigned int hweight32(unsigned int w)
+{
+       return hweight64(w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+       return hweight64(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+       return hweight64(w & 0xff);
+}
 #else
 #include <asm-generic/bitops/hweight.h>
 #endif
index 457c34b6eb09337bc87421aeb0edfe0b35edd2e7..90e6b5d6c2143d8ab23e13b596803e52fec1411f 100644 (file)
@@ -437,9 +437,15 @@ static inline void t2_outl(u32 b, unsigned long addr)
 
 static DEFINE_SPINLOCK(t2_hae_lock);
 
+/*
+ * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
+ *       they may be called directly, rather than through the
+ *       ioreadNN/iowriteNN routines.
+ */
+
 __EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long result, msb;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -453,7 +459,7 @@ __EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
 
 __EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long result, msb;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -471,7 +477,7 @@ __EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
  */
 __EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long result, msb;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -485,7 +491,7 @@ __EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
 
 __EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long r0, r1, work, msb;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -501,7 +507,7 @@ __EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
 
 __EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long msb, w;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -515,7 +521,7 @@ __EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
 
 __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long msb, w;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -533,7 +539,7 @@ __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
  */
 __EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long msb;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -546,7 +552,7 @@ __EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
 
 __EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long) xaddr;
+       unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
        unsigned long msb, work;
        unsigned long flags;
        spin_lock_irqsave(&t2_hae_lock, flags);
@@ -587,14 +593,14 @@ __EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
 __EXTERN_INLINE unsigned int t2_ioread##NS(void __iomem *xaddr)                \
 {                                                                      \
        if (t2_is_mmio(xaddr))                                          \
-               return t2_read##OS(xaddr - T2_DENSE_MEM);               \
+               return t2_read##OS(xaddr);                              \
        else                                                            \
                return t2_in##OS((unsigned long)xaddr - T2_IO);         \
 }                                                                      \
 __EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr)      \
 {                                                                      \
        if (t2_is_mmio(xaddr))                                          \
-               t2_write##OS(b, xaddr - T2_DENSE_MEM);                  \
+               t2_write##OS(b, xaddr);                                 \
        else                                                            \
                t2_out##OS(b, (unsigned long)xaddr - T2_IO);            \
 }
index a64ccbff7d98ac3e0c94a50576df2e57e4a0f34d..a17f6f33b68ec6f339199ed4371307cf20999d2d 100644 (file)
@@ -380,12 +380,7 @@ struct el_PRIVATEER_envdata_mcheck {
 /*
  * Memory functions.  all accesses are done through linear space.
  */
-
-__EXTERN_INLINE void __iomem *titan_ioportmap(unsigned long addr)
-{
-       return (void __iomem *)(addr + TITAN_IO_BIAS);
-}
-
+extern void __iomem *titan_ioportmap(unsigned long addr);
 extern void __iomem *titan_ioremap(unsigned long addr, unsigned long size);
 extern void titan_iounmap(volatile void __iomem *addr);
 
index 44e635d2c5712dab7112e9cbd1aeda4e33033115..58d4fe48742c49c09b03657c97d6269d7e930d02 100644 (file)
@@ -2,6 +2,7 @@
 #define __ALPHA_TSUNAMI__H__
 
 #include <linux/types.h>
+#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
@@ -302,18 +303,8 @@ struct el_TSUNAMI_sysdata_mcheck {
 /*
  * Memory functions.  all accesses are done through linear space.
  */
-
-__EXTERN_INLINE void __iomem *tsunami_ioportmap(unsigned long addr)
-{
-       return (void __iomem *)(addr + TSUNAMI_IO_BIAS);
-}
-
-__EXTERN_INLINE void __iomem *tsunami_ioremap(unsigned long addr, 
-                                             unsigned long size)
-{
-       return (void __iomem *)(addr + TSUNAMI_MEM_BIAS);
-}
-
+extern void __iomem *tsunami_ioportmap(unsigned long addr);
+extern void __iomem *tsunami_ioremap(unsigned long addr, unsigned long size);
 __EXTERN_INLINE int tsunami_is_ioaddr(unsigned long addr)
 {
        return addr >= TSUNAMI_BASE;
index 12af803d445a00444f7af2f85606a13f5f3e3d84..cd562f544ba2deb9c1c77d0ec3fe36b0a939f16e 100644 (file)
@@ -295,7 +295,7 @@ __EXTERN_INLINE int wildfire_is_ioaddr(unsigned long addr)
 
 __EXTERN_INLINE int wildfire_is_mmio(const volatile void __iomem *xaddr)
 {
-       unsigned long addr = (unsigned long)addr;
+       unsigned long addr = (unsigned long)xaddr;
        return (addr & 0x100000000UL) == 0;
 }
 
index f4defc2bd3fb246e225717c527e7c7e5c855ee4a..48a22e3e6f32166570aac056e27d65159181302b 100644 (file)
@@ -76,12 +76,14 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define TIF_UAC_NOFIX          7
 #define TIF_UAC_SIGBUS         8
 #define TIF_MEMDIE             9
+#define TIF_RESTORE_SIGMASK    10      /* restore signal mask in do_signal */
 
 #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_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 
 /* Work to do on interrupt/exception return.  */
 #define _TIF_WORK_MASK         (_TIF_NOTIFY_RESUME     \
index e58a427012dd3c762eb9a233756d32835babe43f..29bf2fdc91c0eefe194b5123774e88eb29c4f8b6 100644 (file)
 #define __NR_osf_memcntl       260     /* not implemented */
 #define __NR_osf_fdatasync     261     /* not implemented */
 
+/*
+ * Ignore legacy syscalls that we don't use.
+ */
+#define __IGNORE_alarm
+#define __IGNORE_creat
+#define __IGNORE_getegid
+#define __IGNORE_geteuid
+#define __IGNORE_getgid
+#define __IGNORE_getpid
+#define __IGNORE_getppid
+#define __IGNORE_getuid
+#define __IGNORE_pause
+#define __IGNORE_time
+#define __IGNORE_utime
 
 /*
  * Linux-specific system calls begin at 300
 #define __NR_inotify_init              444
 #define __NR_inotify_add_watch         445
 #define __NR_inotify_rm_watch          446
+#define __NR_fdatasync                 447
+#define __NR_kexec_load                        448
+#define __NR_migrate_pages             449
+#define __NR_openat                    450
+#define __NR_mkdirat                   451
+#define __NR_mknodat                   452
+#define __NR_fchownat                  453
+#define __NR_futimesat                 454
+#define __NR_fstatat64                 455
+#define __NR_unlinkat                  456
+#define __NR_renameat                  457
+#define __NR_linkat                    458
+#define __NR_symlinkat                 459
+#define __NR_readlinkat                        460
+#define __NR_fchmodat                  461
+#define __NR_faccessat                 462
+#define __NR_pselect6                  463
+#define __NR_ppoll                     464
+#define __NR_unshare                   465
+#define __NR_set_robust_list           466
+#define __NR_get_robust_list           467
+#define __NR_splice                    468
+#define __NR_sync_file_range           469
+#define __NR_tee                       470
+#define __NR_vmsplice                  471
+#define __NR_move_pages                        472
+#define __NR_getcpu                    473
+#define __NR_epoll_pwait               474
+#define __NR_utimensat                 475
+#define __NR_signalfd                  476
+#define __NR_timerfd                   477
+#define __NR_eventfd                   478
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS                    447
+#define NR_SYSCALLS                    479
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index ed06f59b544d4c7c84ef7ccdb20ab56fa1444554..e8df1e7aae6b39155c6cdf625e2549aef6d97627 100644 (file)
@@ -46,6 +46,37 @@ extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
 #define vga_readb(a)   readb((u8 __iomem *)(a))
 #define vga_writeb(v,a)        writeb(v, (u8 __iomem *)(a))
 
+#ifdef CONFIG_VGA_HOSE
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+extern struct pci_controller *pci_vga_hose;
+
+# define __is_port_vga(a)       \
+       (((a) >= 0x3b0) && ((a) < 0x3e0) && \
+        ((a) != 0x3b3) && ((a) != 0x3d3))
+
+# define __is_mem_vga(a) \
+       (((a) >= 0xa0000) && ((a) <= 0xc0000))
+
+# define FIXUP_IOADDR_VGA(a) do {                       \
+       if (pci_vga_hose && __is_port_vga(a))     \
+               (a) += pci_vga_hose->io_space->start;     \
+ } while(0)
+
+# define FIXUP_MEMADDR_VGA(a) do {                       \
+       if (pci_vga_hose && __is_mem_vga(a))     \
+               (a) += pci_vga_hose->mem_space->start; \
+ } while(0)
+
+#else /* CONFIG_VGA_HOSE */
+# define pci_vga_hose 0
+# define __is_port_vga(a) 0
+# define __is_mem_vga(a) 0
+# define FIXUP_IOADDR_VGA(a)
+# define FIXUP_MEMADDR_VGA(a)
+#endif /* CONFIG_VGA_HOSE */
+
 #define VGA_MAP_MEM(x,s)       ((unsigned long) ioremap(x, s))
 
 #endif
index 795fcc266228b93f914a42b9a037fb4bb7046003..01b433de22726baabddcfa1ff461a9718cacf60a 100644 (file)
@@ -14,8 +14,8 @@
 #define AT91_SHDWC_H
 
 #define AT91_SHDW_CR           (AT91_SHDWC + 0x00)     /* Shut Down Control Register */
-#define                AT91_SHDW_SHDW          (1    << 0)             /* Processor Reset */
-#define                AT91_SHDW_KEY           (0xff << 24)            /* KEY Password */
+#define                AT91_SHDW_SHDW          (1    << 0)             /* Shut Down command */
+#define                AT91_SHDW_KEY           (0xa5 << 24)            /* KEY Password */
 
 #define AT91_SHDW_MR           (AT91_SHDWC + 0x04)     /* Shut Down Mode Register */
 #define                AT91_SHDW_WKMODE0       (3 << 0)                /* Wake-up 0 Mode Selection */
index 7251a344c740455a7e627a01e996e89c81b8e5e1..1014e9bf181ff14645d76d2450981a21a349fdba 100644 (file)
@@ -15,7 +15,7 @@
 
 #define AT91_WDT_CR            (AT91_WDT + 0x00)       /* Watchdog Control Register */
 #define                AT91_WDT_WDRSTT         (1    << 0)             /* Restart */
-#define                AT91_WDT_KEY            (0xff << 24)            /* KEY Password */
+#define                AT91_WDT_KEY            (0xa5 << 24)            /* KEY Password */
 
 #define AT91_WDT_MR            (AT91_WDT + 0x04)       /* Watchdog Mode Register */
 #define                AT91_WDT_WDV            (0xfff << 0)            /* Counter Value */
index 84467a5190d093d6ebc0bacd857102c2e36cb289..131e0a1d0df395f3d7740167e54b0b9419e5ad4d 100644 (file)
@@ -10,7 +10,7 @@
  * based on ixdp425.h:
  *     Copyright 2004 (c) MontaVista, Software, Inc.
  *
- * This file is licensed under  the terms of the GNU General Public
+ * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 #define NAS100D_PCI_INTD_PIN   8
 #define NAS100D_PCI_INTE_PIN   7
 
-/* GPIO */
-
-#define NAS100D_GPIO0           0
-#define NAS100D_GPIO1           1
-#define NAS100D_GPIO2           2
-#define NAS100D_GPIO3           3
-#define NAS100D_GPIO4           4
-#define NAS100D_GPIO5           5
-#define NAS100D_GPIO6           6
-#define NAS100D_GPIO7           7
-#define NAS100D_GPIO8           8
-#define NAS100D_GPIO9           9
-#define NAS100D_GPIO10          10
-#define NAS100D_GPIO11          11
-#define NAS100D_GPIO12          12
-#define NAS100D_GPIO13          13
-#define NAS100D_GPIO14          14
-#define NAS100D_GPIO15          15
-
-
 /* Buttons */
 
-#define NAS100D_PB_GPIO         NAS100D_GPIO14
-#define NAS100D_RB_GPIO         NAS100D_GPIO4
-#define NAS100D_PO_GPIO         NAS100D_GPIO12   /* power off */
+#define NAS100D_PB_GPIO         14
+#define NAS100D_RB_GPIO         4
+#define NAS100D_PO_GPIO         12   /* power off */
 
 #define NAS100D_PB_IRQ          IRQ_IXP4XX_GPIO14
 #define NAS100D_RB_IRQ          IRQ_IXP4XX_GPIO4
index 6b437f7c99550e8e56ba5f575ac3814a7efb9c8e..850fdc5b45da21eda6f6a3ad9d03a7a06b9d738a 100644 (file)
@@ -9,7 +9,7 @@
  * based on ixdp425.h:
  *     Copyright 2004 (c) MontaVista, Software, Inc.
  *
- * This file is licensed under  the terms of the GNU General Public
+ * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 #define NSLU2_PCI_INTC_PIN     9
 #define NSLU2_PCI_INTD_PIN     8
 
-
 /* NSLU2 Timer */
 #define NSLU2_FREQ 66000000
-#define NSLU2_CLOCK_TICK_RATE (((NSLU2_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
-#define NSLU2_CLOCK_TICKS_PER_USEC ((NSLU2_CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
-
-/* GPIO */
-
-#define NSLU2_GPIO0            0
-#define NSLU2_GPIO1            1
-#define NSLU2_GPIO2            2
-#define NSLU2_GPIO3            3
-#define NSLU2_GPIO4            4
-#define NSLU2_GPIO5            5
-#define NSLU2_GPIO6            6
-#define NSLU2_GPIO7            7
-#define NSLU2_GPIO8            8
-#define NSLU2_GPIO9            9
-#define NSLU2_GPIO10           10
-#define NSLU2_GPIO11           11
-#define NSLU2_GPIO12           12
-#define NSLU2_GPIO13           13
-#define NSLU2_GPIO14           14
-#define NSLU2_GPIO15           15
 
 /* Buttons */
 
-#define NSLU2_PB_GPIO          NSLU2_GPIO5
-#define NSLU2_PO_GPIO          NSLU2_GPIO8     /* power off */
-#define NSLU2_RB_GPIO          NSLU2_GPIO12
+#define NSLU2_PB_GPIO          5
+#define NSLU2_PO_GPIO          8       /* power off */
+#define NSLU2_RB_GPIO          12
 
 #define NSLU2_PB_IRQ           IRQ_IXP4XX_GPIO5
 #define NSLU2_RB_IRQ           IRQ_IXP4XX_GPIO12
 
 /* LEDs */
 
-#define NSLU2_LED_RED          NSLU2_GPIO0
-#define NSLU2_LED_GRN          NSLU2_GPIO1
+#define NSLU2_LED_RED_GPIO     0
+#define NSLU2_LED_GRN_GPIO     1
 
-#define NSLU2_LED_RED_BM       (1L << NSLU2_LED_RED)
-#define NSLU2_LED_GRN_BM       (1L << NSLU2_LED_GRN)
+#define NSLU2_LED_RED_BM       (1L << NSLU2_LED_RED_GPIO)
+#define NSLU2_LED_GRN_BM       (1L << NSLU2_LED_GRN_GPIO)
 
-#define NSLU2_LED_DISK1                NSLU2_GPIO3
-#define NSLU2_LED_DISK2                NSLU2_GPIO2
+#define NSLU2_LED_DISK1_GPIO   3
+#define NSLU2_LED_DISK2_GPIO   2
 
-#define NSLU2_LED_DISK1_BM     (1L << NSLU2_GPIO2)
-#define NSLU2_LED_DISK2_BM     (1L << NSLU2_GPIO3)
+#define NSLU2_LED_DISK1_BM     (1L << NSLU2_LED_DISK1_GPIO)
+#define NSLU2_LED_DISK2_BM     (1L << NSLU2_LED_DISK2_GPIO)
 
 
index ab194e5f66537cac410c457483282b410d7b6acb..2a44d3d6798078ab29853869e179bd54790f21cd 100644 (file)
@@ -113,6 +113,7 @@ extern unsigned long ixp4xx_timer_freq;
 extern void ixp4xx_map_io(void);
 extern void ixp4xx_init_irq(void);
 extern void ixp4xx_sys_init(void);
+extern void ixp4xx_timer_init(void);
 extern struct sys_timer ixp4xx_timer;
 extern void ixp4xx_pci_preinit(void);
 struct pci_sys_data;
index aeba24347f8e43355619711b3a4f10e4ec0a8c4d..9e99241f3edf41b12c11a7a99a7abda56adde01c 100644 (file)
@@ -45,7 +45,8 @@ static inline int gpio_direction_input(unsigned gpio)
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-       return pxa_gpio_mode(gpio | GPIO_OUT | (value ? 0 : GPIO_DFLT_LOW));
+       return pxa_gpio_mode(gpio | GPIO_OUT |
+                         (value ? GPIO_DFLT_HIGH : GPIO_DFLT_LOW));
 }
 
 static inline int __gpio_get_value(unsigned gpio)
index 4505aefbad17175308ac8a31049eb269058cb258..19e77f038042ec0b64644e25136c326d57ff5b1d 100644 (file)
 #define S3C2440_PA_AC97           (0x5B000000)
 #define S3C2440_SZ_AC97           SZ_1M
 
+/* S3C2443 High-speed SD/MMC */
+#define S3C2443_PA_HSMMC   (0x4A800000)
+#define S3C2443_SZ_HSMMC   (256)
+
 /* ISA style IO, for each machine to sort out mappings for, if it
  * implements it. We reserve two 16M regions for ISA.
  */
index 02131a5a1d3af14f9a4dd7cf3ff8db5265a0bc97..0362332faaf02cf324107c3d3cf3d517222bd1de 100644 (file)
@@ -98,5 +98,9 @@
 #define S3C2440_GPJ12_OUTP      (0x01 << 24)
 #define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
 
+#define S3C2443_GPJ13          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
+#define S3C2443_GPJ14          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
+#define S3C2443_GPJ15          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
+
 #endif /* __ASM_ARCH_REGS_GPIOJ_H */
 
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2412.h b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
new file mode 100644 (file)
index 0000000..8ca6a3b
--- /dev/null
@@ -0,0 +1,21 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-s3c2412.h
+ *
+ * Copyright 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_H
+#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
+
+#define S3C2412_SWRST          (S3C24XX_VA_CLKPWR + 0x30)
+#define S3C2412_SWRST_RESET    (0x533C2412)
+
+#endif /* __ASM_ARCH_REGS_S3C2412_H */
+
index bb9a7aa10c12ebc8e58abaaa19b95fb926dfe8ca..a91d8a1523cff6964febe47a5c362274de23fcb7 100644 (file)
 #define TIOCSBRK       0x5427  /* BSD compatibility */
 #define TIOCCBRK       0x5428  /* BSD compatibility */
 #define TIOCGSID       0x5429  /* Return the session ID of FD */
+#define TCGETS2                _IOR('T',0x2A, struct termios2)
+#define TCSETS2                _IOW('T',0x2B, struct termios2)
+#define TCSETSW2       _IOW('T',0x2C, struct termios2)
+#define TCSETSF2       _IOW('T',0x2D, struct termios2)
 #define TIOCGPTN       _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK     _IOW('T',0x31, int)  /* Lock/unlock Pty */
 
index fd2f9bf4dcc68decea8bede1a8ebeee36552f02f..c59fad18e73b0dae6530014e5f23168520abfba5 100644 (file)
@@ -49,7 +49,7 @@ struct machine_desc {
  */
 #define MACHINE_START(_type,_name)                     \
 static const struct machine_desc __mach_desc_##_type   \
- __attribute_used__                                    \
+ __used                                                        \
  __attribute__((__section__(".arch.info.init"))) = {   \
        .nr             = MACH_TYPE_##_type,            \
        .name           = _name,
index e5407392afcad0413c0df46030f51e2c93c4fd5b..7bbf105463f1adf8fd9cdaf68283cc87f3cb8c97 100644 (file)
@@ -185,7 +185,7 @@ struct tagtable {
 
 #ifdef __KERNEL__
 
-#define __tag __attribute_used__ __attribute__((__section__(".taglist.init")))
+#define __tag __used __attribute__((__section__(".taglist.init")))
 #define __tagtable(tag, fn) \
 static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
@@ -218,7 +218,7 @@ struct early_params {
 };
 
 #define __early_param(name,fn)                                 \
-static struct early_params __early_##fn __attribute_used__     \
+static struct early_params __early_##fn __used                 \
 __attribute__((__section__(".early_param.init"))) = { name, fn }
 
 #endif  /*  __KERNEL__  */
index a3f4fe1742d0ac84abb7a3dc9c2996579ab3e123..f784d11f40b5e630f50bf573c8139d16e0cf473d 100644 (file)
@@ -15,6 +15,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+struct termios2 {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
 struct ktermios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
@@ -128,6 +139,7 @@ struct ktermios {
 #define HUPCL  0002000
 #define CLOCAL 0004000
 #define CBAUDEX 0010000
+#define    BOTHER 0010000
 #define    B57600 0010001
 #define   B115200 0010002
 #define   B230400 0010003
@@ -143,10 +155,12 @@ struct ktermios {
 #define  B3000000 0010015
 #define  B3500000 0010016
 #define  B4000000 0010017
-#define CIBAUD   002003600000  /* input baud rate (not used) */
+#define CIBAUD   002003600000          /* input baud rate */
 #define CMSPAR    010000000000         /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
 
+#define IBSHIFT           16
+
 /* c_lflag bits */
 #define ISIG   0000001
 #define ICANON 0000002
index 329c324c4040c9c3fcb0a1302465a4ed88d49209..293e3f1bc3f22c3c41e0ffd62d77ce9f9c66da70 100644 (file)
@@ -82,8 +82,10 @@ struct termio {
        copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
 })
 
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
index ccd0de010e81bb515d3aec39acb8abcf04ffadbd..71be4fded7e20f1b069f2dbe7ad3c6a5d63456ca 100644 (file)
 # define v6wbi_always_flags    (-1UL)
 #endif
 
+#ifdef CONFIG_CPU_TLB_V7
+# define v7wbi_possible_flags  v6wbi_tlb_flags
+# define v7wbi_always_flags    v6wbi_tlb_flags
+# ifdef _TLB
+#  define MULTI_TLB 1
+# else
+#  define _TLB v7wbi
+# endif
+#else
+# define v7wbi_possible_flags  0
+# define v7wbi_always_flags    (-1UL)
+#endif
+
 #ifndef _TLB
 #error Unknown TLB model
 #endif
index 10fd07c7666264b5f39c0387f66bf4d3200d94b7..e8256230647558a0841483c30cc1af8c20986217 100644 (file)
@@ -173,7 +173,7 @@ struct tagtable {
        int (*parse)(const struct tag *);
 };
 
-#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
+#define __tag __used __attribute__((__section__(".taglist")))
 #define __tagtable(tag, fn) \
 static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
index be303b3eef4096e06be42497583fec69ea097e94..6931af525da3201873274337a993d342d2c9b14b 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _ASM_SYSTEM_H
 #define _ASM_SYSTEM_H
 
+#include <linux/types.h>
 #include <linux/linkage.h>
 
 struct thread_struct;
index 14fae1fa87dfa3e177b46b0a830a2f01beb12f91..7f30cce528573ccbf4345021809dfd595d368d60 100644 (file)
@@ -35,7 +35,7 @@ struct bug_entry {
 #define WARN_ON(condition) ({                                          \
        typeof(condition) __ret_warn_on = (condition);                  \
        if (unlikely(__ret_warn_on)) {                                  \
-               printk("BUG: at %s:%d %s()\n", __FILE__,                \
+               printk("WARNING: at %s:%d %s()\n", __FILE__,            \
                        __LINE__, __FUNCTION__);                        \
                dump_stack();                                           \
        }                                                               \
index 8307b1bb337a055d123c1d6fa4fc2c48d9815604..84155eb67f1d3c7907c4453548e683c2c4ea8952 100644 (file)
@@ -14,8 +14,8 @@
        *(.data)                                                        \
        *(.data.init.refok)
 
-#define RODATA                                                         \
-       . = ALIGN(4096);                                                \
+#define RO_DATA(align)                                                 \
+       . = ALIGN((align));                                             \
        .rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {           \
                VMLINUX_SYMBOL(__start_rodata) = .;                     \
                *(.rodata) *(.rodata.*)                                 \
                VMLINUX_SYMBOL(__end_rodata) = .;                       \
        }                                                               \
                                                                        \
-       . = ALIGN(4096);
+       . = ALIGN((align));
+
+/* RODATA provided for backward compatibility.
+ * All archs are supposed to use RO_DATA() */
+#define RODATA RO_DATA(4096)
 
 #define SECURITY_INIT                                                  \
        .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
index 99b664aa20837e3f1d674800bc9377932267802e..49fc886a623278249302edf3c169c883526e8313 100644 (file)
@@ -78,7 +78,7 @@ struct thread_struct {
 do {                                                           \
        set_fs(USER_DS);           /* reads from user space */  \
        (_regs)->pc = (_pc);                                    \
-       (_regs)->ccr &= 0x00;      /* clear kernel flag */      \
+       (_regs)->ccr = 0x00;       /* clear all flags */        \
        (_regs)->er5 = current->mm->start_data; /* GOT base */  \
        wrusp((unsigned long)(_usp) - sizeof(unsigned long)*3); \
 } while(0)
index 0baa2f89463c70a96f3ef1b42ffe23adf63a5a55..437aac80171131b18f68721c0ecc716f6de13598 100644 (file)
@@ -182,7 +182,7 @@ static __inline__ int atomic_add_return(int i, atomic_t *v)
        int __i;
 #ifdef CONFIG_M386
        unsigned long flags;
-       if(unlikely(boot_cpu_data.x86==3))
+       if(unlikely(boot_cpu_data.x86 <= 3))
                goto no_xadd;
 #endif
        /* Modern 486+ processor */
index e13d3e98823f90a7ee8113855c5adf02b5b3a6a1..6e85975b9ed239cbf953ffd9ec70bd0ad34414fe 100644 (file)
@@ -135,7 +135,7 @@ static __inline__ long local_add_return(long i, local_t *l)
        long __i;
 #ifdef CONFIG_M386
        unsigned long flags;
-       if(unlikely(boot_cpu_data.x86==3))
+       if(unlikely(boot_cpu_data.x86 <= 3))
                goto no_xadd;
 #endif
        /* Modern 486+ processor */
index 5d03792d4f65f92f584f4e7477925e7be912c6b9..5b526357d178fa4b6e4d8f327cc839bd90e4080b 100644 (file)
@@ -30,6 +30,8 @@
 
 #ifdef __KERNEL__
 
+#include <acpi/pdc_intel.h>
+
 #include <linux/init.h>
 #include <linux/numa.h>
 #include <asm/system.h>
@@ -119,11 +121,6 @@ extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
 extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
 #endif
 
-/*
- * Refer Intel ACPI _PDC support document for bit definitions
- */
-#define ACPI_PDC_EST_CAPABILITY_SMP     0x8
-
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
diff --git a/include/asm-m68k/mmzone.h b/include/asm-m68k/mmzone.h
new file mode 100644 (file)
index 0000000..e1f1ec7
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _ASM_M68K_MMZONE_H_
+#define _ASM_M68K_MMZONE_H_
+
+extern pg_data_t pg_data_map[];
+
+#define NODE_DATA(nid)         (&pg_data_map[nid])
+#define NODE_MEM_MAP(nid)      (NODE_DATA(nid)->node_mem_map)
+
+#endif /* _ASM_M68K_MMZONE_H_ */
index c6d75af2d8d34ba5489085fb688b6099aa42fa05..382d20a6fc188409973b3cdeb74057d276b4aefd 100644 (file)
@@ -1,7 +1,39 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+       struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT {                             \
+       .fixup_start            = __start_fixup,        \
+       .fixup_end              = __stop_fixup,         \
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+
+
+enum m68k_fixup_type {
+       m68k_fixup_memoffset,
+       m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+       enum m68k_fixup_type type;
+       void *addr;
+};
+
+#define m68k_fixup(type, addr)                 \
+       "       .section \".m68k_fixup\",\"aw\"\n"      \
+       "       .long " #type "," #addr "\n"    \
+       "       .previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+                        struct m68k_fixup_info *end);
+
 #endif /* _ASM_M68K_MODULE_H */
index 61e4406ed96affcb989ef23e2ded6b6c9ea50d5a..b5b78c01eb6c900f427a2e46fbd77039198dfde3 100644 (file)
@@ -130,7 +130,7 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
 #define pte_present(pte)       (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,ptep)                ({ pte_val(*(ptep)) = 0; })
 
-#define pte_page(pte)          (mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)          virt_to_page(__va(pte_val(pte)))
 #define pte_pfn(pte)           (pte_val(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn, prot)     __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
@@ -143,7 +143,7 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
        while (--__i >= 0)                      \
                *__ptr++ = 0;                   \
 })
-#define pmd_page(pmd)          (mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pmd_page(pmd)          virt_to_page(__va(pmd_val(pmd)))
 
 
 #define pgd_none(pgd)          (!pgd_val(pgd))
@@ -223,10 +223,10 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address)
        return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
 #define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
-#define pte_unmap(pte) kunmap(pte)
-#define pte_unmap_nested(pte) kunmap(pte)
+#define pte_unmap(pte)         ((void)0)
+#define pte_unmap_nested(pte)  ((void)0)
 
 /*
  * Allocate and free page tables. The xxx_kernel() versions are
index fcc165ddd09e11e789a76c04208faef6b93937ee..9e6d0d6debdb39e5617902ed6231047edc0bb743 100644 (file)
@@ -27,6 +27,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/module.h>
+
 #define get_user_page(vaddr)           __get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)     free_page(addr)
 
@@ -114,18 +116,33 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #ifndef __ASSEMBLY__
 
+extern unsigned long m68k_memoffset;
+
 #ifndef CONFIG_SUN3
 
 #define WANT_PAGE_VIRTUAL
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern unsigned long m68k_memoffset;
 
-#define __pa(vaddr)            ((unsigned long)(vaddr)+m68k_memoffset)
-#define __va(paddr)            ((void *)((unsigned long)(paddr)-m68k_memoffset))
-#else
-#define __pa(vaddr)            virt_to_phys((void *)(vaddr))
-#define __va(paddr)            phys_to_virt((unsigned long)(paddr))
-#endif
+static inline unsigned long ___pa(void *vaddr)
+{
+       unsigned long paddr;
+       asm (
+               "1:     addl #0,%0\n"
+               m68k_fixup(%c2, 1b+2)
+               : "=r" (paddr)
+               : "0" (vaddr), "i" (m68k_fixup_memoffset));
+       return paddr;
+}
+#define __pa(vaddr)    ___pa((void *)(vaddr))
+static inline void *__va(unsigned long paddr)
+{
+       void *vaddr;
+       asm (
+               "1:     subl #0,%0\n"
+               m68k_fixup(%c2, 1b+2)
+               : "=r" (vaddr)
+               : "0" (paddr), "i" (m68k_fixup_memoffset));
+       return vaddr;
+}
 
 #else  /* !CONFIG_SUN3 */
 /* This #define is a horrible hack to suppress lots of warnings. --m */
@@ -161,11 +178,47 @@ static inline void *__va(unsigned long x)
 #define virt_to_pfn(kaddr)     (__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)       __va((pfn) << PAGE_SHIFT)
 
-#define virt_to_page(kaddr)    (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define page_to_virt(page)     ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+extern int m68k_virt_to_node_shift;
+
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define __virt_to_node(addr)   (&pg_data_map[0])
+#else
+extern struct pglist_data *pg_data_table[];
+
+static inline __attribute_const__ int __virt_to_node_shift(void)
+{
+       int shift;
+
+       asm (
+               "1:     moveq   #0,%0\n"
+               m68k_fixup(%c1, 1b)
+               : "=d" (shift)
+               : "i" (m68k_fixup_vnode_shift));
+       return shift;
+}
+
+#define __virt_to_node(addr)   (pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()])
+#endif
 
-#define pfn_to_page(pfn)       virt_to_page(pfn_to_virt(pfn))
-#define page_to_pfn(page)      virt_to_pfn(page_to_virt(page))
+#define virt_to_page(addr) ({                                          \
+       pfn_to_page(virt_to_pfn(addr));                                 \
+})
+#define page_to_virt(page) ({                                          \
+       pfn_to_virt(page_to_pfn(page));                                 \
+})
+
+#define pfn_to_page(pfn) ({                                            \
+       unsigned long __pfn = (pfn);                                    \
+       struct pglist_data *pgdat;                                      \
+       pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn));      \
+       pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn);          \
+})
+#define page_to_pfn(_page) ({                                          \
+       struct page *__p = (_page);                                     \
+       struct pglist_data *pgdat;                                      \
+       pgdat = &pg_data_map[page_to_nid(__p)];                         \
+       ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;          \
+})
 
 #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
 #define pfn_valid(pfn)         virt_addr_valid(pfn_to_virt(pfn))
index a9cfb4b99d88b206c43d145694d588d6dc99524b..4cb1a57ab763f103b20fe0aeb0c3c9dc3b7c62be 100644 (file)
@@ -8,11 +8,12 @@
 #include <asm/virtconvert.h>
 
 
-
 #ifdef CONFIG_SUN3
 #include <asm/sun3_pgalloc.h>
 #else
 #include <asm/motorola_pgalloc.h>
 #endif
 
+extern void m68k_setup_node(int node);
+
 #endif /* M68K_PGALLOC_H */
index 555b87a1f7e3220ff562c60ab0409b4273e90568..778a4c538eb2ed03da163506d93573622bb1a4ab 100644 (file)
@@ -107,22 +107,7 @@ extern void *empty_zero_page;
 /* 64-bit machines, beware!  SRB. */
 #define SIZEOF_PTR_LOG2                               2
 
-/*
- * Check if the addr/len goes up to the end of a physical
- * memory chunk.  Used for DMA functions.
- */
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * It makes no sense to consider whether we cross a memory boundary if
- * we support just one physical chunk of memory.
- */
-static inline int mm_end_of_chunk(unsigned long addr, int len)
-{
-       return 0;
-}
-#else
-int mm_end_of_chunk (unsigned long addr, int len);
-#endif
+#define mm_end_of_chunk(addr, len)     0
 
 extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
 
index 5156a28a18d82a722fb9b92879d6c5c413cfeb90..b9e62c1e7ae3d91bdc0b804046524313b595cef1 100644 (file)
@@ -132,8 +132,8 @@ static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *p
 #define pfn_pte(pfn, pgprot) \
 ({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
 
-#define pte_page(pte)          (mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
-#define pmd_page(pmd)          (mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)          virt_to_page(__pte_page(pte))
+#define pmd_page(pmd)          virt_to_page(__pmd_page(pmd))
 
 
 static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
index 83a87c9b1a16fa399f1dfa4126315b84f861421c..dea32fbc7e51c1c5bc995a1aa69ab57f6b1cf6f5 100644 (file)
@@ -8,56 +8,35 @@
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
+#include <linux/mmzone.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#endif
-
 /*
  * Change virtual addresses to physical addresses and vv.
  */
-#ifndef CONFIG_SUN3
-extern unsigned long mm_vtop(unsigned long addr) __attribute_const__;
-extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
-#else
-static inline unsigned long mm_vtop(unsigned long vaddr)
-{
-       return __pa(vaddr);
-}
-
-static inline unsigned long mm_ptov(unsigned long paddr)
-{
-       return (unsigned long)__va(paddr);
-}
-#endif
-
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-static inline unsigned long virt_to_phys(void *vaddr)
-{
-       return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
-}
-
-static inline void * phys_to_virt(unsigned long paddr)
-{
-       return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
-}
-#else
 static inline unsigned long virt_to_phys(void *address)
 {
-       return mm_vtop((unsigned long)address);
+       return __pa(address);
 }
 
 static inline void *phys_to_virt(unsigned long address)
 {
-       return (void *) mm_ptov(address);
+       return __va(address);
 }
-#endif
 
 /* Permanent address of a page. */
-#define __page_address(page)   (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)     virt_to_phys((void *)__page_address(page))
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define page_to_phys(page) \
+       __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
+#else
+#define page_to_phys(_page) ({                                         \
+       struct page *__page = _page;                                    \
+       struct pglist_data *pgdat;                                      \
+       pgdat = pg_data_table[page_to_nid(__page)];                     \
+       page_to_pfn(__page) << PAGE_SHIFT;                              \
+})
+#endif
 
 /*
  * IO bus memory addresses are 1:1 with the physical address,
index 92e62ef711edbac3d7aeedd7d73ffcccfc705fa4..c5f20df780e927e3146137989000ce0f0b39db9e 100644 (file)
        .endm
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-#ifdef CONFIG_CPU_SB1
-       .macro  fpu_enable_hazard
-       .set    push
-       .set    noreorder
-       .set    mips2
-       SSNOP
-       bnezl   $0, .+4
-        SSNOP
-       .set    pop
-       .endm
-#else
-       .macro  fpu_enable_hazard
-       .endm
-#endif
-
 /*
  * Temporary until all gas have MT ASE support
  */
index daaf9f98fc63ce7547a3660b915cb0ee2599e547..a9db576a9768e0493711dd07ee39e2bdc63b6e5f 100644 (file)
@@ -33,6 +33,7 @@ extern void prom_meminit(void);
 extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
 extern void mips_display_message(const char *str);
 extern void mips_display_word(unsigned int num);
+extern void mips_scroll_message(void);
 extern int get_ethernet_addr(char *ethernet_addr);
 
 /* Memory descriptor management. */
index 2f1087b3a20278241d719fa60d594f744780bebf..91c306fcfb725d18b247192cfb310093275bdb20 100644 (file)
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
index d9a3a8ca58a108ed0781e17ed9d80903a5176f7b..94d0294341d65a90006669e2a9bfd7851ab37452 100644 (file)
@@ -90,7 +90,8 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 static inline struct page *pte_alloc_one(struct mm_struct *mm,
                                         unsigned long address)
 {
-       return virt_to_page(pte_alloc_one_kernel(mm, address));
+       pte_t *pte = pte_alloc_one_kernel(mm, address);
+       return pte ? virt_to_page(pte) : NULL;
 }
 
 static inline void pte_free_kernel(pte_t *pte)
index 0a17682663d8f308411b26e8ba28eb91e1c8fe96..66714042e4383399a597ec5867a14e46e52ee1bc 100644 (file)
@@ -38,6 +38,15 @@ extern void pte_free_finish(void);
 
 static inline void tlb_flush(struct mmu_gather *tlb)
 {
+       struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var(ppc64_tlb_batch);
+
+       /* If there's a TLB batch pending, then we must flush it because the
+        * pages are going to be freed and we really don't want to have a CPU
+        * access a freed page because it has a stale TLB
+        */
+       if (tlbbatch->index)
+               __flush_tlb_pending(tlbbatch);
+
        pte_free_finish();
 }
 
index 86564e7a26aef3efe8fc827168df191997cbde47..39f41fcd509d78dbc02123bf8ff23fd769f09354 100644 (file)
@@ -24,6 +24,9 @@
 #define FRQMR1                 0xffc80014
 #else
 #define FRQCR                  0xffc00000
+#define FRQCR_PSTBY            0x0200
+#define FRQCR_PLLEN            0x0400
+#define FRQCR_CKOEN            0x0800
 #endif
 #define MIN_DIVISOR_NR         0
 #define MAX_DIVISOR_NR         3
index faf3051cd4290fd942c0c67d00fe3035607694dc..6034d4a29e73151434597f0ee1fd35d855c0738f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/sched.h>
 #include <linux/sysdev.h>
 #include <asm/cpu/dma.h>
 
index a0e55b09e4fd773b30d9acf30e2e89ed60f72340..aa80930ce8e4ccbc089132c8645309eedd9f7b1e 100644 (file)
@@ -116,13 +116,13 @@ void __raw_readsl(unsigned long addr, void *data, int longlen);
  * redefined by userlevel programs.
  */
 #ifdef __readb
-# define readb(a)      ({ unsigned long r_ = __raw_readb(a); mb(); r_; })
+# define readb(a)      ({ unsigned int r_ = __raw_readb(a); mb(); r_; })
 #endif
 #ifdef __raw_readw
-# define readw(a)      ({ unsigned long r_ = __raw_readw(a); mb(); r_; })
+# define readw(a)      ({ unsigned int r_ = __raw_readw(a); mb(); r_; })
 #endif
 #ifdef __raw_readl
-# define readl(a)      ({ unsigned long r_ = __raw_readl(a); mb(); r_; })
+# define readl(a)      ({ unsigned int r_ = __raw_readl(a); mb(); r_; })
 #endif
 
 #ifdef __raw_writeb
index 3a4acb3e38a15239f695d0f95313977f5cb2f2bc..907c062b4c9a8296eebc5f77964d12296ed35acf 100644 (file)
@@ -1,9 +1,7 @@
-#ifndef __ASM_SH_HITACHI_SE73180_H
-#define __ASM_SH_HITACHI_SE73180_H
+#ifndef __ASM_SH_SE73180_H
+#define __ASM_SH_SE73180_H
 
 /*
- * include/asm-sh/se/se73180.h
- *
  * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
  *
  * SH-Mobile SolutionEngine 73180 support
@@ -62,4 +60,7 @@
 #define __IO_PREFIX    sh73180se
 #include <asm/io_generic.h>
 
-#endif  /* __ASM_SH_HITACHI_SE73180_H */
+/* arch/sh/boards/se/73180/irq.c */
+int shmse_irq_demux(int irq);
+
+#endif  /* __ASM_SH_SE73180_H */
index 71ecddf70db382f7153b6f6888eec216056914b9..caa7b93f1bce4f2276e142fff92b081f92425855 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifdef CONFIG_SMP
 
-#include <asm/spinlock.h>
+#include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
 
index 2586eef07d57214ec977f50b818d61c1c0fff9ed..92f6e2008b2e00963a4fc6a7da2bea95d7b82594 100644 (file)
@@ -11,6 +11,7 @@
 #define __ASM_SH_SPINLOCK_H
 
 #include <asm/atomic.h>
+#include <asm/spinlock_types.h>
 
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
@@ -42,7 +43,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
 
 static inline void __raw_spin_unlock(raw_spinlock_t *lock)
 {
-       assert_spin_locked(lock);
+       //assert_spin_locked(lock);
 
        lock->lock = 0;
 }
@@ -88,6 +89,11 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
        __raw_spin_unlock(&rw->lock);
 }
 
+static inline int __raw_write_can_lock(raw_rwlock_t *rw)
+{
+       return (atomic_read(&rw->counter) == RW_LOCK_BIAS);
+}
+
 static inline int __raw_read_trylock(raw_rwlock_t *lock)
 {
        atomic_t *count = (atomic_t*)lock;
index 8c41b6c3aac87adc4fbd73d5320b95e7592c6b18..5c58134f2c4e35a31a402f69c3368e2a9033c326 100644 (file)
@@ -9,7 +9,9 @@ typedef struct {
        volatile unsigned long lock;
 } raw_spinlock_t;
 
-#define __SPIN_LOCK_UNLOCKED           { 0 }
+#define __RAW_SPIN_LOCK_UNLOCKED       { 1 }
+
+#include <asm/atomic.h>
 
 typedef struct {
        raw_spinlock_t lock;
index 731fa56e0c374c8413c41c8460f16f4844d7046b..bdca5416d8b0a74dd998f3cbb8517839cc8b52d1 100644 (file)
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
+ * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
  *
  * Additions by Keith M Wesolowski (wesolows@foobazco.org) based
  * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
 #ifndef __ARCH_SPARC_ATOMIC__
 #define __ARCH_SPARC_ATOMIC__
 
+#include <linux/types.h>
 
 typedef struct { volatile int counter; } atomic_t;
 
 #ifdef __KERNEL__
 
+/* Emulate cmpxchg() the same way we emulate atomics,
+ * by hashing the object address and indexing into an array
+ * of spinlocks to get a bit of performance...
+ *
+ * See arch/sparc/lib/atomic32.c for implementation.
+ *
+ * Cribbed from <asm-parisc/atomic.h>
+ */
+#define __HAVE_ARCH_CMPXCHG    1
+
+/* bug catcher for when unsupported size is used - won't link */
+extern void __cmpxchg_called_with_bad_pointer(void);
+/* we only need to support cmpxchg of a u32 on sparc */
+extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+
+/* don't worry...optimizer will get rid of most of this */
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
+{
+       switch(size) {
+       case 4:
+               return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
+       default:
+               __cmpxchg_called_with_bad_pointer();
+               break;
+       }
+       return old;
+}
+
+#define cmpxchg(ptr,o,n) ({                                            \
+       __typeof__(*(ptr)) _o_ = (o);                                   \
+       __typeof__(*(ptr)) _n_ = (n);                                   \
+       (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,       \
+                       (unsigned long)_n_, sizeof(*(ptr)));            \
+})
+
 #define ATOMIC_INIT(i)  { (i) }
 
 extern int __atomic_add_return(int, atomic_t *);
index 120422fdb02f349bb64e6bc01ad957cb3efebeaf..bf39d86c0c9ec6f3c74a8ff430109b4b431df615 100644 (file)
@@ -1,9 +1,8 @@
-/*  $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $
- *  include/asm-sparc64/bugs.h:  Sparc probes for various bugs.
+/* bugs.h: Sparc64 probes for various bugs.
  *
- *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
  */
-
+#include <asm/sstate.h>
 
 extern unsigned long loops_per_jiffy;
 
@@ -12,4 +11,5 @@ static void __init check_bugs(void)
 #ifndef CONFIG_SMP
        cpu_data(0).udelay_val = loops_per_jiffy;
 #endif
+       sstate_running();
 }
index e89922d6718c69ffb6095c592bc8a62622ae6a50..445026fbec35e4619ca3b5a1b005a88f9841d5d6 100644 (file)
 typedef struct {
        /* Dcache line 1 */
        unsigned int    __softirq_pending; /* must be 1st, see rtrap.S */
-       unsigned int    __pad0_1;
-       unsigned int    __pad0_2;
-       unsigned int    __pad1;
+       unsigned int    __pad0;
        unsigned long   clock_tick;     /* %tick's per second */
        unsigned long   udelay_val;
+       unsigned int    __pad1;
+       unsigned int    __pad2;
 
        /* Dcache line 2, rarely used */
        unsigned int    dcache_size;
@@ -30,8 +30,8 @@ typedef struct {
        unsigned int    icache_line_size;
        unsigned int    ecache_size;
        unsigned int    ecache_line_size;
-       unsigned int    __pad3;
-       unsigned int    __pad4;
+       int             core_id;
+       int             proc_id;
 } cpuinfo_sparc;
 
 DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
@@ -76,12 +76,18 @@ struct trap_per_cpu {
 
 /* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size.  */
        unsigned int            irq_worklist;
-       unsigned int            __pad1;
-       unsigned long           __pad2[3];
+       unsigned int            cpu_mondo_qmask;
+       unsigned int            dev_mondo_qmask;
+       unsigned int            resum_qmask;
+       unsigned int            nonresum_qmask;
+       unsigned int            __pad2[3];
 } __attribute__((aligned(64)));
 extern struct trap_per_cpu trap_block[NR_CPUS];
 extern void init_cur_cpu_trap(struct thread_info *);
 extern void setup_tba(void);
+extern int ncpus_probed;
+
+extern unsigned long real_hard_smp_processor_id(void);
 
 struct cpuid_patch_entry {
        unsigned int    addr;
@@ -122,6 +128,10 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
 #define TRAP_PER_CPU_TSB_HUGE          0xd0
 #define TRAP_PER_CPU_TSB_HUGE_TEMP     0xd8
 #define TRAP_PER_CPU_IRQ_WORKLIST      0xe0
+#define TRAP_PER_CPU_CPU_MONDO_QMASK   0xe4
+#define TRAP_PER_CPU_DEV_MONDO_QMASK   0xe8
+#define TRAP_PER_CPU_RESUM_QMASK       0xec
+#define TRAP_PER_CPU_NONRESUM_QMASK    0xf0
 
 #define TRAP_BLOCK_SZ_SHIFT            8
 
@@ -192,7 +202,7 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
  * the calculations done by the macro mid-stream.
  */
 #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
-       ldub    [THR + TI_CPU], REG1;                   \
+       lduh    [THR + TI_CPU], REG1;                   \
        sethi   %hi(__per_cpu_shift), REG3;             \
        sethi   %hi(__per_cpu_base), REG2;              \
        ldx     [REG3 + %lo(__per_cpu_shift)], REG3;    \
index 9329429fb7f6af6ae2c50ad92e24e83482b752f4..4e21c2f3065ca16988802fab9067f80c43e2dddc 100644 (file)
@@ -162,6 +162,22 @@ dma_mapping_error(dma_addr_t dma_addr)
 #else
 
 struct device;
+struct page;
+struct scatterlist;
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+       BUG();
+       return 0;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       BUG();
+       return 0;
+}
 
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
                         dma_addr_t *dma_handle, gfp_t flag)
@@ -176,6 +192,52 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
        BUG();
 }
 
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG();
+       return 0;
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+                enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+            unsigned long offset, size_t size,
+            enum dma_data_direction direction)
+{
+       BUG();
+       return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+          enum dma_data_direction direction)
+{
+       BUG();
+       return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+            enum dma_data_direction direction)
+{
+       BUG();
+}
+
 static inline void
 dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
                        enum dma_data_direction direction)
@@ -190,6 +252,27 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t siz
        BUG();
 }
 
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+                   enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+                      enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+       BUG();
+       return 0;
+}
+
 #endif /* PCI */
 
 
index a5558c87556db268252472162169a9c3be6069da..5c2f9d4b9f06070813dad3cfe907aca906bbe080 100644 (file)
@@ -73,6 +73,8 @@
 #define HV_ENOTSUPPORTED               13 /* Function not supported       */
 #define HV_ENOMAP                      14 /* No mapping found             */
 #define HV_ETOOMANY                    15 /* Too many items specified     */
+#define HV_ECHANNEL                    16 /* Invalid LDC channel          */
+#define HV_EBUSY                       17 /* Resource busy                */
 
 /* mach_exit()
  * TRAP:       HV_FAST_TRAP
  */
 #define HV_FAST_MACH_EXIT              0x00
 
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_exit(unsigned long exit_core);
+#endif
+
 /* Domain services.  */
 
 /* mach_desc()
  */
 #define HV_FAST_MACH_DESC              0x01
 
-/* mach_exit()
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
+                                    unsigned long buf_len,
+                                    unsigned long *real_buf_len);
+#endif
+
+/* mach_sir()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_MACH_SIR
  * ERRORS:     This service does not return.
  */
 #define HV_FAST_MACH_SIR               0x02
 
-/* mach_set_soft_state()
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_sir(void);
+#endif
+
+/* mach_set_watchdog()
  * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_SET_SOFT_STATE
- * ARG0:       software state
- * ARG1:       software state description pointer
+ * FUNCTION:   HV_FAST_MACH_SET_WATCHDOG
+ * ARG0:       timeout in milliseconds
  * RET0:       status
- * ERRORS:     EINVAL          software state not valid or software state
- *                             description is not NULL terminated
- *             ENORADDR        software state description pointer is not a
- *                             valid real address
- *             EBADALIGNED     software state description is not correctly
- *                             aligned
+ * RET1:       time remaining in milliseconds
  *
- * This allows the guest to report it's soft state to the hypervisor.  There
- * are two primary components to this state.  The first part states whether
- * the guest software is running or not.  The second containts optional
- * details specific to the software.
+ * A guest uses this API to set a watchdog timer.  Once the gues has set
+ * the timer, it must call the timer service again either to disable or
+ * postpone the expiration.  If the timer expires before being reset or
+ * disabled, then the hypervisor take a platform specific action leading
+ * to guest termination within a bounded time period.  The platform action
+ * may include recovery actions such as reporting the expiration to a
+ * Service Processor, and/or automatically restarting the gues.
  *
- * The software state argument is defined below in HV_SOFT_STATE_*, and
- * indicates whether the guest is operating normally or in a transitional
- * state.
+ * The 'timeout' parameter is specified in milliseconds, however the
+ * implementated granularity is given by the 'watchdog-resolution'
+ * property in the 'platform' node of the guest's machine description.
+ * The largest allowed timeout value is specified by the
+ * 'watchdog-max-timeout' property of the 'platform' node.
  *
- * The software state description argument is a real address of a data buffer
- * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
- * terminated 7-bit ASCII string of up to 31 characters not including the
- * NULL termination.
- */
-#define HV_FAST_MACH_SET_SOFT_STATE    0x03
-#define  HV_SOFT_STATE_NORMAL           0x01
-#define  HV_SOFT_STATE_TRANSITION       0x02
-
-/* mach_get_soft_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_GET_SOFT_STATE
- * ARG0:       software state description pointer
- * RET0:       status
- * RET1:       software state
- * ERRORS:     ENORADDR        software state description pointer is not a
- *                             valid real address
- *             EBADALIGNED     software state description is not correctly
- *                             aligned
+ * If the 'timeout' argument is not zero, the watchdog timer is set to
+ * expire after a minimum of 'timeout' milliseconds.
  *
- * Retrieve the current value of the guest's software state.  The rules
- * for the software state pointer are the same as for mach_set_soft_state()
- * above.
+ * If the 'timeout' argument is zero, the watchdog timer is disabled.
+ *
+ * If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
+ * property, the hypervisor leaves the watchdog timer state unchanged,
+ * and returns a status of EINVAL.
+ *
+ * The 'time remaining' return value is valid regardless of whether the
+ * return status is EOK or EINVAL.  A non-zero return value indicates the
+ * number of milliseconds that were remaining until the timer was to expire.
+ * If less than one millisecond remains, the return value is '1'.  If the
+ * watchdog timer was disabled at the time of the call, the return value is
+ * zero.
+ *
+ * If the hypervisor cannot support the exact timeout value requested, but
+ * can support a larger timeout value, the hypervisor may round the actual
+ * timeout to a value larger than the requested timeout, consequently the
+ * 'time remaining' return value may be larger than the previously requested
+ * timeout value.
+ *
+ * Any guest OS debugger should be aware that the watchdog service may be in
+ * use.  Consequently, it is recommended that the watchdog service is
+ * disabled upon debugger entry (e.g. reaching a breakpoint), and then
+ * re-enabled upon returning to normal execution.  The API has been designed
+ * with this in mind, and the 'time remaining' result of the disable call may
+ * be used directly as the timeout argument of the re-enable call.
  */
-#define HV_FAST_MACH_GET_SOFT_STATE    0x04
+#define HV_FAST_MACH_SET_WATCHDOG      0x05
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
+                                            unsigned long *orig_timeout);
+#endif
 
 /* CPU services.
  *
  * FUNCTION:   HV_FAST_CPU_START
  * ARG0:       CPU ID
  * ARG1:       PC
- * ARG1:       RTBA
- * ARG1:       target ARG0
+ * ARG2:       RTBA
+ * ARG3:       target ARG0
  * RET0:       status
  * ERRORS:     ENOCPU          Invalid CPU ID
  *             EINVAL          Target CPU ID is not in the stopped state
  */
 #define HV_FAST_CPU_START              0x10
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_start(unsigned long cpuid,
+                                    unsigned long pc,
+                                    unsigned long rtba,
+                                    unsigned long arg0);
+#endif
+
 /* cpu_stop()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_CPU_STOP
  */
 #define HV_FAST_CPU_STOP               0x11
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
+#endif
+
 /* cpu_yield()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_CPU_YIELD
@@ -588,6 +624,11 @@ struct hv_fault_status {
  */
 #define HV_FAST_MMU_TSB_CTX0           0x20
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
+                                       unsigned long tsb_desc_ra);
+#endif
+
 /* mmu_tsb_ctxnon0()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_MMU_TSB_CTXNON0
@@ -694,6 +735,13 @@ struct hv_fault_status {
  */
 #define HV_FAST_MMU_MAP_PERM_ADDR      0x25
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
+                                            unsigned long set_to_zero,
+                                            unsigned long tte,
+                                            unsigned long flags);
+#endif
+
 /* mmu_fault_area_conf()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_MMU_FAULT_AREA_CONF
@@ -892,6 +940,10 @@ struct hv_fault_status {
  */
 #define HV_FAST_TOD_GET                        0x50
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_get(unsigned long *time);
+#endif
+
 /* tod_set()
  * TRAP:       HV_FAST_TRAP
  * FUNCTION:   HV_FAST_TOD_SET
@@ -905,6 +957,10 @@ struct hv_fault_status {
  */
 #define HV_FAST_TOD_SET                        0x51
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_set(unsigned long time);
+#endif
+
 /* Console services */
 
 /* con_getchar()
@@ -988,6 +1044,133 @@ extern unsigned long sun4v_con_write(unsigned long buffer,
                                     unsigned long *bytes_written);
 #endif
 
+/* mach_set_soft_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_SET_SOFT_STATE
+ * ARG0:       software state
+ * ARG1:       software state description pointer
+ * RET0:       status
+ * ERRORS:     EINVAL          software state not valid or software state
+ *                             description is not NULL terminated
+ *             ENORADDR        software state description pointer is not a
+ *                             valid real address
+ *             EBADALIGNED     software state description is not correctly
+ *                             aligned
+ *
+ * This allows the guest to report it's soft state to the hypervisor.  There
+ * are two primary components to this state.  The first part states whether
+ * the guest software is running or not.  The second containts optional
+ * details specific to the software.
+ *
+ * The software state argument is defined below in HV_SOFT_STATE_*, and
+ * indicates whether the guest is operating normally or in a transitional
+ * state.
+ *
+ * The software state description argument is a real address of a data buffer
+ * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
+ * terminated 7-bit ASCII string of up to 31 characters not including the
+ * NULL termination.
+ */
+#define HV_FAST_MACH_SET_SOFT_STATE    0x70
+#define  HV_SOFT_STATE_NORMAL           0x01
+#define  HV_SOFT_STATE_TRANSITION       0x02
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
+                                              unsigned long msg_string_ra);
+#endif
+
+/* mach_get_soft_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_GET_SOFT_STATE
+ * ARG0:       software state description pointer
+ * RET0:       status
+ * RET1:       software state
+ * ERRORS:     ENORADDR        software state description pointer is not a
+ *                             valid real address
+ *             EBADALIGNED     software state description is not correctly
+ *                             aligned
+ *
+ * Retrieve the current value of the guest's software state.  The rules
+ * for the software state pointer are the same as for mach_set_soft_state()
+ * above.
+ */
+#define HV_FAST_MACH_GET_SOFT_STATE    0x71
+
+/* svc_send()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_SEND
+ * ARG0:       service ID
+ * ARG1:       buffer real address
+ * ARG2:       buffer size
+ * RET0:       STATUS
+ * RET1:       sent_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_SEND               0x80
+
+/* svc_recv()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_RECV
+ * ARG0:       service ID
+ * ARG1:       buffer real address
+ * ARG2:       buffer size
+ * RET0:       STATUS
+ * RET1:       recv_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_RECV               0x81
+
+/* svc_getstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_GETSTATUS
+ * ARG0:       service ID
+ * RET0:       STATUS
+ * RET1:       status bits
+ */
+#define HV_FAST_SVC_GETSTATUS          0x82
+
+/* svc_setstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_SETSTATUS
+ * ARG0:       service ID
+ * ARG1:       bits to set
+ * RET0:       STATUS
+ */
+#define HV_FAST_SVC_SETSTATUS          0x83
+
+/* svc_clrstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_CLRSTATUS
+ * ARG0:       service ID
+ * ARG1:       bits to clear
+ * RET0:       STATUS
+ */
+#define HV_FAST_SVC_CLRSTATUS          0x84
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_svc_send(unsigned long svc_id,
+                                   unsigned long buffer,
+                                   unsigned long buffer_size,
+                                   unsigned long *sent_bytes);
+extern unsigned long sun4v_svc_recv(unsigned long svc_id,
+                                   unsigned long buffer,
+                                   unsigned long buffer_size,
+                                   unsigned long *recv_bytes);
+extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
+                                        unsigned long *status_bits);
+extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
+                                        unsigned long status_bits);
+extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
+                                        unsigned long status_bits);
+#endif
+
 /* Trap trace services.
  *
  * The hypervisor provides a trap tracing capability for privileged
@@ -1379,6 +1562,113 @@ extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
 extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
 #endif
 
+/* vintr_get_cookie()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_COOKIE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       cookie
+ */
+#define HV_FAST_VINTR_GET_COOKIE       0xa7
+
+/* vintr_set_cookie()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_COOKIE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       cookie
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_COOKIE       0xa8
+
+/* vintr_get_valid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_VALID
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       valid state
+ */
+#define HV_FAST_VINTR_GET_VALID                0xa9
+
+/* vintr_set_valid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_VALID
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       valid state
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_VALID                0xaa
+
+/* vintr_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_STATE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       state
+ */
+#define HV_FAST_VINTR_GET_STATE                0xab
+
+/* vintr_set_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_STATE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       state
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_STATE                0xac
+
+/* vintr_get_target()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_TARGET
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       cpuid
+ */
+#define HV_FAST_VINTR_GET_TARGET       0xad
+
+/* vintr_set_target()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_TARGET
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       cpuid
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_TARGET       0xae
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long *cookie);
+extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long cookie);
+extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long *valid);
+extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long valid);
+extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long *state);
+extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long state);
+extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long *cpuid);
+extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long cpuid);
+#endif
+
 /* PCI IO services.
  *
  * See the terminology descriptions in the device interrupt services
@@ -2037,6 +2327,346 @@ extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cp
  */
 #define HV_FAST_PCI_MSG_SETVALID       0xd3
 
+/* Logical Domain Channel services.  */
+
+#define LDC_CHANNEL_DOWN               0
+#define LDC_CHANNEL_UP                 1
+#define LDC_CHANNEL_RESETTING          2
+
+/* ldc_tx_qconf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_QCONF
+ * ARG0:       channel ID
+ * ARG1:       real address base of queue
+ * ARG2:       num entries in queue
+ * RET0:       status
+ *
+ * Configure transmit queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * Upon configuration of a valid transmit queue the head and tail
+ * pointers are set to a hypervisor specific identical value indicating
+ * that the queue initially is empty.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.  A transmit queue may be
+ * specified even in the event that the LDC is down (peer endpoint has no
+ * receive queue specified).  Transmission will begin as soon as the peer
+ * endpoint defines a receive queue.
+ *
+ * It is recommended that a guest wait for a transmit queue to empty prior
+ * to reconfiguring it, or un-configuring it.  Re or un-configuring of a
+ * non-empty transmit queue behaves exactly as defined above, however it
+ * is undefined as to how many of the pending entries in the original queue
+ * will be delivered prior to the re-configuration taking effect.
+ * Furthermore, as the queue configuration causes a reset of the head and
+ * tail pointers there is no way for a guest to determine how many entries
+ * have been sent after the configuration operation.
+ */
+#define HV_FAST_LDC_TX_QCONF           0xe0
+
+/* ldc_tx_qinfo()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_QINFO
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       real address base of queue
+ * RET2:       num entries in queue
+ *
+ * Return the configuration info for the transmit queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no transmit
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_TX_QINFO           0xe1
+
+/* ldc_tx_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_GET_STATE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       head offset
+ * RET2:       tail offset
+ * RET3:       channel state
+ *
+ * Return the transmit state, and the head and tail queue pointers, for
+ * the transmit queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the transmit queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_TX_GET_STATE       0xe2
+
+/* ldc_tx_set_qtail()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_SET_QTAIL
+ * ARG0:       channel ID
+ * ARG1:       tail offset
+ * RET0:       status
+ *
+ * Update the tail pointer for the transmit queue associated with the LDC
+ * endpoint defined by the given channel ID.  The tail offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to increase
+ * the number of pending entries on the transmit queue.  Any attempt to
+ * decrease the number of pending transmit queue entires is considered
+ * an invalid tail offset and will result in an EINVAL error.
+ *
+ * Since the tail of the transmit queue may not be moved backwards, the
+ * transmit queue may be flushed by configuring a new transmit queue,
+ * whereupon the hypervisor will configure the initial transmit head and
+ * tail pointers to be equal.
+ */
+#define HV_FAST_LDC_TX_SET_QTAIL       0xe3
+
+/* ldc_rx_qconf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_QCONF
+ * ARG0:       channel ID
+ * ARG1:       real address base of queue
+ * ARG2:       num entries in queue
+ * RET0:       status
+ *
+ * Configure receive queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * If a valid receive queue is specified for a local endpoint the LDC is
+ * in the up state for the purpose of transmission to this endpoint.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.
+ *
+ * As receive queue configuration causes a reset of the queue's head and
+ * tail pointers there is no way for a gues to determine how many entries
+ * have been received between a preceeding ldc_get_rx_state() API call
+ * and the completion of the configuration operation.  It should be noted
+ * that datagram delivery is not guarenteed via domain channels anyway,
+ * and therefore any higher protocol should be resilient to datagram
+ * loss if necessary.  However, to overcome this specific race potential
+ * it is recommended, for example, that a higher level protocol be employed
+ * to ensure either retransmission, or ensure that no datagrams are pending
+ * on the peer endpoint's transmit queue prior to the configuration process.
+ */
+#define HV_FAST_LDC_RX_QCONF           0xe4
+
+/* ldc_rx_qinfo()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_QINFO
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       real address base of queue
+ * RET2:       num entries in queue
+ *
+ * Return the configuration info for the receive queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no receive
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_RX_QINFO           0xe5
+
+/* ldc_rx_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_GET_STATE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       head offset
+ * RET2:       tail offset
+ * RET3:       channel state
+ *
+ * Return the receive state, and the head and tail queue pointers, for
+ * the receive queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the receive queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_RX_GET_STATE       0xe6
+
+/* ldc_rx_set_qhead()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_SET_QHEAD
+ * ARG0:       channel ID
+ * ARG1:       head offset
+ * RET0:       status
+ *
+ * Update the head pointer for the receive queue associated with the LDC
+ * endpoint defined by the given channel ID.  The head offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to decrease
+ * the number of pending entries on the receive queue.  Any attempt to
+ * increase the number of pending receive queue entires is considered
+ * an invalid head offset and will result in an EINVAL error.
+ *
+ * The receive queue may be flushed by setting the head offset equal
+ * to the current tail offset.
+ */
+#define HV_FAST_LDC_RX_SET_QHEAD       0xe7
+
+/* LDC Map Table Entry.  Each slot is defined by a translation table
+ * entry, as specified by the LDC_MTE_* bits below, and a 64-bit
+ * hypervisor invalidation cookie.
+ */
+#define LDC_MTE_PADDR  0x0fffffffffffe000 /* pa[55:13]          */
+#define LDC_MTE_COPY_W 0x0000000000000400 /* copy write access  */
+#define LDC_MTE_COPY_R 0x0000000000000200 /* copy read access   */
+#define LDC_MTE_IOMMU_W        0x0000000000000100 /* IOMMU write access */
+#define LDC_MTE_IOMMU_R        0x0000000000000080 /* IOMMU read access  */
+#define LDC_MTE_EXEC   0x0000000000000040 /* execute            */
+#define LDC_MTE_WRITE  0x0000000000000020 /* read               */
+#define LDC_MTE_READ   0x0000000000000010 /* write              */
+#define LDC_MTE_SZALL  0x000000000000000f /* page size bits     */
+#define LDC_MTE_SZ16GB 0x0000000000000007 /* 16GB page          */
+#define LDC_MTE_SZ2GB  0x0000000000000006 /* 2GB page           */
+#define LDC_MTE_SZ256MB        0x0000000000000005 /* 256MB page         */
+#define LDC_MTE_SZ32MB 0x0000000000000004 /* 32MB page          */
+#define LDC_MTE_SZ4MB  0x0000000000000003 /* 4MB page           */
+#define LDC_MTE_SZ512K 0x0000000000000002 /* 512K page          */
+#define LDC_MTE_SZ64K  0x0000000000000001 /* 64K page           */
+#define LDC_MTE_SZ8K   0x0000000000000000 /* 8K page            */
+
+#ifndef __ASSEMBLY__
+struct ldc_mtable_entry {
+       unsigned long   mte;
+       unsigned long   cookie;
+};
+#endif
+
+/* ldc_set_map_table()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_SET_MAP_TABLE
+ * ARG0:       channel ID
+ * ARG1:       table real address
+ * ARG2:       num entries
+ * RET0:       status
+ *
+ * Register the MTE table at the given table real address, with the
+ * specified num entries, for the LDC indicated by the given channel
+ * ID.
+ */
+#define HV_FAST_LDC_SET_MAP_TABLE      0xea
+
+/* ldc_get_map_table()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_GET_MAP_TABLE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       table real address
+ * RET2:       num entries
+ *
+ * Return the configuration of the current mapping table registered
+ * for the given channel ID.
+ */
+#define HV_FAST_LDC_GET_MAP_TABLE      0xeb
+
+#define LDC_COPY_IN    0
+#define LDC_COPY_OUT   1
+
+/* ldc_copy()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_COPY
+ * ARG0:       channel ID
+ * ARG1:       LDC_COPY_* direction code
+ * ARG2:       target real address
+ * ARG3:       local real address
+ * ARG4:       length in bytes
+ * RET0:       status
+ * RET1:       actual length in bytes
+ */
+#define HV_FAST_LDC_COPY               0xec
+
+#define LDC_MEM_READ   1
+#define LDC_MEM_WRITE  2
+#define LDC_MEM_EXEC   4
+
+/* ldc_mapin()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_MAPIN
+ * ARG0:       channel ID
+ * ARG1:       cookie
+ * RET0:       status
+ * RET1:       real address
+ * RET2:       LDC_MEM_* permissions
+ */
+#define HV_FAST_LDC_MAPIN              0xed
+
+/* ldc_unmap()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_UNMAP
+ * ARG0:       real address
+ * RET0:       status
+ */
+#define HV_FAST_LDC_UNMAP              0xee
+
+/* ldc_revoke()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_REVOKE
+ * ARG0:       cookie
+ * ARG1:       ldc_mtable_entry cookie
+ * RET0:       status
+ */
+#define HV_FAST_LDC_REVOKE             0xef
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
+                                       unsigned long ra,
+                                       unsigned long num_entries);
+extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
+                                       unsigned long *ra,
+                                       unsigned long *num_entries);
+extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
+                                           unsigned long *head_off,
+                                           unsigned long *tail_off,
+                                           unsigned long *chan_state);
+extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
+                                           unsigned long tail_off);
+extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
+                                       unsigned long ra,
+                                       unsigned long num_entries);
+extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
+                                       unsigned long *ra,
+                                       unsigned long *num_entries);
+extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
+                                           unsigned long *head_off,
+                                           unsigned long *tail_off,
+                                           unsigned long *chan_state);
+extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
+                                           unsigned long head_off);
+extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
+                                            unsigned long ra,
+                                            unsigned long num_entries);
+extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
+                                            unsigned long *ra,
+                                            unsigned long *num_entries);
+extern unsigned long sun4v_ldc_copy(unsigned long channel,
+                                   unsigned long dir_code,
+                                   unsigned long tgt_raddr,
+                                   unsigned long lcl_raddr,
+                                   unsigned long len,
+                                   unsigned long *actual_len);
+extern unsigned long sun4v_ldc_mapin(unsigned long channel,
+                                    unsigned long cookie,
+                                    unsigned long *ra,
+                                    unsigned long *perm);
+extern unsigned long sun4v_ldc_unmap(unsigned long ra);
+extern unsigned long sun4v_ldc_revoke(unsigned long cookie,
+                                     unsigned long mte_cookie);
+#endif
+
 /* Performance counter services.  */
 
 #define HV_PERF_JBUS_PERF_CTRL_REG     0x00
@@ -2168,6 +2798,105 @@ struct hv_mmu_statistics {
  */
 #define HV_FAST_MMUSTAT_INFO           0x103
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
+extern unsigned long sun4v_mmustat_info(unsigned long *ra);
+#endif
+
+/* NCS crypto services  */
+
+/* ncs_request() sub-function numbers */
+#define HV_NCS_QCONF                   0x01
+#define HV_NCS_QTAIL_UPDATE            0x02
+
+#ifndef __ASSEMBLY__
+struct hv_ncs_queue_entry {
+       /* MAU Control Register */
+       unsigned long   mau_control;
+#define MAU_CONTROL_INV_PARITY 0x0000000000002000
+#define MAU_CONTROL_STRAND     0x0000000000001800
+#define MAU_CONTROL_BUSY       0x0000000000000400
+#define MAU_CONTROL_INT                0x0000000000000200
+#define MAU_CONTROL_OP         0x00000000000001c0
+#define MAU_CONTROL_OP_SHIFT   6
+#define MAU_OP_LOAD_MA_MEMORY  0x0
+#define MAU_OP_STORE_MA_MEMORY 0x1
+#define MAU_OP_MODULAR_MULT    0x2
+#define MAU_OP_MODULAR_REDUCE  0x3
+#define MAU_OP_MODULAR_EXP_LOOP        0x4
+#define MAU_CONTROL_LEN                0x000000000000003f
+#define MAU_CONTROL_LEN_SHIFT  0
+
+       /* Real address of bytes to load or store bytes
+        * into/out-of the MAU.
+        */
+       unsigned long   mau_mpa;
+
+       /* Modular Arithmetic MA Offset Register.  */
+       unsigned long   mau_ma;
+
+       /* Modular Arithmetic N Prime Register.  */
+       unsigned long   mau_np;
+};
+
+struct hv_ncs_qconf_arg {
+       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
+       unsigned long   base;     /* Real address base of queue */
+       unsigned long   end;      /* Real address end of queue */
+       unsigned long   num_ents; /* Number of entries in queue */
+};
+
+struct hv_ncs_qtail_update_arg {
+       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
+       unsigned long   tail;     /* New tail index to use */
+       unsigned long   syncflag; /* only SYNCFLAG_SYNC is implemented */
+#define HV_NCS_SYNCFLAG_SYNC   0x00
+#define HV_NCS_SYNCFLAG_ASYNC  0x01
+};
+#endif
+
+/* ncs_request()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_NCS_REQUEST
+ * ARG0:       NCS sub-function
+ * ARG1:       sub-function argument real address
+ * ARG2:       size in bytes of sub-function argument
+ * RET0:       status
+ *
+ * The MAU chip of the Niagara processor is not directly accessible
+ * to privileged code, instead it is programmed indirectly via this
+ * hypervisor API.
+ *
+ * The interfaces defines a queue of MAU operations to perform.
+ * Privileged code registers a queue with the hypervisor by invoking
+ * this HVAPI with the HV_NCS_QCONF sub-function, which defines the
+ * base, end, and number of entries of the queue.  Each queue entry
+ * contains a MAU register struct block.
+ *
+ * The privileged code then proceeds to add entries to the queue and
+ * then invoke the HV_NCS_QTAIL_UPDATE sub-function.  Since only
+ * synchronous operations are supported by the current hypervisor,
+ * HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
+ * completion and return HV_EOK, or return an error code.
+ *
+ * The real address of the sub-function argument must be aligned on at
+ * least an 8-byte boundary.
+ *
+ * The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
+ * offset, into the queue and must be less than or equal the 'num_ents'
+ * argument given in the HV_NCS_QCONF call.
+ */
+#define HV_FAST_NCS_REQUEST            0x110
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ncs_request(unsigned long request,
+                                      unsigned long arg_ra,
+                                      unsigned long arg_size);
+#endif
+
+#define HV_FAST_FIRE_GET_PERFREG       0x120
+#define HV_FAST_FIRE_SET_PERFREG       0x121
+
 /* Function numbers for HV_CORE_TRAP.  */
 #define HV_CORE_SET_VER                        0x00
 #define HV_CORE_PUTCHAR                        0x01
@@ -2204,6 +2933,7 @@ extern void sun4v_hvapi_unregister(unsigned long group);
 extern int sun4v_hvapi_get(unsigned long group,
                           unsigned long *major,
                           unsigned long *minor);
+extern void sun4v_hvapi_init(void);
 #endif
 
 #endif /* !(_SPARC64_HYPERVISOR_H) */
index 627e3396a5f0c136bf486eada3a6706b76f68486..9974c7b0aebc18563568cd50a5b5c2c457e5b908 100644 (file)
@@ -32,7 +32,6 @@ enum die_val {
        DIE_TRAP,
        DIE_TRAP_TL1,
        DIE_CALL,
-       DIE_PAGE_FAULT,
 };
 
 #endif
diff --git a/include/asm-sparc64/mdesc.h b/include/asm-sparc64/mdesc.h
new file mode 100644 (file)
index 0000000..124eb8c
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _SPARC64_MDESC_H
+#define _SPARC64_MDESC_H
+
+#include <linux/types.h>
+#include <asm/prom.h>
+
+struct mdesc_node;
+struct mdesc_arc {
+       const char              *name;
+       struct mdesc_node       *arc;
+};
+
+struct mdesc_node {
+       const char              *name;
+       u64                     node;
+       unsigned int            unique_id;
+       unsigned int            num_arcs;
+       struct property         *properties;
+       struct mdesc_node       *hash_next;
+       struct mdesc_node       *allnodes_next;
+       struct mdesc_arc        arcs[0];
+};
+
+extern struct mdesc_node *md_find_node_by_name(struct mdesc_node *from,
+                                              const char *name);
+#define md_for_each_node_by_name(__mn, __name) \
+       for (__mn = md_find_node_by_name(NULL, __name); __mn; \
+            __mn = md_find_node_by_name(__mn, __name))
+
+extern struct property *md_find_property(const struct mdesc_node *mp,
+                                        const char *name,
+                                        int *lenp);
+extern const void *md_get_property(const struct mdesc_node *mp,
+                                  const char *name,
+                                  int *lenp);
+
+extern void sun4v_mdesc_init(void);
+
+#endif
index 6a0da3b1695c0c913f484bf88d90bf7378c9594a..992f9f7a476cef4e79fa7dee9403d1e835ddf0c9 100644 (file)
@@ -316,11 +316,8 @@ extern int prom_setprop(int node, const char *prop_name, char *prop_value,
                        
 extern int prom_pathtoinode(const char *path);
 extern int prom_inst2pkg(int);
-
-/* CPU probing helpers.  */
-struct device_node;
-int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid);
-int cpu_find_by_mid(int mid, struct device_node **prom_node);
+extern int prom_service_exists(const char *service_name);
+extern void prom_sun4v_guest_soft_state(void);
 
 /* Client interface level routines. */
 extern void prom_set_trap_table(unsigned long tba);
index ced8cbde046dab27cc505aea639fc43e25914b4f..88db872ce2f8aed9c2b23689dc04375976e0d363 100644 (file)
@@ -5,7 +5,8 @@
 
 #ifdef CONFIG_SMP
 
-extern void setup_per_cpu_areas(void);
+#define setup_per_cpu_areas()                  do { } while (0)
+extern void real_setup_per_cpu_areas(void);
 
 extern unsigned long __per_cpu_base;
 extern unsigned long __per_cpu_shift;
@@ -34,6 +35,7 @@ do {                                                          \
 } while (0)
 #else /* ! SMP */
 
+#define real_setup_per_cpu_areas()             do { } while (0)
 #define DEFINE_PER_CPU(type, name) \
     __typeof__(type) per_cpu__##name
 
index ddad5f99ac7f0851ed630bd5a3d8f26d80c87b70..b4df3042add06fa5dbde80de1d43b8add4dd800b 100644 (file)
@@ -90,6 +90,7 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
        const char *type, const char *compat);
 extern struct device_node *of_find_node_by_path(const char *path);
 extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_find_node_by_cpuid(int cpuid);
 extern struct device_node *of_get_parent(const struct device_node *node);
 extern struct device_node *of_get_next_child(const struct device_node *node,
                                             struct device_node *prev);
index 869d16fb907bb134dd040dcef05f91806c6b5ff4..4fb8c4bfb84869bf58c302f811bdb2857aecd69d 100644 (file)
@@ -33,6 +33,8 @@ extern cpumask_t phys_cpu_present_map;
 #define cpu_possible_map phys_cpu_present_map
 
 extern cpumask_t cpu_sibling_map[NR_CPUS];
+extern cpumask_t cpu_core_map[NR_CPUS];
+extern int sparc64_multi_core;
 
 /*
  *     General functions that each host system must provide.
@@ -41,7 +43,7 @@ extern cpumask_t cpu_sibling_map[NR_CPUS];
 extern int hard_smp_processor_id(void);
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-extern void smp_setup_cpu_possible_map(void);
+extern void smp_fill_in_sib_core_maps(void);
 extern unsigned char boot_cpu_id;
 
 #endif /* !(__ASSEMBLY__) */
@@ -49,7 +51,7 @@ extern unsigned char boot_cpu_id;
 #else
 
 #define hard_smp_processor_id()                0
-#define smp_setup_cpu_possible_map() do { } while (0)
+#define smp_fill_in_sib_core_maps() do { } while (0)
 #define boot_cpu_id    (0)
 
 #endif /* !(CONFIG_SMP) */
diff --git a/include/asm-sparc64/sstate.h b/include/asm-sparc64/sstate.h
new file mode 100644 (file)
index 0000000..a7c35db
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_SSTATE_H
+#define _SPARC64_SSTATE_H
+
+extern void sstate_booting(void);
+extern void sstate_running(void);
+extern void sstate_halt(void);
+extern void sstate_poweroff(void);
+extern void sstate_panic(void);
+extern void sstate_reboot(void);
+
+extern void sun4v_sstate_init(void);
+
+#endif /* _SPARC64_SSTATE_H */
index 2ebf7f27bf918cb2394da774ecc970c5877e3a24..98252cd44dd6db88b3f91367b94c36f4e8d4bae1 100644 (file)
@@ -38,8 +38,8 @@ struct thread_info {
        /* D$ line 1 */
        struct task_struct      *task;
        unsigned long           flags;
-       __u8                    cpu;
        __u8                    fpsaved[7];
+       __u8                    pad;
        unsigned long           ksp;
 
        /* D$ line 2 */
@@ -49,7 +49,7 @@ struct thread_info {
        int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
        __u8                    new_child;
        __u8                    syscall_noerror;
-       __u16                   __pad;
+       __u16                   cpu;
 
        unsigned long           *utraps;
 
@@ -83,8 +83,7 @@ struct thread_info {
 #define TI_CURRENT_DS  (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
 #define TI_FPDEPTH     (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
 #define TI_WSAVED      (TI_FLAGS + TI_FLAG_BYTE_WSAVED)
-#define TI_CPU         0x00000010
-#define TI_FPSAVED     0x00000011
+#define TI_FPSAVED     0x00000010
 #define TI_KSP         0x00000018
 #define TI_FAULT_ADDR  0x00000020
 #define TI_KREGS       0x00000028
@@ -92,6 +91,7 @@ struct thread_info {
 #define TI_PRE_COUNT   0x00000038
 #define TI_NEW_CHILD   0x0000003c
 #define TI_SYS_NOERROR 0x0000003d
+#define TI_CPU         0x0000003e
 #define TI_UTRAPS      0x00000040
 #define TI_REG_WINDOW  0x00000048
 #define TI_RWIN_SPTRS  0x000003c8      
index 98a6c613589dcbe29205d0705ebf871b6f577b22..290ac75f385bee443a24eb9bba11fb70783edc46 100644 (file)
@@ -1,9 +1,17 @@
 #ifndef _ASM_SPARC64_TOPOLOGY_H
 #define _ASM_SPARC64_TOPOLOGY_H
 
-#include <asm/spitfire.h>
-#define smt_capable()  (tlb_type == hypervisor)
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu)      (cpu_data(cpu).proc_id)
+#define topology_core_id(cpu)                  (cpu_data(cpu).core_id)
+#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu)          (cpu_sibling_map[cpu])
+#define mc_capable()                           (sparc64_multi_core)
+#define smt_capable()                          (sparc64_multi_core)
+#endif /* CONFIG_SMP */
 
 #include <asm-generic/topology.h>
 
+#define cpu_coregroup_map(cpu)                 (cpu_core_map[cpu])
+
 #endif /* _ASM_SPARC64_TOPOLOGY_H */
index ab55ffcb7bf4963cb07f61a730f6b89390e43771..76e4299dd9bc957667668bd39b38713d8cb9440e 100644 (file)
@@ -271,7 +271,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
        sethi           %hi(swapper_4m_tsb), REG1; \
        or              REG1, %lo(swapper_4m_tsb), REG1; \
-       and             TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \
+       and             TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
        sllx            REG2, 4, REG2; \
        add             REG1, REG2, REG2; \
        KTSB_LOAD_QUAD(REG2, REG3); \
index d815649617aadb0701dee98672dd53661d9bb7d2..1c1e0d933eea8311db44907231d94a62b025c334 100644 (file)
@@ -7,7 +7,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
  */
 
 #ifndef _XTENSA_BITOPS_H
 
 #if XCHAL_HAVE_NSA
 
-static __inline__ int __cntlz (unsigned long x)
+static inline unsigned long __cntlz (unsigned long x)
 {
        int lz;
        asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
-       return 31 - lz;
+       return lz;
 }
 
-#else
-
-static __inline__ int __cntlz (unsigned long x)
-{
-       unsigned long sum, x1, x2, x4, x8, x16;
-       x1  = x & 0xAAAAAAAA;
-       x2  = x & 0xCCCCCCCC;
-       x4  = x & 0xF0F0F0F0;
-       x8  = x & 0xFF00FF00;
-       x16 = x & 0xFFFF0000;
-       sum = x2 ? 2 : 0;
-       sum += (x16 != 0) * 16;
-       sum += (x8 != 0) * 8;
-       sum += (x4 != 0) * 4;
-       sum += (x1 != 0);
-
-       return sum;
-}
-
-#endif
-
 /*
  * ffz: Find first zero in word. Undefined if no zero exists.
  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  */
 
-static __inline__ int ffz(unsigned long x)
+static inline int ffz(unsigned long x)
 {
-       if ((x = ~x) == 0)
-               return 32;
-       return __cntlz(x & -x);
+       return 31 - __cntlz(~x & -~x);
 }
 
 /*
  * __ffs: Find first bit set in word. Return 0 for bit 0
  */
 
-static __inline__ int __ffs(unsigned long x)
+static inline int __ffs(unsigned long x)
 {
-       return __cntlz(x & -x);
+       return 31 - __cntlz(x & -x);
 }
 
 /*
@@ -86,9 +63,9 @@ static __inline__ int __ffs(unsigned long x)
  * differs in spirit from the above ffz (man ffs).
  */
 
-static __inline__ int ffs(unsigned long x)
+static inline int ffs(unsigned long x)
 {
-       return __cntlz(x & -x) + 1;
+       return 32 - __cntlz(x & -x);
 }
 
 /*
@@ -96,20 +73,36 @@ static __inline__ int ffs(unsigned long x)
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 
-static __inline__ int fls (unsigned int x)
+static inline int fls (unsigned int x)
 {
-       return __cntlz(x);
+       return 32 - __cntlz(x);
 }
+
+#else
+
+/* Use the generic implementation if we don't have the nsa/nsau instructions. */
+
+# include <asm-generic/bitops/ffs.h>
+# include <asm-generic/bitops/__ffs.h>
+# include <asm-generic/bitops/ffz.h>
+# include <asm-generic/bitops/fls.h>
+
+#endif
+
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 
 #ifdef __XTENSA_EL__
-# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr))
-# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr))
+# define ext2_set_bit_atomic(lock,nr,addr)                             \
+       test_and_set_bit((nr), (unsigned long*)(addr))
+# define ext2_clear_bit_atomic(lock,nr,addr)                           \
+       test_and_clear_bit((nr), (unsigned long*)(addr))
 #elif defined(__XTENSA_EB__)
-# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr))
-# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr))
+# define ext2_set_bit_atomic(lock,nr,addr)                             \
+       test_and_set_bit((nr) ^ 0x18, (unsigned long*)(addr))
+# define ext2_clear_bit_atomic(lock,nr,addr)                           \
+       test_and_clear_bit((nr) ^ 0x18, (unsigned long*)(addr))
 #else
 # error processor byte order undefined!
 #endif
index 0f540a5f4c01c7f6ef799a9b1c997348ce3a6b22..765edf17a9a466b5497046c4c78a50185dc83a92 100644 (file)
@@ -12,6 +12,7 @@
 #define _XTENSA_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
@@ -78,4 +79,4 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
 # error processor byte order undefined!
 #endif
 
-#endif /* __ASM_XTENSA_BYTEORDER_H */
+#endif /* _XTENSA_BYTEORDER_H */
index bd09ec02d57f941182f2de62a4de7476c36250d2..aa2121034558684f3f6a654b383a77bb838ae558 100644 (file)
@@ -64,6 +64,7 @@ typedef struct {
 #  define COPROCESSOR_INFO_SIZE 8
 # endif
 #endif
+#endif /* XCHAL_HAVE_CP */
 
 
 #ifndef __ASSEMBLY__
@@ -74,8 +75,11 @@ extern void save_coprocessor_registers(void*, int);
 # else
 #  define release_coprocessors(task)
 # endif
-#endif
 
-#endif
+typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE]
+       __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
+
+#endif /* !__ASSEMBLY__ */
+
 
 #endif /* _XTENSA_COPROCESSOR_H */
index 20965e3af1dde6117b43811aaf9f319b9ca86c0e..f35678cb0a9b1153cb19bbe109a78d0e5f2b6d2f 100644 (file)
@@ -5,21 +5,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
  */
 
 #ifndef _XTENSA_DIV64_H
 #define _XTENSA_DIV64_H
 
-#include <linux/types.h>
+#include <asm-generic/div64.h>
 
-#define do_div(n,base) ({ \
-       int __res = n % ((unsigned int) base); \
-       n /= (unsigned int) base; \
-       __res; })
-
-static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor)
-{
-       return dividend / divisor;
-}
-#endif
+#endif /* _XTENSA_DIV64_H */
index f0f9fd8560a5f905aebd43e321688e771dc572fe..1569b53cec91a38a36643480ea5a1d874cca9e1f 100644 (file)
@@ -13,7 +13,6 @@
 #ifndef _XTENSA_ELF_H
 #define _XTENSA_ELF_H
 
-#include <asm/variant/core.h>
 #include <asm/ptrace.h>
 
 /* Xtensa processor ELF architecture-magic number */
@@ -49,7 +48,7 @@ typedef struct {
        elf_greg_t lcount;
        elf_greg_t sar;
        elf_greg_t syscall;
-       elf_greg_t ar[XCHAL_NUM_AREGS];
+       elf_greg_t ar[64];
 } xtensa_gregset_t;
 
 #define ELF_NGREG      (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
index 0609fc691b72b97b3d4511f4993788560561b964..46ab12db57397dfc44a7aa84f9c10ac5e97509d9 100644 (file)
@@ -1,99 +1 @@
-/*
- * include/asm-xtensa/fcntl.h
- *
- * 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) 1995, 1996, 1997, 1998 by Ralf Baechle
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_FCNTL_H
-#define _XTENSA_FCNTL_H
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
-#define O_ACCMODE         0003
-#define O_RDONLY            00
-#define O_WRONLY            01
-#define O_RDWR              02
-#define O_CREAT                   0100 /* not fcntl */
-#define O_EXCL            0200 /* not fcntl */
-#define O_NOCTTY          0400 /* not fcntl */
-#define O_TRUNC                  01000 /* not fcntl */
-#define O_APPEND         02000
-#define O_NONBLOCK       04000
-#define O_NDELAY       O_NONBLOCK
-#define O_SYNC          010000
-#define FASYNC          020000 /* fcntl, for BSD compatibility */
-#define O_DIRECT        040000 /* direct disk access hint */
-#define O_LARGEFILE    0100000
-#define O_DIRECTORY    0200000 /* must be a directory */
-#define O_NOFOLLOW     0400000 /* don't follow links */
-#define O_NOATIME      01000000
-
-#define F_DUPFD                0       /* dup */
-#define F_GETFD                1       /* get close_on_exec */
-#define F_SETFD                2       /* set/clear close_on_exec */
-#define F_GETFL                3       /* get file->f_flags */
-#define F_SETFL                4       /* set file->f_flags */
-#define F_GETLK                5
-#define F_SETLK                6
-#define F_SETLKW       7
-
-#define F_SETOWN       8       /*  for sockets. */
-#define F_GETOWN       9       /*  for sockets. */
-#define F_SETSIG       10      /*  for sockets. */
-#define F_GETSIG       11      /*  for sockets. */
-
-#define F_GETLK64      12      /*  using 'struct flock64' */
-#define F_SETLK64      13
-#define F_SETLKW64     14
-
-/* for F_[GET|SET]FL */
-#define FD_CLOEXEC     1       /* actually anything with low bit set goes */
-
-/* for posix fcntl() and lockf() */
-#define F_RDLCK                0
-#define F_WRLCK                1
-#define F_UNLCK                2
-
-/* for old implementation of bsd flock () */
-#define F_EXLCK                4       /* or 3 */
-#define F_SHLCK                8       /* or 4 */
-
-/* for leases */
-#define F_INPROGRESS   16
-
-/* operations for bsd flock(), also used by the kernel implementation */
-#define LOCK_SH                1       /* shared lock */
-#define LOCK_EX                2       /* exclusive lock */
-#define LOCK_NB                4       /* or'd with one of the above to prevent
-                                  blocking */
-#define LOCK_UN                8       /* remove lock */
-
-#define LOCK_MAND      32      /* This is a mandatory flock */
-#define LOCK_READ      64      /* ... Which allows concurrent read operations */
-#define LOCK_WRITE     128     /* ... Which allows concurrent write operations */
-#define LOCK_RW                192     /* ... Which allows concurrent read & write ops */
-
-struct flock {
-       short l_type;
-       short l_whence;
-       off_t l_start;
-       off_t l_len;
-       pid_t l_pid;
-};
-
-struct flock64 {
-       short  l_type;
-       short  l_whence;
-       loff_t l_start;
-       loff_t l_len;
-       pid_t  l_pid;
-};
-
-#define F_LINUX_SPECIFIC_BASE  1024
-
-#endif /* _XTENSA_FCNTL_H */
+#include <asm-generic/fcntl.h>
index 92f948392ebccede88123965b1d71bd91c1a48ca..c0fd8e5b4513562ee5d9884108fbb1723ed7cd8d 100644 (file)
@@ -14,6 +14,7 @@
 #define _XTENSA_MMU_CONTEXT_H
 
 #include <linux/stringify.h>
+#include <linux/sched.h>
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
index c631d006194b476db9d4f307a3e034f20625aa60..1213cde7543803d813f6a87c261525936138b07f 100644 (file)
@@ -131,6 +131,6 @@ void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#endif /* __KERNEL__ */
 #include <asm-generic/memory_model.h>
+#endif /* __KERNEL__ */
 #endif /* _XTENSA_PAGE_H */
index 6f281392e3f854fc0589b104f9d188f3c4210e3a..ce3a336cad07c188ebe7dc10805c2d6c060212a8 100644 (file)
 #ifndef _XTENSA_PARAM_H
 #define _XTENSA_PARAM_H
 
-#include <asm/variant/core.h>
-
 #ifdef __KERNEL__
 # define HZ            100             /* internal timer frequency */
 # define USER_HZ       100             /* for user interfaces in "ticks" */
 # define CLOCKS_PER_SEC (USER_HZ)      /* frequnzy at which times() counts */
 #endif
 
-#define EXEC_PAGESIZE  (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+#define EXEC_PAGESIZE  4096
 
 #ifndef NGROUPS
 #define NGROUPS                32
index 1b7fe363fad1ea4dda17622cab04471ba5f344a4..77ff02d307bba119141aacfa733d51f01c137168 100644 (file)
@@ -11,8 +11,6 @@
 #ifndef _XTENSA_PTRACE_H
 #define _XTENSA_PTRACE_H
 
-#include <asm/variant/core.h>
-
 /*
  * Kernel stack
  *
@@ -101,7 +99,8 @@ struct pt_regs {
        unsigned long windowbase;       /*  48 */
        unsigned long windowstart;      /*  52 */
        unsigned long syscall;          /*  56 */
-       int reserved[2];                /*  64 */
+       unsigned long icountlevel;      /*  60 */
+       int reserved[1];                /*  64 */
 
        /* Make sure the areg field is 16 bytes aligned. */
        int align[0] __attribute__ ((aligned(16)));
@@ -113,6 +112,9 @@ struct pt_regs {
 };
 
 #ifdef __KERNEL__
+
+#include <asm/variant/core.h>
+
 # define task_pt_regs(tsk) ((struct pt_regs*) \
   (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
index d3b65bfa71c3b7314ddf3b8cfc6e451696a85f77..c8cc16c3da9e68f8e409eed03db985298a9eca07 100644 (file)
@@ -9,8 +9,6 @@
 #ifndef _XTENSA_SHMPARAM_H
 #define _XTENSA_SHMPARAM_H
 
-#include <asm/processor.h>
-
 /*
  * Xtensa can have variable size caches, and if
  * the size of single way is larger than the page size,
index a75177291418d5302c72ca2c032a560c90ac23dc..e3381cee5059ae9946f3c53044c8fcac45276651 100644 (file)
@@ -5,21 +5,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2003 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
  */
 
 #ifndef _XTENSA_SIGCONTEXT_H
 #define _XTENSA_SIGCONTEXT_H
 
-#define _ASMLANGUAGE
-#include <asm/processor.h>
-#include <asm/coprocessor.h>
-
-
-struct _cpstate {
-       unsigned char _cpstate[XTENSA_CP_EXTRA_SIZE];
-} __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
-
 
 struct sigcontext {
        unsigned long   oldmask;
@@ -27,18 +18,13 @@ struct sigcontext {
        /* CPU registers */
        unsigned long sc_pc;
        unsigned long sc_ps;
-       unsigned long sc_wmask;
-       unsigned long sc_windowbase;
-       unsigned long sc_windowstart;
        unsigned long sc_lbeg;
        unsigned long sc_lend;
        unsigned long sc_lcount;
        unsigned long sc_sar;
-       unsigned long sc_depc;
-       unsigned long sc_dareg0;
-       unsigned long sc_treg[4];
-       unsigned long sc_areg[XCHAL_NUM_AREGS];
-       struct _cpstate *sc_cpstate;
+       unsigned long sc_acclo;
+       unsigned long sc_acchi;
+       unsigned long sc_a[16];
 };
 
-#endif /* __ASM_XTENSA_SIGCONTEXT_H */
+#endif /* _XTENSA_SIGCONTEXT_H */
index 5ae34ab715972a812ef81a8e634e18d8ea50b776..3fa29799b435302e3ca7ddfd4131c4f51d6b2545 100644 (file)
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SINGLESTEP         4       /* restore singlestep on return to user mode */
 #define TIF_IRET               5       /* return with iret */
 #define TIF_MEMDIE             6
+#define TIF_RESTORE_SIGMASK    7       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -125,6 +126,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
 #define _TIF_IRET              (1<<TIF_IRET)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index 8a7fb6964ce144319576ce856cfd4d16284abf68..9bd34024431c12a2b7cace88e566402fa7334828 100644 (file)
@@ -485,8 +485,8 @@ __SYSCALL(217, sys_sched_get_priority_min, 1)
 __SYSCALL(218, sys_sched_rr_get_interval, 2)
 #define __NR_sched_yield                       219
 __SYSCALL(219, sys_sched_yield, 0)
-#define __NR_sigreturn                         222
-__SYSCALL(222, xtensa_sigreturn, 0)
+#define __NR_available222                      222
+__SYSCALL(222, sys_ni_syscall, 0)
 
 /* Signal Handling */
 
index e1013156c25ed21214223950c60b9bd5a253df80..f317c270d4bfe9acbefdf3a567f8313480ad4e0e 100644 (file)
@@ -62,6 +62,8 @@ header-y += fadvise.h
 header-y += fd.h
 header-y += fdreg.h
 header-y += fib_rules.h
+header-y += firewire-cdev.h
+header-y += firewire-constants.h
 header-y += fuse.h
 header-y += genetlink.h
 header-y += gen_stats.h
index edb31bfff68fb3586097173f5dc61b7b215333ab..703febb2df31e248243e7017b6a34828ec23128a 100644 (file)
@@ -151,6 +151,7 @@ enum {
        ATA_CMD_WRITE_MULTI_EXT = 0x39,
        ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
        ATA_CMD_SET_FEATURES    = 0xEF,
+       ATA_CMD_SET_MULTI       = 0xC6,
        ATA_CMD_PACKET          = 0xA0,
        ATA_CMD_VERIFY          = 0x40,
        ATA_CMD_VERIFY_EXT      = 0x42,
@@ -249,7 +250,7 @@ enum ata_tf_protocols {
        /* ATA taskfile protocols */
        ATA_PROT_UNKNOWN,       /* unknown/invalid */
        ATA_PROT_NODATA,        /* no data */
-       ATA_PROT_PIO,           /* PIO single sector */
+       ATA_PROT_PIO,           /* PIO data xfer */
        ATA_PROT_DMA,           /* DMA */
        ATA_PROT_NCQ,           /* NCQ */
        ATA_PROT_ATAPI,         /* packet command, PIO data xfer*/
index 0365ec9fc0c9248422801fe71b232d1188a12972..c83534ee1e796c46b2cc47c129ad3924cedbeb20 100644 (file)
@@ -59,6 +59,7 @@ extern void *__alloc_bootmem_core(struct bootmem_data *bdata,
                                  unsigned long align,
                                  unsigned long goal,
                                  unsigned long limit);
+extern void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size);
 
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 extern void reserve_bootmem(unsigned long addr, unsigned long size);
index 6548b35ab9f685d3f7a215cea8b2bfc557a1ac17..bbf8df7de28f0991fcc7a240eb8f70723b38eb35 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 
+struct task_struct;
+
 /* User-level do most of the mapping between kernel and user
    capabilities based on the version tag given by the kernel. The
    kernel might be somewhat backwards compatible, but don't bet on
index a461f76fb004e874f38ec245c6a6834b333a5004..dc77fed7b28566c585ccc2193f14dfdea8227421 100644 (file)
@@ -9,6 +9,9 @@
  * to achieve effects such as fast scrolling by changing the origin.
  */
 
+#ifndef _LINUX_CONSOLE_STRUCT_H
+#define _LINUX_CONSOLE_STRUCT_H
+
 #include <linux/wait.h>
 #include <linux/vt.h>
 #include <linux/workqueue.h>
@@ -130,3 +133,5 @@ extern void vc_SAK(struct work_struct *work);
 #define CUR_DEFAULT CUR_UNDERLINE
 
 #define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
+
+#endif /* _LINUX_CONSOLE_STRUCT_H */
index d90b80f9b28c7c0402b71a8fa19b2cc8d9e5efd8..46685832ed99106bc6e4084f739abadceae0d549 100644 (file)
@@ -5,7 +5,12 @@
 
 #ifdef __KERNEL__
 
-/* Should never be seen by user programs */
+/*
+ * These should never be seen by user programs.  To return one of ERESTART*
+ * codes, signal_pending() MUST be set.  Note that ptrace can observe these
+ * at syscall exit tracing, but they will never be left for the debugged user
+ * process to see.
+ */
 #define ERESTARTSYS    512
 #define ERESTARTNOINTR 513
 #define ERESTARTNOHAND 514     /* restart if no handler.. */
index 54c576d414c32b83d993942188e66b4171962f85..de1f9f78625a3279bf5ddb580d57cc1003eef152 100644 (file)
@@ -32,9 +32,9 @@
 /*
  * Define EXT4_RESERVATION to reserve data blocks for expanding files
  */
-#define EXT4_DEFAULT_RESERVE_BLOCKS     8
+#define EXT4_DEFAULT_RESERVE_BLOCKS    8
 /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
-#define EXT4_MAX_RESERVE_BLOCKS         1027
+#define EXT4_MAX_RESERVE_BLOCKS                1027
 #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0
 /*
  * Always enable hashed directories
@@ -204,12 +204,12 @@ struct ext4_group_desc
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext4_new_group_input {
-       __u32 group;            /* Group number for this data */
-       __u64 block_bitmap;     /* Absolute block number of block bitmap */
-       __u64 inode_bitmap;     /* Absolute block number of inode bitmap */
-       __u64 inode_table;      /* Absolute block number of inode table start */
-       __u32 blocks_count;     /* Total number of blocks in this group */
-       __u16 reserved_blocks;  /* Number of reserved blocks in this group */
+       __u32 group;            /* Group number for this data */
+       __u64 block_bitmap;     /* Absolute block number of block bitmap */
+       __u64 inode_bitmap;     /* Absolute block number of inode bitmap */
+       __u64 inode_table;      /* Absolute block number of inode table start */
+       __u32 blocks_count;     /* Total number of blocks in this group */
+       __u16 reserved_blocks;  /* Number of reserved blocks in this group */
        __u16 unused;
 };
 
@@ -310,7 +310,7 @@ struct ext4_inode {
                        __u8    l_i_frag;       /* Fragment number */
                        __u8    l_i_fsize;      /* Fragment size */
                        __le16  l_i_file_acl_high;
-                       __le16  l_i_uid_high;   /* these 2 fields    */
+                       __le16  l_i_uid_high;   /* these 2 fields */
                        __le16  l_i_gid_high;   /* were reserved2[0] */
                        __u32   l_i_reserved2;
                } linux2;
@@ -513,7 +513,14 @@ struct ext4_super_block {
 /*150*/        __le32  s_blocks_count_hi;      /* Blocks count */
        __le32  s_r_blocks_count_hi;    /* Reserved blocks count */
        __le32  s_free_blocks_count_hi; /* Free blocks count */
-       __u32   s_reserved[169];        /* Padding to the end of the block */
+       __u16   s_min_extra_isize;      /* All inodes have at least # bytes */
+       __u16   s_want_extra_isize;     /* New inodes should reserve # bytes */
+       __u32   s_flags;                /* Miscellaneous flags */
+       __u16   s_raid_stride;          /* RAID stride */
+       __u16   s_mmp_interval;         /* # seconds to wait in MMP checking */
+       __u64   s_mmp_block;            /* Block for multi-mount protection */
+       __u32   s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+       __u32   s_reserved[163];        /* Padding to the end of the block */
 };
 
 #ifdef __KERNEL__
@@ -780,9 +787,9 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
  * Ok, these declarations are also in <linux/kernel.h> but none of the
  * ext4 source programs needs to include it so they are duplicated here.
  */
-# define NORET_TYPE    /**/
-# define ATTRIB_NORET  __attribute__((noreturn))
-# define NORET_AND     noreturn,
+# define NORET_TYPE    /**/
+# define ATTRIB_NORET  __attribute__((noreturn))
+# define NORET_AND     noreturn,
 
 /* balloc.c */
 extern unsigned int ext4_block_group(struct super_block *sb,
index 7eb1d73fc5d1634ee535f777d7d5576b784e9180..acfe59740b032d1a5adcfebaa69ca491c048cafa 100644 (file)
@@ -151,8 +151,8 @@ typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
        ((struct ext4_extent_idx *) (((char *) (__hdr__)) +     \
                                     sizeof(struct ext4_extent_header)))
 #define EXT_HAS_FREE_INDEX(__path__) \
-        (le16_to_cpu((__path__)->p_hdr->eh_entries) \
-                                    < le16_to_cpu((__path__)->p_hdr->eh_max))
+       (le16_to_cpu((__path__)->p_hdr->eh_entries) \
+                                    < le16_to_cpu((__path__)->p_hdr->eh_max))
 #define EXT_LAST_EXTENT(__hdr__) \
        (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
 #define EXT_LAST_INDEX(__hdr__) \
@@ -190,6 +190,7 @@ ext4_ext_invalidate_cache(struct inode *inode)
 
 extern int ext4_extent_tree_init(handle_t *, struct inode *);
 extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *);
+extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
 extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
 extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *);
 extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *);
index d5b177e5b3958338d13bfc46a9d8fcc1e338a9ee..9de4944069955a46e0183fbfe0a00adf04163270 100644 (file)
@@ -41,14 +41,14 @@ struct ext4_reserve_window_node {
 
 struct ext4_block_alloc_info {
        /* information about reservation window */
-       struct ext4_reserve_window_node rsv_window_node;
+       struct ext4_reserve_window_node rsv_window_node;
        /*
         * was i_next_alloc_block in ext4_inode_info
         * is the logical (file-relative) number of the
         * most-recently-allocated block in this file.
         * We use this for detecting linearly ascending allocation requests.
         */
-       __u32                   last_alloc_logical_block;
+       __u32 last_alloc_logical_block;
        /*
         * Was i_next_alloc_goal in ext4_inode_info
         * is the *physical* companion to i_next_alloc_block.
@@ -56,7 +56,7 @@ struct ext4_block_alloc_info {
         * allocated to this file.  This give us the goal (target) for the next
         * allocation when we detect linearly ascending requests.
         */
-       ext4_fsblk_t            last_alloc_physical_block;
+       ext4_fsblk_t last_alloc_physical_block;
 };
 
 #define rsv_start rsv_window._rsv_start
index c654d0e9ce3313d6f345eeac6ebd72279240d238..66226824ab68b4bd106525c820d8803934c054ed 100644 (file)
@@ -942,6 +942,7 @@ extern int fb_new_modelist(struct fb_info *info);
 
 extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
+extern struct class *fb_class;
 
 static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
                                           u8 *src, u32 s_pitch, u32 height)
index d4455eb2ae3566251c26680cc8394c17441c6c04..efbe1fda1a22f0c769f9e103d39317568d597de2 100644 (file)
@@ -198,13 +198,15 @@ struct fw_cdev_create_iso_context {
        __u32 handle;
 };
 
+#define FW_CDEV_ISO_PAYLOAD_LENGTH(v)  (v)
+#define FW_CDEV_ISO_INTERRUPT          (1 << 16)
+#define FW_CDEV_ISO_SKIP               (1 << 17)
+#define FW_CDEV_ISO_TAG(v)             ((v) << 18)
+#define FW_CDEV_ISO_SY(v)              ((v) << 20)
+#define FW_CDEV_ISO_HEADER_LENGTH(v)   ((v) << 24)
+
 struct fw_cdev_iso_packet {
-       __u16 payload_length;   /* Length of indirect payload. */
-       __u32 interrupt : 1;    /* Generate interrupt on this packet */
-       __u32 skip : 1;         /* Set to not send packet at all. */
-       __u32 tag : 2;
-       __u32 sy : 4;
-       __u32 header_length : 8;        /* Length of immediate header. */
+       __u32 control;
        __u32 header[0];
 };
 
index 5e75e26d4787248caf175063afad75010824672a..4631086f50603d56050efcc001548cf44fc21e43 100644 (file)
@@ -37,25 +37,25 @@ static inline void do_not_freeze(struct task_struct *p)
 
 /*
  * Wake up a frozen process
+ *
+ * task_lock() is taken to prevent the race with refrigerator() which may
+ * occur if the freezing of tasks fails.  Namely, without the lock, if the
+ * freezing of tasks failed, thaw_tasks() might have run before a task in
+ * refrigerator() could call frozen_process(), in which case the task would be
+ * frozen and no one would thaw it.
  */
 static inline int thaw_process(struct task_struct *p)
 {
+       task_lock(p);
        if (frozen(p)) {
                p->flags &= ~PF_FROZEN;
+               task_unlock(p);
                wake_up_process(p);
                return 1;
        }
-       return 0;
-}
-
-/*
- * freezing is complete, mark process as frozen
- */
-static inline void frozen_process(struct task_struct *p)
-{
-       p->flags |= PF_FROZEN;
-       wmb();
        clear_tsk_thread_flag(p, TIF_FREEZE);
+       task_unlock(p);
+       return 0;
 }
 
 extern void refrigerator(void);
@@ -71,14 +71,55 @@ static inline int try_to_freeze(void)
                return 0;
 }
 
-extern void thaw_some_processes(int all);
+/*
+ * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
+ * calls wait_for_completion(&vfork) and reset right after it returns from this
+ * function.  Next, the parent should call try_to_freeze() to freeze itself
+ * appropriately in case the child has exited before the freezing of tasks is
+ * complete.  However, we don't want kernel threads to be frozen in unexpected
+ * places, so we allow them to block freeze_processes() instead or to set
+ * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
+ * parents.  Fortunately, in the ____call_usermodehelper() case the parent won't
+ * really block freeze_processes(), since ____call_usermodehelper() (the child)
+ * does a little before exec/exit and it can't be frozen before waking up the
+ * parent.
+ */
+
+/*
+ * If the current task is a user space one, tell the freezer not to count it as
+ * freezable.
+ */
+static inline void freezer_do_not_count(void)
+{
+       if (current->mm)
+               current->flags |= PF_FREEZER_SKIP;
+}
+
+/*
+ * If the current task is a user space one, tell the freezer to count it as
+ * freezable again and try to freeze it.
+ */
+static inline void freezer_count(void)
+{
+       if (current->mm) {
+               current->flags &= ~PF_FREEZER_SKIP;
+               try_to_freeze();
+       }
+}
+
+/*
+ * Check if the task should be counted as freezeable by the freezer
+ */
+static inline int freezer_should_skip(struct task_struct *p)
+{
+       return !!(p->flags & PF_FREEZER_SKIP);
+}
 
 #else
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
 static inline void freeze(struct task_struct *p) { BUG(); }
 static inline int thaw_process(struct task_struct *p) { return 1; }
-static inline void frozen_process(struct task_struct *p) { BUG(); }
 
 static inline void refrigerator(void) {}
 static inline int freeze_processes(void) { BUG(); return 0; }
@@ -86,5 +127,7 @@ static inline void thaw_processes(void) {}
 
 static inline int try_to_freeze(void) { return 0; }
 
-
+static inline void freezer_do_not_count(void) {}
+static inline void freezer_count(void) {}
+static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 #endif
index 7cf0c54a46a7fff64365b3184ea492d572dac9b0..b3ae77cccbb6723499e094ec01cd4660607fcee7 100644 (file)
@@ -938,6 +938,7 @@ struct super_block {
        struct list_head        s_files;
 
        struct block_device     *s_bdev;
+       struct mtd_info         *s_mtd;
        struct list_head        s_instances;
        struct quota_info       s_dquot;        /* Diskquota specific options */
 
index 4c03ee353e78684f64fd230101c7eab150860d79..9756fc102a83f284a1040386bd076d6acca81cff 100644 (file)
@@ -66,6 +66,7 @@ struct partition {
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/workqueue.h>
 
 struct partition {
        unsigned char boot_ind;         /* 0x80 - active */
@@ -94,6 +95,7 @@ struct hd_struct {
 
 #define GENHD_FL_REMOVABLE                     1
 #define GENHD_FL_DRIVERFS                      2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY           4
 #define GENHD_FL_CD                            8
 #define GENHD_FL_UP                            16
 #define GENHD_FL_SUPPRESS_PARTITION_INFO       32
@@ -138,6 +140,7 @@ struct gendisk {
 #else
        struct disk_stats dkstats;
 #endif
+       struct work_struct async_notify;
 };
 
 /* Structure for sysfs attributes on block devices */
@@ -419,7 +422,7 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id);
 extern struct gendisk *alloc_disk(int minors);
 extern struct kobject *get_disk(struct gendisk *disk);
 extern void put_disk(struct gendisk *disk);
-
+extern void genhd_media_change_notify(struct gendisk *disk);
 extern void blk_register_region(dev_t dev, unsigned long range,
                        struct module *module,
                        struct kobject *(*probe)(dev_t, int *, void *),
index 07aba87d369db7d87c781ab5ebe66eda07985875..1e365acdd36922dafcfc0a8b287a5368c5b9c9c2 100644 (file)
@@ -1001,6 +1001,7 @@ struct ide_driver_s {
        struct device_driver    gen_driver;
        int             (*probe)(ide_drive_t *);
        void            (*remove)(ide_drive_t *);
+       void            (*resume)(ide_drive_t *);
        void            (*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
        ide_proc_entry_t        *proc;
index c0f7aec331c2031f3aa0f1c89db00a7b0b14b699..ae04901aa09a838bef2a20674848f7cb5c72e5fe 100644 (file)
@@ -3,6 +3,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/bitmap.h>
 #include <linux/if.h>
 #include <linux/netdevice.h>
 #include <linux/rcupdate.h>
 
 struct ipv4_devconf
 {
-       int     accept_redirects;
-       int     send_redirects;
-       int     secure_redirects;
-       int     shared_media;
-       int     accept_source_route;
-       int     rp_filter;
-       int     proxy_arp;
-       int     bootp_relay;
-       int     log_martians;
-       int     forwarding;
-       int     mc_forwarding;
-       int     tag;
-       int     arp_filter;
-       int     arp_announce;
-       int     arp_ignore;
-       int     arp_accept;
-       int     medium_id;
-       int     no_xfrm;
-       int     no_policy;
-       int     force_igmp_version;
-       int     promote_secondaries;
        void    *sysctl;
+       int     data[__NET_IPV4_CONF_MAX - 1];
+       DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
 };
 
 extern struct ipv4_devconf ipv4_devconf;
@@ -60,30 +42,70 @@ struct in_device
        struct rcu_head         rcu_head;
 };
 
-#define IN_DEV_FORWARD(in_dev)         ((in_dev)->cnf.forwarding)
-#define IN_DEV_MFORWARD(in_dev)                (ipv4_devconf.mc_forwarding && (in_dev)->cnf.mc_forwarding)
-#define IN_DEV_RPFILTER(in_dev)                (ipv4_devconf.rp_filter && (in_dev)->cnf.rp_filter)
-#define IN_DEV_SOURCE_ROUTE(in_dev)    (ipv4_devconf.accept_source_route && (in_dev)->cnf.accept_source_route)
-#define IN_DEV_BOOTP_RELAY(in_dev)     (ipv4_devconf.bootp_relay && (in_dev)->cnf.bootp_relay)
-
-#define IN_DEV_LOG_MARTIANS(in_dev)    (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians)
-#define IN_DEV_PROXY_ARP(in_dev)       (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp)
-#define IN_DEV_SHARED_MEDIA(in_dev)    (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media)
-#define IN_DEV_TX_REDIRECTS(in_dev)    (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
-#define IN_DEV_SEC_REDIRECTS(in_dev)   (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
-#define IN_DEV_IDTAG(in_dev)           ((in_dev)->cnf.tag)
-#define IN_DEV_MEDIUM_ID(in_dev)       ((in_dev)->cnf.medium_id)
-#define IN_DEV_PROMOTE_SECONDARIES(in_dev)     (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)
+#define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
+#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
+
+static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
+{
+       index--;
+       return in_dev->cnf.data[index];
+}
+
+static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
+                                   int val)
+{
+       index--;
+       set_bit(index, in_dev->cnf.state);
+       in_dev->cnf.data[index] = val;
+}
+
+static inline void ipv4_devconf_setall(struct in_device *in_dev)
+{
+       bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
+}
+
+#define IN_DEV_CONF_GET(in_dev, attr) \
+       ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
+#define IN_DEV_CONF_SET(in_dev, attr, val) \
+       ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
+
+#define IN_DEV_ANDCONF(in_dev, attr) \
+       (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
+#define IN_DEV_ORCONF(in_dev, attr) \
+       (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
+#define IN_DEV_MAXCONF(in_dev, attr) \
+       (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
+
+#define IN_DEV_FORWARD(in_dev)         IN_DEV_CONF_GET((in_dev), FORWARDING)
+#define IN_DEV_MFORWARD(in_dev)                (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
+                                        IPV4_DEVCONF((in_dev)->cnf, \
+                                                     MC_FORWARDING))
+#define IN_DEV_RPFILTER(in_dev)                IN_DEV_ANDCONF((in_dev), RP_FILTER)
+#define IN_DEV_SOURCE_ROUTE(in_dev)    IN_DEV_ANDCONF((in_dev), \
+                                                      ACCEPT_SOURCE_ROUTE)
+#define IN_DEV_BOOTP_RELAY(in_dev)     IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
+
+#define IN_DEV_LOG_MARTIANS(in_dev)    IN_DEV_ORCONF((in_dev), LOG_MARTIANS)
+#define IN_DEV_PROXY_ARP(in_dev)       IN_DEV_ORCONF((in_dev), PROXY_ARP)
+#define IN_DEV_SHARED_MEDIA(in_dev)    IN_DEV_ORCONF((in_dev), SHARED_MEDIA)
+#define IN_DEV_TX_REDIRECTS(in_dev)    IN_DEV_ORCONF((in_dev), SEND_REDIRECTS)
+#define IN_DEV_SEC_REDIRECTS(in_dev)   IN_DEV_ORCONF((in_dev), \
+                                                     SECURE_REDIRECTS)
+#define IN_DEV_IDTAG(in_dev)           IN_DEV_CONF_GET(in_dev, TAG)
+#define IN_DEV_MEDIUM_ID(in_dev)       IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
+#define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
+                                       IN_DEV_ORCONF((in_dev), \
+                                                     PROMOTE_SECONDARIES)
 
 #define IN_DEV_RX_REDIRECTS(in_dev) \
        ((IN_DEV_FORWARD(in_dev) && \
-         (ipv4_devconf.accept_redirects && (in_dev)->cnf.accept_redirects)) \
+         IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
         || (!IN_DEV_FORWARD(in_dev) && \
-         (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects)))
+         IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
 
-#define IN_DEV_ARPFILTER(in_dev)       (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
-#define IN_DEV_ARP_ANNOUNCE(in_dev)    (max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce))
-#define IN_DEV_ARP_IGNORE(in_dev)      (max(ipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore))
+#define IN_DEV_ARPFILTER(in_dev)       IN_DEV_ORCONF((in_dev), ARPFILTER)
+#define IN_DEV_ARP_ANNOUNCE(in_dev)    IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
+#define IN_DEV_ARP_IGNORE(in_dev)      IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
 
 struct in_ifaddr
 {
@@ -108,7 +130,6 @@ extern struct net_device    *ip_dev_find(__be32 addr);
 extern int             inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
 extern int             devinet_ioctl(unsigned int cmd, void __user *);
 extern void            devinet_init(void);
-extern struct in_device *inetdev_init(struct net_device *dev);
 extern struct in_device        *inetdev_by_index(int);
 extern __be32          inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
 extern __be32          inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
index 09ea01a8a99cf8ac4404bcb811862a66e7a97e83..648bd1f0912d3cbbba77b9276d34309f1f1700d5 100644 (file)
@@ -209,9 +209,8 @@ enum {
        DEVCONF_RTR_PROBE_INTERVAL,
        DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
        DEVCONF_PROXY_NDP,
-       __DEVCONF_OPTIMISTIC_DAD,
-       DEVCONF_ACCEPT_SOURCE_ROUTE,
        DEVCONF_OPTIMISTIC_DAD,
+       DEVCONF_ACCEPT_SOURCE_ROUTE,
        DEVCONF_MAX
 };
 
index 45353d757cd0f1ca57cc266aaf228c549fcfbf48..7a485250591491089549455a60c944aa4be0a5ff 100644 (file)
@@ -218,10 +218,14 @@ enum {
        DUMP_PREFIX_ADDRESS,
        DUMP_PREFIX_OFFSET
 };
-extern void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf,
-                               size_t linebuflen);
-extern void print_hex_dump(const char *level, int prefix_type,
-                               void *buf, size_t len);
+extern void hex_dump_to_buffer(const void *buf, size_t len,
+                               int rowsize, int groupsize,
+                               char *linebuf, size_t linebuflen, bool ascii);
+extern void print_hex_dump(const char *level, const char *prefix_str,
+                               int prefix_type, int rowsize, int groupsize,
+                               void *buf, size_t len, bool ascii);
+extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
+                       void *buf, size_t len);
 #define hex_asc(x)     "0123456789abcdef"[x]
 
 #ifdef DEBUG
index 85f7b1bd1482ae7094c1d00eeec00b72b2b88d5f..745c4f9b4caafab27c1299268cf4eb363d7e7d7f 100644 (file)
@@ -171,7 +171,6 @@ enum {
        ATA_FLAG_SKIP_D2H_BSY   = (1 << 12), /* can't wait for the first D2H
                                              * Register FIS clearing BSY */
        ATA_FLAG_DEBUGMSG       = (1 << 13),
-       ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
        ATA_FLAG_IGN_SIMPLEX    = (1 << 15), /* ignore SIMPLEX */
        ATA_FLAG_NO_IORDY       = (1 << 16), /* controller lacks iordy */
        ATA_FLAG_ACPI_SATA      = (1 << 17), /* need native SATA ACPI layout */
@@ -754,6 +753,7 @@ extern u8 ata_check_status(struct ata_port *ap);
 extern u8 ata_altstatus(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
+extern int ata_sff_port_start (struct ata_port *ap);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
 extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
                          unsigned int buflen, int write_data);
diff --git a/include/linux/mtd/super.h b/include/linux/mtd/super.h
new file mode 100644 (file)
index 0000000..4016dd6
--- /dev/null
@@ -0,0 +1,30 @@
+/* MTD-based superblock handling
+ *
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __MTD_SUPER_H__
+#define __MTD_SUPER_H__
+
+#ifdef __KERNEL__
+
+#include <linux/mtd/mtd.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+
+extern int get_sb_mtd(struct file_system_type *fs_type, int flags,
+                     const char *dev_name, void *data,
+                     int (*fill_super)(struct super_block *, void *, int),
+                     struct vfsmount *mnt);
+extern void kill_mtd_super(struct super_block *sb);
+
+
+#endif /* __KERNEL__ */
+
+#endif /* __MTD_SUPER_H__ */
index f671cd2f133fd55377f925d59ff224b343993dec..3a70f553b28f853bede95f0b0437dfe1a161d88a 100644 (file)
@@ -910,6 +910,17 @@ static inline int netif_rx_reschedule(struct net_device *dev, int undo)
        return 0;
 }
 
+/* same as netif_rx_complete, except that local_irq_save(flags)
+ * has already been issued
+ */
+static inline void __netif_rx_complete(struct net_device *dev)
+{
+       BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
+       list_del(&dev->poll_list);
+       smp_mb__before_clear_bit();
+       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
+
 /* Remove interface from poll list: it must be in the poll list
  * on current cpu. This primitive is called by dev->poll(), when
  * it completes the work. The device cannot be out of poll list at this
@@ -920,10 +931,7 @@ static inline void netif_rx_complete(struct net_device *dev)
        unsigned long flags;
 
        local_irq_save(flags);
-       BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
-       list_del(&dev->poll_list);
-       smp_mb__before_clear_bit();
-       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+       __netif_rx_complete(dev);
        local_irq_restore(flags);
 }
 
@@ -940,17 +948,6 @@ static inline void netif_poll_enable(struct net_device *dev)
        clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
 }
 
-/* same as netif_rx_complete, except that local_irq_save(flags)
- * has already been issued
- */
-static inline void __netif_rx_complete(struct net_device *dev)
-{
-       BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
-       list_del(&dev->poll_list);
-       smp_mb__before_clear_bit();
-       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
-}
-
 static inline void netif_tx_lock(struct net_device *dev)
 {
        spin_lock(&dev->_xmit_lock);
index 81453ea7e4c2c063e351ce6ff6f63fa01e601a2d..b7c360ffd0d037db5fedef34b45ca921132fe82e 100644 (file)
@@ -37,8 +37,7 @@ extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
                                       enum nf_ct_ftp_type type,
                                       unsigned int matchoff,
                                       unsigned int matchlen,
-                                      struct nf_conntrack_expect *exp,
-                                      u32 *seq);
+                                      struct nf_conntrack_expect *exp);
 #endif /* __KERNEL__ */
 
 #endif /* _NF_CONNTRACK_FTP_H */
index 38d74d5c970098cc8e07c18a5b79c0a448f63f1f..f35b6b4801e76298174966b0ecee6e173f53ef43 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006
+/* Generated by Jing Min Zhao's ASN.1 parser, May 16 2007
  *
  * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
  *
@@ -12,7 +12,7 @@ typedef struct TransportAddress_ipAddress {   /* SEQUENCE */
 
 typedef struct TransportAddress_ip6Address {   /* SEQUENCE */
        int options;            /* No use */
-       unsigned ip6;
+       unsigned ip;
 } TransportAddress_ip6Address;
 
 typedef struct TransportAddress {      /* CHOICE */
@@ -364,23 +364,6 @@ typedef struct Alerting_UUIE {     /* SEQUENCE */
        Alerting_UUIE_fastStart fastStart;
 } Alerting_UUIE;
 
-typedef struct Information_UUIE_fastStart {    /* SEQUENCE OF */
-       int count;
-       OpenLogicalChannel item[30];
-} Information_UUIE_fastStart;
-
-typedef struct Information_UUIE {      /* SEQUENCE */
-       enum {
-               eInformation_UUIE_callIdentifier = (1 << 31),
-               eInformation_UUIE_tokens = (1 << 30),
-               eInformation_UUIE_cryptoTokens = (1 << 29),
-               eInformation_UUIE_fastStart = (1 << 28),
-               eInformation_UUIE_fastConnectRefused = (1 << 27),
-               eInformation_UUIE_circuitInfo = (1 << 26),
-       } options;
-       Information_UUIE_fastStart fastStart;
-} Information_UUIE;
-
 typedef struct FacilityReason {        /* CHOICE */
        enum {
                eFacilityReason_routeCallToGatekeeper,
@@ -471,7 +454,6 @@ typedef struct H323_UU_PDU_h323_message_body {      /* CHOICE */
                CallProceeding_UUIE callProceeding;
                Connect_UUIE connect;
                Alerting_UUIE alerting;
-               Information_UUIE information;
                Facility_UUIE facility;
                Progress_UUIE progress;
        };
@@ -561,6 +543,7 @@ typedef struct OpenLogicalChannelAck {      /* SEQUENCE */
        } options;
        OpenLogicalChannelAck_reverseLogicalChannelParameters
            reverseLogicalChannelParameters;
+       NetworkAccessParameters separateStack;
        OpenLogicalChannelAck_forwardMultiplexAckParameters
            forwardMultiplexAckParameters;
 } OpenLogicalChannelAck;
index 2f46dd728ee1fa9596e4a491782543fc44946012..e992cd6b28f57798e17d4e3c7f7aa9c81554da01 100644 (file)
@@ -264,6 +264,26 @@ ipt_get_target(struct ipt_entry *e)
        __ret;                                                  \
 })
 
+/* fn returns 0 to continue iteration */
+#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
+({                                                             \
+       unsigned int __i, __n;                                  \
+       int __ret = 0;                                          \
+       struct ipt_entry *__entry;                              \
+                                                               \
+       for (__i = 0, __n = 0; __i < (size);                    \
+            __i += __entry->next_offset, __n++) {              \
+               __entry = (void *)(entries) + __i;              \
+               if (__n < n)                                    \
+                       continue;                               \
+                                                               \
+               __ret = fn(__entry , ## args);                  \
+               if (__ret != 0)                                 \
+                       break;                                  \
+       }                                                       \
+       __ret;                                                  \
+})
+
 /*
  *     Main firewall chains definitions and global var's definitions.
  */
index 41afab6b5f09c2cf3dbcde8bab5ee4eb896eaf44..bd193af801629a95bdc2c45ef201d84305b25b61 100644 (file)
@@ -81,6 +81,7 @@ extern        void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
 extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
                                   struct nfs_page *);
 extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
+extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
 extern  int nfs_wait_on_request(struct nfs_page *);
 extern void nfs_unlock_request(struct nfs_page *req);
 extern  int nfs_set_page_writeback_locked(struct nfs_page *req);
index 62b3e008e64121b702ebea4b5511798862c07683..9a03b47da603526dc07c29a32c92c6c53d53f6af 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 #define PCI_DEVICE_ID_ATI_IXP700_SATA  0x4390
+#define PCI_DEVICE_ID_ATI_IXP700_IDE   0x439c
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_VLSI_82C592      0x0005
 #define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
 
 #define PCI_VENDOR_ID_IMS              0x10e0
 #define PCI_DEVICE_ID_IMS_TT128                0x9128
 #define PCI_DEVICE_ID_VIA_P4M890       0x0327
 #define PCI_DEVICE_ID_VIA_VT3324       0x0324
 #define PCI_DEVICE_ID_VIA_VT3336       0x0336
+#define PCI_DEVICE_ID_VIA_VT3351       0x0351
 #define PCI_DEVICE_ID_VIA_8371_0       0x0391
 #define PCI_DEVICE_ID_VIA_8501_0       0x0501
 #define PCI_DEVICE_ID_VIA_82C561       0x0561
 #define PCI_DEVICE_ID_SERVERWORKS_LE     0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
 #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_ICH8_5     0x283e
 #define PCI_DEVICE_ID_INTEL_ICH8_6     0x2850
 #define PCI_DEVICE_ID_INTEL_ICH9_0     0x2910
-#define PCI_DEVICE_ID_INTEL_ICH9_1     0x2911
+#define PCI_DEVICE_ID_INTEL_ICH9_1     0x2917
 #define PCI_DEVICE_ID_INTEL_ICH9_2     0x2912
 #define PCI_DEVICE_ID_INTEL_ICH9_3     0x2913
 #define PCI_DEVICE_ID_INTEL_ICH9_4     0x2914
-#define PCI_DEVICE_ID_INTEL_ICH9_5     0x2915
+#define PCI_DEVICE_ID_INTEL_ICH9_5     0x2919
 #define PCI_DEVICE_ID_INTEL_ICH9_6     0x2930
 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
 #define PCI_DEVICE_ID_INTEL_82830_HB   0x3575
index 8bcbc54e1b488213fceff419d0d364cc74b61c43..c8884f9712285b25cc88ff7518c2e0b79e0bcb39 100644 (file)
@@ -16,6 +16,21 @@ struct pipe_buffer {
        unsigned int flags;
 };
 
+struct pipe_inode_info {
+       wait_queue_head_t wait;
+       unsigned int nrbufs, curbuf;
+       struct page *tmp_page;
+       unsigned int readers;
+       unsigned int writers;
+       unsigned int waiting_writers;
+       unsigned int r_counter;
+       unsigned int w_counter;
+       struct fasync_struct *fasync_readers;
+       struct fasync_struct *fasync_writers;
+       struct inode *inode;
+       struct pipe_buffer bufs[PIPE_BUFFERS];
+};
+
 /*
  * Note on the nesting of these functions:
  *
@@ -38,21 +53,6 @@ struct pipe_buf_operations {
        void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
 };
 
-struct pipe_inode_info {
-       wait_queue_head_t wait;
-       unsigned int nrbufs, curbuf;
-       struct page *tmp_page;
-       unsigned int readers;
-       unsigned int writers;
-       unsigned int waiting_writers;
-       unsigned int r_counter;
-       unsigned int w_counter;
-       struct fasync_struct *fasync_readers;
-       struct fasync_struct *fasync_writers;
-       struct inode *inode;
-       struct pipe_buffer bufs[PIPE_BUFFERS];
-};
-
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #define PIPE_SIZE              PAGE_SIZE
index 6db9a4c153556a7236caf4dbf376b27900af3f15..dd5a05d03d4f477f2c90040331ec6d8c7de03d36 100644 (file)
@@ -232,6 +232,7 @@ struct bitmap {
        struct page **filemap; /* list of cache pages for the file */
        unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
        unsigned long file_pages; /* number of pages in the file */
+       int last_page_size; /* bytes in the last page */
 
        unsigned long flags;
 
index 7c1ffbab78657a105018ffd2c71b8871496255f4..a8a6ea809da096d19fbb0d164c986be671dcef12 100644 (file)
@@ -63,7 +63,7 @@ enum rfkill_state {
  * This structure represents a RF switch located on a network device.
  */
 struct rfkill {
-       char *name;
+       const char *name;
        enum rfkill_type type;
 
        enum rfkill_state state;
index a81897e2a244a7cb0a9f84dd03adc7ba27e46253..693f0e6c54d47595c6f3268d0e20b5de74303d90 100644 (file)
@@ -1162,6 +1162,7 @@ static inline void put_task_struct(struct task_struct *t)
                                        /* Not implemented yet, only for 486*/
 #define PF_STARTING    0x00000002      /* being created */
 #define PF_EXITING     0x00000004      /* getting shut down */
+#define PF_EXITPIDONE  0x00000008      /* pi exit done on shut down */
 #define PF_FORKNOEXEC  0x00000040      /* forked but didn't exec */
 #define PF_SUPERPRIV   0x00000100      /* used super-user privileges */
 #define PF_DUMPCORE    0x00000200      /* dumped core */
@@ -1182,6 +1183,7 @@ static inline void put_task_struct(struct task_struct *t)
 #define PF_SPREAD_SLAB 0x02000000      /* Spread some slab caches over cpuset */
 #define PF_MEMPOLICY   0x10000000      /* Non-default NUMA mempolicy */
 #define PF_MUTEX_TESTER        0x20000000      /* Thread belongs to the rt mutex tester */
+#define PF_FREEZER_SKIP        0x40000000      /* Freezer should not count it as freezeable */
 
 /*
  * Only the _current_ task can read/write to tsk->flags, but other
@@ -1615,11 +1617,13 @@ static inline int lock_need_resched(spinlock_t *lock)
        return 0;
 }
 
-/* Reevaluate whether the task has signals pending delivery.
-   This is required every time the blocked sigset_t changes.
-   callers must hold sighand->siglock.  */
-
-extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t));
+/*
+ * Reevaluate whether the task has signals pending delivery.
+ * Wake the task if so.
+ * This is required every time the blocked sigset_t changes.
+ * callers must hold sighand->siglock.
+ */
+extern void recalc_sigpending_and_wake(struct task_struct *t);
 extern void recalc_sigpending(void);
 
 extern void signal_wake_up(struct task_struct *t, int resume_stopped);
index a3ac4c8968312b1173903ccd7caa890c56ae01bc..7f2c99d66e9d697203a72ec4f965459495f4bb63 100644 (file)
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/mutex.h>
+#include <linux/sysrq.h>
 
 struct uart_port;
 struct uart_info;
index 0764c829d967ab8c1841cddf79ba51204956e4a8..a0ad37463d623ec1a933c7bc7c3cb8c966b15ff6 100644 (file)
@@ -70,11 +70,8 @@ extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1];
  */
 static inline int kmalloc_index(size_t size)
 {
-       /*
-        * We should return 0 if size == 0 but we use the smallest object
-        * here for SLAB legacy reasons.
-        */
-       WARN_ON_ONCE(size == 0);
+       if (!size)
+               return 0;
 
        if (size > KMALLOC_MAX_SIZE)
                return -1;
@@ -153,13 +150,25 @@ static inline struct kmem_cache *kmalloc_slab(size_t size)
 #define SLUB_DMA 0
 #endif
 
+
+/*
+ * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
+ *
+ * Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault.
+ *
+ * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
+ * Both make kfree a no-op.
+ */
+#define ZERO_SIZE_PTR ((void *)16)
+
+
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
        if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
                struct kmem_cache *s = kmalloc_slab(size);
 
                if (!s)
-                       return NULL;
+                       return ZERO_SIZE_PTR;
 
                return kmem_cache_alloc(s, flags);
        } else
@@ -172,7 +181,7 @@ static inline void *kzalloc(size_t size, gfp_t flags)
                struct kmem_cache *s = kmalloc_slab(size);
 
                if (!s)
-                       return NULL;
+                       return ZERO_SIZE_PTR;
 
                return kmem_cache_zalloc(s, flags);
        } else
@@ -188,7 +197,7 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
                struct kmem_cache *s = kmalloc_slab(size);
 
                if (!s)
-                       return NULL;
+                       return ZERO_SIZE_PTR;
 
                return kmem_cache_alloc_node(s, flags, node);
        } else
index e0c5c16c992f2aeac2a2db8436354aec639c1f9a..c661710d3627daeeb40dca898ef48e4123d023cb 100644 (file)
@@ -68,6 +68,12 @@ extern int del_timer(struct timer_list * timer);
 extern int __mod_timer(struct timer_list *timer, unsigned long expires);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
 
+/*
+ * The jiffies value which is added to now, when there is no timer
+ * in the timer wheel:
+ */
+#define NEXT_TIMER_MAX_DELTA   ((1UL << 30) - 1)
+
 /*
  * Return when the next timer-wheel timeout occurs (in absolute jiffies),
  * locks the timer base:
index e7560389079ceb0980b057eb9290c5429a746b3d..d16a2b57dc8105806a07afa5e97e843cd0844274 100644 (file)
@@ -243,8 +243,7 @@ struct v4l2_capability
 #define V4L2_CAP_SLICED_VBI_CAPTURE    0x00000040  /* Is a sliced VBI capture device */
 #define V4L2_CAP_SLICED_VBI_OUTPUT     0x00000080  /* Is a sliced VBI output device */
 #define V4L2_CAP_RDS_CAPTURE           0x00000100  /* RDS data capture */
-#define V4L2_CAP_VIDEO_OUTPUT_POS       0x00000200  /* Video output can have x,y coords */
-#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY  0x00000400  /* Can do video output overlay */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY  0x00000200  /* Can do video output overlay */
 
 #define V4L2_CAP_TUNER                 0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO                 0x00020000  /* has audio support */
@@ -616,12 +615,16 @@ struct v4l2_framebuffer
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING  0x0008
 #define V4L2_FBUF_CAP_LOCAL_ALPHA      0x0010
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA     0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA  0x0040
+#define V4L2_FBUF_CAP_GLOBAL_INV_ALPHA 0x0080
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY         0x0001
 #define V4L2_FBUF_FLAG_OVERLAY         0x0002
 #define V4L2_FBUF_FLAG_CHROMAKEY       0x0004
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA     0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA    0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
+#define V4L2_FBUF_FLAG_GLOBAL_INV_ALPHA        0x0040
 
 struct v4l2_clip
 {
index c0398f5a8cb98667d77f979ac863ed2a7822ad10..65f49fd7deff1620c3f6fdc9102c717f8f2dedae 100644 (file)
@@ -62,13 +62,11 @@ struct unix_skb_parms {
 #define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
 #define UNIXSID(skb)   (&UNIXCB((skb)).secid)
 
-#define unix_state_rlock(s)    spin_lock(&unix_sk(s)->lock)
-#define unix_state_runlock(s)  spin_unlock(&unix_sk(s)->lock)
-#define unix_state_wlock(s)    spin_lock(&unix_sk(s)->lock)
-#define unix_state_wlock_nested(s) \
+#define unix_state_lock(s)     spin_lock(&unix_sk(s)->lock)
+#define unix_state_unlock(s)   spin_unlock(&unix_sk(s)->lock)
+#define unix_state_lock_nested(s) \
                                spin_lock_nested(&unix_sk(s)->lock, \
                                SINGLE_DEPTH_NESTING)
-#define unix_state_wunlock(s)  spin_unlock(&unix_sk(s)->lock)
 
 #ifdef __KERNEL__
 /* The AF_UNIX socket */
index 8242a0ee1f5868666a24526fb0cd00aefd3e2e57..87df4e87622d0ce19df6c848d160db3fda995e05 100644 (file)
@@ -129,8 +129,10 @@ struct l2cap_conf_rsp {
        __u8       data[0];
 } __attribute__ ((packed));
 
-#define L2CAP_CONF_SUCCESS     0x00
-#define L2CAP_CONF_UNACCEPT    0x01
+#define L2CAP_CONF_SUCCESS     0x0000
+#define L2CAP_CONF_UNACCEPT    0x0001
+#define L2CAP_CONF_REJECT      0x0002
+#define L2CAP_CONF_UNKNOWN     0x0003
 
 struct l2cap_conf_opt {
        __u8       type;
@@ -215,6 +217,8 @@ struct l2cap_pinfo {
 
        __u32           link_mode;
 
+       __u8            conf_req[64];
+       __u8            conf_len;
        __u8            conf_state;
        __u8            conf_retry;
        __u16           conf_mtu;
index 4f90f5554faccc3bad4dce9d028cb58be3cbe9eb..a6bb94530cfddfbd0e8d3bd10880fdfcd8c996b5 100644 (file)
@@ -203,12 +203,10 @@ static inline int cipso_v4_cache_add(const struct sk_buff *skb,
 
 #ifdef CONFIG_NETLABEL
 void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
-int cipso_v4_socket_setattr(const struct socket *sock,
-                           const struct cipso_v4_doi *doi_def,
-                           const struct netlbl_lsm_secattr *secattr);
+int cipso_v4_sock_setattr(struct sock *sk,
+                         const struct cipso_v4_doi *doi_def,
+                         const struct netlbl_lsm_secattr *secattr);
 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
-int cipso_v4_socket_getattr(const struct socket *sock,
-                           struct netlbl_lsm_secattr *secattr);
 int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
                            struct netlbl_lsm_secattr *secattr);
 int cipso_v4_validate(unsigned char **option);
@@ -220,9 +218,9 @@ static inline void cipso_v4_error(struct sk_buff *skb,
        return;
 }
 
-static inline int cipso_v4_socket_setattr(const struct socket *sock,
-                                 const struct cipso_v4_doi *doi_def,
-                                 const struct netlbl_lsm_secattr *secattr)
+static inline int cipso_v4_sock_setattr(struct sock *sk,
+                                     const struct cipso_v4_doi *doi_def,
+                                     const struct netlbl_lsm_secattr *secattr)
 {
        return -ENOSYS;
 }
@@ -233,12 +231,6 @@ static inline int cipso_v4_sock_getattr(struct sock *sk,
        return -ENOSYS;
 }
 
-static inline int cipso_v4_socket_getattr(const struct socket *sock,
-                                         struct netlbl_lsm_secattr *secattr)
-{
-       return -ENOSYS;
-}
-
 static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
                                          struct netlbl_lsm_secattr *secattr)
 {
index e12a8ce0b9b30737a39edbeaea90ba9edca76557..82270f9332db94077bb6d95bcca2f2ef0010c636 100644 (file)
@@ -265,9 +265,16 @@ static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
 {
        return 0;
 } 
+static inline int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+                               struct sock *sk, int flags)
+{
+       return 0;
+}
 #else
 extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
                       struct sock *sk, int flags);
+extern int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+                        struct sock *sk, int flags);
 #endif
 #endif
 
index ed3a8872c6cafa25f550ba6dcaa2b2d30328d339..83e41dd15ccde6e88b304687dac539462815d7dd 100644 (file)
@@ -64,7 +64,7 @@ struct fib_rules_ops
        void                    (*flush_cache)(void);
 
        int                     nlgroup;
-       struct nla_policy       *policy;
+       const struct nla_policy *policy;
        struct list_head        *rules_list;
        struct module           *owner;
 };
index adff4c898d50ea40d5a4b09afedbf708c0c508f8..b6eaca122db871ab4b269a99dcbabda0fe9bcf90 100644 (file)
@@ -60,7 +60,7 @@ struct genl_ops
 {
        u8                      cmd;
        unsigned int            flags;
-       struct nla_policy       *policy;
+       const struct nla_policy *policy;
        int                    (*doit)(struct sk_buff *skb,
                                       struct genl_info *info);
        int                    (*dumpit)(struct sk_buff *skb,
index bb207db03675bbe473b1d7d00e6e3c5c27e1aaf4..abf2820a1125d73af2a83b8dab7a6e66509c88e5 100644 (file)
@@ -143,6 +143,7 @@ struct ip_reply_arg {
        __wsum      csum;
        int         csumoffset; /* u16 offset of csum in iov[0].iov_base */
                                /* -1 if not needed */ 
+       int         bound_dev_if;
 }; 
 
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
index 5a4a0366c24feb89883bcef5898054b0add95fa1..69252cbe05b0392fe392b4ca708784330ba73f29 100644 (file)
@@ -213,7 +213,7 @@ extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
 #endif /* CONFIG_IP_MULTIPLE_TABLES */
 
 /* Exported by fib_frontend.c */
-extern struct nla_policy rtm_ipv4_policy[];
+extern const struct nla_policy rtm_ipv4_policy[];
 extern void            ip_fib_init(void);
 extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
                               struct net_device *dev, __be32 *spec_dst, u32 *itag);
index 4fa5dfe886c4e387a094b2a244a788b4f20e744c..78a0d06d98d5420b2094b4c5a78b9d62c1cfdc10 100644 (file)
@@ -469,6 +469,9 @@ extern void                 ip6_flush_pending_frames(struct sock *sk);
 extern int                     ip6_dst_lookup(struct sock *sk,
                                               struct dst_entry **dst,
                                               struct flowi *fl);
+extern int                     ip6_dst_blackhole(struct sock *sk,
+                                                 struct dst_entry **dst,
+                                                 struct flowi *fl);
 extern int                     ip6_sk_dst_lookup(struct sock *sk,
                                                  struct dst_entry **dst,
                                                  struct flowi *fl);
index 83da7e1f0d3db8aeaae7d6e21bdcfe7c3e5d2715..9b7d6f2ac9a3ed9c0107a16131be3e165477e6ed 100644 (file)
@@ -332,17 +332,15 @@ static inline int netlbl_secattr_catmap_setrng(
  */
 
 #ifdef CONFIG_NETLABEL
-int netlbl_socket_setattr(const struct socket *sock,
-                         const struct netlbl_lsm_secattr *secattr);
+int netlbl_sock_setattr(struct sock *sk,
+                       const struct netlbl_lsm_secattr *secattr);
 int netlbl_sock_getattr(struct sock *sk,
                        struct netlbl_lsm_secattr *secattr);
-int netlbl_socket_getattr(const struct socket *sock,
-                         struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
                          struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 #else
-static inline int netlbl_socket_setattr(const struct socket *sock,
+static inline int netlbl_sock_setattr(struct sock *sk,
                                     const struct netlbl_lsm_secattr *secattr)
 {
        return -ENOSYS;
@@ -354,12 +352,6 @@ static inline int netlbl_sock_getattr(struct sock *sk,
        return -ENOSYS;
 }
 
-static inline int netlbl_socket_getattr(const struct socket *sock,
-                                       struct netlbl_lsm_secattr *secattr)
-{
-       return -ENOSYS;
-}
-
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
                                        struct netlbl_lsm_secattr *secattr)
 {
index 0bf325c29aff4803a9dcfed9b53d12cce6ac3ae1..7b510a9edb911a34dbf6b356318cb5a45a09d09d 100644 (file)
@@ -222,10 +222,10 @@ extern int                nlmsg_notify(struct sock *sk, struct sk_buff *skb,
                                     gfp_t flags);
 
 extern int             nla_validate(struct nlattr *head, int len, int maxtype,
-                                    struct nla_policy *policy);
+                                    const struct nla_policy *policy);
 extern int             nla_parse(struct nlattr *tb[], int maxtype,
                                  struct nlattr *head, int len,
-                                 struct nla_policy *policy);
+                                 const struct nla_policy *policy);
 extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
 extern size_t          nla_strlcpy(char *dst, const struct nlattr *nla,
                                    size_t dstsize);
@@ -360,7 +360,7 @@ static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
  */
 static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
                              struct nlattr *tb[], int maxtype,
-                             struct nla_policy *policy)
+                             const struct nla_policy *policy)
 {
        if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
                return -EINVAL;
@@ -392,7 +392,7 @@ static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
  * @policy: validation policy
  */
 static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
-                                struct nla_policy *policy)
+                                const struct nla_policy *policy)
 {
        if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
                return -EINVAL;
@@ -729,7 +729,7 @@ static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
  */
 static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
                                   struct nlattr *nla,
-                                  struct nla_policy *policy)
+                                  const struct nla_policy *policy)
 {
        return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
 }
@@ -990,7 +990,7 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
  * Returns 0 on success or a negative error code.
  */
 static inline int nla_validate_nested(struct nlattr *start, int maxtype,
-                                     struct nla_policy *policy)
+                                     const struct nla_policy *policy)
 {
        return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
 }
index 689b886038da88da7b4268c377606a96293932d9..dfeb8b13024f8827febf8cedbcee48666106d4b3 100644 (file)
@@ -218,13 +218,13 @@ struct sock {
        atomic_t                sk_rmem_alloc;
        atomic_t                sk_wmem_alloc;
        atomic_t                sk_omem_alloc;
+       int                     sk_sndbuf;
        struct sk_buff_head     sk_receive_queue;
        struct sk_buff_head     sk_write_queue;
        struct sk_buff_head     sk_async_wait_queue;
        int                     sk_wmem_queued;
        int                     sk_forward_alloc;
        gfp_t                   sk_allocation;
-       int                     sk_sndbuf;
        int                     sk_route_caps;
        int                     sk_gso_type;
        int                     sk_rcvlowat;
index e22b4f0305a339ce402b1e959ee0a64665fe2b1e..a8af9ae0017719bb7071ef5b34faa2c3f751a7b3 100644 (file)
@@ -254,6 +254,12 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
        return seq3 - seq2 >= seq1 - seq2;
 }
 
+static inline int tcp_too_many_orphans(struct sock *sk, int num)
+{
+       return (num > sysctl_tcp_max_orphans) ||
+               (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+                atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
+}
 
 extern struct proto tcp_prot;
 
index 496f89d45c8b89eabf7b57bde71016e85552a677..98755ebaf163cfe788b4117167cfeaf1a861f269 100644 (file)
@@ -119,16 +119,9 @@ static inline void udp_lib_close(struct sock *sk, long timeout)
 }
 
 
-struct udp_get_port_ops {
-       int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2);
-       int (*saddr_any)(const struct sock *sk);
-       unsigned int (*hash_port_and_rcv_saddr)(__u16 port,
-                                               const struct sock *sk);
-};
-
 /* net/ipv4/udp.c */
 extern int     udp_get_port(struct sock *sk, unsigned short snum,
-                            const struct udp_get_port_ops *ops);
+                            int (*saddr_cmp)(const struct sock *, const struct sock *));
 extern void    udp_err(struct sk_buff *, u32);
 
 extern int     udp_sendmsg(struct kiocb *iocb, struct sock *sk,
index 50b4b424d1caab47e79673eb3fa6972c45651e91..635b0eafca95d256e789edb0323cbb8aef759f4f 100644 (file)
@@ -120,5 +120,5 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
 
 extern void    udplite4_register(void);
 extern int     udplite_get_port(struct sock *sk, unsigned short snum,
-                                const struct udp_get_port_ops *ops);
+                       int (*scmp)(const struct sock *, const struct sock *));
 #endif /* _UDPLITE_H */
index 39ef925d39dd5dd8dce802e4e35ee668338d7d6c..311f25af5e1a7b936a87f8b3a0fd17926688a806 100644 (file)
@@ -237,7 +237,6 @@ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c);
 extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
-#define XFRM_ACQ_EXPIRES       30
 
 struct xfrm_tmpl;
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
@@ -965,7 +964,7 @@ struct xfrmk_spdinfo {
 
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
-extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
+extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
 extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
 extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
 extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
@@ -1021,13 +1020,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
                                          struct xfrm_sec_ctx *ctx, int delete,
                                          int *err);
 struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
-void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
+int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
                                  xfrm_address_t *daddr, xfrm_address_t *saddr,
                                  int create, unsigned short family);
-extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
+extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
 extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
                          struct flowi *fl, int family, int strict);
index 50ee4fd420fa3b0ec19d7155c9e8e663360253b4..8e5b2f0f594625f5a360489d6558373549b43343 100644 (file)
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
-#define CONFIG_SND_VERSION "1.0.14rc4"
-#define CONFIG_SND_DATE " (Wed May 16 09:45:46 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.14"
+#define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)"
index c6d14b8008ddf3007831723fc1113cd63ad3cb46..5c8ecbaa19a530cc4d417a897457b0d0318bc39b 100644 (file)
@@ -762,11 +762,8 @@ static void exit_notify(struct task_struct *tsk)
                read_lock(&tasklist_lock);
                spin_lock_irq(&tsk->sighand->siglock);
                for (t = next_thread(tsk); t != tsk; t = next_thread(t))
-                       if (!signal_pending(t) && !(t->flags & PF_EXITING)) {
-                               recalc_sigpending_tsk(t);
-                               if (signal_pending(t))
-                                       signal_wake_up(t, 0);
-                       }
+                       if (!signal_pending(t) && !(t->flags & PF_EXITING))
+                               recalc_sigpending_and_wake(t);
                spin_unlock_irq(&tsk->sighand->siglock);
                read_unlock(&tasklist_lock);
        }
@@ -895,13 +892,29 @@ fastcall NORET_TYPE void do_exit(long code)
        if (unlikely(tsk->flags & PF_EXITING)) {
                printk(KERN_ALERT
                        "Fixing recursive fault but reboot is needed!\n");
+               /*
+                * We can do this unlocked here. The futex code uses
+                * this flag just to verify whether the pi state
+                * cleanup has been done or not. In the worst case it
+                * loops once more. We pretend that the cleanup was
+                * done as there is no way to return. Either the
+                * OWNER_DIED bit is set by now or we push the blocked
+                * task into the wait for ever nirwana as well.
+                */
+               tsk->flags |= PF_EXITPIDONE;
                if (tsk->io_context)
                        exit_io_context();
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule();
        }
 
+       /*
+        * tsk->flags are checked in the futex code to protect against
+        * an exiting task cleaning up the robust pi futexes.
+        */
+       spin_lock_irq(&tsk->pi_lock);
        tsk->flags |= PF_EXITING;
+       spin_unlock_irq(&tsk->pi_lock);
 
        if (unlikely(in_atomic()))
                printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
@@ -915,7 +928,7 @@ fastcall NORET_TYPE void do_exit(long code)
        }
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
-               hrtimer_cancel(&tsk->signal->real_timer);
+               hrtimer_cancel(&tsk->signal->real_timer);
                exit_itimers(tsk->signal);
        }
        acct_collect(code, group_dead);
@@ -968,6 +981,12 @@ fastcall NORET_TYPE void do_exit(long code)
         * Make sure we are holding no locks:
         */
        debug_check_no_locks_held(tsk);
+       /*
+        * We can do this unlocked here. The futex code uses this flag
+        * just to verify whether the pi state cleanup has been done
+        * or not. In the worst case it loops once more.
+        */
+       tsk->flags |= PF_EXITPIDONE;
 
        if (tsk->io_context)
                exit_io_context();
index 87069cfc18a126f5344f1d2ac77309b1eb72e7fc..73ad5cda1bcd277cf3c86c29bd851df3fc933c73 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/acct.h>
 #include <linux/tsacct_kern.h>
 #include <linux/cn_proc.h>
+#include <linux/freezer.h>
 #include <linux/delayacct.h>
 #include <linux/taskstats_kern.h>
 #include <linux/random.h>
@@ -1405,7 +1406,9 @@ long do_fork(unsigned long clone_flags,
                }
 
                if (clone_flags & CLONE_VFORK) {
+                       freezer_do_not_count();
                        wait_for_completion(&vfork);
+                       freezer_count();
                        if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
                                current->ptrace_message = nr;
                                ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
index b7ce15c67e324b468d13599d47df7423adcd69d4..3b7f7713d9a4148e4ee0c9e9a748be0009b7d5c7 100644 (file)
@@ -430,10 +430,6 @@ static struct task_struct * futex_find_get_task(pid_t pid)
                p = NULL;
                goto out_unlock;
        }
-       if (p->exit_state != 0) {
-               p = NULL;
-               goto out_unlock;
-       }
        get_task_struct(p);
 out_unlock:
        rcu_read_unlock();
@@ -502,7 +498,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
        struct futex_q *this, *next;
        struct plist_head *head;
        struct task_struct *p;
-       pid_t pid;
+       pid_t pid = uval & FUTEX_TID_MASK;
 
        head = &hb->chain;
 
@@ -520,6 +516,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
                                return -EINVAL;
 
                        WARN_ON(!atomic_read(&pi_state->refcount));
+                       WARN_ON(pid && pi_state->owner &&
+                               pi_state->owner->pid != pid);
 
                        atomic_inc(&pi_state->refcount);
                        *ps = pi_state;
@@ -530,15 +528,33 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
 
        /*
         * We are the first waiter - try to look up the real owner and attach
-        * the new pi_state to it, but bail out when the owner died bit is set
-        * and TID = 0:
+        * the new pi_state to it, but bail out when TID = 0
         */
-       pid = uval & FUTEX_TID_MASK;
-       if (!pid && (uval & FUTEX_OWNER_DIED))
+       if (!pid)
                return -ESRCH;
        p = futex_find_get_task(pid);
-       if (!p)
-               return -ESRCH;
+       if (IS_ERR(p))
+               return PTR_ERR(p);
+
+       /*
+        * We need to look at the task state flags to figure out,
+        * whether the task is exiting. To protect against the do_exit
+        * change of the task flags, we do this protected by
+        * p->pi_lock:
+        */
+       spin_lock_irq(&p->pi_lock);
+       if (unlikely(p->flags & PF_EXITING)) {
+               /*
+                * The task is on the way out. When PF_EXITPIDONE is
+                * set, we know that the task has finished the
+                * cleanup:
+                */
+               int ret = (p->flags & PF_EXITPIDONE) ? -ESRCH : -EAGAIN;
+
+               spin_unlock_irq(&p->pi_lock);
+               put_task_struct(p);
+               return ret;
+       }
 
        pi_state = alloc_pi_state();
 
@@ -551,7 +567,6 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
        /* Store the key for possible exit cleanups: */
        pi_state->key = *key;
 
-       spin_lock_irq(&p->pi_lock);
        WARN_ON(!list_empty(&pi_state->list));
        list_add(&pi_state->list, &p->pi_state_list);
        pi_state->owner = p;
@@ -618,6 +633,8 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
         * preserve the owner died bit.)
         */
        if (!(uval & FUTEX_OWNER_DIED)) {
+               int ret = 0;
+
                newval = FUTEX_WAITERS | new_owner->pid;
                /* Keep the FUTEX_WAITER_REQUEUED flag if it was set */
                newval |= (uval & FUTEX_WAITER_REQUEUED);
@@ -625,10 +642,15 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
                pagefault_disable();
                curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
                pagefault_enable();
+
                if (curval == -EFAULT)
-                       return -EFAULT;
+                       ret = -EFAULT;
                if (curval != uval)
-                       return -EINVAL;
+                       ret = -EINVAL;
+               if (ret) {
+                       spin_unlock(&pi_state->pi_mutex.wait_lock);
+                       return ret;
+               }
        }
 
        spin_lock_irq(&pi_state->owner->pi_lock);
@@ -1174,7 +1196,7 @@ static int futex_requeue(u32 __user *uaddr1, struct rw_semaphore *fshared,
 #ifdef CONFIG_DEBUG_PI_LIST
                                this->list.plist.lock = &hb2->lock;
 #endif
-                       }
+                       }
                        this->key = key2;
                        get_futex_key_refs(&key2);
                        drop_count++;
@@ -1326,12 +1348,10 @@ static void unqueue_me_pi(struct futex_q *q)
 /*
  * Fixup the pi_state owner with current.
  *
- * The cur->mm semaphore must be  held, it is released at return of this
- * function.
+ * Must be called with hash bucket lock held and mm->sem held for non
+ * private futexes.
  */
-static int fixup_pi_state_owner(u32 __user *uaddr, struct rw_semaphore *fshared,
-                               struct futex_q *q,
-                               struct futex_hash_bucket *hb,
+static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
                                struct task_struct *curr)
 {
        u32 newtid = curr->pid | FUTEX_WAITERS;
@@ -1355,23 +1375,24 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct rw_semaphore *fshared,
        list_add(&pi_state->list, &curr->pi_state_list);
        spin_unlock_irq(&curr->pi_lock);
 
-       /* Unqueue and drop the lock */
-       unqueue_me_pi(q);
-       if (fshared)
-               up_read(fshared);
        /*
         * We own it, so we have to replace the pending owner
         * TID. This must be atomic as we have preserve the
         * owner died bit here.
         */
-       ret = get_user(uval, uaddr);
+       ret = get_futex_value_locked(&uval, uaddr);
+
        while (!ret) {
                newval = (uval & FUTEX_OWNER_DIED) | newtid;
                newval |= (uval & FUTEX_WAITER_REQUEUED);
+
+               pagefault_disable();
                curval = futex_atomic_cmpxchg_inatomic(uaddr,
                                                       uval, newval);
+               pagefault_enable();
+
                if (curval == -EFAULT)
-                       ret = -EFAULT;
+                       ret = -EFAULT;
                if (curval == uval)
                        break;
                uval = curval;
@@ -1553,10 +1574,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
                         */
                        uaddr = q.pi_state->key.uaddr;
 
-                       /* mmap_sem and hash_bucket lock are unlocked at
-                          return of this function */
-                       ret = fixup_pi_state_owner(uaddr, fshared,
-                                                  &q, hb, curr);
+                       ret = fixup_pi_state_owner(uaddr, &q, curr);
                } else {
                        /*
                         * Catch the rare case, where the lock was released
@@ -1567,12 +1585,13 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
                                if (rt_mutex_trylock(&q.pi_state->pi_mutex))
                                        ret = 0;
                        }
-                       /* Unqueue and drop the lock */
-                       unqueue_me_pi(&q);
-                       if (fshared)
-                               up_read(fshared);
                }
 
+               /* Unqueue and drop the lock */
+               unqueue_me_pi(&q);
+               if (fshared)
+                       up_read(fshared);
+
                debug_rt_mutex_free_waiter(&q.waiter);
 
                return ret;
@@ -1688,7 +1707,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        struct futex_hash_bucket *hb;
        u32 uval, newval, curval;
        struct futex_q q;
-       int ret, lock_held, attempt = 0;
+       int ret, lock_taken, ownerdied = 0, attempt = 0;
 
        if (refill_pi_state_cache())
                return -ENOMEM;
@@ -1709,10 +1728,11 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        if (unlikely(ret != 0))
                goto out_release_sem;
 
+ retry_unlocked:
        hb = queue_lock(&q, -1, NULL);
 
  retry_locked:
-       lock_held = 0;
+       ret = lock_taken = 0;
 
        /*
         * To avoid races, we attempt to take the lock here again
@@ -1728,43 +1748,44 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        if (unlikely(curval == -EFAULT))
                goto uaddr_faulted;
 
-       /* We own the lock already */
+       /*
+        * Detect deadlocks. In case of REQUEUE_PI this is a valid
+        * situation and we return success to user space.
+        */
        if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) {
-               if (!detect && 0)
-                       force_sig(SIGKILL, current);
-               /*
-                * Normally, this check is done in user space.
-                * In case of requeue, the owner may attempt to lock this futex,
-                * even if the ownership has already been given by the previous
-                * waker.
-                * In the usual case, this is a case of deadlock, but not in case
-                * of REQUEUE_PI.
-                */
                if (!(curval & FUTEX_WAITER_REQUEUED))
                        ret = -EDEADLK;
                goto out_unlock_release_sem;
        }
 
        /*
-        * Surprise - we got the lock. Just return
-        * to userspace:
+        * Surprise - we got the lock. Just return to userspace:
         */
        if (unlikely(!curval))
                goto out_unlock_release_sem;
 
        uval = curval;
+
        /*
-        * In case of a requeue, check if there already is an owner
-        * If not, just take the futex.
+        * Set the WAITERS flag, so the owner will know it has someone
+        * to wake at next unlock
         */
-       if ((curval & FUTEX_WAITER_REQUEUED) && !(curval & FUTEX_TID_MASK)) {
-               /* set current as futex owner */
-               newval = curval | current->pid;
-               lock_held = 1;
-       } else
-               /* Set the WAITERS flag, so the owner will know it has someone
-                  to wake at next unlock */
-               newval = curval | FUTEX_WAITERS;
+       newval = curval | FUTEX_WAITERS;
+
+       /*
+        * There are two cases, where a futex might have no owner (the
+        * owner TID is 0): OWNER_DIED or REQUEUE. We take over the
+        * futex in this case. We also do an unconditional take over,
+        * when the owner of the futex died.
+        *
+        * This is safe as we are protected by the hash bucket lock !
+        */
+       if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+               /* Keep the OWNER_DIED and REQUEUE bits */
+               newval = (curval & ~FUTEX_TID_MASK) | current->pid;
+               ownerdied = 0;
+               lock_taken = 1;
+       }
 
        pagefault_disable();
        curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
@@ -1775,8 +1796,13 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        if (unlikely(curval != uval))
                goto retry_locked;
 
-       if (lock_held) {
-               set_pi_futex_owner(hb, &q.key, curr);
+       /*
+        * We took the lock due to requeue or owner died take over.
+        */
+       if (unlikely(lock_taken)) {
+               /* For requeue we need to fixup the pi_futex */
+               if (curval & FUTEX_WAITER_REQUEUED)
+                       set_pi_futex_owner(hb, &q.key, curr);
                goto out_unlock_release_sem;
        }
 
@@ -1787,34 +1813,40 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        ret = lookup_pi_state(uval, hb, &q.key, &q.pi_state);
 
        if (unlikely(ret)) {
-               /*
-                * There were no waiters and the owner task lookup
-                * failed. When the OWNER_DIED bit is set, then we
-                * know that this is a robust futex and we actually
-                * take the lock. This is safe as we are protected by
-                * the hash bucket lock. We also set the waiters bit
-                * unconditionally here, to simplify glibc handling of
-                * multiple tasks racing to acquire the lock and
-                * cleanup the problems which were left by the dead
-                * owner.
-                */
-               if (curval & FUTEX_OWNER_DIED) {
-                       uval = newval;
-                       newval = current->pid |
-                               FUTEX_OWNER_DIED | FUTEX_WAITERS;
+               switch (ret) {
 
-                       pagefault_disable();
-                       curval = futex_atomic_cmpxchg_inatomic(uaddr,
-                                                              uval, newval);
-                       pagefault_enable();
+               case -EAGAIN:
+                       /*
+                        * Task is exiting and we just wait for the
+                        * exit to complete.
+                        */
+                       queue_unlock(&q, hb);
+                       if (fshared)
+                               up_read(fshared);
+                       cond_resched();
+                       goto retry;
 
-                       if (unlikely(curval == -EFAULT))
+               case -ESRCH:
+                       /*
+                        * No owner found for this futex. Check if the
+                        * OWNER_DIED bit is set to figure out whether
+                        * this is a robust futex or not.
+                        */
+                       if (get_futex_value_locked(&curval, uaddr))
                                goto uaddr_faulted;
-                       if (unlikely(curval != uval))
+
+                       /*
+                        * We simply start over in case of a robust
+                        * futex. The code above will take the futex
+                        * and return happy.
+                        */
+                       if (curval & FUTEX_OWNER_DIED) {
+                               ownerdied = 1;
                                goto retry_locked;
-                       ret = 0;
+                       }
+               default:
+                       goto out_unlock_release_sem;
                }
-               goto out_unlock_release_sem;
        }
 
        /*
@@ -1845,31 +1877,42 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                down_read(fshared);
        spin_lock(q.lock_ptr);
 
-       /*
-        * Got the lock. We might not be the anticipated owner if we
-        * did a lock-steal - fix up the PI-state in that case.
-        */
-       if (!ret && q.pi_state->owner != curr)
-               /* mmap_sem is unlocked at return of this function */
-               ret = fixup_pi_state_owner(uaddr, fshared, &q, hb, curr);
-       else {
+       if (!ret) {
+               /*
+                * Got the lock. We might not be the anticipated owner
+                * if we did a lock-steal - fix up the PI-state in
+                * that case:
+                */
+               if (q.pi_state->owner != curr)
+                       ret = fixup_pi_state_owner(uaddr, &q, curr);
+       } else {
                /*
                 * Catch the rare case, where the lock was released
-                * when we were on the way back before we locked
-                * the hash bucket.
+                * when we were on the way back before we locked the
+                * hash bucket.
                 */
-               if (ret && q.pi_state->owner == curr) {
-                       if (rt_mutex_trylock(&q.pi_state->pi_mutex))
-                               ret = 0;
+               if (q.pi_state->owner == curr &&
+                   rt_mutex_trylock(&q.pi_state->pi_mutex)) {
+                       ret = 0;
+               } else {
+                       /*
+                        * Paranoia check. If we did not take the lock
+                        * in the trylock above, then we should not be
+                        * the owner of the rtmutex, neither the real
+                        * nor the pending one:
+                        */
+                       if (rt_mutex_owner(&q.pi_state->pi_mutex) == curr)
+                               printk(KERN_ERR "futex_lock_pi: ret = %d "
+                                      "pi-mutex: %p pi-state %p\n", ret,
+                                      q.pi_state->pi_mutex.owner,
+                                      q.pi_state->owner);
                }
-               /* Unqueue and drop the lock */
-               unqueue_me_pi(&q);
-               if (fshared)
-                       up_read(fshared);
        }
 
-       if (!detect && ret == -EDEADLK && 0)
-               force_sig(SIGKILL, current);
+       /* Unqueue and drop the lock */
+       unqueue_me_pi(&q);
+       if (fshared)
+               up_read(fshared);
 
        return ret != -EINTR ? ret : -ERESTARTNOINTR;
 
@@ -1887,16 +1930,19 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
         * non-atomically.  Therefore, if get_user below is not
         * enough, we need to handle the fault ourselves, while
         * still holding the mmap_sem.
+        *
+        * ... and hb->lock. :-) --ANK
         */
+       queue_unlock(&q, hb);
+
        if (attempt++) {
                ret = futex_handle_fault((unsigned long)uaddr, fshared,
                                         attempt);
                if (ret)
-                       goto out_unlock_release_sem;
-               goto retry_locked;
+                       goto out_release_sem;
+               goto retry_unlocked;
        }
 
-       queue_unlock(&q, hb);
        if (fshared)
                up_read(fshared);
 
@@ -1940,9 +1986,9 @@ retry:
                goto out;
 
        hb = hash_futex(&key);
+retry_unlocked:
        spin_lock(&hb->lock);
 
-retry_locked:
        /*
         * To avoid races, try to do the TID -> 0 atomic transition
         * again. If it succeeds then we can return without waking
@@ -2005,16 +2051,19 @@ pi_faulted:
         * non-atomically.  Therefore, if get_user below is not
         * enough, we need to handle the fault ourselves, while
         * still holding the mmap_sem.
+        *
+        * ... and hb->lock. --ANK
         */
+       spin_unlock(&hb->lock);
+
        if (attempt++) {
                ret = futex_handle_fault((unsigned long)uaddr, fshared,
                                         attempt);
                if (ret)
-                       goto out_unlock;
-               goto retry_locked;
+                       goto out;
+               goto retry_unlocked;
        }
 
-       spin_unlock(&hb->lock);
        if (fshared)
                up_read(fshared);
 
index 338a9b489fbc34fc2ca2ceeecd19f44f2889dd21..27478948b318968a052e4b9fad9a27dd881ca67f 100644 (file)
@@ -144,20 +144,21 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
        struct timespec ts;
        ktime_t t, *tp = NULL;
        int val2 = 0;
+       int cmd = op & FUTEX_CMD_MASK;
 
-       if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
+       if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) {
                if (get_compat_timespec(&ts, utime))
                        return -EFAULT;
                if (!timespec_valid(&ts))
                        return -EINVAL;
 
                t = timespec_to_ktime(ts);
-               if (op == FUTEX_WAIT)
+               if (cmd == FUTEX_WAIT)
                        t = ktime_add(ktime_get(), t);
                tp = &t;
        }
-       if (op == FUTEX_REQUEUE || op == FUTEX_CMP_REQUEUE
-           || op == FUTEX_CMP_REQUEUE_PI)
+       if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE
+           || cmd == FUTEX_CMP_REQUEUE_PI)
                val2 = (int) (unsigned long) utime;
 
        return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
index b0d81aae472ff44e61d3670f81112d4cd2f54ac9..bd9e272d55e9f007984b06e0999f6a37bb7208e1 100644 (file)
@@ -135,6 +135,39 @@ report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
        }
 }
 
+static inline int try_misrouted_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
+{
+       struct irqaction *action;
+
+       if (!irqfixup)
+               return 0;
+
+       /* We didn't actually handle the IRQ - see if it was misrouted? */
+       if (action_ret == IRQ_NONE)
+               return 1;
+
+       /*
+        * But for 'irqfixup == 2' we also do it for handled interrupts if
+        * they are marked as IRQF_IRQPOLL (or for irq zero, which is the
+        * traditional PC timer interrupt.. Legacy)
+        */
+       if (irqfixup < 2)
+               return 0;
+
+       if (!irq)
+               return 1;
+
+       /*
+        * Since we don't get the descriptor lock, "action" can
+        * change under us.  We don't really care, but we don't
+        * want to follow a NULL pointer. So tell the compiler to
+        * just load it once by using a barrier.
+        */
+       action = desc->action;
+       barrier();
+       return action && (action->flags & IRQF_IRQPOLL);
+}
+
 void note_interrupt(unsigned int irq, struct irq_desc *desc,
                    irqreturn_t action_ret)
 {
@@ -144,15 +177,10 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
                        report_bad_irq(irq, desc, action_ret);
        }
 
-       if (unlikely(irqfixup)) {
-               /* Don't punish working computers */
-               if ((irqfixup == 2 && ((irq == 0) ||
-                               (desc->action->flags & IRQF_IRQPOLL))) ||
-                               action_ret == IRQ_NONE) {
-                       int ok = misrouted_irq(irq);
-                       if (action_ret == IRQ_NONE)
-                               desc->irqs_unhandled -= ok;
-               }
+       if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {
+               int ok = misrouted_irq(irq);
+               if (action_ret == IRQ_NONE)
+                       desc->irqs_unhandled -= ok;
        }
 
        desc->irq_count++;
index f1bda23140b2a60d0be17fade305d3ec3afae431..fed54418626c10727662a79d0e505ee302e0bcbf 100644 (file)
@@ -257,7 +257,8 @@ const char *kallsyms_lookup(unsigned long addr,
                pos = get_symbol_pos(addr, symbolsize, offset);
                /* Grab name */
                kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
-               *modname = NULL;
+               if (modname)
+                       *modname = NULL;
                return namebuf;
        }
 
index df8a8e8f6ca4fbb55d2da6770f9040d31de9cf0b..bbd51b81a3e86e239584925dfaf637dce187a831 100644 (file)
@@ -70,7 +70,7 @@ static int kthread(void *_create)
        data = create->data;
 
        /* OK, tell user we're spawned, wait for stop or wakeup */
-       __set_current_state(TASK_INTERRUPTIBLE);
+       __set_current_state(TASK_UNINTERRUPTIBLE);
        complete(&create->started);
        schedule();
 
@@ -162,7 +162,10 @@ EXPORT_SYMBOL(kthread_create);
  */
 void kthread_bind(struct task_struct *k, unsigned int cpu)
 {
-       BUG_ON(k->state != TASK_INTERRUPTIBLE);
+       if (k->state != TASK_UNINTERRUPTIBLE) {
+               WARN_ON(1);
+               return;
+       }
        /* Must have done schedule() in kthread() before we set_task_cpu */
        wait_task_inactive(k);
        set_task_cpu(k, cpu);
index 088419387388ca181d6e855a8aa98be97e930025..e0233d8422b9ed4ec9d62ce1f54bd65165931daa 100644 (file)
@@ -31,16 +31,36 @@ static inline int freezeable(struct task_struct * p)
        return 1;
 }
 
+/*
+ * freezing is complete, mark current process as frozen
+ */
+static inline void frozen_process(void)
+{
+       if (!unlikely(current->flags & PF_NOFREEZE)) {
+               current->flags |= PF_FROZEN;
+               wmb();
+       }
+       clear_tsk_thread_flag(current, TIF_FREEZE);
+}
+
 /* Refrigerator is place where frozen processes are stored :-). */
 void refrigerator(void)
 {
        /* Hmm, should we be allowed to suspend when there are realtime
           processes around? */
        long save;
+
+       task_lock(current);
+       if (freezing(current)) {
+               frozen_process();
+               task_unlock(current);
+       } else {
+               task_unlock(current);
+               return;
+       }
        save = current->state;
        pr_debug("%s entered refrigerator\n", current->comm);
 
-       frozen_process(current);
        spin_lock_irq(&current->sighand->siglock);
        recalc_sigpending(); /* We sent fake signal, clean it up */
        spin_unlock_irq(&current->sighand->siglock);
@@ -81,7 +101,7 @@ static void cancel_freezing(struct task_struct *p)
                pr_debug("  clean up: %s\n", p->comm);
                do_not_freeze(p);
                spin_lock_irqsave(&p->sighand->siglock, flags);
-               recalc_sigpending_tsk(p);
+               recalc_sigpending_and_wake(p);
                spin_unlock_irqrestore(&p->sighand->siglock, flags);
        }
 }
@@ -112,22 +132,12 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
                                cancel_freezing(p);
                                continue;
                        }
-                       if (is_user_space(p)) {
-                               if (!freeze_user_space)
-                                       continue;
-
-                               /* Freeze the task unless there is a vfork
-                                * completion pending
-                                */
-                               if (!p->vfork_done)
-                                       freeze_process(p);
-                       } else {
-                               if (freeze_user_space)
-                                       continue;
-
-                               freeze_process(p);
-                       }
-                       todo++;
+                       if (freeze_user_space && !is_user_space(p))
+                               continue;
+
+                       freeze_process(p);
+                       if (!freezer_should_skip(p))
+                               todo++;
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
                yield();                        /* Yield is okay here */
@@ -149,13 +159,16 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
                                TIMEOUT / HZ, todo);
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       if (is_user_space(p) == !freeze_user_space)
+                       if (freeze_user_space && !is_user_space(p))
                                continue;
 
-                       if (freezeable(p) && !frozen(p))
+                       task_lock(p);
+                       if (freezeable(p) && !frozen(p) &&
+                           !freezer_should_skip(p))
                                printk(KERN_ERR " %s\n", p->comm);
 
                        cancel_freezing(p);
+                       task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
        }
@@ -200,9 +213,7 @@ static void thaw_tasks(int thaw_user_space)
                if (is_user_space(p) == !thaw_user_space)
                        continue;
 
-               if (!thaw_process(p))
-                       printk(KERN_WARNING " Strange, %s not stopped\n",
-                               p->comm );
+               thaw_process(p);
        } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
 }
index b8b235cc19d1591077f7cda71175ec2c152ff808..8b1a1b8371459eb7bb2d4b8ba34fbdc98e95ccdd 100644 (file)
@@ -584,7 +584,7 @@ int swsusp_check(void)
        resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
        if (!IS_ERR(resume_bdev)) {
                set_blocksize(resume_bdev, PAGE_SIZE);
-               memset(swsusp_header, 0, sizeof(PAGE_SIZE));
+               memset(swsusp_header, 0, PAGE_SIZE);
                error = bio_read_page(swsusp_resume_block,
                                        swsusp_header, NULL);
                if (error)
index 12879f6c1ec3b9a53069690f0205082ea581565c..a6fbb41305210c9d3d45c56a670f3fe96af6ce64 100644 (file)
@@ -189,6 +189,19 @@ int rt_mutex_adjust_prio_chain(struct task_struct *task,
        if (!waiter || !waiter->task)
                goto out_unlock_pi;
 
+       /*
+        * Check the orig_waiter state. After we dropped the locks,
+        * the previous owner of the lock might have released the lock
+        * and made us the pending owner:
+        */
+       if (orig_waiter && !orig_waiter->task)
+               goto out_unlock_pi;
+
+       /*
+        * Drop out, when the task has no waiters. Note,
+        * top_waiter can be NULL, when we are in the deboosting
+        * mode!
+        */
        if (top_waiter && (!task_has_pi_waiters(task) ||
                           top_waiter != task_top_pi_waiter(task)))
                goto out_unlock_pi;
@@ -636,9 +649,16 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
                         * all over without going into schedule to try
                         * to get the lock now:
                         */
-                       if (unlikely(!waiter.task))
+                       if (unlikely(!waiter.task)) {
+                               /*
+                                * Reset the return value. We might
+                                * have returned with -EDEADLK and the
+                                * owner released the lock while we
+                                * were walking the pi chain.
+                                */
+                               ret = 0;
                                continue;
-
+                       }
                        if (unlikely(ret))
                                break;
                }
index 799d23b4e35dacf56e118d82953102db54c0fdfb..13cdab3b4c4805712cd1039588d0938b54c8822f 100644 (file)
@@ -4775,9 +4775,7 @@ int __sched cond_resched_softirq(void)
        BUG_ON(!in_softirq());
 
        if (need_resched() && system_state == SYSTEM_RUNNING) {
-               raw_local_irq_disable();
-               _local_bh_enable();
-               raw_local_irq_enable();
+               local_bh_enable();
                __cond_resched();
                local_bh_disable();
                return 1;
index 364fc95bf97cee2623597753708ff6cf293d2421..fe590e00db8df24823280b0bbf94a1daead4cfb5 100644 (file)
@@ -96,20 +96,38 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 
 #define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
 
-fastcall void recalc_sigpending_tsk(struct task_struct *t)
+static int recalc_sigpending_tsk(struct task_struct *t)
 {
        if (t->signal->group_stop_count > 0 ||
            (freezing(t)) ||
            PENDING(&t->pending, &t->blocked) ||
-           PENDING(&t->signal->shared_pending, &t->blocked))
+           PENDING(&t->signal->shared_pending, &t->blocked)) {
                set_tsk_thread_flag(t, TIF_SIGPENDING);
-       else
-               clear_tsk_thread_flag(t, TIF_SIGPENDING);
+               return 1;
+       }
+       /*
+        * We must never clear the flag in another thread, or in current
+        * when it's possible the current syscall is returning -ERESTART*.
+        * So we don't clear it here, and only callers who know they should do.
+        */
+       return 0;
+}
+
+/*
+ * After recalculating TIF_SIGPENDING, we need to make sure the task wakes up.
+ * This is superfluous when called on current, the wakeup is a harmless no-op.
+ */
+void recalc_sigpending_and_wake(struct task_struct *t)
+{
+       if (recalc_sigpending_tsk(t))
+               signal_wake_up(t, 0);
 }
 
 void recalc_sigpending(void)
 {
-       recalc_sigpending_tsk(current);
+       if (!recalc_sigpending_tsk(current))
+               clear_thread_flag(TIF_SIGPENDING);
+
 }
 
 /* Given the mask, find the first available signal that should be serviced. */
@@ -373,7 +391,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
                        }
                }
        }
-       recalc_sigpending_tsk(tsk);
+       if (likely(tsk == current))
+               recalc_sigpending();
        if (signr && unlikely(sig_kernel_stop(signr))) {
                /*
                 * Set a marker that we have dequeued a stop signal.  Our
@@ -744,7 +763,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
                action->sa.sa_handler = SIG_DFL;
                if (blocked) {
                        sigdelset(&t->blocked, sig);
-                       recalc_sigpending_tsk(t);
+                       recalc_sigpending_and_wake(t);
                }
        }
        ret = specific_send_sig_info(sig, info, t);
@@ -1568,8 +1587,9 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
        /*
         * Queued signals ignored us while we were stopped for tracing.
         * So check for any that we should take before resuming user mode.
+        * This sets TIF_SIGPENDING, but never clears it.
         */
-       recalc_sigpending();
+       recalc_sigpending_tsk(current);
 }
 
 void ptrace_notify(int exit_code)
@@ -2273,7 +2293,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
                        rm_from_queue_full(&mask, &t->signal->shared_pending);
                        do {
                                rm_from_queue_full(&mask, &t->pending);
-                               recalc_sigpending_tsk(t);
+                               recalc_sigpending_and_wake(t);
                                t = next_thread(t);
                        } while (t != current);
                }
index eadfce2fff74c89f30849f1af213cde5a88dee14..8001d37071f59127dfac4ce83a651ad459395e66 100644 (file)
@@ -243,11 +243,18 @@ void tick_broadcast_on_off(unsigned long reason, int *oncpu)
 {
        int cpu = get_cpu();
 
-       if (cpu == *oncpu)
-               tick_do_broadcast_on_off(&reason);
-       else
-               smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
-                                        &reason, 1, 1);
+       if (!cpu_isset(*oncpu, cpu_online_map)) {
+               printk(KERN_ERR "tick-braodcast: ignoring broadcast for "
+                      "offline CPU #%d\n", *oncpu);
+       } else {
+
+               if (cpu == *oncpu)
+                       tick_do_broadcast_on_off(&reason);
+               else
+                       smp_call_function_single(*oncpu,
+                                                tick_do_broadcast_on_off,
+                                                &reason, 1, 1);
+       }
        put_cpu();
 }
 
index 3483e6cb9549c26e17d1985c2700737914871779..52db9e3c526e5bba4dc733a6d5ddd77908458401 100644 (file)
@@ -167,9 +167,15 @@ void tick_nohz_stop_sched_tick(void)
                goto end;
 
        cpu = smp_processor_id();
-       if (unlikely(local_softirq_pending()))
-               printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
-                      local_softirq_pending());
+       if (unlikely(local_softirq_pending())) {
+               static int ratelimit;
+
+               if (ratelimit < 10) {
+                       printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
+                              local_softirq_pending());
+                       ratelimit++;
+               }
+       }
 
        now = ktime_get();
        /*
@@ -241,6 +247,21 @@ void tick_nohz_stop_sched_tick(void)
                if (cpu == tick_do_timer_cpu)
                        tick_do_timer_cpu = -1;
 
+               ts->idle_sleeps++;
+
+               /*
+                * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
+                * there is no timer pending or at least extremly far
+                * into the future (12 days for HZ=1000). In this case
+                * we simply stop the tick timer:
+                */
+               if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
+                       ts->idle_expires.tv64 = KTIME_MAX;
+                       if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
+                               hrtimer_cancel(&ts->sched_timer);
+                       goto out;
+               }
+
                /*
                 * calculate the expiry time for the next timer wheel
                 * timer
@@ -248,7 +269,6 @@ void tick_nohz_stop_sched_tick(void)
                expires = ktime_add_ns(last_update, tick_period.tv64 *
                                       delta_jiffies);
                ts->idle_expires = expires;
-               ts->idle_sleeps++;
 
                if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
                        hrtimer_start(&ts->sched_timer, expires,
index 868f1bceb07ff60bfb87ec2be8d5729a70ece0bd..321693724ad743a74d81c2b3add00f3d4ee21237 100644 (file)
@@ -117,21 +117,6 @@ static struct entry entries[MAX_ENTRIES];
 
 static atomic_t overflow_count;
 
-static void reset_entries(void)
-{
-       nr_entries = 0;
-       memset(entries, 0, sizeof(entries));
-       atomic_set(&overflow_count, 0);
-}
-
-static struct entry *alloc_entry(void)
-{
-       if (nr_entries >= MAX_ENTRIES)
-               return NULL;
-
-       return entries + nr_entries++;
-}
-
 /*
  * The entries are in a hash-table, for fast lookup:
  */
@@ -149,6 +134,22 @@ static struct entry *alloc_entry(void)
 
 static struct entry *tstat_hash_table[TSTAT_HASH_SIZE] __read_mostly;
 
+static void reset_entries(void)
+{
+       nr_entries = 0;
+       memset(entries, 0, sizeof(entries));
+       memset(tstat_hash_table, 0, sizeof(tstat_hash_table));
+       atomic_set(&overflow_count, 0);
+}
+
+static struct entry *alloc_entry(void)
+{
+       if (nr_entries >= MAX_ENTRIES)
+               return NULL;
+
+       return entries + nr_entries++;
+}
+
 static int match_entries(struct entry *entry1, struct entry *entry2)
 {
        return entry1->timer       == entry2->timer       &&
@@ -202,12 +203,15 @@ static struct entry *tstat_lookup(struct entry *entry, char *comm)
        if (curr) {
                *curr = *entry;
                curr->count = 0;
+               curr->next = NULL;
                memcpy(curr->comm, comm, TASK_COMM_LEN);
+
+               smp_mb(); /* Ensure that curr is initialized before insert */
+
                if (prev)
                        prev->next = curr;
                else
                        *head = curr;
-               curr->next = NULL;
        }
  out_unlock:
        spin_unlock(&table_lock);
@@ -232,10 +236,15 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
        /*
         * It doesnt matter which lock we take:
         */
-       spinlock_t *lock = &per_cpu(lookup_lock, raw_smp_processor_id());
+       spinlock_t *lock;
        struct entry *entry, input;
        unsigned long flags;
 
+       if (likely(!active))
+               return;
+
+       lock = &per_cpu(lookup_lock, raw_smp_processor_id());
+
        input.timer = timer;
        input.start_func = startf;
        input.expire_func = timerf;
@@ -360,6 +369,7 @@ static ssize_t tstats_write(struct file *file, const char __user *buf,
                if (!active) {
                        reset_entries();
                        time_start = ktime_get();
+                       smp_mb();
                        active = 1;
                }
                break;
index 5ec5490f8d85ca083d3c1525fd4789fff5f3ff70..1a69705c2fb95536dc67c82479fcff315c0e0e1e 100644 (file)
@@ -666,7 +666,7 @@ static inline void __run_timers(tvec_base_t *base)
 static unsigned long __next_timer_interrupt(tvec_base_t *base)
 {
        unsigned long timer_jiffies = base->timer_jiffies;
-       unsigned long expires = timer_jiffies + (LONG_MAX >> 1);
+       unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA;
        int index, slot, array, found = 0;
        struct timer_list *nte;
        tvec_t *varray[4];
@@ -752,6 +752,14 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
 
        tsdelta = ktime_to_timespec(hr_delta);
        delta = timespec_to_jiffies(&tsdelta);
+
+       /*
+        * Limit the delta to the max value, which is checked in
+        * tick_nohz_stop_sched_tick():
+        */
+       if (delta > NEXT_TIMER_MAX_DELTA)
+               delta = NEXT_TIMER_MAX_DELTA;
+
        /*
         * Take rounding errors in to account and make sure, that it
         * expires in the next tick. Otherwise we go into an endless
index fb56fedd5c0274a3458bd0e7cbc8ae4e0d86cf6d..3bebf73be976592cab56a218e93b7449a5de7df4 100644 (file)
@@ -47,7 +47,6 @@ struct cpu_workqueue_struct {
 
        struct workqueue_struct *wq;
        struct task_struct *thread;
-       int should_stop;
 
        int run_depth;          /* Detect run_workqueue() recursion depth */
 } ____cacheline_aligned;
@@ -71,7 +70,13 @@ static LIST_HEAD(workqueues);
 
 static int singlethread_cpu __read_mostly;
 static cpumask_t cpu_singlethread_map __read_mostly;
-/* optimization, we could use cpu_possible_map */
+/*
+ * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD
+ * flushes cwq->worklist. This means that flush_workqueue/wait_on_work
+ * which comes in between can't use for_each_online_cpu(). We could
+ * use cpu_possible_map, the cpumask below is more a documentation
+ * than optimization.
+ */
 static cpumask_t cpu_populated_map __read_mostly;
 
 /* If it's single threaded, it isn't in the list of workqueues. */
@@ -272,24 +277,6 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
        spin_unlock_irq(&cwq->lock);
 }
 
-/*
- * NOTE: the caller must not touch *cwq if this func returns true
- */
-static int cwq_should_stop(struct cpu_workqueue_struct *cwq)
-{
-       int should_stop = cwq->should_stop;
-
-       if (unlikely(should_stop)) {
-               spin_lock_irq(&cwq->lock);
-               should_stop = cwq->should_stop && list_empty(&cwq->worklist);
-               if (should_stop)
-                       cwq->thread = NULL;
-               spin_unlock_irq(&cwq->lock);
-       }
-
-       return should_stop;
-}
-
 static int worker_thread(void *__cwq)
 {
        struct cpu_workqueue_struct *cwq = __cwq;
@@ -302,14 +289,15 @@ static int worker_thread(void *__cwq)
 
        for (;;) {
                prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
-               if (!freezing(current) && !cwq->should_stop
-                   && list_empty(&cwq->worklist))
+               if (!freezing(current) &&
+                   !kthread_should_stop() &&
+                   list_empty(&cwq->worklist))
                        schedule();
                finish_wait(&cwq->more_work, &wait);
 
                try_to_freeze();
 
-               if (cwq_should_stop(cwq))
+               if (kthread_should_stop())
                        break;
 
                run_workqueue(cwq);
@@ -340,18 +328,21 @@ static void insert_wq_barrier(struct cpu_workqueue_struct *cwq,
        insert_work(cwq, &barr->work, tail);
 }
 
-static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
+static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
 {
+       int active;
+
        if (cwq->thread == current) {
                /*
                 * Probably keventd trying to flush its own queue. So simply run
                 * it by hand rather than deadlocking.
                 */
                run_workqueue(cwq);
+               active = 1;
        } else {
                struct wq_barrier barr;
-               int active = 0;
 
+               active = 0;
                spin_lock_irq(&cwq->lock);
                if (!list_empty(&cwq->worklist) || cwq->current_work != NULL) {
                        insert_wq_barrier(cwq, &barr, 1);
@@ -362,6 +353,8 @@ static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
                if (active)
                        wait_for_completion(&barr.done);
        }
+
+       return active;
 }
 
 /**
@@ -674,7 +667,6 @@ static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
                return PTR_ERR(p);
 
        cwq->thread = p;
-       cwq->should_stop = 0;
 
        return 0;
 }
@@ -740,29 +732,27 @@ EXPORT_SYMBOL_GPL(__create_workqueue);
 
 static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 {
-       struct wq_barrier barr;
-       int alive = 0;
-
-       spin_lock_irq(&cwq->lock);
-       if (cwq->thread != NULL) {
-               insert_wq_barrier(cwq, &barr, 1);
-               cwq->should_stop = 1;
-               alive = 1;
-       }
-       spin_unlock_irq(&cwq->lock);
+       /*
+        * Our caller is either destroy_workqueue() or CPU_DEAD,
+        * workqueue_mutex protects cwq->thread
+        */
+       if (cwq->thread == NULL)
+               return;
 
-       if (alive) {
-               wait_for_completion(&barr.done);
+       /*
+        * If the caller is CPU_DEAD the single flush_cpu_workqueue()
+        * is not enough, a concurrent flush_workqueue() can insert a
+        * barrier after us.
+        * When ->worklist becomes empty it is safe to exit because no
+        * more work_structs can be queued on this cwq: flush_workqueue
+        * checks list_empty(), and a "normal" queue_work() can't use
+        * a dead CPU.
+        */
+       while (flush_cpu_workqueue(cwq))
+               ;
 
-               while (unlikely(cwq->thread != NULL))
-                       cpu_relax();
-               /*
-                * Wait until cwq->thread unlocks cwq->lock,
-                * it won't touch *cwq after that.
-                */
-               smp_rmb();
-               spin_unlock_wait(&cwq->lock);
-       }
+       kthread_stop(cwq->thread);
+       cwq->thread = NULL;
 }
 
 /**
index fbc5c622acb05db13d5cb5d248e42837470b1ca4..da95e10cfd7094e8996ab08bb38c1f1bd5d4d6f9 100644 (file)
@@ -126,7 +126,10 @@ config TIMER_STATS
          reprogrammed. The statistics can be read from /proc/timer_stats.
          The statistics collection is started by writing 1 to /proc/timer_stats,
          writing 0 stops it. This feature is useful to collect information
-         about timer usage patterns in kernel and userspace.
+         about timer usage patterns in kernel and userspace. This feature
+         is lightweight if enabled in the kernel config but not activated
+         (it defaults to deactivated on bootup and will only be activated
+         if some application like powertop activates it explicitly).
 
 config DEBUG_SLAB
        bool "Debug slab memory allocations"
@@ -378,14 +381,13 @@ config FORCED_INLINING
 config RCU_TORTURE_TEST
        tristate "torture tests for RCU"
        depends on DEBUG_KERNEL
+       depends on m
        default n
        help
          This option provides a kernel module that runs torture tests
          on the RCU infrastructure.  The kernel module may be built
          after the fact on the running kernel to be tested, if desired.
 
-         Say Y here if you want RCU torture tests to start automatically
-         at boot time (you probably don't).
          Say M if you want the RCU torture tests to build as a module.
          Say N if you are unsure.
 
index e6da5b7fc29a1f7ad57842e6f477f096f45c89a7..473f5aed6caeebe88e813429a6e690e3c4ba42c9 100644 (file)
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
+ * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
+ * @ascii: include ASCII after the hex output
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
- * 16 bytes of input data converted to hex + ASCII output.
+ * 16 or 32 bytes of input data converted to hex + ASCII output.
  *
  * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
  * to a hex + ASCII dump at the supplied memory location.
  * The converted output is always NUL-terminated.
  *
  * E.g.:
- *     hex_dump_to_buffer(frame->data, frame->len, linebuf, sizeof(linebuf));
+ *   hex_dump_to_buffer(frame->data, frame->len, 16, 1,
+ *                     linebuf, sizeof(linebuf), 1);
  *
  * example output buffer:
- * 40414243 44454647 48494a4b 4c4d4e4f  @ABCDEFGHIJKLMNO
+ * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
  */
-void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf,
-                       size_t linebuflen)
+void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
+                       int groupsize, char *linebuf, size_t linebuflen,
+                       bool ascii)
 {
        const u8 *ptr = buf;
        u8 ch;
        int j, lx = 0;
+       int ascii_column;
 
-       for (j = 0; (j < 16) && (j < len) && (lx + 3) < linebuflen; j++) {
-               if (j && !(j % 4))
+       if (rowsize != 16 && rowsize != 32)
+               rowsize = 16;
+
+       if (!len)
+               goto nil;
+       if (len > rowsize)              /* limit to one line at a time */
+               len = rowsize;
+       if ((len % groupsize) != 0)     /* no mixed size output */
+               groupsize = 1;
+
+       switch (groupsize) {
+       case 8: {
+               const u64 *ptr8 = buf;
+               int ngroups = len / groupsize;
+
+               for (j = 0; j < ngroups; j++)
+                       lx += scnprintf(linebuf + lx, linebuflen - lx,
+                               "%16.16llx ", (unsigned long long)*(ptr8 + j));
+               ascii_column = 17 * ngroups + 2;
+               break;
+       }
+
+       case 4: {
+               const u32 *ptr4 = buf;
+               int ngroups = len / groupsize;
+
+               for (j = 0; j < ngroups; j++)
+                       lx += scnprintf(linebuf + lx, linebuflen - lx,
+                               "%8.8x ", *(ptr4 + j));
+               ascii_column = 9 * ngroups + 2;
+               break;
+       }
+
+       case 2: {
+               const u16 *ptr2 = buf;
+               int ngroups = len / groupsize;
+
+               for (j = 0; j < ngroups; j++)
+                       lx += scnprintf(linebuf + lx, linebuflen - lx,
+                               "%4.4x ", *(ptr2 + j));
+               ascii_column = 5 * ngroups + 2;
+               break;
+       }
+
+       default:
+               for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen;
+                    j++) {
+                       ch = ptr[j];
+                       linebuf[lx++] = hex_asc(ch >> 4);
+                       linebuf[lx++] = hex_asc(ch & 0x0f);
                        linebuf[lx++] = ' ';
-               ch = ptr[j];
-               linebuf[lx++] = hex_asc(ch >> 4);
-               linebuf[lx++] = hex_asc(ch & 0x0f);
+               }
+               ascii_column = 3 * rowsize + 2;
+               break;
        }
-       if ((lx + 2) < linebuflen) {
-               linebuf[lx++] = ' ';
+       if (!ascii)
+               goto nil;
+
+       while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
                linebuf[lx++] = ' ';
-       }
-       for (j = 0; (j < 16) && (j < len) && (lx + 2) < linebuflen; j++)
+       for (j = 0; (j < rowsize) && (j < len) && (lx + 2) < linebuflen; j++)
                linebuf[lx++] = isprint(ptr[j]) ? ptr[j] : '.';
+nil:
        linebuf[lx++] = '\0';
 }
 EXPORT_SYMBOL(hex_dump_to_buffer);
@@ -59,46 +115,83 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
 /**
  * print_hex_dump - print a text hex dump to syslog for a binary blob of data
  * @level: kernel log level (e.g. KERN_DEBUG)
+ * @prefix_str: string to prefix each line with;
+ *  caller supplies trailing spaces for alignment if desired
  * @prefix_type: controls whether prefix of an offset, address, or none
  *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
+ * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
+ * @ascii: include ASCII after the hex output
  *
  * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
  * to the kernel log at the specified kernel log level, with an optional
  * leading prefix.
  *
+ * print_hex_dump() works on one "line" of output at a time, i.e.,
+ * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * print_hex_dump() iterates over the entire input @buf, breaking it into
+ * "line size" chunks to format and print.
+ *
  * E.g.:
- *   print_hex_dump(KERN_DEBUG, DUMP_PREFIX_ADDRESS, frame->data, frame->len);
+ *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
+ *             16, 1, frame->data, frame->len, 1);
  *
- * Example output using %DUMP_PREFIX_OFFSET:
- * 0009ab42: 40414243 44454647 48494a4b 4c4d4e4f  @ABCDEFGHIJKLMNO
- * Example output using %DUMP_PREFIX_ADDRESS:
- * ffffffff88089af0: 70717273 74757677 78797a7b 7c7d7e7f  pqrstuvwxyz{|}~.
+ * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
+ * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
+ * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
+ * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.
  */
-void print_hex_dump(const char *level, int prefix_type, void *buf, size_t len)
+void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
+                       int rowsize, int groupsize,
+                       void *buf, size_t len, bool ascii)
 {
        u8 *ptr = buf;
        int i, linelen, remaining = len;
-       unsigned char linebuf[100];
+       unsigned char linebuf[200];
 
-       for (i = 0; i < len; i += 16) {
-               linelen = min(remaining, 16);
-               remaining -= 16;
-               hex_dump_to_buffer(ptr + i, linelen, linebuf, sizeof(linebuf));
+       if (rowsize != 16 && rowsize != 32)
+               rowsize = 16;
+
+       for (i = 0; i < len; i += rowsize) {
+               linelen = min(remaining, rowsize);
+               remaining -= rowsize;
+               hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
+                               linebuf, sizeof(linebuf), ascii);
 
                switch (prefix_type) {
                case DUMP_PREFIX_ADDRESS:
-                       printk("%s%*p: %s\n", level,
+                       printk("%s%s%*p: %s\n", level, prefix_str,
                                (int)(2 * sizeof(void *)), ptr + i, linebuf);
                        break;
                case DUMP_PREFIX_OFFSET:
-                       printk("%s%.8x: %s\n", level, i, linebuf);
+                       printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
                        break;
                default:
-                       printk("%s%s\n", level, linebuf);
+                       printk("%s%s%s\n", level, prefix_str, linebuf);
                        break;
                }
        }
 }
 EXPORT_SYMBOL(print_hex_dump);
+
+/**
+ * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
+ * @prefix_str: string to prefix each line with;
+ *  caller supplies trailing spaces for alignment if desired
+ * @prefix_type: controls whether prefix of an offset, address, or none
+ *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
+ * @buf: data blob to dump
+ * @len: number of bytes in the @buf
+ *
+ * Calls print_hex_dump(), with log level of KERN_DEBUG,
+ * rowsize of 16, groupsize of 1, and ASCII output included.
+ */
+void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
+                       void *buf, size_t len)
+{
+       print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
+                       buf, len, 1);
+}
+EXPORT_SYMBOL(print_hex_dump_bytes);
index fc5f3f6e73299a27e394294efb4564dea3511c2c..ac1520651b9b457d89e96bd2447aae02d6f8bb46 100644 (file)
@@ -202,14 +202,14 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
 
                /* be noisy on error issues */
                if (error == -EEXIST)
-                       printk("kobject_add failed for %s with -EEXIST, "
-                              "don't try to register things with the "
-                              "same name in the same directory.\n",
+                       printk(KERN_ERR "kobject_add failed for %s with "
+                              "-EEXIST, don't try to register things with "
+                              "the same name in the same directory.\n",
                               kobject_name(kobj));
                else
-                       printk("kobject_add failed for %s (%d)\n",
+                       printk(KERN_ERR "kobject_add failed for %s (%d)\n",
                               kobject_name(kobj), error);
-                dump_stack();
+               dump_stack();
        }
 
        return error;
index 84279127fcd3ab935f922b4c7e1156bb205d9964..df9d554bea3081ec75b45e828326e015b62c0338 100644 (file)
@@ -65,7 +65,7 @@ static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
        int zone_type;
 
        zone_type = zone - pgdat->node_zones;
-       if (!populated_zone(zone)) {
+       if (!zone->wait_table) {
                int ret = 0;
                ret = init_currently_empty_zone(zone, phys_start_pfn,
                                                nr_pages, MEMMAP_HOTPLUG);
index 8b000d6803c298adf0c2402a3cd9296b350e32e5..bd8e33582d25555af55c93d258a842c173a8072c 100644 (file)
@@ -136,6 +136,11 @@ static unsigned long __meminitdata dma_reserve;
 #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */
 #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 
+#if MAX_NUMNODES > 1
+int nr_node_ids __read_mostly = MAX_NUMNODES;
+EXPORT_SYMBOL(nr_node_ids);
+#endif
+
 #ifdef CONFIG_DEBUG_VM
 static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
 {
@@ -669,26 +674,6 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
        return i;
 }
 
-#if MAX_NUMNODES > 1
-int nr_node_ids __read_mostly = MAX_NUMNODES;
-EXPORT_SYMBOL(nr_node_ids);
-
-/*
- * Figure out the number of possible node ids.
- */
-static void __init setup_nr_node_ids(void)
-{
-       unsigned int node;
-       unsigned int highest = 0;
-
-       for_each_node_mask(node, node_possible_map)
-               highest = node;
-       nr_node_ids = highest + 1;
-}
-#else
-static void __init setup_nr_node_ids(void) {}
-#endif
-
 #ifdef CONFIG_NUMA
 /*
  * Called from the vmstat counter updater to drain pagesets of this
@@ -2704,7 +2689,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat)
                        map = alloc_bootmem_node(pgdat, size);
                pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
        }
-#ifdef CONFIG_FLATMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
        /*
         * With no DISCONTIG, the global mem_map is just set as node 0's
         */
@@ -2733,6 +2718,26 @@ void __meminit free_area_init_node(int nid, struct pglist_data *pgdat,
 }
 
 #ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+
+#if MAX_NUMNODES > 1
+/*
+ * Figure out the number of possible node ids.
+ */
+static void __init setup_nr_node_ids(void)
+{
+       unsigned int node;
+       unsigned int highest = 0;
+
+       for_each_node_mask(node, node_possible_map)
+               highest = node;
+       nr_node_ids = highest + 1;
+}
+#else
+static inline void setup_nr_node_ids(void)
+{
+}
+#endif
+
 /**
  * add_active_range - Register a range of PFNs backed by physical memory
  * @nid: The node ID the range resides on
index e537317bec4d5d02977bf92021d87242e2ff549b..b6aae2b33393d96d694145326c6591acf6f83b4b 100644 (file)
@@ -967,6 +967,8 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_
                *nodelist++ = '\0';
                if (nodelist_parse(nodelist, *policy_nodes))
                        goto out;
+               if (!nodes_subset(*policy_nodes, node_online_map))
+                       goto out;
        }
        if (!strcmp(value, "default")) {
                *policy = MPOL_DEFAULT;
index 2e71a328aa09540a75f83ab289a3da8931920914..6d65cf4e4b2e03fb1cbd860a1932ce0cd5cb2621 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3539,7 +3539,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
        check_irq_off();
        objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
 
-       if (use_alien_caches && cache_free_alien(cachep, objp))
+       if (cache_free_alien(cachep, objp))
                return;
 
        if (likely(ac->avail < ac->limit)) {
index 98801d404d6992e9b8a18170561eec3500b48bf6..c9ab68881b43ebe8525fb2fa1e943f9810229c21 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -939,7 +939,7 @@ static void kmem_cache_open_debug_check(struct kmem_cache *s)
         * Debugging or ctor may create a need to move the free
         * pointer. Fail if this happens.
         */
-       if (s->size >= 65535 * sizeof(void *)) {
+       if (s->objsize >= 65535 * sizeof(void *)) {
                BUG_ON(s->flags & (SLAB_RED_ZONE | SLAB_POISON |
                                SLAB_STORE_USER | SLAB_DESTROY_BY_RCU));
                BUG_ON(s->ctor);
@@ -1917,7 +1917,6 @@ static int calculate_sizes(struct kmem_cache *s)
         */
        s->inuse = size;
 
-#ifdef CONFIG_SLUB_DEBUG
        if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) ||
                s->ctor)) {
                /*
@@ -1932,6 +1931,7 @@ static int calculate_sizes(struct kmem_cache *s)
                size += sizeof(void *);
        }
 
+#ifdef CONFIG_SLUB_DEBUG
        if (flags & SLAB_STORE_USER)
                /*
                 * Need to store information about allocs and frees after
@@ -2241,7 +2241,7 @@ void *__kmalloc(size_t size, gfp_t flags)
 
        if (s)
                return slab_alloc(s, flags, -1, __builtin_return_address(0));
-       return NULL;
+       return ZERO_SIZE_PTR;
 }
 EXPORT_SYMBOL(__kmalloc);
 
@@ -2252,16 +2252,20 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
 
        if (s)
                return slab_alloc(s, flags, node, __builtin_return_address(0));
-       return NULL;
+       return ZERO_SIZE_PTR;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 #endif
 
 size_t ksize(const void *object)
 {
-       struct page *page = get_object_page(object);
+       struct page *page;
        struct kmem_cache *s;
 
+       if (object == ZERO_SIZE_PTR)
+               return 0;
+
+       page = get_object_page(object);
        BUG_ON(!page);
        s = page->slab;
        BUG_ON(!s);
@@ -2293,7 +2297,13 @@ void kfree(const void *x)
        struct kmem_cache *s;
        struct page *page;
 
-       if (!x)
+       /*
+        * This has to be an unsigned comparison. According to Linus
+        * some gcc version treat a pointer as a signed entity. Then
+        * this comparison would be true for all "negative" pointers
+        * (which would cover the whole upper half of the address space).
+        */
+       if ((unsigned long)x <= (unsigned long)ZERO_SIZE_PTR)
                return;
 
        page = virt_to_head_page(x);
@@ -2398,12 +2408,12 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)
        void *ret;
        size_t ks;
 
-       if (unlikely(!p))
+       if (unlikely(!p || p == ZERO_SIZE_PTR))
                return kmalloc(new_size, flags);
 
        if (unlikely(!new_size)) {
                kfree(p);
-               return NULL;
+               return ZERO_SIZE_PTR;
        }
 
        ks = ksize(p);
@@ -2435,6 +2445,7 @@ void __init kmem_cache_init(void)
         */
        create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
                sizeof(struct kmem_cache_node), GFP_KERNEL);
+       kmalloc_caches[0].refcount = -1;
 #endif
 
        /* Able to allocate the per node structures */
@@ -2482,6 +2493,12 @@ static int slab_unmergeable(struct kmem_cache *s)
        if (s->ctor)
                return 1;
 
+       /*
+        * We may have set a slab to be unmergeable during bootstrap.
+        */
+       if (s->refcount < 0)
+               return 1;
+
        return 0;
 }
 
@@ -2600,6 +2617,19 @@ static void for_all_slabs(void (*func)(struct kmem_cache *, int), int cpu)
        up_read(&slub_lock);
 }
 
+/*
+ * Version of __flush_cpu_slab for the case that interrupts
+ * are enabled.
+ */
+static void cpu_slab_flush(struct kmem_cache *s, int cpu)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __flush_cpu_slab(s, cpu);
+       local_irq_restore(flags);
+}
+
 /*
  * Use the cpu notifier to insure that the cpu slabs are flushed when
  * necessary.
@@ -2614,7 +2644,7 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
        case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               for_all_slabs(__flush_cpu_slab, cpu);
+               for_all_slabs(cpu_slab_flush, cpu);
                break;
        default:
                break;
@@ -2632,7 +2662,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
        struct kmem_cache *s = get_slab(size, gfpflags);
 
        if (!s)
-               return NULL;
+               return ZERO_SIZE_PTR;
 
        return slab_alloc(s, gfpflags, -1, caller);
 }
@@ -2643,7 +2673,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
        struct kmem_cache *s = get_slab(size, gfpflags);
 
        if (!s)
-               return NULL;
+               return ZERO_SIZE_PTR;
 
        return slab_alloc(s, gfpflags, node, caller);
 }
index 1302f8348d51c8dbc10d104c333eeea3e01a6f1a..e03b39f3540f79adf384c476f185e7a9da91e4ac 100644 (file)
@@ -209,6 +209,12 @@ static int __meminit sparse_init_one_section(struct mem_section *ms,
        return 1;
 }
 
+__attribute__((weak))
+void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
+{
+       return NULL;
+}
+
 static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
 {
        struct page *map;
@@ -219,6 +225,11 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
        if (map)
                return map;
 
+       map = alloc_bootmem_high_node(NODE_DATA(nid),
+                       sizeof(struct page) * PAGES_PER_SECTION);
+       if (map)
+               return map;
+
        map = alloc_bootmem_node(NODE_DATA(nid),
                        sizeof(struct page) * PAGES_PER_SECTION);
        if (map)
@@ -229,6 +240,27 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
        return NULL;
 }
 
+/*
+ * Allocate the accumulated non-linear sections, allocate a mem_map
+ * for each and record the physical to section mapping.
+ */
+void __init sparse_init(void)
+{
+       unsigned long pnum;
+       struct page *map;
+
+       for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
+               if (!valid_section_nr(pnum))
+                       continue;
+
+               map = sparse_early_mem_map_alloc(pnum);
+               if (!map)
+                       continue;
+               sparse_init_one_section(__nr_to_section(pnum), pnum, map);
+       }
+}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
 static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
 {
        struct page *page, *ret;
@@ -268,27 +300,6 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
                           get_order(sizeof(struct page) * nr_pages));
 }
 
-/*
- * Allocate the accumulated non-linear sections, allocate a mem_map
- * for each and record the physical to section mapping.
- */
-void __init sparse_init(void)
-{
-       unsigned long pnum;
-       struct page *map;
-
-       for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
-               if (!valid_section_nr(pnum))
-                       continue;
-
-               map = sparse_early_mem_map_alloc(pnum);
-               if (!map)
-                       continue;
-               sparse_init_one_section(__nr_to_section(pnum), pnum, map);
-       }
-}
-
-#ifdef CONFIG_MEMORY_HOTPLUG
 /*
  * returns the number of sections whose mem_maps were properly
  * set.  If this is <=0, then that means that the passed-in
index bd93c45778d4eaf2d9e3534620da43a088217b10..de78c9dd713bbfb0bb0942bea0f98bd5ffb6179a 100644 (file)
@@ -240,10 +240,8 @@ static int unregister_vlan_dev(struct net_device *real_dev,
                         * interlock with HW accelerating devices or SW vlan
                         * input packet processing.
                         */
-                       if (real_dev->features &
-                           (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER)) {
+                       if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
                                real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
-                       }
 
                        vlan_group_set_device(grp, vlan_id, NULL);
                        synchronize_net();
@@ -409,16 +407,14 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
-           (real_dev->vlan_rx_register == NULL ||
-            real_dev->vlan_rx_kill_vid == NULL)) {
+           !real_dev->vlan_rx_register) {
                printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
                        __FUNCTION__, real_dev->name);
                goto out_put_dev;
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
-           (real_dev->vlan_rx_add_vid == NULL ||
-            real_dev->vlan_rx_kill_vid == NULL)) {
+           (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
                printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
                        __FUNCTION__, real_dev->name);
                goto out_put_dev;
@@ -740,8 +736,7 @@ static int vlan_ioctl_handler(void __user *arg)
        case SET_VLAN_NAME_TYPE_CMD:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               if ((args.u.name_type >= 0) &&
-                   (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
+               if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
                        vlan_name_type = args.u.name_type;
                        err = 0;
                } else {
index a59b1fb63b76d82baf849bc28ee0d29b551ddea9..670ff95ca64b1b30048ce72eb82584ca5b17baa3 100644 (file)
@@ -507,6 +507,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
        }
 
        /* Default config options */
+       pi->conf_len = 0;
        pi->conf_mtu = L2CAP_DEFAULT_MTU;
        pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
 }
@@ -1271,42 +1272,6 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
        return len;
 }
 
-static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-{
-       int type, hint, olen;
-       unsigned long val;
-       void *ptr = data;
-
-       BT_DBG("sk %p len %d", sk, len);
-
-       while (len >= L2CAP_CONF_OPT_SIZE) {
-               len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-
-               hint  = type & 0x80;
-               type &= 0x7f;
-
-               switch (type) {
-               case L2CAP_CONF_MTU:
-                       l2cap_pi(sk)->conf_mtu = val;
-                       break;
-
-               case L2CAP_CONF_FLUSH_TO:
-                       l2cap_pi(sk)->flush_to = val;
-                       break;
-
-               case L2CAP_CONF_QOS:
-                       break;
-
-               default:
-                       if (hint)
-                               break;
-
-                       /* FIXME: Reject unknown option */
-                       break;
-               }
-       }
-}
-
 static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
 {
        struct l2cap_conf_opt *opt = *ptr;
@@ -1358,39 +1323,75 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
        return ptr - data;
 }
 
-static inline int l2cap_conf_output(struct sock *sk, void **ptr)
+static int l2cap_parse_conf_req(struct sock *sk, void *data)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
-       int result = 0;
+       struct l2cap_conf_rsp *rsp = data;
+       void *ptr = rsp->data;
+       void *req = pi->conf_req;
+       int len = pi->conf_len;
+       int type, hint, olen;
+       unsigned long val;
+       u16 result = L2CAP_CONF_SUCCESS;
 
-       /* Configure output options and let the other side know
-        * which ones we don't like. */
-       if (pi->conf_mtu < pi->omtu)
-               result = L2CAP_CONF_UNACCEPT;
-       else
-               pi->omtu = pi->conf_mtu;
+       BT_DBG("sk %p", sk);
+
+       while (len >= L2CAP_CONF_OPT_SIZE) {
+               len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
 
-       l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+               hint  = type & 0x80;
+               type &= 0x7f;
+
+               switch (type) {
+               case L2CAP_CONF_MTU:
+                       pi->conf_mtu = val;
+                       break;
+
+               case L2CAP_CONF_FLUSH_TO:
+                       pi->flush_to = val;
+                       break;
+
+               case L2CAP_CONF_QOS:
+                       break;
+
+               default:
+                       if (hint)
+                               break;
+
+                       result = L2CAP_CONF_UNKNOWN;
+                       *((u8 *) ptr++) = type;
+                       break;
+               }
+       }
+
+       if (result == L2CAP_CONF_SUCCESS) {
+               /* Configure output options and let the other side know
+                * which ones we don't like. */
+
+               if (pi->conf_mtu < pi->omtu)
+                       result = L2CAP_CONF_UNACCEPT;
+               else
+                       pi->omtu = pi->conf_mtu;
+
+               l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+       }
 
-       BT_DBG("sk %p result %d", sk, result);
-       return result;
+       rsp->scid   = cpu_to_le16(pi->dcid);
+       rsp->result = cpu_to_le16(result);
+       rsp->flags  = cpu_to_le16(0x0000);
+
+       return ptr - data;
 }
 
-static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
+static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
 {
        struct l2cap_conf_rsp *rsp = data;
        void *ptr = rsp->data;
-       u16 flags = 0;
-
-       BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
 
-       if (result)
-               *result = l2cap_conf_output(sk, &ptr);
-       else
-               flags = 0x0001;
+       BT_DBG("sk %p", sk);
 
        rsp->scid   = cpu_to_le16(l2cap_pi(sk)->dcid);
-       rsp->result = cpu_to_le16(result ? *result : 0);
+       rsp->result = cpu_to_le16(result);
        rsp->flags  = cpu_to_le16(flags);
 
        return ptr - data;
@@ -1535,7 +1536,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        u16 dcid, flags;
        u8 rsp[64];
        struct sock *sk;
-       int result;
+       int len;
 
        dcid  = __le16_to_cpu(req->dcid);
        flags = __le16_to_cpu(req->flags);
@@ -1548,25 +1549,40 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (sk->sk_state == BT_DISCONN)
                goto unlock;
 
-       l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
+       /* Reject if config buffer is too small. */
+       len = cmd->len - sizeof(*req);
+       if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
+               l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
+                               l2cap_build_conf_rsp(sk, rsp,
+                                       L2CAP_CONF_REJECT, flags), rsp);
+               goto unlock;
+       }
+
+       /* Store config. */
+       memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
+       l2cap_pi(sk)->conf_len += len;
 
        if (flags & 0x0001) {
                /* Incomplete config. Send empty response. */
                l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
-                               l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
+                               l2cap_build_conf_rsp(sk, rsp,
+                                       L2CAP_CONF_SUCCESS, 0x0001), rsp);
                goto unlock;
        }
 
        /* Complete config. */
-       l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
-                       l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-
-       if (result)
+       len = l2cap_parse_conf_req(sk, rsp);
+       if (len < 0)
                goto unlock;
 
-       /* Output config done */
+       l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
+
+       /* Output config done. */
        l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
 
+       /* Reset config buffer. */
+       l2cap_pi(sk)->conf_len = 0;
+
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
                sk->sk_state = BT_CONNECTED;
                l2cap_chan_ready(sk);
index 91b017016d5bcbdd240770f9528706439b91a5f7..3fc697293819524823ee8bb4d9918493f12db6e0 100644 (file)
@@ -121,6 +121,7 @@ void br_fdb_cleanup(unsigned long _data)
 {
        struct net_bridge *br = (struct net_bridge *)_data;
        unsigned long delay = hold_time(br);
+       unsigned long next_timer = jiffies + br->forward_delay;
        int i;
 
        spin_lock_bh(&br->hash_lock);
@@ -129,14 +130,21 @@ void br_fdb_cleanup(unsigned long _data)
                struct hlist_node *h, *n;
 
                hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
-                       if (!f->is_static &&
-                           time_before_eq(f->ageing_timer + delay, jiffies))
+                       unsigned long this_timer;
+                       if (f->is_static)
+                               continue;
+                       this_timer = f->ageing_timer + delay;
+                       if (time_before_eq(this_timer, jiffies))
                                fdb_delete(f);
+                       else if (this_timer < next_timer)
+                               next_timer = this_timer;
                }
        }
        spin_unlock_bh(&br->hash_lock);
 
-       mod_timer(&br->gc_timer, jiffies + HZ/10);
+       /* Add HZ/4 to ensure we round the jiffies upwards to be after the next
+        * timer, otherwise we might round down and will have no-op run. */
+       mod_timer(&br->gc_timer, round_jiffies(next_timer + HZ/4));
 }
 
 /* Completely flush all dynamic entries in forwarding database.*/
index 0e035d6162cc840e1e7a71592f79894e0cb5b316..e38034aa56f5a2f6d1476f38cf3e931a18513fe0 100644 (file)
@@ -178,7 +178,8 @@ void br_transmit_config(struct net_bridge_port *p)
                br_send_config_bpdu(p, &bpdu);
                p->topology_change_ack = 0;
                p->config_pending = 0;
-               mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
+               mod_timer(&p->hold_timer,
+                         round_jiffies(jiffies + BR_HOLD_TIME));
        }
 }
 
index 24e0ca4a3131948af3cf2d59c956ccf9f852fc96..77f5255e691569a48766cce3ce109a4aec17c0df 100644 (file)
@@ -42,7 +42,7 @@ static void br_hello_timer_expired(unsigned long arg)
        if (br->dev->flags & IFF_UP) {
                br_config_bpdu_generation(br);
 
-               mod_timer(&br->hello_timer, jiffies + br->hello_time);
+               mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time));
        }
        spin_unlock(&br->lock);
 }
index 5a7f20f7857468aeab6ba56ba391c228a59efc91..26090621ea6b6b6e5c5210a6cfaaa2915a135e5e 100644 (file)
@@ -2577,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev)
 
 int dev_change_flags(struct net_device *dev, unsigned flags)
 {
-       int ret;
+       int ret, changes;
        int old_flags = dev->flags;
 
        /*
@@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
                dev_set_allmulti(dev, inc);
        }
 
-       if (old_flags ^ dev->flags)
-               rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags);
+       /* Exclude state transition flags, already notified */
+       changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING);
+       if (changes)
+               rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
 
        return ret;
 }
index 764bccb3d99265b2a014b41167d999cf1574e639..c6a05879d58cd3c87fb854541bb3c3440d858de9 100644 (file)
@@ -111,13 +111,7 @@ out:
        spin_unlock(&dst_lock);
 }
 
-static int dst_discard_in(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return 0;
-}
-
-static int dst_discard_out(struct sk_buff *skb)
+static int dst_discard(struct sk_buff *skb)
 {
        kfree_skb(skb);
        return 0;
@@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops)
        dst->ops = ops;
        dst->lastuse = jiffies;
        dst->path = dst;
-       dst->input = dst_discard_in;
-       dst->output = dst_discard_out;
+       dst->input = dst->output = dst_discard;
 #if RT_CACHE_DEBUG >= 2
        atomic_inc(&dst_total);
 #endif
@@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst)
           protocol module is unloaded.
         */
        if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
-               dst->input = dst_discard_in;
-               dst->output = dst_discard_out;
+               dst->input = dst->output = dst_discard;
        }
        dst->obsolete = 2;
 }
@@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
                return;
 
        if (!unregister) {
-               dst->input = dst_discard_in;
-               dst->output = dst_discard_out;
+               dst->input = dst->output = dst_discard;
        } else {
                dst->dev = &loopback_dev;
                dev_hold(&loopback_dev);
index 6f3bb73053c23fc6d4427957567d3a84c6033b62..9df26a07f0672ccabe610f366026fa4b2123524c 100644 (file)
@@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
        return NULL;
 }
 
-static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
+static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
        [NDTA_NAME]             = { .type = NLA_STRING },
        [NDTA_THRESH1]          = { .type = NLA_U32 },
        [NDTA_THRESH2]          = { .type = NLA_U32 },
@@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
        [NDTA_PARMS]            = { .type = NLA_NESTED },
 };
 
-static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = {
+static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
        [NDTPA_IFINDEX]                 = { .type = NLA_U32 },
        [NDTPA_QUEUE_LEN]               = { .type = NLA_U32 },
        [NDTPA_PROXY_QLEN]              = { .type = NLA_U32 },
index 8c971a2efe2a1df32f8b9791852360a597a47bf5..02e8bf084277963300be7cd68f7a8b6de67cab59 100644 (file)
@@ -437,7 +437,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
        a->tx_compressed = b->tx_compressed;
 };
 
-static inline size_t if_nlmsg_size(int iwbuflen)
+static inline size_t if_nlmsg_size(void)
 {
        return NLMSG_ALIGN(sizeof(struct ifinfomsg))
               + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,13 +452,12 @@ static inline size_t if_nlmsg_size(int iwbuflen)
               + nla_total_size(4) /* IFLA_LINK */
               + nla_total_size(4) /* IFLA_MASTER */
               + nla_total_size(1) /* IFLA_OPERSTATE */
-              + nla_total_size(1) /* IFLA_LINKMODE */
-              + nla_total_size(iwbuflen);
+              + nla_total_size(1); /* IFLA_LINKMODE */
 }
 
 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
-                           void *iwbuf, int iwbuflen, int type, u32 pid,
-                           u32 seq, u32 change, unsigned int flags)
+                           int type, u32 pid, u32 seq, u32 change,
+                           unsigned int flags)
 {
        struct ifinfomsg *ifm;
        struct nlmsghdr *nlh;
@@ -523,9 +522,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                }
        }
 
-       if (iwbuf)
-               NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf);
-
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
@@ -543,7 +539,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
        for_each_netdev(dev) {
                if (idx < s_idx)
                        goto cont;
-               if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK,
+               if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
                                     NETLINK_CB(cb->skb).pid,
                                     cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
                        break;
@@ -555,7 +551,7 @@ cont:
        return skb->len;
 }
 
-static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = {
+static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_IFNAME]           = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
        [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
        [IFLA_MTU]              = { .type = NLA_U32 },
@@ -584,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
        err = -EINVAL;
        ifm = nlmsg_data(nlh);
-       if (ifm->ifi_index >= 0)
+       if (ifm->ifi_index > 0)
                dev = dev_get_by_index(ifm->ifi_index);
        else if (tb[IFLA_IFNAME])
                dev = dev_get_by_name(ifname);
@@ -676,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
         * name provided implies that a name change has been
         * requested.
         */
-       if (ifm->ifi_index >= 0 && ifname[0]) {
+       if (ifm->ifi_index > 0 && ifname[0]) {
                err = dev_change_name(dev, ifname);
                if (err < 0)
                        goto errout_dev;
@@ -689,8 +685,15 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        }
 
 
-       if (ifm->ifi_flags)
-               dev_change_flags(dev, ifm->ifi_flags);
+       if (ifm->ifi_flags || ifm->ifi_change) {
+               unsigned int flags = ifm->ifi_flags;
+
+               /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
+               if (ifm->ifi_change)
+                       flags = (flags & ifm->ifi_change) |
+                               (dev->flags & ~ifm->ifi_change);
+               dev_change_flags(dev, flags);
+       }
 
        if (tb[IFLA_TXQLEN])
                dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
@@ -730,8 +733,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        struct nlattr *tb[IFLA_MAX+1];
        struct net_device *dev = NULL;
        struct sk_buff *nskb;
-       char *iw_buf = NULL, *iw = NULL;
-       int iw_buf_len = 0;
        int err;
 
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
@@ -739,21 +740,21 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                return err;
 
        ifm = nlmsg_data(nlh);
-       if (ifm->ifi_index >= 0) {
+       if (ifm->ifi_index > 0) {
                dev = dev_get_by_index(ifm->ifi_index);
                if (dev == NULL)
                        return -ENODEV;
        } else
                return -EINVAL;
 
-       nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
+       nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
        if (nskb == NULL) {
                err = -ENOBUFS;
                goto errout;
        }
 
-       err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
-                              NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
+       err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
+                              nlh->nlmsg_seq, 0, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in if_nlmsg_size */
                WARN_ON(err == -EMSGSIZE);
@@ -762,7 +763,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        }
        err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
 errout:
-       kfree(iw_buf);
        dev_put(dev);
 
        return err;
@@ -797,11 +797,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL);
+       skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
 
-       err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
+       err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in if_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
index 22183c2ef28497a3698112e215d691b24dbda816..c14ce0198d25d7be42762ee3dae5df76ba9ec8d6 100644 (file)
@@ -206,7 +206,19 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
                return -EINVAL;
        if (copy_from_user(&tv, optval, sizeof(tv)))
                return -EFAULT;
-
+       if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
+               return -EDOM;
+
+       if (tv.tv_sec < 0) {
+               static int warned = 0;
+               *timeo_p = 0;
+               if (warned < 10 && net_ratelimit())
+                       warned++;
+                       printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
+                              "tries to set negative timeout\n",
+                               current->comm, current->pid);
+               return 0;
+       }
        *timeo_p = MAX_SCHEDULE_TIMEOUT;
        if (tv.tv_sec == 0 && tv.tv_usec == 0)
                return 0;
@@ -986,7 +998,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
        __sk_dst_set(sk, dst);
        sk->sk_route_caps = dst->dev->features;
        if (sk->sk_route_caps & NETIF_F_GSO)
-               sk->sk_route_caps |= NETIF_F_GSO_MASK;
+               sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
        if (sk_can_gso(sk)) {
                if (dst->header_len)
                        sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
index b29712033dd4a2ba246d8b9ccb3c1dface442459..6d5ea97620408a41e4b05a71d4e6b159c2228354 100644 (file)
@@ -24,6 +24,8 @@ extern int sysctl_core_destroy_delay;
 #ifdef CONFIG_XFRM
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
+extern int sysctl_xfrm_larval_drop;
+extern u32 sysctl_xfrm_acq_expires;
 #endif
 
 ctl_table core_table[] = {
@@ -118,6 +120,22 @@ ctl_table core_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "xfrm_larval_drop",
+               .data           = &sysctl_xfrm_larval_drop,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "xfrm_acq_expires",
+               .data           = &sysctl_xfrm_acq_expires,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
 #endif /* CONFIG_XFRM */
 #endif /* CONFIG_NET */
        {
index adecfd281ae98d6b8239eada1b26de0dbe459890..2030bb8c2d30c4c27fccf960f87acd51fc5fac54 100644 (file)
@@ -139,16 +139,16 @@ int in4_pton(const char *src, int srclen,
        while(1) {
                int c;
                c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
-               if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
+               if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) {
                        goto out;
                }
-               if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
+               if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
                        if (w == 0)
                                goto out;
                        *d++ = w & 0xff;
                        w = 0;
                        i++;
-                       if (c & IN6PTON_DELIM) {
+                       if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
                                if (i != 4)
                                        goto out;
                                break;
index b8a68dd41000348f58ec5215c35761098a1bb68c..0549e4719b1349e4eb1f4506e3dd42035c7464ae 100644 (file)
@@ -1,8 +1,6 @@
-menu "DCCP Configuration (EXPERIMENTAL)"
-       depends on INET && EXPERIMENTAL
-
-config IP_DCCP
+menuconfig IP_DCCP
        tristate "The DCCP Protocol (EXPERIMENTAL)"
+       depends on INET && EXPERIMENTAL
        ---help---
          Datagram Congestion Control Protocol (RFC 4340)
 
@@ -19,19 +17,20 @@ config IP_DCCP
 
          If in doubt, say N.
 
+if IP_DCCP
+
 config INET_DCCP_DIAG
-       depends on IP_DCCP && INET_DIAG
+       depends on INET_DIAG
        def_tristate y if (IP_DCCP = y && INET_DIAG = y)
        def_tristate m
 
 config IP_DCCP_ACKVEC
-       depends on IP_DCCP
        bool
 
 source "net/dccp/ccids/Kconfig"
 
 menu "DCCP Kernel Hacking"
-       depends on IP_DCCP && DEBUG_KERNEL=y
+       depends on DEBUG_KERNEL=y
 
 config IP_DCCP_DEBUG
        bool "DCCP debug messages"
@@ -61,4 +60,4 @@ config NET_DCCPPROBE
 
 endmenu
 
-endmenu
+endif # IP_DDCP
index d7d9ce7372441a0ac913abd81d24795a15a04b12..ec7fa4d67f080c344ba38c8915b004c1a8e3b9cb 100644 (file)
@@ -419,7 +419,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
 
 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
-       const struct dccp_sock *dp = dccp_sk(sk);
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
        struct ccid3_options_received *opt_recv;
        struct dccp_tx_hist_entry *packet;
@@ -491,7 +490,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                        ccid3_pr_debug("%s(%p), s=%u, MSS=%u, "
                                       "R_sample=%uus, X=%u\n", dccp_role(sk),
                                       sk, hctx->ccid3hctx_s,
-                                      dp->dccps_mss_cache, r_sample,
+                                      dccp_sk(sk)->dccps_mss_cache, r_sample,
                                       (unsigned)(hctx->ccid3hctx_x >> 6));
 
                        ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
index 64eac2515aa2554205534426b5f1cfcf7626931e..31737cdf156a5e657760278c557cbb861d2961f7 100644 (file)
@@ -1043,9 +1043,13 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       err = xfrm_lookup(&dst, &fl, sk, 1);
-       if (err < 0)
-               goto failure;
+       err = __xfrm_lookup(&dst, &fl, sk, 1);
+       if (err < 0) {
+               if (err == -EREMOTE)
+                       err = ip6_dst_blackhole(sk, &dst, &fl);
+               if (err < 0)
+                       goto failure;
+       }
 
        if (saddr == NULL) {
                saddr = &fl.fl6_src;
index 1f5e3ba62065e76bf8c48b39b7a7a6a174800919..43a3adb027e7593ba9b15b366f3ae7d1b7843325 100644 (file)
@@ -128,7 +128,7 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf,
        int error = 0, cnt = 0;
        unsigned char *tbuf;
 
-       if (!buf || len < 0)
+       if (!buf)
                return -EINVAL;
 
        if (len == 0)
index 764a56a13e3831f8a93d7908164c57476d25e874..ab41c1879fd498612f15e5356ab6a06a063d4050 100644 (file)
@@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
        return dn_dev;
 }
 
-static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = {
+static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
        [IFA_ADDRESS]           = { .type = NLA_U16 },
        [IFA_LOCAL]             = { .type = NLA_U16 },
        [IFA_LABEL]             = { .type = NLA_STRING,
index 17a1932216d63f01d8b3d4ff6e802d825eecc008..84ff3dd370709fc8c8c7f2927d1e6f9861019ea5 100644 (file)
@@ -108,7 +108,7 @@ errout:
        return err;
 }
 
-static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
+static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
        FRA_GENERIC_POLICY,
 };
 
index 7ec6610841bab68435cdba151ab2102ef15e1c53..17ad278696edfada4765d6ae540903c1ef2a565a 100644 (file)
@@ -140,7 +140,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
        dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
        if (!dev) {
-               IEEE80211_ERROR("Unable to network device.\n");
+               IEEE80211_ERROR("Unable to allocate network device.\n");
                goto failed;
        }
        ieee = netdev_priv(dev);
index e9cdc6615ddc7483447d34907205c907a39782a0..c308756c2f9dae7edb6f65d90e98dfbe41fded7a 100644 (file)
@@ -33,7 +33,10 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
        struct ieee80211softmac_device *softmac;
        struct net_device *dev;
 
-       dev = alloc_ieee80211(sizeof(struct ieee80211softmac_device) + sizeof_priv);
+       dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
+       if (!dev)
+               return NULL;
+
        softmac = ieee80211_priv(dev);
        softmac->dev = dev;
        softmac->ieee = netdev_priv(dev);
index 7110779a0244598b17518c46cc4784370198f3d0..e00767e8ebd94ed4facfc11b3a3b746e84a50345 100644 (file)
@@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb)
 
        n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
 
-       if (ipv4_devconf.arp_accept) {
+       if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
                /* Unsolicited ARP is not accepted by default.
                   It is possible, that this option should be enabled for some
                   devices (strip is candidate)
@@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev)
                        return 0;
                }
                if (dev == NULL) {
-                       ipv4_devconf.proxy_arp = 1;
+                       IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
                        return 0;
                }
                if (__in_dev_get_rtnl(dev)) {
-                       __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1;
+                       IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
                        return 0;
                }
                return -ENXIO;
@@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
                        return pneigh_delete(&arp_tbl, &ip, dev);
                if (mask == 0) {
                        if (dev == NULL) {
-                               ipv4_devconf.proxy_arp = 0;
+                               IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
                                return 0;
                        }
                        if (__in_dev_get_rtnl(dev)) {
-                               __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0;
+                               IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
+                                               PROXY_ARP, 0);
                                return 0;
                        }
                        return -ENXIO;
index 86a2b52aad3836c6aef2edf83413c3bda42a1319..ab56a052ce31cb53e873df670a4afdc8dc68972a 100644 (file)
@@ -45,6 +45,7 @@
 #include <net/cipso_ipv4.h>
 #include <asm/atomic.h>
 #include <asm/bug.h>
+#include <asm/unaligned.h>
 
 struct cipso_v4_domhsh_entry {
        char *domain;
@@ -1000,7 +1001,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
                return -EFAULT;
 
        for (iter = 0; iter < enumcat_len; iter += 2) {
-               cat = ntohs(*((__be16 *)&enumcat[iter]));
+               cat = ntohs(get_unaligned((__be16 *)&enumcat[iter]));
                if (cat <= cat_prev)
                        return -EFAULT;
                cat_prev = cat;
@@ -1068,8 +1069,8 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
 
        for (iter = 0; iter < net_cat_len; iter += 2) {
                ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
-                                           ntohs(*((__be16 *)&net_cat[iter])),
-                                           GFP_ATOMIC);
+                               ntohs(get_unaligned((__be16 *)&net_cat[iter])),
+                               GFP_ATOMIC);
                if (ret_val != 0)
                        return ret_val;
        }
@@ -1102,9 +1103,10 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
                return -EFAULT;
 
        for (iter = 0; iter < rngcat_len; iter += 4) {
-               cat_high = ntohs(*((__be16 *)&rngcat[iter]));
+               cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter]));
                if ((iter + 4) <= rngcat_len)
-                       cat_low = ntohs(*((__be16 *)&rngcat[iter + 2]));
+                       cat_low = ntohs(
+                               get_unaligned((__be16 *)&rngcat[iter + 2]));
                else
                        cat_low = 0;
 
@@ -1201,9 +1203,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
        u16 cat_high;
 
        for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
-               cat_high = ntohs(*((__be16 *)&net_cat[net_iter]));
+               cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter]));
                if ((net_iter + 4) <= net_cat_len)
-                       cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2]));
+                       cat_low = ntohs(
+                             get_unaligned((__be16 *)&net_cat[net_iter + 2]));
                else
                        cat_low = 0;
 
@@ -1565,7 +1568,7 @@ int cipso_v4_validate(unsigned char **option)
        }
 
        rcu_read_lock();
-       doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2])));
+       doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2])));
        if (doi_def == NULL) {
                err_offset = 2;
                goto validate_return_locked;
@@ -1709,22 +1712,22 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
 }
 
 /**
- * cipso_v4_socket_setattr - Add a CIPSO option to a socket
- * @sock: the socket
+ * cipso_v4_sock_setattr - Add a CIPSO option to a socket
+ * @sk: the socket
  * @doi_def: the CIPSO DOI to use
  * @secattr: the specific security attributes of the socket
  *
  * Description:
  * Set the CIPSO option on the given socket using the DOI definition and
  * security attributes passed to the function.  This function requires
- * exclusive access to @sock->sk, which means it either needs to be in the
- * process of being created or locked via lock_sock(sock->sk).  Returns zero on
- * success and negative values on failure.
+ * exclusive access to @sk, which means it either needs to be in the
+ * process of being created or locked.  Returns zero on success and negative
+ * values on failure.
  *
  */
-int cipso_v4_socket_setattr(const struct socket *sock,
-                           const struct cipso_v4_doi *doi_def,
-                           const struct netlbl_lsm_secattr *secattr)
+int cipso_v4_sock_setattr(struct sock *sk,
+                         const struct cipso_v4_doi *doi_def,
+                         const struct netlbl_lsm_secattr *secattr)
 {
        int ret_val = -EPERM;
        u32 iter;
@@ -1732,7 +1735,6 @@ int cipso_v4_socket_setattr(const struct socket *sock,
        u32 buf_len = 0;
        u32 opt_len;
        struct ip_options *opt = NULL;
-       struct sock *sk;
        struct inet_sock *sk_inet;
        struct inet_connection_sock *sk_conn;
 
@@ -1740,7 +1742,6 @@ int cipso_v4_socket_setattr(const struct socket *sock,
         * defined yet but it is not a problem as the only users of these
         * "lite" PF_INET sockets are functions which do an accept() call
         * afterwards so we will label the socket as part of the accept(). */
-       sk = sock->sk;
        if (sk == NULL)
                return 0;
 
@@ -1858,7 +1859,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
        if (ret_val == 0)
                return ret_val;
 
-       doi = ntohl(*(__be32 *)&cipso_ptr[2]);
+       doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
        rcu_read_lock();
        doi_def = cipso_v4_doi_search(doi);
        if (doi_def == NULL) {
@@ -1891,29 +1892,6 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
        return ret_val;
 }
 
-/**
- * cipso_v4_socket_getattr - Get the security attributes from a socket
- * @sock: the socket
- * @secattr: the security attributes
- *
- * Description:
- * Query @sock to see if there is a CIPSO option attached to the socket and if
- * there is return the CIPSO security attributes in @secattr.  Returns zero on
- * success and negative values on failure.
- *
- */
-int cipso_v4_socket_getattr(const struct socket *sock,
-                           struct netlbl_lsm_secattr *secattr)
-{
-       int ret_val;
-
-       lock_sock(sock->sk);
-       ret_val = cipso_v4_sock_getattr(sock->sk, secattr);
-       release_sock(sock->sk);
-
-       return ret_val;
-}
-
 /**
  * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
  * @skb: the packet
@@ -1936,7 +1914,7 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
        if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
                return 0;
 
-       doi = ntohl(*(__be32 *)&cipso_ptr[2]);
+       doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2]));
        rcu_read_lock();
        doi_def = cipso_v4_doi_search(doi);
        if (doi_def == NULL)
index dd02a45d0f675945c8c85799ac99b4fbea4c9c04..0301dd468cf47638fdd7d434c35ac44a7b96cae6 100644 (file)
@@ -50,8 +50,12 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                               RT_CONN_FLAGS(sk), oif,
                               sk->sk_protocol,
                               inet->sport, usin->sin_port, sk, 1);
-       if (err)
+       if (err) {
+               if (err == -ENETUNREACH)
+                       IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return err;
+       }
+
        if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {
                ip_rt_put(rt);
                return -EACCES;
index 7f95e6e9beebd55ff6ade8adfcfcbacf9488f89f..abf6352f990f33ff380a27f364325b4f57153b56 100644 (file)
 #include <net/rtnetlink.h>
 
 struct ipv4_devconf ipv4_devconf = {
-       .accept_redirects = 1,
-       .send_redirects =  1,
-       .secure_redirects = 1,
-       .shared_media =   1,
+       .data = {
+               [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
+       },
 };
 
 static struct ipv4_devconf ipv4_devconf_dflt = {
-       .accept_redirects =  1,
-       .send_redirects =    1,
-       .secure_redirects =  1,
-       .shared_media =      1,
-       .accept_source_route = 1,
+       .data = {
+               [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
+               [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
+               [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
+       },
 };
 
-static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = {
+#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
+
+static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
        [IFA_LOCAL]             = { .type = NLA_U32 },
        [IFA_ADDRESS]           = { .type = NLA_U32 },
        [IFA_BROADCAST]         = { .type = NLA_U32 },
@@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
        }
 }
 
-struct in_device *inetdev_init(struct net_device *dev)
+static struct in_device *inetdev_init(struct net_device *dev)
 {
        struct in_device *in_dev;
 
@@ -321,12 +327,8 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                }
 
        }
-       if (destroy) {
+       if (destroy)
                inet_free_ifa(ifa1);
-
-               if (!in_dev->ifa_list)
-                       inetdev_destroy(in_dev);
-       }
 }
 
 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
@@ -399,12 +401,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
        ASSERT_RTNL();
 
        if (!in_dev) {
-               in_dev = inetdev_init(dev);
-               if (!in_dev) {
-                       inet_free_ifa(ifa);
-                       return -ENOBUFS;
-               }
+               inet_free_ifa(ifa);
+               return -ENOBUFS;
        }
+       ipv4_devconf_setall(in_dev);
        if (ifa->ifa_dev != in_dev) {
                BUG_TRAP(!ifa->ifa_dev);
                in_dev_hold(in_dev);
@@ -514,13 +514,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
 
        in_dev = __in_dev_get_rtnl(dev);
        if (in_dev == NULL) {
-               in_dev = inetdev_init(dev);
-               if (in_dev == NULL) {
-                       err = -ENOBUFS;
-                       goto errout;
-               }
+               err = -ENOBUFS;
+               goto errout;
        }
 
+       ipv4_devconf_setall(in_dev);
+
        ifa = inet_alloc_ifa();
        if (ifa == NULL) {
                /*
@@ -1057,11 +1056,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
        if (!in_dev) {
                if (event == NETDEV_REGISTER) {
                        in_dev = inetdev_init(dev);
-                       if (!in_dev)
-                               panic("devinet: Failed to create loopback\n");
                        if (dev == &loopback_dev) {
-                               in_dev->cnf.no_xfrm = 1;
-                               in_dev->cnf.no_policy = 1;
+                               if (!in_dev)
+                                       panic("devinet: "
+                                             "Failed to create loopback\n");
+                               IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
+                               IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
                        }
                }
                goto out;
@@ -1237,13 +1237,98 @@ errout:
 
 #ifdef CONFIG_SYSCTL
 
+static void devinet_copy_dflt_conf(int i)
+{
+       struct net_device *dev;
+
+       read_lock(&dev_base_lock);
+       for_each_netdev(dev) {
+               struct in_device *in_dev;
+               rcu_read_lock();
+               in_dev = __in_dev_get_rcu(dev);
+               if (in_dev && !test_bit(i, in_dev->cnf.state))
+                       in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
+               rcu_read_unlock();
+       }
+       read_unlock(&dev_base_lock);
+}
+
+static int devinet_conf_proc(ctl_table *ctl, int write,
+                            struct file* filp, void __user *buffer,
+                            size_t *lenp, loff_t *ppos)
+{
+       int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+
+       if (write) {
+               struct ipv4_devconf *cnf = ctl->extra1;
+               int i = (int *)ctl->data - cnf->data;
+
+               set_bit(i, cnf->state);
+
+               if (cnf == &ipv4_devconf_dflt)
+                       devinet_copy_dflt_conf(i);
+       }
+
+       return ret;
+}
+
+static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
+                              void __user *oldval, size_t __user *oldlenp,
+                              void __user *newval, size_t newlen)
+{
+       struct ipv4_devconf *cnf;
+       int *valp = table->data;
+       int new;
+       int i;
+
+       if (!newval || !newlen)
+               return 0;
+
+       if (newlen != sizeof(int))
+               return -EINVAL;
+
+       if (get_user(new, (int __user *)newval))
+               return -EFAULT;
+
+       if (new == *valp)
+               return 0;
+
+       if (oldval && oldlenp) {
+               size_t len;
+
+               if (get_user(len, oldlenp))
+                       return -EFAULT;
+
+               if (len) {
+                       if (len > table->maxlen)
+                               len = table->maxlen;
+                       if (copy_to_user(oldval, valp, len))
+                               return -EFAULT;
+                       if (put_user(len, oldlenp))
+                               return -EFAULT;
+               }
+       }
+
+       *valp = new;
+
+       cnf = table->extra1;
+       i = (int *)table->data - cnf->data;
+
+       set_bit(i, cnf->state);
+
+       if (cnf == &ipv4_devconf_dflt)
+               devinet_copy_dflt_conf(i);
+
+       return 1;
+}
+
 void inet_forward_change(void)
 {
        struct net_device *dev;
-       int on = ipv4_devconf.forwarding;
+       int on = IPV4_DEVCONF_ALL(FORWARDING);
 
-       ipv4_devconf.accept_redirects = !on;
-       ipv4_devconf_dflt.forwarding = on;
+       IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
+       IPV4_DEVCONF_DFLT(FORWARDING) = on;
 
        read_lock(&dev_base_lock);
        for_each_netdev(dev) {
@@ -1251,7 +1336,7 @@ void inet_forward_change(void)
                rcu_read_lock();
                in_dev = __in_dev_get_rcu(dev);
                if (in_dev)
-                       in_dev->cnf.forwarding = on;
+                       IN_DEV_CONF_SET(in_dev, FORWARDING, on);
                rcu_read_unlock();
        }
        read_unlock(&dev_base_lock);
@@ -1268,9 +1353,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
        int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
        if (write && *valp != val) {
-               if (valp == &ipv4_devconf.forwarding)
+               if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
                        inet_forward_change();
-               else if (valp != &ipv4_devconf_dflt.forwarding)
+               else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
                        rt_cache_flush(0);
        }
 
@@ -1295,42 +1380,43 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
                                  void __user *oldval, size_t __user *oldlenp,
                                  void __user *newval, size_t newlen)
 {
-       int *valp = table->data;
-       int new;
+       int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
+                                     newval, newlen);
 
-       if (!newval || !newlen)
-               return 0;
+       if (ret == 1)
+               rt_cache_flush(0);
 
-       if (newlen != sizeof(int))
-               return -EINVAL;
+       return ret;
+}
 
-       if (get_user(new, (int __user *)newval))
-               return -EFAULT;
 
-       if (new == *valp)
-               return 0;
+#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
+       { \
+               .ctl_name       = NET_IPV4_CONF_ ## attr, \
+               .procname       = name, \
+               .data           = ipv4_devconf.data + \
+                                 NET_IPV4_CONF_ ## attr - 1, \
+               .maxlen         = sizeof(int), \
+               .mode           = mval, \
+               .proc_handler   = proc, \
+               .strategy       = sysctl, \
+               .extra1         = &ipv4_devconf, \
+       }
 
-       if (oldval && oldlenp) {
-               size_t len;
+#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
+       DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \
+                            devinet_conf_sysctl)
 
-               if (get_user(len, oldlenp))
-                       return -EFAULT;
+#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
+       DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \
+                            devinet_conf_sysctl)
 
-               if (len) {
-                       if (len > table->maxlen)
-                               len = table->maxlen;
-                       if (copy_to_user(oldval, valp, len))
-                               return -EFAULT;
-                       if (put_user(len, oldlenp))
-                               return -EFAULT;
-               }
-       }
-
-       *valp = new;
-       rt_cache_flush(0);
-       return 1;
-}
+#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \
+       DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl)
 
+#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
+       DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \
+                                    ipv4_doint_and_flush_strategy)
 
 static struct devinet_sysctl_table {
        struct ctl_table_header *sysctl_header;
@@ -1341,178 +1427,34 @@ static struct devinet_sysctl_table {
        ctl_table               devinet_root_dir[2];
 } devinet_sysctl = {
        .devinet_vars = {
-               {
-                       .ctl_name       = NET_IPV4_CONF_FORWARDING,
-                       .procname       = "forwarding",
-                       .data           = &ipv4_devconf.forwarding,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &devinet_sysctl_forward,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_MC_FORWARDING,
-                       .procname       = "mc_forwarding",
-                       .data           = &ipv4_devconf.mc_forwarding,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0444,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ACCEPT_REDIRECTS,
-                       .procname       = "accept_redirects",
-                       .data           = &ipv4_devconf.accept_redirects,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_SECURE_REDIRECTS,
-                       .procname       = "secure_redirects",
-                       .data           = &ipv4_devconf.secure_redirects,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_SHARED_MEDIA,
-                       .procname       = "shared_media",
-                       .data           = &ipv4_devconf.shared_media,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_RP_FILTER,
-                       .procname       = "rp_filter",
-                       .data           = &ipv4_devconf.rp_filter,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_SEND_REDIRECTS,
-                       .procname       = "send_redirects",
-                       .data           = &ipv4_devconf.send_redirects,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
-                       .procname       = "accept_source_route",
-                       .data           = &ipv4_devconf.accept_source_route,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_PROXY_ARP,
-                       .procname       = "proxy_arp",
-                       .data           = &ipv4_devconf.proxy_arp,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_MEDIUM_ID,
-                       .procname       = "medium_id",
-                       .data           = &ipv4_devconf.medium_id,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_BOOTP_RELAY,
-                       .procname       = "bootp_relay",
-                       .data           = &ipv4_devconf.bootp_relay,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_LOG_MARTIANS,
-                       .procname       = "log_martians",
-                       .data           = &ipv4_devconf.log_martians,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_TAG,
-                       .procname       = "tag",
-                       .data           = &ipv4_devconf.tag,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ARPFILTER,
-                       .procname       = "arp_filter",
-                       .data           = &ipv4_devconf.arp_filter,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ARP_ANNOUNCE,
-                       .procname       = "arp_announce",
-                       .data           = &ipv4_devconf.arp_announce,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ARP_IGNORE,
-                       .procname       = "arp_ignore",
-                       .data           = &ipv4_devconf.arp_ignore,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ARP_ACCEPT,
-                       .procname       = "arp_accept",
-                       .data           = &ipv4_devconf.arp_accept,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_NOXFRM,
-                       .procname       = "disable_xfrm",
-                       .data           = &ipv4_devconf.no_xfrm,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &ipv4_doint_and_flush,
-                       .strategy       = &ipv4_doint_and_flush_strategy,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_NOPOLICY,
-                       .procname       = "disable_policy",
-                       .data           = &ipv4_devconf.no_policy,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &ipv4_doint_and_flush,
-                       .strategy       = &ipv4_doint_and_flush_strategy,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_FORCE_IGMP_VERSION,
-                       .procname       = "force_igmp_version",
-                       .data           = &ipv4_devconf.force_igmp_version,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &ipv4_doint_and_flush,
-                       .strategy       = &ipv4_doint_and_flush_strategy,
-               },
-               {
-                       .ctl_name       = NET_IPV4_CONF_PROMOTE_SECONDARIES,
-                       .procname       = "promote_secondaries",
-                       .data           = &ipv4_devconf.promote_secondaries,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &ipv4_doint_and_flush,
-                       .strategy       = &ipv4_doint_and_flush_strategy,
-               },
+               DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
+                                            devinet_sysctl_forward,
+                                            devinet_conf_sysctl),
+               DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
+
+               DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
+               DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
+               DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
+               DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
+               DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
+               DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
+                                       "accept_source_route"),
+               DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
+               DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
+               DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
+               DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
+               DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
+               DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
+               DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
+               DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
+               DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
+
+               DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
+               DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
+               DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
+                                             "force_igmp_version"),
+               DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
+                                             "promote_secondaries"),
        },
        .devinet_dev = {
                {
@@ -1561,6 +1503,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
                return;
        for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
                t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
+               t->devinet_vars[i].extra1 = p;
        }
 
        if (dev) {
index 837f2957fa83d702a948dafb24b5cac1661a80ec..311d633f7f397b545b6a0839319c1d446c18eb27 100644 (file)
@@ -250,8 +250,6 @@ e_inval:
        return -EINVAL;
 }
 
-#ifndef CONFIG_IP_NOSIOCRT
-
 static inline __be32 sk_extract_addr(struct sockaddr *addr)
 {
        return ((struct sockaddr_in *) addr)->sin_addr.s_addr;
@@ -443,16 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
        return -EINVAL;
 }
 
-#else
-
-int ip_rt_ioctl(unsigned int cmd, void *arg)
-{
-       return -EINVAL;
-}
-
-#endif
-
-struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = {
+const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
        [RTA_DST]               = { .type = NLA_U32 },
        [RTA_SRC]               = { .type = NLA_U32 },
        [RTA_IIF]               = { .type = NLA_U32 },
index 9cfecf1215c94b6b00d6177edf9a4d7f8e6b2ab3..07e843a47dde6bf6c774a4080ac2ea16a688e311 100644 (file)
@@ -456,6 +456,8 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                        fib_release_info(fi_drop);
                        if (state & FA_S_ACCESSED)
                                rt_cache_flush(-1);
+                       rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id,
+                                 &cfg->fc_nlinfo, NLM_F_REPLACE);
                        return 0;
                }
 
@@ -523,7 +525,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
        rt_cache_flush(-1);
 
        rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id,
-                 &cfg->fc_nlinfo);
+                 &cfg->fc_nlinfo, 0);
        return 0;
 
 out_free_new_fa:
@@ -589,7 +591,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
 
                fa = fa_to_delete;
                rtmsg_fib(RTM_DELROUTE, key, fa, cfg->fc_dst_len,
-                         tb->tb_id, &cfg->fc_nlinfo);
+                         tb->tb_id, &cfg->fc_nlinfo, 0);
 
                kill_fn = 0;
                write_lock_bh(&fib_hash_lock);
index 0e8b70bad4e194b6f4a3968acb127b2387b6c2fe..eef9eec17e0c584a383df0a8064117b3feb238f8 100644 (file)
@@ -30,7 +30,8 @@ extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                         int dst_len, u8 tos, struct fib_info *fi,
                         unsigned int);
 extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
-                     int dst_len, u32 tb_id, struct nl_info *info);
+                     int dst_len, u32 tb_id, struct nl_info *info,
+                     unsigned int nlm_flags);
 extern struct fib_alias *fib_find_alias(struct list_head *fah,
                                        u8 tos, u32 prio);
 extern int fib_detect_death(struct fib_info *fi, int order,
index 33083ad52e9ff2d0678f9a2914c230a98b1a40d5..2a947840210ece1a1e218972725e5bda5b21ea6f 100644 (file)
@@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void)
        return NULL;
 }
 
-static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
+static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
        FRA_GENERIC_POLICY,
        [FRA_FLOW]      = { .type = NLA_U32 },
 };
index 406ea7050aede7c0dd6926fe20d0349b2109eee2..bb94550d95c3e8a2c80b1fc74bed9b9eb1b52a5a 100644 (file)
@@ -301,7 +301,8 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
 }
 
 void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
-              int dst_len, u32 tb_id, struct nl_info *info)
+              int dst_len, u32 tb_id, struct nl_info *info,
+              unsigned int nlm_flags)
 {
        struct sk_buff *skb;
        u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
@@ -313,7 +314,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
 
        err = fib_dump_info(skb, info->pid, seq, event, tb_id,
                            fa->fa_type, fa->fa_scope, key, dst_len,
-                           fa->fa_tos, fa->fa_info, 0);
+                           fa->fa_tos, fa->fa_info, nlm_flags);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
index 9be7da7c3a8fa8ed474031e2375aa53586d81f12..30e332ade61bbb442a9660ec68e11c0871714ee5 100644 (file)
@@ -1226,6 +1226,8 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
                        fib_release_info(fi_drop);
                        if (state & FA_S_ACCESSED)
                                rt_cache_flush(-1);
+                       rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
+                               tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
 
                        goto succeeded;
                }
@@ -1278,7 +1280,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
 
        rt_cache_flush(-1);
        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
-                 &cfg->fc_nlinfo);
+                 &cfg->fc_nlinfo, 0);
 succeeded:
        return 0;
 
@@ -1624,7 +1626,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
 
        fa = fa_to_delete;
        rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
-                 &cfg->fc_nlinfo);
+                 &cfg->fc_nlinfo, 0);
 
        l = fib_find_node(t, key);
        li = find_leaf_info(l, plen);
index e238b17f554cc150e36e1430f238af194f9e9b55..02a899bec1969fcb6511722d41fe20009b6f2dbc 100644 (file)
@@ -514,12 +514,15 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 
        saddr = iph->daddr;
        if (!(rt->rt_flags & RTCF_LOCAL)) {
-               /* This is broken, skb_in->dev points to the outgoing device
-                * after the packet passes through ip_output().
-                */
-               if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr)
-                       saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
-               else
+               struct net_device *dev = NULL;
+
+               if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
+                       dev = dev_get_by_index(rt->fl.iif);
+
+               if (dev) {
+                       saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
+                       dev_put(dev);
+               } else
                        saddr = 0;
        }
 
index f4dd47453108e5041dd4394308d64567522ec1ac..a646409c2d068040ac0054b9f2cf3a29472a495d 100644 (file)
  * contradict to specs provided this delay is small enough.
  */
 
-#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \
-               (in_dev)->cnf.force_igmp_version == 1 || \
-               ((in_dev)->mr_v1_seen && \
-               time_before(jiffies, (in_dev)->mr_v1_seen)))
-#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \
-               (in_dev)->cnf.force_igmp_version == 2 || \
-               ((in_dev)->mr_v2_seen && \
-               time_before(jiffies, (in_dev)->mr_v2_seen)))
+#define IGMP_V1_SEEN(in_dev) \
+       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
+        IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
+        ((in_dev)->mr_v1_seen && \
+         time_before(jiffies, (in_dev)->mr_v1_seen)))
+#define IGMP_V2_SEEN(in_dev) \
+       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
+        IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
+        ((in_dev)->mr_v2_seen && \
+         time_before(jiffies, (in_dev)->mr_v2_seen)))
 
 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
 static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
index 43fb1600f1f03904846bc3d53a98c73e0f729a61..fbe7714f21d08593beecb3945f2f85848b506be8 100644 (file)
@@ -31,10 +31,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
 
 /*
  * This array holds the first and last local port number.
- * For high-usage systems, use sysctl to change this to
- * 32768-61000
  */
-int sysctl_local_port_range[2] = { 1024, 4999 };
+int sysctl_local_port_range[2] = { 32768, 61000 };
 
 int inet_csk_bind_conflict(const struct sock *sk,
                           const struct inet_bind_bucket *tb)
index d6427d9185125c34140f5306b98a692b255a6619..34ea4547ebbea10cda26bca8a6f05307218b9518 100644 (file)
@@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
        }
 
        {
-               struct flowi fl = { .nl_u = { .ip4_u =
+               struct flowi fl = { .oif = arg->bound_dev_if,
+                                   .nl_u = { .ip4_u =
                                              { .daddr = daddr,
                                                .saddr = rt->rt_spec_dst,
                                                .tos = RT_TOS(ip_hdr(skb)->tos) } },
@@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
        inet->tos = ip_hdr(skb)->tos;
        sk->sk_priority = skb->priority;
        sk->sk_protocol = ip_hdr(skb)->protocol;
+       sk->sk_bound_dev_if = arg->bound_dev_if;
        ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
                       &ipc, rt, MSG_DONTWAIT);
        if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
index 0ebae413ae873c733d21880c8ceadf5ebbde18b1..d96582acdf69a7b4110cc4dfafc2d2c290d7a379 100644 (file)
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
                        dev->flags |= IFF_MULTICAST;
 
                        in_dev = __in_dev_get_rtnl(dev);
-                       if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL)
+                       if (in_dev == NULL)
                                goto failure;
-                       in_dev->cnf.rp_filter = 0;
+
+                       ipv4_devconf_setall(in_dev);
+                       IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
 
                        if (dev_open(dev))
                                goto failure;
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
        }
        dev->iflink = 0;
 
-       if ((in_dev = inetdev_init(dev)) == NULL)
+       rcu_read_lock();
+       if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
+               rcu_read_unlock();
                goto failure;
+       }
 
-       in_dev->cnf.rp_filter = 0;
+       ipv4_devconf_setall(in_dev);
+       IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
+       rcu_read_unlock();
 
        if (dev_open(dev))
                goto failure;
@@ -281,7 +288,7 @@ static int vif_delete(int vifi)
        dev_set_allmulti(dev, -1);
 
        if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
-               in_dev->cnf.mc_forwarding--;
+               IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
                ip_rt_multicast_event(in_dev);
        }
 
@@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
 
        if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
                return -EADDRNOTAVAIL;
-       in_dev->cnf.mc_forwarding++;
+       IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
        dev_set_allmulti(dev, +1);
        ip_rt_multicast_event(in_dev);
 
@@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk)
 {
        rtnl_lock();
        if (sk == mroute_socket) {
-               ipv4_devconf.mc_forwarding--;
+               IPV4_DEVCONF_ALL(MC_FORWARDING)--;
 
                write_lock_bh(&mrt_lock);
                mroute_socket=NULL;
@@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                        mroute_socket=sk;
                        write_unlock_bh(&mrt_lock);
 
-                       ipv4_devconf.mc_forwarding++;
+                       IPV4_DEVCONF_ALL(MC_FORWARDING)++;
                }
                rtnl_unlock();
                return ret;
index 891b9355cf9666c3c41f9fb9e83bd2e03351b193..09d0c3f3566978a42f0f7790e0e1875d93e145b3 100644 (file)
@@ -1,10 +1,7 @@
 #
 # IP Virtual Server configuration
 #
-menu   "IP: Virtual Server Configuration"
-       depends on NETFILTER
-
-config IP_VS
+menuconfig IP_VS
        tristate "IP virtual server support (EXPERIMENTAL)"
        depends on NETFILTER
        ---help---
@@ -25,9 +22,10 @@ config       IP_VS
          If you want to compile it in kernel, say Y. To compile it as a
          module, choose M here. If unsure, say N.
 
+if IP_VS
+
 config IP_VS_DEBUG
        bool "IP virtual server debugging"
-       depends on IP_VS
        ---help---
          Say Y here if you want to get additional messages useful in
          debugging the IP virtual server code. You can change the debug
@@ -35,7 +33,6 @@ config        IP_VS_DEBUG
 
 config IP_VS_TAB_BITS
        int "IPVS connection table size (the Nth power of 2)"
-       depends on IP_VS 
        default "12" 
        ---help---
          The IPVS connection hash table uses the chaining scheme to handle
@@ -61,42 +58,35 @@ config      IP_VS_TAB_BITS
          needed for your box.
 
 comment "IPVS transport protocol load balancing support"
-        depends on IP_VS
 
 config IP_VS_PROTO_TCP
        bool "TCP load balancing support"
-       depends on IP_VS
        ---help---
          This option enables support for load balancing TCP transport
          protocol. Say Y if unsure.
 
 config IP_VS_PROTO_UDP
        bool "UDP load balancing support"
-       depends on IP_VS
        ---help---
          This option enables support for load balancing UDP transport
          protocol. Say Y if unsure.
 
 config IP_VS_PROTO_ESP
        bool "ESP load balancing support"
-       depends on IP_VS
        ---help---
          This option enables support for load balancing ESP (Encapsulation
          Security Payload) transport protocol. Say Y if unsure.
 
 config IP_VS_PROTO_AH
        bool "AH load balancing support"
-       depends on IP_VS
        ---help---
          This option enables support for load balancing AH (Authentication
          Header) transport protocol. Say Y if unsure.
 
 comment "IPVS scheduler"
-        depends on IP_VS
 
 config IP_VS_RR
        tristate "round-robin scheduling"
-       depends on IP_VS
        ---help---
          The robin-robin scheduling algorithm simply directs network
          connections to different real servers in a round-robin manner.
@@ -106,7 +96,6 @@ config       IP_VS_RR
  
 config IP_VS_WRR
         tristate "weighted round-robin scheduling" 
-       depends on IP_VS
        ---help---
          The weighted robin-robin scheduling algorithm directs network
          connections to different real servers based on server weights
@@ -120,7 +109,6 @@ config      IP_VS_WRR
 
 config IP_VS_LC
         tristate "least-connection scheduling"
-        depends on IP_VS
        ---help---
          The least-connection scheduling algorithm directs network
          connections to the server with the least number of active 
@@ -131,7 +119,6 @@ config      IP_VS_LC
 
 config IP_VS_WLC
         tristate "weighted least-connection scheduling"
-        depends on IP_VS
        ---help---
          The weighted least-connection scheduling algorithm directs network
          connections to the server with the least active connections
@@ -142,7 +129,6 @@ config      IP_VS_WLC
 
 config IP_VS_LBLC
        tristate "locality-based least-connection scheduling"
-        depends on IP_VS
        ---help---
          The locality-based least-connection scheduling algorithm is for
          destination IP load balancing. It is usually used in cache cluster.
@@ -157,7 +143,6 @@ config      IP_VS_LBLC
 
 config  IP_VS_LBLCR
        tristate "locality-based least-connection with replication scheduling"
-        depends on IP_VS
        ---help---
          The locality-based least-connection with replication scheduling
          algorithm is also for destination IP load balancing. It is 
@@ -176,7 +161,6 @@ config  IP_VS_LBLCR
 
 config IP_VS_DH
        tristate "destination hashing scheduling"
-        depends on IP_VS
        ---help---
          The destination hashing scheduling algorithm assigns network
          connections to the servers through looking up a statically assigned
@@ -187,7 +171,6 @@ config      IP_VS_DH
 
 config IP_VS_SH
        tristate "source hashing scheduling"
-        depends on IP_VS
        ---help---
          The source hashing scheduling algorithm assigns network
          connections to the servers through looking up a statically assigned
@@ -198,7 +181,6 @@ config      IP_VS_SH
 
 config IP_VS_SED
        tristate "shortest expected delay scheduling"
-        depends on IP_VS
        ---help---
          The shortest expected delay scheduling algorithm assigns network
          connections to the server with the shortest expected delay. The 
@@ -212,7 +194,6 @@ config      IP_VS_SED
 
 config IP_VS_NQ
        tristate "never queue scheduling"
-        depends on IP_VS
        ---help---
          The never queue scheduling algorithm adopts a two-speed model.
          When there is an idle server available, the job will be sent to
@@ -225,11 +206,10 @@ config    IP_VS_NQ
          module, choose M here. If unsure, say N.
 
 comment 'IPVS application helper'
-       depends on IP_VS
 
 config IP_VS_FTP
        tristate "FTP protocol helper"
-        depends on IP_VS && IP_VS_PROTO_TCP
+        depends on IP_VS_PROTO_TCP
        ---help---
          FTP is a protocol that transfers IP address and/or port number in
          the payload. In the virtual server via Network Address Translation,
@@ -241,4 +221,4 @@ config      IP_VS_FTP
          If you want to compile it in kernel, say Y. To compile it as a
          module, choose M here. If unsure, say N.
 
-endmenu
+endif # IP_VS
index e3f83bf160d9ebf01d518664237c8864bee58a22..9bacf1a0363085793544d85a1658f8ce91f2d8ba 100644 (file)
@@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name)
 }
 
 static inline int check_match(struct ipt_entry_match *m, const char *name,
-                               const struct ipt_ip *ip, unsigned int hookmask)
+                               const struct ipt_ip *ip, unsigned int hookmask,
+                               unsigned int *i)
 {
        struct xt_match *match;
        int ret;
@@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name,
                         m->u.kernel.match->name);
                ret = -EINVAL;
        }
+       if (!ret)
+               (*i)++;
        return ret;
 }
 
@@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m,
        }
        m->u.kernel.match = match;
 
-       ret = check_match(m, name, ip, hookmask);
+       ret = check_match(m, name, ip, hookmask, i);
        if (ret)
                goto err;
 
-       (*i)++;
        return 0;
 err:
        module_put(m->u.kernel.match->me);
@@ -1425,7 +1427,7 @@ out:
 }
 
 static inline int
-compat_check_calc_match(struct ipt_entry_match *m,
+compat_find_calc_match(struct ipt_entry_match *m,
            const char *name,
            const struct ipt_ip *ip,
            unsigned int hookmask,
@@ -1448,6 +1450,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
        return 0;
 }
 
+static inline int
+compat_release_match(struct ipt_entry_match *m, unsigned int *i)
+{
+       if (i && (*i)-- == 0)
+               return 1;
+
+       module_put(m->u.kernel.match->me);
+       return 0;
+}
+
+static inline int
+compat_release_entry(struct ipt_entry *e, unsigned int *i)
+{
+       struct ipt_entry_target *t;
+
+       if (i && (*i)-- == 0)
+               return 1;
+
+       /* Cleanup all matches */
+       IPT_MATCH_ITERATE(e, compat_release_match, NULL);
+       t = ipt_get_target(e);
+       module_put(t->u.kernel.target->me);
+       return 0;
+}
+
 static inline int
 check_compat_entry_size_and_hooks(struct ipt_entry *e,
                           struct xt_table_info *newinfo,
@@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
        off = 0;
        entry_offset = (void *)e - (void *)base;
        j = 0;
-       ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip,
+       ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
                        e->comefrom, &off, &j);
        if (ret != 0)
-               goto cleanup_matches;
+               goto release_matches;
 
        t = ipt_get_target(e);
        target = try_then_request_module(xt_find_target(AF_INET,
@@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
                duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
                                                        t->u.user.name);
                ret = target ? PTR_ERR(target) : -ENOENT;
-               goto cleanup_matches;
+               goto release_matches;
        }
        t->u.kernel.target = target;
 
@@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 
 out:
        module_put(t->u.kernel.target->me);
-cleanup_matches:
-       IPT_MATCH_ITERATE(e, cleanup_match, &j);
+release_matches:
+       IPT_MATCH_ITERATE(e, compat_release_match, &j);
        return ret;
 }
 
@@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
        return ret;
 }
 
-static inline int compat_check_entry(struct ipt_entry *e, const char *name)
+static inline int compat_check_entry(struct ipt_entry *e, const char *name,
+                                               unsigned int *i)
 {
-       int ret;
+       int j, ret;
 
-       ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom);
+       j = 0;
+       ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
        if (ret)
-               return ret;
+               goto cleanup_matches;
+
+       ret = check_target(e, name);
+       if (ret)
+               goto cleanup_matches;
 
-       return check_target(e, name);
+       (*i)++;
+       return 0;
+
+ cleanup_matches:
+       IPT_MATCH_ITERATE(e, cleanup_match, &j);
+       return ret;
 }
 
 static int
@@ -1673,10 +1711,17 @@ translate_compat_table(const char *name,
        if (!mark_source_chains(newinfo, valid_hooks, entry1))
                goto free_newinfo;
 
+       i = 0;
        ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
-                                                                       name);
-       if (ret)
-               goto free_newinfo;
+                                                               name, &i);
+       if (ret) {
+               j -= i;
+               IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
+                                               compat_release_entry, &j);
+               IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
+               xt_free_table_info(newinfo);
+               return ret;
+       }
 
        /* And one copy for every other CPU */
        for_each_possible_cpu(i)
@@ -1691,7 +1736,7 @@ translate_compat_table(const char *name,
 free_newinfo:
        xt_free_table_info(newinfo);
 out:
-       IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
+       IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
        return ret;
 out_unlock:
        compat_flush_offsets();
index fd62a41d69cc82e3cc2da81b088ac36d4316a265..6dc72a815f77623a2973f94a5d3a84eafae1f80f 100644 (file)
@@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
        struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
        struct nf_conn_help *help;
+       struct nf_conntrack_helper *helper;
 
        /* This is where we call the helper: as the packet goes out. */
        ct = nf_ct_get(*pskb, &ctinfo);
@@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
                return NF_ACCEPT;
 
        help = nfct_help(ct);
-       if (!help || !help->helper)
+       if (!help)
                return NF_ACCEPT;
-
-       return help->helper->help(pskb,
-                                 skb_network_offset(*pskb) + ip_hdrlen(*pskb),
-                                 ct, ctinfo);
+       /* rcu_read_lock()ed by nf_hook_slow */
+       helper = rcu_dereference(help->helper);
+       if (!helper)
+               return NF_ACCEPT;
+       return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
+                           ct, ctinfo);
 }
 
 static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
index 751b598017555e9e2a1faefbec43cc67be3fae6f..e6bc8e5a72f13796a36c3fa1af3b5d12619fb1b2 100644 (file)
@@ -40,8 +40,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
                     unsigned int matchoff,
                     unsigned int matchlen,
                     struct nf_conn *ct,
-                    enum ip_conntrack_info ctinfo,
-                    u32 *seq)
+                    enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
 
@@ -50,7 +49,6 @@ mangle_rfc959_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
@@ -63,8 +61,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
                   unsigned int matchoff,
                   unsigned int matchlen,
                   struct nf_conn *ct,
-                  enum ip_conntrack_info ctinfo,
-                  u32 *seq)
+                  enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("|1|255.255.255.255|65535|")];
 
@@ -72,7 +69,6 @@ mangle_eprt_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
@@ -85,8 +81,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
                   unsigned int matchoff,
                   unsigned int matchlen,
                   struct nf_conn *ct,
-                  enum ip_conntrack_info ctinfo,
-                  u32 *seq)
+                  enum ip_conntrack_info ctinfo)
 {
        char buffer[sizeof("|||65535|")];
 
@@ -94,14 +89,13 @@ mangle_epsv_packet(struct sk_buff **pskb,
 
        DEBUGP("calling nf_nat_mangle_tcp_packet\n");
 
-       *seq += strlen(buffer) - matchlen;
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
 }
 
 static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
                       unsigned int, unsigned int, struct nf_conn *,
-                      enum ip_conntrack_info, u32 *seq)
+                      enum ip_conntrack_info)
 = {
        [NF_CT_FTP_PORT] = mangle_rfc959_packet,
        [NF_CT_FTP_PASV] = mangle_rfc959_packet,
@@ -116,8 +110,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
                               enum nf_ct_ftp_type type,
                               unsigned int matchoff,
                               unsigned int matchlen,
-                              struct nf_conntrack_expect *exp,
-                              u32 *seq)
+                              struct nf_conntrack_expect *exp)
 {
        __be32 newip;
        u_int16_t port;
@@ -145,8 +138,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
        if (port == 0)
                return NF_DROP;
 
-       if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
-                         seq)) {
+       if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
                nf_conntrack_unexpect_related(exp);
                return NF_DROP;
        }
index fcebc968d37f67681cd52a8f0094029544a730fa..c5d2a2d690b84e54b558ac8e558b6c0550a7ac36 100644 (file)
@@ -455,9 +455,9 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
                if (idx > 0 &&
                    get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
                    (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
-                       set_h225_addr_hook(pskb, data, 0, &taddr[0],
-                                          &ct->tuplehash[!dir].tuple.dst.u3,
-                                          info->sig_port[!dir]);
+                       set_h225_addr(pskb, data, 0, &taddr[0],
+                                     &ct->tuplehash[!dir].tuple.dst.u3,
+                                     info->sig_port[!dir]);
                }
        } else {
                nf_conntrack_unexpect_related(exp);
index cdbc6c1358494c616d8146c9a23712ca6c92e308..3b690cf2a4ee62263a16c11c6f69d861f42e1056 100644 (file)
@@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
                seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
 
        seq_printf(seq, "\nIp: %d %d",
-                       ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl);
+                  IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
 
        for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
                seq_printf(seq, " %lu",
index df9fe4f2e8cc5df95fc43c3fe1c271d8d480ac89..29ca63e81ced23877fe568573b8522e0ce16d8a1 100644 (file)
@@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
-       if (in_dev->cnf.no_policy)
+       if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
                rth->u.dst.flags |= DST_NOPOLICY;
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
@@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb,
        if (res->fi->fib_nhs > 1)
                rth->u.dst.flags |= DST_BALANCED;
 #endif
-       if (in_dev->cnf.no_policy)
+       if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
                rth->u.dst.flags |= DST_NOPOLICY;
-       if (out_dev->cnf.no_xfrm)
+       if (IN_DEV_CONF_GET(out_dev, NOXFRM))
                rth->u.dst.flags |= DST_NOXFRM;
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
@@ -2021,7 +2021,7 @@ local_input:
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
-       if (in_dev->cnf.no_policy)
+       if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
                rth->u.dst.flags |= DST_NOPOLICY;
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
@@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result,
                        rth->u.dst.flags |= DST_BALANCED;
        }
 #endif
-       if (in_dev->cnf.no_xfrm)
+       if (IN_DEV_CONF_GET(in_dev, NOXFRM))
                rth->u.dst.flags |= DST_NOXFRM;
-       if (in_dev->cnf.no_policy)
+       if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
                rth->u.dst.flags |= DST_NOPOLICY;
 
        rth->fl.fl4_dst = oldflp->fl4_dst;
@@ -2598,6 +2598,69 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
 
 EXPORT_SYMBOL_GPL(__ip_route_output_key);
 
+static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+}
+
+static struct dst_ops ipv4_dst_blackhole_ops = {
+       .family                 =       AF_INET,
+       .protocol               =       __constant_htons(ETH_P_IP),
+       .destroy                =       ipv4_dst_destroy,
+       .check                  =       ipv4_dst_check,
+       .update_pmtu            =       ipv4_rt_blackhole_update_pmtu,
+       .entry_size             =       sizeof(struct rtable),
+};
+
+
+static int ipv4_blackhole_output(struct sk_buff *skb)
+{
+       kfree_skb(skb);
+       return 0;
+}
+
+static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk)
+{
+       struct rtable *ort = *rp;
+       struct rtable *rt = (struct rtable *)
+               dst_alloc(&ipv4_dst_blackhole_ops);
+
+       if (rt) {
+               struct dst_entry *new = &rt->u.dst;
+
+               atomic_set(&new->__refcnt, 1);
+               new->__use = 1;
+               new->input = ipv4_blackhole_output;
+               new->output = ipv4_blackhole_output;
+               memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
+
+               new->dev = ort->u.dst.dev;
+               if (new->dev)
+                       dev_hold(new->dev);
+
+               rt->fl = ort->fl;
+
+               rt->idev = ort->idev;
+               if (rt->idev)
+                       in_dev_hold(rt->idev);
+               rt->rt_flags = ort->rt_flags;
+               rt->rt_type = ort->rt_type;
+               rt->rt_dst = ort->rt_dst;
+               rt->rt_src = ort->rt_src;
+               rt->rt_iif = ort->rt_iif;
+               rt->rt_gateway = ort->rt_gateway;
+               rt->rt_spec_dst = ort->rt_spec_dst;
+               rt->peer = ort->peer;
+               if (rt->peer)
+                       atomic_inc(&rt->peer->refcnt);
+
+               dst_free(new);
+       }
+
+       dst_release(&(*rp)->u.dst);
+       *rp = rt;
+       return (rt ? 0 : -ENOMEM);
+}
+
 int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
 {
        int err;
@@ -2610,7 +2673,11 @@ int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk,
                        flp->fl4_src = (*rp)->rt_src;
                if (!flp->fl4_dst)
                        flp->fl4_dst = (*rp)->rt_dst;
-               return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
+               err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
+               if (err == -EREMOTE)
+                       err = ipv4_dst_blackhole(rp, flp, sk);
+
+               return err;
        }
 
        return 0;
@@ -2692,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                __be32 dst = rt->rt_dst;
 
                if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
-                   ipv4_devconf.mc_forwarding) {
+                   IPV4_DEVCONF_ALL(MC_FORWARDING)) {
                        int err = ipmr_get_route(skb, r, nowait);
                        if (err <= 0) {
                                if (!nowait) {
@@ -3139,6 +3206,8 @@ int __init ip_rt_init(void)
                kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0,
                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
 
+       ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep;
+
        rt_hash_table = (struct rt_hash_bucket *)
                alloc_large_system_hash("IP route cache",
                                        sizeof(struct rt_hash_bucket),
index 6817d6485df5c195430ab808c2c345e8d6e15ba4..53ef0f4bbdaa507137d0a99b7a120fe43bddf1bb 100644 (file)
@@ -37,12 +37,12 @@ static
 int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int val = ipv4_devconf.forwarding;
+       int val = IPV4_DEVCONF_ALL(FORWARDING);
        int ret;
 
        ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
-       if (write && ipv4_devconf.forwarding != val)
+       if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
                inet_forward_change();
 
        return ret;
@@ -222,7 +222,7 @@ ctl_table ipv4_table[] = {
        {
                .ctl_name       = NET_IPV4_FORWARD,
                .procname       = "ip_forward",
-               .data           = &ipv4_devconf.forwarding,
+               .data           = &IPV4_DEVCONF_ALL(FORWARDING),
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &ipv4_sysctl_forward,
index bd4c295f5d796347c2ba705710c417a50d6002fe..cd3c7e95de9e07296de8583fdc5b3df73aa45cdf 100644 (file)
@@ -1674,9 +1674,8 @@ adjudge_to_death:
        }
        if (sk->sk_state != TCP_CLOSE) {
                sk_stream_mem_reclaim(sk);
-               if (atomic_read(sk->sk_prot->orphan_count) > sysctl_tcp_max_orphans ||
-                   (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-                    atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) {
+               if (tcp_too_many_orphans(sk,
+                               atomic_read(sk->sk_prot->orphan_count))) {
                        if (net_ratelimit())
                                printk(KERN_INFO "TCP: too many of orphaned "
                                       "sockets\n");
@@ -2465,13 +2464,10 @@ void __init tcp_init(void)
                        order++)
                ;
        if (order >= 4) {
-               sysctl_local_port_range[0] = 32768;
-               sysctl_local_port_range[1] = 61000;
                tcp_death_row.sysctl_max_tw_buckets = 180000;
                sysctl_tcp_max_orphans = 4096 << (order - 4);
                sysctl_max_syn_backlog = 1024;
        } else if (order < 3) {
-               sysctl_local_port_range[0] = 1024 * (3 - order);
                tcp_death_row.sysctl_max_tw_buckets >>= (3 - order);
                sysctl_tcp_max_orphans >>= (3 - order);
                sysctl_max_syn_backlog = 128;
index 38cb25b48bf3b9961e1ba737db9ea194c448c3b1..74683d81c3f18f8c3450b3100ff89373179ea101 100644 (file)
@@ -2407,8 +2407,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
        struct sk_buff *skb;
        __u32 now = tcp_time_stamp;
        int acked = 0;
+       int prior_packets = tp->packets_out;
        __s32 seq_rtt = -1;
-       u32 pkts_acked = 0;
        ktime_t last_ackt = ktime_set(0,0);
 
        while ((skb = tcp_write_queue_head(sk)) &&
@@ -2437,7 +2437,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
                 */
                if (!(scb->flags & TCPCB_FLAG_SYN)) {
                        acked |= FLAG_DATA_ACKED;
-                       ++pkts_acked;
                } else {
                        acked |= FLAG_SYN_ACKED;
                        tp->retrans_stamp = 0;
@@ -2481,6 +2480,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
        }
 
        if (acked&FLAG_ACKED) {
+               u32 pkts_acked = prior_packets - tp->packets_out;
                const struct tcp_congestion_ops *ca_ops
                        = inet_csk(sk)->icsk_ca_ops;
 
index 5a3e7f839fc52f838122a88a40209566ce2e3ab7..97e294e8267913477987ef38d473cf5ff534df2c 100644 (file)
@@ -192,8 +192,11 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                               RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
                               IPPROTO_TCP,
                               inet->sport, usin->sin_port, sk, 1);
-       if (tmp < 0)
+       if (tmp < 0) {
+               if (tmp == -ENETUNREACH)
+                       IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return tmp;
+       }
 
        if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
                ip_rt_put(rt);
@@ -702,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
                                      ip_hdr(skb)->saddr, /* XXX */
                                      arg.iov[0].iov_len, IPPROTO_TCP, 0);
        arg.csumoffset = offsetof(struct tcphdr, check) / 2;
+       if (twsk)
+               arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
 
        ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
 
index 3938d5dbdf208292157573aa6448e088505a3145..d9323dfff82620487b413ce9e6b61fa426108e37 100644 (file)
@@ -62,6 +62,9 @@ struct {
  * Print to log with timestamps.
  * FIXME: causes an extra copy
  */
+static void printl(const char *fmt, ...)
+       __attribute__ ((format (printf, 1, 2)));
+
 static void printl(const char *fmt, ...)
 {
        va_list args;
@@ -95,7 +98,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
        /* Only update if port matches */
        if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port)
            && (full || tp->snd_cwnd != tcpw.lastcwnd)) {
-               printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u\n",
+               printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n",
                       NIPQUAD(inet->saddr), ntohs(inet->sport),
                       NIPQUAD(inet->daddr), ntohs(inet->dport),
                       skb->len, tp->snd_nxt, tp->snd_una,
index 2ca97b20929d60540529c7af5cc46658ef4b70fb..e9b151b3a598e46dfd162bdc4645bdb083d48e83 100644 (file)
@@ -78,9 +78,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset)
        if (sk->sk_err_soft)
                orphans <<= 1;
 
-       if (orphans >= sysctl_tcp_max_orphans ||
-           (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-            atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) {
+       if (tcp_too_many_orphans(sk, orphans)) {
                if (net_ratelimit())
                        printk(KERN_INFO "Out of socket memory\n");
 
@@ -294,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk)
                 * we cannot allow such beasts to hang infinitely.
                 */
 #ifdef TCP_DEBUG
-               if (net_ratelimit()) {
+               if (1) {
                        struct inet_sock *inet = inet_sk(sk);
-                       printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
+                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
                               NIPQUAD(inet->daddr), ntohs(inet->dport),
                               inet->num, tp->snd_una, tp->snd_nxt);
                }
index 4c7e95fa090d181234e3dbb1a2d1934a259c317f..facb7e29304e7df9a7a172d2e4ad2f63acfa1074 100644 (file)
@@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock);
 
 static int udp_port_rover;
 
-/*
- * Note about this hash function :
- * Typical use is probably daddr = 0, only dport is going to vary hash
- */
-static inline unsigned int udp_hash_port(__u16 port)
-{
-       return port;
-}
-
-static inline int __udp_lib_port_inuse(unsigned int hash, int port,
-                                      const struct sock *this_sk,
-                                      struct hlist_head udptable[],
-                                      const struct udp_get_port_ops *ops)
+static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
 {
        struct sock *sk;
        struct hlist_node *node;
-       struct inet_sock *inet;
 
-       sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
-               if (sk->sk_hash != hash)
-                       continue;
-               inet = inet_sk(sk);
-               if (inet->num != port)
-                       continue;
-               if (this_sk) {
-                       if (ops->saddr_cmp(sk, this_sk))
-                               return 1;
-               } else if (ops->saddr_any(sk))
+       sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
+               if (sk->sk_hash == num)
                        return 1;
-       }
        return 0;
 }
 
@@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
  *  @snum:        port number to look up
  *  @udptable:    hash list table, must be of UDP_HTABLE_SIZE
  *  @port_rover:  pointer to record of last unallocated port
- *  @ops:         AF-dependent address operations
+ *  @saddr_comp:  AF-dependent comparison of bound local IP addresses
  */
 int __udp_lib_get_port(struct sock *sk, unsigned short snum,
                       struct hlist_head udptable[], int *port_rover,
-                      const struct udp_get_port_ops *ops)
+                      int (*saddr_comp)(const struct sock *sk1,
+                                        const struct sock *sk2 )    )
 {
        struct hlist_node *node;
        struct hlist_head *head;
        struct sock *sk2;
-       unsigned int hash;
        int    error = 1;
 
        write_lock_bh(&udp_hash_lock);
@@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
                for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
                        int size;
 
-                       hash = ops->hash_port_and_rcv_saddr(result, sk);
-                       head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
+                       head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
                        if (hlist_empty(head)) {
                                if (result > sysctl_local_port_range[1])
                                        result = sysctl_local_port_range[0] +
@@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
                                result = sysctl_local_port_range[0]
                                        + ((result - sysctl_local_port_range[0]) &
                                           (UDP_HTABLE_SIZE - 1));
-                       hash = udp_hash_port(result);
-                       if (__udp_lib_port_inuse(hash, result,
-                                                NULL, udptable, ops))
-                               continue;
-                       if (ops->saddr_any(sk))
-                               break;
-
-                       hash = ops->hash_port_and_rcv_saddr(result, sk);
-                       if (! __udp_lib_port_inuse(hash, result,
-                                                  sk, udptable, ops))
+                       if (! __udp_lib_lport_inuse(result, udptable))
                                break;
                }
                if (i >= (1 << 16) / UDP_HTABLE_SIZE)
@@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
 gotit:
                *port_rover = snum = result;
        } else {
-               hash = udp_hash_port(snum);
-               head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
+               head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
 
                sk_for_each(sk2, node, head)
-                       if (sk2->sk_hash == hash &&
-                           sk2 != sk &&
-                           inet_sk(sk2)->num == snum &&
-                           (!sk2->sk_reuse || !sk->sk_reuse) &&
-                           (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
-                            sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
-                           ops->saddr_cmp(sk, sk2))
+                       if (sk2->sk_hash == snum                             &&
+                           sk2 != sk                                        &&
+                           (!sk2->sk_reuse        || !sk->sk_reuse)         &&
+                           (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
+                            || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
+                           (*saddr_comp)(sk, sk2)                             )
                                goto fail;
-
-               if (!ops->saddr_any(sk)) {
-                       hash = ops->hash_port_and_rcv_saddr(snum, sk);
-                       head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
-
-                       sk_for_each(sk2, node, head)
-                               if (sk2->sk_hash == hash &&
-                                   sk2 != sk &&
-                                   inet_sk(sk2)->num == snum &&
-                                   (!sk2->sk_reuse || !sk->sk_reuse) &&
-                                   (!sk2->sk_bound_dev_if ||
-                                    !sk->sk_bound_dev_if ||
-                                    sk2->sk_bound_dev_if ==
-                                    sk->sk_bound_dev_if) &&
-                                   ops->saddr_cmp(sk, sk2))
-                                       goto fail;
-               }
        }
        inet_sk(sk)->num = snum;
-       sk->sk_hash = hash;
+       sk->sk_hash = snum;
        if (sk_unhashed(sk)) {
-               head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
+               head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
                sk_add_node(sk, head);
                sock_prot_inc_use(sk->sk_prot);
        }
@@ -265,12 +214,12 @@ fail:
 }
 
 int udp_get_port(struct sock *sk, unsigned short snum,
-                const struct udp_get_port_ops *ops)
+                       int (*scmp)(const struct sock *, const struct sock *))
 {
-       return  __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops);
+       return  __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
 }
 
-static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
+int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
 {
        struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
 
@@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
                   inet1->rcv_saddr == inet2->rcv_saddr      ));
 }
 
-static int ipv4_rcv_saddr_any(const struct sock *sk)
-{
-       return !inet_sk(sk)->rcv_saddr;
-}
-
-static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr)
-{
-       addr ^= addr >> 16;
-       addr ^= addr >> 8;
-       return port ^ addr;
-}
-
-static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port,
-                                                const struct sock *sk)
-{
-       return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr);
-}
-
-const struct udp_get_port_ops udp_ipv4_ops = {
-       .saddr_cmp = ipv4_rcv_saddr_equal,
-       .saddr_any = ipv4_rcv_saddr_any,
-       .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr,
-};
-
 static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
 {
-       return udp_get_port(sk, snum, &udp_ipv4_ops);
+       return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
 }
 
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
@@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
 {
        struct sock *sk, *result = NULL;
        struct hlist_node *node;
-       unsigned int hash, hashwild;
-       int score, best = -1, hport = ntohs(dport);
-
-       hash = ipv4_hash_port_and_addr(hport, daddr);
-       hashwild = udp_hash_port(hport);
+       unsigned short hnum = ntohs(dport);
+       int badness = -1;
 
        read_lock(&udp_hash_lock);
-
-lookup:
-
-       sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
+       sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
                struct inet_sock *inet = inet_sk(sk);
 
-               if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
-                       inet->num != hport)
-                       continue;
-
-               score = (sk->sk_family == PF_INET ? 1 : 0);
-               if (inet->rcv_saddr) {
-                       if (inet->rcv_saddr != daddr)
-                               continue;
-                       score+=2;
-               }
-               if (inet->daddr) {
-                       if (inet->daddr != saddr)
-                               continue;
-                       score+=2;
-               }
-               if (inet->dport) {
-                       if (inet->dport != sport)
-                               continue;
-                       score+=2;
-               }
-               if (sk->sk_bound_dev_if) {
-                       if (sk->sk_bound_dev_if != dif)
-                               continue;
-                       score+=2;
-               }
-               if (score == 9) {
-                       result = sk;
-                       goto found;
-               } else if (score > best) {
-                       result = sk;
-                       best = score;
+               if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
+                       int score = (sk->sk_family == PF_INET ? 1 : 0);
+                       if (inet->rcv_saddr) {
+                               if (inet->rcv_saddr != daddr)
+                                       continue;
+                               score+=2;
+                       }
+                       if (inet->daddr) {
+                               if (inet->daddr != saddr)
+                                       continue;
+                               score+=2;
+                       }
+                       if (inet->dport) {
+                               if (inet->dport != sport)
+                                       continue;
+                               score+=2;
+                       }
+                       if (sk->sk_bound_dev_if) {
+                               if (sk->sk_bound_dev_if != dif)
+                                       continue;
+                               score+=2;
+                       }
+                       if (score == 9) {
+                               result = sk;
+                               break;
+                       } else if (score > badness) {
+                               result = sk;
+                               badness = score;
+                       }
                }
        }
-
-       if (hash != hashwild) {
-               hash = hashwild;
-               goto lookup;
-       }
-found:
        if (result)
                sock_hold(result);
        read_unlock(&udp_hash_lock);
        return result;
 }
 
-static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum,
-                                            int hport, __be32 loc_addr,
+static inline struct sock *udp_v4_mcast_next(struct sock *sk,
+                                            __be16 loc_port, __be32 loc_addr,
                                             __be16 rmt_port, __be32 rmt_addr,
                                             int dif)
 {
        struct hlist_node *node;
        struct sock *s = sk;
+       unsigned short hnum = ntohs(loc_port);
 
        sk_for_each_from(s, node) {
                struct inet_sock *inet = inet_sk(s);
 
                if (s->sk_hash != hnum                                  ||
-                   inet->num != hport                                  ||
                    (inet->daddr && inet->daddr != rmt_addr)            ||
                    (inet->dport != rmt_port && inet->dport)            ||
                    (inet->rcv_saddr && inet->rcv_saddr != loc_addr)    ||
@@ -722,8 +633,11 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                                 .dport = dport } } };
                security_sk_classify_flow(sk, &fl);
                err = ip_route_output_flow(&rt, &fl, sk, 1);
-               if (err)
+               if (err) {
+                       if (err == -ENETUNREACH)
+                               IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                        goto out;
+               }
 
                err = -EACCES;
                if ((rt->rt_flags & RTCF_BROADCAST) &&
@@ -1218,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
                                    __be32 saddr, __be32 daddr,
                                    struct hlist_head udptable[])
 {
-       struct sock *sk, *skw, *sknext;
+       struct sock *sk;
        int dif;
-       int hport = ntohs(uh->dest);
-       unsigned int hash = ipv4_hash_port_and_addr(hport, daddr);
-       unsigned int hashwild = udp_hash_port(hport);
-
-       dif = skb->dev->ifindex;
 
        read_lock(&udp_hash_lock);
-
-       sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]);
-       skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]);
-
-       sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
-       if (!sk) {
-               hash = hashwild;
-               sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source,
-                       saddr, dif);
-       }
+       sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
+       dif = skb->dev->ifindex;
+       sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
        if (sk) {
+               struct sock *sknext = NULL;
+
                do {
                        struct sk_buff *skb1 = skb;
-                       sknext = udp_v4_mcast_next(sk_next(sk), hash, hport,
-                                               daddr, uh->source, saddr, dif);
-                       if (!sknext && hash != hashwild) {
-                               hash = hashwild;
-                               sknext = udp_v4_mcast_next(skw, hash, hport,
-                                       daddr, uh->source, saddr, dif);
-                       }
+
+                       sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr,
+                                                  uh->source, saddr, dif);
                        if (sknext)
                                skb1 = skb_clone(skb, GFP_ATOMIC);
 
                        if (skb1) {
                                int ret = udp_queue_rcv_skb(sk, skb1);
                                if (ret > 0)
-                                       /*
-                                        * we should probably re-process
-                                        * instead of dropping packets here.
-                                        */
+                                       /* we should probably re-process instead
+                                        * of dropping packets here. */
                                        kfree_skb(skb1);
                        }
                        sk = sknext;
@@ -1343,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
                return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
 
        sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
-                              skb->dev->ifindex, udptable);
+                              skb->dev->ifindex, udptable        );
 
        if (sk != NULL) {
                int ret = udp_queue_rcv_skb(sk, skb);
index 06d94195e644848fa464f54456c4abb450496a25..820a477cfaa6e9899234b03ee8120c9ca158babd 100644 (file)
@@ -5,14 +5,14 @@
 #include <net/protocol.h>
 #include <net/inet_common.h>
 
-extern const struct udp_get_port_ops udp_ipv4_ops;
-
 extern int     __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
 extern void    __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
 
 extern int     __udp_lib_get_port(struct sock *sk, unsigned short snum,
                                   struct hlist_head udptable[], int *port_rover,
-                                  const struct udp_get_port_ops *ops);
+                                  int (*)(const struct sock*,const struct sock*));
+extern int     ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
+
 
 extern int     udp_setsockopt(struct sock *sk, int level, int optname,
                               char __user *optval, int optlen);
index 3653b32dce2d79f6ec18eb2a484aaf325448578a..f34fd686a8f15ac6e49b687742701c1037ab1417 100644 (file)
@@ -19,15 +19,14 @@ struct hlist_head   udplite_hash[UDP_HTABLE_SIZE];
 static int             udplite_port_rover;
 
 int udplite_get_port(struct sock *sk, unsigned short p,
-                    const struct udp_get_port_ops *ops)
+                    int (*c)(const struct sock *, const struct sock *))
 {
-       return  __udp_lib_get_port(sk, p, udplite_hash,
-                                  &udplite_port_rover, ops);
+       return  __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
 }
 
 static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
 {
-       return udplite_get_port(sk, snum, &udp_ipv4_ops);
+       return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
 }
 
 static int udplite_rcv(struct sk_buff *skb)
index 5ceca951d73f4fc4964d802ce68aac833c463904..fa1902dc81b86e1c20f24451c5bf515567e9015f 100644 (file)
@@ -139,10 +139,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
        nf_reset(skb);
 
        if (decaps) {
-               if (!(skb->dev->flags&IFF_LOOPBACK)) {
-                       dst_release(skb->dst);
-                       skb->dst = NULL;
-               }
+               dst_release(skb->dst);
+               skb->dst = NULL;
                netif_rx(skb);
                return 0;
        } else {
index a2f2e6a5ec5d1662e6ba0b372af47059288cebaf..9963700e74c1e6185f31ea807b839a0d67a87081 100644 (file)
@@ -85,6 +85,8 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        top_iph->saddr = x->props.saddr.a4;
        top_iph->daddr = x->id.daddr.a4;
 
+       skb->protocol = htons(ETH_P_IP);
+
        memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
        return 0;
 }
index c7ea248fae2e28e7519052400f7256b491c016e9..5a5f8bd4597a71362570316cfbeb068d2ad5af24 100644 (file)
@@ -2154,15 +2154,6 @@ static void addrconf_dev_config(struct net_device *dev)
 
        ASSERT_RTNL();
 
-       if ((dev->type != ARPHRD_ETHER) &&
-           (dev->type != ARPHRD_FDDI) &&
-           (dev->type != ARPHRD_IEEE802_TR) &&
-           (dev->type != ARPHRD_ARCNET) &&
-           (dev->type != ARPHRD_INFINIBAND)) {
-               /* Alas, we support only Ethernet autoconfiguration. */
-               return;
-       }
-
        idev = addrconf_add_dev(dev);
        if (idev == NULL)
                return;
@@ -2250,13 +2241,33 @@ static void addrconf_ip6_tnl_config(struct net_device *dev)
        ip6_tnl_add_linklocal(idev);
 }
 
+static int ipv6_hwtype(struct net_device *dev)
+{
+       if ((dev->type == ARPHRD_ETHER) ||
+           (dev->type == ARPHRD_LOOPBACK) ||
+           (dev->type == ARPHRD_SIT) ||
+           (dev->type == ARPHRD_TUNNEL6) ||
+           (dev->type == ARPHRD_FDDI) ||
+           (dev->type == ARPHRD_IEEE802_TR) ||
+           (dev->type == ARPHRD_ARCNET) ||
+           (dev->type == ARPHRD_INFINIBAND))
+               return 1;
+
+       return 0;
+}
+
 static int addrconf_notify(struct notifier_block *this, unsigned long event,
                           void * data)
 {
        struct net_device *dev = (struct net_device *) data;
-       struct inet6_dev *idev = __in6_dev_get(dev);
+       struct inet6_dev *idev;
        int run_pending = 0;
 
+       if (!ipv6_hwtype(dev))
+               return NOTIFY_OK;
+
+       idev = __in6_dev_get(dev);
+
        switch(event) {
        case NETDEV_REGISTER:
                if (!idev) {
@@ -2979,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
        return pfx;
 }
 
-static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = {
+static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
        [IFA_ADDRESS]           = { .len = sizeof(struct in6_addr) },
        [IFA_LOCAL]             = { .len = sizeof(struct in6_addr) },
        [IFA_CACHEINFO]         = { .len = sizeof(struct ifa_cacheinfo) },
index b696c8401200b64c7775f85c511bad6e026d292b..128f94c79c641e462d62e3a762e92b00ab2fb0dc 100644 (file)
@@ -247,7 +247,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
        memcpy(tmp_base, top_iph, sizeof(tmp_base));
 
        tmp_ext = NULL;
-       extlen = skb_transport_offset(skb) + sizeof(struct ipv6hdr);
+       extlen = skb_transport_offset(skb) - sizeof(struct ipv6hdr);
        if (extlen) {
                extlen += sizeof(*tmp_ext);
                tmp_ext = kmalloc(extlen, GFP_ATOMIC);
index 403eee66b9c5e4303e22fc2712eb67340a244b32..b1fe7ac5dc9006795e871621179bf4d20f58cd9b 100644 (file)
@@ -177,8 +177,12 @@ ipv4_connected:
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
-               goto out;
+       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+               if (err == -EREMOTE)
+                       err = ip6_dst_blackhole(sk, &dst, &fl);
+               if (err < 0)
+                       goto out;
+       }
 
        /* source address lookup done in ip6_dst_lookup */
 
index fc3882c906049ce8b051b30c1658fa20e1f6fce6..53b3998a486ced67d9eae000cff6c9a1269ecf66 100644 (file)
@@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
        return 1;
 }
 
-static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
+static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
        FRA_GENERIC_POLICY,
 };
 
index ca08ee88d07f2913558c0ac331201f7d3a05527b..662a7d9681fdb03b4c2a9c089ec4dffdcfb2f4d2 100644 (file)
@@ -619,14 +619,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 
        ins = &fn->leaf;
 
-       if (fn->fn_flags&RTN_TL_ROOT &&
-           fn->leaf == &ip6_null_entry &&
-           !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
-               fn->leaf = rt;
-               rt->u.dst.rt6_next = NULL;
-               goto out;
-       }
-
        for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) {
                /*
                 *      Search for duplicates
@@ -666,7 +658,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
         *      insert node
         */
 
-out:
        rt->u.dst.rt6_next = iter;
        *ins = rt;
        rt->rt6i_node = fn;
index 6d2a0820511104994dc90a08b4a14b8b52759741..1b1797f1f33d0e839926dab7b3fcc88cfacb85c8 100644 (file)
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
 {
        struct nf_conn *ct;
        struct nf_conn_help *help;
+       struct nf_conntrack_helper *helper;
        enum ip_conntrack_info ctinfo;
        unsigned int ret, protoff;
        unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
@@ -172,18 +173,21 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
                goto out;
 
        help = nfct_help(ct);
-       if (!help || !help->helper)
+       if (!help)
+               goto out;
+       /* rcu_read_lock()ed by nf_hook_slow */
+       helper = rcu_dereference(help->helper);
+       if (!helper)
                goto out;
 
        protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
                                         (*pskb)->len - extoff);
-       if (protoff < 0 || protoff > (*pskb)->len ||
-           pnum == NEXTHDR_FRAGMENT) {
+       if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) {
                DEBUGP("proto header not found\n");
                return NF_ACCEPT;
        }
 
-       ret = help->helper->help(pskb, protoff, ct, ctinfo);
+       ret = helper->help(pskb, protoff, ct, ctinfo);
        if (ret != NF_ACCEPT)
                return ret;
 out:
index 0be790d250f9c239f6f1977927fd53b3604537e4..8814b95b232630604eb4e568d7771bcda8e47cb6 100644 (file)
@@ -168,8 +168,7 @@ icmpv6_error_message(struct sk_buff *skb,
                                           skb->len - inip6off
                                                    - sizeof(struct ipv6hdr));
 
-       if ((inprotoff < 0) || (inprotoff > skb->len) ||
-           (inprotonum == NEXTHDR_FRAGMENT)) {
+       if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
                DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
                return -NF_ACCEPT;
        }
index 009a1047fc3fab58b87c95a62591606e75d7c2a8..a58459a766849fe71e2fa4c08cb67dd65e78aa03 100644 (file)
@@ -818,8 +818,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
-               goto out;
+       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+               if (err == -EREMOTE)
+                       err = ip6_dst_blackhole(sk, &dst, &fl);
+               if (err < 0)
+                       goto out;
+       }
 
        if (hlimit < 0) {
                if (ipv6_addr_is_multicast(&fl.fl6_dst))
index b46ad53044bac791e48cb164002a48f9455f1195..fe8d9837f9f89a2067b5f633d5a9cdd992385bf2 100644 (file)
@@ -119,6 +119,19 @@ static struct dst_ops ip6_dst_ops = {
        .entry_size             =       sizeof(struct rt6_info),
 };
 
+static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+}
+
+static struct dst_ops ip6_dst_blackhole_ops = {
+       .family                 =       AF_INET6,
+       .protocol               =       __constant_htons(ETH_P_IPV6),
+       .destroy                =       ip6_dst_destroy,
+       .check                  =       ip6_dst_check,
+       .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
+       .entry_size             =       sizeof(struct rt6_info),
+};
+
 struct rt6_info ip6_null_entry = {
        .u = {
                .dst = {
@@ -833,6 +846,54 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
 
 EXPORT_SYMBOL(ip6_route_output);
 
+static int ip6_blackhole_output(struct sk_buff *skb)
+{
+       kfree_skb(skb);
+       return 0;
+}
+
+int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl)
+{
+       struct rt6_info *ort = (struct rt6_info *) *dstp;
+       struct rt6_info *rt = (struct rt6_info *)
+               dst_alloc(&ip6_dst_blackhole_ops);
+       struct dst_entry *new = NULL;
+
+       if (rt) {
+               new = &rt->u.dst;
+
+               atomic_set(&new->__refcnt, 1);
+               new->__use = 1;
+               new->input = ip6_blackhole_output;
+               new->output = ip6_blackhole_output;
+
+               memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
+               new->dev = ort->u.dst.dev;
+               if (new->dev)
+                       dev_hold(new->dev);
+               rt->rt6i_idev = ort->rt6i_idev;
+               if (rt->rt6i_idev)
+                       in6_dev_hold(rt->rt6i_idev);
+               rt->rt6i_expires = 0;
+
+               ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway);
+               rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+               rt->rt6i_metric = 0;
+
+               memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
+#ifdef CONFIG_IPV6_SUBTREES
+               memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
+#endif
+
+               dst_free(new);
+       }
+
+       dst_release(*dstp);
+       *dstp = new;
+       return (new ? 0 : -ENOMEM);
+}
+EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
+
 /*
  *     Destination cache support functions
  */
@@ -1938,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu)
        fib6_clean_all(rt6_mtu_change_route, 0, &arg);
 }
 
-static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = {
+static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
        [RTA_GATEWAY]           = { .len = sizeof(struct in6_addr) },
        [RTA_OIF]               = { .type = NLA_U32 },
        [RTA_IIF]               = { .type = NLA_U32 },
@@ -2495,6 +2556,8 @@ void __init ip6_route_init(void)
        ip6_dst_ops.kmem_cachep =
                kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+       ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
+
        fib6_init();
 #ifdef         CONFIG_PROC_FS
        p = proc_net_create("ipv6_route", 0, rt6_proc_info);
index e2f25ea43b6871edab1f9324afc994ef3c2ba216..4f06a51ad4fd73ebd6406a1cadb4b1840e6db8ca 100644 (file)
@@ -265,8 +265,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
-               goto failure;
+       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+               if (err == -EREMOTE)
+                       err = ip6_dst_blackhole(sk, &dst, &fl);
+               if (err < 0)
+                       goto failure;
+       }
 
        if (saddr == NULL) {
                saddr = &fl.fl6_src;
index a7ae59c954d5a2d68f7d18c6bdb3addf1abcbdaf..4210951edb6e9f0d6b8d88d917d99dd34689c5db 100644 (file)
 
 DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
 
-static int ipv6_rcv_saddr_any(const struct sock *sk)
-{
-       struct ipv6_pinfo *np = inet6_sk(sk);
-
-       return ipv6_addr_any(&np->rcv_saddr);
-}
-
-static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port,
-                                                const struct sock *sk)
-{
-       return port;
-}
-
-const struct udp_get_port_ops udp_ipv6_ops = {
-       .saddr_cmp = ipv6_rcv_saddr_equal,
-       .saddr_any = ipv6_rcv_saddr_any,
-       .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr,
-};
-
 static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
 {
-       return udp_get_port(sk, snum, &udp_ipv6_ops);
+       return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
 }
 
 static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
@@ -767,8 +748,12 @@ do_udp_sendmsg:
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
-               goto out;
+       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+               if (err == -EREMOTE)
+                       err = ip6_dst_blackhole(sk, &dst, &fl);
+               if (err < 0)
+                       goto out;
+       }
 
        if (hlimit < 0) {
                if (ipv6_addr_is_multicast(&fl.fl6_dst))
index 36b0c11a28a312dcad2bfa6f82d4bbd057dd307e..6e252f318f7c91c81f5cdf04d2822b476f26a8ae 100644 (file)
@@ -6,8 +6,6 @@
 #include <net/addrconf.h>
 #include <net/inet_common.h>
 
-extern const struct udp_get_port_ops udp_ipv6_ops;
-
 extern int     __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
 extern void    __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
                               int , int , int , __be32 , struct hlist_head []);
index c40a51362f89ed6861d64acccdf371712ca7c61b..f54016a55004d2d931471c06f14db922efa5f84d 100644 (file)
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = {
 
 static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
 {
-       return udplite_get_port(sk, snum, &udp_ipv6_ops);
+       return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
 }
 
 struct proto udplitev6_prot = {
index d7ed8aa56ec18657e79abbf0abe45bbdcd01f878..c858537cec4b0b756ba03907b1ffa7dbcc787793 100644 (file)
@@ -104,10 +104,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
        nf_reset(skb);
 
        if (decaps) {
-               if (!(skb->dev->flags&IFF_LOOPBACK)) {
-                       dst_release(skb->dst);
-                       skb->dst = NULL;
-               }
+               dst_release(skb->dst);
+               skb->dst = NULL;
                netif_rx(skb);
                return -1;
        } else {
index a6c0cdf46ad6a3458f9b905cf284529c1371db97..9fc95bc6509f718b675579ba037adfc5cc0a9065 100644 (file)
@@ -80,6 +80,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
        ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
        ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+       skb->protocol = htons(ETH_P_IPV6);
        return 0;
 }
 
index d302ddae580c567b19dc7edc3925f883453bc126..0f8304b0246bac224f241d7036341bf83db55532 100644 (file)
@@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
        unsigned proto;
        struct km_event c;
        struct xfrm_audit audit_info;
+       int err;
 
        proto = pfkey_satype2proto(hdr->sadb_msg_satype);
        if (proto == 0)
@@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
 
        audit_info.loginuid = audit_get_loginuid(current->audit_context);
        audit_info.secid = 0;
-       xfrm_state_flush(proto, &audit_info);
+       err = xfrm_state_flush(proto, &audit_info);
+       if (err)
+               return err;
        c.data.proto = proto;
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
@@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 {
        struct km_event c;
        struct xfrm_audit audit_info;
+       int err;
 
        audit_info.loginuid = audit_get_loginuid(current->audit_context);
        audit_info.secid = 0;
-       xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
+       err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
+       if (err)
+               return err;
        c.data.type = XFRM_POLICY_TYPE_MAIN;
        c.event = XFRM_MSG_FLUSHPOLICY;
        c.pid = hdr->sadb_msg_pid;
index 6e36df67f8d59b3ecc1c61089249a74454863862..4e84f24fd439852e8473d70147227e82268f4aa0 100644 (file)
@@ -2474,6 +2474,8 @@ static int ieee80211_open(struct net_device *dev)
        if (sdata->type == IEEE80211_IF_TYPE_STA &&
            !local->user_space_mlme)
                netif_carrier_off(dev);
+       else
+               netif_carrier_on(dev);
 
        netif_start_queue(dev);
        return 0;
@@ -3278,8 +3280,10 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
                        return TXRX_DROP;
                }
        }
-       while ((skb = __skb_dequeue(&entry->skb_list)))
+       while ((skb = __skb_dequeue(&entry->skb_list))) {
                memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len);
+               dev_kfree_skb(skb);
+       }
 
        /* Complete frame has been reassembled - process it now */
        rx->fragmented = 1;
index 3e07e9d6fa426f8dd7184c9ee4244b312ff52f7b..9f30ae4c2ab3e4be6f97f05d816528bb3e411a2c 100644 (file)
@@ -1155,6 +1155,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
        if (status_code != WLAN_STATUS_SUCCESS) {
                printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
                       dev->name, status_code);
+               if (status_code == WLAN_STATUS_REASSOC_NO_ASSOC)
+                       ifsta->prev_bssid_set = 0;
                return;
        }
 
@@ -2995,7 +2997,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct sta_info *sta;
-       struct ieee80211_sub_if_data *sdata = NULL;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        /* TODO: Could consider removing the least recently used entry and
         * allow new one to be added. */
index b8869eab7650f233ae50181838f93323ec121290..0568f2e86b5990cc713bd4a374fe3995a04dc898 100644 (file)
@@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void)
 {
        int ret, i;
 
-       ret = -ENOMEM;
        for (i = 0; i < ARRAY_SIZE(search); i++) {
                search[i].ts = textsearch_prepare(ts_algo, search[i].string,
                                                  search[i].len,
                                                  GFP_KERNEL, TS_AUTOLOAD);
-               if (search[i].ts == NULL)
+               if (IS_ERR(search[i].ts)) {
+                       ret = PTR_ERR(search[i].ts);
                        goto err1;
+               }
        }
        ret = nf_conntrack_helper_register(&amanda_helper[0]);
        if (ret < 0)
@@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void)
 err2:
        nf_conntrack_helper_unregister(&amanda_helper[0]);
 err1:
-       for (; i >= 0; i--) {
-               if (search[i].ts)
-                       textsearch_destroy(search[i].ts);
-       }
+       while (--i >= 0)
+               textsearch_destroy(search[i].ts);
+
        return ret;
 }
 
index 483e927a9ca4130182815670c138b87eca3a856b..7a15e30356f2284613c708dc081ceebfeff94e23 100644 (file)
@@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack)
 {
        struct nf_conn *ct = (void *)ul_conntrack;
        struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_helper *helper;
 
-       if (help && help->helper && help->helper->destroy)
-               help->helper->destroy(ct);
+       if (help) {
+               rcu_read_lock();
+               helper = rcu_dereference(help->helper);
+               if (helper && helper->destroy)
+                       helper->destroy(ct);
+               rcu_read_unlock();
+       }
 
        write_lock_bh(&nf_conntrack_lock);
        /* Inside lock so preempt is disabled on module removal path.
@@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
               unsigned int dataoff)
 {
        struct nf_conn *conntrack;
+       struct nf_conn_help *help;
        struct nf_conntrack_tuple repl_tuple;
        struct nf_conntrack_expect *exp;
        u_int32_t features = 0;
@@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
        write_lock_bh(&nf_conntrack_lock);
        exp = find_expectation(tuple);
 
+       help = nfct_help(conntrack);
        if (exp) {
                DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
                        conntrack, exp);
@@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
                __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
                conntrack->master = exp->master;
                if (exp->helper)
-                       nfct_help(conntrack)->helper = exp->helper;
+                       rcu_assign_pointer(help->helper, exp->helper);
 #ifdef CONFIG_NF_CONNTRACK_MARK
                conntrack->mark = exp->master->mark;
 #endif
@@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
                nf_conntrack_get(&conntrack->master->ct_general);
                NF_CT_STAT_INC(expect_new);
        } else {
-               struct nf_conn_help *help = nfct_help(conntrack);
-
-               if (help)
-                       help->helper = __nf_ct_helper_find(&repl_tuple);
+               if (help) {
+                       /* not in hash table yet, so not strictly necessary */
+                       rcu_assign_pointer(help->helper,
+                                          __nf_ct_helper_find(&repl_tuple));
+               }
                NF_CT_STAT_INC(new);
        }
 
@@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
                helper = __nf_ct_helper_find(newreply);
                if (helper)
                        memset(&help->help, 0, sizeof(help->help));
-               help->helper = helper;
+               /* not in hash table yet, so not strictly necessary */
+               rcu_assign_pointer(help->helper, helper);
        }
        write_unlock_bh(&nf_conntrack_lock);
 }
index 117cbfdb910c57bf08b4f62e1a254cccb32df7c1..504fb6c083f99bc30a9fac847943fa2dac4c51cb 100644 (file)
@@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
        NF_CT_ASSERT(master_help);
 
        write_lock_bh(&nf_conntrack_lock);
+       if (!master_help->helper) {
+               ret = -ESHUTDOWN;
+               goto out;
+       }
        list_for_each_entry(i, &nf_conntrack_expect_list, list) {
                if (expect_matches(i, expect)) {
                        /* Refresh timer: if it's dying, ignore.. */
index a186799f654212ef218a7560f5991f99ee407832..82db2aa53bfce5acecac166f4d10e493dc2fe478 100644 (file)
@@ -48,8 +48,7 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
                                enum nf_ct_ftp_type type,
                                unsigned int matchoff,
                                unsigned int matchlen,
-                               struct nf_conntrack_expect *exp,
-                               u32 *seq);
+                               struct nf_conntrack_expect *exp);
 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
 
 #if 0
@@ -335,15 +334,17 @@ static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir,
                if (info->seq_aft_nl[dir][i] == nl_seq)
                        return;
 
-               if (oldest == info->seq_aft_nl_num[dir]
-                   || before(info->seq_aft_nl[dir][i], oldest))
+               if (oldest == info->seq_aft_nl_num[dir] ||
+                   before(info->seq_aft_nl[dir][i],
+                          info->seq_aft_nl[dir][oldest]))
                        oldest = i;
        }
 
        if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
                info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
                nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
-       } else if (oldest != NUM_SEQ_TO_REMEMBER) {
+       } else if (oldest != NUM_SEQ_TO_REMEMBER &&
+                  after(nl_seq, info->seq_aft_nl[dir][oldest])) {
                info->seq_aft_nl[dir][oldest] = nl_seq;
                nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
        }
@@ -519,7 +520,7 @@ static int help(struct sk_buff **pskb,
        nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook);
        if (nf_nat_ftp && ct->status & IPS_NAT_MASK)
                ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
-                                matchoff, matchlen, exp, &seq);
+                                matchoff, matchlen, exp);
        else {
                /* Can't expect this?  Best to drop packet now. */
                if (nf_conntrack_expect_related(exp) != 0)
index b284db73ca7ce935d886b9c1bc06ba38ca5cb74d..a1b95acad297471c0d65973a5a1678ebf648ceb4 100644 (file)
@@ -520,6 +520,16 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
                }
        }
 
+       if ((olca->options & eOpenLogicalChannelAck_separateStack) &&
+               olca->separateStack.networkAddress.choice ==
+               eNetworkAccessParameters_networkAddress_localAreaAddress) {
+               ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
+                                 &olca->separateStack.networkAddress.
+                                 localAreaAddress);
+               if (ret < 0)
+                       return -1;
+       }
+
        return 0;
 }
 
@@ -640,7 +650,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
        case eTransportAddress_ip6Address:
                if (family != AF_INET6)
                        return 0;
-               p = data + taddr->ip6Address.ip6;
+               p = data + taddr->ip6Address.ip;
                len = 16;
                break;
        default:
@@ -976,30 +986,6 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
        return 0;
 }
 
-/****************************************************************************/
-static int process_information(struct sk_buff **pskb,
-                              struct nf_conn *ct,
-                              enum ip_conntrack_info ctinfo,
-                              unsigned char **data, int dataoff,
-                              Information_UUIE *info)
-{
-       int ret;
-       int i;
-
-       DEBUGP("nf_ct_q931: Information\n");
-
-       if (info->options & eInformation_UUIE_fastStart) {
-               for (i = 0; i < info->fastStart.count; i++) {
-                       ret = process_olc(pskb, ct, ctinfo, data, dataoff,
-                                         &info->fastStart.item[i]);
-                       if (ret < 0)
-                               return -1;
-               }
-       }
-
-       return 0;
-}
-
 /****************************************************************************/
 static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
                            enum ip_conntrack_info ctinfo,
@@ -1096,11 +1082,6 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
                ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
                                       &pdu->h323_message_body.alerting);
                break;
-       case eH323_UU_PDU_h323_message_body_information:
-               ret = process_information(pskb, ct, ctinfo, data, dataoff,
-                                         &pdu->h323_message_body.
-                                         information);
-               break;
        case eH323_UU_PDU_h323_message_body_facility:
                ret = process_facility(pskb, ct, ctinfo, data, dataoff,
                                       &pdu->h323_message_body.facility);
index 4c6f8b3b12083c4c5fe0bc8c9bccafc1c4056ae9..3a21fdf1a2654ce8bedbccf8fda781da59919e0a 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006
+/* Generated by Jing Min Zhao's ASN.1 parser, May 16 2007
  *
  * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
  *
@@ -37,7 +37,7 @@ static field_t _TransportAddress_ipxAddress[] = {     /* SEQUENCE */
 
 static field_t _TransportAddress_ip6Address[] = {      /* SEQUENCE */
        {FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
-        offsetof(TransportAddress_ip6Address, ip6), NULL},
+        offsetof(TransportAddress_ip6Address, ip), NULL},
        {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
@@ -67,7 +67,8 @@ static field_t _TransportAddress[] = {        /* CHOICE */
        {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0,
         _TransportAddress_ipxAddress},
        {FNAME("ip6Address") SEQ, 0, 2, 2, DECODE | EXT,
-       offsetof(TransportAddress, ip6Address), _TransportAddress_ip6Address},
+        offsetof(TransportAddress, ip6Address),
+        _TransportAddress_ip6Address},
        {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
        {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
        {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0,
@@ -638,7 +639,8 @@ static field_t _UnicastAddress_iPXAddress[] = {     /* SEQUENCE */
 };
 
 static field_t _UnicastAddress_iP6Address[] = {        /* SEQUENCE */
-       {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
+       {FNAME("network") OCTSTR, FIXD, 16, 0, DECODE,
+        offsetof(UnicastAddress_iP6Address, network), NULL},
        {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
@@ -665,8 +667,8 @@ static field_t _UnicastAddress[] = {        /* CHOICE */
         offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
        {FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
         _UnicastAddress_iPXAddress},
-       {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
-        _UnicastAddress_iP6Address},
+       {FNAME("iP6Address") SEQ, 0, 2, 2, DECODE | EXT,
+        offsetof(UnicastAddress, iP6Address), _UnicastAddress_iP6Address},
        {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
        {FNAME("iPSourceRouteAddress") SEQ, 0, 4, 4, SKIP | EXT, 0,
         _UnicastAddress_iPSourceRouteAddress},
@@ -984,19 +986,12 @@ static field_t _Alerting_UUIE[] = {       /* SEQUENCE */
        {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Information_UUIE_fastStart[] = {       /* SEQUENCE OF */
-       {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
-        sizeof(OpenLogicalChannel), _OpenLogicalChannel}
-       ,
-};
-
 static field_t _Information_UUIE[] = { /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
        {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
-       {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
-        offsetof(Information_UUIE, fastStart), _Information_UUIE_fastStart},
+       {FNAME("fastStart") SEQOF, SEMI, 0, 30, SKIP | OPT, 0, NULL},
        {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
 };
@@ -1343,9 +1338,7 @@ static field_t _H323_UU_PDU_h323_message_body[] = {       /* CHOICE */
         offsetof(H323_UU_PDU_h323_message_body, connect), _Connect_UUIE},
        {FNAME("alerting") SEQ, 1, 3, 17, DECODE | EXT,
         offsetof(H323_UU_PDU_h323_message_body, alerting), _Alerting_UUIE},
-       {FNAME("information") SEQ, 0, 1, 7, DECODE | EXT,
-        offsetof(H323_UU_PDU_h323_message_body, information),
-        _Information_UUIE},
+       {FNAME("information") SEQ, 0, 1, 7, SKIP | EXT, 0, _Information_UUIE},
        {FNAME("releaseComplete") SEQ, 1, 2, 11, SKIP | EXT, 0,
         _ReleaseComplete_UUIE},
        {FNAME("facility") SEQ, 3, 5, 21, DECODE | EXT,
@@ -1430,7 +1423,9 @@ static field_t _OpenLogicalChannelAck[] = {       /* SEQUENCE */
         DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
                                      reverseLogicalChannelParameters),
         _OpenLogicalChannelAck_reverseLogicalChannelParameters},
-       {FNAME("separateStack") SEQ, 2, 4, 5, SKIP | EXT | OPT, 0, NULL},
+       {FNAME("separateStack") SEQ, 2, 4, 5, DECODE | EXT | OPT,
+        offsetof(OpenLogicalChannelAck, separateStack),
+        _NetworkAccessParameters},
        {FNAME("forwardMultiplexAckParameters") CHOICE, 0, 1, 1,
         DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
                                      forwardMultiplexAckParameters),
index 0743be4434b019d201a0caa4dc5826d7061d4f75..f868b7fbd9b4caee49d1e49b560ff6daeaa185bf 100644 (file)
@@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
 
        if (help && help->helper == me) {
                nf_conntrack_event(IPCT_HELPER, ct);
-               help->helper = NULL;
+               rcu_assign_pointer(help->helper, NULL);
        }
        return 0;
 }
index d6d39e2413278b5b8fa9a60523be7a74ded14979..3f73327794ab40a7bb4ae05d0a8b3334458f9eea 100644 (file)
@@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
 {
        struct nfattr *nest_helper;
        const struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_helper *helper;
 
-       if (!help || !help->helper)
+       if (!help)
                return 0;
 
+       rcu_read_lock();
+       helper = rcu_dereference(help->helper);
+       if (!helper)
+               goto out;
+
        nest_helper = NFA_NEST(skb, CTA_HELP);
-       NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
+       NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
 
-       if (help->helper->to_nfattr)
-               help->helper->to_nfattr(skb, ct);
+       if (helper->to_nfattr)
+               helper->to_nfattr(skb, ct);
 
        NFA_NEST_END(skb, nest_helper);
-
+out:
+       rcu_read_unlock();
        return 0;
 
 nfattr_failure:
+       rcu_read_unlock();
        return -1;
 }
 
@@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
                if (help && help->helper) {
                        /* we had a helper before ... */
                        nf_ct_remove_expectations(ct);
-                       help->helper = NULL;
+                       rcu_assign_pointer(help->helper, NULL);
                }
 
                return 0;
@@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
 
        /* need to zero data of old helper */
        memset(&help->help, 0, sizeof(help->help));
-       help->helper = helper;
+       rcu_assign_pointer(help->helper, helper);
 
        return 0;
 }
@@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        struct nf_conn *ct;
        int err = -EINVAL;
        struct nf_conn_help *help;
+       struct nf_conntrack_helper *helper = NULL;
 
        ct = nf_conntrack_alloc(otuple, rtuple);
        if (ct == NULL || IS_ERR(ct))
@@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
 #endif
 
        help = nfct_help(ct);
-       if (help)
-               help->helper = nf_ct_helper_find_get(rtuple);
+       if (help) {
+               helper = nf_ct_helper_find_get(rtuple);
+               /* not in hash table yet so not strictly necessary */
+               rcu_assign_pointer(help->helper, helper);
+       }
 
        add_timer(&ct->timeout);
        nf_conntrack_hash_insert(ct);
 
-       if (help && help->helper)
-               nf_ct_helper_put(help->helper);
+       if (helper)
+               nf_ct_helper_put(helper);
 
        return 0;
 
index 5434472420fe68dc83cc231cbc6436d5d47854d9..339c397d1b5facb318419deeeb6fb2e1e876de62 100644 (file)
@@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
        struct nf_conn_help *help = nfct_help(ct);
        struct nf_ct_gre_keymap **kmp, *km;
 
-       BUG_ON(strcmp(help->helper->name, "pptp"));
        kmp = &help->help.ct_pptp_info.keymap[dir];
        if (*kmp) {
                /* check whether it's a retransmission */
@@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
        enum ip_conntrack_dir dir;
 
        DEBUGP("entering for ct %p\n", ct);
-       BUG_ON(strcmp(help->helper->name, "pptp"));
 
        write_lock_bh(&nf_ct_gre_lock);
        for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
index 07e47dbcb0a9cd1fa455ef8b7f7d60c19ac33971..24b660f16ce3b5c74bb74035ed935f7a2f96ed86 100644 (file)
@@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = {
 };
 
 /* NetLabel Netlink attribute policy */
-static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
+static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
        [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
        [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
        [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
index f2535e7f286979bf5488b7464a39a64c7d79ace7..b165712aaa702ae09d4d35c252c089ac5506a906 100644 (file)
@@ -246,19 +246,18 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
 
 /**
  * netlbl_socket_setattr - Label a socket using the correct protocol
- * @sock: the socket to label
+ * @sk: the socket to label
  * @secattr: the security attributes
  *
  * Description:
  * Attach the correct label to the given socket using the security attributes
- * specified in @secattr.  This function requires exclusive access to
- * @sock->sk, which means it either needs to be in the process of being
- * created or locked via lock_sock(sock->sk).  Returns zero on success,
- * negative values on failure.
+ * specified in @secattr.  This function requires exclusive access to @sk,
+ * which means it either needs to be in the process of being created or locked.
+ * Returns zero on success, negative values on failure.
  *
  */
-int netlbl_socket_setattr(const struct socket *sock,
-                         const struct netlbl_lsm_secattr *secattr)
+int netlbl_sock_setattr(struct sock *sk,
+                       const struct netlbl_lsm_secattr *secattr)
 {
        int ret_val = -ENOENT;
        struct netlbl_dom_map *dom_entry;
@@ -269,9 +268,9 @@ int netlbl_socket_setattr(const struct socket *sock,
                goto socket_setattr_return;
        switch (dom_entry->type) {
        case NETLBL_NLTYPE_CIPSOV4:
-               ret_val = cipso_v4_socket_setattr(sock,
-                                                 dom_entry->type_def.cipsov4,
-                                                 secattr);
+               ret_val = cipso_v4_sock_setattr(sk,
+                                               dom_entry->type_def.cipsov4,
+                                               secattr);
                break;
        case NETLBL_NLTYPE_UNLABELED:
                ret_val = 0;
@@ -308,30 +307,6 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
        return netlbl_unlabel_getattr(secattr);
 }
 
-/**
- * netlbl_socket_getattr - Determine the security attributes of a socket
- * @sock: the socket
- * @secattr: the security attributes
- *
- * Description:
- * Examines the given socket to see any NetLabel style labeling has been
- * applied to the socket, if so it parses the socket label and returns the
- * security attributes in @secattr.  Returns zero on success, negative values
- * on failure.
- *
- */
-int netlbl_socket_getattr(const struct socket *sock,
-                         struct netlbl_lsm_secattr *secattr)
-{
-       int ret_val;
-
-       ret_val = cipso_v4_socket_getattr(sock, secattr);
-       if (ret_val == 0)
-               return 0;
-
-       return netlbl_unlabel_getattr(secattr);
-}
-
 /**
  * netlbl_skbuff_getattr - Determine the security attributes of a packet
  * @skb: the packet
index e8c80f33f3d717ee91e43dd2f41388d914564bbb..e00fc219c72b7c70cd6c581ccd474e0a8c3b2034 100644 (file)
@@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = {
 };
 
 /* NetLabel Netlink attribute policy */
-static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
+static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
        [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
        [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
        [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
index b931edee4b8be1c3836a200461915a0ed9d4e8a9..5c303c68af1d074e003e778b25360160f71b986f 100644 (file)
@@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = {
 };
 
 /* NetLabel Netlink attribute policy */
-static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
        [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
 };
 
index df5f820a4c325be1547b778031b1f9bfcd159ca7..c591212793ee4d7cbd981cabe753a5825f68b4fc 100644 (file)
@@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
 };
 
 static int validate_nla(struct nlattr *nla, int maxtype,
-                       struct nla_policy *policy)
+                       const struct nla_policy *policy)
 {
-       struct nla_policy *pt;
+       const struct nla_policy *pt;
        int minlen = 0, attrlen = nla_len(nla);
 
        if (nla->nla_type <= 0 || nla->nla_type > maxtype)
@@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype,
  * Returns 0 on success or a negative error code.
  */
 int nla_validate(struct nlattr *head, int len, int maxtype,
-                struct nla_policy *policy)
+                const struct nla_policy *policy)
 {
        struct nlattr *nla;
        int rem, err;
@@ -130,7 +130,7 @@ errout:
  * Returns 0 on success or a negative error code.
  */
 int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
-             struct nla_policy *policy)
+             const struct nla_policy *policy)
 {
        struct nlattr *nla;
        int rem, err;
index 6e31234a41966e0df32becfe61613036ac6fd2bd..b9ab62f938d07111f2b7489ad9f5ca9d31dbb746 100644 (file)
@@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
        return skb;
 }
 
-static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
+static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
        [CTRL_ATTR_FAMILY_ID]   = { .type = NLA_U16 },
        [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
                                    .len = GENL_NAMSIZ - 1 },
index 02e401cd683ffbff04dc28403ace1234071990b9..f8b83014cccad9ad56108cd1f6a3dce8b71f2b1d 100644 (file)
 #include <net/inet_common.h>
 #endif
 
-#define CONFIG_SOCK_PACKET     1
-
-/*
-   Proposed replacement for SIOC{ADD,DEL}MULTI and
-   IFF_PROMISC, IFF_ALLMULTI flags.
-
-   It is more expensive, but I believe,
-   it is really correct solution: reentereble, safe and fault tolerant.
-
-   IFF_PROMISC/IFF_ALLMULTI/SIOC{ADD/DEL}MULTI are faked by keeping
-   reference count and global flag, so that real status is
-   (gflag|(count != 0)), so that we can use obsolete faulty interface
-   not harming clever users.
- */
-#define CONFIG_PACKET_MULTICAST        1
-
 /*
    Assumptions:
    - if device has no dev->hard_header routine, it adds and removes ll header
@@ -159,7 +143,6 @@ static atomic_t packet_socks_nr;
 
 /* Private packet socket structures. */
 
-#ifdef CONFIG_PACKET_MULTICAST
 struct packet_mclist
 {
        struct packet_mclist    *next;
@@ -179,7 +162,7 @@ struct packet_mreq_max
        unsigned short  mr_alen;
        unsigned char   mr_address[MAX_ADDR_LEN];
 };
-#endif
+
 #ifdef CONFIG_PACKET_MMAP
 static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing);
 #endif
@@ -205,9 +188,7 @@ struct packet_sock {
                                origdev:1;
        int                     ifindex;        /* bound device         */
        __be16                  num;
-#ifdef CONFIG_PACKET_MULTICAST
        struct packet_mclist    *mclist;
-#endif
 #ifdef CONFIG_PACKET_MMAP
        atomic_t                mapped;
        unsigned int            pg_vec_order;
@@ -263,7 +244,6 @@ static void packet_sock_destruct(struct sock *sk)
 
 static const struct proto_ops packet_ops;
 
-#ifdef CONFIG_SOCK_PACKET
 static const struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
@@ -435,7 +415,6 @@ out_unlock:
                dev_put(dev);
        return err;
 }
-#endif
 
 static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
                                      unsigned int res)
@@ -851,9 +830,7 @@ static int packet_release(struct socket *sock)
                __sock_put(sk);
        }
 
-#ifdef CONFIG_PACKET_MULTICAST
        packet_flush_mclist(sk);
-#endif
 
 #ifdef CONFIG_PACKET_MMAP
        if (po->pg_vec) {
@@ -936,8 +913,6 @@ out_unlock:
  *     Bind a packet socket to a device
  */
 
-#ifdef CONFIG_SOCK_PACKET
-
 static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sock *sk=sock->sk;
@@ -960,7 +935,6 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add
        }
        return err;
 }
-#endif
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
@@ -1012,11 +986,8 @@ static int packet_create(struct socket *sock, int protocol)
 
        if (!capable(CAP_NET_RAW))
                return -EPERM;
-       if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW
-#ifdef CONFIG_SOCK_PACKET
-           && sock->type != SOCK_PACKET
-#endif
-           )
+       if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
+           sock->type != SOCK_PACKET)
                return -ESOCKTNOSUPPORT;
 
        sock->state = SS_UNCONNECTED;
@@ -1027,10 +998,9 @@ static int packet_create(struct socket *sock, int protocol)
                goto out;
 
        sock->ops = &packet_ops;
-#ifdef CONFIG_SOCK_PACKET
        if (sock->type == SOCK_PACKET)
                sock->ops = &packet_ops_spkt;
-#endif
+
        sock_init_data(sock, sk);
 
        po = pkt_sk(sk);
@@ -1046,10 +1016,10 @@ static int packet_create(struct socket *sock, int protocol)
 
        spin_lock_init(&po->bind_lock);
        po->prot_hook.func = packet_rcv;
-#ifdef CONFIG_SOCK_PACKET
+
        if (sock->type == SOCK_PACKET)
                po->prot_hook.func = packet_rcv_spkt;
-#endif
+
        po->prot_hook.af_packet_priv = sk;
 
        if (proto) {
@@ -1169,7 +1139,6 @@ out:
        return err;
 }
 
-#ifdef CONFIG_SOCK_PACKET
 static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
                               int *uaddr_len, int peer)
 {
@@ -1190,7 +1159,6 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
 
        return 0;
 }
-#endif
 
 static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
                          int *uaddr_len, int peer)
@@ -1221,7 +1189,6 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
        return 0;
 }
 
-#ifdef CONFIG_PACKET_MULTICAST
 static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what)
 {
        switch (i->type) {
@@ -1349,7 +1316,6 @@ static void packet_flush_mclist(struct sock *sk)
        }
        rtnl_unlock();
 }
-#endif
 
 static int
 packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
@@ -1362,7 +1328,6 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                return -ENOPROTOOPT;
 
        switch(optname) {
-#ifdef CONFIG_PACKET_MULTICAST
        case PACKET_ADD_MEMBERSHIP:
        case PACKET_DROP_MEMBERSHIP:
        {
@@ -1383,7 +1348,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                        ret = packet_mc_drop(sk, &mreq);
                return ret;
        }
-#endif
+
 #ifdef CONFIG_PACKET_MMAP
        case PACKET_RX_RING:
        {
@@ -1506,11 +1471,10 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
 
                switch (msg) {
                case NETDEV_UNREGISTER:
-#ifdef CONFIG_PACKET_MULTICAST
                        if (po->mclist)
                                packet_dev_mclist(dev, po->mclist, -1);
-                       // fallthrough
-#endif
+                       /* fallthrough */
+
                case NETDEV_DOWN:
                        if (dev->ifindex == po->ifindex) {
                                spin_lock(&po->bind_lock);
@@ -1856,7 +1820,6 @@ out:
 #endif
 
 
-#ifdef CONFIG_SOCK_PACKET
 static const struct proto_ops packet_ops_spkt = {
        .family =       PF_PACKET,
        .owner =        THIS_MODULE,
@@ -1877,7 +1840,6 @@ static const struct proto_ops packet_ops_spkt = {
        .mmap =         sock_no_mmap,
        .sendpage =     sock_no_sendpage,
 };
-#endif
 
 static const struct proto_ops packet_ops = {
        .family =       PF_PACKET,
index 91b3d52f6f1a45b7194c6bf7fb648cd12e3686d8..e662f1d076641ccab1fe09814b547483ec29cdfb 100644 (file)
@@ -4,7 +4,7 @@
 
 config AF_RXRPC
        tristate "RxRPC session sockets"
-       depends on EXPERIMENTAL
+       depends on INET && EXPERIMENTAL
        select KEYS
        help
          Say Y or M here to include support for RxRPC session sockets (just
index 4d92d88ff1fc8114f1aa3242aa6106405ec1efd4..3c04b00dab74930075adc8fc225225a1c8d431a4 100644 (file)
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
+const char *rxrpc_call_states[] = {
+       [RXRPC_CALL_CLIENT_SEND_REQUEST]        = "ClSndReq",
+       [RXRPC_CALL_CLIENT_AWAIT_REPLY]         = "ClAwtRpl",
+       [RXRPC_CALL_CLIENT_RECV_REPLY]          = "ClRcvRpl",
+       [RXRPC_CALL_CLIENT_FINAL_ACK]           = "ClFnlACK",
+       [RXRPC_CALL_SERVER_SECURING]            = "SvSecure",
+       [RXRPC_CALL_SERVER_ACCEPTING]           = "SvAccept",
+       [RXRPC_CALL_SERVER_RECV_REQUEST]        = "SvRcvReq",
+       [RXRPC_CALL_SERVER_ACK_REQUEST]         = "SvAckReq",
+       [RXRPC_CALL_SERVER_SEND_REPLY]          = "SvSndRpl",
+       [RXRPC_CALL_SERVER_AWAIT_ACK]           = "SvAwtACK",
+       [RXRPC_CALL_COMPLETE]                   = "Complete",
+       [RXRPC_CALL_SERVER_BUSY]                = "SvBusy  ",
+       [RXRPC_CALL_REMOTELY_ABORTED]           = "RmtAbort",
+       [RXRPC_CALL_LOCALLY_ABORTED]            = "LocAbort",
+       [RXRPC_CALL_NETWORK_ERROR]              = "NetError",
+       [RXRPC_CALL_DEAD]                       = "Dead    ",
+};
+
 struct kmem_cache *rxrpc_call_jar;
 LIST_HEAD(rxrpc_calls);
 DEFINE_RWLOCK(rxrpc_call_lock);
index 58f4b4e5cece404eba4368ad0b1d79bb646a4d2a..1c0be0e77b162949fa74ebd32587773276cdf818 100644 (file)
@@ -25,25 +25,6 @@ static const char *rxrpc_conn_states[] = {
        [RXRPC_CONN_NETWORK_ERROR]      = "NetError",
 };
 
-const char *rxrpc_call_states[] = {
-       [RXRPC_CALL_CLIENT_SEND_REQUEST]        = "ClSndReq",
-       [RXRPC_CALL_CLIENT_AWAIT_REPLY]         = "ClAwtRpl",
-       [RXRPC_CALL_CLIENT_RECV_REPLY]          = "ClRcvRpl",
-       [RXRPC_CALL_CLIENT_FINAL_ACK]           = "ClFnlACK",
-       [RXRPC_CALL_SERVER_SECURING]            = "SvSecure",
-       [RXRPC_CALL_SERVER_ACCEPTING]           = "SvAccept",
-       [RXRPC_CALL_SERVER_RECV_REQUEST]        = "SvRcvReq",
-       [RXRPC_CALL_SERVER_ACK_REQUEST]         = "SvAckReq",
-       [RXRPC_CALL_SERVER_SEND_REPLY]          = "SvSndRpl",
-       [RXRPC_CALL_SERVER_AWAIT_ACK]           = "SvAwtACK",
-       [RXRPC_CALL_COMPLETE]                   = "Complete",
-       [RXRPC_CALL_SERVER_BUSY]                = "SvBusy  ",
-       [RXRPC_CALL_REMOTELY_ABORTED]           = "RmtAbort",
-       [RXRPC_CALL_LOCALLY_ABORTED]            = "LocAbort",
-       [RXRPC_CALL_NETWORK_ERROR]              = "NetError",
-       [RXRPC_CALL_DEAD]                       = "Dead    ",
-};
-
 /*
  * generate a list of extant and dead calls in /proc/net/rxrpc_calls
  */
index 45b3cda86a21413e6103c3c18ab9ca0116f407f8..6f8684b5617e5653e2fe5bcfd09aee084c7d9134 100644 (file)
@@ -164,8 +164,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
                                printk("offset must be on 32 bit boundaries\n");
                                goto bad;
                        }
-                       if (skb->len < 0 ||
-                           (offset > 0 && offset > skb->len)) {
+                       if (offset > 0 && offset > skb->len) {
                                printk("offset %d cant exceed pkt length %d\n",
                                       offset, skb->len);
                                goto bad;
index be7d299acd73e8f9ab3d39b8ffd9c6469db89419..d1c383fca82c277b2d7c2138b9f4226d25500a5f 100644 (file)
@@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
        /* races ? */
        while ((flow = p->flows)) {
                tcf_destroy_chain(flow->filter_list);
+               flow->filter_list = NULL;
                if (flow->ref > 1)
                        printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
                            flow->ref);
index a294542cb8e4724eba3f3995e775568123cb481b..ee2d5967d109bdd61c7eb67c4ec04d585974b1f5 100644 (file)
@@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch)
         * classes from root to leafs which means that filters can still
         * be bound to classes which have been destroyed already. --TGR '04
         */
-       for (h = 0; h < 16; h++)
-               for (cl = q->classes[h]; cl; cl = cl->next)
+       for (h = 0; h < 16; h++) {
+               for (cl = q->classes[h]; cl; cl = cl->next) {
                        tcf_destroy_chain(cl->filter_list);
-
+                       cl->filter_list = NULL;
+               }
+       }
        for (h = 0; h < 16; h++) {
                struct cbq_class *next;
 
index f28bb2dc58d0af3f17c7430eafe9d110ec6cba31..f4d34480a093d126061920e6f53e7b4fc8dfe83b 100644 (file)
@@ -169,8 +169,8 @@ requeue:
                else
                        q->ops->requeue(skb, q);
                netif_schedule(dev);
-               return 0;
        }
+       return 0;
 
 out:
        BUG_ON((int) q->q.qlen < 0);
@@ -224,7 +224,8 @@ void __netdev_watchdog_up(struct net_device *dev)
        if (dev->tx_timeout) {
                if (dev->watchdog_timeo <= 0)
                        dev->watchdog_timeo = 5*HZ;
-               if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
+               if (!mod_timer(&dev->watchdog_timer,
+                              round_jiffies(jiffies + dev->watchdog_timeo)))
                        dev_hold(dev);
        }
 }
index 99bcec8dd04c1ac6fbba3a8d78492fc7cd5137ba..035788c5b7f8a75c07961c0694df50aeaa9ecef1 100644 (file)
@@ -976,8 +976,9 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
 
                if (q->now >= q->near_ev_cache[level]) {
                        event = htb_do_events(q, level);
-                       q->near_ev_cache[level] = event ? event :
-                                                         PSCHED_TICKS_PER_SEC;
+                       if (!event)
+                               event = q->now + PSCHED_TICKS_PER_SEC;
+                       q->near_ev_cache[level] = event;
                } else
                        event = q->near_ev_cache[level];
 
index 9cba49e2ad431895e202a96659252d3697c4696e..8210f549c4929914f29fe07f4d81809bbdb41a24 100644 (file)
@@ -2,11 +2,9 @@
 # SCTP configuration
 #
 
-menu "SCTP Configuration (EXPERIMENTAL)"
-       depends on INET && EXPERIMENTAL
-
-config IP_SCTP
+menuconfig IP_SCTP
        tristate "The SCTP Protocol (EXPERIMENTAL)"
+       depends on INET && EXPERIMENTAL
        depends on IPV6 || IPV6=n
        select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
        select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
@@ -36,9 +34,10 @@ config IP_SCTP
 
          If in doubt, say N.
 
+if IP_SCTP
+
 config SCTP_DBG_MSG
        bool "SCTP: Debug messages"
-       depends on IP_SCTP
        help
          If you say Y, this will enable verbose debugging messages. 
 
@@ -47,7 +46,6 @@ config SCTP_DBG_MSG
 
 config SCTP_DBG_OBJCNT
        bool "SCTP: Debug object counts"
-       depends on IP_SCTP
        help
          If you say Y, this will enable debugging support for counting the 
          type of objects that are currently allocated.  This is useful for 
@@ -59,7 +57,6 @@ config SCTP_DBG_OBJCNT
 
 choice
        prompt "SCTP: Cookie HMAC Algorithm"
-       depends on IP_SCTP
        default SCTP_HMAC_MD5
        help
          HMAC algorithm to be used during association initialization.  It
@@ -86,4 +83,5 @@ config SCTP_HMAC_MD5
          advised to use either HMAC-MD5 or HMAC-SHA1.
 
 endchoice
-endmenu
+
+endif # IP_SCTP
index e8c0f7435d7f68be0eefd21b1baac4f1a05b1636..80f70aa533867317e5dcbdbadc7333d29c519901 100644 (file)
@@ -77,8 +77,6 @@ static const char *sctp_cid_tbl[SCTP_NUM_BASE_CHUNK_TYPES] = {
 /* Lookup "chunk type" debug name. */
 const char *sctp_cname(const sctp_subtype_t cid)
 {
-       if (cid.chunk < 0)
-               return "illegal chunk id";
        if (cid.chunk <= SCTP_CID_BASE_MAX)
                return sctp_cid_tbl[cid.chunk];
 
@@ -146,8 +144,6 @@ static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = {
 /* Lookup primitive debug name. */
 const char *sctp_pname(const sctp_subtype_t id)
 {
-       if (id.primitive < 0)
-               return "illegal primitive";
        if (id.primitive <= SCTP_EVENT_PRIMITIVE_MAX)
                return sctp_primitive_tbl[id.primitive];
        return "unknown_primitive";
@@ -161,8 +157,6 @@ static const char *sctp_other_tbl[] = {
 /* Lookup "other" debug name. */
 const char *sctp_oname(const sctp_subtype_t id)
 {
-       if (id.other < 0)
-               return "illegal 'other' event";
        if (id.other <= SCTP_EVENT_OTHER_MAX)
                return sctp_other_tbl[id.other];
        return "unknown 'other' event";
@@ -184,8 +178,6 @@ static const char *sctp_timer_tbl[] = {
 /* Lookup timer debug name. */
 const char *sctp_tname(const sctp_subtype_t id)
 {
-       if (id.timeout < 0)
-               return "illegal 'timer' event";
        if (id.timeout <= SCTP_EVENT_TIMEOUT_MAX)
                return sctp_timer_tbl[id.timeout];
        return "unknown_timer";
index 523071c7902fbb5a163f1418c17e85fcb0d4f503..70a91ece3c49444de91b41b7db7f4b486a16e7de 100644 (file)
@@ -960,7 +960,7 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
        if (state > SCTP_STATE_MAX)
                return &bug;
 
-       if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
+       if (cid <= SCTP_CID_BASE_MAX)
                return &chunk_event_table[cid][state];
 
        if (sctp_prsctp_enable) {
index f9e367d946eb69ec22d06662168a5e173ea678ae..3b30d1130b615fa75db3d2f4a5f8d308cff21164 100644 (file)
@@ -2,11 +2,9 @@
 # TIPC configuration
 #
 
-menu "TIPC Configuration (EXPERIMENTAL)"
-       depends on INET && EXPERIMENTAL
-
-config TIPC
+menuconfig TIPC
        tristate "The TIPC Protocol (EXPERIMENTAL)"
+       depends on INET && EXPERIMENTAL
        ---help---
          The Transparent Inter Process Communication (TIPC) protocol is
          specially designed for intra cluster communication. This protocol
@@ -22,9 +20,10 @@ config TIPC
 
          If in doubt, say N.
 
+if TIPC
+
 config TIPC_ADVANCED
        bool "TIPC: Advanced configuration"
-       depends on TIPC
        default n
        help
          Saying Y here will open some advanced configuration
@@ -33,7 +32,7 @@ config TIPC_ADVANCED
 
 config TIPC_ZONES
        int "Maximum number of zones in network"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default "3"
        help
         Max number of zones inside TIPC network. Max supported value 
@@ -44,7 +43,7 @@ config TIPC_ZONES
 
 config TIPC_CLUSTERS
        int "Maximum number of clusters in a zone"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default "1"
        help
           ***Only 1 (one cluster in a zone) is supported by current code.
@@ -59,7 +58,7 @@ config TIPC_CLUSTERS
 
 config TIPC_NODES
        int "Maximum number of nodes in cluster"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default "255"
        help
          Maximum number of nodes inside a TIPC cluster. Maximum 
@@ -70,7 +69,7 @@ config TIPC_NODES
 
 config TIPC_SLAVE_NODES
        int "Maximum number of slave nodes in cluster"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default "0"
        help
           ***This capability is not supported by current code.***
@@ -83,7 +82,7 @@ config TIPC_SLAVE_NODES
 
 config TIPC_PORTS
        int "Maximum number of ports in a node"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default "8191"
        help
          Maximum number of ports within a node. Maximum 
@@ -94,7 +93,7 @@ config TIPC_PORTS
 
 config TIPC_LOG
        int "Size of log buffer"
-       depends on TIPC && TIPC_ADVANCED
+       depends on TIPC_ADVANCED
        default 0
        help
          Size (in bytes) of TIPC's internal log buffer, which records the
@@ -106,7 +105,6 @@ config TIPC_LOG
 
 config TIPC_DEBUG
        bool "Enable debugging support"
-       depends on TIPC
        default n
        help
          This will enable debugging of TIPC.
@@ -114,4 +112,4 @@ config TIPC_DEBUG
          Only say Y here if you are having trouble with TIPC.  It will
          enable the display of detailed information about what is going on.
 
-endmenu
+endif # TIPC
index 0ee6ded18f3a503a99ed08c4a11cd110f8a719c2..77d2d9ce896248822562843b96d3bb7e53574413 100644 (file)
@@ -120,18 +120,20 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
 
 static int enable_bearer(struct tipc_bearer *tb_ptr)
 {
-       struct net_device *dev, *pdev;
+       struct net_device *dev = NULL;
+       struct net_device *pdev = NULL;
        struct eth_bearer *eb_ptr = &eth_bearers[0];
        struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
        char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
 
        /* Find device with specified name */
-       dev = NULL;
-       for_each_netdev(pdev)
-               if (!strncmp(dev->name, driver_name, IFNAMSIZ)) {
+
+       for_each_netdev(pdev){
+               if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
                        dev = pdev;
                        break;
                }
+       }
        if (!dev)
                return -ENODEV;
 
index fc12ba51c1fc8223672c744e2c3eb06239741303..d70fa30d4294383f4cbdc45feec8a1df90f65a2b 100644 (file)
@@ -174,11 +174,11 @@ static struct sock *unix_peer_get(struct sock *s)
 {
        struct sock *peer;
 
-       unix_state_rlock(s);
+       unix_state_lock(s);
        peer = unix_peer(s);
        if (peer)
                sock_hold(peer);
-       unix_state_runlock(s);
+       unix_state_unlock(s);
        return peer;
 }
 
@@ -369,7 +369,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
        unix_remove_socket(sk);
 
        /* Clear state */
-       unix_state_wlock(sk);
+       unix_state_lock(sk);
        sock_orphan(sk);
        sk->sk_shutdown = SHUTDOWN_MASK;
        dentry       = u->dentry;
@@ -378,7 +378,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
        u->mnt       = NULL;
        state = sk->sk_state;
        sk->sk_state = TCP_CLOSE;
-       unix_state_wunlock(sk);
+       unix_state_unlock(sk);
 
        wake_up_interruptible_all(&u->peer_wait);
 
@@ -386,12 +386,12 @@ static int unix_release_sock (struct sock *sk, int embrion)
 
        if (skpair!=NULL) {
                if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
-                       unix_state_wlock(skpair);
+                       unix_state_lock(skpair);
                        /* No more writes */
                        skpair->sk_shutdown = SHUTDOWN_MASK;
                        if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
                                skpair->sk_err = ECONNRESET;
-                       unix_state_wunlock(skpair);
+                       unix_state_unlock(skpair);
                        skpair->sk_state_change(skpair);
                        read_lock(&skpair->sk_callback_lock);
                        sk_wake_async(skpair,1,POLL_HUP);
@@ -448,7 +448,7 @@ static int unix_listen(struct socket *sock, int backlog)
        err = -EINVAL;
        if (!u->addr)
                goto out;                       /* No listens on an unbound socket */
-       unix_state_wlock(sk);
+       unix_state_lock(sk);
        if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
                goto out_unlock;
        if (backlog > sk->sk_max_ack_backlog)
@@ -462,7 +462,7 @@ static int unix_listen(struct socket *sock, int backlog)
        err = 0;
 
 out_unlock:
-       unix_state_wunlock(sk);
+       unix_state_unlock(sk);
 out:
        return err;
 }
@@ -858,6 +858,31 @@ out_mknod_parent:
        goto out_up;
 }
 
+static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
+{
+       if (unlikely(sk1 == sk2) || !sk2) {
+               unix_state_lock(sk1);
+               return;
+       }
+       if (sk1 < sk2) {
+               unix_state_lock(sk1);
+               unix_state_lock_nested(sk2);
+       } else {
+               unix_state_lock(sk2);
+               unix_state_lock_nested(sk1);
+       }
+}
+
+static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
+{
+       if (unlikely(sk1 == sk2) || !sk2) {
+               unix_state_unlock(sk1);
+               return;
+       }
+       unix_state_unlock(sk1);
+       unix_state_unlock(sk2);
+}
+
 static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                              int alen, int flags)
 {
@@ -877,11 +902,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                    !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
                        goto out;
 
+restart:
                other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
                if (!other)
                        goto out;
 
-               unix_state_wlock(sk);
+               unix_state_double_lock(sk, other);
+
+               /* Apparently VFS overslept socket death. Retry. */
+               if (sock_flag(other, SOCK_DEAD)) {
+                       unix_state_double_unlock(sk, other);
+                       sock_put(other);
+                       goto restart;
+               }
 
                err = -EPERM;
                if (!unix_may_send(sk, other))
@@ -896,7 +929,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                 *      1003.1g breaking connected state with AF_UNSPEC
                 */
                other = NULL;
-               unix_state_wlock(sk);
+               unix_state_double_lock(sk, other);
        }
 
        /*
@@ -905,19 +938,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
        if (unix_peer(sk)) {
                struct sock *old_peer = unix_peer(sk);
                unix_peer(sk)=other;
-               unix_state_wunlock(sk);
+               unix_state_double_unlock(sk, other);
 
                if (other != old_peer)
                        unix_dgram_disconnected(sk, old_peer);
                sock_put(old_peer);
        } else {
                unix_peer(sk)=other;
-               unix_state_wunlock(sk);
+               unix_state_double_unlock(sk, other);
        }
        return 0;
 
 out_unlock:
-       unix_state_wunlock(sk);
+       unix_state_double_unlock(sk, other);
        sock_put(other);
 out:
        return err;
@@ -936,7 +969,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
                (skb_queue_len(&other->sk_receive_queue) >
                 other->sk_max_ack_backlog);
 
-       unix_state_runlock(other);
+       unix_state_unlock(other);
 
        if (sched)
                timeo = schedule_timeout(timeo);
@@ -994,11 +1027,11 @@ restart:
                goto out;
 
        /* Latch state of peer */
-       unix_state_rlock(other);
+       unix_state_lock(other);
 
        /* Apparently VFS overslept socket death. Retry. */
        if (sock_flag(other, SOCK_DEAD)) {
-               unix_state_runlock(other);
+               unix_state_unlock(other);
                sock_put(other);
                goto restart;
        }
@@ -1048,18 +1081,18 @@ restart:
                goto out_unlock;
        }
 
-       unix_state_wlock_nested(sk);
+       unix_state_lock_nested(sk);
 
        if (sk->sk_state != st) {
-               unix_state_wunlock(sk);
-               unix_state_runlock(other);
+               unix_state_unlock(sk);
+               unix_state_unlock(other);
                sock_put(other);
                goto restart;
        }
 
        err = security_unix_stream_connect(sock, other->sk_socket, newsk);
        if (err) {
-               unix_state_wunlock(sk);
+               unix_state_unlock(sk);
                goto out_unlock;
        }
 
@@ -1096,7 +1129,7 @@ restart:
        smp_mb__after_atomic_inc();     /* sock_hold() does an atomic_inc() */
        unix_peer(sk)   = newsk;
 
-       unix_state_wunlock(sk);
+       unix_state_unlock(sk);
 
        /* take ten and and send info to listening sock */
        spin_lock(&other->sk_receive_queue.lock);
@@ -1105,14 +1138,14 @@ restart:
         * is installed to listening socket. */
        atomic_inc(&newu->inflight);
        spin_unlock(&other->sk_receive_queue.lock);
-       unix_state_runlock(other);
+       unix_state_unlock(other);
        other->sk_data_ready(other, 0);
        sock_put(other);
        return 0;
 
 out_unlock:
        if (other)
-               unix_state_runlock(other);
+               unix_state_unlock(other);
 
 out:
        if (skb)
@@ -1178,10 +1211,10 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
        wake_up_interruptible(&unix_sk(sk)->peer_wait);
 
        /* attach accepted sock to socket */
-       unix_state_wlock(tsk);
+       unix_state_lock(tsk);
        newsock->state = SS_CONNECTED;
        sock_graft(tsk, newsock);
-       unix_state_wunlock(tsk);
+       unix_state_unlock(tsk);
        return 0;
 
 out:
@@ -1208,7 +1241,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
        }
 
        u = unix_sk(sk);
-       unix_state_rlock(sk);
+       unix_state_lock(sk);
        if (!u->addr) {
                sunaddr->sun_family = AF_UNIX;
                sunaddr->sun_path[0] = 0;
@@ -1219,7 +1252,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
                *uaddr_len = addr->len;
                memcpy(sunaddr, addr->name, *uaddr_len);
        }
-       unix_state_runlock(sk);
+       unix_state_unlock(sk);
        sock_put(sk);
 out:
        return err;
@@ -1337,7 +1370,7 @@ restart:
                        goto out_free;
        }
 
-       unix_state_rlock(other);
+       unix_state_lock(other);
        err = -EPERM;
        if (!unix_may_send(sk, other))
                goto out_unlock;
@@ -1347,20 +1380,20 @@ restart:
                 *      Check with 1003.1g - what should
                 *      datagram error
                 */
-               unix_state_runlock(other);
+               unix_state_unlock(other);
                sock_put(other);
 
                err = 0;
-               unix_state_wlock(sk);
+               unix_state_lock(sk);
                if (unix_peer(sk) == other) {
                        unix_peer(sk)=NULL;
-                       unix_state_wunlock(sk);
+                       unix_state_unlock(sk);
 
                        unix_dgram_disconnected(sk, other);
                        sock_put(other);
                        err = -ECONNREFUSED;
                } else {
-                       unix_state_wunlock(sk);
+                       unix_state_unlock(sk);
                }
 
                other = NULL;
@@ -1397,14 +1430,14 @@ restart:
        }
 
        skb_queue_tail(&other->sk_receive_queue, skb);
-       unix_state_runlock(other);
+       unix_state_unlock(other);
        other->sk_data_ready(other, len);
        sock_put(other);
        scm_destroy(siocb->scm);
        return len;
 
 out_unlock:
-       unix_state_runlock(other);
+       unix_state_unlock(other);
 out_free:
        kfree_skb(skb);
 out:
@@ -1494,14 +1527,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        goto out_err;
                }
 
-               unix_state_rlock(other);
+               unix_state_lock(other);
 
                if (sock_flag(other, SOCK_DEAD) ||
                    (other->sk_shutdown & RCV_SHUTDOWN))
                        goto pipe_err_free;
 
                skb_queue_tail(&other->sk_receive_queue, skb);
-               unix_state_runlock(other);
+               unix_state_unlock(other);
                other->sk_data_ready(other, size);
                sent+=size;
        }
@@ -1512,7 +1545,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        return sent;
 
 pipe_err_free:
-       unix_state_runlock(other);
+       unix_state_unlock(other);
        kfree_skb(skb);
 pipe_err:
        if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL))
@@ -1641,7 +1674,7 @@ static long unix_stream_data_wait(struct sock * sk, long timeo)
 {
        DEFINE_WAIT(wait);
 
-       unix_state_rlock(sk);
+       unix_state_lock(sk);
 
        for (;;) {
                prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
@@ -1654,14 +1687,14 @@ static long unix_stream_data_wait(struct sock * sk, long timeo)
                        break;
 
                set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-               unix_state_runlock(sk);
+               unix_state_unlock(sk);
                timeo = schedule_timeout(timeo);
-               unix_state_rlock(sk);
+               unix_state_lock(sk);
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
        }
 
        finish_wait(sk->sk_sleep, &wait);
-       unix_state_runlock(sk);
+       unix_state_unlock(sk);
        return timeo;
 }
 
@@ -1711,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                int chunk;
                struct sk_buff *skb;
 
+               unix_state_lock(sk);
                skb = skb_dequeue(&sk->sk_receive_queue);
                if (skb==NULL)
                {
                        if (copied >= target)
-                               break;
+                               goto unlock;
 
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
 
                        if ((err = sock_error(sk)) != 0)
-                               break;
+                               goto unlock;
                        if (sk->sk_shutdown & RCV_SHUTDOWN)
-                               break;
+                               goto unlock;
+
+                       unix_state_unlock(sk);
                        err = -EAGAIN;
                        if (!timeo)
                                break;
@@ -1738,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                        }
                        mutex_lock(&u->readlock);
                        continue;
+ unlock:
+                       unix_state_unlock(sk);
+                       break;
                }
+               unix_state_unlock(sk);
 
                if (check_creds) {
                        /* Never glue messages from different writers */
@@ -1816,12 +1856,12 @@ static int unix_shutdown(struct socket *sock, int mode)
        mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
 
        if (mode) {
-               unix_state_wlock(sk);
+               unix_state_lock(sk);
                sk->sk_shutdown |= mode;
                other=unix_peer(sk);
                if (other)
                        sock_hold(other);
-               unix_state_wunlock(sk);
+               unix_state_unlock(sk);
                sk->sk_state_change(sk);
 
                if (other &&
@@ -1833,9 +1873,9 @@ static int unix_shutdown(struct socket *sock, int mode)
                                peer_mode |= SEND_SHUTDOWN;
                        if (mode&SEND_SHUTDOWN)
                                peer_mode |= RCV_SHUTDOWN;
-                       unix_state_wlock(other);
+                       unix_state_lock(other);
                        other->sk_shutdown |= peer_mode;
-                       unix_state_wunlock(other);
+                       unix_state_unlock(other);
                        other->sk_state_change(other);
                        read_lock(&other->sk_callback_lock);
                        if (peer_mode == SHUTDOWN_MASK)
@@ -1973,7 +2013,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
        else {
                struct sock *s = v;
                struct unix_sock *u = unix_sk(s);
-               unix_state_rlock(s);
+               unix_state_lock(s);
 
                seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
                        s,
@@ -2001,7 +2041,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
                        for ( ; i < len; i++)
                                seq_putc(seq, u->addr->name->sun_path[i]);
                }
-               unix_state_runlock(s);
+               unix_state_unlock(s);
                seq_putc(seq, '\n');
        }
 
index 7a19e0ede2891238b910ecae4f416cfd6c6b49a7..849cc06bd9141a62da44061a230e7bc70c472761 100644 (file)
@@ -454,7 +454,7 @@ static int wanrouter_device_setup(struct wan_device *wandev,
        }
 
        if (conf->data_size && conf->data) {
-               if (conf->data_size > 128000 || conf->data_size < 0) {
+               if (conf->data_size > 128000) {
                        printk(KERN_INFO
                            "%s: ERROR, Invalid firmware data size %i !\n",
                                        wandev->name, conf->data_size);
index 8a72def25a3479f5807e31f014aecdb48fdf4d68..5ced62c19c63e1d0a31d308ba7964229a7d2da5a 100644 (file)
@@ -407,27 +407,27 @@ static struct xfrm_algo_desc *xfrm_find_algo(
 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
                             const void *data)
 {
-       return entry->desc.sadb_alg_id == (int)data;
+       return entry->desc.sadb_alg_id == (unsigned long)data;
 }
 
 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
 {
        return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
-                             (void *)alg_id, 1);
+                             (void *)(unsigned long)alg_id, 1);
 }
 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
 
 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
 {
        return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
-                             (void *)alg_id, 1);
+                             (void *)(unsigned long)alg_id, 1);
 }
 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
 
 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
 {
        return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
-                             (void *)alg_id, 1);
+                             (void *)(unsigned long)alg_id, 1);
 }
 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
 
index d0882e53b6fced18c5a4f2ef4b87b38c2a0716c7..157bfbd250ba62f2c451805106b25a1f13b581bf 100644 (file)
 #include <net/xfrm.h>
 #include <net/ip.h>
 #include <linux/audit.h>
+#include <linux/cache.h>
 
 #include "xfrm_hash.h"
 
+int sysctl_xfrm_larval_drop __read_mostly;
+
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -831,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 }
 EXPORT_SYMBOL(xfrm_policy_byid);
 
-void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int
+xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 {
-       int dir;
+       int dir, err = 0;
+
+       for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
+               struct xfrm_policy *pol;
+               struct hlist_node *entry;
+               int i;
+
+               hlist_for_each_entry(pol, entry,
+                                    &xfrm_policy_inexact[dir], bydst) {
+                       if (pol->type != type)
+                               continue;
+                       err = security_xfrm_policy_delete(pol);
+                       if (err) {
+                               xfrm_audit_log(audit_info->loginuid,
+                                              audit_info->secid,
+                                              AUDIT_MAC_IPSEC_DELSPD, 0,
+                                              pol, NULL);
+                               return err;
+                       }
+                }
+               for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
+                       hlist_for_each_entry(pol, entry,
+                                            xfrm_policy_bydst[dir].table + i,
+                                            bydst) {
+                               if (pol->type != type)
+                                       continue;
+                               err = security_xfrm_policy_delete(pol);
+                               if (err) {
+                                       xfrm_audit_log(audit_info->loginuid,
+                                                      audit_info->secid,
+                                                      AUDIT_MAC_IPSEC_DELSPD,
+                                                      0, pol, NULL);
+                                       return err;
+                               }
+                       }
+               }
+       }
+       return err;
+}
+#else
+static inline int
+xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
+{
+       return 0;
+}
+#endif
+
+int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
+{
+       int dir, err = 0;
 
        write_lock_bh(&xfrm_policy_lock);
+
+       err = xfrm_policy_flush_secctx_check(type, audit_info);
+       if (err)
+               goto out;
+
        for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
                struct xfrm_policy *pol;
                struct hlist_node *entry;
@@ -888,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
                xfrm_policy_count[dir] -= killed;
        }
        atomic_inc(&flow_cache_genid);
+out:
        write_unlock_bh(&xfrm_policy_lock);
+       return err;
 }
 EXPORT_SYMBOL(xfrm_policy_flush);
 
@@ -1390,8 +1451,8 @@ static int stale_bundle(struct dst_entry *dst);
  * At the moment we eat a raw IP route. Mostly to speed up lookups
  * on interfaces with disabled IPsec.
  */
-int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
-               struct sock *sk, int flags)
+int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+                 struct sock *sk, int flags)
 {
        struct xfrm_policy *policy;
        struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
@@ -1509,6 +1570,13 @@ restart:
 
                if (unlikely(nx<0)) {
                        err = nx;
+                       if (err == -EAGAIN && sysctl_xfrm_larval_drop) {
+                               /* EREMOTE tells the caller to generate
+                                * a one-shot blackhole route.
+                                */
+                               xfrm_pol_put(policy);
+                               return -EREMOTE;
+                       }
                        if (err == -EAGAIN && flags) {
                                DECLARE_WAITQUEUE(wait, current);
 
@@ -1598,6 +1666,21 @@ error:
        *dst_p = NULL;
        return err;
 }
+EXPORT_SYMBOL(__xfrm_lookup);
+
+int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+               struct sock *sk, int flags)
+{
+       int err = __xfrm_lookup(dst_p, fl, sk, flags);
+
+       if (err == -EREMOTE) {
+               dst_release(*dst_p);
+               *dst_p = NULL;
+               err = -EAGAIN;
+       }
+
+       return err;
+}
 EXPORT_SYMBOL(xfrm_lookup);
 
 static inline int
@@ -2558,4 +2641,3 @@ restore_state:
 }
 EXPORT_SYMBOL(xfrm_migrate);
 #endif
-
index 9955ff4da0a2a304e708c5622381ff991c739c5b..85f3f43a6cca402a3339aa4ef8317d7b41eaaa00 100644 (file)
 #include <linux/cache.h>
 #include <asm/uaccess.h>
 #include <linux/audit.h>
+#include <linux/cache.h>
 
 #include "xfrm_hash.h"
 
 struct sock *xfrm_nl;
 EXPORT_SYMBOL(xfrm_nl);
 
-u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
+u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
 EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
 
-u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
+u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
 EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
 
+u32 sysctl_xfrm_acq_expires __read_mostly = 30;
+
 /* Each xfrm_state may be linked to two tables:
 
    1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
@@ -388,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x)
 }
 EXPORT_SYMBOL(xfrm_state_delete);
 
-void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
 {
-       int i;
-       int err = 0;
+       int i, err = 0;
+
+       for (i = 0; i <= xfrm_state_hmask; i++) {
+               struct hlist_node *entry;
+               struct xfrm_state *x;
+
+               hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+                       if (xfrm_id_proto_match(x->id.proto, proto) &&
+                          (err = security_xfrm_state_delete(x)) != 0) {
+                               xfrm_audit_log(audit_info->loginuid,
+                                              audit_info->secid,
+                                              AUDIT_MAC_IPSEC_DELSA,
+                                               0, NULL, x);
+
+                               return err;
+                       }
+               }
+       }
+
+       return err;
+}
+#else
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
+{
+       return 0;
+}
+#endif
+
+int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+{
+       int i, err = 0;
 
        spin_lock_bh(&xfrm_state_lock);
+       err = xfrm_state_flush_secctx_check(proto, audit_info);
+       if (err)
+               goto out;
+
        for (i = 0; i <= xfrm_state_hmask; i++) {
                struct hlist_node *entry;
                struct xfrm_state *x;
@@ -416,8 +455,12 @@ restart:
                        }
                }
        }
+       err = 0;
+
+out:
        spin_unlock_bh(&xfrm_state_lock);
        wake_up(&km_waitq);
+       return err;
 }
 EXPORT_SYMBOL(xfrm_state_flush);
 
@@ -622,8 +665,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                                h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
                                hlist_add_head(&x->byspi, xfrm_state_byspi+h);
                        }
-                       x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
-                       x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+                       x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
+                       x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
                        add_timer(&x->timer);
                        xfrm_state_num++;
                        xfrm_hash_grow_check(x->bydst.next != NULL);
@@ -772,9 +815,9 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
                x->props.family = family;
                x->props.mode = mode;
                x->props.reqid = reqid;
-               x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+               x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
                xfrm_state_hold(x);
-               x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+               x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
                add_timer(&x->timer);
                hlist_add_head(&x->bydst, xfrm_state_bydst+h);
                h = xfrm_src_hash(daddr, saddr, family);
index b14c7e590c31b8e5898ba2f389f7accbe17ec853..c06883bf620ee21fa896654847fc4ee85f445e33 100644 (file)
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct km_event c;
        struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
        struct xfrm_audit audit_info;
+       int err;
 
        audit_info.loginuid = NETLINK_CB(skb).loginuid;
        audit_info.secid = NETLINK_CB(skb).sid;
-       xfrm_state_flush(p->proto, &audit_info);
+       err = xfrm_state_flush(p->proto, &audit_info);
+       if (err)
+               return err;
        c.data.proto = p->proto;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        audit_info.loginuid = NETLINK_CB(skb).loginuid;
        audit_info.secid = NETLINK_CB(skb).sid;
-       xfrm_policy_flush(type, &audit_info);
+       err = xfrm_policy_flush(type, &audit_info);
+       if (err)
+               return err;
        c.data.type = type;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
new file mode 100755 (executable)
index 0000000..aea90d3
--- /dev/null
@@ -0,0 +1,868 @@
+#!/usr/bin/perl -w
+# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
+# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
+# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
+# Licensed under the terms of the GNU GPL License version 2
+
+use strict;
+
+my $P = $0;
+$P =~ s@.*/@@g;
+
+my $V = '0.04';
+
+use Getopt::Long qw(:config no_auto_abbrev);
+
+my $quiet = 0;
+my $tree = 1;
+my $chk_signoff = 1;
+my $chk_patch = 1;
+GetOptions(
+       'q|quiet'       => \$quiet,
+       'tree!'         => \$tree,
+       'signoff!'      => \$chk_signoff,
+       'patch!'        => \$chk_patch,
+) or exit;
+
+my $exit = 0;
+
+if ($#ARGV < 0) {
+       print "usage: $P [options] patchfile\n";
+       print "version: $V\n";
+       print "options: -q           => quiet\n";
+       print "         --no-tree    => run without a kernel tree\n";
+       exit(1);
+}
+
+if ($tree && !top_of_kernel_tree()) {
+       print "Must be run from the top-level dir. of a kernel tree\n";
+       exit(2);
+}
+
+my @dep_includes = ();
+my @dep_functions = ();
+my $removal = 'Documentation/feature-removal-schedule.txt';
+if ($tree && -f $removal) {
+       open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n";
+       while (<REMOVE>) {
+               if (/^Files:\s+(.*\S)/) {
+                       for my $file (split(/[, ]+/, $1)) {
+                               if ($file =~ m@include/(.*)@) {
+                                       push(@dep_includes, $1);
+                               }
+                       }
+
+               } elsif (/^Funcs:\s+(.*\S)/) {
+                       for my $func (split(/[, ]+/, $1)) {
+                               push(@dep_functions, $func);
+                       }
+               }
+       }
+}
+
+my @rawlines = ();
+while (<>) {
+       chomp;
+       push(@rawlines, $_);
+       if (eof(ARGV)) {
+               if (!process($ARGV, @rawlines)) {
+                       $exit = 1;
+               }
+               @rawlines = ();
+       }
+}
+
+exit($exit);
+
+sub top_of_kernel_tree {
+       if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") &&
+           (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") &&
+           (-d "Documentation") && (-d "arch") && (-d "include") &&
+           (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") &&
+           (-d "kernel") && (-d "lib") && (-d "scripts")) {
+               return 1;
+       }
+       return 0;
+}
+
+sub expand_tabs {
+       my ($str) = @_;
+
+       my $res = '';
+       my $n = 0;
+       for my $c (split(//, $str)) {
+               if ($c eq "\t") {
+                       $res .= ' ';
+                       $n++;
+                       for (; ($n % 8) != 0; $n++) {
+                               $res .= ' ';
+                       }
+                       next;
+               }
+               $res .= $c;
+               $n++;
+       }
+
+       return $res;
+}
+
+sub line_stats {
+       my ($line) = @_;
+
+       # Drop the diff line leader and expand tabs
+       $line =~ s/^.//;
+       $line = expand_tabs($line);
+
+       # Pick the indent from the front of the line.
+       my ($white) = ($line =~ /^(\s*)/);
+
+       return (length($line), length($white));
+}
+
+sub sanitise_line {
+       my ($line) = @_;
+
+       my $res = '';
+       my $l = '';
+
+       my $quote = '';
+
+       foreach my $c (split(//, $line)) {
+               if ($l ne "\\" && ($c eq "'" || $c eq '"')) {
+                       if ($quote eq '') {
+                               $quote = $c;
+                               $res .= $c;
+                               $l = $c;
+                               next;
+                       } elsif ($quote eq $c) {
+                               $quote = '';
+                       }
+               }
+               if ($quote && $c ne "\t") {
+                       $res .= "X";
+               } else {
+                       $res .= $c;
+               }
+
+               $l = $c;
+       }
+
+       return $res;
+}
+
+sub ctx_block_get {
+       my ($linenr, $remain, $outer) = @_;
+       my $line;
+       my $start = $linenr - 1;
+       my $blk = '';
+       my @o;
+       my @c;
+       my @res = ();
+
+       for ($line = $start; $remain > 0; $line++) {
+               next if ($rawlines[$line] =~ /^-/);
+               $remain--;
+
+               $blk .= $rawlines[$line];
+
+               @o = ($blk =~ /\{/g);
+               @c = ($blk =~ /\}/g);
+
+               if (!$outer || (scalar(@o) - scalar(@c)) == 1) {
+                       push(@res, $rawlines[$line]);
+               }
+
+               last if (scalar(@o) == scalar(@c));
+       }
+
+       return @res;
+}
+sub ctx_block_outer {
+       my ($linenr, $remain) = @_;
+
+       return ctx_block_get($linenr, $remain, 1);
+}
+sub ctx_block {
+       my ($linenr, $remain) = @_;
+
+       return ctx_block_get($linenr, $remain, 0);
+}
+
+sub ctx_locate_comment {
+       my ($first_line, $end_line) = @_;
+
+       # Catch a comment on the end of the line itself.
+       my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@);
+       return $current_comment if (defined $current_comment);
+
+       # Look through the context and try and figure out if there is a
+       # comment.
+       my $in_comment = 0;
+       $current_comment = '';
+       for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
+               my $line = $rawlines[$linenr - 1];
+               #warn "           $line\n";
+               if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
+                       $in_comment = 1;
+               }
+               if ($line =~ m@/\*@) {
+                       $in_comment = 1;
+               }
+               if (!$in_comment && $current_comment ne '') {
+                       $current_comment = '';
+               }
+               $current_comment .= $line . "\n" if ($in_comment);
+               if ($line =~ m@\*/@) {
+                       $in_comment = 0;
+               }
+       }
+
+       chomp($current_comment);
+       return($current_comment);
+}
+sub ctx_has_comment {
+       my ($first_line, $end_line) = @_;
+       my $cmt = ctx_locate_comment($first_line, $end_line);
+
+       ##print "LINE: $rawlines[$end_line - 1 ]\n";
+       ##print "CMMT: $cmt\n";
+
+       return ($cmt ne '');
+}
+
+sub cat_vet {
+       my ($vet) = @_;
+
+       $vet =~ s/\t/^I/;
+       $vet =~ s/$/\$/;
+
+       return $vet;
+}
+
+sub process {
+       my $filename = shift;
+       my @lines = @_;
+
+       my $linenr=0;
+       my $prevline="";
+       my $stashline="";
+
+       my $length;
+       my $indent;
+       my $previndent=0;
+       my $stashindent=0;
+
+       my $clean = 1;
+       my $signoff = 0;
+       my $is_patch = 0;
+
+       # Trace the real file/line as we go.
+       my $realfile = '';
+       my $realline = 0;
+       my $realcnt = 0;
+       my $here = '';
+       my $in_comment = 0;
+       my $first_line = 0;
+
+       foreach my $line (@lines) {
+               $linenr++;
+
+#extract the filename as it passes
+               if ($line=~/^\+\+\+\s+(\S+)/) {
+                       $realfile=$1;
+                       $realfile =~ s@^[^/]*/@@;
+                       $in_comment = 0;
+                       next;
+               }
+#extract the line range in the file after the patch is applied
+               if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) {
+                       $is_patch = 1;
+                       $first_line = $linenr + 1;
+                       $in_comment = 0;
+                       $realline=$1-1;
+                       if (defined $2) {
+                               $realcnt=$3+1;
+                       } else {
+                               $realcnt=1+1;
+                       }
+                       next;
+               }
+
+# track the line number as we move through the hunk, note that
+# new versions of GNU diff omit the leading space on completely
+# blank context lines so we need to count that too.
+               if ($line =~ /^( |\+|$)/) {
+                       $realline++;
+
+                       # track any sort of multi-line comment.  Obviously if
+                       # the added text or context do not include the whole
+                       # comment we will not see it. Such is life.
+                       #
+                       # Guestimate if this is a continuing comment.  If this
+                       # is the start of a diff block and this line starts
+                       # ' *' then it is very likely a comment.
+                       if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
+                               $in_comment = 1;
+                       }
+                       if ($line =~ m@/\*@) {
+                               $in_comment = 1;
+                       }
+                       if ($line =~ m@\*/@) {
+                               $in_comment = 0;
+                       }
+
+                       # Measure the line length and indent.
+                       ($length, $indent) = line_stats($line);
+
+                       # Track the previous line.
+                       ($prevline, $stashline) = ($stashline, $line);
+                       ($previndent, $stashindent) = ($stashindent, $indent);
+               }
+               $realcnt-- if ($realcnt != 0);
+
+#make up the handle for any error we report on this line
+               $here = "#$linenr: ";
+               $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
+
+               my $hereline = "$here\n$line\n";
+               my $herecurr = "$here\n$line\n\n";
+               my $hereprev = "$here\n$prevline\n$line\n\n";
+
+#check the patch for a signoff:
+               if ($line =~ /^\s*Signed-off-by:\s/) {
+                       $signoff++;
+
+               } elsif ($line =~ /^\s*signed-off-by:/i) {
+                       # This is a signoff, if ugly, so do not double report.
+                       $signoff++;
+                       if (!($line =~ /^\s*Signed-off-by:/)) {
+                               print "use Signed-off-by:\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+                       if ($line =~ /^\s*signed-off-by:\S/i) {
+                               print "need space after Signed-off-by:\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+
+# Check for wrappage within a valid hunk of the file
+               if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) {
+                       print "patch seems to be corrupt (line wrapped?) [$realcnt]\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+#ignore lines being removed
+               if ($line=~/^-/) {next;}
+
+# check we are in a valid source file if not then ignore this hunk
+               next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+
+#trailing whitespace
+               if ($line=~/\+.*\S\s+$/) {
+                       my $herevet = "$here\n" . cat_vet($line) . "\n\n";
+                       print "trailing whitespace\n";
+                       print "$herevet";
+                       $clean = 0;
+               }
+#80 column limit
+               if ($line =~ /^\+/ && !($prevline=~/\/\*\*/) && $length > 80) {
+                       print "line over 80 characters\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# check we are in a valid source file *.[hc] if not then ignore this hunk
+               next if ($realfile !~ /\.[hc]$/);
+
+# at the beginning of a line any tabs must come first and anything
+# more than 8 must use tabs.
+               if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s*        \s*/) {
+                       my $herevet = "$here\n" . cat_vet($line) . "\n\n";
+                       print "use tabs not spaces\n";
+                       print "$herevet";
+                       $clean = 0;
+               }
+
+               #
+               # The rest of our checks refer specifically to C style
+               # only apply those _outside_ comments.
+               #
+               next if ($in_comment);
+
+               # Remove comments from the line before processing.
+               $line =~ s@/\*.*\*/@@g;
+               $line =~ s@/\*.*@@;
+               $line =~ s@.*\*/@@;
+
+               #
+               # Checks which may be anchored in the context.
+               #
+
+               # Check for switch () and associated case and default
+               # statements should be at the same indent.
+               if ($line=~/\bswitch\s*\(.*\)/) {
+                       my $err = '';
+                       my $sep = '';
+                       my @ctx = ctx_block_outer($linenr, $realcnt);
+                       shift(@ctx);
+                       for my $ctx (@ctx) {
+                               my ($clen, $cindent) = line_stats($ctx);
+                               if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
+                                                       $indent != $cindent) {
+                                       $err .= "$sep$ctx\n";
+                                       $sep = '';
+                               } else {
+                                       $sep = "[...]\n";
+                               }
+                       }
+                       if ($err ne '') {
+                               print "switch and case should be at the same indent\n";
+                               print "$here\n$line\n$err\n";
+                               $clean = 0;
+                       }
+               }
+
+#ignore lines not being added
+               if ($line=~/^[^\+]/) {next;}
+
+               #
+               # Checks which are anchored on the added line.
+               #
+
+# no C99 // comments
+               if ($line =~ m{//}) {
+                       print "do not use C99 // comments\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+               # Remove C99 comments.
+               $line =~ s@//.*@@;
+
+               # Standardise the strings and chars within the input
+               # to simplify matching.
+               $line = sanitise_line($line);
+
+#EXPORT_SYMBOL should immediately follow its function closing }.
+               if (($line =~ /EXPORT_SYMBOL.*\(.*\)/) ||
+                   ($line =~ /EXPORT_UNUSED_SYMBOL.*\(.*\)/)) {
+                       if (($prevline !~ /^}/) &&
+                          ($prevline !~ /^\+}/) &&
+                          ($prevline !~ /^ }/)) {
+                               print "EXPORT_SYMBOL(func); should immediately follow its function\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+
+               # check for static initialisers.
+               if ($line=~/\s*static\s.*=\s+(0|NULL);/) {
+                       print "do not initialise statics to 0 or NULL\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+               # check for new typedefs.
+               if ($line=~/\s*typedef\s/) {
+                       print "do not add new typedefs\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# * goes on variable not on type
+               my $type = '(?:char|short|int|long|unsigned|float|double|' .
+                          'struct\s+[A-Za-z\d_]+|' .
+                          'union\s+[A-Za-z\d_]+)';
+
+               if ($line =~ m{[A-Za-z\d_]+(\*+) [A-Za-z\d_]+}) {
+                       print "\"foo$1 bar\" should be \"foo $1bar\"\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+               if ($line =~ m{$type (\*) [A-Za-z\d_]+} ||
+                   $line =~ m{[A-Za-z\d_]+ (\*\*+) [A-Za-z\d_]+}) {
+                       print "\"foo $1 bar\" should be \"foo $1bar\"\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+               if ($line =~ m{\([A-Za-z\d_\s]+[A-Za-z\d_](\*+)\)}) {
+                       print "\"(foo$1)\" should be \"(foo $1)\"\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+               if ($line =~ m{\([A-Za-z\d_\s]+[A-Za-z\d_]\s+(\*+)\s+\)}) {
+                       print "\"(foo $1 )\" should be \"(foo $1)\"\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# # no BUG() or BUG_ON()
+#              if ($line =~ /\b(BUG|BUG_ON)\b/) {
+#                      print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
+#                      print "$herecurr";
+#                      $clean = 0;
+#              }
+
+# printk should use KERN_* levels.  Note that follow on printk's on the
+# same line do not need a level, so we use the current block context
+# to try and find and validate the current printk.  In summary the current
+# printk includes all preceeding printk's which have no newline on the end.
+# we assume the first bad printk is the one to report.
+               if ($line =~ /\bprintk\((?!KERN_)/) {
+                       my $ok = 0;
+                       for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
+                               #print "CHECK<$lines[$ln - 1]\n";
+                               # we have a preceeding printk if it ends
+                               # with "\n" ignore it, else it is to blame
+                               if ($lines[$ln - 1] =~ m{\bprintk\(}) {
+                                       if ($rawlines[$ln - 1] !~ m{\\n"}) {
+                                               $ok = 1;
+                                       }
+                                       last;
+                               }
+                       }
+                       if ($ok == 0) {
+                               print "printk() should include KERN_ facility level\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+
+#function brace can't be on same line, except for #defines of do while, or if closed on same line
+               if (($line=~/[A-Za-z\d_]+\**\s+\**[A-Za-z\d_]+\(.*\).* {/) and
+                   !($line=~/\#define.*do\s{/) and !($line=~/}/)) {
+                       print "braces following function declarations go on the next line\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+               # Note we expand the line with the leading + as the real
+               # line will be displayed with the leading + and the tabs
+               # will therefore also expand that way.
+               my $opline = $line;
+               $opline = expand_tabs($opline);
+               $opline =~ s/^./ /;
+               if (!($line=~/\#\s*include/)) {
+                       # Check operator spacing.
+                       my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline);
+                       my $off = 0;
+                       for (my $n = 0; $n < $#elements; $n += 2) {
+                               $off += length($elements[$n]);
+
+                               my $a = '';
+                               $a = 'V' if ($elements[$n] ne '');
+                               $a = 'W' if ($elements[$n] =~ /\s$/);
+                               $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
+                               $a = 'O' if ($elements[$n] eq '');
+                               $a = 'E' if ($elements[$n] eq '' && $n == 0);
+
+                               my $op = $elements[$n + 1];
+
+                               my $c = '';
+                               if (defined $elements[$n + 2]) {
+                                       $c = 'V' if ($elements[$n + 2] ne '');
+                                       $c = 'W' if ($elements[$n + 2] =~ /^\s/);
+                                       $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
+                                       $c = 'O' if ($elements[$n + 2] eq '');
+                               } else {
+                                       $c = 'E';
+                               }
+
+                               # Pick up the preceeding and succeeding characters.
+                               my $ca = substr($opline, $off - 1, 1);
+                               my $cc = '';
+                               if (length($opline) > ($off + length($elements[$n]))) {
+                                       $cc = substr($opline, $off + 1 + length($elements[$n]), 1);
+                               }
+
+                               my $ctx = "${a}x${c}";
+
+                               my $at = "(ctx:$ctx)";
+
+                               my $ptr = (" " x $off) . "^";
+                               my $hereptr = "$hereline$ptr\n\n";
+
+                               ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n";
+
+                               # We need ; as an operator.  // is a comment.
+                               if ($op eq ';' or $op eq '//') {
+
+                               # -> should have no spaces
+                               } elsif ($op eq '->') {
+                                       if ($ctx =~ /Wx.|.xW/) {
+                                               print "no spaces around that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # , must have a space on the right.
+                               } elsif ($op eq ',') {
+                                       if ($ctx !~ /.xW|.xE/) {
+                                               print "need space after that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # unary ! and unary ~ are allowed no space on the right
+                               } elsif ($op eq '!' or $op eq '~') {
+                                       if ($ctx !~ /[WOEB]x./) {
+                                               print "need space before that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+                                       if ($ctx =~ /.xW/) {
+                                               print "no space after that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # unary ++ and unary -- are allowed no space on one side.
+                               } elsif ($op eq '++' or $op eq '--') {
+                                       if ($ctx !~ /[WOB]x[^W]|[^W]x[WOB]/) {
+                                               print "need space one side of that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # & is both unary and binary
+                               # unary:
+                               #       a &b
+                               # binary (consistent spacing):
+                               #       a&b             OK
+                               #       a & b           OK
+                               #
+                               # boiling down to: if there is a space on the right then there
+                               # should be one on the left.
+                               #
+                               # - is the same
+                               #
+                               } elsif ($op eq '&' or $op eq '-') {
+                                       if ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]/) {
+                                               print "need space before that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # * is the same as & only adding:
+                               # type:
+                               #       (foo *)
+                               #       (foo **)
+                               #
+                               } elsif ($op eq '*') {
+                                       if ($ca eq '*') {
+                                               if ($cc =~ /\s/) {
+                                                       print "no space after that '$op' $at\n";
+                                                       print "$hereptr";
+                                                       $clean = 0;
+                                               }
+                                       } elsif ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]|OxV|WxB/) {
+                                               print "need space before that '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # << and >> may either have or not have spaces both sides
+                               } elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or
+                                        $op eq '^' or $op eq '|')
+                               {
+                                       if ($ctx !~ /VxV|WxW|VxE|WxE/) {
+                                               print "need consistent spacing around '$op' $at\n";
+                                               print "$hereptr";
+                                               $clean = 0;
+                                       }
+
+                               # All the others need spaces both sides.
+                               } elsif ($ctx !~ /[EW]x[WE]/) {
+                                       print "need spaces around that '$op' $at\n";
+                                       print "$hereptr";
+                                       $clean = 0;
+                               }
+                               $off += length($elements[$n + 1]);
+                       }
+               }
+
+#need space before brace following if, while, etc
+               if ($line=~/\(.*\){/) {
+                       print "need a space before the brace\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+#goto labels aren't indented, allow a single space however
+               if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
+                  !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
+                       print "labels should not be indented\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# Need a space before open parenthesis after if, while etc
+               if ($line=~/\b(if|while|for|switch)\(/) {
+                       print "need a space before the open parenthesis\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# Check for illegal assignment in if conditional.
+               if ($line=~/\b(if|while)\s*\(.*[^<>!=]=[^=].*\)/) {
+                       #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
+                       print "do not use assignment in condition\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+               # Check for }<nl>else {, these must be at the same
+               # indent level to be relevant to each other.
+               if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
+                                               $previndent == $indent) {
+                       print "else should follow close brace\n";
+                       print "$hereprev";
+                       $clean = 0;
+               }
+
+#studly caps, commented out until figure out how to distinguish between use of existing and adding new
+#              if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
+#                  print "No studly caps, use _\n";
+#                  print "$herecurr";
+#                  $clean = 0;
+#              }
+
+#no spaces allowed after \ in define
+               if ($line=~/\#define.*\\\s$/) {
+                       print("Whitepspace after \\ makes next lines useless\n");
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+#warn if <asm/foo.h> is #included and <linux/foo.h> is available.
+               if ($tree && $line =~ qr|\s*\#\s*include\s*\<asm\/(.*)\.h\>|) {
+                       my $checkfile = "include/linux/$1.h";
+                       if (-f $checkfile) {
+                               print "Use #include <linux/$1.h> instead of <asm/$1.h>\n";
+                               print $herecurr;
+                               $clean = 0;
+                       }
+               }
+
+#if/while/etc brace do not go on next line, unless #defining a do while loop, or if that brace on the next line is for something else
+               if ($prevline=~/\b(if|while|for|switch)\s*\(/) {
+                       my @opened = $prevline=~/\(/g;
+                       my @closed = $prevline=~/\)/g;
+                       my $nr_line = $linenr;
+                       my $remaining = $realcnt - 1;
+                       my $next_line = $line;
+                       my $extra_lines = 0;
+                       my $display_segment = $prevline;
+
+                       while ($remaining > 0 && scalar @opened > scalar @closed) {
+                               $prevline .= $next_line;
+                               $display_segment .= "\n" . $next_line;
+                               $next_line = $lines[$nr_line];
+                               $nr_line++;
+                               $remaining--;
+
+                               @opened = $prevline=~/\(/g;
+                               @closed = $prevline=~/\)/g;
+                       }
+
+                       if (($prevline=~/\b(if|while|for|switch)\s*\(.*\)\s*$/) and ($next_line=~/{/) and
+                          !($next_line=~/\b(if|while|for)/) and !($next_line=~/\#define.*do.*while/)) {
+                               print "That { should be on the previous line\n";
+                               print "$here\n$display_segment\n$next_line\n\n";
+                               $clean = 0;
+                       }
+               }
+
+#multiline macros should be enclosed in a do while loop
+               if (($prevline=~/\#define.*\\/) and !($prevline=~/do\s+{/) and
+                  !($prevline=~/\(\{/) and ($line=~/;\s*\\/) and
+                  !($line=~/do.*{/) and !($line=~/\(\{/)) {
+                       print "Macros with multiple statements should be enclosed in a do - while loop\n";
+                       print "$hereprev";
+                       $clean = 0;
+               }
+
+# don't include deprecated include files
+               for my $inc (@dep_includes) {
+                       if ($line =~ m@\#\s*include\s*\<$inc>@) {
+                               print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+
+# don't use deprecated functions
+               for my $func (@dep_functions) {
+                       if ($line =~ /\b$func\b/) {
+                               print "Don't use $func(): see Documentation/feature-removal-schedule.txt\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+
+# no volatiles please
+               if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) {
+                       print "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# warn about #if 0
+               if ($line =~ /^.#\s*if\s+0\b/) {
+                       print "#if 0 -- if this code redundant remove it\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+
+# warn about #ifdefs in C files
+#              if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
+#                      print "#ifdef in C files should be avoided\n";
+#                      print "$herecurr";
+#                      $clean = 0;
+#              }
+
+# check for spinlock_t definitions without a comment.
+               if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) {
+                       my $which = $1;
+                       if (!ctx_has_comment($first_line, $linenr)) {
+                               print "$1 definition without comment\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+# check for memory barriers without a comment.
+               if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
+                       if (!ctx_has_comment($first_line, $linenr)) {
+                               print "memory barrier without comment\n";
+                               print "$herecurr";
+                               $clean = 0;
+                       }
+               }
+# check of hardware specific defines
+               if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@) {
+                       print "architecture specific defines should be avoided\n";
+                       print "$herecurr";
+                       $clean = 0;
+               }
+       }
+
+       if ($chk_patch && !$is_patch) {
+               $clean = 0;
+               print "Does not appear to be a unified-diff format patch\n";
+       }
+       if ($is_patch && $chk_signoff && $signoff == 0) {
+               $clean = 0;
+               print "Missing Signed-off-by: line(s)\n";
+       }
+
+       if ($clean == 1 && $quiet == 0) {
+               print "Your patch has no obvious style problems and is ready for submission.\n"
+       }
+       if ($clean == 0 && $quiet == 0) {
+               print "Your patch has style problems, please review.  If any of these errors\n";
+               print "are false positives report them to the maintainer, see\n";
+               print "CHECKPATCH in MAINTAINERS.\n";
+       }
+       return $clean;
+}
index bf8750791dd19613a6ae40a77dc9be4feb167c90..e64eca246f1ab25ce57cb1190cc578fa643421e9 100644 (file)
@@ -36,8 +36,8 @@
 #include "security.h"
 
 /**
- * selinux_netlbl_socket_setsid - Label a socket using the NetLabel mechanism
- * @sock: the socket to label
+ * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
+ * @sk: the socket to label
  * @sid: the SID to use
  *
  * Description:
  * this function and rcu_read_unlock() after this function returns.
  *
  */
-static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
+static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid)
 {
        int rc;
-       struct sk_security_struct *sksec = sock->sk->sk_security;
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
 
        rc = security_netlbl_sid_to_secattr(sid, &secattr);
        if (rc != 0)
                return rc;
 
-       rc = netlbl_socket_setattr(sock, &secattr);
+       rc = netlbl_sock_setattr(sk, &secattr);
        if (rc == 0) {
                spin_lock_bh(&sksec->nlbl_lock);
                sksec->nlbl_state = NLBL_LABELED;
@@ -206,7 +206,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
        /* Try to set the NetLabel on the socket to save time later, if we fail
         * here we will pick up the pieces in later calls to
         * selinux_netlbl_inode_permission(). */
-       selinux_netlbl_socket_setsid(sock, sksec->sid);
+       selinux_netlbl_sock_setsid(sk, sksec->sid);
 
        rcu_read_unlock();
 }
@@ -223,14 +223,15 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
 int selinux_netlbl_socket_post_create(struct socket *sock)
 {
        int rc = 0;
+       struct sock *sk = sock->sk;
        struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
-       struct sk_security_struct *sksec = sock->sk->sk_security;
+       struct sk_security_struct *sksec = sk->sk_security;
 
        sksec->sclass = isec->sclass;
 
        rcu_read_lock();
        if (sksec->nlbl_state == NLBL_REQUIRE)
-               rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
+               rc = selinux_netlbl_sock_setsid(sk, sksec->sid);
        rcu_read_unlock();
 
        return rc;
@@ -251,14 +252,16 @@ int selinux_netlbl_socket_post_create(struct socket *sock)
 int selinux_netlbl_inode_permission(struct inode *inode, int mask)
 {
        int rc;
-       struct sk_security_struct *sksec;
+       struct sock *sk;
        struct socket *sock;
+       struct sk_security_struct *sksec;
 
        if (!S_ISSOCK(inode->i_mode) ||
            ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
                return 0;
        sock = SOCKET_I(inode);
-       sksec = sock->sk->sk_security;
+       sk = sock->sk;
+       sksec = sk->sk_security;
 
        rcu_read_lock();
        if (sksec->nlbl_state != NLBL_REQUIRE) {
@@ -266,9 +269,9 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
                return 0;
        }
        local_bh_disable();
-       bh_lock_sock_nested(sock->sk);
-       rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
-       bh_unlock_sock(sock->sk);
+       bh_lock_sock_nested(sk);
+       rc = selinux_netlbl_sock_setsid(sk, sksec->sid);
+       bh_unlock_sock(sk);
        local_bh_enable();
        rcu_read_unlock();
 
@@ -345,14 +348,17 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
                                     int optname)
 {
        int rc = 0;
-       struct sk_security_struct *sksec = sock->sk->sk_security;
+       struct sock *sk = sock->sk;
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
 
        rcu_read_lock();
        if (level == IPPROTO_IP && optname == IP_OPTIONS &&
            sksec->nlbl_state == NLBL_LABELED) {
                netlbl_secattr_init(&secattr);
-               rc = netlbl_socket_getattr(sock, &secattr);
+               lock_sock(sk);
+               rc = netlbl_sock_getattr(sk, &secattr);
+               release_sock(sk);
                if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
                        rc = -EACCES;
                netlbl_secattr_destroy(&secattr);
index c7e1b26461938eea09e0381fd0e83e213219fb4f..e7ed868fa7c0d4f50d5d1c7d87c117b4efc76569 100644 (file)
@@ -987,7 +987,7 @@ static int __init sa11xx_uda1341_init(void)
                if (platform_get_drvdata(device))
                        return 0;
                platform_device_unregister(device);
-               err = -ENODEV
+               err = -ENODEV;
        } else
                err = PTR_ERR(device);
        platform_driver_unregister(&sa11xx_uda1341_driver);
index e1ed59549c5063a76ba0eb200f966ebaa0c268c8..cb59f994c68f2a4bdfd2c9c1925d5b8cb2dd507d 100644 (file)
@@ -1250,7 +1250,7 @@ static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
                        evoice->substream = substream;
                }
        } else {
-               if (!evoice) {
+               if (evoice) {
                        snd_ali_free_voice(codec, evoice);
                        pvoice->extra = evoice = NULL;
                }
@@ -1267,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
        struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
 
        snd_pcm_lib_free_pages(substream);
-       if (!evoice) {
+       if (evoice) {
                snd_ali_free_voice(codec, evoice);
                pvoice->extra = NULL;
        }
@@ -1356,7 +1356,7 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
                                 VOL,
                                 CTRL,
                                 EC);
-       if (!evoice) {
+       if (evoice) {
                evoice->count = pvoice->count;
                evoice->eso = pvoice->count << 1;
                ESO = evoice->eso - 1;
index 8e89d56b6400d2721a6d68e505aa11358c47113e..f87f8f088956d31827ea62750ffebe10fc2f189a 100644 (file)
@@ -713,6 +713,19 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
        return info->amp_caps;
 }
 
+int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
+                             unsigned int caps)
+{
+       struct hda_amp_info *info;
+
+       info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, dir, 0));
+       if (!info)
+               return -EINVAL;
+       info->amp_caps = caps;
+       info->status |= INFO_AMP_CAPS;
+       return 0;
+}
+
 /*
  * read the current volume to info
  * if the cache exists, read the cache value.
index be12b8814c39b62d8e27ee65b0f9fce0c49aedb6..f91ea5ec9f6d547527c91996a45ba34bdbd079cc 100644 (file)
@@ -277,5 +277,7 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
        return codec->wcaps[nid - codec->start_nid];
 }
 
+int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
+                             unsigned int caps);
 
 #endif /* __SOUND_HDA_LOCAL_H */
index a5a4b2bddf200a8daecde2b76c28b24f702a6231..bef214bcdddfa2ad60c0fa02a9f8c9a16c0036af 100644 (file)
@@ -705,6 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
                .get = conexant_mux_enum_get,
                .put = conexant_mux_enum_put,
        },
+       /* Audio input controls */
+       HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
+       HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
+       HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
+       HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
+       HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
        { } /* end */
 };
 
@@ -947,6 +958,23 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
        snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
 }
 
+/* mute internal speaker if HP is plugged */
+static void cxt5047_hp2_automute(struct hda_codec *codec)
+{
+       struct conexant_spec *spec = codec->spec;
+       unsigned int bits;
+
+       spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+
+       bits = spec->hp_present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
+       /* Mute/Unmute PCM 2 for good measure - some systems need this */
+       snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
+}
+
 /* toggle input of built-in and mic jack appropriately */
 static void cxt5047_hp_automic(struct hda_codec *codec)
 {
@@ -985,6 +1013,21 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
        }
 }
 
+/* unsolicited event for HP jack sensing - non-EAPD systems */
+static void cxt5047_hp2_unsol_event(struct hda_codec *codec,
+                                 unsigned int res)
+{
+       res >>= 26;
+       switch (res) {
+       case CONEXANT_HP_EVENT:
+               cxt5047_hp2_automute(codec);
+               break;
+       case CONEXANT_MIC_EVENT:
+               cxt5047_hp_automic(codec);
+               break;
+       }
+}
+
 static struct snd_kcontrol_new cxt5047_mixers[] = {
        HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
@@ -1300,19 +1343,20 @@ static int patch_cxt5047(struct hda_codec *codec)
        spec->channel_mode = cxt5047_modes,
 
        codec->patch_ops = conexant_patch_ops;
-       codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 
        board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
                                                  cxt5047_models,
                                                  cxt5047_cfg_tbl);
        switch (board_config) {
        case CXT5047_LAPTOP:
+               codec->patch_ops.unsol_event = cxt5047_hp2_unsol_event;
                break;
        case CXT5047_LAPTOP_HP:
                spec->input_mux = &cxt5047_hp_capture_source;
                spec->num_init_verbs = 2;
                spec->init_verbs[1] = cxt5047_hp_init_verbs;
                spec->mixers[0] = cxt5047_hp_mixers;
+               codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
                codec->patch_ops.init = cxt5047_hp_init;
                break;
        case CXT5047_LAPTOP_EAPD:
@@ -1320,12 +1364,14 @@ static int patch_cxt5047(struct hda_codec *codec)
                spec->num_init_verbs = 2;
                spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
                spec->mixers[0] = cxt5047_toshiba_mixers;
+               codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
                break;
 #ifdef CONFIG_SND_DEBUG
        case CXT5047_TEST:
                spec->input_mux = &cxt5047_test_capture_source;
                spec->mixers[0] = cxt5047_test_mixer;
                spec->init_verbs[0] = cxt5047_test_init_verbs;
+               codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 #endif 
        }
        return 0;
index 34ac634695328c2ddedb780101f1c8545deef666..4776de93928b4b55fa78a2b570b40715a54b1f4d 100644 (file)
@@ -6379,8 +6379,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
+       SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
@@ -6391,6 +6393,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
+       SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
@@ -8765,7 +8768,6 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
-       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
@@ -9473,6 +9475,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST),
        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
index 6fcda9bcf0cfc593137701fa3bc6d79c5ecde97c..43f537ef40bf12a134c86b64cd7fa93b6d0f2de7 100644 (file)
@@ -304,6 +304,8 @@ struct hda_codec_preset snd_hda_preset_si3054[] = {
        { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
        { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
        { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
+       /* Asus A8J Modem (SM56) */
+       { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 },
        {}
 };
 
index a6a0a80edc3b19860f781595b84d300aab4de5bd..e3964fc4c40521cb3914740fdd25f764e836209f 100644 (file)
@@ -51,6 +51,7 @@ enum {
        STAC_925x_REF,
        STAC_M2_2,
        STAC_MA6,
+       STAC_PA6,
        STAC_925x_MODELS
 };
 
@@ -152,6 +153,10 @@ static hda_nid_t stac925x_dac_nids[1] = {
         0x02,
 };
 
+static hda_nid_t stac925x_dmic_nids[1] = {
+       0x15, 
+};
+
 static hda_nid_t stac922x_adc_nids[2] = {
         0x06, 0x07,
 };
@@ -469,6 +474,14 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
                      "Dell Precision M90", STAC_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
                      "unknown Dell", STAC_REF),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
+                     "Dell Inspiron 640m", STAC_REF),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
+                     "Dell Inspiron 1501", STAC_REF),
+
+       /* Panasonic */
+       SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
+
        {} /* terminator */
 };
 
@@ -482,29 +495,38 @@ static unsigned int stac925x_MA6_pin_configs[8] = {
        0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
 };
 
+static unsigned int stac925x_PA6_pin_configs[8] = {
+       0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
+       0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
+};
+
 static unsigned int stac925xM2_2_pin_configs[8] = {
-       0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020,
-       0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e,
+       0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
+       0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
 };
 
 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
        [STAC_REF] = ref925x_pin_configs,
        [STAC_M2_2] = stac925xM2_2_pin_configs,
        [STAC_MA6] = stac925x_MA6_pin_configs,
+       [STAC_PA6] = stac925x_PA6_pin_configs,
 };
 
 static const char *stac925x_models[STAC_925x_MODELS] = {
        [STAC_REF] = "ref",
        [STAC_M2_2] = "m2-2",
        [STAC_MA6] = "m6",
+       [STAC_PA6] = "pa6",
 };
 
 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
        /* SigmaTel reference board */
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
+       SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
        SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
        SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
        SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
+       SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
        SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
        {} /* terminator */
 };
@@ -1742,6 +1764,21 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
        unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
 
+       if (pin_ctl & AC_PINCTL_IN_EN) {
+               /*
+                * we need to check the current set-up direction of
+                * shared input pins since they can be switched via
+                * "xxx as Output" mixer switch
+                */
+               struct sigmatel_spec *spec = codec->spec;
+               struct auto_pin_cfg *cfg = &spec->autocfg;
+               if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
+                    spec->line_switch) ||
+                   (nid == cfg->input_pins[AUTO_PIN_MIC] &&
+                    spec->mic_switch))
+                       return;
+       }
+
        /* if setting pin direction bits, clear the current
           direction bits first */
        if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
@@ -1911,7 +1948,8 @@ static int patch_stac925x(struct hda_codec *codec)
                                                        stac925x_cfg_tbl);
  again:
        if (spec->board_config < 0) {
-               snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n");
+               snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 
+                                     "using BIOS defaults\n");
                err = stac92xx_save_bios_config_regs(codec);
                if (err < 0) {
                        stac92xx_free(codec);
@@ -1929,7 +1967,18 @@ static int patch_stac925x(struct hda_codec *codec)
        spec->adc_nids = stac925x_adc_nids;
        spec->mux_nids = stac925x_mux_nids;
        spec->num_muxes = 1;
-       spec->num_dmics = 0;
+       switch (codec->vendor_id) {
+       case 0x83847632: /* STAC9202  */
+       case 0x83847633: /* STAC9202D */
+       case 0x83847636: /* STAC9251  */
+       case 0x83847637: /* STAC9251D */
+               spec->num_dmics = 1;
+               spec->dmic_nids = stac925x_dmic_nids;
+               break;
+       default:
+               spec->num_dmics = 0;
+               break;
+       }
 
        spec->init = stac925x_core_init;
        spec->mixer = stac925x_mixer;
@@ -2110,6 +2159,13 @@ static int patch_stac927x(struct hda_codec *codec)
 
        codec->patch_ops = stac92xx_patch_ops;
 
+       /* Fix Mux capture level; max to 2 */
+       snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
+                                 (0 << AC_AMPCAP_OFFSET_SHIFT) |
+                                 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+                                 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+                                 (0 << AC_AMPCAP_MUTE_SHIFT));
+
        return 0;
 }
 
index 21dc6974d6a3922c3d6a94baf5f232e4bf5e8c44..bfbdc3cbd43b5e936c0614c9429d1414e4a4bb56 100644 (file)
@@ -337,6 +337,8 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
        if (prtd == NULL)
                return -ENOMEM;
 
+       spin_lock_init(&prtd->lock);
+
        runtime->private_data = prtd;
        return 0;
 }